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

[vJASS] Why this timer does not stop?

Status
Not open for further replies.
Level 11
Joined
Oct 11, 2012
Messages
711
Hey all. I am using Mag's spell example but the timer in the spell does not stop. Help please, thanks.
JASS:
struct Spell

    private static constant integer ABIL_CODE = 'Arej'


    private static constant real TIMEOUT = 1.00

    private thistype next
    private thistype prev

    private static timer iterator = CreateTimer()
    private static integer count = 0

    private unit caster
    private unit target
    private real damage

    private method destroy takes nothing returns nothing

        call this.deallocate()


        set this.next.prev = this.prev
        set this.prev.next = this.next

        set count = count - 1
        if count == 0 then
            call PauseTimer(iterator)
        endif


        set this.caster = null
        set this.target = null


    endmethod

    private static method periodic takes nothing returns nothing

        local thistype this = thistype(0).next
        loop
            exitwhen this == 0

            call UnitRemoveBuffs(this.target,false,true)
            call BJDebugMsg("removing buffs")
            call BJDebugMsg(I2S(this))

            set this = this.next
        endloop
    endmethod

    private static method run takes nothing returns boolean
 
        local thistype this = thistype.allocate()


        set this.next = 0
        set this.prev = thistype(0).prev
        set thistype(0).prev.next = this
        set thistype(0).prev = this

        
        set count = count + 1
        if count == 1 then
            call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
        endif


        set this.caster = GetTriggerUnit()
        set this.target = GetSpellTargetUnit()


        return false
    endmethod

    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function thistype.run))
        set t = null
    endmethod
endstruct
 
You should call the .destroy() in the periodic method. It depends on what kind of spell you're making. Let's say that we want it to last 5 seconds. If so, we'd just make it look like this:
JASS:
struct Spell

    private static constant integer ABIL_CODE = 'Arej'


    private static constant real TIMEOUT = 1.00

    private thistype next
    private thistype prev

    private static timer iterator = CreateTimer()
    private static integer count = 0

    private unit caster
    private unit target
    private real damage
    private real duration

    private method destroy takes nothing returns nothing

        call this.deallocate()


        set this.next.prev = this.prev
        set this.prev.next = this.next

        set count = count - 1
        if count == 0 then
            call PauseTimer(iterator)
        endif


        set this.caster = null
        set this.target = null


    endmethod

    private static method periodic takes nothing returns nothing

        local thistype this = thistype(0).next
        loop
            exitwhen this == 0

            /* Decrement the duration */
            set this.duration = this.duration - TIMEOUT

            call UnitRemoveBuffs(this.target,false,true)
            call BJDebugMsg("removing buffs")
            call BJDebugMsg(I2S(this))

            /* Check if the duration has finished */
            if this.duration <= 0.00 then 
                call this.destroy()
            endif

            set this = this.next
        endloop
    endmethod

    private static method run takes nothing returns boolean
 
        local thistype this = thistype.allocate()


        set this.next = 0
        set this.prev = thistype(0).prev
        set thistype(0).prev.next = this
        set thistype(0).prev = this

        
        set count = count + 1
        if count == 1 then
            call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
        endif


        set this.caster = GetTriggerUnit()
        set this.target = GetSpellTargetUnit()
        set this.duration = 5.00


        return false
    endmethod

    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function thistype.run))
        set t = null
    endmethod
endstruct
 
Level 11
Joined
Oct 11, 2012
Messages
711
You should call the .destroy() in the periodic method. It depends on what kind of spell you're making. Let's say that we want it to last 5 seconds. If so, we'd just make it look like this:
JASS:
struct Spell

    private static constant integer ABIL_CODE = 'Arej'


    private static constant real TIMEOUT = 1.00

    private thistype next
    private thistype prev

    private static timer iterator = CreateTimer()
    private static integer count = 0

    private unit caster
    private unit target
    private real damage
    private real duration

    private method destroy takes nothing returns nothing

        call this.deallocate()


        set this.next.prev = this.prev
        set this.prev.next = this.next

        set count = count - 1
        if count == 0 then
            call PauseTimer(iterator)
        endif


        set this.caster = null
        set this.target = null


    endmethod

    private static method periodic takes nothing returns nothing

        local thistype this = thistype(0).next
        loop
            exitwhen this == 0

            /* Decrement the duration */
            set this.duration = this.duration - TIMEOUT

            call UnitRemoveBuffs(this.target,false,true)
            call BJDebugMsg("removing buffs")
            call BJDebugMsg(I2S(this))

            /* Check if the duration has finished */
            if this.duration <= 0.00 then 
                call this.destroy()
            endif

            set this = this.next
        endloop
    endmethod

    private static method run takes nothing returns boolean
 
        local thistype this = thistype.allocate()


        set this.next = 0
        set this.prev = thistype(0).prev
        set thistype(0).prev.next = this
        set thistype(0).prev = this

        
        set count = count + 1
        if count == 1 then
            call TimerStart(iterator, TIMEOUT, true, function thistype.periodic)
        endif


        set this.caster = GetTriggerUnit()
        set this.target = GetSpellTargetUnit()
        set this.duration = 5.00


        return false
    endmethod

    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function thistype.run))
        set t = null
    endmethod
endstruct

Thanks, PurgeandFire. I just figured out how to do this, but your way is more efficient. +Rep.
 
Last edited:
Status
Not open for further replies.
Top