Project

Profile

Help

Triggers » History » Sprint/Milestone 5

Vincent Le Goff, 12/11/2017 07:14 PM

1 1 Vincent Le Goff
h1. Triggers in CocoMUD
2 2 Vincent Le Goff
3 2 Vincent Le Goff
Triggers may very well be the most powerful feature of any MUD client.  CocoMUD offers an advanced system of triggers, which will be discussed and presented with examples in this documentation.
4 2 Vincent Le Goff
5 2 Vincent Le Goff
{{toc}}
6 2 Vincent Le Goff
7 2 Vincent Le Goff
h2. What is a trigger?
8 2 Vincent Le Goff
9 2 Vincent Le Goff
Usually, when you enter a command, the server to which you are connected "replies" with one or more lines.  This reply, just like the command you sent, is mere text (sometimes with little additions, like colors).
10 2 Vincent Le Goff
11 2 Vincent Le Goff
Triggers can intercept a specific line of text and react to it to do something.  That's the basic definition of any trigger:  I react to something (one or more lines sent by the server) and I do something in response (playing a sound, changing the text, sending another command, saving some parts of the line, moving the cursor and so on).
12 2 Vincent Le Goff
13 2 Vincent Le Goff
Since triggers are so powerful, their setting has been spread on several layers.  You don't need to understand, or even know, the most advanced type of trigger to use this feature.  This documentation will walk you through the basic setting of triggers, until the setting of most advanced ones.
14 2 Vincent Le Goff
15 2 Vincent Le Goff
h2. Creating a trigger
16 2 Vincent Le Goff
17 2 Vincent Le Goff
Let's begin with something simple: a trigger that plays a sound when someone (anybody) speaks in a channel.
18 2 Vincent Le Goff
19 2 Vincent Le Goff
This will obviously differ on every MUD, so don't hesitate to adapt this example.  For this example, we'd say we can use the "chat" command to send a message to everyone logged to the MUD.  The command we will type should be like this:
20 2 Vincent Le Goff
21 2 Vincent Le Goff
<pre>
22 2 Vincent Le Goff
chat hello everyone!
23 2 Vincent Le Goff
</pre>
24 2 Vincent Le Goff
25 2 Vincent Le Goff
And if the MUD behaves, it should reply with:
26 2 Vincent Le Goff
27 2 Vincent Le Goff
<pre>
28 2 Vincent Le Goff
[public] You say: hello everyone!
29 2 Vincent Le Goff
</pre>
30 2 Vincent Le Goff
31 2 Vincent Le Goff
Similarly, if someone else speaks on this channel, you might see something like:
32 2 Vincent Le Goff
33 2 Vincent Le Goff
<pre>
34 2 Vincent Le Goff
[public] Aaron says: hi there
35 2 Vincent Le Goff
</pre>
36 2 Vincent Le Goff
37 2 Vincent Le Goff
In short, if we want to intercept the messages on this channel, we need to watch for lines that begin by "[public]" (that is the word "public" between brackets).
38 2 Vincent Le Goff
39 2 Vincent Le Goff
bq. Why should we intercept these messages, anyway?
40 2 Vincent Le Goff
41 2 Vincent Le Goff
If you're new to triggers, you might wonder why it's useful.  The answer in that specific case could be that, if we receive a message on the public channel, the client could play a sound to alert us.  That's on this task we're going to work.
42 2 Vincent Le Goff
43 2 Vincent Le Goff
So we're going to see how to create a trigger that:
44 2 Vincent Le Goff
45 2 Vincent Le Goff
* Reacts when it receives a line beginning with "[public]".
46 2 Vincent Le Goff
* Plays a sound when it does.
47 2 Vincent Le Goff
48 2 Vincent Le Goff
Like most features on CocoMUD, triggers can be created either through the interface or through SharpScript.  We'll see the former first:
49 2 Vincent Le Goff
50 2 Vincent Le Goff
h3. Through the interface
51 2 Vincent Le Goff
52 2 Vincent Le Goff
To add, edit or remove triggers, select *Game* in the menu bar, then *Triggers*.
53 2 Vincent Le Goff
54 2 Vincent Le Goff
You will find yourself in the list of current triggers configured for this world.  This list might very well be empty at first.  To create a trigger, click on the *Add* button.
55 2 Vincent Le Goff
56 2 Vincent Le Goff
A new dialog box opens.  The cursor should be in an edit field, where you're asked to type your trigger.  That's the reaction part, the place where you will specify what fires your triggers.
57 2 Vincent Le Goff
58 2 Vincent Le Goff
In our example, we've determined that our trigger should be executed whenever a line "beginning by @[public]@ is detected.  You can type @[public]@ in this field, but don't leave it just yet: if we create a trigger @[public]@, it will only fire when the server sends a line containing *only* @[public]@.  That's not the case for us, we want for our trigger to fire when the line begins with, not only contains @[public]@.  To do that, we'll have to add an asterisk (@*@) after @[public]@.  If we type @[public]*@ in our trigger, CocoMUD will know that we are looking for lines that begin with @[public]@ followed by something (no matter what).
59 2 Vincent Le Goff
60 2 Vincent Le Goff
You might recognize this syntax, it's the same we use to create [[Alias|aliases]] with variables.  And that's not a coincidence, we'll see later why.
61 2 Vincent Le Goff
62 2 Vincent Le Goff
For the time being, you can write in this edit field:
63 2 Vincent Le Goff
64 2 Vincent Le Goff
<pre>
65 2 Vincent Le Goff
[public]*
66 2 Vincent Le Goff
</pre>
67 2 Vincent Le Goff
68 2 Vincent Le Goff
Press Tab: you find yourself on a list of possible actions to be performed when this trigger fires.  In our example, we want our trigger @[public]*@ to play a sound.  So browse this list until you find:
69 2 Vincent Le Goff
70 2 Vincent Le Goff
<pre>
71 2 Vincent Le Goff
Play an audio file
72 2 Vincent Le Goff
</pre>
73 2 Vincent Le Goff
74 2 Vincent Le Goff
Then press Tab again and click on the *Add action* button.
75 2 Vincent Le Goff
76 4 Vincent Le Goff
You are now asked to configure this action.  What audio file do you want to play when this trigger fires?  You have a *Browse* button if you want to select the file in your file system.  And once selected, you have a *Test* button, to check that CocoMUD can play this audio file just right (CocoMUD supports @.wav@ and @.ogg@ files).  If everything works, just press *OK*.  The action will be added.  The cursor is moved into a list where you see only one item:
77 2 Vincent Le Goff
78 2 Vincent Le Goff
<pre>
79 2 Vincent Le Goff
#play whatever.wav
80 2 Vincent Le Goff
</pre>
81 2 Vincent Le Goff
82 2 Vincent Le Goff
Of course, the "whatever.wav" will be replaced by your file path and name.
83 2 Vincent Le Goff
84 2 Vincent Le Goff
This is the sharp editor: it is used by every feature ([[Alias|aliases]] or [[Macros|macros]] for instance) that needs to execute complex actions at some point.  The window can be a little intimidating at first, but as you've seen, adding an action isn't that complicated.  So here is a brief summary of the trigger dialog with the sharp editor:
85 2 Vincent Le Goff
86 2 Vincent Le Goff
* The first thing to set is the trigger itself (the part that will fire the trigger, @[public]*@ in our case).
87 2 Vincent Le Goff
* Below is a list of actions currently associated with this trigger.  It's a list of actions (what to do when this trigger fires)?  You can add more than just one action.  Note that this list is disabled if it's empty.
88 2 Vincent Le Goff
* An *Edit* button, to edit the selected action.  For instance, in our case, if you've changed your mind and want to play a different audio file, you need to select this line and click on *Edit* to change the audio file.
89 2 Vincent Le Goff
* A *Remove* button, to remove this line of action.
90 2 Vincent Le Goff
* Still below is another list of actions.  This time, it's a list of actions you could desire to add.  That's the list we browsed through when trying to play a sound if this trigger fires.  We won't describe all of them, but you'll see other examples in this documentation.
91 2 Vincent Le Goff
* Then is a button to *Add* the action you have selected.  Remember that you can connect a trigger with zero, one, two or more actions, there's no real limit.
92 2 Vincent Le Goff
* There are other checkboxes and options in this dialog that we will discuss later.
93 2 Vincent Le Goff
94 2 Vincent Le Goff
You can now press on the *OK* button, since we did what we wanted: our @[public]*@ trigger is connected to the action to play a sound.
95 2 Vincent Le Goff
96 2 Vincent Le Goff
You will find yourself in the list of triggers again, with your newly created trigger.  You can press *OK* again to close this dialog and save the trigger to your configuration.  If you don't press *OK*, the trigger will not be saved.
97 2 Vincent Le Goff
98 2 Vincent Le Goff
To see if it works, let's try to fire this trigger!  You could send to the server something like:
99 2 Vincent Le Goff
100 2 Vincent Le Goff
<pre>
101 2 Vincent Le Goff
chat does it work?
102 2 Vincent Le Goff
</pre>
103 2 Vincent Le Goff
104 2 Vincent Le Goff
If everything goes well (assuming, one more time, that the server answers the way we have planned), it should send you something like:
105 2 Vincent Le Goff
106 2 Vincent Le Goff
<pre>
107 2 Vincent Le Goff
[public] You say: does it work?
108 2 Vincent Le Goff
</pre>
109 2 Vincent Le Goff
110 2 Vincent Le Goff
And you should hear a sound, the sound you have selected.  There!  It wasn't that complex, was it?
111 2 Vincent Le Goff
112 2 Vincent Le Goff
h3. Through SharpScript
113 2 Vincent Le Goff
114 2 Vincent Le Goff
As usual, the interface allows to manipulate potentially complex settings, but they all are converted to SharpScript in the end.  Setting the trigger we have worked on above in SharpScript is quite simple.  You can enter the following command in your MUD client, or write it in your "config.set" file:
115 2 Vincent Le Goff
116 2 Vincent Le Goff
<pre>
117 2 Vincent Le Goff
#trigger [public]* {#play path/to/sound.wav}
118 2 Vincent Le Goff
</pre>
119 2 Vincent Le Goff
120 2 Vincent Le Goff
It's a SharpScript instruction.  From left to right:
121 2 Vincent Le Goff
122 2 Vincent Le Goff
* @#trigger@ is the name of the action.  Here, @#trigger@ just creates a new trigger.
123 2 Vincent Le Goff
* @[public]*@ is what should fire our trigger.  Just like above, we have specified @[public]*@ , which means @[public]@ followed by anything.
124 2 Vincent Le Goff
* Then we specify the action or actions to be executed when this trigger fires.  Here, we have @#play path/to/sound.wav@.  @#play@ is another SharpScript action that just plays the sound you give it in argument, if it can.  Notice that we have surrounded our call between braces, because there is a space between the name of the function (@#play@) and the argument of the function (@path/to/sound.wav@).
125 2 Vincent Le Goff
126 2 Vincent Le Goff
Adding a trigger using the SharpScript syntax may be quicker, but it will not forgive easily if you make an error of syntax.  That's one of the reasons why using the interface might be safer.
127 2 Vincent Le Goff
128 2 Vincent Le Goff
h2. Editing a trigger
129 2 Vincent Le Goff
130 2 Vincent Le Goff
In the dialog box of triggers (menu bar, *Game* -> *Triggers*), you can edit a trigger if needed.  You will need to do so if you want to change the part that fires the trigger, or the actions associated with this trigger (for instance, the audio file to be played, in our example).
131 2 Vincent Le Goff
132 2 Vincent Le Goff
h2. Removing a trigger
133 2 Vincent Le Goff
134 2 Vincent Le Goff
Removing the trigger can also be done through the interface.  Just press the *Remove* button and confirm that you do want to remove this trigger.  Do not forget to click on *OK* to close the list of triggers.  If you don't, the trigger will not be removed.
135 2 Vincent Le Goff
136 2 Vincent Le Goff
h2. Using variables in triggers
137 2 Vincent Le Goff
138 2 Vincent Le Goff
It is time to look more closely at our previous trigger, in particular at the asterisk sign (@*@).  It is not a coincidence that you may recognize this syntax from the documentation on [[Alias|aliases]], for it is exactly the same principle: @*@ means anything.
139 2 Vincent Le Goff
140 2 Vincent Le Goff
So here is a list of possible syntax:
141 2 Vincent Le Goff
142 2 Vincent Le Goff
| Syntax | Meaning |
143 2 Vincent Le Goff
| @Welcome*@ | Any line beginning by @Welcome@ . |
144 2 Vincent Le Goff
| @*dude@ | Any line that ends with @dude@ . |
145 2 Vincent Le Goff
| @*spoil*@ | Any line containing @spoil@, at the beginning, the end or the middle.  It will also fire if the line contains @spoiler@ for instance. |
146 2 Vincent Le Goff
| @* spoil *@ | Any line that contains the word @spoil@ surrounded by spaces.  The word @spoiler@ would not fire the trigger in this context. |
147 2 Vincent Le Goff
| @You earned * credits in *.@ | Lines like @You earned 80 credits in combat.@ or @You earned 10 credits in management.@ will fire this trigger.  Also note that the line @You earned some unknown credits in something.@ will also fire. |
148 2 Vincent Le Goff
149 2 Vincent Le Goff
In short, an asterisk sign (@*@) means anything, including a number, a letter, a word, a space, or whatever else... including nothing.
150 2 Vincent Le Goff
151 2 Vincent Le Goff
A little word of caution: the syntax of your trigger is really important, and you should check when the trigger would be fired.
152 2 Vincent Le Goff
153 2 Vincent Le Goff
<pre>
154 2 Vincent Le Goff
*public*
155 2 Vincent Le Goff
</pre>
156 2 Vincent Le Goff
157 2 Vincent Le Goff
This trigger would fire when there is the word @public@ everywhere in the line.  It means this trigger would fire when you receive the following line:
158 2 Vincent Le Goff
159 2 Vincent Le Goff
<pre>
160 2 Vincent Le Goff
[ooc] Modo says: please talk on the public channel, not here, if you're stuck with a quest.
161 2 Vincent Le Goff
Yassen tells you: where should I write, if I want my message to be publicly readable?
162 2 Vincent Le Goff
To send your book to publication, press S.
163 2 Vincent Le Goff
</pre>
164 2 Vincent Le Goff
165 2 Vincent Le Goff
Remember that a trigger can be easily restricted... but can easily be fired.  That all depends on you.
166 2 Vincent Le Goff
167 2 Vincent Le Goff
Back to variables.  The asterisk does two things:
168 2 Vincent Le Goff
169 2 Vincent Le Goff
* It determines when the trigger should fire (specifying "anything").
170 2 Vincent Le Goff
* It writes in variables.
171 2 Vincent Le Goff
172 2 Vincent Le Goff
Let's use the same example of our trigger @[public]*@.  What happens when, say, you receive a line like:
173 2 Vincent Le Goff
174 2 Vincent Le Goff
<pre>
175 2 Vincent Le Goff
[public] Edgar says: I don't get it at all, could someone help me?
176 2 Vincent Le Goff
</pre>
177 2 Vincent Le Goff
178 2 Vincent Le Goff
First, the trigger @[public]*@ fires, then the part after @[public]@ is sent to a variable.  A variable can store information, and that's just what it does here.  Variables are numbered starting with @$1@, @$2@, @$3@ and so on.  So in our example, when we receive the above message, the variable @$1@ is created containing the text:
179 2 Vincent Le Goff
180 2 Vincent Le Goff
<pre>
181 2 Vincent Le Goff
 Edgar says: I don't get it at all, could someone help me?
