Написал простенькую систему разброса урона, чисто 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

Принятый ответ

Нет, не оптимально, юзаешь точки вместо координат и даже не обнуляешь их, переменные юнитов тоже не обнулил, таймеры не обнуляешь, да и локальные триггеры тоже в 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 )
Функция дамажит всех без исключения если не ошибаюсь, лучше самим юнитом через цикл/группу дамажить юнитов

Ой посмотрел на это всё, вообще желательно всё переписать, зачем сохранять что-то в хэш-таблицу если ты уже создал триггер для этого
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
22
3 года назад
Отредактирован makkad
0
PT153, Разница в утечке памяти. Вот тестовая карта. А удалять - это больше строчек на код тратить, конкретно в этом случае. Если sleep не нужен.
Загруженные файлы
0
28
3 года назад
Отредактирован PT153
0
makkad, убедил. TriggerClearActions и ResetTrigger не нужно, это ничего не удаляет.
0
22
3 года назад
0
PT153:
makkad, убедил. TriggerClearActions и ResetTrigger не нужно, это ничего не удаляет.
Да. И это тоже проверялось.
1
16
3 года назад
1
AddAction создает уникальный объект при каждом обращении, а AddCondition кэширует объекты. поэтому в динамических триггерах, где всё создается и разрушается множество раз за игру, нужно использовать именно Condition
Filter() и Condition() одно и то же
3
32
3 года назад
Отредактирован quq_CCCP
3
Детект урона что ты описал, уже есть на сайте и готовый, широко юзается в доте фрога - и это вызывает баги, не столь критичные но тем не менее, ибо замахиваясь ты провоцирует событие триггера, который создаёт еше 1 триггер, который ждёт любого урона по цели, что неправильно, во первых время существования триггера нужно, вдруг промах, так же событие смерти, если жертва умерла - то закругляемся.
Про кондишены правильно написал лич, ибо триггер акшин это объект, который сам по себе не удаляется.
0
9
3 года назад
0
Кстати, ты можешь делать намного интереснее вещи с триггерной атакой, вплоть до кривой цепной молнии скакающей по юнитам накладывающая дебаффы с отталкиванием и всей ерундой что только можешь придумать
Да, я знаю. Дамми-касты и всё такое. rsfghd:
Чистый гуи да, но у тебя есть кастом скрипт, где можно обнулить точки и это всё, что в принципе нужно, чтобы эта система работала без утечек
Я же не про утечки. Например, как в гуи прицепить функцию к таймеру?
PT153:
А по теме - динамическое создание триггеров тут не нужно.
А можно подробнее?
quq_CCCP:
во первых время существования триггера нужно, вдруг промах,
Да, в случае промаха урон просто откладывается. Но я не придумал как можно прицепить удаление триггера по времени. Самый правильный вариант - добавить событие в триггер, но... В общем, как это сделать чтобы работало - я не придумал.
0
28
3 года назад
0
map_maiker, юнит входит на карту, на него и добавляем событие на получение урона. Всё. А все эти костыли с событием на атаку бред. Тем более, что это замах, а не сама атака. И на каждый замах по новому триггеру - бред.
0
32
3 года назад
0
map_maiker, с мемхаком куда веселее, просто смотришь тип урона и атаки.
0
9
3 года назад
0
PT153:
map_maiker, юнит входит на карту, на него и добавляем событие на получение урона. Всё. А все эти костыли с событием на атаку бред. Тем более, что это замах, а не сама атака. И на каждый замах по новому триггеру - бред.
Звучит как создание одного громоздкого триггера...
quq_CCCP:
map_maiker, с мемхаком куда веселее, просто смотришь тип урона и атаки.
К мемхаку я только присматриваюсь. Издалека. Мб и до него руки дойдут.
2
28
3 года назад
2
Звучит как создание одного громоздкого триггера...
Что лучше, чем бред с постоянным созданием и удалением триггеров. Сколько писал на варе, ни разу такой дичи не потребовалось.
1
32
3 года назад
1
map_maiker, проблема в другом - что такая реализация очень хромает и хоть как то еще годится для мили юнитов, для ренжей никак, можно стопя атаку провоцировать создание пачки триггеров, все яды, или другие виды урона от лица героя тоже заставят триггер сработать. Ибо нужно ставить еще событие время вышло (секунды полторы), события - юнит отдал приказ - цель точка, цель обьект, без указания цели, чтобы удалять триггер не дожидаясь урона по цели, но это годится для милишников, ренжам - только собтие время вышло (примерное время за сколько долетит снаряд до цели +- секунда). И все. Есть вариация еще с отрецательным маг уроном, это когда всем на карте вручена пассивка рунных браслетов, если урон выше 0 - он физический или чистый, иначе магический (ну условно, не будем вдаватся в подробности типов урона и атаки).
Ну и естественно компенсировать лечение от отрицательного маг урона, забирать пассивку браслетов и еще раз наносить урон от лица того кто до этого нанес урон, при этом отключив триггеры реагирующие на урон, после вернуть все наместо. Вот такая реализация кроме ресурсоемкости уже почти идеальна и как то заобузить или забаговать её не получится.

С наработкой детекта урона из мемхака у тебя появляется возможность проверять типы урона и прочие параметры в потоке любого триггера, сработавшего на событие - юнит получает урон.

кстати там какраз выше производительность.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.