• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] System Only Loops Twice

Status
Not open for further replies.
JASS:
function Dot_Create takes unit Dot,integer Nid,real AoE,real Dmg returns nothing
    // ***** Local variables *****
    local integer Id=udg_Dot_Num+1
    // ***** Allocate dot *****
    set udg_Dot_Unit[Id]=Dot
    set udg_Dot_Spawn[Id]=Nid
    set udg_Dot_AoE[Id]=AoE
    set udg_Dot_Damage[Id]=Dmg
    // ***** Start timer as needed *****
    if Id==1then
        call ResumeTimer(udg_Dot_Ticker)
    endif
    // ***** Clean-up *****
    set udg_Dot_Num=Id
endfunction
function Dot_Delete takes integer Id returns nothing
    // ***** Prevent bad de-allocates *****
    if Id<1or Id>udg_Dot_Num then
        return
    endif
    // ***** Deallocate dot *****
    set udg_Dot_Unit[Id]=udg_Dot_Unit[udg_Dot_Num]
    set udg_Dot_Spawn[Id]=udg_Dot_Spawn[udg_Dot_Num]
    set udg_Dot_AoE[Id]=udg_Dot_AoE[udg_Dot_Num]
    set udg_Dot_Damage[Id]=udg_Dot_Damage[udg_Dot_Num]
    set udg_Dot_Unit[udg_Dot_Num]=null
    // ***** Pause timer as needed *****
    if udg_Dot_Num==1then
        call PauseTimer(udg_Dot_Ticker)
    endif
    // ***** Clean-up *****
    set udg_Dot_Num=udg_Dot_Num-1
endfunction
function Dot_Tick takes nothing returns nothing
    // ***** Local variables *****
    local integer Id=1
    local unit Tar=null
    local unit Dot=null
    local group G=udg_Groups[0]
    local real Dmg
    // ***** Iterate over all dots *****
    loop
        // Loop set-up.
        exitwhen Id>udg_Dot_Num
        // Handle dot.
        set Dot=udg_Dot_Unit[Id]
        if Dot==null or GetUnitTypeId(Dot)==0or IsUnitType(Dot,UNIT_TYPE_DEAD)then
            call Dot_Delete(Id)
        else
            set Dmg=udg_Dot_Damage[Id]*0.25
            call GroupEnumUnitsInRange(G,GetUnitX(udg_Dot_Unit[Id]),GetUnitY(udg_Dot_Unit[Id]),udg_Dot_AoE[Id],null)
            // Loop over targets.
            loop
                // Loop set-up.
                set Tar=FirstOfGroup(G)
                exitwhen Tar==null
                call GroupRemoveUnit(G,Tar)
                // Handle Target.
                if GetUnitTypeId(Tar)!=0and IsUnitType(Tar,UNIT_TYPE_DEAD)==false and GetUnitAbilityLevel(Tar,'A002')==0then
                    call UnitDamageTarget(Dot,Tar,Dmg,true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,null)
                endif
                // Loop clean-up.
                set Tar=null
            endloop
            // Deal damage to dot.
            call SetWidgetLife(Dot,GetWidgetLife(Dot)-0.25)
            set Id=Id+1
        endif
        // Loop clean-up.
        set Dot=null
    endloop
    // ***** Clean-up *****
    set G=null
    set Tar=null
    set Dot=null
endfunction
Initialization
JASS:
call TimerStart(udg_Dot_Ticker,0.25,true,function Dot_Tick)
call PauseTimer(udg_Dot_Ticker)
set udg_Dot_Num=0

This system only iterates over all the dots twice. The timer is not paused, which makes me think that the thread is crashing. Even if the thread crashed, shouldn't it keep iterating because it's a repeating timer?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
WC3 is very buggy.

Pausing a timer removes its periodic flag. When you resume the timer it will only fire once after the remaining time finishes and never again (as if it was non-repeating).

Replace resume timer operation with a restart timer (start timer call repeated, this is bad programing practice and ugly but the only way around this bug). Pause can be kept the same as you basically use it to remove timer overhead when operation is not required. It is not possible to resume a periodic timer without it reverting to once off (as far as I know).
 
Status
Not open for further replies.
Top