• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[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
 
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.
Back
Top