В данный момент думаю изменить упоротую систему привязки ивентов к глобальному таймеру на менее упоротую, но, поскольку вряд ли это последнее изменение, ищу советов, основанных на личном опыте (или гугле, да).
Упоротая система
Хэштейбл с 50000 строк для таймера. В ячейках: 0 - число ячеек в строке, 1 - Запускаемый на этом тике триггер, 2 - Целочисленное, которое при запуске триггера заносится в глобалку, 3 - Юнит, который при запуске заносится в глобалку(иногда позволяет избегать муторных стекообразных костылей). Далее 123 повторяются. После выполнения действий со строкой child_0 становится = 0. Планировал 2 и 3 просто перевести в неопределенные параметры, без привязки к типу, а 1 в экзекут функции (но, в случае с экзекута триггера с ним так удобно работать через WE :) )
Проблема возникает когда нужно делать что-то с малым периодом. Опять же, передвижение юнита с 0.01 (покуда существуют 100Hz+ мониторы, я буду юзать период 0.01(хотя периодичность легко меняется, т..к. всё в дефайнах)). В этом случае нужно проделывать дофига действий каждый тик. Не айс.
Менее упоротая система
Хэштейбл с 0 строк для таймера. В ячейках: 0 - число ячеек в строке, 1 - Запускаемый при (2==3) триггер, 2 - текущий тик для события, 3 - Периодичность события, 4 - Число тиков(уменьшается с каждым проком. Если равно нулю - приравнять к -1. Ячейки с -1 пропускаются циклом - обработчиком. Если событие бесконечное - приравнять к -2 (пока минусуя единицу оно дойдет до нуля через переполнение целочисленной - пройдет 12к часов при тикрейте в 0.01)), 5 и 6 - под любые данные. (если данных нет - лишнюю память не жрет, так ведь?)
В этом случае нет ограничения в 50к тиков, как устанавливалось до этого. И, в целом, я пока не вижу минусов у этой системы. Во избежание слишком лютого проседания памяти планирую флашить строку, если обработчик нашел только минус единицы. (бесконечные ивенты легко засунуть обратно).
Мхм... Теперь, изложив свои мысли вижу смысл сделать 3 строки в хештейбле - 1 для одноразовых проверок, 2 - для периодичных, 3 - для бесконечных ивентов. И флашить по строке, когда в 1 или 2 остаются лишь минус единицы.
И да, мне в кайф изобретать велосипеды.

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

Diaboliko, xgm.guru/p/blog-nvc123/101422
это про то как вешать всякую фигню на общий таймер
хэш тут нафиг не нужен т.к. таймер 1
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
21
8 лет назад
Отредактирован Raised
0
Ну, я делал так
   globals
      timer periodic
      real period = 0.01
      group restoreHP
   endglobals

   function restoreParamatersCallback takes nothing returns nothing
      
      local integer iD = GetHandleId(GetEnumUnit())
      local real hpRegen = LoadReal(Hash,iD,HASH_LIFE_REGENERATION_INDEX)
      local real manaRegen = LoadReal(Hash,iD,HASH_MANA_REGENERATION_INDEX)
         
         call SetUnitState(GetEnumUnit(),UNIT_STATE_LIFE,GetUnitState(GetEnumUnit(),UNIT_STATE_LIFE)+hpRegen*restorationPeriod)
         call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,GetUnitState(GetEnumUnit(),UNIT_STATE_MANA)+manaRegen*restorationPeriod)            

   endfunction
   
   function periodicActions takes nothing returns nothing //Тут просто вызовы всего что нужно
      call ForGroup(restoreHP,function restoreHPCallback)
   endfunction

   function Initialization takes nothing returns nothing  
      set periodic = CreateTimer()
      call TimerStart(periodic,period,true,function periodicActions)
   endfunction

