Triggers - Efficient Triggering

Tutorial By Mythic Fr0st

Just before I do anything else, I would like to say, before looking at any triggers, read Adding Events By Triggers And Loading Units Into An Array
I would also like you to take note of these things:
Any trigger that has events added from another trigger, will have (Added From Another Trigger) in the place an event usually goes.

You will need to make variables, when I tell you to make them,
it will be in this type of format
Variables:
(Name, Type, Array, Value)

Example A:
Variables:
TmpStr, String

I did not specify an array, or a value, which means I do not want you to edit them, by default a variable is not an array, and a value is Null or 0, therefore when you see no array or value specification, do not change them.

I would also like you to know that, often in these codes, I will have in my code (when using arrays, and usually at the start of the trigger,
mostly for hero based triggers etc..)

Variables
Pn, Integer

Set Pn = Player Number Of Owner Of Triggering Unit
Obviously Owner Of Triggering Unit part will change based on the event...
In that case the event would have to be A unit dies, Or an event that triggering unit can be used in.


Also any where I put a * (asterisk symbol), I want you to enter nothing (Or if the game won't let you, enter one space)





Index
Newbie Section
Events
Conditions
Actions
Variables
Custom Script
Tips/Advice

Triggers
Adding Events By Triggers
Loading Units Into An Array
Name Spoofer
Ice Slide
Terrain Kill
Shroom World Revive System
Jumping By Footswitch
Terrain Deformation





Events
Basically, in the game, anytime something happens, an event occurs, I will use the A unit dies event for an example.

Whenever a unit dies, the game checks through all triggers, to see if any of them have an event that says A unit dies, once it finds a trigger (maybe more than one) that has that event, it will then check the conditions inside that trigger.

Conditions
If the conditions allow the event to preceed, it will then check the actions, and perform them...

So simply put if you have an event such as this

MyExampleTrigger1 Events - A unit dies Conditions - Dying unit is owned by player 1 red Actions

The condition basically filters out all the stuff you do not want to happen, so in this example, I am checking to see if the dying unit was owned by player 1 red, if so, it will run the actions below, otherwise, it will not.

Actions
Once an event occurs, and the condition allows the event to preceed,
It will perform all actions below...

An action, does something in the game, such as increasing a players amount of money, or moving a unit, killing a unit, reviving a hero, and so forth.

You use them to manipulate objects in the game, such as money, tree's, unit's, hero's, and so on, thats basically it.


Variables
A variable is something that stores data,
this data can be accessed at a later time if not overwritten.

The point of a variable is to store data,
which you can retrieve at a later date, in most situations, certain data you want to store, can not be retrieved at a later time, without storing it in a variable.

(In this example, we will store the name of player 2 blue, and show it to player 1 red when any of his unit's die)

Variables
LastChatMsgFromPlayer1, String

MyExampleTrigger2 Events - Player 1 red types a chat message containing "*" As a substring Conditions Actions - Set LastChatMsgFromPlayer1 = Entered Chat String


MyExampleTrigger3 Events - A unit owned by player 1 red dies Conditions Actions - Display to all players the text LastChatMsgFromPlayer1

Obviously, when a unit from player 1 red dies, you can not show what he last said without a variable, (because you can not use the correct event for it)

This example will probably never be used in any code by anyone, but it is just to show you what a variable can be used to do.

A Variable Array

An array, I like to think of it as an almost unlimited amount of one variable,
firstly, an index, which references that specific variable array,
when you edit a variable array, you can see it requires an index, the index is an integer (or number).

The highest array index for a variable in warcraft is about 8000 (Do not go further than this)

Also note that an array's index starts at 0
Example:

Variables
MyStringArray, String, Array 1

Set MyStringArray[0] = "Hello Part 1"
Set MyStringArray[1] = "Hello Part 2"

The index (The number in the [ ] brackets) basically is an identifier, so instead of making hundreds of variables, you can make one, with an index of one hundred, which saves alot of time, when you create them in the variable editor, and also indexes have uses for other (more advanced) purposes

If you make a trigger like this
MyExampleTrigger5 Events - Map Initilization Conditions Actions Set MyStringArray[0] = "Hello Part 1" Display to all players the text MyStringArray[0] Set MyStringArray[1] = "Hello Part 2" Display to all players the text MyStringArray[1]

They will display different strings, if you do this in your trigger:
(The error highlighted in red)

MyExampleTrigger5 Events - Map Initilization Conditions Actions Set MyStringArray[0] = "Hello Part 1" Display to all players the text MyStringArray[0] Set MyStringArray[1] = "Hello Part 2" Set MyStringArray[1] = "Hello Part 3" Display to all players the text MyStringArray[1]

You will only see "Hello Part 1", and "Hello Part 3" show, since setting MyStringArray[1] = "Hello Part 3" after you set MyStringArray[1] = "Hello Part 2", it erased it,

If your asking why MyStringArray[0] did not get erased, that is because the index number is different, MyStringArray[0] has the index number 0, MyStringArray[1] has the index number 1,

I will also point out, the index number does not actually matter, long as you declare an index number of atleast 1, you can reference and use
MyStringArray[500], even if you only set the index to 1...

So you can see now, why array's are useful in variables.

Custom Script
Custom Script is also know as Jass, it is a (very lame) programming language, however it is all you have to program with, anything made with the GUI part of the World Editor (GUI is Graphical User Interface), converts to jass...

Some reason, blizzard did not leave us a way to clean memory leaks.. so we have to use the action Custom Script.

You can find this action near the very top of the actions list...
I recommend you read a jass tutorial, and memory leak tutorial for more information, however I will give an example

Variables
MyPoint, Point


Create a region on the map called Region1
MyExampleTrigger6 Events - Map Initilization Conditions Actions - Set MyPoint = Center of Region1

This creates a memory leak, a memory leak is basically when you set some data to something, and you do not remove it, in this example, we have used a point...

Memory leaks occur when you use a variable, to reference one of the below
or you reference one of the below without making a variable (which the variable allows you to clean it up): (Only the major ones, listed from worst to least worst)

• Special Effects
• Points
• Unit Groups
• Player Groups

Things that cannot leak: (Only some)

• Integers
• Strings
• Booleans
• Units


Back to our example
To fix this leak, we must add the line in red
MyExampleTrigger6 Events - Map Initilization Conditions Actions - Set MyPoint = Center of Region1 - call RemoveLocation(udg_MyPoint)

Now, you must only remove a variable (Such as above) when you are done with it, do not delete it while you are still using it...

call RemoveLocation(udg_MyPoint) is text I have written, to do this
Go to the actions section, and look for the name "Custom Script" and select that and type that in

Custom Script (Also know as jass) is caps sensitive you must ALWAYS use the exact name of your variable including capitals

In Custom Script udg_MyPoint is not the same as udg_MyPOint

I will also point out what udg is,
udg stands for User Defined Global, which is a global variable,
a global variable can be used and referenced in all triggers you make...

there is also another type of variable (used in jass) which is called a local variable, which can only be used in the trigger it is created in
(read a jass tutorial for more information)

thats basically it.

Tips
I would like to tell you some things I learnt while using the World Editor
In the action section there is an action called If Then Else

You should use in its place If Then Else Multiple Actions

Also in the actions section, there is an action called Pick every unit in unit group and do actions

You should use in its place Pick every unit in unit group and do multiple actions

Also in the actions section, there is an action called Pick every player in player group and do actions

You should use in its place Pick every player in player group and do multiple actions

They are basic, but are useful to know when first starting.


Adding Events By Trigger
Variables
None

Adding Events By Trigger Events Map initialization Conditions Actions - Pick every player in (All players) and do (Actions) Loop - Actions - Add to Name Spoofer <gen> the event (Player - (Picked player) types a chat message containing -name as A substring)

Name Spoofer
Variables
None

Name Spoofer Events (Event added by trigger) Conditions Actions If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Length of (Substring((Entered chat string), 6, (Length of (Entered chat string))))) Less than or equal to 20 Then - Actions - Set name of (Triggering player) to (Substring((Entered chat string), 6, (Length of (Entered chat string)))) Else - Actions

The event Triggering player, will reference the player who typed the chat message.

A substring, gets a part of a string, for example
substring("Hello" 3, 3) would be "l" 3,4 would be "ll", 3,5 would be "llo"
substring("Hello",1, 5) would be "hello", 2,5 would be "Ello"

it is fairly simple.

Loading Units Into An Array
Variables
Unit, unit, array 1
Events Map initialization Conditions Actions Set Unit[1] = Mythic Fr0st 0016 <gen> Set Unit[2] = Mythic Fr0st 0017 <gen> Set Unit[3] = Mythic Fr0st 0018 <gen> Set Unit[4] = Mythic Fr0st 0019 <gen> Set Unit[5] = Mythic Fr0st 0020 <gen> Set Unit[6] = Mythic Fr0st 0021 <gen> Set Unit[7] = Mythic Fr0st 0022 <gen> Set Unit[8] = Mythic Fr0st 0023 <gen> Set Unit[9] = Mythic Fr0st 0024 <gen> Set Unit[10] = Mythic Fr0st 0025 <gen> Set Unit[11] = Mythic Fr0st 0026 <gen> Set Unit[12] = Mythic Fr0st 0027 <gen>

Doing this is very good, it is usable (and necessary) in almost all maps...
If you think that Mythic Fr0st 0016 is owned by player 1 red,
and that Mythic Fr0st 0017 is owned by player 2 blue,
then in more advanced code it is very easy to manipulate the players characters (code examples of this, are below)


Ice Slide
(This requires you've read, and setup the code "Loading Units Into An Array" as one of your triggers)
Variables

• Loc, point, array 1
• Unit, unit, array 1

Events Time - Every 0.03 seconds of game time Conditions Actions For each (Integer A) from 1 to 12, do (Actions) Loop - Actions Set Loc[1] = (Position of Unit[(Integer A)]) If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions [SIZE="1"] (Terrain type at Loc[1]) Equal to Icecrown Glacier - Ice Then - Actions Set Loc[2] = (Loc[1] offset by 13.00 towards (Facing of Unit[(Integer A)]) degrees) Move Unit[(Integer A)] instantly to Loc[2] Custom script: call RemoveLocation(udg_Loc[2]) Else - Actions Custom script: call RemoveLocation(udg_Loc[1])

Ice Turn
Variables

• Loc, Point, Array 1

[Generic Unit Event]
Events A unit Is issued an order targeting a point Conditions Actions Set Loc[3] = (Position of (Triggering unit)) If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Terrain type at Loc[3]) Equal to Icecrown Glacier - Ice Then - Actions Make (Triggering unit) face (Target point of issued order) over 0.00 seconds Else - Actions Custom script: call RemoveLocation(udg_Loc[3])

Wisp Wheel
(This requires you load all your wisps you want to spin, into an array called Unit, (Read "Loading Units Into An Array"))
(Note you will have to create regions for the area you want the wisps to spin around, I've used Rect 017, and Rect 000 as mine)
Variables

• Loc, point, array 1
• Unit, unit, array 1
• Angle, real, array 1

[Periodic Event]
Events Every 0.05 seconds of game time Conditions Actions Set Loc[4] = (Center of Rect 017 <gen>) For each (Integer A) from 1 to 3, do (Actions) Loop - Actions Set Loc[5] = (Center of Rect 000 <gen>) Set Loc[6] = (Loc[4] offset by 300.00 towards Angle[(Integer A)] degrees) Set Angle[(Integer A)] = (Angle[(Integer A)] + 1.00) Move Unit[(Integer A)] instantly to Loc[5] Custom script: call RemoveLocation(udg_Loc[4]) Custom script: call RemoveLocation(udg_Loc[5])
Custom script: call RemoveLocation(udg_Loc[6])[/CODE]


Terrain Kill
(You need to have stored all your heroes / units into an array called "Unit" for this (Read "Loading Units Into An Array"))
Variables

• Loc, point, Array 1
• Unit, unit, array 1

Events Every 0.12 seconds of game time Conditions Actions For each (Integer A) from 1 to 12, do (Actions) Loop - Actions Set Loc[7] = (Position of Unit[(Integer A)]) If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Terrain type at Loc[7]) Equal to Icecrown Glacier - Rough Dirt Then - Actions Kill Unit[(Integer A)] Else - Actions Custom script: call RemoveLocation(udg_Loc[7])


Shroom World Revival System
(You need to have loaded your heroes into an array called "Unit for this" (Read "Loading Units Into An Array"))
Note
In order for this to work, you must have 12 revive circles, on the map somewhere, place them so they're ALL owned by player 12 brown...
Part 1:
Variables

• i, integer, no array
• ReviveCircles, unit, array 1
• StartingPointRevives, point, array 1

Load Revive Circles
Events Map initialization Conditions Actions Set i = 0 Unit Group - Pick every unit in (Units of type Revive) and do (Actions) Loop - Actions Set i = (i + 1) Set ReviveCircles[i] = (Picked unit) Change ownership of ReviveCircles[i] to (Player(i)) and Change color Set StartingPointRevives[i] = (Position of (Picked unit)) Hide ReviveCircles[i]

Part 2:
Variables

• ReviveUnitLoc, Point, Array 1
• Pn, Integer

Move to Body
Events A unit Dies Conditions Actions Set Pn = Player Number Of Owner Of Triggering Unit For each (Integer A) from 1 to 11, do (Actions) Loop - Actions If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Unit-type of (Triggering unit)) Equal to (Your_Unit_Here) Then - Actions Set ReviveUnitLoc[0] = (Position of (Triggering unit)) Move ReviveCircles[Pn] instantly to ReviveUnitLoc[0] Unhide ReviveCircles[Pn] Custom script: call RemoveLocation(udg_ReviveUnitLoc[0]) Else - Actions

