Недавно убрал из кода запуск таймеров через луп, некоторое количество лишних локалок осталось покачто в коде - уберу позже. Однако где то есть утечки хэндлов - где - не могу сообразить. Прошу знающих людей прочитать код и сказать где же я недоглядел.
function Trig_Spell_RalRune_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A00E' ) ) then
return false
endif
return true
endfunction
function MatchingFiresoulsConditions takes nothing returns boolean
return IsUnitAlly(GetFilterUnit(), GetOwningPlayer(udg_U_Cookie)) != true and GetUnitState(GetFilterUnit(),UNIT_STATE_LIFE) > 0 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false
endfunction
function Unit_Firsouls_Temp_Group takes nothing returns nothing
call GroupAddUnitSimple( GetEnumUnit(), udg_Temp_Group )
endfunction
function ExplodeFireSoul takes nothing returns nothing
local unit u = udg_U_Cookie
local unit v = GetEnumUnit()
local integer lvl = GetUnitAbilityLevel(u, 'A00E')
local real constantdmg = 10*lvl
local real constantburndmg = 2*lvl
local real constantburnsec = 5
call MakeEleDamage(u, v, constantdmg, 2)
call BurnUnit(v, u, constantburndmg, constantburnsec)
set u = null
set v = null
set constantdmg = 0
set constantburndmg = 0
set constantburnsec = 0
set lvl = 0
endfunction
function MoveFireSouls takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer i = GetHandleId(t)
local unit u = LoadUnitHandle(udg_Data, i, 1)
local real angle = LoadReal(udg_Data, i, 2)
local integer right = LoadInteger(udg_Data, i, 4)
local real x1 = LoadReal(udg_Data, i, 5)
local real y1 = LoadReal(udg_Data, i, 6)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real dist = LoadReal(udg_Data, i, 3)
local real array temp
local real constantdist = 0
local real atf = 0
local unit caster = LoadUnitHandle(udg_Data, i, 7)
local location target = Location(x1,y1)
local location curpos = Location(x,y)
if (GetUnitUserData(u) == 0)then
set temp[1] = DistanceBetweenPoints(curpos, target)
set temp[2] = AngleBetweenPoints(curpos, target)
if ( right == 1 ) then
set temp[3] = (temp[2] - (temp[1]/20))
else
set temp[3] = (temp[2] + (temp[1]/20))
endif
if ( temp[3] > (temp[2] + 100)) then
set temp[3] = temp[2] + 100
else
endif
if ( temp[3] < (temp[2] - 100)) then
set temp[3] = temp[2] - 100
else
endif
set constantdist = temp[1]/5
set x = x + constantdist * Cos(temp[3] * bj_DEGTORAD)
set y = y + constantdist * Sin(temp[3] * bj_DEGTORAD)
call MoveLocation(curpos, x, y)
call SetUnitPositionLoc(u, curpos)
if (DistanceBetweenPoints(curpos, target) <= 10) then
if (GetUnitUserData(u) == 0)then
set udg_U_Cookie = caster
set bj_wantDestroyGroup = true
call ForGroupBJ( GetUnitsInRangeOfLocMatching(80.00, curpos, Condition(function MatchingFiresoulsConditions)), function ExplodeFireSoul )
call SetUnitUserData(u,1)
call KillUnit(u)
call DestroyTimer(t)
call FlushChildHashtable(udg_Data, i)
else
endif
else
endif
else
endif
set i = 0
set t = null
set u = null
set angle = 0
set x = 0
set y = 0
set dist = 0
set temp[1] = 0
set temp[2] = 0
set temp[3] = 0
set atf = 0
set right = 0
set constantdist = 0
call RemoveLocation(curpos)
call RemoveLocation(target)
endfunction
function SetFireSoul takes unit owner, unit missle, real angle, location p, integer lvl, integer i4 returns nothing
local timer t = CreateTimer()
local location p1 = Location(GetUnitX(owner), GetUnitY(owner))
local real tempdist = DistanceBetweenPoints(p1,p)
local real tempdist1 = tempdist/4
local integer i1 = R2I(tempdist1)
local integer i2 = 1
local real array temp
local integer hi = 0
local integer i3 = 0
set temp[2] = DistanceBetweenPoints(p1, p)
set tempdist = 0
set temp[3] = temp[2] / ( temp[2] / 25 )
set i1 = R2I(temp[3])
if ( i4 == 1 ) then
set i3 = 0
else
set i3 = 1
endif
set hi = GetHandleId(t)
call SaveUnitHandle(udg_Data, hi, 1, missle)
call SaveReal(udg_Data, hi, 2, angle)
call SaveReal(udg_Data, hi, 3, temp[2])
call SaveReal(udg_Data, hi, 5, GetLocationX(p))
call SaveReal(udg_Data, hi, 6, GetLocationY(p))
call SaveUnitHandle(udg_Data, hi, 7, owner)
call SaveInteger(udg_Data, hi, 4, i3)
call TimerStart(t, 0.03, true, function MoveFireSouls)
set t = null
call UnitApplyTimedLife(missle, 'BTLF' ,((I2R(i2)*0.03)+0.6))
set i1 = 0
set i2 = 0
set temp[1] = 0
set temp[3] = 0
set temp[2] = 0
set hi = 0
call RemoveLocation(p)
call RemoveLocation(p1)
set i3 = 0
set i4 = 0
set owner = null
set missle = null
endfunction
function SpawnFS takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer i = GetHandleId(t)
local unit u = LoadUnitHandle(udg_Data,i, 1)
local real x = LoadReal(udg_Data, i, 3)
local real y = LoadReal(udg_Data, i, 4)
local rect rec = Rect((x-80),(y-80), (x+80), (y+80))
local location p = GetRandomLocInRect(rec)
local location p1 = Location(GetUnitX(u), GetUnitY(u))
local integer lvl = LoadInteger(udg_Data, i, 5)
local real angle = AngleBetweenPoints(p1, p)
local integer i4 = LoadInteger(udg_Data, i, 6)
local unit u1 = CreateUnitAtLoc( GetOwningPlayer(u), 'h002', p1, bj_UNIT_FACING )
call SetFireSoul(u, u1, AngleBetweenPoints(p1, p), p, lvl, i4)
call RemoveLocation(p)
call RemoveLocation(p1)
call FlushChildHashtable(udg_Data, i)
call DestroyTimer(t)
set u1 = null
set u = null
set lvl = 0
set angle = 0
set x = 0
set y = 0
set i4 = 0
call RemoveRect(rec)
endfunction
function SpawnFireSouls takes unit caster, integer lvl, real x1, real y1 returns nothing
local timer array t
local integer const = 10+(10*lvl)
local integer i = 1
local integer i3 = 0
loop
exitwhen i > const
set t[i] = CreateTimer()
if ( i3 == 1 ) then
set i3 = 0
else
set i3 = 1
endif
call SaveUnitHandle(udg_Data,GetHandleId(t[i]), 1, caster)
call SaveInteger(udg_Data, GetHandleId(t[i]), 2, lvl)
call SaveReal(udg_Data, GetHandleId(t[i]), 3, x1)
call SaveReal(udg_Data, GetHandleId(t[i]), 4, y1)
call SaveInteger(udg_Data,GetHandleId(t[i]), 5, lvl)
call SaveInteger(udg_Data,GetHandleId(t[i]), 6, i3)
call TimerStart(t[i], 0.2*I2R(i), false, function SpawnFS)
set t[i] = null
set i = i+1
endloop
set i = 0
set i3 = 0
set const = 0
endfunction
function Trig_Spell_RalRune_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local integer i = 1
local integer lvl = GetUnitAbilityLevel(u, GetSpellAbilityId())
local location p = Location(GetUnitX(u), GetUnitY(u))
local location p1 = GetSpellTargetLoc()
loop
exitwhen ( IsUnitInGroup(GetTriggerUnit(), udg_CASTING_GROUP) != true )
call TriggerSleepAction(RMaxBJ(bj_WAIT_FOR_COND_MIN_INTERVAL, 0.10))
endloop
if ( GetUnitUserData(GetTriggerUnit()) <= 0 ) then
call SpawnFireSouls(u, lvl, GetLocationX(p1), GetLocationY(p1))
else
endif
set u = null
call RemoveLocation(p)
call RemoveLocation(p1)
set i = 0
set lvl = 0
endfunction
//===========================================================================
function InitTrig_Spell_RalRune takes nothing returns nothing
set gg_trg_Spell_RalRune = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell_RalRune, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Spell_RalRune, Condition( function Trig_Spell_RalRune_Conditions ) )
call TriggerAddAction( gg_trg_Spell_RalRune, function Trig_Spell_RalRune_Actions )
endfunction
MakeEleDamage и BurnUnit - функции из другой оперы. Функция вызывает утечки независимо от того, есть ли хоть какое то количество юнитов рядом.
P.S острить по поводу бж в некоторых местах - не надо. И да, я знаю что код не самый читабельный или чистый.