Triggers
What is a trigger exactly?
Triggers match on something received from the MUD. They trigger some sort of action by MUSHclient, hence their name.
They have a counterpart that matches on what you type, called an "alias".
What can I do with triggers?
How do I get a trigger to match?
You normally match on incoming text, but you can also match on the colour of an incoming line.
There are two sorts of matches you can do:
Normal matching
A normal trigger (ie. with "regular expression" not checked) just matches on literally what is entered in the "Trigger" box, with optional wildcards represented by asterisks. You can have up to 999 asterisks, each representing some "unknown" text that might vary from line-to-line (eg. the name of someone or something).
For example:
For example, to match a line starting with an asterisk, you could match on this (with a regular expression):
Regular expression
Regular expressions are a bit more complex, but give you more power over what you match on.
A couple of simple rules:
Making regular expressions check for alternatives
Another powerful thing you can do with regular expressions is to look for "this" or "that".
For instance, if you want to make a trigger warn you if one of Cigowyr, Herrach, Crael or Wiceadric has paged you, you can match like this:
How to gag annoying players
Simply set up a regular expression like the one above (substituting the relevant player names, of course), and then check "omit from output". Any paragraphs matching that trigger will be discarded from your output window.
If you want to let them know you have them gagged you could put something like this in the "Send" box:
What you could do to guard against this would be to make the trigger call a script routine, and in the script count how many times it has been called. After (say) 20 times it could notify you (using world.note) or disable the trigger, so you could take corrective action (like complaining to an admin about the other player).
Matching on everything except a word
In some cases, you might want to match on everything except one word. For example, in SMAUG both room names and exits are displayed in white on black. You could detect room names by setting the match string like this:
Another real-life example was where a player wanted to congratulate other players when they reached another level, but not congratulate himself. He could do that like this:
Trigger scripts
Triggers can execute script commands by simply putting the command into the "send" box and selecting "send to script".
However for more complex scripts you can put scripts into your script file (see scripting configuration tab for the world) and then call the script from the trigger. To do this put the name of the script subroutine into the trigger's script box.
The script subroutine must have three arguments (four for Lua), as follows:
Other wildcards can be accessed by using the GetTriggerWildcard script routine (for example, named wildcards, or wildcards over number 9).
For Lua, wildcard 10 is the tenth wildcard, wildcard 11 is the eleventh wildcard and so on. All wildcards are returned in the Lua wildcards table. Wildcard subscript 0 is the entire matching line. Also in Lua named wildcards are returned in the wildcards table keyed by name.
For Lua, the fourth argument (which you can optionally supply) is returned with a table of each style run for the triggered line. Inside that table (which starts at 1 for the first style) is a table per style. Per style, you will get four entries:
Wildcards
A powerful feature in matching triggers or aliases is the ability to specify "wildcards" which are variable information that might change from time to time.
For example:
Using the wildcard in the "send" box ...
To use this unknown quantity you can refer to it as %1 (for the first wildcard) in the "send" box, like this:
For wildcards above 9 you can use this syntax:
Also, if you use regular expressions, you can name wildcards, like this:
Trigger evaluation
Normally when a trigger matches, no further matching is done, for the main world, or the current plugin. That way a match "deals with" the current situation (eg. if your character is hungry). However if you check "keep evaluating" then further triggers in the list are evaluated as well.
Regardless of the "keep evaluating" flag, triggers in other plugins are still processed, as each plugin is supposed to be independent.
However a script can call the StopEvaluatingTriggers if it needs to stop further evaluation, either in the current plugin, or all plugins. This lets a script decide, at run-time, whether or not it handled the situation.
Triggers match on something received from the MUD. They trigger some sort of action by MUSHclient, hence their name.
They have a counterpart that matches on what you type, called an "alias".
What can I do with triggers?
-
Colour a line to make it stand out (eg. colour chat channels in blue)
Colour individual words to make them stand out (eg. colour your character's name)
Highlight lines or words in bold, italic or underline
Gag annoying players by discarding lines which contain messages from them
Omit uninteresting things from the log file
Play a sound when certain things happen
Call a script routine to handle special events
Send a response back to the MUD (eg. "wield sword" when you are attacked)
Make editing attributes in a MUSH or MUCK easier
How do I get a trigger to match?
You normally match on incoming text, but you can also match on the colour of an incoming line.
There are two sorts of matches you can do:
-
Normal, with wildcards
Regular expression
Normal matching
A normal trigger (ie. with "regular expression" not checked) just matches on literally what is entered in the "Trigger" box, with optional wildcards represented by asterisks. You can have up to 999 asterisks, each representing some "unknown" text that might vary from line-to-line (eg. the name of someone or something).
For example:
-
To match on pages:
Rhayctred pages: I saw Ibydan down by the river.
Trigger: * pages: *
-
To match on emotes:
From afar, Ocalef sighs
Trigger: From afar, *
One restriction on normal triggers is that you can't match on the "*" character itself, as it is a wildcard symbol. To do that, you would need to use a regular expression (see below), and "escape" the "*" by putting a backslash in front of it. For example, to match a line starting with an asterisk, you could match on this (with a regular expression):
^\*
Regular expression
Regular expressions are a bit more complex, but give you more power over what you match on.
A couple of simple rules:
-
^ - Matches the start of the line
$ - Matches the end of the line
. - Matches any character
* - Matches zero or more of the previous character or set (so, ".*" matches any number of anything)
+ - Matches one or more of the previous character or set (eg. "be+d" matches "bed", "beed", "beeed" and so on.)
Making regular expressions check for alternatives
Another powerful thing you can do with regular expressions is to look for "this" or "that".
For instance, if you want to make a trigger warn you if one of Cigowyr, Herrach, Crael or Wiceadric has paged you, you can match like this:
^(Cigowyr|Herrach|Crael|Wiceadric) pages\: .+$
The "|" symbol means "or", so the expression matches on one name or another. You can extend this idea to matching on whether they page or say something, like this:
^(Cigowyr|Herrach|Crael|Wiceadric) (pages\:|says,) .+$
You probably want to check "ignore case" in case their name is given as "cigowyr" rather than "Cigowyr".
How to gag annoying players
Simply set up a regular expression like the one above (substituting the relevant player names, of course), and then check "omit from output". Any paragraphs matching that trigger will be discarded from your output window.
If you want to let them know you have them gagged you could put something like this in the "Send" box:
page %1 = I am ignoring you.
Note - it might be unwise to set up an "auto-response" like the one above, because it could be used as the basis of a Denial Of Service (DOS) attack. If two players each set up an auto-response like that, then they will get into a loop, as the response from one player triggers the response from the other, and so on. Especially if they have "omit from output" set, they will not even be aware that they are causing a great overhead for the MUD, as it continually sends the messages backwards and forwards between the two players. What you could do to guard against this would be to make the trigger call a script routine, and in the script count how many times it has been called. After (say) 20 times it could notify you (using world.note) or disable the trigger, so you could take corrective action (like complaining to an admin about the other player).
Matching on everything except a word
In some cases, you might want to match on everything except one word. For example, in SMAUG both room names and exits are displayed in white on black. You could detect room names by setting the match string like this:
Trigger: ^(?!Exits:).*$
Match: white on black, bold
Regular expression: Checked
The expression "(?!Exits:)" means not the word "Exits:". Another real-life example was where a player wanted to congratulate other players when they reached another level, but not congratulate himself. He could do that like this:
Trigger: ^(?!Caeth )(\w*) has risen to .*$
Regular expression: Checked
Send: say Congratulations %1!
This example assumes the player's name is Caeth.
Trigger scripts
Triggers can execute script commands by simply putting the command into the "send" box and selecting "send to script".
However for more complex scripts you can put scripts into your script file (see scripting configuration tab for the world) and then call the script from the trigger. To do this put the name of the script subroutine into the trigger's script box.
The script subroutine must have three arguments (four for Lua), as follows:
-
Name of the trigger
The matching line
An array of the first 10 wildcards (Lua - all wildcards)
Lua only - a table of all the styles in the line
sub MyTrigger (name, line, wildcards)
world.Note "Trigger " & name & " matched."
world.Note "Wildcard 1 was" & wildcards (1)
end sub
Wildcard 10 is the entire matching sequence, which is not necessarily the same as the matching line in the case of regular expressions.Other wildcards can be accessed by using the GetTriggerWildcard script routine (for example, named wildcards, or wildcards over number 9).
For Lua, wildcard 10 is the tenth wildcard, wildcard 11 is the eleventh wildcard and so on. All wildcards are returned in the Lua wildcards table. Wildcard subscript 0 is the entire matching line. Also in Lua named wildcards are returned in the wildcards table keyed by name.
For Lua, the fourth argument (which you can optionally supply) is returned with a table of each style run for the triggered line. Inside that table (which starts at 1 for the first style) is a table per style. Per style, you will get four entries:
-
textcolour - the RGB colour of the text in that style run
backcolour - the RGB colour of the background colour in that style run
text - the text of that style run
length - the length of that style run
style - style flags (or'ed together): bold=1, underline=2, blink=4.
Wildcards
A powerful feature in matching triggers or aliases is the ability to specify "wildcards" which are variable information that might change from time to time.
For example:
* attacks you.
In this case the asterisk represents the name of the unknown attacker.Using the wildcard in the "send" box ...
To use this unknown quantity you can refer to it as %1 (for the first wildcard) in the "send" box, like this:
kick %1
The second wildcard is %2, and so on. Wildcard %0 is a special case which represents the entire matching text.For wildcards above 9 you can use this syntax:
kick %<22>
The number in the angled brackets can be from 0 to 999.Also, if you use regular expressions, you can name wildcards, like this:
^(?P<target>.*) attacks you\.$
This names the wildcard as "target". You can then use this name in a similar way:
kick %<target>
Trigger evaluation
Normally when a trigger matches, no further matching is done, for the main world, or the current plugin. That way a match "deals with" the current situation (eg. if your character is hungry). However if you check "keep evaluating" then further triggers in the list are evaluated as well.
Regardless of the "keep evaluating" flag, triggers in other plugins are still processed, as each plugin is supposed to be independent.
However a script can call the StopEvaluatingTriggers if it needs to stop further evaluation, either in the current plugin, or all plugins. This lets a script decide, at run-time, whether or not it handled the situation.
Topics
- Aliases
- Default triggers/aliases/timers/macros/colours
- Getting started
- Groups
- Plugins
- Regular Expressions
- Timers
Commands
Dialogs
Functions
- (AddTrigger) Adds a trigger
- (AddTriggerEx) Adds a trigger - extended arguments
- (DeleteTemporaryTriggers) Deletes all temporary triggers
- (DeleteTrigger) Deletes a trigger
- (DeleteTriggerGroup) Deletes a group of triggers
- (EnableTrigger) Enables or disables a trigger
- (EnableTriggerGroup) Enables/disables a group of triggers
- (GetPluginTriggerInfo) Gets details about a named trigger for a specified plugin
- (GetPluginTriggerList) Gets the list of triggers in a specified plugin
- (GetTrigger) Gets details about a named trigger
- (GetTriggerInfo) Gets details about a named trigger
- (GetTriggerList) Gets the list of triggers
- (GetTriggerOption) Gets the value of a named trigger option
- (GetTriggerWildcard) Returns the contents of the specified wildcard for the named trigger
- (IsTrigger) Tests to see if a trigger exists
- (SetTriggerOption) Sets the value of a named trigger option
- (StopEvaluatingTriggers) Stops trigger evaluation