Добавлен Fa1korn
В моей карте один единственный триггер вызывается каждый раз при получении юнитом урона и, следовательно, 90% утечек происходит из за этого триггера.
Прошу мастеров оптимизации разобраться, в каком именно месте создаются утечки?
Прошу мастеров оптимизации разобраться, в каком именно месте создаются утечки?
код jass (SDMS триггер)
//set Color[0] = "|c00FF0303"//Игрок 1(красный)
//set Color[1] = "|c000042FF"//и по порядку...
//set Color[2] = "|c001CE6B9"
//set Color[3] = "|c00540079"
//set Color[4] = "|c00FFFC01"
//set Color[5] = "|c00FE8A0E"
//set Color[6] = "|cff00ff00"
//set Color[7] = "|c00E55BB0"
//set Color[8] = "|c00959697"
//set Color[9] = "|c007EBFF1"
//set Color[10] = "|c00106246"
//set Color[11] = "|c004E2A04"
//set Color[12] = "|c00282828"// \
//set Color[13] = "|c00282828"// >>Три нейтральных игрока
//set Color[14] = "|c00282828"// /
//========================================
//----------цветовые переменные-----------
//========================================
function SDMSTextVars takes integer PlayerNumber returns string
local string array Color
set Color[0] = "|cffffa500"//Игрок 1(красный)
set Color[1] = "|cffffa500"//и по порядку...
set Color[2] = "|cffffa500"
set Color[3] = "|cffffa500"
set Color[4] = "|cffffa500"
set Color[5] = "|cffffa500"
set Color[6] = "|cffffa500"
set Color[7] = "|cffffa500"
set Color[8] = "|cffffa500"
set Color[9] = "|cffffa500"
set Color[10] = "|cffffa500"
set Color[11] = "|cffffa500"
set Color[12] = "|cff9db9eb"// \
set Color[13] = "|cff9db9eb"// >>Три нейтральных игрока
set Color[14] = "|cff9db9eb"// /
return Color[PlayerNumber]
endfunction
//========================================
//---------Возвращаемые значения----------
//========================================
function SDMSFontSize takes nothing returns real
return 10.0//Размер шрифта, которым будут писаться плавающие строки. Не ставить слишком маленький, т.к. не будет видно. Рекомендую 10-15 пунктов.
endfunction
function SDMStheTrigger takes nothing returns trigger
return udg_SDMStrigger//Здесь название любой простой глобальной переменной типа триггер.
endfunction
function SDMSLifeTime takes nothing returns real
return 1.0//Время продолжительности строки. Большой не ставить, т. к. будет лагать. Рекомендую 1-2 секунды.
endfunction
function SDMSLifeTimeSecondary takes nothing returns real
return 2.0//Дополнительное время продолжительности жизни строки. Не ставить меньше, чем основное, но чем меньше это значение, тем меньше утечка памяти. Рекомендую 120-200% от основного времени.
endfunction
function SDMSMinus takes nothing returns string
return "-"//Возвращает то, что стоит перед числом нанесённого урона. Примеры:
//"Нанесено " например: Нанесено 15
//"Получено " например: Получено 21
//"" например: 16
//Рекомендую использовать "-" из-за большей производительности
endfunction
function SDMSPlus takes nothing returns string
return ""//Возвращает то, что стоит перед числом нанесённого урона. Примеры:
//" ед. урона" например: 15 ед. урона
//" очков повреждения" например: 21 очков повреждения
//Рекомендую использовать "" из-за большей производительности. Комбинируя функции Minus и Plus, можно добиваться отличных результатов. Например: Нанесено 17 ед. урона.
endfunction
//========================================
//----Постоянные функции - не изменять!---
//========================================
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local player pl=GetOwningPlayer(u)
local player pl2=GetOwningPlayer(s)
local integer i=GetConvertedPlayerId(pl)
local texttag tt=null
local real fontSize=SDMSFontSize()
local real lifeTime=SDMSLifeTime()
local real lifeTime2=SDMSLifeTimeSecondary()
local real dmg=GetEventDamage()
local string minus=SDMSMinus()
local string plus=SDMSPlus()
local string textColor=SDMSTextVars(i-1)
local boolean b
local location l
if ( pl2 == Player(PLAYER_NEUTRAL_AGGRESSIVE) and udg_Players > 1) then
set dmg = dmg + dmg*(udg_Players-1)*0.25
if ( GetUnitStateSwap(UNIT_STATE_LIFE, u) <= dmg*(udg_Players-1)*0.25 ) then
call SetUnitState(u, UNIT_STATE_LIFE, 1.00)
else
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, u) - ( dmg*(udg_Players-1)*0.25 ) ))
endif
endif
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
set tt = CreateTextTag()
call SetTextTagText(tt, textColor+minus+I2S(R2I(dmg))+plus+"|r", TextTagSize2Height(fontSize))
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, TextTagSpeed2Velocity(96.0) * Cos(90 * bj_DEGTORAD), TextTagSpeed2Velocity(96.0) * Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, lifeTime)
call SetTextTagFadepoint(tt, 0.0)
endif
//эффекты брызг крови
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 1.0 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", u, "chest"))
else
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 0.33 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl", u, "chest"))
else
if ( dmg >= ( GetUnitState(u, UNIT_STATE_MAX_LIFE) * 0.2 )) then
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl", u, "chest"))
endif
endif
endif
//Отлов урона
if GetUnitTypeId(s) == 'u026' then //Прорубающая Атака мастера меча
set s = gg_unit_Nbbc_0091
if ( GetUnitAbilityLevelSwapped('A06B', s) > 0 ) then
if ( GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 1 ) then
if ( GetRandomInt(1, 100) <= 3 + GetUnitAbilityLevelSwapped('A06B', s) ) then
set l=GetUnitLoc(u)
call DummyCastUnit( GetOwningPlayer(s), l, 0.5, 'A045', 1, "bloodlust", s )
call RemoveLocation(l)
endif
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Spirit_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 2 ) then
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call SetUnitState(s, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, s) + I2R(GetHeroAgi(s, true)) * ( 0.04 + ( 0.04 * I2R(GetUnitAbilityLevelSwapped('A06B', s)) ) ) ) )
else
call SetUnitState(s, UNIT_STATE_LIFE, ( GetUnitStateSwap(UNIT_STATE_LIFE, s) + I2R(GetHeroAgi(s, true)) * ( 0.02 + ( 0.02 * I2R(GetUnitAbilityLevelSwapped('A06B', s)) ) ) ) )
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", s, "chest"))
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Grow_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 3 ) then
call DisableTrigger( GetTriggeringTrigger())
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call DamageArea (s, GetUnitX(u), GetUnitY(u), 200, I2R(GetHeroAgi(s, true)) * ( 0.2 + ( 0.2 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL)
else
call DamageArea (s, GetUnitX(u), GetUnitY(u), 200, I2R(GetHeroAgi(s, true)) * ( 0.1 + ( 0.1 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL)
endif
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", u, "chest"))
call EnableTrigger( GetTriggeringTrigger())
else
call DisableTrigger( GetTriggeringTrigger())
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)) * ( 0.2 + ( 0.2 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)) * ( 0.1 + ( 0.1 * I2R(GetUnitAbilityLevel(s,'A06B')) ) ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
call EnableTrigger( GetTriggeringTrigger())
endif
endif
if ( (GetRandomInt(1, 100) <= udg_Hero_Might_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 1) and GetRandomInt(1, 100) <= 35 ) then
call DisableTrigger( GetTriggeringTrigger())
call UnitDamageTarget(s, u, 50 + ( 25 * I2R(GetUnitAbilityLevelSwapped('A0A9', s)) ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger())
endif
if ( GetRandomInt(1, 100) <= udg_Hero_Spirit_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune1[GetConvertedPlayerId(GetOwningPlayer(s))] == 2 ) then
set l=GetUnitLoc(u)
if ( GetRandomInt(1, 100) <= udg_Hero_Grow_Chance[GetConvertedPlayerId(GetOwningPlayer(s))] or udg_Rune2[GetConvertedPlayerId(GetOwningPlayer(s))] == 3 ) then
call DummyCastUnit(GetOwningPlayer(s),l,0.5,'A0IK',2,"acidbomb",u)
else
call DummyCastUnit(GetOwningPlayer(s),l,0.5,'A0IK',1,"acidbomb",u)
endif
call RemoveLocation(l)
endif
endif
//эффекты предметов
if (GetUnitAbilityLevel(u, 'B02S') > 0) then
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + dmg * 2.00 ))
endif
if (GetUnitAbilityLevel(u, 'B01L') > 0) then
call SetUnitState(s, UNIT_STATE_MANA, ( GetUnitState(s, UNIT_STATE_MANA) + 6.00 ))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl", s, "overhead"))
endif
if (GetUnitAbilityLevel(u, 'B01K') > 0) then
call SetUnitState(s, UNIT_STATE_MANA, ( GetUnitState(s, UNIT_STATE_MANA) + 20.00 ))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl", s, "overhead"))
else
if (GetUnitAbilityLevel(u, 'B01E') > 0) then
call DisableTrigger( GetTriggeringTrigger() )
call UnitDamageTarget(s, u, I2R(GetHeroAgi(s, true)), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger() )
else
if (GetUnitAbilityLevel(u, 'B01G') > 0) then
call DisableTrigger( GetTriggeringTrigger() )
call UnitDamageTarget(s, u, ((GetUnitX(u)-GetUnitX(s))*(GetUnitX(u)-GetUnitX(s)) + (GetUnitY(u)-GetUnitY(s))*(GetUnitY(u)-GetUnitY(s)))*0.2, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
call EnableTrigger( GetTriggeringTrigger() )
endif
endif
endif
if ( GetUnitAbilityLevel(u, 'B02O') > 0 or GetUnitAbilityLevel(u, 'B02N') > 0 ) then
set udg_FireBlades_Target = u
call CreateUnit( pl2, 'u00W', GetUnitX(u), GetUnitY(u), bj_UNIT_FACING )
endif
if (GetUnitAbilityLevel(u, 'B03M') > 0) then
if ( dmg > 50.00 ) then
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + 50.00 ))
else
call SetUnitState(u, UNIT_STATE_LIFE, ( GetUnitState(u, UNIT_STATE_LIFE) + dmg ))
endif
endif
//
call PolledWait(lifeTime2)
set u=null
set s=null
set pl=null
set pl2=null
set l=null
set i=0
set fontSize=0
set lifeTime=0
set lifeTime2=0
set dmg=0
set minus=""
set plus=""
set textColor=""
call DestroyTextTag(tt)
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(SDMStheTrigger(),GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function SDMSGroupFunction takes nothing returns nothing
local unit u=GetEnumUnit()
call TriggerRegisterUnitEvent(SDMStheTrigger(),u,EVENT_UNIT_DAMAGED)
set u=null
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
local trigger TextTagCreate=SDMStheTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter,GetPlayableMapRect())
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
call ForGroupBJ(GetUnitsInRectAll(GetPlayableMapRect()),function SDMSGroupFunction)
set UnitEnter=null
set TextTagCreate=null
endfunction
//========================================
//---------------Не трогать!--------------
//========================================
function InitTrig_the_SDM_Ttrigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(SDMStheTrigger(),function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Карта прилагается
Принятый ответ
Эмм что за ерунда, сократил код, убрав всё лишнее, но утечки все равно остаются, по 1.5 - 2 хэндла за каждое нанесение урона (тип хэндла не знаю как посмотреть). Когда триггер отключаешь, то всё нормально.
Сокращенный код
function SDMSCreateTextTag takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit s=GetEventDamageSource()
local integer i=GetConvertedPlayerId(GetOwningPlayer(u))
local texttag tt=CreateTextTag()
local real dmg=GetEventDamage()
if ( dmg > 1.00 ) and ( dmg < 9999.00 ) then
if GetPlayerId(GetOwningPlayer(u))==12 then
call SetTextTagText(tt, "|cff9db9eb-"+I2S(R2I(dmg))+"|r", 0.023)
else
call SetTextTagText(tt, "|cffffa500-"+I2S(R2I(dmg))+"|r", 0.023)
endif
call SetTextTagPosUnit(tt, u, 0)
call SetTextTagColor(tt, 255, 255, 255, 255)
call SetTextTagVelocity(tt, 0.05325*Cos(90 * bj_DEGTORAD), 0.05325*Sin(90 * bj_DEGTORAD))
call SetTextTagPermanent(tt, false)
call SetTextTagLifespan(tt, 1.0)
call SetTextTagFadepoint(tt, 0.0)
endif
call PolledWait(2.0)
call DestroyTextTag(tt)
set u=null
set s=null
set i=0
set dmg=0
set tt=null
endfunction
function SDMSTriggerRegisterUnitDamaged takes nothing returns nothing
call TriggerRegisterUnitEvent(udg_SDMStrigger,GetEnteringUnit(),EVENT_UNIT_DAMAGED)
endfunction
function theSDMSTriggerActions takes nothing returns nothing
local trigger UnitEnter=CreateTrigger()
call TriggerRegisterEnterRectSimple(UnitEnter, gg_rct_Arena)
call TriggerAddAction(UnitEnter,function SDMSTriggerRegisterUnitDamaged)
set UnitEnter=null
endfunction
function InitTrig_the_SDMS_Trigger takes nothing returns nothing
local trigger tr=CreateTrigger()
set udg_SDMStrigger=CreateTrigger()//Тут также меняется название глобальной переменной типа триггер.
call TriggerAddAction(udg_SDMStrigger,function SDMSCreateTextTag)
call TriggerRegisterTimerEventSingle(tr,0.0)
call TriggerAddAction(tr,function theSDMSTriggerActions)
set tr=null
endfunction
Wait вызывает утечки ((
Пришлось делать через таймер
Пришлось делать через таймер
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Советую почитать про утечки как следует. Или внимательно просмотреть карту Leak вот здесь xgm.guru/p/wc3/bpe
Melissa:
Пришлось делать через таймер