Если работает - отлично. Я бы, правда, для чистоты эксперимента вызывал сборку вне контекста в котором плодятся потенциально мусорные объекты, но это я уже придираюсь. Хотя странно - у тебя же раньше сжирало анонимные таймеры. Или они были до инициализации, как и триггеры которые сжирает если выдавать им события до инициализации?
Опять напоминаю про сборщик мусора. Нужно проверить падает ли на автоматической сборке мусора то, что падает при ручной. Что-то мне подсказывает, что код из этой статьи не выдерживает принудительную сборку мусора.
Один из вариантов как отследить момент срабатывания сборщика мусора - добавить финализатор к таблице через метаметод __gc, потом убить все ссылки на эту таблицу и ждать, параллельно засирая память.
В момент срабатывания финальной фазы сборки мусора перед удалением нашей таблицы вызовется __gc из её метатаблицы.
ScopteRectuS, таблица Heroes тебе еще пригодится если у героев появятся механики, требующие что-то делать, например, при входе героя на карту или при смерти, индивидуально для разных героев. Эти действия можно будет занести в таблицу Heroes аналогично тому как можно занести действия способностей. Или, например, если для героев нужно будет хранить какие-то дополнительные данные по равкоду героя.
ScopteRectuS, идея в том чтобы просто их разделить. Heroes - примерно так как сейчас, с ключами по равкодам героев, а в значениях таблицы с инфой по героям, включая перечисление их способностей. А в Abilities - ключи это равкоды способностей, а значения - таблицы способностей.
Сейчас у тебя в Ability складывается два типа данных - по равкоду героя его список способностей, а по каким-то другим ключам таблицы с данными конкретных способностей.
Естественно, я исхожу из предположения что триггеры срабатывания способностей переделаны на получение таблицы способности по равкоду, вместо отдельных триггеров на каждую способность.
Конструкция "if GetSpellAbilityId( ) ~= Ability[ HERO_DEATH_KNIGHT ][ Q ] then return end" ужасна - это вызов функции и два обращения к таблице/массиву в глобальной переменной. И хуже всего - эта конструкция вызывается каждый раз когда срабатывает триггер, а срабатывает он на все способности. Когда способностей будет сто и все на разных триггерах - аналогичная конструкция будет вызываться уже сто раз при каждом касте любой способности.
Я бы еще рекомендовал хранить в разных таблицах сами способности и привязку способностей к героям.
Грубо говоря, герои в таблице Heroes, способности в таблице Abilities. Позволит ускорить перебор и избежать ненужных проверок.
Ability = { }
Ability.DeathCoil = { }
function Ability.DeathCoil.init( )
print( 321 )
end
function InitAllAbilities( )
for parentKey, parentValue in pairs( Ability ) do
if (type( parentValue ) == "table") then
if(parentValue.init and type( parentValue.init ) == "function" ) then
parentValue.init()
end
end
end
end
InitAllAbilities( ) -- Этот вызов лучше бы перенести куда-то после инициализации карты, иначе будут проблемы.
Более того, я бы и от проверок на table и function избавился бы, условившись с самим собой что в таблице Ability могут лежать только таблицы спелов, а в таблицах спелов init либо функция либо его нет.
Ну и самое важное - я бы ключами в таблице Ability взял равкоды абилок, чтобы по равкоду абилки можно было сразу получить доступ к связанной с этим равкодом таблице.
Как-то так
Ability = {}
local DeathCoil = {}
Ability[FourCC('A000')] = DeathCoil
function DeathCoil.init( )
...
end
function DeathCoil.cast( )
...
end
...
function SomeTriggerAction()
local spellId = GetSpellAbilityId()
if( Ability[spellId]) then
if(Ability[spellId].cast)then
Ability[spellId].cast()
end
end
end
...
А при желании можно еще и параметры в cast передавать.
А какой смысл портировать устаревшие системы под 1.31, если в 1.31 можно написать нормальный инвентарь на кастом фреймах и новых функциях для работы с полями?
Подскажи как 100% отловить срабатывание сборщика, затестю.
Один из вариантов - добавить финализатор к таблице через метаметод __gc, потом убить все ссылки на эту таблицу и ждать.
В момент срабатывания финальной фазы сборки мусора перед удалением нашей таблицы вызовется __gc из её метатаблицы.
ручной запуск сборщика может прибить таймеры и события триггеров
А ты проверил в итоге, не делает ли то же самое автоматический сборщик? У меня с тех пор пока не было столько времени чтобы сесть и довести вар до сборки мусора несколько раз. Что-то мне подсказывает, что неудачные попытки делать систему движения снарядов на PTR были вызваны именно этим - сборщик мусора ел анонимные таймеры на анонимных функциях в анонимных триггерах.
Мне кажется, многие тут даже не поняли о чем эта наработка... Это же не о снарядах, на самом деле, а о математике для разных способов интерполяции... Снаряды я и сам напишу, например, а интерполяцию сложнее линейной мне обычно лень писать и проще взять готовую.
Вы забываете важный нюанс - в варе мультиплеер основан на локстэпе, а значит любой рандом должен быть полностью детерминистичным иначе нас ждет рассинхрон.
Наивные.. Дырки будут латать, как обычно, на ходу. Потому как никакая закрытая бета не выловит всех багов и даже те что выловятся будут фикситься по приоритетности и менее приоритетные просто не влезут в бюджет и будут отложены. Вот если бы зашел инсайд что бюджет проекта подняли - можно было бы на что-то надеяться.
В 1.31 ReplaceUnitBJ точно обрабатывает и предметы и опыт у героев, а вот бонусные статы от одноразовых предметов вроде книг теряются. Как было в 1.26 не помню.
А еще при реплейсе теряются все бафы у юнита и все ссылки в переменных на юнита, поскольку на самом деле там создается новый юнит.
Прежде всего, включена ли настройка, делающая рандом не рандомным при старте из редактора?
И не во время кинематика ли происходит выбор случайных чисел?
Это две самых распространенных причины почему рандом выдает одинаковые последовательности чисел в варкрафте.
NazarPunk, если код передается через гитхаб - значит у всех кто работает с кодом настроена среда разработки. Зачем тогда полностью синхронизировать код с редактором пофайлово, если его можно весь в один блок кастом-скрипта вынести и не париться, а в редакторе триггеров оставить отдельными вкладками только всякие настройки, которые только через редактор и будут редактироваться?
» WarCraft 3 / [lua] Двигаем снаряды
» WarCraft 3 / [lua] Двигаем снаряды
В момент срабатывания финальной фазы сборки мусора перед удалением нашей таблицы вызовется __gc из её метатаблицы.
Ред. prog
» WarCraft 3 / Lua: функции в таблице
Ред. prog
» WarCraft 3 / Lua: функции в таблице
Сейчас у тебя в Ability складывается два типа данных - по равкоду героя его список способностей, а по каким-то другим ключам таблицы с данными конкретных способностей.
Естественно, я исхожу из предположения что триггеры срабатывания способностей переделаны на получение таблицы способности по равкоду, вместо отдельных триггеров на каждую способность.
Конструкция "if GetSpellAbilityId( ) ~= Ability[ HERO_DEATH_KNIGHT ][ Q ] then return end" ужасна - это вызов функции и два обращения к таблице/массиву в глобальной переменной. И хуже всего - эта конструкция вызывается каждый раз когда срабатывает триггер, а срабатывает он на все способности. Когда способностей будет сто и все на разных триггерах - аналогичная конструкция будет вызываться уже сто раз при каждом касте любой способности.
» WarCraft 3 / Lua: функции в таблице
Грубо говоря, герои в таблице Heroes, способности в таблице Abilities. Позволит ускорить перебор и избежать ненужных проверок.
Ред. prog
» WarCraft 3 / Lua: функции в таблице
» WarCraft 3 / Lua: функции в таблице
» WarCraft 3 / Изменение количества урона
» WarCraft 3 / Проблема с компиляцией jass кода в 2-х конкретных системах
» WarCraft 3 / Проблема с компиляцией jass кода в 2-х конкретных системах
Ред. prog
» WarCraft 3 / Заклинание: Волна Воды
В момент срабатывания финальной фазы сборки мусора перед удалением нашей таблицы вызовется __gc из её метатаблицы.
» WarCraft 3 / Заклинание: Волна Воды
» WarCraft 3 / Заклинание: Волна Воды
И вот тут начинаются нюансы.
» WarCraft 3 / math.ease
» WarCraft 3 / Хэш на Lua ?
Ред. prog
» WarCraft 3 / Неверное изменение чисел в таблице
» WarCraft 3 / Как получить истинный рандом?
» WarCraft 3 / XGM. Новости Warcraft III: Reforged
Ред. prog
» WarCraft 3 / Сделать получение професси юнита
А еще при реплейсе теряются все бафы у юнита и все ссылки в переменных на юнита, поскольку на самом деле там создается новый юнит.
» WarCraft 3 / Сохранения в кэши игры
» WarCraft 3 / не могу брать предметы
» WarCraft 3 / Сохранения в кэши игры
» WarCraft 3 / не могу брать предметы
» WarCraft 3 / Как получить истинный рандом?
И не во время кинематика ли происходит выбор случайных чисел?
Это две самых распространенных причины почему рандом выдает одинаковые последовательности чисел в варкрафте.
» Эксперименты в Пустоте / Ломаем Warcraft3 1.31 полностью: Кастомный компилятор Lua