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

258 lines
10 KiB
Lua

local ____lualib = require("lualib_bundle")
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
require("utils.utils")
local ____axe_battle_hunger_custom = require("abilities.heroes.axe.axe_battle_hunger_custom")
local axeApplyBattleHungerFromCall = ____axe_battle_hunger_custom.axeApplyBattleHungerFromCall
local NEVERMORE_RAID_BOSS = "npc_boss_nevermore"
local function isNevermoreRaidBoss(self, unit)
return unit:GetUnitName() == NEVERMORE_RAID_BOSS
end
--- Berserker's Call — как в доте: тантует врагов в радиусе, броня на Акса; шард вешает Battle Hunger.
____exports.axe_berserkers_call_custom = __TS__Class()
local axe_berserkers_call_custom = ____exports.axe_berserkers_call_custom
axe_berserkers_call_custom.name = "axe_berserkers_call_custom"
axe_berserkers_call_custom.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_berserkers_call_custom.lua"
__TS__ClassExtends(axe_berserkers_call_custom, BaseAbility)
function axe_berserkers_call_custom.prototype.Precache(self, context)
PrecacheResource("particle", "particles/units/heroes/hero_axe/axe_beserkers_call_owner.vpcf", context)
PrecacheResource("particle", "particles/status_fx/status_effect_beserkers_call.vpcf", context)
PrecacheResource("soundfile", "soundevents/game_sounds_heroes/game_sounds_axe.vsndevts", context)
end
function axe_berserkers_call_custom.prototype.OnAbilityPhaseStart(self)
if IsServer() then
EmitSoundOn(
"Hero_Axe.BerserkersCall.Start",
self:GetCaster()
)
end
return true
end
function axe_berserkers_call_custom.prototype.OnAbilityPhaseInterrupted(self)
if IsServer() then
StopSoundOn(
"Hero_Axe.BerserkersCall.Start",
self:GetCaster()
)
end
end
function axe_berserkers_call_custom.prototype.OnSpellStart(self)
if not IsServer() then
return
end
local caster = self:GetCaster()
local radius = self:GetSpecialValueFor("radius")
local duration = self:GetSpecialValueFor("duration")
caster:AddNewModifier(caster, self, ____exports.modifier_axe_berserkers_call_armor.name, {duration = duration})
local enemies = FindUnitsInRadius(
caster:GetTeamNumber(),
caster:GetAbsOrigin(),
nil,
radius,
DOTA_UNIT_TARGET_TEAM_ENEMY,
DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES,
FIND_ANY_ORDER,
false
)
local shard = HasShard(nil, caster)
local hungerDur = self:GetSpecialValueFor("shard_hunger_duration")
for ____, enemy in ipairs(enemies) do
do
if not enemy or not enemy:IsAlive() then
goto __continue10
end
if isNevermoreRaidBoss(nil, enemy) then
goto __continue10
end
self:issueAttackOrder(enemy, caster)
enemy:AddNewModifier(caster, self, ____exports.modifier_axe_berserkers_call_taunt.name, {duration = duration})
if shard then
axeApplyBattleHungerFromCall(nil, caster, enemy, hungerDur)
end
end
::__continue10::
end
if shard then
local allies = FindUnitsInRadius(
caster:GetTeamNumber(),
caster:GetAbsOrigin(),
nil,
radius,
DOTA_UNIT_TARGET_TEAM_FRIENDLY,
DOTA_UNIT_TARGET_HERO,
DOTA_UNIT_TARGET_FLAG_NONE,
FIND_ANY_ORDER,
false
)
for ____, ally in ipairs(allies) do
do
if not ally or not ally:IsAlive() then
goto __continue16
end
axeApplyBattleHungerFromCall(nil, caster, ally, hungerDur)
end
::__continue16::
end
end
if #enemies > 0 then
EmitSoundOn("Hero_Axe.Berserkers_Call", caster)
end
local particle_cast = "particles/units/heroes/hero_axe/axe_beserkers_call_owner.vpcf"
local effect_cast = ParticleManager:CreateParticle(particle_cast, PATTACH_ABSORIGIN_FOLLOW, caster)
ParticleManager:SetParticleControlEnt(
effect_cast,
1,
caster,
PATTACH_ABSORIGIN_FOLLOW,
"attach_mouth",
Vector(0, 0, 0),
true
)
ParticleManager:SetParticleControl(
effect_cast,
2,
Vector(radius, radius, radius)
)
ParticleManager:ReleaseParticleIndex(effect_cast)
end
function axe_berserkers_call_custom.prototype.issueAttackOrder(self, attacker, target)
local canAttack = attacker:GetAttackCapability() ~= DOTA_UNIT_CAP_NO_ATTACK and not attacker:IsDisarmed()
if not canAttack then
ExecuteOrderFromTable({
UnitIndex = attacker:entindex(),
OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
Position = target:GetAbsOrigin(),
Queue = false
})
return
end
ExecuteOrderFromTable({
UnitIndex = attacker:entindex(),
OrderType = DOTA_UNIT_ORDER_ATTACK_TARGET,
TargetIndex = target:entindex(),
Queue = false
})
end
axe_berserkers_call_custom = __TS__Decorate(
axe_berserkers_call_custom,
axe_berserkers_call_custom,
{registerAbility(nil)},
{kind = "class", name = "axe_berserkers_call_custom"}
)
____exports.axe_berserkers_call_custom = axe_berserkers_call_custom
____exports.modifier_axe_berserkers_call_armor = __TS__Class()
local modifier_axe_berserkers_call_armor = ____exports.modifier_axe_berserkers_call_armor
modifier_axe_berserkers_call_armor.name = "modifier_axe_berserkers_call_armor"
modifier_axe_berserkers_call_armor.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_berserkers_call_custom.lua"
__TS__ClassExtends(modifier_axe_berserkers_call_armor, BaseModifier)
function modifier_axe_berserkers_call_armor.prototype.IsHidden(self)
return false
end
function modifier_axe_berserkers_call_armor.prototype.IsPurgable(self)
return false
end
function modifier_axe_berserkers_call_armor.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS}
end
function modifier_axe_berserkers_call_armor.prototype.GetModifierPhysicalArmorBonus(self)
return self:GetAbility():GetSpecialValueFor("bonus_armor")
end
function modifier_axe_berserkers_call_armor.prototype.GetStatusEffectName(self)
return "particles/status_fx/status_effect_beserkers_call.vpcf"
end
modifier_axe_berserkers_call_armor = __TS__Decorate(
modifier_axe_berserkers_call_armor,
modifier_axe_berserkers_call_armor,
{registerModifier(nil)},
{kind = "class", name = "modifier_axe_berserkers_call_armor"}
)
____exports.modifier_axe_berserkers_call_armor = modifier_axe_berserkers_call_armor
____exports.modifier_axe_berserkers_call_taunt = __TS__Class()
local modifier_axe_berserkers_call_taunt = ____exports.modifier_axe_berserkers_call_taunt
modifier_axe_berserkers_call_taunt.name = "modifier_axe_berserkers_call_taunt"
modifier_axe_berserkers_call_taunt.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_berserkers_call_custom.lua"
__TS__ClassExtends(modifier_axe_berserkers_call_taunt, BaseModifier)
function modifier_axe_berserkers_call_taunt.prototype.IsHidden(self)
return false
end
function modifier_axe_berserkers_call_taunt.prototype.IsPurgable(self)
return false
end
function modifier_axe_berserkers_call_taunt.prototype.IsDebuff(self)
return true
end
function modifier_axe_berserkers_call_taunt.prototype.CheckState(self)
return {[MODIFIER_STATE_COMMAND_RESTRICTED] = true}
end
function modifier_axe_berserkers_call_taunt.prototype.GetStatusEffectName(self)
return "particles/status_fx/status_effect_beserkers_call.vpcf"
end
function modifier_axe_berserkers_call_taunt.prototype.OnCreated(self)
if not IsServer() then
return
end
local parent = self:GetParent()
local caster = self:GetCaster()
if not caster or not parent then
return
end
self.reissueTimer = Timers:CreateTimer(
0.25,
function()
if not IsValidEntity(parent) or not IsValidEntity(caster) then
return nil
end
if not parent:IsAlive() or not caster:IsAlive() then
return nil
end
local canAttack = parent:GetAttackCapability() ~= DOTA_UNIT_CAP_NO_ATTACK and not parent:IsDisarmed()
if not canAttack then
ExecuteOrderFromTable({
UnitIndex = parent:entindex(),
OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
Position = caster:GetAbsOrigin(),
Queue = false
})
return 0.25
end
ExecuteOrderFromTable({
UnitIndex = parent:entindex(),
OrderType = DOTA_UNIT_ORDER_ATTACK_TARGET,
TargetIndex = caster:entindex(),
Queue = false
})
return 0.25
end
)
end
function modifier_axe_berserkers_call_taunt.prototype.OnDestroy(self)
if self.reissueTimer ~= nil then
Timers:RemoveTimer(self.reissueTimer)
self.reissueTimer = nil
end
end
function modifier_axe_berserkers_call_taunt.prototype.OnDeath(self, event)
if IsServer() and event.unit == self:GetCaster() then
self:Destroy()
end
end
function modifier_axe_berserkers_call_taunt.prototype.DeclareFunctions(self)
return {MODIFIER_EVENT_ON_DEATH}
end
modifier_axe_berserkers_call_taunt = __TS__Decorate(
modifier_axe_berserkers_call_taunt,
modifier_axe_berserkers_call_taunt,
{registerModifier(nil)},
{kind = "class", name = "modifier_axe_berserkers_call_taunt"}
)
____exports.modifier_axe_berserkers_call_taunt = modifier_axe_berserkers_call_taunt
return ____exports