[Solved] I need this system for many of my triggers [Mui timer OR wait]

Status
Not open for further replies.
Level 18
Joined
Jun 2, 2009
Messages
1,233
As the title says. I have many triggers duplicated for 10 players and i don't have a wish to create for new one. I have a lot of timers and unit groups just like this.
I just want to add units to specific groups for a few seconds and remove them from these groups OR timers.

I need this template badly.

--- Example request ---

  • Events
    • Unit - A unit Is attacked
  • Conditions
    • ((Triggering unit) is in ExampleGroup) Equal to False
  • Actions
    • Unit Group - Add (Triggering unit) to ExampleGroup
    • Wait 3.00 seconds
    • Unit Group - Remove (Triggering unit) from ExampleGroup
    • -------- And prevent them to adding the same group for few seconds IF possible --------
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
That trigger works fine since (Triggering unit) is treated like a local variable.

But the idea of looping over a Unit Group every time a unit is attacked sounds awful.

Instead, you could use a Unit Indexer or Hashtable to track which groups a unit is in.
  • Conditions
    • IsInExampleGroup[Custom value of (Triggering unit)] Equal to False
IsInExampleGroup is a Boolean array variable using the Unit Indexing method. You would set this boolean to True when you add the unit to the unit group and set it to False when you remove it from the unit group.

Anyway, the solution in GUI requires locally created timers which need to be created using Custom Script. You then need to track these Timers and the Units/data involved with them in a Hashtable. I made a little system that should help make this far more convenient.

This could definitely be made better but I don't really care to learn how to write proper Jass code when Lua exists:
vJASS:
library GUISimpleTimers

globals
    hashtable GST_Hash = InitHashtable()
    timer GST_LoadedTimer
    integer GST_NewParentKey = 0
    integer GST_Index = 0
endglobals


// Used to destroy and clean up an expired repeating timer.
// The user must manually call this function:
function GST_DestroyTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call FlushChildHashtable(GST_Hash, GetHandleId(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction


// Used with the Key system to "restart" a timer.
// It destroys the previously created timer (if one is found).
// Then the new timer that was just created replaces it.
function GST_RestartTimer takes nothing returns nothing
    set GST_NewParentKey = (-1000000000 + (100000 * LoadInteger(GST_Hash, -1, GetHandleId(udg_GST_Trigger))))
    if (GST_NewParentKey != -1000000000) then
        // key already exists
        set GST_NewParentKey = GST_NewParentKey + udg_GST_ParentKey
    else
        // key doesn't exist, initialize it
        set GST_Index = GST_Index + 1
        set GST_NewParentKey = (-1000000000 + (100000 * GST_Index)) + udg_GST_ParentKey
        call SaveInteger(GST_Hash, -1, GetHandleId(udg_GST_Trigger), GST_Index)
    endif

    set GST_LoadedTimer = LoadTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey)

    // remove the old timer stored at these keys
    if (GST_LoadedTimer != null) then
        call PauseTimer(GST_LoadedTimer)
        call DestroyTimer(GST_LoadedTimer)
        call RemoveSavedInteger(GST_Hash, GST_NewParentKey, udg_GST_ChildKey)
    endif
endfunction


// Callback functions which run when a timer expires:
function GST_Int_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Integer2 = LoadInteger(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntIntInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 4)
    local boolean repeating = LoadBoolean(GST_Hash, id, 3)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Integer2 = LoadInteger(GST_Hash, id, 1)
    set udg_GST_Integer3 = LoadInteger(GST_Hash, id, 2)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Real_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_RealReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 0)
    set udg_GST_Real2 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Unit_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitUnit_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Unit2 = LoadUnitHandle(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Simple_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 0)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction


