Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Наработка
Версия Warcraft:
1.26+
Библиотека, позволяющая отменять входящий урон.
код
library NegateDamageLib
globals
    private constant group Group = CreateGroup()
    private constant timer Timer = CreateTimer()
    
    // MUST BE SPECIFIED
    public constant integer MaxLifeBonusAbility = 'A000'
    public constant integer MaxLifeBonus = 1000000
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
    
    if life2set > GetUnitState(u, UNIT_STATE_MAX_LIFE) then
        call GroupAddUnit(Group, u)
        call UnitAddAbility(u, MaxLifeBonusAbility)
    endif
    
    call SetWidgetLife(u, life2set)
    
    call TimerStart(Timer, 0., false, function ProcessUnits)
endfunction

endlibrary

Требования

  • Наличие способности (NegateDamageAbil), которая увеличивает максимальное здоровье юнитов на 1 миллион здоровья или больше. Можно сделать на основе Item Life Bonus [AIlf].

Установка

  1. В карте создать триггер NegateDamage, сконвертировать его в Custom Text и очистить содержимое.
  2. Скопировать код библиотеки в созданный триггер.

Настройка

  • Установить равкод способности NegateDamageAbil в константу MaxLifeBonusAbility.
  • Установить бонус здоровья NegateDamageAbil в константу MaxLifeBonus. Необходимо только для верной работы функции GetUnitMaxLife.

Использование

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, которая даёт ему щиты. Щиты поглощают весь входящий урон, пока не израсходуются.

Обновления

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
Исправлены критические ошибки
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
18
3 года назад
0
Класс, а почему WidgetLife?
0
28
3 года назад
0
Vlod, потому что это короче, говорят, что ещё и быстрее, а суть та же, что и у UnitState для жизни.
2
17
3 года назад
2
Нипанаятна.
С одной стороны, юниту необходимо установить его текущее здоровье в момент выдачи способности с дополнительным хп, поскольку, при увеличении максимального запаса здоровья, процент текущего запаса здоровья сохраняется, что изменяет его численное количество (или нет?).
С другой стороны, отхиливать юнита нужно в момент нанесения урона. Если делать это в таймере с нулевой задержкой, то в момент исполнения кода таймера юнит уже может быть мертв от того самого урона, от которого его полагалось отлечить.
0
8
3 года назад
0
С другой стороны, отхиливать юнита нужно в момент нанесения урона. Если делать это в таймере с нулевой задержкой, то в момент исполнения кода таймера юнит уже может быть мертв от того самого урона, от которого его полагалось отлечить.
Поэтому абилка с хп и добавляется. Всегда так делали на старых патчах
0
17
3 года назад
0
Поэтому абилка с хп и добавляется
Речь не про абилку а про отхил. Про то что отхиливать нужно в момент получения урона.
0
28
3 года назад
0
GetLocalPlayer, когда срабатывает событие, никакого урона нет. Он будет нанесён, когда триггер завершится. Если в триггере есть пауза, то когда она начнёт выполняться.

А, я понял, о чём речь.

Пока снял с публикации.
0
28
3 года назад
0
GetLocalPlayer, всё исправил, спасибо за замечание.
0
28
3 года назад
0
Либа обновлена.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.