Files
Dota-Zombie-Invasion/scripts/vscripts/ai/nevermore_boss_requiem_bridge.lua
T
2026-05-29 15:11:31 +07:00

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