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