129 lines
4.9 KiB
Lua
129 lines
4.9 KiB
Lua
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
local ____exports = {}
|
|
local requiemNextAiAt, onScriptedPhaseRequiem
|
|
function ____exports.nevermoreBumpRequiemAiCooldown(self)
|
|
requiemNextAiAt = GameRules:GetGameTime() + RandomInt(____exports.NEVERMORE_REQUIEM_AI_CD_MIN, ____exports.NEVERMORE_REQUIEM_AI_CD_MAX)
|
|
end
|
|
--- Перед кастом реквиема после Terror Wave: очистка очередей серий ИИ + откладываем ульту у ИИ.
|
|
function ____exports.nevermoreNotifyScriptedPhaseRequiem(self)
|
|
if onScriptedPhaseRequiem ~= nil then
|
|
onScriptedPhaseRequiem(nil)
|
|
end
|
|
____exports.nevermoreBumpRequiemAiCooldown(nil)
|
|
end
|
|
--- Кулдаун реквиема для ИИ, счётчик обязательных кастов ульты, принудительный каст.
|
|
____exports.NEVERMORE_REQUIEM_AI_CD_MIN = 72
|
|
____exports.NEVERMORE_REQUIEM_AI_CD_MAX = 96
|
|
--- Сколько раз босс должен скастовать реквием (ульт), чтобы снять «броню».
|
|
____exports.NEVERMORE_REQUIEM_REQUIRED_CASTS = 3
|
|
--- HP% строго ниже — включается −80% входящего, пока не набрано 3 каста.
|
|
____exports.NEVERMORE_REQUIEM_HP_THRESHOLD = 50
|
|
____exports.NEVERMORE_REQUIEM_DAMAGE_REDUCTION_PCT = 80
|
|
local REQUIEM_ABILITY = "boss_nevermore_requiem_barrage"
|
|
requiemNextAiAt = 0
|
|
local requiemCastCountByEnt = {}
|
|
function ____exports.nevermoreRegisterPhaseRequiemHook(self, fn)
|
|
onScriptedPhaseRequiem = fn
|
|
end
|
|
function ____exports.nevermoreGetRequiemNextAiTime(self)
|
|
return requiemNextAiAt
|
|
end
|
|
function ____exports.nevermoreGetRequiemCastCount(self, boss)
|
|
return requiemCastCountByEnt[boss:entindex()] or 0
|
|
end
|
|
function ____exports.nevermoreIncrementRequiemCastCount(self, boss)
|
|
local ent = boss:entindex()
|
|
local next = math.min(____exports.NEVERMORE_REQUIEM_REQUIRED_CASTS, (requiemCastCountByEnt[ent] or 0) + 1)
|
|
requiemCastCountByEnt[ent] = next
|
|
end
|
|
function ____exports.nevermoreClearRequiemCastCount(self, boss)
|
|
requiemCastCountByEnt[boss:entindex()] = nil
|
|
end
|
|
--- Нужно добить касты ульты: уже ниже порога HP, а реквиемов < 3.
|
|
function ____exports.nevermoreNeedsMandatoryRequiem(self, boss)
|
|
if not boss or boss:IsNull() or not boss:IsAlive() then
|
|
return false
|
|
end
|
|
return boss:GetHealthPercent() < ____exports.NEVERMORE_REQUIEM_HP_THRESHOLD and ____exports.nevermoreGetRequiemCastCount(nil, boss) < ____exports.NEVERMORE_REQUIEM_REQUIRED_CASTS
|
|
end
|
|
local function getRequiemCastPositionForBoss(self, boss)
|
|
local origin = GetGroundPosition(
|
|
boss:GetAbsOrigin(),
|
|
nil
|
|
)
|
|
local enemies = FindUnitsInRadius(
|
|
boss:GetTeamNumber(),
|
|
origin,
|
|
nil,
|
|
12000,
|
|
DOTA_UNIT_TARGET_TEAM_ENEMY,
|
|
bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC),
|
|
DOTA_UNIT_TARGET_FLAG_NONE,
|
|
FIND_CLOSEST,
|
|
false
|
|
)
|
|
for ____, e in ipairs(enemies) do
|
|
do
|
|
if not e or e:IsNull() or not e:IsAlive() then
|
|
goto __continue11
|
|
end
|
|
local ep = GetGroundPosition(
|
|
e:GetAbsOrigin(),
|
|
nil
|
|
)
|
|
local to = ep - origin
|
|
if to:Length2D() < 1 then
|
|
goto __continue11
|
|
end
|
|
local fwd = to:Normalized()
|
|
return GetGroundPosition(ep + fwd * 100, nil)
|
|
end
|
|
::__continue11::
|
|
end
|
|
local f = boss:GetForwardVector()
|
|
local len2d = math.sqrt(f.x * f.x + f.y * f.y)
|
|
local dir = len2d < 0.01 and Vector(1, 0, 0) or Vector(f.x / len2d, f.y / len2d, 0)
|
|
return GetGroundPosition(origin + dir * 400, nil)
|
|
end
|
|
--- Телепорт в центр (если есть) и каст реквиема.
|
|
function ____exports.tryForceNevermoreRequiemCast(self, boss)
|
|
if not IsServer() then
|
|
return false
|
|
end
|
|
if not boss or boss:IsNull() or not boss:IsAlive() then
|
|
return false
|
|
end
|
|
if boss:IsChanneling() then
|
|
return false
|
|
end
|
|
local req = boss:FindAbilityByName(REQUIEM_ABILITY)
|
|
if not req or req:IsNull() then
|
|
return false
|
|
end
|
|
if req:GetLevel() < 1 then
|
|
req:SetLevel(1)
|
|
end
|
|
req:EndCooldown()
|
|
if not req:IsFullyCastable() then
|
|
return false
|
|
end
|
|
____exports.nevermoreNotifyScriptedPhaseRequiem(nil)
|
|
local center = Entities:FindByName(nil, "nevermore_center_point")
|
|
if center and not center:IsNull() then
|
|
FindClearSpaceForUnit(
|
|
boss,
|
|
center:GetAbsOrigin(),
|
|
true
|
|
)
|
|
end
|
|
local aim = getRequiemCastPositionForBoss(nil, boss)
|
|
ExecuteOrderFromTable({
|
|
UnitIndex = boss:entindex(),
|
|
OrderType = DOTA_UNIT_ORDER_CAST_POSITION,
|
|
AbilityIndex = req:entindex(),
|
|
Position = aim
|
|
})
|
|
return true
|
|
end
|
|
return ____exports
|