Castiel, создание-удаление таймеров и групп намного дороже обходится чем pairs, если что...
Ну и еще один нюанс - что ты будеш делать когда захочеш снимать кровотечение с цели каким-нибудь бинтом или очищением или рассеиванием или еще чем-нибудь, до истечения длительности кровотечения? В моей реализации данные о кровотечении хранятся по хендлу цели поэтому до них очень легко добраться зная только цель, в твоей же реализации тебе надо обязательно знать кастера прежде чем ты сможеш добраться до данных о кровотечении на цели.
Editor, не знаю какой интерес может быть к игре, когда подавляющее большинство матчей сводится к тому что ты либо значительно лучше либо значительно хуже чем твой противник, а действительно ровные матчи в которых нужно действительно переиграть противника это редкость. В то время как при более-менее рабочем матчмейкинге наоборот - значительный перекос сил это редкость, а более-менее ровные матчи обычное дело.
nvc123, можно, конечно. Но, например, у себя в картах я обычно храню намного больше информации привязаной к юнитам - если бы каждая система хранила свои данные в массиве, то удаление этих данных превратилось бы в ад, как и доступ к этим данным вне перебора. Вот когда удаление и доступ к данным просходит только внутри одной системы и только внутри перебора, то можно и в массив без хендлов сложить, конечно.
Castiel, еще раз повторюсь - это не более чем пример. Для практического использования, естественно, нужны дополнительные проверки.
Для группы проверка это не более чем экономия одного вызова нативки т.к. вар не дает два раза добавить одного юнита в группу, а вот проверка на то есть ли уже кровотечение от этого кастера имеет смысл, чтобы модифицировать данные о кровотечении, а не добавлять еще одно.
Castiel, если что, пример выше это только очень простой пример того как можно записать данные. Его нужно дополнять и расширять для практического использования.
Есть альтернативный способ - вместо записи последовательно, записывать по хендлу кастера и перебирать потом через pairs.
function BleedBitch(caster,target,duration,basedamage)
-- добавляем новое кровотечение к юниту по хендлу кастера
local data = bleeding_data[GetHandleId(target)]
data[GetHandleId(caster)] = {caster=caster, duration=duration, damage=GetHeroStr(caster,true)*basedamage}
GroupAddUnit(BleedGroup,target)
end
function BleedTickUnit (target)
local data = bleeding_data[GetHandleId(target)]
for cid, bdat in pairs(data)
Damage(bdat.caster, target, bdat.damage)
end
end
Перебор через pairs медленней перебора по индексам, но и мороки с ним меньше, плюс проверка на то есть ли на цели кровотечение от кастера проще. Но есть нюанс - тогда в перебираемой таблице не должно быть лишних записей, чтобы не париться проверками нужная ли это запись или что-то левое.
Castiel, но никто ведь не мешает записать самого юнита.
function BleedBitch(caster,target,duration,basedamage)
-- добавляем новое кровотечение к юниту
local data = bleeding_data[GetHandleId(target)]
local num_bleed = data.num
data.num = num_bleed+1
data[num_bleed] = {caster=caster, duration=duration, damage=GetHeroStr(caster,true)*basedamage}
GroupAddUnit(BleedGroup,target)
end
В коде выше большая часть кода пропущена для наглядности.
Castiel, еще раз перечитай мой комментарий выше - там есть и основные отличия и то где хранится информация о кастере. Главное преимущество такого способа - нет жонглирования множеством групп и таймеров, можно даже полностью без групп обойтись, а юнитов для перебора в массиве хранить. Второе ключевое отличие - более гибкая система, позволяющая хранить дополнительную информацию о кровотечении индивидуально для каждой цели и получать эту информацию зная только юнита-цель.
Castiel, ты храниш все по хендлу кастера, а я предлагаю хранить данные по хендлу цели. Ты создаеш по одному таймеру для каждого кастера и по одной группе на каждого кастера и еще и удаляеш их каждый раз когда у кастера заканчиваются цели, я предлагаю использовать один таймер и одну группу на всех, причем без создания-удаления. разве что таймер можно стопать и рестартовать если очень хочется оптимизации, но, опять-же, удалять его нет смысла.
Это может выглядеть примерно так:
функция ДобавитьКровотечение (кастер, цель, длительность)
проверяет если ли на юните кровотечение от кастера, если есть, то продлевает его, а если нет, то добавляет новое кровотечение в список записаный по хендлу цели (в данных о кровотечении хранится, как минимум, кастер и оставшаяся длительность, но можно хранить и больше данных, например урон за такт чтобы кровотечение не усиливалось магическим образом если кастер прокачался пока идет кровотечение)
добавляет цель в группу для перебора
если таймер остановлен, то запускает его заново
Функция таймера (желательно отдельной именованой функцией, а не анонимной пересоздаваемой при каждом старте таймера)
перебирает группу раз в секунду, для каждого юнита в группе перебирает все повешеные на него кровотечения, наносит урон и уменьшает оставшиеся такты кровотечения на 1
если прошли все такты кровотечения, то кровотечение убирается из данных записаных по хендлу юнита
если по хендлу юнита больше не записано кровотечений, то юнит убирается из группы перебора
если в группе перебора не осталось юнитов, то таймер стопается, но не удаляется, группа тоже не удаляется
Прежде всего, зачем по таймеру для каждого игрока, а тем более на каждого кастера, если можно обойтись одним таймером на всех?
Группы я бы тоже не хранил для каждого игрока, а вместо этого хранил бы по хендлу цели сколько осталось тактов кровотечения и от чьего имени наносить урон, а всех юнитов с кровотечением складывал бы в одну группу для всех.
Постоянное создание-удаление групп, в принципе, тоже не лучшая идея, лучше их чистить и повторно использовать.
Ну и я бы не стал использовать анонимную функцию в таймере - она тут не нужна, все отлично передается глобалками.
Процитирую по памяти запомнившееся мне сообщение, с которым давным давно закрыли похожую тему на одном из ресурсов, когда началось нытье на ретконы в WoW и опасения что близы начнут ретконить вар3, задолго до того как это стало мейнстримом.
Авторские права на вселенную принадлежат близам и они могут сношать её в любых позах, где и когда им угодно. Не нравится - пилите кастомные кампании со старой историей и собирайтесь греться вокруг них на своих выхлопах. Или собирайте подписи под петициями к близам о том что ретконы это плохо. Вместо того чтобы засорять форумы однообразным нытьем.
Если вы тут ради ремейка, то претензии по изменению кампании не принимаются, ибо о них предупреждали во время анонса. Если вы тут ради иконок и моделек, то странно вообще возмущаться тем, что что-то ещё сделали.
Раскрою страшную тайну, за которую мне насыпят минусов - многие тут просто по ныть...
Bergi_Bear, ты забыл еще добавить, что их еще и вынести отдельной панелью можно, а не в спеллбук совать. Но есть один нюанс - автор вопроса сидит на 1.26, где такое только через мемхак.
Каналу можно поменять ID приказа, поэтому несколько способностей на его основе могут быть у одного героя. С этим бывают баги если выбран неудачный ID, но в целом это универсальная способность-пустышка.
Но есть нюанс - канал вроде нельзя настроить так чтобы текущий приказ не сбивался.
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
Ну и еще один нюанс - что ты будеш делать когда захочеш снимать кровотечение с цели каким-нибудь бинтом или очищением или рассеиванием или еще чем-нибудь, до истечения длительности кровотечения? В моей реализации данные о кровотечении хранятся по хендлу цели поэтому до них очень легко добраться зная только цель, в твоей же реализации тебе надо обязательно знать кастера прежде чем ты сможеш добраться до данных о кровотечении на цели.
Ред. prog
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Странные тени на портрете персонажа.
» WarCraft 3 / 1 таймер много юнитов!
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
Есть альтернативный способ - вместо записи последовательно, записывать по хендлу кастера и перебирать потом через pairs.
» WarCraft 3 / 1 таймер много юнитов!
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
» WarCraft 3 / 1 таймер много юнитов!
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
Ред. prog
» WarCraft 3 / 1 таймер много юнитов!
Группы я бы тоже не хранил для каждого игрока, а вместо этого хранил бы по хендлу цели сколько осталось тактов кровотечения и от чьего имени наносить урон, а всех юнитов с кровотечением складывал бы в одну группу для всех.
Постоянное создание-удаление групп, в принципе, тоже не лучшая идея, лучше их чистить и повторно использовать.
Ну и я бы не стал использовать анонимную функцию в таймере - она тут не нужна, все отлично передается глобалками.
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
Авторские права на вселенную принадлежат близам и они могут сношать её в любых позах, где и когда им угодно. Не нравится - пилите кастомные кампании со старой историей и собирайтесь греться вокруг них на своих выхлопах. Или собирайте подписи под петициями к близам о том что ретконы это плохо. Вместо того чтобы засорять форумы однообразным нытьем.
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / 11 Одинаковых абилок.
» WarCraft 3 / 11 Одинаковых абилок.
» WarCraft 3 / 11 Одинаковых абилок.
» WarCraft 3 / Удалить сообщение DisplayTimedTextToForce
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
» WarCraft 3 / Почему не работает абилка?(чекните GetDistance)