Добавлен ArhiMEN
Делал триггер и увидел огромное количество утечек, совершенно не понятных для меня, можете объяснить, как их убрать?
Утечки
function Trig_TerribleWounds_Actions takes nothing returns nothing
local real TerribleWoundsCount
local real UnitLifeOld
local real UnitLifeNow
local group TWGroup = CreateGroup()
local unit TWUnit
call GroupEnumUnitsInRect(TWGroup, GetWorldBounds( ), null)
loop
set TWUnit = FirstOfGroup(TWGroup)
exitwhen TWUnit == null
set TerribleWoundsCount = LoadReal(H, GetHandleId(TWUnit), StringHash("TerribleWoundsCount"))
set UnitLifeOld = LoadReal(H, GetHandleId(TWUnit), StringHash("UnitLifeOld"))
set UnitLifeNow = GetUnitState(TWUnit, UNIT_STATE_LIFE)
if TerribleWoundsCount > 1 then
set TerribleWoundsCount = 1
endif
if (UnitLifeOld < UnitLifeNow) and UnitLifeOld != 0 and TerribleWoundsCount != 0 then
call SetUnitState(TWUnit, UNIT_STATE_LIFE, (UnitLifeNow - (UnitLifeNow - UnitLifeOld) * TerribleWoundsCount))
endif
set UnitLifeOld = GetUnitState(TWUnit, UNIT_STATE_LIFE)
call SaveReal(H, GetHandleId(TWUnit), StringHash("UnitLifeOld"), UnitLifeOld)
call GroupRemoveUnit(TWGroup, TWUnit)
endloop
set TWGroup = null
set TWUnit = null
endfunction
//===========================================================================
function InitTrig_TerribleWounds takes nothing returns nothing
local trigger TerribleWoundsTrigger
set TerribleWoundsTrigger = CreateTrigger( )
call TriggerRegisterTimerEvent(TerribleWoundsTrigger, 0.01, true)
call TriggerAddAction(TerribleWoundsTrigger, function Trig_TerribleWounds_Actions)
set TerribleWoundsTrigger = null
endfunction
При этом делал схожий триггер, но он утечки не вызывает.
Нет утечек
//! nocjass
library Horror requires MemoryHackDamageEventHook
globals
group HorrorGroup = CreateGroup( )
endglobals
function HorrorCheckGroup takes nothing returns nothing
local real HorrorTime = LoadReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"))
local effect HorrorEffect = LoadEffectHandle(H, GetHandleId(GetEnumUnit()), StringHash("HorrorEffect"))
local unit Isazam = LoadUnitHandle(H, GetHandleId(GetEnumUnit()), StringHash("Isazam"))
local real TargetX = GetUnitX(GetEnumUnit())
local real TargetY = GetUnitY(GetEnumUnit())
local real IsazamX = GetUnitX(Isazam)
local real IsazamY = GetUnitY(Isazam)
local integer HorrorQuest = LoadInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"))
if HorrorTime >= 20 then
set HorrorQuest = 1
call SaveInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"), HorrorQuest)
endif
if SquareRoot((IsazamX - TargetX) * (IsazamX - TargetX) + (IsazamY - TargetY) * (IsazamY - TargetY)) >= 700 then //Указываем желаемую дальность увеличенного снижения ужаса
set HorrorTime = HorrorTime - 1.5
else
set HorrorTime = HorrorTime - 1
endif
if HorrorTime <= 0 then
call DestroyEffect(HorrorEffect)
call GroupRemoveUnit(HorrorGroup, GetEnumUnit())
set HorrorTime = 0
else
call PingMinimapEx(TargetX, TargetY, 1, 255, 0, 0, false)
endif
call SaveReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"), HorrorTime)
set HorrorEffect = null
set Isazam = null
endfunction
function HorrorCheckAction takes nothing returns nothing
call ForGroup(HorrorGroup, function HorrorCheckGroup)
endfunction
function Damaged_Handler takes unit source, unit target, real dmg returns nothing
local integer evnt = GetDamageEventESPData()
local integer data = ReadRealMemory(evnt + 0x00)
local real init_dmg = CleanReal(IndexToReal(ReadRealMemory(evnt + 0x04)))
local integer flags = ReadRealMemory(data + 0x0C)
local integer atk_t = ReadRealMemory(data + 0x20)
local real HorrorTime = LoadReal(H, GetHandleId(target), StringHash("HorrorTime"))
local effect HorrorEffect
local unit Isazam
local integer HorrorQuest = LoadInteger(H, GetHandleId(source), StringHash("HorrorQuest"))
if GetUnitTypeId(source) == 'U005' then // Ставим свой ID Исазама
call SaveReal(H, GetHandleId(target), StringHash("HorrorTime"), HorrorTime + 2 + HorrorQuest)
if HorrorTime <= 0 then
set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl", target, "chest")
call SaveEffectHandle(H, GetHandleId(target), StringHash("HorrorEffect"), HorrorEffect)
call SaveUnitHandle(H, GetHandleId(target), StringHash("Isazam"), source)
call GroupAddUnit(HorrorGroup, target)
elseif (IsFlagBitSet(flags, 0x100) or IsFlagBitSet(flags, 0x101)) and atk_t != 0 and HorrorTime > 0 then
set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", source, "origin")
call DestroyEffectTimer(HorrorEffect, 0.3)
call SetUnitState(source, UNIT_STATE_LIFE, (GetUnitState(source, UNIT_STATE_LIFE) + init_dmg * 0.2))
endif
endif
set HorrorEffect = null
set Isazam = null
endfunction
function Damage_Event takes nothing returns nothing
call DisableTrigger( GetTriggeringTrigger( ) )
call Damaged_Handler( GetEventDamageSource( ), GetTriggerUnit( ), GetEventDamage( ) )
call EnableTrigger( GetTriggeringTrigger( ) )
endfunction
endlibrary
function InitTrig_Horror takes nothing returns nothing
local group gMain = CreateGroup()
local unit uTemp
local trigger trTemp
local trigger HorrorCheck
if true then
set trTemp = CreateTrigger( )
call GroupEnumUnitsInRect( gMain, GetWorldBounds( ), null )
loop
set uTemp = FirstOfGroup( gMain )
exitwhen uTemp == null
call TriggerRegisterUnitEvent( trTemp, uTemp, EVENT_UNIT_DAMAGED )
call GroupRemoveUnit( gMain, uTemp )
endloop
call TriggerAddAction( trTemp, function Damage_Event )
endif
set HorrorCheck = CreateTrigger( )
call TriggerRegisterTimerEvent(HorrorCheck, 1, true)
call TriggerAddAction(HorrorCheck, function HorrorCheckAction)
set gMain = null
set uTemp = null
set trTemp = null
set HorrorCheck = null
endfunction
//! endnocjass
Принятый ответ
Да, в самом коде тоже можно оптимизировать. Про вынос стрингхешей уже сказали.
Еще например функция GetWorldBounds(), насколько помнится, создает новый рект каждый вызов. То есть его как минимум надо удалять после этого. А лучше только один раз ее вызвать и тоже просто загнать в глобалку на всю игру. Или можно пользоваться БЖшной глобалкой bj_mapInitialPlayableArea (но она учитывает только играбельную зону карты, без черных краев).
Еще например функция GetWorldBounds(), насколько помнится, создает новый рект каждый вызов. То есть его как минимум надо удалять после этого. А лучше только один раз ее вызвать и тоже просто загнать в глобалку на всю игру. Или можно пользоваться БЖшной глобалкой bj_mapInitialPlayableArea (но она учитывает только играбельную зону карты, без черных краев).
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Ред. Hanabishi
Еще например функция GetWorldBounds(), насколько помнится, создает новый рект каждый вызов. То есть его как минимум надо удалять после этого. А лучше только один раз ее вызвать и тоже просто загнать в глобалку на всю игру. Или можно пользоваться БЖшной глобалкой bj_mapInitialPlayableArea (но она учитывает только играбельную зону карты, без черных краев).
Ред. rsfghd
Ред. quq_CCCP