223 lines
7.2 KiB
Lua
223 lines
7.2 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 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
|