Today I finally took the time to learn the usage of structs. A blessing over local handle vars indeed, and I recoded a few of my spells. I have one concern, and that is when using groups in your struct.
The below spell works perfectly. It is called erratic entangle, you cast roots on a unit and every .75 seconds it roots a nearby unit. I'm worried this leaks when handling the groups in the functions "GaiaEntangle" and "GaiaEntangleFunc2". If I destroy the group, even after setting it to "data.entangled", the spell does not work. But currently, to me it seems the local groups are not being destroyed, leaking the groups every time its cast and every tick on the timer. My questions are, is this leaking and if it is, how can I easily resolve the issue?
The below spell works perfectly. It is called erratic entangle, you cast roots on a unit and every .75 seconds it roots a nearby unit. I'm worried this leaks when handling the groups in the functions "GaiaEntangle" and "GaiaEntangleFunc2". If I destroy the group, even after setting it to "data.entangled", the spell does not work. But currently, to me it seems the local groups are not being destroyed, leaking the groups every time its cast and every tick on the timer. My questions are, is this leaking and if it is, how can I easily resolve the issue?
JASS:
scope ErraticEntangle
struct entangle
player caster
group entangled
integer duration
endstruct
function GaiaEntangleCond takes nothing returns boolean
local integer id = GetSpellAbilityId()
local unit u = GetSpellAbilityUnit()
local integer i = GetUnitTypeId(u)
set u = null
return (id == 'A02U') and (i == 'e006')
endfunction
function GaiaEntangleFunc1 takes nothing returns boolean
return not(IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)) and not(IsUnitType(GetFilterUnit(), UNIT_TYPE_ANCIENT)) and IsUnitEnemy(GetFilterUnit(), GetTriggerPlayer())
endfunction
function GaiaEntangleFunc2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local entangle data = entangle(GetHandleInt(t,"struct"))
local unit u = GroupPickRandomUnit(data.entangled)
local unit v
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = CreateGroup()
local boolexpr b = Condition(function GaiaEntangleFunc1)
if (data.duration > 0) then
set v = CreateUnit(data.caster, 'h062', x, y, 270)
call UnitAddAbility(v, 'A02U')
call IssueTargetOrder(v, "entanglingroots", u)
call UnitApplyTimedLife(v, 'BTLF', 1)
call GroupEnumUnitsInRange(g, x, y, 400, b)
call GroupRemoveUnit(g, u)
set data.entangled = g
set data.duration = data.duration - 1
call SetHandleInt(t, "struct", data)
else
call data.destroy()
call PauseTimer(t)
call FlushHandleLocals(t)
call DestroyTimer(t)
endif
call DestroyBoolExpr(b)
set t = null
set g = null
set u = null
set v = null
set b = null
endfunction
function GaiaEntangle takes nothing returns nothing
local entangle data = entangle.create()
local unit s = GetSpellAbilityUnit()
local unit u = GetSpellTargetUnit()
local player p = GetOwningPlayer(s)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local group g = CreateGroup()
local timer t = CreateTimer()
local boolexpr b = Condition(function GaiaEntangleFunc1)
call GroupEnumUnitsInRange(g, x, y, 400, b)
set data.caster = p
set data.entangled = g
set data.duration = 40
call SetHandleInt(t, "struct", data)
call TimerStart(t, .75, true, function GaiaEntangleFunc2)
call DestroyBoolExpr(b)
set s = null
set u = null
set p = null
set g = null
set t = null
set b = null
endfunction
function InitTrig_EarthEntangleCast takes nothing returns nothing
local integer i = 0
local player p
set gg_trg_EarthEntangleCast = CreateTrigger()
loop
exitwhen i > 11
set p = Player(i)
call TriggerRegisterPlayerUnitEvent(gg_trg_EarthEntangleCast, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
endloop
call TriggerAddCondition(gg_trg_EarthEntangleCast, Condition(function GaiaEntangleCond))
call TriggerAddAction(gg_trg_EarthEntangleCast, function GaiaEntangle)
set p = null
endfunction
endscope