Оптимальна ли реализация?
Написал простенькую систему разброса урона, чисто jass без диалектов и мемхака.
Собственно, вопрос в том, оптимально ли это или есть какие-то неочевидные минусы, способные как-то навредить?
//attack -> add damage event -> function


function damaging takes nothing returns nothing
    local integer i = 0
    local integer h = GetHandleId(GetExpiredTimer())
    local unit damager = LoadUnitHandle(udg_data, h, 0)
    local unit damaged = LoadUnitHandle(udg_data, h, 1)
    local real radius = GetRandomReal(udg_minradius, udg_maxradius) 
    local location tmp = PolarProjectionBJ(GetUnitLoc(damaged), radius, GetRandomReal(0, 360))      
    local unit u = CreateUnit(GetOwningPlayer(damager), 'h000', GetLocationX(tmp), GetLocationY(tmp), 0 )  
    call SetUnitInvulnerable( damaged, false )
    call DestroyEffect(AddSpecialEffectLoc( udg_effect_name, tmp ))
    call UnitDamagePointLoc( u, 0, udg_damage_radius, tmp, udg_damage, ATTACK_TYPE_PIERCE, DAMAGE_TYPE_NORMAL ) 
    call RemoveUnit(u)
    set u = null
endfunction

function get_damage takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(GetTriggeringTrigger())
    local unit damager = LoadUnitHandle(udg_data, h, 0)
    local unit damaged = LoadUnitHandle(udg_data, h, 1)
    local integer h = GetHandleId(t)                                     
    call SaveUnitHandle(udg_data, h, 0, damager)
    call SaveUnitHandle(udg_data, h, 1, damaged)
    call SetUnitInvulnerable( GetTriggerUnit(), true )
    call TimerStart(t, 0.0, false, function damaging)
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Trig_attacking_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetAttacker()) == 'hrif'
endfunction

function Trig_attacking_Actions takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer h = GetHandleId(t)
    call TriggerRegisterUnitEvent( t, GetTriggerUnit(), EVENT_UNIT_DAMAGED )            
    call TriggerAddAction(t, function get_damage)
    call SaveUnitHandle(udg_data, h, 0, GetAttacker())
    call SaveUnitHandle(udg_data, h, 1, GetTriggerUnit())
endfunction

function InitTrig_attacking takes nothing returns nothing
    set gg_trg_attacking = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_attacking, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_attacking, Condition( function Trig_attacking_Conditions ) )
    call TriggerAddAction( gg_trg_attacking, function Trig_attacking_Actions )
endfunction



Views: 316

makkad #2 - 3 months ago 0
Голосов: +0 / -0
Могу сказать, что TriggerAddAction вызывает утечку памяти, если отдельно его не сохранять и позже удалять. Лучше через TriggerAddCondition вызывать действия триггера.
rsfghd #3 - 3 months ago (изм. ) 0
Голосов: +0 / -0
Нет, не оптимально, юзаешь точки вместо координат и даже не обнуляешь их, переменные юнитов тоже не обнулил, таймеры не обнуляешь, да и локальные триггеры тоже в null можно

local location tmp = PolarProjectionBJ(GetUnitLoc(damaged), radius, GetRandomReal(0, 360)) 
-->
local real x = GetUnitX(damaged)+radius*Cos(GetRandomReal(0,360)*bj_DEGTORAD))
local real y = GetUnitY(damaged)+radius*Sin(GetRandomReal(0,360)*bj_DEGTORAD))
local unit u = CreateUnit(GetOwningPlayer(damager), 'h000',x, y, 0 ) 
Координаты обнулять не нужно

call UnitDamagePointLoc( u, 0, udg_damage_radius, tmp, udg_damage, ATTACK_TYPE_PIERCE, DAMAGE_TYPE_NORMAL )
Функция дамажит всех без исключения если не ошибаюсь, лучше самим юнитом через цикл/группу дамажить юнитов

Ой посмотрел на это всё, вообще желательно всё переписать, зачем сохранять что-то в хэш-таблицу если ты уже создал триггер для этого
map_maiker #4 - 3 months ago 0
Голосов: +0 / -0
call TriggerAddCondition( gg_trg_attacking, Condition( function Trig_attacking_Conditions ) )
То есть, можно написать нечто в духе
call TriggerAddCondition( gg_trg_attacking, function Trig_attacking_Actions )
и оно будет работать?
Нет, не оптимально, юзаешь точки вместо координат и даже не обнуляешь их, переменные юнитов тоже не обнулил, таймеры не обнуляешь, да и локальные триггеры тоже в null можно
Хм, ясно. А хеш-таблицу по ключу не надо очищать?
А сама идея норм или есть лучше варианты? С тз алгоритма.

Функция дамажит всех без исключения если не ошибаюсь, лучше самим юнитом через цикл/группу дамажить юнитов
В данном случае так и задумывалось...
rsfghd:
Ой посмотрел на это всё, вообще желательно всё переписать, зачем сохранять что-то в хэш-таблицу если ты уже создал триггер для этого
Значения передавать...
rsfghd #5 - 3 months ago (изм. ) 0
Голосов: +0 / -0
Не нужно значения передавать, у тебя триггер реагирует на дамаг по этому юниту, ты уже можешь получить нужные тебе переменные с самого триггера

Как ты вообще сохранил карту без ошибок, если у тебя пересоздание переменной идёт?

закинул счётчик хэндлов, можешь посмотреть что происходит
Прикрепленные файлы
makkad #6 - 3 months ago 0
Голосов: +0 / -0
local code c=function Trig_attacking_Actions
call TriggerAddCondition( gg_trg_attacking, Filter(c) )
rsfghd #7 - 3 months ago 0
Голосов: +0 / -0
Сейчас попробую реализовать твою задумку, если никто не преуспеет)
map_maiker #8 - 3 months ago 0
Голосов: +0 / -0
Не нужно значения передавать, у тебя триггер реагирует на дамаг по этому юниту, ты уже можешь получить нужные тебе переменные с самого триггера
Хм, логично. Как-то не подумал.
rsfghd:
Как ты вообще сохранил карту без ошибок, если у тебя пересоздание переменной идёт?
Забавно. Ну как-то так получилось. Мб вар не считает это ошибкой?
makkad:
local code c=function Trig_attacking_Actions
call TriggerAddCondition( gg_trg_attacking, Filter(c) )
Хм, а что Filter делает?

закинул счётчик хэндлов, можешь посмотреть что происходит
Вылет в главное меню...
rsfghd #9 - 3 months ago 0
Голосов: +0 / -0
map_maiker, сохрани карту перед запуском

И возможно стоит проверить эти галочки, раз уж вар не выдал ошибку с пересозданием переменной
Прикрепленные файлы
map_maiker #10 - 3 months ago 0
Голосов: +0 / -0
map_maiker, сохрани карту перед запуском
У меня обычный редактор, если это имеет значение. Как-то не дошли пока руки поставить jngp.
makkad #11 - 3 months ago 0
Голосов: +0 / -0
map_maiker, Filter() - в твоём случае позволит подставить вместо функции, которая должна возвратить boolean, подставить функцию, которая возвращает nothing
rsfghd #12 - 3 months ago 0
Голосов: +0 / -0
map_maiker, лол, как ты вообще работаешь с кодом в обычном редакторе?
Многое теряешь без джнгп, и скорее всего, мою версию не заценишь