Превращения и дизейблы

В прошлом, когда-то давно, я уже описывал принципы трансформации в отдельных темах. Вот старая статья о превращениях (морфах) и ее фичах. Естественно, с годами мы все становимся мудрее, да и опыт вскрытия варкрафта помогает лучше проникаться костылями фичами игры. Поэтому я посчитал нужным быстренько написать блог-дополнение с объяснением, как же это всё на самом деле работает, и почему даже в Allstars можно нарваться на такую проблему (пусть и ненадолго).

Основа бага
Почему же трансформация заставляет юнита игнорировать приказы? По какой-то причине все навыки, превращающие юнита в любого другого, используют скрытый стан. Тут, возможно, следует пояснить, что стан вовсе не нуждается в бафе — картинка и анимация существуют сугубо для игроков. Само же состояние «в стане» является внутриигровым осведомителем.
Каждый юнит носит с собой свой счетчик станов. Если в нем 0 записей (никто не станил), юнит спокойно слушает приказы и выполняет их немедленно. Если же запись отличается от нуля, любой переданный ему приказ отложится в очередь. Что же происходит, когда юнит ловит стан от свена  ?

Пойманный болт заставляет юнита выполнить приказ «стан». Это эффективно отключает желание цели атаковать, а в остальном аналогично кнопке «держать позицию». Т.к. активный приказ есть («стан»), юнит не занимается самодеятельностью, а просто ждет, когда же текущий приказ закончится. Как можно заметить, стан — это всего лишь приказ, ничем не отличающийся от любого другого. Важно — приказ «стан» отдается лишь тогда, когда счетчик станов равен нулю. Во всех остальных случаях игра подразумевает, что кто-то уже отдал нужный приказ, и повторяться не стоит.

Когда начинается превращение (морф), юнит всегда на какой-то промежуток времени (каст тайм) получает псевдо-стан, без бафа. Благодаря ручному, а не системному, увеличению счетчика, игра не заставляет юнита исполнять приказ «стан», однако любой отданный приказ вновь отправляется в очередь, т.к. счетчик больше нуля. Поэтому каст успешно завершается и юнит нормально бегает в новой форме.

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

Взаимодействие станов и приказов
В оригинальном варкрафте превращений достаточно, но все они относительно быстрые. Поэтому разработчики не думали, что эта система может стать для кого-то проблемой. На практике же проблемы наблюдаются даже с мгновенным морфом бетрайдера, что уж говорить о более тормознутых алхимиках и ликанах.
Благодаря наличию ненулевого счетчика во время превращения юнит может эффективно проигнорировать любой отданный сверху приказ. Как уже было сказано, новый приказ «стана» будет проигнорирован из-за счетчика. Но самое главное, что действовать продолжит тот приказ, который сейчас активен у юнита. Если он превращался, он продолжит превращаться. Если стоял в стане, то продолжит стоять. Если бежал кого-то кусать  , то продолжит бежать.

Обратный морф
Обратное превращение в варкрафте реализовано максимально ленивым методом. По большому счету, юнит просто заново кастует превращение, а в этом случае игра меняет местами «целевого» и «исходного» юнита, превращая, например, из медведя  обратно в друида. Единственное отличие друида в том, что его морф можно таким образом прервать в любой момент. Морфы ликана  или алхимика  блокируются на время действия, и отменить их может лишь сама игра.

У «ленивого подхода» есть и проблемы покрупнее. Так, юнит, может, и не тратит ману на это обратное превращение, но как событие «скастовано заклинание» игра его все же считает. По этой причине откликаются все способности, регистрирующие это событие, например — исчезает инвиз от лотара , как будто было скастовано реальное заклинание.

Более того, при «ленивом» превращении юнит не теряет свой текущий приказ. Если изначально подразумевается, что он занимается кастом заклинания, то в данной ситуации это играет против разработчиков. Юнит продолжает выполнять свой текущий приказ и совершенно не слушается новых, пока счетчик станов не вернется к нулю.

Багованный сброс счетчика
В начале превращения юнит получает псевдо стан и игра начинает ждать, когда же закончится превращение. При этом в абилку превращения добавляется специальный флаг «я тут занимаюсь морфингом». Судя по всему, он используется, чтобы отличить вход от выхода из морфа. Если абилка «срабатывает», а флага нет, то она снимает стан с кастера.

Для начала разберем на примере, который могут повторить все — бетрайдер   (на морф просит 0.35). Берем героя, покупаем бладстон  , и через шифт выполняем — отправляем юнита куда-нибудь идти, через шифт жмем превращение и через шифт же применяем бладстон  на точку чуть дальше. Важно, чтобы поворачиваться для каста не требовалось, иначе в тайминг можно и не уложиться.

