It appears to me that a timer is used to call a function after a certain delay, which is however set to 0.
This is a common technique and I can see why it is confusing. A 0 second delay makes no sense usually.
Let's say you have two triggers:
-
Kill 1
-

Events
-

Conditions
-

Actions
-


Player - Add 10 to Player 1 (Red) Current gold
-
Kill 2
-

Events
-

Conditions
-

Actions
-


Player - Add 10 to Player 2 (Red) Current gold
Both will be triggered by the same event, so they will happen at the same time (within 0 seconds). However they will run sequentially, so one will run first after that the other will run.
If you use a 0 second delay on one of many triggers that happen within 0 seconds, it will start after all triggers without the delay. So the 0 second delay lets you control in which order some triggers run, if they are at the same time.
In warcraft 3 most events are triggered, before they actually happen.
In our case we detect, when an order is given.
1. player gives order
2. event fires
3. unit executes order
0. Priest currently has autocast on
1. Player deactivates heal autocast (healoff)
2. event is fired
now we check, if "healon" can be used. Healon can only be used, if heal autocast is deactivated (you can't activate it, if it's already activated)
we get, that heal autocast is activated (because the order was not eexecuted yet) - that's not what we want, because we just deactivated it
3. now Priest has autocast off
Solution:
0. Priest currently has autocast on
1. Player deactivates heal autocast (healoff)
2. event is fired
wait 0 seconds
3. now Priest has autocast off
now we check and get what we expected
So basically we delay the trigger, so it runs after 3.
the two local timer t, how are they related? My understanding is that the fact that they're local restricts them to the block where they are written. However, they're used to save and load what seems to be the same unit to/from the table hash. Must be the same thing then, but how? Mind explaining this to me?
There are two types of variables:
primitive variables : integer, string, real, boolean, probably some more
handles (reference varaible, pointer) : anything else: units, points, regions, unit groups, hashtables, timers ...
Handles just point towards an object. They are not the object itself. For example a unit variable is no unit, but just points towards a unit. Destroying the variable won't kill the unit.
All handles have explicit create and destroy functions. CreateTimer, DestroyTimer, CreateGroup, DestroyGroup, Location, RemoveLocation, CreateUnit, RemoveUnit
Unit is special, because it can also be created/removed without the trigger editor (training/summoning a unit, kill -> decay)
A local variable only exists within one function, that's correct. But if a local unit variable no longer exists, the unit won't die. It's the same for timers. The local variable no longer exists, but the timer still exists. You can get the timer in the other function by using GetExpiredTimer().
The hashtable attaches data to the timer, so we have access to the unit in a different function, where GetTriggerUnit() does no longer work.
while having the trigger disabled, this runs.
If I don't disable the trigger, there will be an infinte loop.
Event: order is issued
Action: issue order
the if(IssueImmediateOrder( u,"healon")) returns true if the heal autocast is able to be ordered <-> the heal autocast is off. Why then is it necessary to call IssueImmediateOrder( u, "healoff" )?
It not only returns true, it also gives the order and we need to revert it.
Lastly, how does this all run during the situation of a stunned caster? Is the applied delay a solution to the stun "order blockage"?
It is all just because of the return value.
It will say ON, if you cannot use "healon" else it will say OFF. You can't use "healon", only if it is already activated. So this solution can directly detect whether autocast is on or off, so it's 100% safe and stun does not matter.
Here is the problem with stun explained, if you use a simple apporach.
A unit is ordered "healon"
-> set VariableAutocast = true
A unit is ordered "healoff"
-> set VariableAutocast= false
unit is stunned, autocast is off:
player toggles autocast several times (allare healon, because unit is stunned)
"healon" -> true, but autocast still off, because of stun
"healon" -> true, but autocast still off, because of stun
...
player uses stop (or any other order)
"stop" ->still true, but autocast still off, because of stun
unit no longer stunned. Last order will be executed (stop)
now autocast is still off, but variable is set to true
So it will cause problem whenever you toggle autocast while stunned, but give a different order to the unit afterwards.