// Functions to start timers:
function GST_Real takes real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveReal(GST_Hash, id, 0, r1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Real_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_RealReal takes real r1, real r2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveReal(GST_Hash, id, 0, r1)
    call SaveReal(GST_Hash, id, 1, r2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_RealReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntReal takes integer i1, real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveReal(GST_Hash, id, 1, r1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_Int takes integer i1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Int_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntInt takes integer i1, integer i2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveInteger(GST_Hash, id, 1, i2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntIntInt takes integer i1, integer i2, integer i3, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveInteger(GST_Hash, id, 1, i2)
    call SaveInteger(GST_Hash, id, 2, i3)
    call SaveBoolean(GST_Hash, id, 3, repeating)
    call SaveTriggerHandle(GST_Hash, id, 4, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntIntInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitInt takes unit u1, integer i1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveInteger(GST_Hash, id, 1, i1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitReal takes unit u1, real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveReal(GST_Hash, id, 1, r1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitUnit takes unit u1, unit u2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveUnitHandle(GST_Hash, id, 1, u2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitUnit_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_Unit takes unit u1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Unit_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif

    // clean up memory leaks
    set t = null
endfunction

function GST_Simple takes boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveTriggerHandle(GST_Hash, id, 0, udg_GST_Trigger)
    call SaveBoolean(GST_Hash, id, 1, repeating)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Simple_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_ParentKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewParentKey, udg_GST_ChildKey, t)
        set udg_GST_ParentKey = -1
        set udg_GST_ChildKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

endlibrary
You would add that code to your map and then create the following variables:

Unit:
GST_Unit1
GST_Unit2

Integer:
GST_Integer1
GST_Integer2
GST_Integer3
GST_ParentKey (set initial value to -1)
GST_ChildKey (set initial value to -1)

Real:
GST_Real1
GST_Real2

Trigger:
GST_Trigger

Make sure the variables exist before saving the map. Once that's done you can use the system.

Here's an example of how to use it:
  • Example
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
      • Set SomeUnit = (Last created unit)
      • Unit Group - Add SomeUnit to SomeUnitGroup
      • -------- --------
      • -------- First, set this variable to the trigger that you want to run when the timer expires: --------
      • Set GST_Trigger = Example Expire <gen>
      • -------- --------
      • -------- Then tell the system to create a 3.00 second one-shot timer which will track SomeUnit: --------
      • Custom script: call GST_Unit(udg_SomeUnit, false, 3.00)
Here's the trigger that will run when the timer that we created in our last trigger expires:
  • Example Expire
    • Events
    • Conditions
    • Actions
      • -------- GST_Unit1 is set to the Unit used in your GST_Unit() function. So it's the Footman from before! --------
      • Unit Group - Remove GST_Unit1 from SomeUnitGroup
The system will automatically set GST_Unit1 to the Footman (SomeUnit) from before. This is because we told it to track that unit in the GST_Unit() function.
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
Thank you so much again. Now i have created variables and pasted the code. Is this system conflicts with UnitIndexer? Because everytime i am fixing bugs, creating new systems and new bugs appears.

Now i am checking the example but still i don't understand it yet. How can i add attacking unit to ExampleGroup and remove it within this group after 3 seconds? Still i don't understand with variables shoud i use. I just need 1 example. It doesn't look complicated but still i don't understand.

  • Kule aggro Copy
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • ((Triggering unit) is in ExampleGroup) Equal to False
    • Actions
      • Unit Group - Add (Triggering unit) to ExampleGroup
      • Wait 3.00 seconds
      • Unit Group - Remove (Triggering unit) from ExampleGroup
      • -------- And prevent them to adding the same group for few seconds IF possible --------
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
My example shows you how to do it, and no, it won't mess with the Unit Indexer. I'll never suggest something that doesn't work with a Unit Indexer.

But here's another example closer to exactly what you want:
  • Example
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • IsInExampleGroup[Custom value of (Attacked unit)] Equal to False
    • Actions
      • Set AttackedUnit = (Attacked unit)
      • Unit Group - Add AttackedUnit to ExampleGroup
      • Set IsInExampleGroup[Custom value of AttackedUnit] = True
      • Set GST_Trigger = Example Expire <gen>
      • Custom script: call GST_Unit(udg_AttackedUnit, false, 3.00)
Create another trigger which runs when the timer expires (this is what GST_Trigger references):
  • Example Expire
    • Events
    • Conditions
    • Actions
      • Custom script: local unit udg_AttackedUnit = udg_GST_Unit1
      • Unit Group - Remove AttackedUnit from ExampleGroup
      • Wait 3.00 game-time seconds
      • Set IsInExampleGroup[Custom value of AttackedUnit] = False
      • Custom script: set udg_AttackedUnit = null
AttackedUnit can be any Unit variable that you want. The variable is really only there to make things easier to setup.

I added the Custom Script stuff to the Example Expire trigger in order to make AttackedUnit act like a local variable.

You can read about this technique here: local udg_
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
Hello again @Uncle now i have created trigger

  • AggroCopy
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • AttackedUnitBL[(Custom value of AttackedUnit)] Equal to False
    • Actions
      • Set AttackedUnit = (Attacked unit)
      • Game - Display to (All players) for 1.00 seconds the text: (AttackedUnit set + (Name of (Attacked unit)))
      • Unit Group - Add AttackedUnit to ExampleGroup
      • Wait 3.00 seconds
      • Set AttackedUnitBL[(Custom value of AttackedUnit)] = True
      • Set GST_Trigger = AggroExpire <gen>
      • Custom script: call GST_Unit(udg_AttackedUnit, false, 3.00)
  • AggroExpire
    • Events
    • Conditions
    • Actions
      • Custom script: local unit udg_AttackedUnit = udg_GST_Unit1
      • Unit Group - Remove AttackedUnit from ExampleGroup
      • Game - Display to (All players) for 1.00 seconds the text: ((Name of AttackedUnit) + LEFT THE GROUP)
      • Wait 3.00 game-time seconds
      • Set AttackedUnitBL[(Custom value of AttackedUnit)] = False
      • Custom script: set udg_AttackedUnit = null
And put heroes from 2 teams in the same place for the testing purpose. But only it works for Mountain King. I was expecting units we're get removed from this group in order. That means it is not working now. Am i missing something?

And additionally i have created test map for the makes things easier for both of us. Check the attachment.
 

Attachments

  • 1.png
    1.png
    653.4 KB · Views: 8
  • 2.png
    2.png
    411.9 KB · Views: 9
  • newsystemtest.w3x
    46.1 KB · Views: 5
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
As you can see your first trigger is not like my first trigger.

This is what it should look like:
  • AggroCopy
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • AttackedUnitBL[(Custom value of (Attacked unit))] Equal to False
    • Actions
      • Set AttackedUnit = (Attacked unit)
      • Game - Display to (All players) for 1.00 seconds the text: (AttackedUnit set + (Name of AttackedUnit))
      • Unit Group - Add AttackedUnit to ExampleGroup
      • Set AttackedUnitBL[(Custom value of AttackedUnit)] = True
      • Set GST_Trigger = AggroExpire <gen>
      • Custom script: call GST_Unit(udg_AttackedUnit, false, 3.00)
I got rid of the Wait since that's not safe and defeats the whole purpose of the timer. I also fixed the Condition since it was checking AttackedUnit which hadn't been Set yet. You can't reference a variable that hasn't been set yet.

Your AggroExpire trigger looks good though.
 
Level 18
Joined
Jun 2, 2009
Messages
1,233
@Uncle Yes it seems i was misread Attacked Unit and AttackedUnit. This works fine and now i am trying to implement this with one of the timers like this but this works only once.
  • HoGAcquire
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set HogUserYeni = (Triggering unit)
      • Wait 1.00 game-time seconds
      • Hero - Modify Strength of HogUserYeni: Add 1
How can i make it loop?

  • HoGAcquire
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Helm of Gar'thok
    • Actions
      • Wait 0.50 seconds
      • Countdown Timer - Start Timer_HoG[(Player number of (Owner of (Hero manipulating item)))] as a Repeating timer that will expire in 60.00 seconds
      • Set User_HoG[(Player number of (Owner of (Hero manipulating item)))] = (Hero manipulating item)
  • HoG1
    • Events
      • Time - Timer_HoG[2] expires
    • Conditions
    • Actions
      • Hero - Modify Strength of User_HoG[2]: Add 1

That should gonna work but
  • HoGStat
    • Events
      • Unit - A unit Acquires an item
    • Conditions
    • Actions
      • Set HogUserYeni = (Triggering unit)
      • Set GST_Trigger = HoGStat Copy <gen>
  • HoGStat Copy
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
    • Actions
      • Hero - Modify Strength of HogUserYeni: Add 1
Each player should have the separate times. Besides this is not working. When i pick item from another hero, trigger stops for the first hero.
Still i am thinking and nothing comes up my mind because i don't understand how this system works and what kind of solution i need.

Item: When you pick this item, you will get +1 stat every 60 seconds.

Player 1 picks item at 05:10
Player 2 picks item at 05:20

Player 1 gets stat at 06:10
Player 2 gets stat at 06:20
"loops for every 60 seconds for specific players"
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
This will start a 60.00 second REPEATING timer (true) when a unit acquires the item:
  • HoGAcquire
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Helm of Gar'tho
    • Actions
      • Set AttackedUnit = (Triggering unit)
      • Set GST_Trigger = HoGExpire <gen>
      • Custom script: call GST_Unit(udg_AttackedUnit, true, 60.00)
Again, AttackedUnit is there to make things easier for you. You can name this variable whatever you want or use another existing variable. Just remember to change it's name in the Custom Script where it says "udg_AttackedUnit".

Then in our expire trigger which runs every 60.00 seconds we reference GST_Unit1 to get the unit that is linked to our timer:
  • HoGExpire
    • Events
    • Conditions
    • Actions
      • Hero - Modify Strength of GST_Unit1: Add 1



So my GST system comes with a bunch of different functions that you can use to store different things.

In the above examples we are linking a unit to the timer. Here are all of the options:
  • Custom script: call GST_Unit(unit, boolean, time)
  • Custom script: call GST_UnitUnit(unit, unit, boolean, time)
  • Custom script: call GST_UnitInt(unit, integer, boolean, time)
  • Custom script: call GST_UnitReal(unit, real, boolean, time)
  • Custom script: call GST_Int(integer, boolean, time)
  • Custom script: call GST_IntInt(integer, integer, boolean, time)
  • Custom script: call GST_IntIntInt(integer, integer, integer, boolean, time)
  • Custom script: call GST_Real(real, boolean, time)
  • Custom script: call GST_RealReal(real, real, boolean, time)
  • Custom script: call GST_Simple(boolean, time)
Inside of the () you need to type the name of the thing that you want to link to the timer. So for GST_Unit you need to put a Unit in there, for GST_Int you need to put an Integer, and for GST_UnitInt you need to put a Unit and then an Integer in that order. GST_Simple() doesn't link anything to your timer.

The boolean when set to false = One-shot timer. When it's set to true = Repeating timer.

The last thing you write in the () is the time, which is how long the timer lasts. Note how I used 3.00 seconds and 60.00 seconds in the other examples.

BUT before calling any of these functions you must first Set the GST_Trigger variable.

This should be equal to the trigger that you want your timer to run when it expires:
  • Set GST_Trigger = SomeTriggerExpire <gen>
This tells the timer to run that trigger when it expires.

Finally, inside of your Expire triggers you use the GST_ variables to interact with the things that you linked to the timer:
GST_Unit1 = The first unit in any of the GST_Unit() functions.
GST_Unit2 = The second unit in the GST_UnitUnit() function.
GST_Integer1 = The first integer in any of the GST_Int() functions.
GST_Integer2 = The second integer in any of the GST_Int() functions.
GST_Integer3 = The third integer in any of the GST_Int() functions.
GST_Real1 = The first real in any of the GST_Real() functions.
GST_Real2 = The second real in any of the GST_Real() functions.

If you ever want to stop a Repeating timer you need to call this function inside of that timer's Expire trigger:
  • Custom script: call GST_DestroyTimer()
This tells the GST system to destroy that repeating timer.

You can also restart a timer by using the GST_ParentKey and GST_ChildKey variables. This uses Hashtable logic and may be a bit confusing so you can worry about that later. Basically, you would Set GST_ParentKey to something like a unit's custom value or a player number and Set GST_ChildKey to a unique value that your other timers don't use.
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
You are amazing. Everything works well now. Now it is time to implement this changes in my map now. I am not tagging it as solved yet until final tests. Then i will let you know if anything happens. Thank you so much again @Uncle now i am going to delete many triggers for 10 different players :)
Can i use this AttackedUnit in any trigger or do i need another variable for different systems? In this test map it seems this variable works fine with my first trigger and this item thing

Wow you updated your message while i am posting. Thank you for this great explanation. Now i am going to get help from Google Translate. English is bit of difficult to me.
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
The AttackedUnit variable isn't doing anything special, it's just an ordinary Unit variable.

It's being used in the GST Custom Script:
  • Custom script: call GST_Unit(udg_AttackedUnit, )
We're telling the GST system to create a Timer and link it to whatever unit we've set AttackedUnit to.

If you used a different Unit variable then you would simply change the name of it in the Custom Script:
  • Events
    • Unit - A unit dies
  • Conditions
  • Actions
    • Set SomeUnitVar = (Dying unit)
    • Custom script: call GST_Unit(udg_SomeUnitVar, )
All that is important is that you put a Unit inside of the GST_Unit() function.

So it should be fine to reuse the variable. If you wanted to you could even use a GST variable instead:
  • Events
    • Unit - A unit dies
  • Conditions
  • Actions
    • Set GST_Unit1 = (Dying unit)
    • Custom script: call GST_Unit(udg_GST_Unit1, )
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
Understood. I mean it seems i can use this same variable in different triggers. By the way here is the cleaned and optimized trigger now.
I named this Variable as UncleTheBest and it always stays in my map forever.

  • StatItemsStart
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Item-type of (Item being manipulated)) Equal to Helm of Gar'thok
          • (Item-type of (Item being manipulated)) Equal to Helm of Ancients
          • (Item-type of (Item being manipulated)) Equal to Mind Staff
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set GST_Trigger = StatItems <gen>
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3)
  • StatItems
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (UncleTheBest has an item of type Helm of Gar'thok) Equal to True
        • Then - Actions
          • Hero - Modify Strength of GST_Unit1: Add 1
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (UncleTheBest has an item of type Helm of Ancients) Equal to True
        • Then - Actions
          • Hero - Modify Agility of GST_Unit1: Add 1
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (UncleTheBest has an item of type Mind Staff) Equal to True
        • Then - Actions
          • Hero - Modify Intelligence of GST_Unit1: Add 1
        • Else - Actions
Tomorrow i will test it with my friends. Set it as 3 for testing purpoose. Thank you again.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Note that the system creates a new Timer each time the unit acquires any of those items.

Also, the Timer isn't going to stop if the unit loses any of those items.

For this specific Item trigger it's a little tricky but you could do something like this:
  • StatItemsStart
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • HasStatItem[Player number of (Owner of (Triggering unit)) Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Item-type of (Item being manipulated)) Equal to Helm of Gar'thok
          • (Item-type of (Item being manipulated)) Equal to Helm of Ancients
          • (Item-type of (Item being manipulated)) Equal to Mind Staff
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set HasStatItem[Player number of (Owner of UncleTheBest)] = True
      • Set GST_Trigger = StatItems <gen>
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3)
  • StatItems
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Helm of Gar'thok) Equal to False
          • (GST_Unit1 has an item of type Helm of Ancients) Equal to False
          • (GST_Unit1 has an item of type Mind Staff) Equal to False
        • Then - Actions
          • Set HasStatItem[Player number of (Owner of GST_Unit1)] = False
          • Custom script: call GST_DestroyTimer()
          • Skip remaining actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Helm of Gar'thok) Equal to True
        • Then - Actions
          • Hero - Modify Strength of GST_Unit1: Add 1
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Helm of Ancients) Equal to True
        • Then - Actions
          • Hero - Modify Agility of GST_Unit1: Add 1
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Mind Staff) Equal to True
        • Then - Actions
          • Hero - Modify Intelligence of GST_Unit1: Add 1
        • Else - Actions
With this setup each Player will only be able to have 1 Stat Timer.

Also, remember that you need to reference GST_Unit1 in your Expire trigger. The GST system sets these GST_ variables for you and you MUST use them. The UncleTheBest variable could have changed in the last 60.00 seconds so it's not safe to use.

The GST_DestroyTimer() function is there to destroy the timer.

I'm doing this if the unit no longer has any of these items. This way if the unit loses the items the timer will eventually destroy itself. This isn't perfect since the unit may get the items back before the timer expires, allowing the timer to continue, but it's not that big of a deal.




Alternatively, the system offers a way to "restart" existing timers. You do this by using the GST_ParentKey and GST_ChildKey variables.

For example you could change StatItemsStart to use these Key variables so that it's restartable:
  • StatItemsStart
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • HasStatItem[Player number of (Owner of (Triggering unit)) Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Item-type of (Item being manipulated)) Equal to Helm of Gar'thok
          • (Item-type of (Item being manipulated)) Equal to Helm of Ancients
          • (Item-type of (Item being manipulated)) Equal to Mind Staff
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set HasStatItem[Player number of (Owner of UncleTheBest)] = True
      • Set GST_Trigger = StatItems <gen>
      • Set GST_ParentKey = Player number of (Owner of UncleTheBest)
      • Set GST_ChildKey = 0
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3)
Then create a new trigger. This will allow the StatItemsStart trigger to happen again since it's setting HasStatItem to False:
  • StatItemsStop
    • Events
      • Unit - A unit Loses an item
    • Conditions
      • HasStatItem[Player number of (Owner of (Triggering unit)) Equal to True
      • ((Triggering unit) has an item of type Helm of Gar'thok) Equal to False
      • ((Triggering unit) has an item of type Helm of Ancients) Equal to False
      • ((Triggering unit) has an item of type Mind Staff) Equal to False
    • Actions
      • Set HasStatItem[Player number of (Owner of (Triggering unit))] = False
Then if our unit gets the Items back again our timer will restart. If it's been destroyed it will start a new one instead.

Keep in mind that these GST_Key variables are being used to store the timer in a Hashtable. If you reuse the same exact Key values in another timer then you will run into issues.

All you really need to do is make sure that GST_ChildKey has a unique value for each Timer that it's being used with. So if you were to use this method for an entirely different Timer then you would change GST_ChildKey from 0 to some other value like 1. Then you would continue this pattern for each new Timer.
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
Thank you again. I was experimenting on the system and i found a bug. It is not a big deal actually because players have own only 1 Hero. It means this bug will never happens.

Red Paladin gets Claws: Starts to get Strength
Red Archmage gets Crown: Not works for Archmage

  • stattest
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • HasStatItem[(Player number of (Owner of (Triggering unit)))] Equal to False
      • Or - Any (Conditions) are true
        • Conditions
          • (Item-type of (Item being manipulated)) Equal to Claws of Attack +15
          • (Item-type of (Item being manipulated)) Equal to Crown of Kings +5
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set HasStatItem[(Player number of (Owner of UncleTheBest))] = True
      • Set GST_Trigger = statrun <gen>
      • Game - Display to (All players) for 1.00 seconds the text: (Name of UncleTheBest)
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3)
  • statrun
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Claws of Attack +15) Equal to False
          • (GST_Unit1 has an item of type Crown of Kings +5) Equal to False
        • Then - Actions
          • Set HasStatItem[(Player number of (Owner of GST_Unit1))] = False
          • Custom script: call GST_DestroyTimer()
          • Skip remaining actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Claws of Attack +15) Equal to True
        • Then - Actions
          • Hero - Modify Strength of GST_Unit1: Add 1
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (GST_Unit1 has an item of type Crown of Kings +5) Equal to True
        • Then - Actions
          • Hero - Modify Agility of GST_Unit1: Add 1
        • Else - Actions
