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

353 lines
14 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
local ____modifier_general_hunger = require("abilities.modifiers.modifier_general_hunger")
local modifier_general_hunger = ____modifier_general_hunger.modifier_general_hunger
local ____heal_tracker = require("utils.heal_tracker")
local HealWithBattlePass = ____heal_tracker.HealWithBattlePass
____exports.AXE_BATTLE_HUNGER_CUSTOM = "axe_battle_hunger_custom"
--- Вызывается из Berserker's Call (шард): вешает голод даже без клика, если способность прокачана.
function ____exports.axeApplyBattleHungerFromCall(self, caster, target, duration)
if not IsServer() then
return
end
local hunger = caster:FindAbilityByName(____exports.AXE_BATTLE_HUNGER_CUSTOM)
if not hunger or hunger:GetLevel() <= 0 then
return
end
if target:GetTeamNumber() == caster:GetTeamNumber() then
target:AddNewModifier(caster, hunger, ____exports.modifier_axe_battle_hunger_ally_buff.name, {duration = duration})
else
target:AddNewModifier(caster, hunger, ____exports.modifier_axe_battle_hunger_debuff.name, {duration = duration})
end
end
____exports.axe_battle_hunger_custom = __TS__Class()
local axe_battle_hunger_custom = ____exports.axe_battle_hunger_custom
axe_battle_hunger_custom.name = "axe_battle_hunger_custom"
axe_battle_hunger_custom.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_battle_hunger_custom.lua"
__TS__ClassExtends(axe_battle_hunger_custom, BaseAbility)
function axe_battle_hunger_custom.prototype.Precache(self, context)
PrecacheResource("particle", "particles/units/heroes/hero_axe/axe_battle_hunger.vpcf", context)
PrecacheResource("soundfile", "soundevents/game_sounds_heroes/game_sounds_axe.vsndevts", context)
end
function axe_battle_hunger_custom.prototype.OnSpellStart(self)
if not IsServer() then
return
end
local caster = self:GetCaster()
local target = self:GetCursorTarget()
if not target then
return
end
local duration = self:GetSpecialValueFor("duration")
if target:GetTeamNumber() == caster:GetTeamNumber() then
target:AddNewModifier(caster, self, ____exports.modifier_axe_battle_hunger_ally_buff.name, {duration = duration})
else
target:AddNewModifier(caster, self, ____exports.modifier_axe_battle_hunger_debuff.name, {duration = duration})
end
EmitSoundOn("Hero_Axe.Battle_Hunger", target)
end
function axe_battle_hunger_custom.prototype.GetCastRange(self)
return self:GetSpecialValueFor("AbilityCastRange")
end
function axe_battle_hunger_custom.prototype.CastFilterResultTarget(self, target)
if target:IsInvulnerable() then
return UF_FAIL_CUSTOM
end
return UF_SUCCESS
end
function axe_battle_hunger_custom.prototype.GetAbilityTargetTeam(self)
return DOTA_UNIT_TARGET_TEAM_BOTH
end
axe_battle_hunger_custom.ALLY_HUNGER_STACKS_PER_SECOND = 5
axe_battle_hunger_custom.ALLY_HEAL_PCT_PER_SECOND = 1.5
axe_battle_hunger_custom = __TS__Decorate(
axe_battle_hunger_custom,
axe_battle_hunger_custom,
{registerAbility(nil)},
{kind = "class", name = "axe_battle_hunger_custom"}
)
____exports.axe_battle_hunger_custom = axe_battle_hunger_custom
--- На Аксе: +% скорости за каждого врага с Battle Hunger.
____exports.modifier_axe_battle_hunger_owner_counter = __TS__Class()
local modifier_axe_battle_hunger_owner_counter = ____exports.modifier_axe_battle_hunger_owner_counter
modifier_axe_battle_hunger_owner_counter.name = "modifier_axe_battle_hunger_owner_counter"
modifier_axe_battle_hunger_owner_counter.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_battle_hunger_custom.lua"
__TS__ClassExtends(modifier_axe_battle_hunger_owner_counter, BaseModifier)
function modifier_axe_battle_hunger_owner_counter.prototype.IsHidden(self)
return true
end
function modifier_axe_battle_hunger_owner_counter.prototype.IsPurgable(self)
return false
end
function modifier_axe_battle_hunger_owner_counter.changeStacksOnCaster(self, caster, delta)
local ab = caster:FindAbilityByName(____exports.AXE_BATTLE_HUNGER_CUSTOM)
if ab then
local m = caster:FindModifierByName(____exports.modifier_axe_battle_hunger_owner_counter.name)
if not m and delta > 0 then
m = caster:AddNewModifier(caster, ab, ____exports.modifier_axe_battle_hunger_owner_counter.name, {})
end
if m and not m:IsNull() then
local next = math.max(
0,
m:GetStackCount() + delta
)
m:SetStackCount(next)
if next <= 0 then
m:Destroy()
end
end
end
end
function modifier_axe_battle_hunger_owner_counter.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE}
end
function modifier_axe_battle_hunger_owner_counter.prototype.GetModifierMoveSpeedBonus_Percentage(self)
local ab = self:GetAbility()
if not ab then
return 0
end
local pct = ab:GetSpecialValueFor("speed_per_enemy_pct")
return self:GetStackCount() * pct
end
modifier_axe_battle_hunger_owner_counter = __TS__Decorate(
modifier_axe_battle_hunger_owner_counter,
modifier_axe_battle_hunger_owner_counter,
{registerModifier(nil)},
{kind = "class", name = "modifier_axe_battle_hunger_owner_counter"}
)
____exports.modifier_axe_battle_hunger_owner_counter = modifier_axe_battle_hunger_owner_counter
____exports.modifier_axe_battle_hunger_debuff = __TS__Class()
local modifier_axe_battle_hunger_debuff = ____exports.modifier_axe_battle_hunger_debuff
modifier_axe_battle_hunger_debuff.name = "modifier_axe_battle_hunger_debuff"
modifier_axe_battle_hunger_debuff.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_battle_hunger_custom.lua"
__TS__ClassExtends(modifier_axe_battle_hunger_debuff, BaseModifier)
function modifier_axe_battle_hunger_debuff.prototype.IsHidden(self)
return false
end
function modifier_axe_battle_hunger_debuff.prototype.IsDebuff(self)
return true
end
function modifier_axe_battle_hunger_debuff.prototype.GetAttributes(self)
return MODIFIER_ATTRIBUTE_MULTIPLE
end
function modifier_axe_battle_hunger_debuff.prototype.IsPurgable(self)
return true
end
function modifier_axe_battle_hunger_debuff.prototype.GetTexture(self)
return "axe_battle_hunger"
end
function modifier_axe_battle_hunger_debuff.prototype.OnCreated(self)
if not IsServer() then
return
end
self:StartIntervalThink(1)
____exports.modifier_axe_battle_hunger_owner_counter:changeStacksOnCaster(
self:GetCaster(),
1
)
local parent = self:GetParent()
self.killListener = ListenToGameEvent(
"entity_killed",
function(event)
if not parent or not parent:IsAlive() then
return
end
local attacker = EntIndexToHScript(event.entindex_attacker)
if attacker == parent then
self:Destroy()
end
end,
nil
)
end
function modifier_axe_battle_hunger_debuff.prototype.OnIntervalThink(self)
if not IsServer() then
return
end
local parent = self:GetParent()
local caster = self:GetCaster()
local ability = self:GetAbility()
if not parent or not caster or not ability then
return
end
local basePerSec = ability:GetSpecialValueFor("damage_per_second")
local armorMult = ability:GetSpecialValueFor("armor_mult") * 0.01
local armorBonus = caster:GetPhysicalArmorBaseValue() * armorMult
local dmg = math.max(1, basePerSec + armorBonus)
local dealtDamage = ApplyDamage({
victim = parent,
attacker = caster,
damage = dmg,
damage_type = ability:GetAbilityDamageType(),
ability = ability
})
SendOverheadEventMessage(
nil,
OVERHEAD_ALERT_BONUS_SPELL_DAMAGE,
parent,
dealtDamage,
caster:GetPlayerOwner()
)
end
function modifier_axe_battle_hunger_debuff.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE}
end
function modifier_axe_battle_hunger_debuff.prototype.GetModifierMoveSpeedBonus_Percentage(self)
local ability = self:GetAbility()
if not ability then
return 0
end
local slow = ability:GetSpecialValueFor("slow")
local parent = self:GetParent()
local caster = self:GetCaster()
if not parent or not caster then
return 0
end
local toAxe = caster:GetAbsOrigin():__sub(parent:GetAbsOrigin()):Normalized()
local fwd = parent:GetForwardVector()
local facingAxe = fwd:Dot(toAxe)
if facingAxe < 0.25 then
return -slow
end
return 0
end
function modifier_axe_battle_hunger_debuff.prototype.GetEffectName(self)
return "particles/units/heroes/hero_axe/axe_battle_hunger.vpcf"
end
function modifier_axe_battle_hunger_debuff.prototype.GetEffectAttachType(self)
return PATTACH_OVERHEAD_FOLLOW
end
function modifier_axe_battle_hunger_debuff.prototype.OnRefresh(self)
if IsServer() then
self:SetDuration(
self:GetAbility():GetSpecialValueFor("duration"),
true
)
end
end
function modifier_axe_battle_hunger_debuff.prototype.OnDestroy(self)
if IsServer() then
local caster = self:GetCaster()
if caster then
____exports.modifier_axe_battle_hunger_owner_counter:changeStacksOnCaster(caster, -1)
end
if self.killListener ~= nil then
StopListeningToGameEvent(self.killListener)
self.killListener = nil
end
end
end
modifier_axe_battle_hunger_debuff = __TS__Decorate(
modifier_axe_battle_hunger_debuff,
modifier_axe_battle_hunger_debuff,
{registerModifier(nil)},
{kind = "class", name = "modifier_axe_battle_hunger_debuff"}
)
____exports.modifier_axe_battle_hunger_debuff = modifier_axe_battle_hunger_debuff
____exports.modifier_axe_battle_hunger_ally_buff = __TS__Class()
local modifier_axe_battle_hunger_ally_buff = ____exports.modifier_axe_battle_hunger_ally_buff
modifier_axe_battle_hunger_ally_buff.name = "modifier_axe_battle_hunger_ally_buff"
modifier_axe_battle_hunger_ally_buff.____file_path = "scripts/vscripts/abilities/heroes/axe/axe_battle_hunger_custom.lua"
__TS__ClassExtends(modifier_axe_battle_hunger_ally_buff, BaseModifier)
function modifier_axe_battle_hunger_ally_buff.prototype.IsHidden(self)
return false
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetAttributes(self)
return MODIFIER_ATTRIBUTE_MULTIPLE
end
function modifier_axe_battle_hunger_ally_buff.prototype.IsDebuff(self)
return false
end
function modifier_axe_battle_hunger_ally_buff.prototype.IsPurgable(self)
return true
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetTexture(self)
return "axe_battle_hunger"
end
function modifier_axe_battle_hunger_ally_buff.prototype.OnCreated(self)
if not IsServer() then
return
end
self:StartIntervalThink(1)
end
function modifier_axe_battle_hunger_ally_buff.prototype.OnIntervalThink(self)
if not IsServer() then
return
end
local parent = self:GetParent()
local caster = self:GetCaster()
local ability = self:GetAbility()
if not parent or not caster or not ability then
return
end
local hunger = parent:FindModifierByName(modifier_general_hunger.name)
if not hunger then
hunger = parent:AddNewModifier(caster, ability, modifier_general_hunger.name, {})
end
if hunger and not hunger:IsNull() then
do
local i = 0
while i < ____exports.axe_battle_hunger_custom.ALLY_HUNGER_STACKS_PER_SECOND do
hunger:IncrementStackCount()
i = i + 1
end
end
end
local heal = parent:GetMaxHealth() * (____exports.axe_battle_hunger_custom.ALLY_HEAL_PCT_PER_SECOND * 0.01)
if heal > 0 then
HealWithBattlePass(
nil,
parent,
heal,
ability,
caster
)
SendOverheadEventMessage(
nil,
OVERHEAD_ALERT_HEAL,
parent,
heal,
parent:GetPlayerOwner()
)
end
end
function modifier_axe_battle_hunger_ally_buff.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_BASEDAMAGEOUTGOING_PERCENTAGE, MODIFIER_PROPERTY_TOOLTIP}
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetModifierBaseDamageOutgoing_Percentage(self)
local ability = self:GetAbility()
if not ability then
return 0
end
return ability:GetSpecialValueFor("speed_bonus")
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetModifierTooltip(self)
local parent = self:GetParent()
if not parent then
return 0
end
return math.floor(parent:GetMaxHealth() * (____exports.axe_battle_hunger_custom.ALLY_HEAL_PCT_PER_SECOND * 0.01) + 0.5)
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetEffectName(self)
return "particles/units/heroes/hero_axe/axe_battle_hunger.vpcf"
end
function modifier_axe_battle_hunger_ally_buff.prototype.GetEffectAttachType(self)
return PATTACH_OVERHEAD_FOLLOW
end
modifier_axe_battle_hunger_ally_buff = __TS__Decorate(
modifier_axe_battle_hunger_ally_buff,
modifier_axe_battle_hunger_ally_buff,
{registerModifier(nil)},
{kind = "class", name = "modifier_axe_battle_hunger_ally_buff"}
)
____exports.modifier_axe_battle_hunger_ally_buff = modifier_axe_battle_hunger_ally_buff
return ____exports