В данной статье рассмотрим такой предмет, как Антимагический амулет и как применять его против триггерных заклинаний. Опять же, как у всех взрослых дядь психологические проблемы растут из детства, так и потребность в данной статье была у меня в давние времена знакомства с редактором Warcraft 3 TFT. За неимением другого ресурса по поводу работы линки, пишу свой. Не без огрехов.
Работать данная система будет с помощью стандартной абилки антимагического амулета и нескольких функций. Для начала создаем глобальную группу и таблицу, куда мы будем записывать таймеры обладателей этого прекрасного предмета.
LinkenCooldownGroup = CreateGroup()
LinkenTimers = {}
Далее пишем функцию добавления юнита в глобальную группу перезарядки линки и функцию проверки находится ли предмет в кд
function LinkenAddUnitToCooldownGroup(unit)
GroupAddUnit(LinkenCooldownGroup, unit)
local unitId = GetHandleId(unit)
-- Создание и запуск таймера
local timer = CreateTimer()
TimerStart(timer, 15, false, function()
GroupRemoveUnit(LinkenCooldownGroup, unit)
DestroyTimer(timer)
LinkenTimers[unitId] = nil
end)
-- Сохранение таймера для юнита
LinkenTimers[unitId] = timer
end
-- Проверка, находится ли юнит в группе
function LinkenIsUnitInCooldownGroup(unit)
return IsUnitInGroup(unit, LinkenCooldownGroup)
end
Здесь мы запускаем таймер для каждого юнита с линкой на 15 сек. (время отката предмета), после чего исключаем его из группы кд предмета.
Далее создаем сам предмет, присваиваем ему id 'ITls' и не забываем добавить способность антимагического амулета (важно чтобы время отката способности было идентично времени таймера нахождения в группе). После работаем только с кодом способностей. Допустим, хочу чтобы способность Thunder Bolt помимо оглушения и стандартного урона еще и наносила урон от брони кастера.
function ThunderBolt_Conditions() -- Условие применения способности Thunder Bolt
return GetSpellAbilityId() == FourCC('AHtb')
end
function ThunderBolt_Actions()
local caster = GetTriggerUnit() -- Юнит, использующий способность
local target = GetSpellTargetUnit() -- Цель способности
local abilityLevel = GetUnitAbilityLevel(caster, FourCC('AHtb')) -- Уровень способности
-- Проверка наличия линки
if UnitHasItemOfTypeBJ(target, FourCC('ITls')) then
-- Если цель имеет линку и не находится в группе, добавляем в группу и блокируем способность
if not LinkenIsUnitInCooldownGroup(target) then
LinkenAddUnitToCooldownGroup(target)
return -- Блокируем выполнение кода заклинания
end
end
-- Расчет урона
local armor = BlzGetUnitArmor(caster)
local damage = armor * 10
-- Нанесение урона
UnitDamageTarget(caster, target, damage, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_METAL_HEAVY_BASH)
end
function InitThunderBolt()
local ThunderBolt = CreateTrigger()
TriggerRegisterAnyUnitEventBJ(ThunderBolt, EVENT_PLAYER_UNIT_SPELL_EFFECT)
TriggerAddCondition(ThunderBolt, Condition(ThunderBolt_Conditions))
TriggerAddAction(ThunderBolt, ThunderBolt_Actions)
end
Необходимо вставить проверку наличия линки и нахождения в группе именно в функцию способности, а не в отдельную функцию из-за того, что в этом случае функция действий спела и функция добавления цели в группу кд будут выполняться одновременно, что приведет к нежелательным результатам.
В итоге, если применить громовой молот в цель с линкой, стандартная способность амулета заблокирует оглушение и урон от способности, а скрипт заблокирует триггерные действия (урон от брони). При условии равенства времени кд предмета и времени таймера линка будет исправно работать. Для добавления системы в свою карту, перенесите группу, таблицу таймеров и функции линки в свой код и добавляйте проверку выше в каждую свою направленную способность.
Ред. nazarpunk
Ред. Kalvin273