| Message |
Here is a more general solution...
First we want a multi-line trigger that has enough in it to match this line and hopefully exclude things that are completely irrevelant.
<triggers>
<trigger
enabled="y"
lines_to_match="5"
match="(?s)^[A-Z][A-Za-z]+ (slices|chops|hits|slashes) [^.]+\.\Z"
multi_line="y"
regexp="y"
script="attack_trigger"
sequence="110"
>
</trigger>
</triggers>
In this case I have tested for:
- (?s) means "dot matches all" which means newlines can be part of a regular expression. Normally newlines terminate a regular expression.
- First thing on line starts with a capital letter (A-Z) followed by at least one lower-case letter followed by a space. That hopefully gives matches on names (like Ryboi) but not stuff like prompts.
- The words "(slices|chops|hits|slashes)" to try to identify this as one of your combat messages. You would put words here that would appear (the | means "or").
- Any character other than a period. Excluding periods rules out double matches. Otherwise this would match twice:
Ryboi slices across your head with a solar eclipse shofa, spilling stinging
blood into your eyes.
You go north.
- A trailing period as the last character.
This gives a reasonable chance that the trigger will match multiple lines which are in the general category of what you want.
Now in the trigger script (in the script file, for convenience, because of the imbedded newlines and other reasons) we have this as the trigger function:
local attack_re = rex.new ("^(?<who>[A-Za-z]+) (?<attack>slices|chops|hits|slashes) across (?<where>.*) with (?<what>.*), spilling .*\.$")
function attack_trigger (name, line, wildcards)
-- change newlines and multiple spaces into a single space
local matching_text = string.gsub (wildcards [0], "%s+", " ")
-- test full regular expression
local s, e, t = attack_re:match (matching_text)
-- see if match
if s == nil then
return
end -- no match
-- debugging
print ("line=", matching_text)
require "tprint"
tprint (t)
end -- attack_trigger
The string.gsub fixes up the lines to change spaces and newlines to just spaces. This gets rid of the problem of imbedded newlines.
Now we make a more detailed regular expression using rex.new (this has the same syntax as the normal trigger regexps) and can now match as if we got a single line.
In this case I am pulling out who attacked us, with what, what sort of attack, and the effect of the attack.
My debugging output is:
Ryboi chops across your head with a solar eclipse shofa, spilling stinging
blood into your eyes.
line= Ryboi chops across your head with a solar eclipse shofa, spilling stinging blood into your eyes.
1="Ryboi"
2="chops"
3="your head"
4="a solar eclipse shofa"
"who"="Ryboi"
"what"="a solar eclipse shofa"
"where"="your head"
"attack"="chops"
This general technique could be applied to many cases where you need to match multiple lines.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | top |
|