- 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?
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: