Triggers in JASS
This tutorial is about triggers in JASS. I am expecting you to know JASS' syntax already, reading my previous JASS tutorial would be enough.

You can call this Tutorual the sequel of the previously named tutorial. That was a great tutorial for understanding all of the theory behind JASS and, I accept it, programming. This tutorial is more about applying the knowledge you got in that tutorial.

But you can learn from this tutorial as long as you understand JASS' syntax and don't know about the stuff I am gonna talk about here.

What is this tutorial about?
This section covers explanations about the objective of the tutorial. Because of blizzard's way of calling things the title "Triggers in JASS" might be ambiguous.

What is a trigger?
A trigger is a JASS object. Probably the most important JASS object cause it detects events, checks conditions and executes functions for your if necessary. Also creates a new thread. I will ellaborate about threads and their use later.

What is a World Editor Trigger?
That's the problem, what world editor calls triggers are : A conjunction of a global variable and a script section which includes a function that is automatically executed on map initialization.

What is 'triggers' ?
A lot of people think that "triggers" is a language that is different of JASS. You would most of the times find a typical question thread "What is better, JASS or triggers?" what they call triggers is actually a GUI that world editor provides for JASS. That tree thing that is based in clicks and allows you to add events/ conditions / actions and some control structures is a Graphical User Interface that creates JASS scripts for you.

Convert to custom text
Is the process of telling world editor to hide the GUI and show the JASS code it would otherwise generate directly in the map script, So you can modiffy it to your will.

In few words this tutorial is about using the trigger object in JASS thus allowing you to actually do stuff in JASS instead of having to use GUI for everything. Because you edit the JASS script directly you have a lot more of freedom and less limitations than using GUI.

Getting started
What do you need? you would need some sort of text editor. I use notepad++, you could use others like textpad or the notepad included in windows. You can also try JASS shop pro.

You need access to common.j and blizzard.j functions. I have them open in notepad++, you can use JASS shop pro to browse for them or the API browser at http://jass.sourceforge.net/doc/ .

Let's exploit the editor
So the world editor's triggers are sections of code that include a function that is automatically executed on map initialization. And also a global variable.

We are going to create one of them, this is easy, go to the Trigger Editor then choose New then click Trigger. You will be able to set a name for it. Let us give it the name testtrig.

It will show something like this:

Trigger:

testtrig

EventsConditionsActions

Now we have to go to Edit\Convert to custom text. Now we have something decent out there. From now on this is the process called "Create a World Editor trigger".

It is time to face the truth, World editor isn't robust and if you use JASS it may crash for just the tinyest syntax error sometimes. So it is time to get used to use a text editor everytime you want to change any JASS stuff inside your map. And save the scripts externally too.

So you have to select all the text in the WE trigger and copy it to your favorite text editor. If you are lucky your text editor is ready to highlight JASS syntax in a way like the [jass] that is not required though.

Being slow I've been? Well the introduction is the most important part. It is time to explain. I will start advancing some topics that are important before understanding the JASS script world editor just generated for us.

I. The code type
You certainlly understand the integer, boolean, string and real types already. There is another important type called code. code is an important part of JASS syntax.

You would certainlly note it when checking the argument list of TriggerAddAction for example:

note the function Trig_testtrig_Actions . The reason to add the function keyword is to let whatever parses the script know that you are not talking about a variable but a function.

JASS:

callTriggerAddAction( gg_trg_testtrig, Trig_testtrig_Actions )

This would be refering to a variable called Trig_testtrig_Actions instead of a code value.

Another allowed value for the code type is null.

Note that the function must be declared before you try to use it as a value for 'code'. Most likelly the function must be Above in the script or in another script file that is loaded before your map's script, like a custom blizzard.j for example. You can actually use natives as code values but that's probably useless.

And in order to be used as a value for code , the function must take NO ARGUMENTS.

code variables - arguments - return values
Just an informative place in case you didn't note that as magical as the code type is it can be used like any other types

II. Boolexprs
If the code type is used to tell natives what function to call some time. Boolexprs are actually "pointers to functions that return boolean", Sometimes the function used by the native is used as a condition that the native evaluates.