Tonight we will play and probably i will set this post as solved. Thank you so much Uncle. Everything looks fine now.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Change HasStatItem to use Custom Value instead of Player Number. I assumed you only had 1 Hero per Player which is why I went with Player Number.

If you want something to work once for each Player then you use their Player Number in your array [index].

If you want something to work once for each Unit then you use their Custom Value in your array [index].

These are known as the Player Indexing and Unit Indexing methods.

Unit Indexing is only usable after importing a Unit Indexer into your map. Player Indexing is available by default since Blizzard already provides a unique Player Number for each Player.
 
Last edited:
Level 18
Joined
Jun 2, 2009
Messages
1,233
I have read the entire topic again, this time i was sure i was able to success. But not worked again.
Item runs trigger when user casts spell with x seconds cooldown.

  • CloakAriaPick
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Claws of Attack +15
      • ItemReady[(Player number of (Owner of (Triggering unit)))] Equal to False
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set ItemReady[(Player number of (Owner of UncleTheBest))] = True
      • Special Effect - Create a special effect attached to the weapon of UncleTheBest using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
      • Set YeniItemEffect[(Player number of (Owner of UncleTheBest))] = (Last created special effect)
  • CloakAriaCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (UncleTheBest has an item of type Claws of Attack +15) Equal to True
      • ItemReady[(Player number of (Owner of UncleTheBest))] Equal to True
      • ((Target unit of ability being cast) belongs to an enemy of (Owner of UncleTheBest)) Equal to True
      • ((Unit-type of (Target unit of ability being cast)) is A Hero) Equal to True
    • Actions
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing ((Life of (Target unit of ability being cast)) / 4.00) damage of attack type Chaos and damage type Unknown
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing 1000.00 damage of attack type Chaos and damage type Unknown
      • Set ItemReady[(Player number of (Owner of UncleTheBest))] = False
      • Special Effect - Destroy YeniItemEffect[(Player number of (Owner of UncleTheBest))]
      • Set GST_Trigger = cooldownend <gen>
      • Set GST_ParentKey = (Player number of (Owner of UncleTheBest))
      • Set GST_ChildKey = 0
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3.00)
  • cooldownend
    • Events
    • Conditions
    • Actions
      • Custom script: local unit udg_UncleTheBest = udg_GST_Unit1
      • Special Effect - Create a special effect attached to the weapon of GST_Unit1 using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
      • Set YeniItemEffect[(Player number of (Owner of GST_Unit1))] = (Last created special effect)
      • Set ItemReady[(Player number of (Owner of GST_Unit1))] = True
