The simplest kind of trigger specifies only a pattern and an action. Below these parameters are described in detail.
What exactly is pattern
? It is a
regular expression. In short, a regular
expression is a way to specify text patterns that are looked for in
the lines that the server sends. If you know Perl, you certainly know
what is a regular expression. If not, it is advised that you look for
some more information on it, there are plenty of tutorials on the
Internet. For those who know them, you can use the full power of
Perl's regular expressions in triggers, because Perl is used for the
matching.
What about the action
? It can be
anything that could be entered in the command line. It can be a simple
command, that is sent to the MUD. Or you can send several commands at
separating them with %;
as described in
Section 3.2, “Interacting with the MUD”. Finally, you can execute some Perl
code when a trigger matches, and this allows you to do virtually
anything you want.
Below is an example of a very simple trigger. To create this trigger, inform the Pattern and Action parameters shown below. Leave the other parameters in their default values.
Pattern: has attacked you!
Action: wield sword
Whenever a line that contains the phrase "has attacked
you!
" is received, the command "wield
sword
" will be automatically be sent. Note that in this
case the received line will probably be something like "An
orc has attacked you!
", but the trigger matches because that
line contains the pattern
. This is a
feature of regular expressions. If you want to match the entire line
and not only part of it, you must use the ^
and
$
anchors in the beginning and end,
respectively.
By default, case is considered when matching: if the server sent
a line saying "Has Attacked
" then there would be no
match. To make case be ignored when matching, check
the Ignore case when matching option.
It is also possible for the action to be executed to depend on what was received from the server. This is better explained by an example:
Pattern: ^(.*) has attacked you!$
Action: cast missile $1
There are two new things in the pattern. The first one is that
is surrounded by ^
and $
which
means that the entire line must match, as described previously. The
other new thing (and the one that concerns us at this moment) is
the (.*)
part. In regular expressions, the dot
means to match any character. The asterisk means zero or more of the
previous element. So the combination .*
means zero
or more of any characters. Essentially, it matches anything. The
brackets ()
around any part of a regular expression
captures part of the string to be used afterwards. So the whole
regular expression means: look for a line that contains something
followed by has attacked you!
. What comes
before has attacked you!
is stored for later
use.
This stored string is then used in the action by means of
the $1
construct. This special placeholder is
substituted by what was captured in the matched string. So if the
line Orc has attacked you!
is
received, cast missile Orc
is send.
If Smaug has attacked you!
is received,
then cast missile Smaug
is sent to the World, and
so on.
It is possible to have more than one captured string in the
pattern. In this case, $1
is replaced by what was
captured in the first group, $2
by the second
group, and so on.
Sending commands to the World is useful, but the real power is
the fact that you can also run Perl commands in response to triggers.
Just enter them as you would in the command box: prefixed
by /
. If the action is simple you can enter the
statements there directly, if not, you can define a function in your
script file and call it from the trigger.
Let us rewrite Example 8.2, “A trigger which captures part of the received line and uses it in the action” to use Perl in the action:
Pattern: ^(.*) has attacked you!$
Action: /$world->send("cast missile $_[1]")
This time, when a line consisting of some arbitrary text
followed by "has attacked you!
" is received, the
$world->send
will be called to send some text
to the World.
You may have noticed that here $_[1]
was used
instead of $1
in the action to represent the first
captured bracketed group. The reason for this is complex, and if you
do not want to worry about the inner workings, just use the following
rule: in commands sent to the mud,
use $1
, $2
, etc., and in actions
that are Perl commands,
use $_[1]
, $_[2]
and so
on.
Here are the details for the different syntaxes. Feel free to skip the next two paragraphs:
When a trigger matches, KildClient substitutes
$1
(and the other placeholders) by the captured
expressions from the received line. However, $_[1]
(and the other similar tokens) are not replaced by KildClient. If the
action is just a string sent to the mud, they would not be replaced,
so the only possibility to use the captured groups is with
the $1
syntax. But Perl commands can access the
captured groups in another way: the strings are stored in
the @_
array. The first
position, $_[0]
contains the whole matched line.
Subsequent positions contain each matched grouped expression,
so $_[1]
is the first bracketed
substring, $_[2]
is the second, and so on. This
way, when a Perl command is executed the values are replaced by the
Perl interpreter itself.
It is also possible to use $1
in commands to
be passed to the Perl interpreter. Most of the time it will work, but
in some specific circumstances you may get unexpected results. So it's
preferable to let Perl do the substitution when commands are to be
run by the Perl interpreter.
If you call a sub-routine as the trigger action, the matched
arguments are not automatically passed, so you need to pass them
manually. Since they are in the array @_
, just pass
that whole array as the argument to the sub-routine. Inside the
sub-routine, they will be available as the sub-routine's arguments,
which incidentally means that they will be accessed in the exact same
way: with $_[1]
, $_[2]
and so
on. Alternatively, you can only pass the parameters that you need
instead of the whole array.
Here's an example of a trigger that calls a sub-routine:
Pattern: ^(.*) has attacked you!$
Action: /myGreatAttackSequence(@_)
Naturally, you need to define the
myGreatAttackSequence
sub-routine in your script
file. It will be called as the result of the trigger. The
@_
array, containing the whole matched line and the
matched bracketed expressions is passed to the sub-routine as argument,
and its contents will be available to the sub-routine as its
parameters.