W3League.net Logo

    Linken’s Sphere: эволюция, устройство, баги и решение

    admin logo
    11 ноября 2025 г.quq_CCCP, Korneeey

    Введение: эволюция Linken’s Sphere

    В ранних версиях DotA предмет Linkens SphereLinken's Sphere (далее — линка, линкен сфера) представлял собой Amulet Of Spell ShieldAmulet of Spell Shield (далее — амулет защиты), который блокировал стандартные заклинания, однако весьма скоро появилась проблема – как отличить дефолтные способности от кастомных.

    Дефолтные способности

    Это встроенные в движок Warcraft III умения, например:

    • Storm BoltStorm BoltMountain KingMountain King
    • SlowSlowSorceressSorceress
    • BlizzardBlizzardArchmageArchmage

    Их механику можно изменить только через патчинг game.dll — задача не из простых.

    Кастомные способности

    Они создавались авторами DotA вручную через код карты.
    Например, кастомная способность Magic MissileMagic Missile у героя Vengeful SpiritVengeful Spirit — это обычный Storm BoltStorm Bolt (далее – молот). Иконка, снаряд, описание, анимации – все это можно настроить, но нельзя заставить молот оглушать и замедлять цель одновременно.

    Но решение было найдено весьма быстро: использовать одну дефолтную способность как основу, а поверх нее добавить вторую. Пример — VoidVoid у BalanarBalanar.

    • Урон и микростан обеспечиваются молотом.
    • Замедление же основано на Slow, которое применяет Dummy юнит (далее – dummy). Dummy – невидимый и неуязвимый юнит, который создается кодом, выполняет определенное действие и затем обычно удаляется.

    Amulet Of Spell ShieldАмулет защиты не сумеет заблокировать такое заклинание. Поскольку Dummy юнит не имеет анимации каста, а Slow не имеет снаряда, то замедление применится первым и собьет амулет защиты, и лишь потом долетит молот (имеет скорость 10000, без анимации снаряда).

    Руна Linken’s Sphere и её устройство

    Так как стандартными средствами игры никак не проверить активен ли Amulet Of Spell ShieldАмулет защиты или еще находится на перезарядке, в одной из версий IceFrog сделал кастомный аналог Linkens Sphereлинки. Сам предмет – пустышка, который ничего не блокирует, однако при его подборе, герою вручается Linkens Sphereруна Linken's Sphere (далее – руна).

    Вы тоже видели этот старый баг, когда руна выпадает при вручении? https://www.youtube.com/watch?v=kii4c_I1YVU

    Это происходило, если в момент передачи линки, герой отсутствовал на карте (Astral ImprisonmentAstral Imprisonment, DisruptionDisruption, BurrowstrikeBurrowstrike, SupernovaSupernova), или у него заблокирован инвентарь (Meat HookMeat Hook во время броска) то руна оставалась лежать на земле возле героя.

    IceFrog частично решил проблему, реализовав простую логику: если герой не смог подобрать руну, она удаляется, и попытка вручения повторяется до успешного результата.

    На самом деле Linkens Sphereруна основана на стандартном предмете Rune Of ShieldingRune of Shielding, который наделяет героя щитом, блокирующим одно вражеское заклинание.

    Принцип работы почти такой же как у амулета защиты, но главное отличие – это бафф в статусе, наличие которого можно проверить кодом.

    IceFrog ввел функцию, название которой нам точно неизвестно из-за обфускации (защиты) кода, но предположим что она имела такую сигнатуру:

    function IsUnitHasNegation takes unit u returns boolean
        return GetUnitAbilityLevel(u, 'B0BI') > 0
            or GetUnitAbilityLevel(u, 'BNss') > 0
            or GetUnitAbilityLevel(u, 'B0EV') > 0
    endfunction
    

    Эта функция проверяет, есть ли бафф руны у юнита ('B0BI').

    С тех пор кастомные способности проверяют наличие баффа руны. Если он есть, то дальнейшая часть кода с созданием Dummy, применением замедления или еще чего-либо не выполняется. Сам бафф сбивается, блокируя основную способность, на которой основан конкретный навык. Однако IceFrog пропустил пару десятков способностей, не добавив туда эту проверку, что привело к неполноценной реализации. В нашей карте все выявленные проблемные способности исправлены и теперь корректно взаимодействуют с линкой.

    Баг с Dummy и AOE способностями

    Но были и другие проблемы: некоторые способности не имеют прицела по юниту, а применяются по области.

    Пример — ShrapnelShrapnel у SniperDwarven Sniper которая основана на канале, то есть это просто способность-пустышка, для которой можно настроить тип прицела и цели. Поскольку основа данной способности ничего не делает, то весь ее эффект производится кодом карты. Замедление в DotA от IceFrog – это все тот же SlowSlow, которое применяет Dummy. Однако IceFrog допустил ошибку и сделал владельцем Dummy самого Dwarven Sniper, вместо героя, на которого Dummy применяет замедление.

    Соответственно бафф Linkens Sphereруны срабатывал и сбивался. К счастью, мы исправили эту ошибку.

    Баг с работой Linken’s Sphere после продажи

    Знакомый баг, не так ли? https://www.youtube.com/watch?v=ORKW3tgYXgE

    Он связан с устройством самой Linkens Sphereлинки. Поскольку она сделана кодом карты, технически она ничего не отражает – отражает именно бафф руны, которая вручается герою. Красивая анимация перезарядки – есть не что иное, как фикция, сделанная большим количеством кода.

    Немного технической информации

    В скрипте карты существует цикл, который со старта игры каждые 0.33 сек. проходится по всем героям и проверяет, жив ли герой, присутствует ли он на карте, а также, проверяет состояние счетчика линки.

    Если счетчик больше 0, герой жив, присутствует на карте, но на нем нет отражающего баффа, то вызывается дополнительная функция, которая проверяет весь инвентарь, ищет там линкен сферы (если их вдруг больше, чем одна), выбрасывает их на землю и удаляет. После создает фейковые линки в инвентаре Dummy с такими же статами. Эти линки не имеют прицела и их нельзя применять на союзников, а при нажатии они уходят в перезарядку. Далее симулируется нажатие, линки уходят в перезарядку, а после вручаются герою.

    Все это происходит почти мгновенно, игрок не успевает ничего заметить и видит, как идет перезарядка. Попутно создается таймер, который ждет время перезарядки Linkens Sphereлинки, либо пока герой оживет, если он умер за это время – чтобы вручить руну и заменить предмет в инвентаре.

    Но почему же бафф Linkens Sphereруны оставался даже после продажи предмета?

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

    Решение проблемы через глобальную переменную Зачем были нужны такие костыли – непонятно. Но решение мы нашли.

    Добавив глобальную boolean переменную ItemBool, а также проверку ее значений в триггере, который реагирует на подбор и выкладывание предметов, теперь:

    • перед запуском перезарядки линки, мы изменяем значение переменной
    • после запуска – возвращаем значение назад
    • рекурсия не происходит
    • счётчик всегда равен фактическому количеству линкен сфер у героя

    Вряд ли кто-то захочет купить больше одной линки.

    Заключение

    На этом мы завершаем наш обзор этого чудесного предмета. Мы рассмотрели его устройство, проблемы, с которыми он кочевал сквозь годы, а также пример элегантного решения. Дочитать такое – всё равно что создать линку с нуля, и вы с этим справились 🙂