There are some issues with Boolexprs, they are ambiguous too. Cause for some reason there are 2 types that are derived from them, you would note in common.j:

What's the difference between conditionfunc, filterfunc and boolexpr? The answer is none. In fact I will focus on talking about boolexpr here. Because all the natives take boolexpr arguments.

Although some natives return conditionfunc or filterfunc, you won't have any problem if you use boolexpr directly.

Create a boolexpr

JASS:

nativeConditiontakescodefuncreturnsconditionfunc

So you would have to use Condition(function Some_function) or soemthing like that in order to create a boolexpr. Yes it returns conditionfunc but it can be used freely as boolexpr since conditionfunc is a type derived from boolexpr
[/b]Destroy a boolexpr[/b]

JASS:

nativeDestroyBoolExprtakesboolexprbreturnsnothing

What?
I was feeling that this theory was required before going into usage of triggers. Sorry if it was kind of boring or obvious.

As I said a WE trigger consists of a block of code that includes a function that is executed automatically on map initialization and a global variable. The names of the function and the global variable depend on the name of the World editor trigger, if you change that name it will just change the name of the global variable and the init function.

I forgot to say that a World Editor trigger also has a checkbox that allows you to make world editor set the map script so it automatically executes the trigger pointed by the variable after all the init functions of all the triggers were called. This option is called "run on map initialization"

In this case it is clear that the init function is InitTrig_testtrig and the global variable is gg_trg_testtrig. In other words the InitTrig_testtrig will automatically be execute when the map starts.

The rest is easy to understand once you now about the trigger object.

What is an event?
An event is a condition you add to the trigger to tell the game to execute the trigger whenever that event happens. Events are optional. A trigger without events may exist and it would be used probably by TriggerExecute , ConditionalTriggerExecute or maybe the script would add events to the trigger later.

A trigger may have many events and only one of them is required to trigger in order to make the trigger execute

What is a condition?
A condition is a function that is automatically called and evaluated by the game when an event triggers, if the function returns true then it will execute the trigger, otherwise it will not execute the trigger. Conditions are optional too, a trigger without conditions will simply execute automatically when an event triggers or if the trigger is executed.

What is an action?
An action is a function that is called by the trigger when the trigger is executed. Actions are optional too, because of natives like GetTriggerEvalCount or GetTriggerExecCount , you could have a trigger and use it as a counter to know how many times an event has happened.

Create a trigger

JASS:

nativeCreateTriggertakesnothingreturnstrigger

This is the native that creates a trigger for you and returns a reference (pointer) for you. You should assign this to a variable actually.

In the case of our very own script code it is set gg_trg_testtrig = CreateTrigger() It is creating a trigger then making gg_trg_testtrig point to the new object.

This native sets a function to be the trigger's action. But it is not just that. It also creates a triggeraction object. It is a problem when you are no longer going to use the trigger, destroying the trigger ins't enough you have to destroy the triggeraction object too unless you want it to leak memory. That's something to take care later. The returned pointer is also useful when you want to change a trigger's action although the users for that may not be clear.

To the already created trigger we are adding the function Trig_testtrig_Actions as the function to be called by the trigger when the trigger is executed.

What?
We currently have a function that is called during map initialization that creates a trigger for us, a trigger that does absolutelly nothing and is never executed.

What a waste of time, all the text I typed and the lesson has not even started yet.

So let's just make this work. First of all remove the "Melee Initialization" trigger in case it is still there. Change the description of the map to trigger tests. And let's continue.

Add Events to your trigger
Triggers wouldn't be as useful if it wasn't because of events. JASS would be an extremely disabled scripting language if it wasn't because of triggers' events.

The definition of event is somewhere above. But the only way to tell the game that you'd want to execute a trigger when XXXX thing happens is to use a function to register the event .

I will have to say something, Long ago when I was just starting I knew about JASS and how to use the "Custom Script:" option in GUI also how to add functions to the custom script section.

