353 lines
14 KiB
Lua
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
|