Библиотека, позволяющая отменять входящий урон.
код
library NegateDamageLib
globals
private constant group Group = CreateGroup()
private constant timer Timer = CreateTimer()
public keyword MaxLifeBonusAbility
public keyword MaxLifeBonus
endglobals
native UnitAlive takes unit id returns boolean
function GetUnitMaxLife takes unit u returns real
return GetUnitState(u, UNIT_STATE_MAX_LIFE) - GetUnitAbilityLevel(u, MaxLifeBonusAbility) * MaxLifeBonus
endfunction
private function ProcessUnits takes nothing returns nothing
local unit u
local real life2set
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if UnitAlive(u) then
set life2set = GetWidgetLife(u)
call UnitRemoveAbility(u, MaxLifeBonusAbility)
call SetWidgetLife(u, life2set)
else
call UnitRemoveAbility(u, MaxLifeBonusAbility)
endif
endloop
endfunction
function NegateDamage takes unit u, real negated returns nothing
local real life2set = GetWidgetLife(u) + negated
local boolean add_ability = life2set > GetUnitState(u, UNIT_STATE_MAX_LIFE)
if add_ability then
call GroupAddUnit(Group, u)
call UnitAddAbility(u, MaxLifeBonusAbility)
endif
call SetWidgetLife(u, life2set)
if add_ability then
call TimerStart(Timer, 0., false, function ProcessUnits)
endif
endfunction
endlibrary
Установка
- Скачать .j файл и переместить в Директория-JNGP/jass.
- В коде карты прописать импорт библиотеки.
//! import "NegateDamageLibrary.j"
- Создать способность (далее NegateDamageAbil), которая увеличивает максимальное здоровье юнитов. Рекомендуется создать способность на основе Item Life Bonus [AIlf] с увеличением здоровья на 1 миллион или больше.
- Указать равкод способности и значение увеличения здоровья в константах по шаблону ниже.
globals
constant integer NegateDamageLib_MaxLifeBonusAbility = 'A000'
constant integer NegateDamageLib_MaxLifeBonus = 1000000
endglobals
Использование
NegateDamage
call NegateDamage(damaged_unit, damage_to_negate)
Отменяет damage_to_negate для damaged_unit. damage_to_negate должно быть больше 0. Если это значение больше входящего урона, то юнит будет вылечен на разницу этих значений. Если вызывать функцию не в триггере получения урона, то damaged_unit будет вылечен на damage_to_negate.
Отмена может не произойти в следующих случаях:
- Входящий урон больше, чем бонус здоровья способности NegateDamageAbil.
- У юнита здоровья меньше чем 1.
GetUnitMaxLife
set max_life = GetUnitMaxLife(any_unit)
Возвращает максимальное здоровье any_unit без учёта бонуса от NegateDamageAbil.
Особенности
Функция NegateDamage меняет текущее и максимальное здоровье юнита во время вызова и через некоторое время ещё раз:
- Триггеры с событием Unit - Life (TriggerRegisterUnitLifeEvent) могут срабатывать во время изменений здоровья.
- Чтобы узнавать максимальное здоровье без учёта изменений от NegateDamage, используйте функцию GetUnitMaxLife.
Примеры
Имунные рабочие
Карта
Рабочие игнорируют любой урон до миллиона включительно. Урон более миллиона может убить, а может и не убить.
Рабочие игнорируют любой урон до миллиона включительно. Урон более миллиона может убить, а может и не убить.
Щит
Карта
У пехотинца есть способность Shield, которая даёт ему щиты. Щиты поглощают весь входящий урон, пока не израсходуются.
У пехотинца есть способность Shield, которая даёт ему щиты. Щиты поглощают весь входящий урон, пока не израсходуются.
Обновления
08.12.2024
- Настраиваемые константы (MaxLifeBonusAbility и MaxLifeBonus) теперь можно определить вне библиотеки.
- Это позволяет импортировать библиотеку из файла, а не копировать её в код карты.
- В связи с этим изменён способ установки и настройки.
- Тестовые карты были обновлены для соответствия изменениям выше.
01.12.2024
- Таймер запускается, только если способность NegateDamageAbil была добавлена.
- Тестовые карты были обновлены для соответствия изменениям выше.
- В карте NegateDamage-shield занулены поля Art - Animation - Cast Backswing и Art - Animation - Cast Point у пехотинца.
27.01.2022
- Теперь способность добавляется в случаях, если сумма текущего здоровья и отменяемого урона больше максимального запаса здоровья.
- GetUnitMaxHealth переименована в GetUnitMaxLife.
- Тестовые карты были обновлены для соответствия изменениям выше.
25.12.2021
- Убрано требование "библиотеки" AINativesLib, так как тот ресурс был обновлён.
- Определение UnitAlive было добавлено в код самой библиотеки.
- Обновлены тестовые карты дабы соответствовать изменениям выше.
23.03.2021
- Добавлена функция GetUnitMaxHealth.
- Некоторые константы стали публичными.
- Добавлена ещё одна карта-пример.
21.03.2021 - 3
Полная переработка библиотеки:
- Делает всё тоже самое, но лучше. Например, теперь регенерация здоровья верно работают у юнитов, которые игнорируют весь входящий урон и находятся под непрерывным огнём.
- Убрана целая куча настроек и требований.
21.03.2021 - 2
- В требования добавлена AI natives library.
- Изменена проверка того, что юнит жив.
21.03.2021 - 1
- Обновлён способ отключения других триггеров, отслеживающих урон.
- Обновлена карта-пример.
- Улучшена обработка случая, когда юнит умирает от полученного урона.
16.03.2021
Исправлены критические ошибки.
Но это прокатило бы если бы хуки вызывали хук-функцию после оригинальной, а не перед.
Ред. PT153
И хуки с предупреждением в дебаг моде на функции GetUnitState, GetUnitStateSwap, GetUnitStatePercent, GetUnitLife все таки нужны.
Ред. KaneThaumaturge
Ред. PT153
Ред. PT153
Ред. Daro
Ред. PT153