I was reluctant to start using JASS seriously and it was because event registering seemed like chinesse.

If you want to use JASS seriously you have to get used into registering events . They are just functions, nothing more. But of course because there are so many player and unit events there are many variations.

In order to make JASS work for you I will have to give some examples of events and specially tell a way to figure out what event to use. Enjoy.

The press escape event

What do we want?
In this case we want to make a trigger execute when the player presses Escape. You would have noted that this is used by the campaign to skip cinematics for example.

So what kind of event is it?
The player presses the key escape so it should be a player event

These are just some of the constants of the type playervent that are declared in common.j . So playerevent is just a type that holds the different kinds of player events you can use.

After looking and looking the only one that seems to be what we are looking for is EVENT_PLAYER_END_CINEMATIC , because we know that ESC is used to skip cinematics, let's try it then.

Let's use the trigger registering native. We only needed 3 things, the trigger (we already have one), the player (what?) and the playerevent (we now know that we have to use EVENT_PLAYER_END_CINEMATIC )

What to put for player? For the moment there is only one thing you need to know about players and it is that to get a good reference to a player you only need the function:

JASS:

constantnativePlayertakesintegernumberreturnsplayer

The number starts from 0, so Player(0) is Player 1, Player(1) is Player 2 and so and so.

We will start simple, we want to display a message whenever Player 1 presses Escape. I am going to use the DisplayTextToPlayer function

It is a native that registers a unit event. It requires a trigger, a unit and a unitevent. You would have noted that this is not what we want cause it would only work if that specific unit casts a spell, but we want every unit to do so. Let's go on:

Note that it calls the previous function and just uses null as filter argument. So there is no condition and it works too! . But still only for one player, we want it to run each time any unit casts a spell.

Now this blizzard function helps us. It just uses a loop to register the same event for every possible player in the game. We will use this one this time.

Anything else?

Yes, note that the function we are going to use requires a playerunitevent argument. Which is fairly similar to the playerevent type. After looking for constants of that type we have a bunch of options for what we want here:

These are the playerunitevent that seem to have a relationship with spells being casted. Which of these ones to use? Common knowledge will say:

EVENT_PLAYER_UNIT_SPELL_CHANNEL : useless, ignore it
EVENT_PLAYER_UNIT_SPELL_CAST : To detect the moment before a unit spends mana/cooldown and is about to cast a spell
EVENT_PLAYER_UNIT_SPELL_EFFECT : The exact moment a unit casts the spell and consumes mana/cooldown
EVENT_PLAYER_UNIT_SPELL_FINISH : The unit has succesfully ended casting the spell
EVENT_PLAYER_UNIT_SPELL_ENDCAST: The unit stopped casting the spell (either succesfully or not)

Now preplace a bunch of units with spells , make sure they can cast the spells and use test map. Make one of them cast a spell and read the message.

End of Events
You now know that you require functions to register events for triggers. Note that you won't always find an event to detect what you want, and sometimes the event names are not as precise as you would like.

TriggerRegisterUnitEvent works the same as TriggerRegisterPlayerUnitEvent but it works only if the specified unit causes the event and also uses other events that start with EVENT_UNIT_ instead of EVENT_PLAYER_UNIT_ note that some EVENT_UNIT_ events don't have EVENT_PLAYER_UNIT_ equivalents and viceversa.

Note that there are other kinds of events like gamestateevents and some that are of importance, timer events.

Map initialization is not an event it is a flag you add to a trigger so world editor makes the script execute the trigger automatically after initialization has finished.

Event Responses
An event response is a function that returns something that has a relationship with the "triggering event" . Note that all the functions called by a trigger that was under the effect of an event can use these Event Responses.

GetTriggerUnit
When you are handling a unit event. You would have to know what unit triggered the event, right?.

The general event response used by those events is GetTriggerUnit:

JASS:

// returns handle to unit which triggered the most recent event when called from// within a trigger action function...returns null handle when used incorrectlyconstantnativeGetTriggerUnittakesnothingreturnsunit

Let's apply it, since we are using text messages, we would want to display the name of the unit that is casting the spell. Let's us use GetUnitName

