• 🏆 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] Double Free Errors.

Status
Not open for further replies.
Level 9
Joined
Apr 23, 2011
Messages
460
[Solved] Double Free Errors.

I'm experiencing some double free errors and I'm not certain where from. It's most certainly from how I clean up after the buff wears off, of when the buff overshoots the mana. Ideas?

JASS:
library ArcDrain initializer init uses RegisterPlayerUnitEvent, TimerUtils
    globals
        private constant integer SPELL_ID  = 'ArcD'
        private constant integer BUFF_ID   = 'Arcs'
        private constant real MSPEED       = .35
        private constant real TIMERTIME    = 4.
        private constant real TURNOVER     = .25 
    endglobals
    
  struct ArcDrain
        private real TIMEOUT
        private boolean DEALLOCATEME
        private timer TIMER
        private unit CASTER 
        private unit TARGET
        private real DRAIN
        
        private method destroy takes nothing returns nothing
            set this.CASTER = null
            set this.TARGET = null
            set this.TIMER = null
            call this.deallocate()
        endmethod
        
        private static method periodic takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())
            local real targetMana = GetUnitState(this.TARGET, UNIT_STATE_MANA)
            local real casterMana = GetUnitState(this.CASTER, UNIT_STATE_MANA)
            local boolean giveMana = true
            if this.TIMEOUT <= 0 then
                call ReleaseTimer(this.TIMER)
                set this.DEALLOCATEME = true
            elseif targetMana < this.DRAIN then
                set this.DRAIN = (targetMana / 4)
                set this.DEALLOCATEME = true
                call ReleaseTimer(this.TIMER)
            elseif casterMana == GetUnitState(this.CASTER, UNIT_STATE_MAX_MANA) then
                set giveMana = false
            endif
            call SetUnitState(this.TARGET, UNIT_STATE_MANA, (GetUnitState(this.TARGET, UNIT_STATE_MANA) - this.DRAIN))
            if giveMana then
                call SetUnitState(this.CASTER, UNIT_STATE_MANA, (GetUnitState(this.CASTER, UNIT_STATE_MANA) + R2I(this.DRAIN * TURNOVER)))
            endif
            set this.TIMEOUT = this.TIMEOUT - 1
            if this.DEALLOCATEME then
                call this.deallocate()
            endif            
        endmethod
        
        private static method spell takes nothing returns nothing
            local unit u = GetSpellAbilityUnit()
            local unit uu = GetSpellTargetUnit()
            local thistype this
            if not IsUnitType(uu, UNIT_TYPE_DEAD) and not IsUnitAlly(uu, Player(GetPlayerId(GetOwningPlayer(u)))) then
                set this = thistype.create()
                set this.CASTER = u
                set this.TARGET = uu
                set this.DRAIN = ((GetUnitAbilityLevel(u, SPELL_ID)*20)+50)
                set this.TIMER = NewTimer()
                set this.TIMEOUT = TIMERTIME
                call SetTimerData(this.TIMER, this)
                call TimerStart(this.TIMER, 1., true, function thistype.periodic)
            endif
        endmethod
        
       static method cast takes nothing returns nothing
            if GetSpellAbilityId() == SPELL_ID then
                call thistype.spell()
                return
            endif
        endmethod
    endstruct
    
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST, function ArcDrain.cast)
        set t = null
    endfunction
endlibrary
 
Last edited:
Status
Not open for further replies.
Top