• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

My Spell (Periodic Timer)

Status
Not open for further replies.
Level 17
Joined
Mar 21, 2011
Messages
1,597
Hi,
after learning the basics of timer, i tried to create a trigger using periodic timers.
When unit x enters playable map area, it will count down a timer (just for testing) and it works for me. If i create 2 units, it will create 2 indipendent timers.
My question is: wouldnt it be better to run 1 timer that covers both units?

JASS:
struct NuclearBomb extends array
    unit Bomb
    integer Time
endstruct

function Nuclear_Bomb_Timed takes nothing returns nothing

    local timer         t       = GetExpiredTimer()
    local NuclearBomb   data    = GetTimerData(t)
    local unit          u       = data.Bomb
    
    if (GetUnitState(u, UNIT_STATE_LIFE) > 0) then
        set data.Time = data.Time - 1
        call BJDebugMsg(GetUnitName(u) + ": " + I2S(data.Time))
    else
        call ReleaseTimer(t)
    endif
    
    set t = null
    set u = null
    
endfunction

function Trig_Nuclear_Bomb_Conditions takes nothing returns boolean

    local NuclearBomb   data
    local unit          u       = GetTriggerUnit()
    
    if (GetUnitTypeId(u) == 'n005') then
    
        set data        = GetUnitUserData(u)
        set data.Bomb   = u
        set data.Time   = 50
        
        call UnitApplyTimedLife(u, 'BTLF', 50.00)
        call TimerStart(NewTimerEx(data), 1.00, true, function Nuclear_Bomb_Timed)
        
        set u = null
        
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Nuclear_Bomb takes nothing returns nothing
    local region r = CreateRegion()
    call RegionAddRect(r, bj_mapInitialPlayableArea)
    set gg_trg_Nuclear_Bomb = CreateTrigger()
    call TriggerRegisterEnterRegion(gg_trg_Nuclear_Bomb, r, null)
    call TriggerAddCondition(gg_trg_Nuclear_Bomb, Condition(function Trig_Nuclear_Bomb_Conditions))
    set r = null
endfunction
 
How you prefer. It won't kill you if you use one timer per instance.

You can create only one timer for all instances, yes, but then you need take care of data structure.
If you loop for example each 0.03125 seconds and want to substract that value from RemainingTime, then
you need to iterate somehow though all instances.

With 1 timer per instance you don't have to make data list + it's a bit more accurate.

If it will have very much objects then I would use one global timer,
but if the amount is not huge, then independant timers do a good job.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Basically
If you want to have an interval of the minimum that you use (0.05, 0.04, 0.03125, 0.03), then you should use one timer.
If not, then you should use multiple timers.

Unless you merge timers... but that is something else.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Some improvements:

JASS:
scope Nuke initializer Init

globals
    private integer array time
globals

private function Timed takes nothing returns nothing
    local integer data = GetTimerData(GetExpiredTimer())
    
    if not IsUnitType(udg_UDexUnits[data], UNIT_TYPE_DEAD) then
        set time[data] = time[data] - 1
        call BJDebugMsg(GetUnitName(udg_UDexUnits[data]) + ": " + I2S(time[data]))
    else
        call ReleaseTimer(GetExpiredTimer())
    endif
endfunction

private function Conditions takes nothing returns boolean
    if (GetUnitTypeId(udg_UDexUnits[udg_UDex]) == 'n005') then
        set time[udg_UDex] = 50
        
        call UnitApplyTimedLife(udg_UDexUnits[udg_UDex], 'BTLF', 50.00)
        call TimerStart(NewTimerEx(udg_UDex), 1.00, true, function Timed)
    endif
    return false
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
    call TriggerAddCondition(t, Condition(function Conditions))
    set t = null
endfunction

endscope
 
Status
Not open for further replies.
Top