Библиотека, добавляющая возможность вычислять текущую броню юнита со всеми текущими бонусами.
Установка
- Установить Math library и Negate Damage library.
- Скачать .j файл и переместить в Директория-JNGP/jass.
- В коде карты прописать импорт библиотеки.
//! import "GetUnitArmorLibrary.j"
- В коде карты определить константы для библиотеки:
globals
constant integer GetUnitArmorLib_RegisteredPurgeThreshold = 100
constant real GetUnitArmorLib_ArmorDamageReductionMultiplier = 0.06
constant real GetUnitArmorLib_DamageAmount = 10000.
endglobals
Константы означают следующее:
- RegisteredPurgeThreshold - указывает периодичность очистки группы с зарегистрированными юнитами. Рекомендуется установить значение на 100, то есть каждые 100 новых регистраций группа будет пересоздаваться.
- ArmorDamageReductionMultiplier - значение игровой константы DefenseArmor (англ. Combat - Armor Damage Reduction Multiplier).
- DamageAmount - урон, наносимый для вычисления брони. Данная константа должна соответствовать неравенству ниже для корректной работы библиотеки. Для большинства случаев 10000 подойдёт.
неравенство
1 / (min_damage_type_factor * min_etherial_factor * (1 - (max_armor * armor_factor) / (1 + max_armor * armor_factor))) < DamageAmount < max_life_bonus / (max_damage_type_factor * max_etherial_factor * (2 - (1 - armor_factor) ^ (-min_armor)))
Где:
- min_damage_type_factor и max_damage_type_factor - минимальное и максимальное значения среди ненулевых значений из игровых констант типа DamageBonus.... По умолчанию 0.05 и 2.00 соответственно.
- min_etherial_factor и max_etherial_factor - минимальное и максимальное значения среди ненулевых значений из игровой константы EtherialDamageBonus. По умолчанию оба значения равны 1.66.
- armor_factor - значение игровой константы DefenseArmor. По умолчанию 0.06.
- max_life_bonus - значение константы MaxLifeBonus для библиотеки NegateDamageLib.
- min_armor и max_armor - минимальное и максимальное возможные значения брони в вашей карте. Считать min_armor как 0, если негативных значений брони в карте не предвидится.
Неравенство выглядит так, если использовать значения по умолчанию для игровых констант:
12.5 / (1 - (max_armor * 0.06) / (1 + max_armor * 0.06)) < DamageAmount < max_life_bonus / (3.32 * (2 - 0.94 ^ (-min_armor)))
Если в результате подстановки значений верхняя граница меньше нижней, необходимо увеличивать значение max_life_bonus, пока неравенство не начнёт соблюдаться.
Использование
GetUnitArmorLib_ReturnValue
Специальная структура, объекты которой возвращает функция GetUnitArmor. Её объекты не нужно уничтожать.
Имеет следующие поля:
- status - статус вычисления. Принимает значения с 0 по 4, все они занесены в константы структуры с префиксом STATUS.
- 0 - вычисление выполнено успешно.
- 1 - вычисление не было выполнено, потому что юнит не жив (то есть мёртв или не существует).
- 2 - вычисление не было выполнено, потому что юнит неуязвим к магии и является эфириалом.
- 3 - вычисление не было выполнено, потому что юнит не получил урон универсального типа.
- 4 - вычисление не было выполнено, потому что юнит не получил урон нормального типа.
- armor - вычисленное значение брони в случае успеха или 0 в противном случае.
Для удобства работы со статусом были созданы следующие поля-операторы:
- rv.success - аналогично rv.status == 0.
- rv.failure - аналогично rv.status != 0.
- rv.failure_not_alive - аналогично rv.status == 1.
- rv.failure_etherial_and_magic_immune - аналогично rv.status == 2.
- rv.failure_no_damage - аналогично rv.status == 3 or rv.status == 4.
- rv.failure_no_universal_damage - аналогично rv.status == 3.
- rv.failure_no_normal_damage - аналогично rv.status == 4.
Также есть один метод:
- rv.get_armor_or_value(real_value) - возвращает rv.amor, если rv.status == 0, и real_value в противном случае.
Важно: данная структура предназначена для локального использования. Если хранить её объекты в глобальных переменных или хранилищах, их значения могут измениться спустя какое-то время. Одновременно может существовать 8192 разных объектов этой структуры.
GetUnitArmor
local GetUnitArmorLib_ReturnValue rv = GetUnitArmor(some_unit)
Вычисляет броню для some_unit. Если это возможно, то rv.success будет true и вычисленное значение брони будет в rv.armor. Стоит отметить, что значения брони будут с некоторой погрешностью из-за вычислений.
Примеры
Трекер брони
Карта
Тестовая карта библиотеки. В карте минимальная броня равна -18, а максимальная равна 9900. Согласно неравенству, константа DamageAmount должна быть в диапазоне (7437.5, 180181.2). Но там указано 1000, отчего для некоторых значений и типов брони вычисление будет неверным.
Тестовая карта библиотеки. В карте минимальная броня равна -18, а максимальная равна 9900. Согласно неравенству, константа DamageAmount должна быть в диапазоне (7437.5, 180181.2). Но там указано 1000, отчего для некоторых значений и типов брони вычисление будет неверным.
Паладин
Карта
У паладина есть аура, которая обжигает нежить поблизости. Урон ауры зависит от количества брони или от статуса паладина.
У паладина есть аура, которая обжигает нежить поблизости. Урон ауры зависит от количества брони или от статуса паладина.
Обновления
28.12.2025
- Полностью переработана библиотека:
- Теперь нужно настроить всего 3 значения.
- Работает с эфириалами.
- Функция GetUnitArmor возвращает специальную структуру со значением брони и статусом.
- Обновлена тестовая карта.
- Добавлена карта-пример.
25.12.2021
- В код добавлены оригинальные формулы брони на случай, если указанные ссылки станут недоступны.
- Залита последняя тестовая карта.
- С эфириалами всё ещё не работает.
16.03.2021 - 4
- Улучшена надёжность определения того, что урон наносится с целью вычислить броню.
- Добавлена константа ValueWhenUnitInvulnerable.
16.03.2021 - 3
Убран даммик.
16.03.2021 - 2
- Добавлена обработка случая, когда юнит неуязвим.
- Обновлена карта-пример.
16.03.2021 - 1
EvalArmor возвращает true, если урон использовался для вычисления брони, false - если нет. Удобно использовать как условие для триггера, который отлавливает нанесение урона.
пример
function Trig_TakesDamage_Conditions takes nothing returns boolean
return not EvalArmor()
endfunction
function Trig_TakesDamage_Actions takes nothing returns nothing
// ваш код
endfunction
function InitTrig_TakesDamage takes nothing returns nothing
set gg_trg_TakesDamage = CreateTrigger( )
call TriggerAddCondition( gg_trg_TakesDamage, Filter(function Trig_TakesDamage_Conditions) )
call TriggerAddAction( gg_trg_TakesDamage, function Trig_TakesDamage_Actions )
endfunction
В данном примере действия триггера будут выполняться только в том случае, если урон наносился не с целью вычисления брони.

WC3





Вкратце, базовые типы атаки заданы константами
Броня героя: Увеличивают броню союзных юнитов на значение равно 50% брони героя. И допустим это паладин с божественным щитом, получается скил отработает в 0.
Тогда наверное в случае инвула, стоит возвращать последнее значение брони, которое удалось получить, это конечно тоже не точное, но всё таки не 0
Ред. PT153
Так что пусть картодел сам решает, как ему с этим быть. Я специально добавил константу ValueWhenUnitInvulnerable. Можно поставить ей такое значение, которое не может получиться в игре. Это будет свидетельствовать о том, что юнит неуязвим.
Ред. PT153
Ред. PT153