And stil i don't know why. I was looked the previous trigger and tried to do it like the other one. Yes it works but not works for all players. Still trying to detect issue. I don't exaggerate SINCE 40 MINUTES i did many tests. Still i don't understand. I am reading the trigger by myself but i don't understand the customscript parts.

It works on first run, deals bonus damage and effect removes. It is ok. But not works properly after first use. I have badly demoralized now. Still my capacity not enough to understand this. I don't want to come here and ask everything that i cannot do.

Update: I have changed last part like this. This time i have decided to check condition first. It looks fine but now it is not working for different players.

  • cooldownend
    • Events
    • Conditions
    • Actions
      • Custom script: local unit udg_UncleTheBest = udg_GST_Unit1
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ItemReady[(Player number of (Owner of GST_Unit1))] Equal to False
        • Then - Actions
          • Special Effect - Create a special effect attached to the weapon of GST_Unit1 using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
          • Set YeniItemEffect[(Player number of (Owner of GST_Unit1))] = (Last created special effect)
          • Set ItemReady[(Player number of (Owner of GST_Unit1))] = True
        • Else - Actions
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
You can't reference variables in your Conditions/Actions like this:
  • CloakAriaCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (UncleTheBest has an item of type Claws of Attack +15) Equal to True
      • ItemReady[(Player number of (Owner of UncleTheBest))] Equal to True
      • ((Target unit of ability being cast) belongs to an enemy of (Owner of UncleTheBest)) Equal to True
      • ((Unit-type of (Target unit of ability being cast)) is A Hero) Equal to True
    • Actions
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing ((Life of (Target unit of ability being cast)) / 4.00) damage of attack type Chaos and damage type Unknown
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing 1000.00 damage of attack type Chaos and damage type Unknown
      • Set ItemReady[(Player number of (Owner of UncleTheBest))] = False
      • Special Effect - Destroy YeniItemEffect[(Player number of (Owner of UncleTheBest))]
      • Set GST_Trigger = cooldownend <gen>
      • Set GST_ParentKey = (Player number of (Owner of UncleTheBest))
      • Set GST_ChildKey = 0
      • Custom script: call GST_Unit(udg_UncleTheBest, true, 3.00)
