• 🏆 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!

[Solved] Timer actions don't stop even if I stopped and destroyed it and remove the data

Status
Not open for further replies.
Level 24
Joined
Jun 26, 2020
Messages
1,852
I have this spell, but as I said it didn't stop when it should, what is happening?
JASS:
function Trig_Sparky_Explosions_spell_Conditions takes nothing returns boolean
    return GetBooleanOr(GetSpellAbilityId()=='A05C',GetSpellAbilityId()=='A05D')
endfunction

function QueuedExplosions takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer i=GetHandleId(t)
    local unit caster=LoadUnitHandle(udg_Sparky_Explosions_Datos,1,i)
    local integer counter=LoadInteger(udg_Sparky_Explosions_Datos,2,i)+1
    local real area=LoadReal(udg_Sparky_Explosions_Datos,4,i)
    local location caster_loc=LoadLocationHandle(udg_Sparky_Explosions_Datos,6,i)
    local real size=LoadReal(udg_Sparky_Explosions_Datos,8,i)
    local location exp_loc
    local unit u
    local group g=CreateGroup()
    if counter!=8 then
        set exp_loc=PolarProjectionBJ(caster_loc,area,LoadReal(udg_Sparky_Explosions_Datos,7,i)+45.00*LoadReal(udg_Sparky_Explosions_Datos,5,i)*I2R(counter))
        set u=CreateUnitAtLoc(GetOwningPlayer(caster),'h00R',exp_loc,bj_UNIT_FACING)
        call SetUnitScale(u,size,size,size)
        call KillUnit(u)
        call GroupEnumUnitsInRange(g,GetLocationX(exp_loc),GetLocationY(exp_loc),area*CosBJ(67.5),null)
        loop
            set u=FirstOfGroup(g)
            exitwhen u==null
            if IsUnitEnemy(u,GetOwningPlayer(caster)) then
                call UnitDamageTargetBJ(caster,u,LoadReal(udg_Sparky_Explosions_Datos,3,i),ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DEMOLITION)
            endif
            call GroupRemoveUnit(g,u)
        endloop
        call BreakTrees(exp_loc,area*CosBJ(67.5),true)
        call RemoveLocation(exp_loc)
        call SaveInteger(udg_Sparky_Explosions_Datos,2,i,counter)
    else
        set u=CreateUnitAtLoc(GetOwningPlayer(caster),'h00R',caster_loc,bj_UNIT_FACING)
        call SetUnitScale(u,size+0.1,size+0.1,size+0.1)
        call KillUnit(u)
        call GroupEnumUnitsInRange(g,GetLocationX(caster_loc),GetLocationY(caster_loc),area,null)
        loop
            set u=FirstOfGroup(g)
            exitwhen u==null
            if IsUnitEnemy(u,GetOwningPlayer(caster)) then
                call UnitDamageTargetBJ(caster,u,LoadReal(udg_Sparky_Explosions_Datos,3,i),ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DEMOLITION)
            endif
            call GroupRemoveUnit(g,u)
        endloop
        call BreakTrees(exp_loc,area,true)
        call RemoveLocation(caster_loc)
        call RemoveSavedHandle(udg_Sparky_Explosions_Datos,1,i)
        call RemoveSavedInteger(udg_Sparky_Explosions_Datos,2,i)
        call RemoveSavedReal(udg_Sparky_Explosions_Datos,3,i)
        call RemoveSavedReal(udg_Sparky_Explosions_Datos,4,i)
        call RemoveSavedReal(udg_Sparky_Explosions_Datos,5,i)
        call RemoveSavedHandle(udg_Sparky_Explosions_Datos,6,i)
        call RemoveSavedReal(udg_Sparky_Explosions_Datos,7,i)
        call RemoveSavedReal(udg_Sparky_Explosions_Datos,8,i)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    call DestroyGroup(g)
    set t=null
    set caster=null
    set caster_loc=null
    set exp_loc=null
    set g=null
endfunction

function Trig_Sparky_Explosions_spell_Actions takes nothing returns nothing
    local timer t=CreateTimer()
    local integer i=GetHandleId(t)
    local unit u=GetSpellAbilityUnit()
    local real lvl=I2R(GetUnitAbilityLevel(u,GetSpellAbilityId()))
    call SaveUnitHandle(udg_Sparky_Explosions_Datos,1,i,u)
    call SaveInteger(udg_Sparky_Explosions_Datos,2,i,-1)
    if GetSpellAbilityId()=='A05C' then
        call SaveReal(udg_Sparky_Explosions_Datos,3,i,125.00+75.00*lvl)
        call SaveReal(udg_Sparky_Explosions_Datos,4,i,200.00+50.00*lvl)
    else
        call SaveReal(udg_Sparky_Explosions_Datos,3,i,50.00+100.00*lvl)
        call SaveReal(udg_Sparky_Explosions_Datos,4,i,175.00+50.00*lvl)
    endif
    call SaveReal(udg_Sparky_Explosions_Datos,5,i,Pow(-1,I2R(GetRandomInt(1,4))))
    call SaveLocationHandle(udg_Sparky_Explosions_Datos,6,i,GetUnitLoc(u))
    call SaveReal(udg_Sparky_Explosions_Datos,7,i,GetUnitFacing(u))
    call SaveReal(udg_Sparky_Explosions_Datos,8,i,0.8+0.2*lvl)
    call TimerStart(t,0.06,true,function QueuedExplosions)
    set t=null
    set u=null
endfunction

//===========================================================================
function InitTrig_Sparky_Explosions_spell takes nothing returns nothing
    set gg_trg_Sparky_Explosions_spell=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Sparky_Explosions_spell,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Sparky_Explosions_spell,Condition(function Trig_Sparky_Explosions_spell_Conditions))
    call TriggerAddAction(gg_trg_Sparky_Explosions_spell,function Trig_Sparky_Explosions_spell_Actions)
endfunction
 
Level 24
Joined
Jun 26, 2020
Messages
1,852
No it doesnt. Otherwise it would stop, right?

There is probably some error that stops executing the rest of the function inside the 'else' part

Put a debug message above the timer destructin and see if it displays
I did that and the variable "counter" still remaining in 8, I added a "set counter=0" in the else part, but also remains in the value 8, why?
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
Alright, i think i found the mistake.
On every timer iteration, if condition is true, you create a location and call BreakTrees(location)

If condition is false, you jump into your ELSE, which doesnt create this location. You still call BreakTrees(location), but the location is null at this point.

Using nullpoint probably breaks the function
 
Level 24
Joined
Jun 26, 2020
Messages
1,852
Alright, i think i found the mistake.
On every timer iteration, if condition is true, you create a location and call BreakTrees(location)

If condition is false, you jump into your ELSE, which doesnt create this location. You still call BreakTrees(location), but the location is null at this point.

Using nullpoint probably breaks the function
I don't know why that happens, but yes it was, thank you.
 
Status
Not open for further replies.
Top