So we need a trigger and a boolexpr, the boolexpr points to the function that will be evaluated before executing the trigger, that function should return true.

Note that this native does create a triggercondition object. Horrible but true, if you plan destroying a trigger you will need to remove the condition too. As a matter of fact the desctruction or not of the boolexpr is something to worry about too. But that's something we will take care of later.

We first need a boolexpr. The boolexpr needs a function that returns boolean. So we will make it. Let's say we want the trigger to only work if the name of the unit is bob.

So pick the object editor and change the name of the archmage to bob , keep it lower case. Then place a bob unit in the map and make sure he has enough mana to cast spells. Also please any other unit that can cast spells, and make sure both are owned by Player 1.

Threads and multi instances
I accidentally said so before "Triggers also create new threads" this is going to be completelly crazy. But I think it is vital to understand threads in order to understand the rest.

After testing this thing with units casting abilities you may have noted that many units can cast abilities and the trigger works everytime. It is not crazy like in starcraft where you had to add preserve trigger to every single trigger in order to stop it from self destructing.

It is not that important until you start using waits in triggers.

JASS:

nativeTriggerSleepActiontakesrealdelayreturnsnothing

IS the function to make triggers wait some time before continuing, there is also PolledWait which makes sure to wait game-time seconds, but it internally uses TriggerSleepACtion

Let's say a trigger has something called [i]thread[i]. I won't explain directly what a thread is, mostly because I don't know either. I think the word thread is a metaphore like most of the programming world's words.

What TriggerSleepAction does is stop the trigger's thread, then look for other pending threads, in case one of the pending thread check if the thread's sleep time has ended continue on that thread's actions till the thread sleeps again , passes execution to another thread or ends. And so and so till all other threads are sleeping or finished and the trigger's thread's sleeping time has ended.

For the moment we will try a little experiment with waits. Let's make a trigger that shows numbers from 1 to 50 each time a unit casts a spell. To make it more interesting it will not only show a number but also the unit's name. We will wait 0.1 seconds before showing a new message.

Place 2 units of different unit types and able to cast spells in the map. Test the map and make one cast a spell then the other one should do so. The result is predictible it will show something like this:
archmage 1
bloodmage 1
archmage 2
bloodmage 2
archmage 3
bloodmage 3
...

Have fun and try with 3 or more units.

As you can see different instances of the same trigger execute simultaneously, GetTriggerUnit() behaves differently depending on the instance.

Note that if you were using a global variable instead of that i local variable the result would have been much different. This time create an i variable with the variable editor so it is a global:

The same variable will be used by all the instances of the trigger, so it will show the numbers from 1 to 50 but the units will be different and it will show each number once.

It is a problematic topic cause how would you have values that work in different functions but are not that global and work well for each instance? That is a problem for a tutorial about handle variables or attacheable variables.

TriggerExecute
Events are not required by a trigger to be executed. You can use other triggers or timers or the main function to execute a trigger from it.

The function we use to do so is TriggerExecute:

JASS:

nativeTriggerExecutetakestriggerwhichTriggerreturnsnothing

We are going to join the strange world of Executing trigger. But first we need 2 triggers instead of just one. Let's make a very simple trigger that shows an "Another trigger" message.

The original trigger has to be fixed too, we will use the global variable for the new trigger instead of the one we are using right now, because in order to execute a trigger you need to have a pointer to that trigger, which would most of the times be in the form of a variable.

- Step 1: Make the first trigger use a local instead of the global variable.

Set to null? That is a needed step. To be short all local variables of types derived from handle have to set to null once their use in a function has ended, otherwise they leak memory somehow. Take a look to the top of common.j all the types that have extends handle in their declaration are handle derived types. (In this case it is not a needed step because it is little memory that leaks just once, but setting things to null is a habit I built after using JASS for a long time=)

- Step 2: Add the new trigger, assign it to the global gg_trg_testtrig variable.

First thing to note: It doesn't matter that the ToExecute function is bellow the function that executes the trigger. Cause the function that adds the action to the trigger is bellow the function already.