Part 3:
Variables

• ReviveUnitLoc, Point, Array 1

Revive
Events Every 0.03 seconds of game time Conditions Actions For each (Integer A) from 1 to 11, do (Actions) Loop - Actions Set ReviveUnitLoc[2] = (Position of ReviveCircles[(Integer A)]) Unit Group - Pick every unit in (Units within 50.00 of ReviveUnitLoc[2]) and do (Actions) Loop - Actions If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Unit-type of (Picked unit)) Not equal to ReviveCircle (Unit-type of (Picked unit)) Equal to Your_Unit_Here (Unit Being the mazer) ((Picked unit) is alive) Equal to True Then - Actions Set ReviveUnitLoc[1] = (Position of (Picked unit)) For each (Integer B) from 1 to 11, do (Actions) Loop - Actions If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Distance between ReviveUnitLoc[1] and ReviveUnitLoc[2]) Less than or equal to 50.00 Then - Actions Instantly revive Unit[(Integer B)] at ReviveUnitLoc[1], Hide revival graphics Move ReviveCircles[(Integer B)] instantly to StartingPointRevives[(Integer B)] Hide ReviveCircles[(Integer B)] Else - Actions Custom script: call RemoveLocation(udg_ReviveUnitLoc[2]) Custom script: call RemoveLocation(udg_ReviveUnitLoc[1]) Else - Actions



