- Joined
- Mar 3, 2006
- Messages
- 1,564
Are variables that are used in structs get destroyed once onDestroy method is called ?
scope AoETemplate initializer Init
private keyword Data
globals
// Constants
private constant real TIMER_INTERVAL = 0.015
private constant real DIST = 16.00
private constant real NOVA_RADIUS = 544.00 // radius of the Nova
private constant integer NOVA_SIZE = 36 // number of the Nova Units
private constant real dA = 360/NOVA_SIZE
private constant integer UNIT_ID = 'e001' // rawcode of the Nova Unit
private constant integer ABIL_ID = 'A001' // rawcode of the Dummy Spell
private constant attacktype ATKTYPE = ATTACK_TYPE_MAGIC
private constant damagetype DMGTYPE = DAMAGE_TYPE_FIRE
// Note: Changing the following Constants will result in different damage value
// Make sure if you change this values to change the dummy spell damage description as well
private constant real AB_CONST_FACTOR = 50.00
private constant real AB_LEVEL_FACTOR = 50.00
private constant real AB_PREV_LVL_FACTOR = 1
// if the previous constant is set to 0 the damage increment will be arithmatic
// if 1 it will take the damage that the spell deals in the previous level and add AB_CONST_FACTOR + AB_LEVEL_FACTOR * AbilityCurrentLevel
// Variables
private timer tm = CreateTimer()
private Data array temp_dat
private integer index = 0
private Data iFilter // Filter Data
private boolexpr fFilter // Filter function
private group TempGroup = CreateGroup()
endglobals
function Damage takes integer al returns real
local real prevDmg
if al == 1 then
set prevDmg = 0
else
set prevDmg = Damage.evaluate(al -1)
endif
return AB_CONST_FACTOR + AB_LEVEL_FACTOR * al + AB_PREV_LVL_FACTOR * prevDmg
endfunction
private struct Data
unit Caster
unit array Nova[NOVA_SIZE]
real expand
real Cx
real Cy
player Owner
group dGroup = CreateGroup() // Damaged Units Group
real dmg
//static method Damage takes integer AbiLevel returns real
//local real prev
//if AbiLevel == 1 then
//set prev = 0
//else
//set prev = Damage.evaluate(AbiLevel - 1)
//endif
//return AB_CONST_FACTOR + AB_LEVEL_FACTOR * AbiLevel + AB_PREV_LVL_FACTOR * prev
//endmethod
static method NovaExpand takes nothing returns nothing
local thistype dat
local integer i = 0
local integer j
local real x
local real y
local real a
local unit u
loop // this loop cycles through all the casters which have cast the spell
exitwhen i >= index
set dat = temp_dat[i]
// Nova Expanding
set j = 0
set a = 0
set dat.expand = dat.expand + DIST
loop
exitwhen j >= NOVA_SIZE
set x = dat.Cx + dat.expand * Cos( a * bj_DEGTORAD )
set y = dat.Cy + dat.expand * Sin( a * bj_DEGTORAD )
call SetUnitX( dat.Nova[j] , x )
call SetUnitY( dat.Nova[j] , y )
set j = j + 1
set a = a + dA
endloop
// Damage Units that the nova has reached
set iFilter = dat
call GroupEnumUnitsInRange(TempGroup, dat.Cx, dat.Cy, dat.expand, fFilter)
loop
set u = FirstOfGroup(TempGroup)
exitwhen u == null
call GroupAddUnit(dat.dGroup, u)
call UnitDamageTarget(dat.Caster, u, dat.dmg, false, false, ATKTYPE, DMGTYPE, null)
call GroupRemoveUnit(TempGroup, u)
endloop
if dat.expand >= NOVA_RADIUS then // check if the nova has reached its max AoE
set index = index - 1
set temp_dat[i] = temp_dat[index]
set i = i - 1
call dat.destroy()
endif
set i = i + 1
endloop
set u = null
endmethod
static method create takes unit caster returns Data
local thistype dat = thistype.allocate()
local integer i = 0
local real A = 0.00
set dat.Caster = caster
set dat.Owner = GetOwningPlayer(dat.Caster)
set dat.Cx = GetUnitX(dat.Caster)
set dat.Cy = GetUnitY(dat.Caster)
set dat.dmg = Damage(GetUnitAbilityLevel(dat.Caster,ABIL_ID))
// the following function displays a msg of the amount of damage that the spell deals
// make sure when you use it to remove the following function or add "//" before it
//call DisplayTimedTextToPlayer(dat.Owner,0,0,10,"|cffff0000" + R2S(dat.dmg) + "|r")
loop
exitwhen i >= NOVA_SIZE
set dat.Nova[i] = CreateUnit( dat.Owner , UNIT_ID , dat.Cx , dat.Cy , A )
set A = A + dA
set i = i + 1
endloop
if index == 0 then
call TimerStart(tm,TIMER_INTERVAL,true,function Data.NovaExpand)
endif
set temp_dat[index] = dat
set index = index + 1
return dat
endmethod
static method FilterUnit takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) >= .305 and IsUnitEnemy(GetFilterUnit(),iFilter.Owner) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitInGroup(GetFilterUnit(),iFilter.dGroup)
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
exitwhen i >= NOVA_SIZE
call KillUnit(.Nova[i])
set .Nova[i] = null
set .expand = 0
set i = i + 1
endloop
if index == 0 then
call PauseTimer(tm)
endif
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABIL_ID
endfunction
private function Actions takes nothing returns nothing
call Data.create(GetTriggerUnit())
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function Conditions))
call TriggerAddAction(t,function Actions)
set fFilter = Filter(function Data.FilterUnit)
endfunction
endscope
onDestroy
method and put every stuff u want to desroy or nullify in there =>method onDestroy takes nothing returns nothing
call DestroyXXX(this.XXX)
set this.XXX = null
endmethod
struct A
endstruct
struct B
A a
static method create takes nothing returns nothing // or whatever the syntax is
// ops, you never remove this, 1 index less for your A structs
.a = A.create()
endmethod
endstruct
struct Test
private location loc
private method onDestroy takes nothing returns nothing
call RemoveLocation(this.loc)
endmethod
endstruct
Why ? won't this point leak ?Nulling them is basically useless.
It's not faster, it's not more efficient, it makes no difference whatsoever. I guess you could say it's slower since the operation of nulling it might take a nanosecond or two...I never said that they wouldn't recycle be not nulling them... they just recycle faster, maybe faster is the wrong word, because if you do not null it the id can be used some time later again, but if you null it the id is released earlier
struct A
location l = Location(0,0,0)
static method onDestroy takes nothing returns nothing // or whatever the syntax is
call RemoveLocation(.l)
endmethod
endstruct
struct B
endstruct
struct A
B b = B.create()
static method onDestroy takes nothing returns nothing // or whatever the syntax is
call b.destroy()
endmethod
endstruct
You do not have to null struct members if you recycle them quickly, otherwise you do.
This is purly to free up more handle indexes quicker and remember that nulling takes near no time at all. Basically globals do not automatically free the handle index like locals, however they can not leak handle indexes unlike locals. Thus nulling them lets the indexes be recycled, while otherwise if the value of a handle in an array is never overwritten, it clogs up that handle index forever (eg if for some reason you used 30 structs at one point in the game while after that the max you used only was 10, 20 indexes worth of handles would be clogged up unnescescarily).