Настакивается таймер

nranenko

Новичок
28 Фев 2019
3
0
Здравствуйте. Пытаюсь воссоздать режим overthrow для того чтобы более-менее вникнуть во все тонкости аддонов. В центре карты у меня находится триггер, у которого есть output, вызывающий функцию у скрипта:

function OnStartTouch(trigger)
local hero = trigger.activator
_G.timer = Timers:CreateTimer(0, function() hero:AddExperience(10, 0, false, true) hero:ModifyGold(4, true, 0) return 0.2 end)
end

При выходе с триггера срабатывает функция, которая удаляет таймер:

function OnEndTouch(trigger)
Timers:RemoveTimer(_G.timer)
end

Однако, когда персонаж умирает в зоне действия триггера, таймер настакивается после возрождения и продолжает тикать, независимо от того, где находится персонаж. Попытался создать на персонаже отдельный output, вызывающий ту же самую функцию удаления таймера, но ничего не получилось. В чем может быть проблема? Можно ли реализовать это другим, более оптимальным и удобным способом? Заранее спасибо.
 
20 Дек 2016
892
170
В оверфроу это сделано аурой без всяких триггеров и таймеров, и это оптимальный способ.
Как сделать ауру, думаю, разберешься. CreateModifierThinker поможет статично разместить ее в центре карты.

Касательно триггеров и таймеров:
Вроде где-то настройках триггера можно установить вызов функции выхода при смерти, но этот вариант все равно отвратителен, т.к. если записывать таймер в глобал, то когда в триггер будет заходить другой герой, таймер будет перезаписан и не будет сниматься со старого героя.
Можно записывать таймер непосредственно в героя, но намного лучше (и проще) сделать проверку внутри функции таймера, находится ли герой в триггере (и возвращать nil, если не находится).
 

nranenko

Новичок
28 Фев 2019
3
0
В оверфроу это сделано аурой без всяких триггеров и таймеров, и это оптимальный способ.
Как сделать ауру, думаю, разберешься. CreateModifierThinker поможет статично разместить ее в центре карты.

Касательно триггеров и таймеров:
Вроде где-то настройках триггера можно установить вызов функции выхода при смерти, но этот вариант все равно отвратителен, т.к. если записывать таймер в глобал, то когда в триггер будет заходить другой герой, таймер будет перезаписан и не будет сниматься со старого героя.
Можно записывать таймер непосредственно в героя, но намного лучше (и проще) сделать проверку внутри функции таймера, находится ли герой в триггере (и возвращать nil, если не находится).

Как вообще можно разобраться в том, как написан, например, overthrow? Там же в папках с кастомкой только скомпилированные файлы, предназначенные для игры, а не для редактирования?
 

nranenko

Новичок
28 Фев 2019
3
0
В оверфроу это сделано аурой без всяких триггеров и таймеров, и это оптимальный способ.
Как сделать ауру, думаю, разберешься. CreateModifierThinker поможет статично разместить ее в центре карты.

Касательно триггеров и таймеров:
Вроде где-то настройках триггера можно установить вызов функции выхода при смерти, но этот вариант все равно отвратителен, т.к. если записывать таймер в глобал, то когда в триггер будет заходить другой герой, таймер будет перезаписан и не будет сниматься со старого героя.
Можно записывать таймер непосредственно в героя, но намного лучше (и проще) сделать проверку внутри функции таймера, находится ли герой в триггере (и возвращать nil, если не находится).

И видимо таймер стакается не из-за смертей, а из-за того что в триггер заходят разные герои, но я не совсем понял как сделать адекватную проверку на нахождения героя в триггере)
 
20 Дек 2016
892
170
Там же в папках с кастомкой только скомпилированные файлы, предназначенные для игры, а не для редактирования?
Нет. В content все так же есть исходники оверфроу. Ну а луа скрипты ты же сразу в game создаешь, им никакая компиляция не нужна, они в таком виде и используются дотой)

как сделать адекватную проверку на нахождения героя в триггере
Распринтуй таблицу, которая в OnStartTouch передается. Там вроде всего два поля, одно из них - сам триггер.
table.foreach( trigger, print )
И загляни в консоль.
Вот так проверяется нахождение героя в триггере
trigger:IsTouching(hero)
Функции в луа имеют доступ к контексту, в котором они были объявлены. То есть итоговый код будет как-то так выглядеть:
Lua:
function OnStartTouch(trigger)
    local hero = trigger.activator
    local hTrigger = trigger.trigger --[[ Не помню точно, как называется поле, хранящее в себе триггер.
Вместо второго trigger тут может быть что-то другое, ты должен это понять по результатам принта таблицы ]]
    Timers:CreateTimer(0, function()
        if hTrigger:IsTouching(hero) then --[[ если герой в триггере, то даем бонусы и продливаем таймер ]]
            hero:AddExperience(10, 0, false, true)
            hero:ModifyGold(4, true, 0)
            return 0.2
        end
        --[[ *Так как return находится внутри условия, он будет выполнен только когда герой в триггере.
             *Если в луа функция ничего не возвращает, то считается, что она вернула nil
             *Таймер уничтожается, когда функция вернуа nil.
        Объединяя эти 3 факта не сложно понять, что если герой окажется не в триггере, таймер будет остановлен. ]]
    end)
end
И все, не надо никаких OnEndTouch, такой таймер сам себя уберет, когда герой выйдет из триггера.
 
Последнее редактирование:
Реклама: