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

223 lines
7.2 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 BaseModifier = ____dota_ts_adapter.BaseModifier
local registerModifier = ____dota_ts_adapter.registerModifier
local ____hero_rage_nettable = require("abilities.hero_rage.hero_rage_nettable")
local clearHeroRageNetTable = ____hero_rage_nettable.clearHeroRageNetTable
local syncHeroRageNetTable = ____hero_rage_nettable.syncHeroRageNetTable
local DEFAULT_MAX = 100
local DEFAULT_RAGE_PER_ATTACK = 3
local DEFAULT_RAGE_WHEN_HIT = 1
local DEFAULT_OUT_OF_COMBAT = 4
--- Как у infinity: шаг, с которым списывается 1 ед. ярости после тайм-аута «без прироста».
local DEFAULT_DECAY_COOLDOWN = 0.5
--- Реже тик — меньше нагрузка (раньше 0.05 сильно лагало).
local MANA_SYNC = 0.12
local function readParam(self, params, key, def)
if params == nil then
return def
end
local t = params
local v = t[key]
if v == nil or v == nil then
return def
end
local n = tonumber(v)
return n ~= nil and n ~= nil and n or def
end
--- Максимальная и текущая «мана» героя = шкала ярости; списание маны при кастах = ярость.
-- Накопление: удары и получение автоатак, затухание после простоя.
____exports.modifier_hero_rage = __TS__Class()
local modifier_hero_rage = ____exports.modifier_hero_rage
modifier_hero_rage.name = "modifier_hero_rage"
modifier_hero_rage.____file_path = "scripts/vscripts/abilities/hero_rage/hero_rage_modifiers.lua"
__TS__ClassExtends(modifier_hero_rage, BaseModifier)
function modifier_hero_rage.prototype.____constructor(self, ...)
BaseModifier.prototype.____constructor(self, ...)
self.maxRage = DEFAULT_MAX
self.ragePerAttack = DEFAULT_RAGE_PER_ATTACK
self.rageWhenHit = DEFAULT_RAGE_WHEN_HIT
self.timeOutForDecay = DEFAULT_OUT_OF_COMBAT
self.decayStep = DEFAULT_DECAY_COOLDOWN
self.manaDelta = 0
self.timeSinceRageGain = 0
self.decayAcc = 0
self.lastNetCur = -1
self.lastNetMax = -1
self.intellectReadLock = false
end
function modifier_hero_rage.prototype.IsHidden(self)
return true
end
function modifier_hero_rage.prototype.IsDebuff(self)
return false
end
function modifier_hero_rage.prototype.IsPurgable(self)
return false
end
function modifier_hero_rage.prototype.RemoveOnDeath(self)
return false
end
function modifier_hero_rage.prototype.DeclareFunctions(self)
return {MODIFIER_PROPERTY_MANA_BONUS, MODIFIER_PROPERTY_STATS_INTELLECT_BONUS, MODIFIER_EVENT_ON_ATTACK_LANDED, MODIFIER_EVENT_ON_DEATH}
end
function modifier_hero_rage.prototype.OnCreated(self, params)
self.parentHero = self:GetParent()
self.maxRage = readParam(nil, params, "max_rage", DEFAULT_MAX)
self.ragePerAttack = readParam(nil, params, "rage_per_attack", DEFAULT_RAGE_PER_ATTACK)
self.rageWhenHit = readParam(nil, params, "rage_per_damage", DEFAULT_RAGE_WHEN_HIT)
self.timeOutForDecay = readParam(nil, params, "time_decrase_rage", DEFAULT_OUT_OF_COMBAT)
self.decayStep = readParam(nil, params, "tick_decrase_rage", DEFAULT_DECAY_COOLDOWN)
self.timeSinceRageGain = 0
self.decayAcc = 0
self.manaDelta = 0
if IsServer() then
self:StartIntervalThink(MANA_SYNC)
self.parentHero:SetMana(0)
self.lastNetCur = -1
self.lastNetMax = -1
self.parentHero:CalculateStatBonus(true)
syncHeroRageNetTable(
nil,
self.parentHero,
0,
self.maxRage,
true
)
end
end
function modifier_hero_rage.prototype.OnRefresh(self, params)
self.maxRage = readParam(nil, params, "max_rage", self.maxRage)
end
function modifier_hero_rage.prototype.GetModifierManaBonus(self)
return self.manaDelta
end
function modifier_hero_rage.prototype.GetModifierBonusStats_Intellect(self)
if self.intellectReadLock then
return 0
end
local p = self:GetParent()
if not p or p:IsNull() then
return 0
end
self.intellectReadLock = true
local int = p:GetIntellect(true)
self.intellectReadLock = false
return int * -1
end
function modifier_hero_rage.prototype.OnAttackLanded(self, event)
if not IsServer() then
return
end
local p = self.parentHero
if event.attacker == p then
self:bumpRage(self.ragePerAttack)
elseif event.target == p then
self:bumpRage(self.rageWhenHit)
end
end
function modifier_hero_rage.prototype.OnDeath(self, event)
if not IsServer() then
return
end
if event.unit ~= self:GetParent() then
return
end
self.parentHero:SetMana(0)
self:pushNet(0, self.maxRage, true)
end
function modifier_hero_rage.prototype.bumpRage(self, amt)
if amt <= 0 then
return
end
self.timeSinceRageGain = 0
self.decayAcc = 0
local p = self.parentHero
local m = p:GetMaxMana()
p:SetMana(math.min(
m,
p:GetMana() + amt
))
end
function modifier_hero_rage.prototype.stripPassiveManaRegen(self, p)
if not p or p:IsNull() then
return
end
local regenPerSec = p:GetManaRegen()
if regenPerSec > 0 then
p:SetMana(math.max(
0,
p:GetMana() - regenPerSec * MANA_SYNC
))
end
end
function modifier_hero_rage.prototype.pushNet(self, cur, max, force)
if force == nil then
force = false
end
if not force and self.lastNetCur == cur and self.lastNetMax == max then
return
end
self.lastNetCur = cur
self.lastNetMax = max
syncHeroRageNetTable(
nil,
self.parentHero,
cur,
max,
true
)
end
function modifier_hero_rage.prototype.OnIntervalThink(self)
if not IsServer() then
return
end
local p = self.parentHero
if not p or p:IsNull() or not p:IsAlive() then
return
end
self.manaDelta = self.maxRage - p:GetMaxMana() + (self.manaDelta or 0)
p:CalculateStatBonus(true)
p:SetMana(math.min(
p:GetMana(),
p:GetMaxMana()
))
self:stripPassiveManaRegen(p)
self.timeSinceRageGain = self.timeSinceRageGain + MANA_SYNC
if self.timeSinceRageGain >= self.timeOutForDecay then
self.decayAcc = self.decayAcc + MANA_SYNC
if self.decayAcc >= self.decayStep then
p:SetMana(math.max(
0,
p:GetMana() - 1
))
self.decayAcc = self.decayAcc - self.decayStep
end
end
self:pushNet(
p:GetMana(),
math.min(
p:GetMaxMana(),
self.maxRage
),
false
)
end
function modifier_hero_rage.prototype.OnDestroy(self)
if IsServer() then
clearHeroRageNetTable(nil, self.parentHero)
end
end
modifier_hero_rage = __TS__Decorate(
modifier_hero_rage,
modifier_hero_rage,
{registerModifier(nil)},
{kind = "class", name = "modifier_hero_rage"}
)
____exports.modifier_hero_rage = modifier_hero_rage
return ____exports