This lame example will just show "another trigger" each time a unit casts a spell.

Note that although the t variable is local, the Trigger object persists once the function stops, this is because handle derived variables are always pointers (they hold references to objects instead of objects themselves) .

Threads and TriggerExecute
Every time a trigger is executed it creates a new thread for that instance. So TriggerExecute does create its own thread. The next example is a typical one I must have used 15 times already to explain how TriggerExecute creates a thread. I am going to use BJDebugMsg for the text.

- The first line that gets execute is BJDebugMsg("A")
- TriggerExecute(gg_trg_testtrig) makes it go to the trigger object which will call the ToExecute function with another thread. TriggerExecute changes the thread to the other trigger's one until that thread sleeps or ends, then goes back to the thread that called it.
- Because we are in the second trigger's thread now the next call is BJDebugMsg("D")
- Now it calls TriggerSleepAction(2) , this means this thread will sleep for 2 seconds. Since second trigger's thread is sleeping warcraft III will go back to the previous thread, and continue moving on.
- BJDebugMsg("B") is the line now, it will show B
- TriggerSleepAction(4) - Make the thread sleep for 4 seconds.
- warcraft III will now keep looking for threads that can be executed. Eventually - more than 2 seconds later depending on the number of threads that were pending - will get back to second trigger's thread and call BJDebugMsg("E") .
- The thread will be finished after that and warcraft III will look for threads that could continue, 2 seconds later it wil find the first trigger's thread..
- call BJDebugMsg("C")

Conditions and TriggerExecute
First thing you would note after using TriggerExecute for a long time is that it ignores conditions. This is because conditions were meant for events.

But you can make sure it evaluates conditions before executing the trigger.

This is done by a native function TriggerEvaluate:

JASS:

nativeTriggerEvaluatetakestriggerwhichTriggerreturnsboolean

This function calls the trigger's condition and returns the value the condition returned. (if no condition is present it returns true automatically).

Of course it could be kind of redundant to always check the condition so you can use this bj function:

GetTriggerEvalCount returns the number of times the trigger's condition was evaluated. GetTriggerExecCount returns the number of times a trigger was executed.

If you are not using things like TriggerExecute / ConditionalTriggerExecute or TriggerEvaluate on that trigger then GetTriggerEvalCount would return the number of times an event registered for the trigger has happened. And GetTriggerExecCount would return the number of times an event registered for the trigger has happened AND was validated by the trigger's condition.

A sample would be counting the number of times units casted an ability. We would need a trigger that shows the number of times when you press escape and another trigger that has that event registered.

Dynamic triggers
You already know a lot about triggers. But since you are using JASS you should know how to use one of its greatest advantages over just using GUI to make your scripts.

You can create / destroy triggers in game. But I will get into this topic later in another tutorial, because to make it work perfectly without leaks you better get into some gamecache+return bug usage. I think you can actually go on alone from now

Regarding memory leak prevention on triggers you dynamically create and destroy: you use the TriggerRemoveAction(), but does that actually destroy the triggeraction object or just de-link it from a trigger? How about event objects, you don't destroy those at all, is there no function to do that?

At least the boolexprs have a way of destroying them, but sadly they're the least used element of a trigger.

when InitTrig_testtrig is run on the map initialization you have create trigger t
then set t = null that mean on the map initialization finish runing your t = null
but when i use spell the message is display!! how it can display when t = null??

t is not the trigger - t is the pointer TO the trigger. Think of it as a name in a register. If you remove the name from the register (nullifying it), you save space in the register, but do you remove (destroy) the actual object (ie: the person which the name belongs to, or in this case the trigger)?

DistroyTrigger(t) takes the trigger which the variable points to, and then destroys the object. This cannot be done if the pointer (the variable) has been nullified.

But if you have for example an event EVENT_PLAYER_UNIT_SPELL_EFFECT, and you have a condition Casting unit equals to Blood Mage 000 <gen>, how will TriggerEvaluate work if the event didn't fire, so Casting unit doesn't exist?