Jump
Variables

• x, integer, array 1
• Loc, point, array 1
• Hero_Jumper, unit, array 1
• Trampaline_Unit, unit, array 1
• Slide_Group, unit group, no array
• PN, integer, no array

Total Parts 5:
Part 1:
Jump Initilize

Jump Initilize Events Map initialization Conditions Actions Disable fog of war Disable black mask Set Hero_Jumper[1] = Hero Of Your Map 0001 <gen> Set Trampaline_Unit[1] = Trampaline 0000 <gen> For each (Integer A) from 1 to 1, do (Actions) Loop - Actions Make Trampaline_Unit[Integer A] face 270.00 over 0.00 seconds Add to Jump Effect <gen> the event (Unit - A unit comes within 75.00 of Trampaline_Unit[(Integer A)])


Part 2:
Jump Effect
Events (Added from Jump Initilize) Conditions ((Triggering unit) is in Slide_Group) Equal to False (Unit-type of (Triggering unit)) Equal to Hero Of Your Map Actions Add (Triggering unit) to Slide_Group Set PN = (Player number of (Owner of (Triggering unit))) Disable Crow Form for (Owner of (Triggering unit)) Add Crow Form to (Triggering unit) Change (Triggering unit) flying height to 270.00 at 300.00 Wait 1.00 seconds Change (Triggering unit) flying height to 1.00 at 200.00 Wait 1.00 seconds Remove Crow Form from (Triggering unit) Remove (Triggering unit) from Slide_Group