182 2 Vincent Le Goff
</pre>
183 2 Vincent Le Goff
184 2 Vincent Le Goff
What can we do with it?  About anything.  Every parameter in our actions could use variables.  We will see a concrete example below.  For the time being you could display it:
185 2 Vincent Le Goff
186 2 Vincent Le Goff
<pre>
187 2 Vincent Le Goff
#say $1
188 2 Vincent Le Goff
</pre>
189 2 Vincent Le Goff
190 2 Vincent Le Goff
Which should display:
191 2 Vincent Le Goff
192 2 Vincent Le Goff
<pre>
193 2 Vincent Le Goff
 Edgar says: I don't get it at all, could someone help me?
194 2 Vincent Le Goff
</pre>
195 2 Vincent Le Goff
196 2 Vincent Le Goff
bq. Why does it begin with a space?
197 2 Vincent Le Goff
198 2 Vincent Le Goff
If you wonder about it, just put the trigger with the line side-by-side, that might help:
199 2 Vincent Le Goff
200 2 Vincent Le Goff
* Trigger: @[public]*@
201 2 Vincent Le Goff
* Line: @[public] Edgar says: I don't get it at all, could someone help me?@
202 2 Vincent Le Goff
203 2 Vincent Le Goff
Can you see it?  Our line puts "public" between brackets, then a space, then the name of the one speaking... while our trigger just says "public" between brackets and anything after that.  Which includes our space.
204 2 Vincent Le Goff
205 2 Vincent Le Goff
The solution?  To slightly change our trigger:
206 2 Vincent Le Goff
207 2 Vincent Le Goff
<pre>
208 2 Vincent Le Goff
[public] *
209 2 Vincent Le Goff
</pre>
210 2 Vincent Le Goff
211 2 Vincent Le Goff
This time, we put a space between the right bracket and the asterisk sign.  So now if we receive the line:
212 2 Vincent Le Goff
213 2 Vincent Le Goff
<pre>
214 2 Vincent Le Goff
[public] Edgar says: I don't get it at all, could someone help me?
215 2 Vincent Le Goff
</pre>
216 2 Vincent Le Goff
217 2 Vincent Le Goff
And we display @$1@, we'll see:
218 2 Vincent Le Goff
219 2 Vincent Le Goff
<pre>
220 2 Vincent Le Goff
Edgar says: I don't get it at all, could someone help me?
221 2 Vincent Le Goff
</pre>
222 2 Vincent Le Goff
223 2 Vincent Le Goff
Spaces may be the main source of confusion in your triggers.  The best advice is to look closely at the lines you receive from the server, and use only the @*@ sign when you don't know what will be put there.
224 2 Vincent Le Goff
225 2 Vincent Le Goff
h2. CocoMUD channels in triggers
226 2 Vincent Le Goff
227 2 Vincent Le Goff
CocoMUD has a more interesting feature of channels.  A channel is basically a list of events.  It will store these events and you can display this list whenever you want.  It might be useful, for instance, when exploring the game and not paying particular attention to some messages (on the public channel, or the ooc channel, for instance).  Afterward you might want to read them, so you display the list of messages.
228 2 Vincent Le Goff
229 5 Vincent Le Goff
You will find more informatioon in the [Channels|documentation about channels]].
230 2 Vincent Le Goff
231 2 Vincent Le Goff
h2. Mute triggers
232 2 Vincent Le Goff
233 2 Vincent Le Goff
In some cases, when you receive a line, you don't want for it to appear.
234 2 Vincent Le Goff
235 2 Vincent Le Goff
bq. Does it really happen?
236 2 Vincent Le Goff
237 2 Vincent Le Goff
In some contexts.  For instance, some MUDs send regular ambiance messages to the client.  That can be great to set the ambiance, but that's usually not very user-friendly for people using screen readers.
238 2 Vincent Le Goff
239 2 Vincent Le Goff
<pre>
240 2 Vincent Le Goff
A cloud of sparks from your campfire soars toward the darkening sky.
241 2 Vincent Le Goff
</pre>
242 2 Vincent Le Goff
243 2 Vincent Le Goff
Nice and, well, yeah, when you're near a campfire, it cracks and smokes and sends sparks, but with a screen reader, that's not really useful.  So we could just remove this line.
244 2 Vincent Le Goff
245 2 Vincent Le Goff
To do so, create a trigger.  Through the interface:
246 2 Vincent Le Goff
247 2 Vincent Le Goff
* Go to the menu bar, *Game* -> *Trigger*.
248 2 Vincent Le Goff
* Add a trigger.
249 2 Vincent Le Goff
* Paste the line: @A cloud of sparks from your campfire soars toward the darkening sky.@
250 2 Vincent Le Goff
* No need to select an action, we won't do anything (except if you want to add a crackling sound when that happens).
251 2 Vincent Le Goff
* Tab until you find the "mute trigger" checkbox.  Check it.
252 2 Vincent Le Goff
* Press *OK* several times to validate and save.
253 2 Vincent Le Goff
254 2 Vincent Le Goff
If the client receives this line, it will just ignore it and not display it.
255 2 Vincent Le Goff
256 2 Vincent Le Goff
You could have done the same thing in SharpScript:
257 2 Vincent Le Goff
258 2 Vincent Le Goff
<pre>
259 2 Vincent Le Goff
#trigger {A cloud of sparks from your campfire soars toward the darkening sky.} {} +mute
260 2 Vincent Le Goff
</pre>
261 2 Vincent Le Goff
262 2 Vincent Le Goff
Notice that the second parameter is empty (just @{}@, meaning we don't perform any action).  The third parameter is a flag, beginning by @+@ or @-@ and followed by the name of the flag.  Here, @+mute@ means we activate the @mute@ flag to set our trigger as a mute trigger.
263 2 Vincent Le Goff
264 2 Vincent Le Goff
As pointed out, you can have a mute trigger that performs actions, like playing a sound, displaying something, sending a command, putting the line (or part of the line) in a channel, and so on.
265 2 Vincent Le Goff
266 2 Vincent Le Goff
h2. Mark triggers
267 2 Vincent Le Goff
268 2 Vincent Le Goff
Mark triggers can be useful for accessibility.  They will put the cursor directly on the line that fires the trigger.  It is useful in some contexts:  for instance, when you're exploring, you want the cursor to be put on the list of exits, rather than at the bottom of the window where you will have to press the up arrow key several times.
269 2 Vincent Le Goff
270 2 Vincent Le Goff
It's the same principle to create this trigger:
271 2 Vincent Le Goff
272 2 Vincent Le Goff
* Open the menu bar, *Game* -> *Triggers*.
273 2 Vincent Le Goff
* Click on *Add* to add a trigger.
274 2 Vincent Le Goff
* Put the part that should fire the trigger.  In our example, perhaps something like: @Obvious exits: *@ .
275 2 Vincent Le Goff
* Tab to check the "mark trigger" checkbox.
276 2 Vincent Le Goff
277 2 Vincent Le Goff
The next time you will receive the line beginning with "Obvious exits", the cursor will be moved directly on it.
278 2 Vincent Le Goff
279 2 Vincent Le Goff
The same thing in SharpScript would be:
280 2 Vincent Le Goff
281 2 Vincent Le Goff
<pre>
282 2 Vincent Le Goff
#trigger {Obvious exits: *} {} +mark
283 2 Vincent Le Goff
</pre>
284 2 Vincent Le Goff
285 2 Vincent Le Goff
h2. Triggers with substitution
286 2 Vincent Le Goff
287 2 Vincent Le Goff
In some cases, when you receive a trigger, you want to modify the line that fired the trigger.  One of the common case is to shorten the message.  Some MUDs have very long messages for some channels, like this:
288 2 Vincent Le Goff
289 2 Vincent Le Goff
<pre>
290 2 Vincent Le Goff
Somebody publicly speaks on the 'ooc' channel in a worried voice: is it safe?
291 2 Vincent Le Goff
</pre>
292 2 Vincent Le Goff
293 2 Vincent Le Goff
While this is great, it would be nice to shorten it and perhaps write it differently.  Like:
294 2 Vincent Le Goff
295 2 Vincent Le Goff
<pre>
296 2 Vincent Le Goff
[ooc] Somebody: is it safe? (with a worried voice)
297 2 Vincent Le Goff
</pre>
298 2 Vincent Le Goff
299 2 Vincent Le Goff
The way to do that is to create a trigger, and add a line of substitution.  The line of substitution will replace the line that fired the trigger in the client.
300 2 Vincent Le Goff
301 2 Vincent Le Goff
* Open the menu bar, *Game* -> *Triggers*.
302 2 Vincent Le Goff
* Click on *Add* to add a new trigger.
303 2 Vincent Le Goff
* Write the part to fire this line.  Here we might have something like:
304 2 Vincent Le Goff
<pre>
305 2 Vincent Le Goff
* publicly speaks on the '*' channel *: *
306 2 Vincent Le Goff
</pre>
307 2 Vincent Le Goff
* Notice that we have @$1@ containing the name of the speaker, @$2@ containing the name of the channel, 
308 2 Vincent Le Goff
@$3@ containing the tone of the voice and @$4@ containing the message.
309 2 Vincent Le Goff
* Tab until you find the empty text field "Message to substitute to the trigger line, if any".
310 2 Vincent Le Goff
* In it put:
311 2 Vincent Le Goff
<pre>
312 2 Vincent Le Goff
[$2] $1: $4 ($3)
313 2 Vincent Le Goff
</pre>
314 2 Vincent Le Goff
Does it look understandable?  Take the time to read the trigger, the line that should fire it and the substitution.
315 2 Vincent Le Goff
316 2 Vincent Le Goff
The same trigger in SharpScript would be:
317 2 Vincent Le Goff
318 2 Vincent Le Goff
<pre>
319 2 Vincent Le Goff
#trigger {* publicly speaks on the '*' channel *: *} {} {[$2] $1: $4 ($3)}
320 2 Vincent Le Goff
</pre>
321 2 Vincent Le Goff
322 2 Vincent Le Goff
Important note: we have three arguments to the @#trigger@ action here.  The first one is still the name of the trigger, the second one is still the action to be performed (empty in our case).  The third one is our substitution.  If the field is empty, there's no substitution.  That's just what happened for all of our previous tests.
323 2 Vincent Le Goff
324 2 Vincent Le Goff
h2. Triggers fired by a regular expression
325 2 Vincent Le Goff
326 2 Vincent Le Goff
This section is more advanced, beware.
327 2 Vincent Le Goff
328 2 Vincent Le Goff
The asterisk symbol is great, but it doesn't offer much flexibility.  Hopefully, we can connect a trigger with a "regular expression":https://regexone.com/ .  Regular expressions won't be described in this documentation, that's clearly off topic, but there are plenty of resources out there to learn it.
329 2 Vincent Le Goff
330 2 Vincent Le Goff
As far as CocoMUD is concerned, there's not much to know:  if the trigger begins with a @^@ symbol, it's a regular expression and CocoMUD will treat it as is.
331 2 Vincent Le Goff
332 2 Vincent Le Goff
<pre>
333 2 Vincent Le Goff
^You receive \d+ XP.$
334 2 Vincent Le Goff
</pre>
335 2 Vincent Le Goff
336 2 Vincent Le Goff
This will trigger when you receive the line "You receive ... XP.", with "..." being one ore more numbers.  This won't fire the trigger if you receive the following message: "You receive a lot of XP."
337 2 Vincent Le Goff
338 2 Vincent Le Goff
An important thing to note when using regular expressions in triggers, however, is that, if you want to capture parts of the line, you have to use groups:
339 2 Vincent Le Goff
340 2 Vincent Le Goff
<pre>
341 2 Vincent Le Goff
^You receive (\d+) XP.$
342 2 Vincent Le Goff
</pre>
343 2 Vincent Le Goff
344 2 Vincent Le Goff
Then the number of XP will be put in @$1@.  You can also use named groups and call them with @$myname@ afterward.
345 2 Vincent Le Goff
346 2 Vincent Le Goff
h2. Advanced triggers in Python
347 2 Vincent Le Goff
348 2 Vincent Le Goff
The SharpScript engine is really great... but it doesn't allow everything.  And its aim is to remain light and not allow everything.  It's not a programming language.  But Python is.  And CocoMUD is developed in Python.  The SharpScript engine is designed to send code to Python when the user asks it to do so.  That means you can have triggers that execute much more complex actions.  At the same time, the Python code can access all functions defined by the SharpScript engine, which keeps the code simple and potentially very powerful.
349 2 Vincent Le Goff
350 2 Vincent Le Goff
We'll take an example as usual, but keep in mind the possibilities are really endless.
351 2 Vincent Le Goff
352 2 Vincent Le Goff
The game sends a line when earning XP, but it also displays the total number of XP needed to level up.
353 2 Vincent Le Goff
354 2 Vincent Le Goff
For instance:
355 2 Vincent Le Goff
356 2 Vincent Le Goff
<pre>
357 2 Vincent Le Goff
You receive 37 XP and need 500 to level up.
358 2 Vincent Le Goff
</pre>
359 2 Vincent Le Goff
360 2 Vincent Le Goff
Let's say we want to extract these two numbers and display a percentage.  @xp / total * 100@.  That's not going to work with pure SharpScript.
361 2 Vincent Le Goff
362 2 Vincent Le Goff
For the time being, it's not possible to use the interface to manipulate Python code.  So we'll need to do it in the "config.set" file directly.
363 2 Vincent Le Goff
364 2 Vincent Le Goff
<pre>
365 2 Vincent Le Goff
#trigger {You receive * XP and need * to level up.} {+
366 2 Vincent Le Goff
    # $1 contains the number of XP
367 2 Vincent Le Goff
    # $2 contains the total number to level up
368 2 Vincent Le Goff
    xp = args["1"]
369 2 Vincent Le Goff
    total = args["2"]
370 2 Vincent Le Goff
371 2 Vincent Le Goff
    # We're going to try and convert these numbers
372 2 Vincent Le Goff
    try:
373 2 Vincent Le Goff
        xp = int(xp)
374 2 Vincent Le Goff
        total = int(total)
375 2 Vincent Le Goff
    except ValueError:
376 2 Vincent Le Goff
        # The numbers can't be converted, but do nothing
377 2 Vincent Le Goff
        pass
378 2 Vincent Le Goff
    else:
379 2 Vincent Le Goff
        percentage = xp * 100.0 / total
380 2 Vincent Le Goff
        say("You receive {}/{} XP ({}%).".format(xp, total, int(percentage)))
381 2 Vincent Le Goff
}
382 2 Vincent Le Goff
</pre>
383 2 Vincent Le Goff
384 2 Vincent Le Goff
Wow! That was some trigger! Let's quickly review it:
385 2 Vincent Le Goff
386 2 Vincent Le Goff
* The line that should fire the trigger shouldn't be much of a surprise by now.
387 2 Vincent Le Goff
* The second parameter begins by a @{+@ (a left brace followed by a plus sign).  This tells CocoMUD that what follows is Python code.
388 2 Vincent Le Goff
* Note that all the code is indented.  This is not just for readability this time, this is a Python requirement.  You can use a single space or a tabulation to indent, that's your choice, I usually use 4 spaces because it's easier to read, but that's only a convention.
389 2 Vincent Le Goff
* Some comments.  Don't underestimate their positive impact.
390 2 Vincent Le Goff
* We extract the two numbers (XP and total).  To access them, we use @args@ which is a dictionary containing all variables.  Remember that the first variable is @$1@, we need to access it through @args["1"]@.
391 2 Vincent Le Goff
* We need to convert these numbers.  Why?  There are still strings at that moment, it's as if they had been sent by the user.  And CocoMUD doesn't do anything about it, so you need to do it manually.  That's why we convert these numbers in a try/except/else statement.  Notice that if the conversion fails, we do nothing.
392 2 Vincent Le Goff
* Next we create the percentage.  It's Python 2, so we need to explicitly state that it should take into account floating points.
393 2 Vincent Le Goff
* And finally we use the @say()@ function.  That's just like using the @#say@ function in SharpScript, it's the same thing (not the same syntax because we're in Python).  All SharpScript functions can be accessed like that, so you could use @play()@ or @send()@ or @feed()@ and more.
394 2 Vincent Le Goff
395 2 Vincent Le Goff
I'm not really happy about my previous trigger... I'm not against some lines of code, especially since I find them much more readable than when you try to do everything in script, but... we could definitely work on something safer with the help of regular expressions.
396 2 Vincent Le Goff
397 2 Vincent Le Goff
<pre>
398 2 Vincent Le Goff
#trigger {^You receive (\d+) XP and need (\d+) to level up.$} {+
399 2 Vincent Le Goff
    # $1 contains the number of XP
400 2 Vincent Le Goff
    # $2 contains the total number to level up
401 2 Vincent Le Goff
    xp = int(args["1"])
402 2 Vincent Le Goff
    total = int(args["2"])
403 2 Vincent Le Goff
    percentage = xp * 100.0 / total
404 2 Vincent Le Goff
    say("You receive {}/{} XP ({}%).".format(xp, total, int(percentage)))
405 2 Vincent Le Goff
}
406 2 Vincent Le Goff
</pre>
407 2 Vincent Le Goff
408 2 Vincent Le Goff
Okay, using regular expressions in your trigger is a  bit more technical, but the gain for our code isn't to be dismissed.
409 2 Vincent Le Goff
410 2 Vincent Le Goff
If you want more help about using Python code in SharpScript, just refer to [[SharpScript|the section describing SharpScript]].