А вообще создать триггер и добавить событие - глобальный таймер истекает, не?
0
20
8 лет назад
Отредактирован Diaboliko
0
GF RaiseD:
Ну, я делал так
   globals
      timer periodic
      real period = 0.01
      group restoreHP
   endglobals

   function restoreParamatersCallback takes nothing returns nothing
      
      local integer iD = GetHandleId(GetEnumUnit())
      local real hpRegen = LoadReal(Hash,iD,HASH_LIFE_REGENERATION_INDEX)
      local real manaRegen = LoadReal(Hash,iD,HASH_MANA_REGENERATION_INDEX)
         
         call SetUnitState(GetEnumUnit(),UNIT_STATE_LIFE,GetUnitState(GetEnumUnit(),UNIT_STATE_LIFE)+hpRegen*restorationPeriod)
         call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,GetUnitState(GetEnumUnit(),UNIT_STATE_MANA)+manaRegen*restorationPeriod)            

   endfunction
   
   function periodicActions takes nothing returns nothing //Тут просто вызовы всего что нужно
      call ForGroup(restoreHP,function restoreHPCallback)
   endfunction

   function Initialization takes nothing returns nothing  
      set periodic = CreateTimer()
      call TimerStart(periodic,period,true,function periodicActions)
   endfunction
Система подразумевает что все действия, для которых кто-либо использовал бы таймер, реализуются через один глобальный таймер.
А вообще создать триггер и добавить событие - глобальный таймер истекает, не?
Таймер один. Он может на этом тике двинуть юнита, на следующем - двинуть юнита, ..... через 300 тиков сделать 10 действий и двинуть юнита.
Для таких целей моя "менее упоротая система" подходит, вроде как... Но во второй раз я мог не учесть что-то также как и в первый.
0
21
8 лет назад
0
Таймер один. Он может на этом тике двинуть юнита, на следующем - двинуть юнита, ..... через 300 тиков сделать 10 действий и двинуть юнита.
С таким не сталкивался.
0
30
8 лет назад
0
С таким не сталкивался.
Опенсорс доты посмотри например
Этот комментарий удален
0
20
8 лет назад
0
Опенсорс доты посмотри например
TL;DR же. Я попытался вникнуть в систему тоадкопа с пузырьками. На вторую попытку вникать в чужую систему мозгов не осталось.
4
16
8 лет назад
4
>> юнита с 0.01 (покуда существуют 100Hz+ мониторы, я буду юзать период 0.01(хотя периодичность легко меняется, т..к. всё в дефайнах))
пока варкрафт перерисовывает экран не чаще 64 раз в секунду, ты просто выкидываешь на воздух процессорные тики ради неизвестно чего. юниты также передвигаются периодами бОльшими, чем 0.01. Согласно моим прикидкам - каждые 1/32 секунды, ибо именно так хранится скорость передвижения.
Но да, изобретать велосипед с таймерами в 2016 - только если тебе нужно что-то экзотическое. практика показывает, что обычно не нужно. Сперва наброски, потом оформление. не наоборт.
0
20
8 лет назад
Отредактирован Diaboliko
0
DracoL1ch:
>> юнита с 0.01 (покуда существуют 100Hz+ мониторы, я буду юзать период 0.01(хотя периодичность легко меняется, т..к. всё в дефайнах))
пока варкрафт перерисовывает экран не чаще 64 раз в секунду, ты просто выкидываешь на воздух процессорные тики ради неизвестно чего. юниты также передвигаются периодами бОльшими, чем 0.01. Согласно моим прикидкам - каждые 1/32 секунды, ибо именно так хранится скорость передвижения.
Но да, изобретать велосипед с таймерами в 2016 - только если тебе нужно что-то экзотическое. практика показывает, что обычно не нужно. Сперва наброски, потом оформление. не наоборт.
Юниты при естесственном передвижении адекватно интерполируются(или, быть может, дело только в анимации). В случае триггерного передвижения - оно выглядит рвано.
А вот про ограничение в фпс не слышал.
3
30
8 лет назад
3
А вот про ограничение в фпс не слышал.
Отлов фпс, afaik, работает через отлов того, сколько кадров в секунду может отрисовать видеокарта, а не по факту отрисовки кадров на мониторе. Некоторые приложения (в основном старые) могут не поддерживать отрисовку больше определённого количества в секунду.
0
28
8 лет назад
0
Diaboliko, xgm.guru/p/blog-nvc123/101422
это про то как вешать всякую фигню на общий таймер
хэш тут нафиг не нужен т.к. таймер 1
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.