Part 3:
Jump Slide
Events Every 0.03 seconds of game time Conditions Actions For each (Integer A) from 1 to 12, do (Actions) Loop - Actions -------- 1-12, for all players -------- If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions ((Player((Integer A))) slot status) Equal to Is playing Then - Actions If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Hero_Jumper[(Integer A)] is in Slide_Group) Equal to True Then - Actions Set Loc[0] = (Position of Hero_Jumper[(Integer A)]) Set Loc[1] = (Loc[0] offset by 13.00 towards (Facing of Hero_Jumper[(Integer A)]) degrees) -------- 13 offset, being the speed -------- Move Hero_Jumper[(Integer A)] instantly to Loc[1] Custom script: call RemoveLocation(udg_Loc[0]) Custom script: call RemoveLocation(udg_Loc[1]) Else - Actions Else - Actions

Part 4:
Jump Mid Air Turn
Events Unit - A unit Is issued an order targeting a point Conditions ((Triggering unit) is in Slide_Group) Equal to True Actions Make (Triggering unit) face (Target point of issued order) over 0.00 seconds

Part 5:
Jump Safety
Events Unit - A unit Dies Conditions ((Triggering unit) is in Slide_Group) Equal to True Actions Change (Triggering unit) flying height to 1.00 at 956262784.00 Remove (Triggering unit) from Slide_Group

