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

map_maiker #23 - 3 months ago 0
Голосов: +0 / -0
Кстати, ты можешь делать намного интереснее вещи с триггерной атакой, вплоть до кривой цепной молнии скакающей по юнитам накладывающая дебаффы с отталкиванием и всей ерундой что только можешь придумать
Да, я знаю. Дамми-касты и всё такое. rsfghd:
Чистый гуи да, но у тебя есть кастом скрипт, где можно обнулить точки и это всё, что в принципе нужно, чтобы эта система работала без утечек
Я же не про утечки. Например, как в гуи прицепить функцию к таймеру?
PT153:
А по теме - динамическое создание триггеров тут не нужно.
А можно подробнее?
quq_CCCP:
во первых время существования триггера нужно, вдруг промах,
Да, в случае промаха урон просто откладывается. Но я не придумал как можно прицепить удаление триггера по времени. Самый правильный вариант - добавить событие в триггер, но... В общем, как это сделать чтобы работало - я не придумал.
PT153 #24 - 3 months ago 0
Голосов: +0 / -0
map_maiker, юнит входит на карту, на него и добавляем событие на получение урона. Всё. А все эти костыли с событием на атаку бред. Тем более, что это замах, а не сама атака. И на каждый замах по новому триггеру - бред.
quq_CCCP #25 - 3 months ago 0
Голосов: +0 / -0
map_maiker, с мемхаком куда веселее, просто смотришь тип урона и атаки.
map_maiker #26 - 3 months ago 0
Голосов: +0 / -0
PT153:
map_maiker, юнит входит на карту, на него и добавляем событие на получение урона. Всё. А все эти костыли с событием на атаку бред. Тем более, что это замах, а не сама атака. И на каждый замах по новому триггеру - бред.
Звучит как создание одного громоздкого триггера...
quq_CCCP:
map_maiker, с мемхаком куда веселее, просто смотришь тип урона и атаки.
К мемхаку я только присматриваюсь. Издалека. Мб и до него руки дойдут.
PT153 #27 - 3 months ago 2
Голосов: +2 / -0
Звучит как создание одного громоздкого триггера...
Что лучше, чем бред с постоянным созданием и удалением триггеров. Сколько писал на варе, ни разу такой дичи не потребовалось.
quq_CCCP #28 - 3 months ago 1
Голосов: +1 / -0
map_maiker, проблема в другом - что такая реализация очень хромает и хоть как то еще годится для мили юнитов, для ренжей никак, можно стопя атаку провоцировать создание пачки триггеров, все яды, или другие виды урона от лица героя тоже заставят триггер сработать. Ибо нужно ставить еще событие время вышло (секунды полторы), события - юнит отдал приказ - цель точка, цель обьект, без указания цели, чтобы удалять триггер не дожидаясь урона по цели, но это годится для милишников, ренжам - только собтие время вышло (примерное время за сколько долетит снаряд до цели +- секунда). И все. Есть вариация еще с отрецательным маг уроном, это когда всем на карте вручена пассивка рунных браслетов, если урон выше 0 - он физический или чистый, иначе магический (ну условно, не будем вдаватся в подробности типов урона и атаки).
Ну и естественно компенсировать лечение от отрицательного маг урона, забирать пассивку браслетов и еще раз наносить урон от лица того кто до этого нанес урон, при этом отключив триггеры реагирующие на урон, после вернуть все наместо. Вот такая реализация кроме ресурсоемкости уже почти идеальна и как то заобузить или забаговать её не получится.

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

кстати там какраз выше производительность.
map_maiker #29 - 3 months ago 0
Голосов: +0 / -0
Что лучше, чем бред с постоянным созданием и удалением триггеров.
Как я понимаю, правильное удаление триггера не оставляет утечек. Каждый такой триггер живёт непродолжительное время, если добавить соответствующее событие.
Я не особо смотрел на производительность, но четыре сотни стрелков с задержкой между атаками 0.4 тормозили не больше чем любые другие четыре сотни сражающихся юнитов.
Так почему это бред?
события - юнит отдал приказ - цель точка, цель обьект, без указания цели,
А почему это не подойдёт к ренжам? В контексте отслеживания обычной атаки, не способностями.
quq_CCCP:
ренжам - только собтие время вышло (примерное время за сколько долетит снаряд до цели +- секунда)
А зачем +- секунда?
С наработкой детекта урона из мемхака у тебя появляется возможность проверять типы урона и прочие параметры в потоке любого триггера, сработавшего на событие - юнит получает урон.
кстати там какраз выше производительность.
Хм, ясно.
quq_CCCP #30 - 3 months ago 0
Голосов: +0 / -0
map_maiker, потому что нужно думать, ибо пока летит снаряд, юнит уже завершил атаку и может быть отдан новый приказ, что само собой все сломает.
Зачем секунда, другая - а чтобы исключить возможность промаха. чтобы у снаряда было время долететь и ударить, и если за отведенное время это го не получилось - то значит промах и отключаем и удаляем триггер. Как удалять триггеры правильно можно глянуть в доте айсфрога или в наработках на сайте (код баратрума и урсы кто то выкладывал).
Еще раз - подобные способы очень ограничены и их старается никто не юзать, кроме совсем простых вещей, плодить триггеры для сотен юнитов очень хреновая идея, потому что есть способы куда проще и оптимальнее.
PT153 #31 - 3 months ago 2
Голосов: +2 / -0
Так почему это бред?
Конкретно это реализация - потому что замах произойдёт, а атака нет, триггер будет создан, после чего атакованный получит урон от другого юнита, и созданный триггер сработает. И как я уже сказал, для данной задачи плодить триггеры не нужно, достаточно одного.
rsfghd #32 - 3 months ago (изм. ) 0
Голосов: +0 / -0
Если я не ошибаюсь, при удалении триггера событие же всё равно остаётся в памяти?

Звучит как создание одного громоздкого триггера...
Мой пример по такому принципу и работает, один триггер с регистрацией для всех юнитов на карте и те, кто входят в её область

Да, я знаю. Дамми-касты и всё такое
Ну вообще даммикаст только касательно дебаффов, всё остальное триггерно)
Да и на примере молний, разноцветную даммикастом фиг сделаешь)

Я же не про утечки. Например, как в гуи прицепить функцию к таймеру?
Что мешает другой триггер создать?)
Тебе в любом случае тут таймер не нужен был и я об этом и говорю, что твою затею спокойно на гуи можно было сделать