Когда бетрайдер   начинает превращение, счетчик станов увеличивается на 1. Через 0.35 он упадет обратно, но шифт — это супер-кнопка, благодаря которой следующий приказ выполняется максимально быстро. Поэтому, как только каст закончен, тут же применяется бладстон. Функция, регистрирующая конец каста, еще не успела сработать — хоть бладстон и срабатывает ровно через такт, оставляя окно для чего-то еще, это всё равно намного быстрее, чем ждать 0.35 секунды.

Юнит умирает, но сброса флага не происходит. Более того, в фрагменте, который должен обрабатывать подобный случай, стоит проверка, жив ли юнит. Если это не так, то игра даже не попытается отменить морф, полностью забивая на возникшее исключение. В результате морф остается навечно недоступным, а юнита (героя) можно возродить, но его счетчик станов при этом останется на отметке 1.

Итак, причина бага — в некорректной обработке мертвых юнитов, что предотвращает сброс счетчика и оставляет юнита в вечном стане.

Примеры багов со станом
Из теории можно вынести два кейса багов:
  • Тот самый "сломанный ликан". Благодаря длительности морфа в 2 секунды, убить героя во время превращения супер-легко. Можно сломать и алхимика   с его 0.35, но намного сложнее, по очевидным причинам. После возрождения любой отданный приказ будет выполняться до конца. Можно атаковать союзников, т.к. отмена такой атаки тоже основана на приказе «стоп», а следовательно, будет игнорироваться из-за стана.
  • Временно иммунный к дизейблам герой. Лучше всего продемонстрировано в этом старом ролике:


Другие баги превращения
Окей, этот баг проявляется только в случае смерти. Или нет? Ведь существует столько способ прервать выполнение приказа, даже не используя станы и смерть. Например, невидимый стан от сетки наги  , или сайленс, чтоб помешать кастовать? А здесь кроется еще один баг превращений.

Хотя сеть Наги   и не является дизейблом на основе приказа, причина, по которой медведь   её игнорирует, тривиальна — разработчики запретили опутывать юнитов, находящихся в стадии превращения. Приказ просто не проходит, якобы «неподходящая цель», пока та не завершит превращение до конца. Так можно издеваться над ЦМкой  , просто не позволяя ей прожать колбу. С другой стороны, она за такое и по лицу отпинать может, ведь двигаться всё равно нельзя. Аналогично нельзя кидать на юнитов, находящихся в стадии превращений, хекс.

Но что, если бросить сайленс? Быстрая проверка показывает, что медвед просто сразу переходит во вторую форму, независимо от того, в какой именно момент превращения был наложен сайленс. Ведь приказ каста не может выполняться дальше из-за сайленса, поэтому юнит пускается в самодеятельность. Флаг стана, напомню, остается до тех пор, пока не «тикнет» таймер превращения, и никак не зависит от реального состояния юнита.

А если поднять на ветра  ? Еще один дизейбл, о котором не подумали при разработке и «забыли» запретить. В этом случае юнит продолжит превращение уже в воздухе, а по завершению оного ветра, как еще один дизейбл на основе приказа, будут просто носить юнита по воздуху. Сам же медвед   продолжит бегать, атаковать и совершать любое непотребство, как обычно, ведь ветра — это лишь красивая копия стана.

Итак, это объясняет, почему алхимик может проигнорировать ветер или стан, кинутый в него с неудачным таймингом.

Отдельный случай — ульт Spectre
Из вышесказанного мы узнали, что стан — это всего лишь приказ. А знали ли вы, что его можно перебить?

Если пытаться атаковать союзника, юниту будет сбит приказ при помощи «стоп». А что, если отдавать приказ, например, «атаки» каждый раз, когда юнит получает любой другой приказ? В этом случае даже приказ «стан» будет снова перекрыт атакой, и юнит пойдет дальше как ни в чем ни бывало.

Это и произошло с ультой спектры  . Чтобы игроки не могли переконтролить копию, направив её по своим делам, испоьзуется вышеописанный принцип. Т.к. проверки на стан нет, такая илллюзия игнорирует любого рода станы, ветра и т.п. «приказные» дизейблы.

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

Морфы избавляют лишь от дизейблов, но не от других эффектов, вроде урона. В д2 они были портированы наоборот, успешно уклоняя от урона, но не от эффектов.

Проблеме подвержены абсолютно все виды морфов. Недочет, из-за которого способность блокировалась в случае смерти юнита, поправлен только в 88 версии Allstars. Остальные «особенности» по-прежнему актуальны.

1 комментарий

avatar
Очень напрягает, когда ТБ после морфа бежит атаковать цель с ренжом 150 вместо 550. Иногда это дорого обходится.

P.S.
Go Go Power Rangers!
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.