Voila

Note
To stop your unit from dying going over terrain when you are using the terrain kill trigger, add to the condition of your Terrain Kill Trigger (Assuming you have mine, or something exactly like it)Hero_Jump[Integer A] is in Slide_Group equal to false, and you will be fine


Basic Terrain Deformation
Variables Required

• Loc, point, array 1
• Unit, unit, array 1 (From Loading units into an array)


Events Every 0.03 seconds of game time Conditions Actions For each (Integer A) from 1 to 12, do (Actions) Loop - Actions Set Loc[0] = (Position of Unit[(Integer A)]) If (All Conditions are True) then do (Then Actions) else do (Else Actions) If - Conditions (Terrain type at Loc[0]) Equal to Lordaeron Summer - Grass Then - Actions Create a 0.20 second Temporary crater deformation at Loc[0] with radius 125.00 and depth 40.00 Else - Actions Custom script: call RemoveLocation(udg_Loc[0])


I hope this helps you in some way, as this has taken me 3 hours to revise...

I no longer have the world editor on my computer, therefore, I had to make edits to some code, without it, therefore there may be some minor errors, if you find any, please tell me

If anyone has an idea, for something I should add, please post, and I may do so

Cheers all!

If anyone has questions Ask Icyculyr (My other user)

Updated Sunday 15th of July 2007.

Click here to comment on this tutorial.
 
 
Blizzard Entertainment, Inc.
Silkroad Online Forums
Team Griffonrawl Trains Muay Thai and MMA fighters in Ohio.
Apex Steel Pipe - Buys and sells Steel Pipe.