UncleTheBest is NOT set in this trigger. So when you're checking if UncleTheBest has a Claws of Attack +15, you're just hoping that the variable is set to the correct unit or even set at all. Remember, a variable can only have ONE value at a time.

Most of the time you should be referencing a variable inside of a trigger AFTER you Set it:
  • Set UncleTheBest = (Casting unit)
  • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing ((Life of (Target unit of ability being cast)) / 4.00) damage of attack type Chaos and damage type Unknown
Also, remember that the Boolean in the GST_Unit() function determines whether it's a One-shot or Repeating timer. You want a one-shot timer:
  • Custom script: call GST_Unit(udg_UncleTheBest, false, 3.00)
Also, you don't want to do this anymore:
  • Custom script: local unit udg_UncleTheBest = udg_GST_Unit1
This was only needed in the other trigger because it had a Wait action. When using Waits you create a gap of time in which the value of your variables can change to something else. This is what causes triggers to break and is what makes things NOT MUI or MPI. This custom script is a solution to that problem because it turns the global variable into a local variable. Local variables are MUI/MPI because they won't change. Global variables are NOT because they can change.

And like I said in my last post, if you want these triggers to work for any number of Units you need to use Unit Indexing not Player Indexing. Player Indexing only allows a trigger to work for each Player. Unit Indexing allows it to work for any number of Units.

