Files
Dota-Zombie-Invasion/scripts/vscripts/abilities/heroes/nagash/dark_friends.lua
T
2026-05-29 15:11:31 +07:00

336 lines
12 KiB
Lua

local ____lualib = require("lualib_bundle")
local __TS__StringIncludes = ____lualib.__TS__StringIncludes
local __TS__Class = ____lualib.__TS__Class
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
local __TS__Decorate = ____lualib.__TS__Decorate
local ____exports = {}
local ____dota_ts_adapter = require("lib.dota_ts_adapter")
local BaseAbility = ____dota_ts_adapter.BaseAbility
local BaseModifier = ____dota_ts_adapter.BaseModifier
local registerAbility = ____dota_ts_adapter.registerAbility
local registerModifier = ____dota_ts_adapter.registerModifier
local ____sync_owner_modifiers_to_summon = require("utils.sync_owner_modifiers_to_summon")
local syncOwnerModifiersToSummon = ____sync_owner_modifiers_to_summon.syncOwnerModifiersToSummon
--- Подстроки в имени юнита: на таких целей призывы не агрятся.
local DARK_FRIENDS_NO_AGGRO_NAME_PARTS = {"boss", "wisp"}
local function darkFriendsIsNoAggroUnit(self, unitName)
if not unitName then
return false
end
local lowerName = string.lower(unitName)
for ____, part in ipairs(DARK_FRIENDS_NO_AGGRO_NAME_PARTS) do
if __TS__StringIncludes(lowerName, part) then
return true
end
end
return false
end
____exports.dark_friends = __TS__Class()
local dark_friends = ____exports.dark_friends
dark_friends.name = "dark_friends"
dark_friends.____file_path = "scripts/vscripts/abilities/heroes/nagash/dark_friends.lua"
__TS__ClassExtends(dark_friends, BaseAbility)
function dark_friends.prototype.GetIntrinsicModifierName(self)
return "modifier_dark_friends_create"
end
dark_friends = __TS__Decorate(
dark_friends,
dark_friends,
{registerAbility(nil)},
{kind = "class", name = "dark_friends"}
)
____exports.dark_friends = dark_friends
____exports.modifier_dark_friends_create = __TS__Class()
local modifier_dark_friends_create = ____exports.modifier_dark_friends_create
modifier_dark_friends_create.name = "modifier_dark_friends_create"
modifier_dark_friends_create.____file_path = "scripts/vscripts/abilities/heroes/nagash/dark_friends.lua"
__TS__ClassExtends(modifier_dark_friends_create, BaseModifier)
function modifier_dark_friends_create.prototype.spawnFriendForLevel(self, level, caster, ability)
local unitNames = {"npc_dota_melee_nagash_summon", "npc_dota_ranged_nagash_summon", "npc_dota_mage_nagash_summon", "npc_dota_shield_nagash_summon"}
local unitIndex = math.min(level, #unitNames) - 1
local unitName = unitNames[unitIndex + 1] or unitNames[1]
local dark_friends = CreateUnitByName(
unitName,
caster:GetAbsOrigin() + RandomVector(100),
true,
caster,
caster,
caster:GetTeamNumber()
)
dark_friends:SetOwner(caster)
dark_friends:SetBaseDamageMin(caster:GetBaseDamageMin())
dark_friends:SetBaseDamageMax(caster:GetBaseDamageMax())
dark_friends:SetBaseMoveSpeed(caster:GetBaseMoveSpeed() + 65)
dark_friends:AddNewModifier(caster, ability, "modifier_dark_friends", {})
dark_friends:AddAbility("ability_stacking_crit"):SetLevel(1)
EmitSoundOn("Hero_AbyssalUnderlord.DarkRift.Aftershock", caster)
end
function modifier_dark_friends_create.prototype.OnCreated(self, params)
local caster = self:GetCaster()
local ability = self:GetAbility()
if not caster or not ability then
return
end
if caster:PassivesDisabled() then
return
end
local level = math.max(
1,
ability:GetLevel()
)
if self:GetStackCount() < level then
self:spawnFriendForLevel(level, caster, ability)
self:SetStackCount(level)
end
end
function modifier_dark_friends_create.prototype.OnRefresh(self, params)
local caster = self:GetCaster()
local ability = self:GetAbility()
if not caster or not ability then
return
end
if caster:PassivesDisabled() then
return
end
local level = math.max(
1,
ability:GetLevel()
)
if self:GetStackCount() < level then
self:spawnFriendForLevel(level, caster, ability)
self:SetStackCount(level)
end
end
modifier_dark_friends_create = __TS__Decorate(
modifier_dark_friends_create,
modifier_dark_friends_create,
{registerModifier(nil)},
{kind = "class", name = "modifier_dark_friends_create"}
)
____exports.modifier_dark_friends_create = modifier_dark_friends_create
____exports.modifier_dark_friends = __TS__Class()
local modifier_dark_friends = ____exports.modifier_dark_friends
modifier_dark_friends.name = "modifier_dark_friends"
modifier_dark_friends.____file_path = "scripts/vscripts/abilities/heroes/nagash/dark_friends.lua"
__TS__ClassExtends(modifier_dark_friends, BaseModifier)
function modifier_dark_friends.prototype.____constructor(self, ...)
BaseModifier.prototype.____constructor(self, ...)
self.ownerIsDead = false
end
function modifier_dark_friends.prototype.IsHidden(self)
return true
end
function modifier_dark_friends.prototype.IsPurgable(self)
return false
end
function modifier_dark_friends.prototype.OnCreated(self)
if not IsServer() then
return
end
self:StartIntervalThink(0.1)
self:OnIntervalThink()
end
function modifier_dark_friends.prototype.GetRealOwner(self)
local parent = self:GetParent()
if not parent then
return nil
end
if parent:IsRealHero() then
return parent
end
local owner = parent:GetOwner()
if not owner then
return nil
end
local ownerUnit = owner
if ownerUnit:IsRealHero() then
return ownerUnit
end
return nil
end
function modifier_dark_friends.prototype.OnIntervalThink(self)
if not IsServer() then
return
end
local parent = self:GetParent()
if not parent then
return
end
local realOwner = self:GetRealOwner()
if not realOwner then
self.ownerIsDead = true
parent:Stop()
return
end
if not realOwner:IsAlive() then
self.ownerIsDead = true
parent:Stop()
local distanceToOwnerDead = (parent:GetAbsOrigin() - realOwner:GetAbsOrigin()):Length2D()
if distanceToOwnerDead > 300 then
parent:MoveToPosition(toVectorWS(
nil,
realOwner:GetAbsOrigin() + RandomVector(150)
))
end
return
else
self.ownerIsDead = false
end
syncOwnerModifiersToSummon(nil, realOwner, parent)
parent:SetBaseAttackTime(realOwner:GetBaseAttackTime())
parent:SetBaseDamageMin(realOwner:GetAverageTrueAttackDamage(nil))
parent:SetBaseDamageMax(realOwner:GetAverageTrueAttackDamage(nil))
parent:SetBaseMoveSpeed(realOwner:GetBaseMoveSpeed())
local distanceToOwner = (parent:GetAbsOrigin() - realOwner:GetAbsOrigin()):Length2D()
if distanceToOwner > 250 then
parent:MoveToPosition(toVectorWS(
nil,
realOwner:GetAbsOrigin() + RandomVector(200)
))
end
if distanceToOwner > 450 then
FindClearSpaceForUnit(
parent,
toVectorWS(
nil,
realOwner:GetAbsOrigin() + RandomVector(200)
),
true
)
end
if distanceToOwner <= 425 and realOwner:IsAlive() then
local enemies = FindUnitsInRadius(
parent:GetTeamNumber(),
parent:GetAbsOrigin(),
nil,
425,
DOTA_UNIT_TARGET_TEAM_ENEMY,
bit.bor(DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_HERO),
DOTA_UNIT_TARGET_FLAG_NONE,
FIND_CLOSEST,
false
)
local enemyTarget
for ____, u in ipairs(enemies) do
if not darkFriendsIsNoAggroUnit(
nil,
u:GetUnitName()
) then
enemyTarget = u
break
end
end
if enemyTarget then
enemyTarget:MoveToTargetToAttack(realOwner)
parent:MoveToTargetToAttack(enemyTarget)
end
end
end
function modifier_dark_friends.prototype.IsAura(self)
return true
end
function modifier_dark_friends.prototype.GetAuraRadius(self)
local ability = self:GetAbility()
local level = ability and math.max(
1,
ability:GetLevel()
) or 1
return self:GetAbility():GetSpecialValueFor("aura_radius") + level * 50
end
function modifier_dark_friends.prototype.GetAuraSearchTeam(self)
return DOTA_UNIT_TARGET_TEAM_FRIENDLY
end
function modifier_dark_friends.prototype.GetAuraSearchType(self)
return bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC)
end
function modifier_dark_friends.prototype.GetAuraSearchFlags(self)
return DOTA_UNIT_TARGET_FLAG_NONE
end
function modifier_dark_friends.prototype.GetModifierAura(self)
return "modifier_dark_friends_aura_buff"
end
function modifier_dark_friends.prototype.GetAuraEntityReject(self, target)
local caster = self:GetCaster()
if caster and caster:PassivesDisabled() then
return true
end
return false
end
function modifier_dark_friends.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_DAMAGEOUTGOING_PERCENTAGE}
end
function modifier_dark_friends.prototype.CheckState(self)
return {
[MODIFIER_STATE_NO_HEALTH_BAR] = true,
[MODIFIER_STATE_INVULNERABLE] = true,
[MODIFIER_STATE_NO_UNIT_COLLISION] = true,
[MODIFIER_STATE_NO_TEAM_SELECT] = true,
[MODIFIER_STATE_NO_TEAM_MOVE_TO] = true,
[MODIFIER_STATE_DISARMED] = self.ownerIsDead
}
end
function modifier_dark_friends.prototype.GetModifierDamageOutgoing_Percentage(self, event)
return self:GetAbility():GetSpecialValueFor("outgoing_damage_pct")
end
modifier_dark_friends = __TS__Decorate(
modifier_dark_friends,
modifier_dark_friends,
{registerModifier(nil)},
{kind = "class", name = "modifier_dark_friends"}
)
____exports.modifier_dark_friends = modifier_dark_friends
____exports.modifier_dark_friends_aura_buff = __TS__Class()
local modifier_dark_friends_aura_buff = ____exports.modifier_dark_friends_aura_buff
modifier_dark_friends_aura_buff.name = "modifier_dark_friends_aura_buff"
modifier_dark_friends_aura_buff.____file_path = "scripts/vscripts/abilities/heroes/nagash/dark_friends.lua"
__TS__ClassExtends(modifier_dark_friends_aura_buff, BaseModifier)
function modifier_dark_friends_aura_buff.prototype.IsHidden(self)
return true
end
function modifier_dark_friends_aura_buff.prototype.IsPurgable(self)
return false
end
function modifier_dark_friends_aura_buff.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE, MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT, MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE, MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS}
end
function modifier_dark_friends_aura_buff.prototype.GetModifierPreAttack_BonusDamage(self)
local ability = self:GetAbility()
local level = ability and math.max(
1,
ability:GetLevel()
) or 1
return level * self:GetAbility():GetSpecialValueFor("aura_bonus_damage")
end
function modifier_dark_friends_aura_buff.prototype.GetModifierAttackSpeedBonus_Constant(self)
local ability = self:GetAbility()
local level = ability and math.max(
1,
ability:GetLevel()
) or 1
return level * self:GetAbility():GetSpecialValueFor("aura_bonus_attack_speed")
end
function modifier_dark_friends_aura_buff.prototype.GetModifierMoveSpeedBonus_Percentage(self)
local ability = self:GetAbility()
local level = ability and math.max(
1,
ability:GetLevel()
) or 1
return level * self:GetAbility():GetSpecialValueFor("aura_bonus_movespeed_pct")
end
function modifier_dark_friends_aura_buff.prototype.GetModifierPhysicalArmorBonus(self, event)
local ability = self:GetAbility()
local level = ability and math.max(
1,
ability:GetLevel()
) or 1
return level * self:GetAbility():GetSpecialValueFor("aura_bonus_armor")
end
modifier_dark_friends_aura_buff = __TS__Decorate(
modifier_dark_friends_aura_buff,
modifier_dark_friends_aura_buff,
{registerModifier(nil)},
{kind = "class", name = "modifier_dark_friends_aura_buff"}
)
____exports.modifier_dark_friends_aura_buff = modifier_dark_friends_aura_buff
return ____exports