--[[ 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