Lastly, remember the rule for GST_ParentKey and GST_ChildKey. GST_ParentKey can use something like unit Custom Value if you want it to work for multiple units or you can use Player Number if you only need it to work for each Player.

GST_ChildKey needs a unique value that no other Timer is using. If this is your first time using GST_ChildKey then it's fine to keep it at 0. Just remember to give it a different value if you use it somewhere else. You're basically giving your Timer a special ID number that tells the GST system that it's different from other timers.[/trigger]
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
This should make the item work for any number of units:
  • CloakAriaPick
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Claws of Attack +15
      • ItemReady[(Custom value of (Triggering unit))] Equal to False
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Set ItemReady[(Custom value of UncleTheBest)] = True
      • Special Effect - Create a special effect attached to the weapon of UncleTheBest using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
      • Set YeniItemEffect[(Custom value of UncleTheBest)] = (Last created special effect)
  • CloakAriaCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • ((Triggering unit) has an item of type Claws of Attack +15) Equal to True
      • ItemReady[(Custom value of (Triggering unit))] Equal to True
      • ((Target unit of ability being cast) belongs to an enemy of (Owner of (Triggering unit)) Equal to True
      • ((Unit-type of (Target unit of ability being cast)) is A Hero) Equal to True
    • Actions
      • Set UncleTheBest = (Triggering unit)
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing ((Life of (Target unit of ability being cast)) / 4.00) damage of attack type Chaos and damage type Unknown
      • Unit - Cause UncleTheBest to damage (Target unit of ability being cast), dealing 1000.00 damage of attack type Chaos and damage type Unknown
      • Set ItemReady[(Custom value of UncleTheBest)] = False
      • Special Effect - Destroy YeniItemEffect[(Custom value of UncleTheBest)]
      • Set GST_Trigger = CloakAriaExpire <gen>
      • Set GST_ParentKey = (Custom value of UncleTheBest)
      • Set GST_ChildKey = 0
      • Custom script: call GST_Unit(udg_UncleTheBest, false, 3.00)
  • CloakAriaExpire
    • Events
    • Conditions
    • Actions
      • Special Effect - Create a special effect attached to the weapon of GST_Unit1 using Abilities\Spells\Orc\Bloodlust\BloodlustTarget.mdl
      • Set YeniItemEffect[(Custom value of GST_Unit1)] = (Last created special effect)
      • Set ItemReady[(Custom value of GST_Unit1)] = True
Note that the item won't stack though, so if you have 3 of these Claws you will still only be able to use this special ability once every 3.00 seconds.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
So I came up with a better version of this system. You no longer need GST_ChildKey and I added two more GST variables.
vJASS:
library GUISimpleTimers
// created by Uncle

globals
    hashtable GST_Hash = InitHashtable()
    timer GST_LoadedTimer
    integer GST_NewKey = 0
    integer GST_Index = 0
endglobals


// Call this function to destroy and clean up an expired repeating timer.
// Example: Custom script: call GST_DestroyTimer()
// You would call this inside of your GST_Trigger.
function GST_DestroyTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call FlushChildHashtable(GST_Hash, GetHandleId(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction


// Do NOT call this function yourself.
// This is used with the Key system to "restart" a timer.
// It destroys the previously created timer (if one is found).
// Then the new timer that was just created replaces it.
function GST_RestartTimer takes nothing returns nothing
    local integer trigId = GetHandleId(udg_GST_Trigger)
    set GST_NewKey = (-1000000000 + (100000 * LoadInteger(GST_Hash, -1, trigId)))
    if (GST_NewKey != -1000000000) then
        // key already exists
        set GST_NewKey = GST_NewKey + udg_GST_RestartKey
    else
        // key doesn't exist, initialize it
        set GST_Index = GST_Index + 1
        set GST_NewKey = (-1000000000 + (100000 * GST_Index)) + udg_GST_RestartKey
        call SaveInteger(GST_Hash, -1, trigId, GST_Index)
    endif

    set GST_LoadedTimer = LoadTimerHandle(GST_Hash, GST_NewKey, trigId)

    // remove the old timer stored at these keys
    if (GST_LoadedTimer != null) then
        call PauseTimer(GST_LoadedTimer)
        call DestroyTimer(GST_LoadedTimer)
        call RemoveSavedInteger(GST_Hash, GST_NewKey, trigId)
    endif
endfunction


// Callback functions which run when a timer expires:
function GST_Int_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Integer2 = LoadInteger(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntIntInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 4)
    local boolean repeating = LoadBoolean(GST_Hash, id, 3)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Integer2 = LoadInteger(GST_Hash, id, 1)
    set udg_GST_Integer3 = LoadInteger(GST_Hash, id, 2)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Real_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_RealReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 0)
    set udg_GST_Real2 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_RealRealReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 4)
    local boolean repeating = LoadBoolean(GST_Hash, id, 3)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 0)
    set udg_GST_Real2 = LoadReal(GST_Hash, id, 1)
    set udg_GST_Real2 = LoadReal(GST_Hash, id, 2)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_IntReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 0)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Unit_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 2)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitUnit_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Unit2 = LoadUnitHandle(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitUnitUnit_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 4)
    local boolean repeating = LoadBoolean(GST_Hash, id, 3)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Unit2 = LoadUnitHandle(GST_Hash, id, 1)
    set udg_GST_Unit3 = LoadUnitHandle(GST_Hash, id, 2)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitReal_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Real1 = LoadReal(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_UnitInt_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 3)
    local boolean repeating = LoadBoolean(GST_Hash, id, 2)
    set udg_GST_Unit1 = LoadUnitHandle(GST_Hash, id, 0)
    set udg_GST_Integer1 = LoadInteger(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction

function GST_Simple_Expire takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local trigger trig = LoadTriggerHandle(GST_Hash, id, 0)
    local boolean repeating = LoadBoolean(GST_Hash, id, 1)

    // run the GUI trigger
    call TriggerExecute(trig)

    // the timer is not repeating so destroy it
    if (repeating == false) then
        call FlushChildHashtable(GST_Hash, id)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    // clean up memory leaks
    set t = null
    set trig = null
endfunction


// Functions to start timers:
function GST_Real takes real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveReal(GST_Hash, id, 0, r1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Real_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_RealReal takes real r1, real r2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveReal(GST_Hash, id, 0, r1)
    call SaveReal(GST_Hash, id, 1, r2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_RealReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_RealRealReal takes real r1, real r2, real r3, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveReal(GST_Hash, id, 0, r1)
    call SaveReal(GST_Hash, id, 1, r2)
    call SaveReal(GST_Hash, id, 2, r3)
    call SaveBoolean(GST_Hash, id, 3, repeating)
    call SaveTriggerHandle(GST_Hash, id, 4, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_RealRealReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntReal takes integer i1, real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveReal(GST_Hash, id, 1, r1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_Int takes integer i1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Int_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntInt takes integer i1, integer i2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveInteger(GST_Hash, id, 1, i2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_IntIntInt takes integer i1, integer i2, integer i3, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveInteger(GST_Hash, id, 0, i1)
    call SaveInteger(GST_Hash, id, 1, i2)
    call SaveInteger(GST_Hash, id, 2, i3)
    call SaveBoolean(GST_Hash, id, 3, repeating)
    call SaveTriggerHandle(GST_Hash, id, 4, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_IntIntInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitInt takes unit u1, integer i1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveInteger(GST_Hash, id, 1, i1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitInt_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitReal takes unit u1, real r1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveReal(GST_Hash, id, 1, r1)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitReal_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitUnitUnit takes unit u1, unit u2, unit u3, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveUnitHandle(GST_Hash, id, 1, u2)
    call SaveUnitHandle(GST_Hash, id, 2, u2)
    call SaveBoolean(GST_Hash, id, 3, repeating)
    call SaveTriggerHandle(GST_Hash, id, 4, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitUnitUnit_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_UnitUnit takes unit u1, unit u2, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveUnitHandle(GST_Hash, id, 1, u2)
    call SaveBoolean(GST_Hash, id, 2, repeating)
    call SaveTriggerHandle(GST_Hash, id, 3, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_UnitUnit_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

function GST_Unit takes unit u1, boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveUnitHandle(GST_Hash, id, 0, u1)
    call SaveBoolean(GST_Hash, id, 1, repeating)
    call SaveTriggerHandle(GST_Hash, id, 2, udg_GST_Trigger)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Unit_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif

    // clean up memory leaks
    set t = null
endfunction

function GST_Simple takes boolean repeating, real interval returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)

    // save to hashtable
    call SaveTriggerHandle(GST_Hash, id, 0, udg_GST_Trigger)
    call SaveBoolean(GST_Hash, id, 1, repeating)

    // start timer
    call TimerStart(t, interval, repeating, function GST_Simple_Expire)

    // check for keys which are used to restart existing timers
    if udg_GST_RestartKey >= 0 then
        call GST_RestartTimer()
        // keep track of the new timer stored at these keys
        call SaveTimerHandle(GST_Hash, GST_NewKey, GetHandleId(udg_GST_Trigger), t)
        set udg_GST_RestartKey = -1
    endif
 
    // clean up memory leaks
    set t = null
endfunction

endlibrary

To update your system you first need to replace your old code with the new code above.

Then you need to delete the GST_ChildKey variable and then rename the GST_ParentKey variable to GST_RestartKey.

Then you need to create two new variables:
GST_Unit3 (unit)
GST_Real3 (real)

That's it.

You won't be able to open my demo map since you're on an older version of Wc3 but I figured I'd show you my "Initialize" trigger which gives you instructions on how to use the system. You DON'T need this trigger, I'm posting this so you can read it:
  • GST Initialize
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- [ /////////////////////// ] --------
      • -------- How to use the GST system: --------
      • -------- [ /////////////////////// ] --------
      • -------- --------
      • -------- Step 1: Set GST_Trigger to be equal to the trigger that you want to run when your timer expires. --------
      • Set VariableSet GST_Trigger = GST Initialize <gen>
      • -------- --------
      • -------- Step 2: Using custom script, call any of these GST functions. This will start a new timer which tracks the associated type or types of data: --------
      • Custom script: call GST_Int()
      • Custom script: call GST_IntInt()
      • Custom script: call GST_IntIntInt()
      • Custom script: call GST_Real()
      • Custom script: call GST_RealReal()
      • Custom script: call GST_RealRealReal()
      • Custom script: call GST_Unit()
      • Custom script: call GST_UnitUnit()
      • Custom script: call GST_UnitUnitUnit()
      • Custom script: call GST_UnitInt()
      • Custom script: call GST_UnitReal()
      • Custom script: call GST_IntReal()
      • Custom script: call GST_Simple()
      • -------- --------
      • -------- Step 3: --------
      • -------- In the (parenthesis) of the function you must provide the correct information. --------
      • -------- The first value or values inside of the () must be related to the type of function you're calling. So if you call GST_Int() you must first provide the Integer that you want to link to the timer. --------
      • -------- After all of those values have been provided you must tell the system whether you want a One-shot timer or a Repeating timer. This is done using a Boolean: false = One-shot, true = Repeating. --------
      • -------- Then after the Boolean you must provide the duration of the timer using a Real. --------
      • -------- --------
      • -------- Here's an example of a timer that stores the Integer 12345 inside of a One-shot timer (false) which lasts for 1.00 second: --------
      • Custom script: call GST_Int( 12345, false, 1.00 )
      • -------- --------
      • -------- The above example is basically just a more advanced version of this function: --------
      • Countdown Timer - Start (some timer) as a One-shot timer that will expire in 1.00 seconds
      • -------- --------
      • -------- Step 4: --------
      • -------- At this point the system is setup to start your timer. Now you need to go into your GST_Trigger which is what will run when the timer expires and make sure it's setup correctly. --------
      • -------- You MUST use the GST_ variables that are associated with the type of GST function that you called! --------
      • -------- If you called GST_Int() then in order to reference that Integer you must use the variable GST_Integer1. --------
      • -------- If you called GST_Unit() then in order to reference that Unit you must use the variable GST_Unit1. --------
      • -------- If you called GST_UnitUnit() then in order to reference the first Unit you must use the variable GST_Unit1. To reference the second unit you use GST_Unit2. --------
      • -------- This pattern is used for all of the GST functions / GST variable types. --------
      • -------- --------
      • -------- Step 5: Finished! --------
      • -------- [ /////////////////////// ] --------
      • -------- --------
      • -------- Additionally, you can use these features to manage your GST timers: --------
      • -------- --------
      • -------- This function is used to destroy a Repeating timer. One-shot timers are destroyed automatically. You would call this in your GST_Trigger when you're ready to stop the timer: --------
      • Custom script: call GST_DestroyTimer()
      • -------- --------
      • Set VariableSet GST_RestartKey = -1
      • -------- GST_RestartKey is an optional variable used to make your timer "restartable". This makes the timer act more like a standard GUI timer. --------
      • -------- You must set it's value to a number >= 0 and < 100,000 before calling your GST() function in order for this method to work. --------
      • -------- If you want a MUI/MPI restartable timer then you should use Unit Indexing/Player Indexing for it's value! --------
      • -------- For a reference look at GST Example 5 in the GST Examples folder. --------
      • -------- --------
 

Attachments

  • GUI Simple Timers 3.w3m
    31.4 KB · Views: 9
Last edited:
Status
Not open for further replies.
Top