local A, L = ... local oUF = L.oUF or oUF if not oUF then return end local _G = _G local GetTime = GetTime local UnitPower = UnitPower local UnitClass = UnitClass local tonumber = tonumber local UnitPowerType = UnitPowerType local UnitPowerMax = UnitPowerMax local GetSpellPowerCost = GetSpellPowerCost local LastTickTime = GetTime() local TickDelay = 2.025 -- Average tick time is slightly over 2 seconds local CurrentValue = UnitPower('player') local LastValue = CurrentValue local myClass = select(2, UnitClass('player')) local Mp5Delay = 5 local Mp5DelayWillEnd = nil local Mp5IgnoredSpells = { [18182] = true, -- Improved Life Tap 1 [18183] = true, -- Improved Life Tap 2 [1454] = true, -- Life Tap 1 [1455] = true, -- Life Tap 2 [1456] = true, -- Life Tap 3 [11687] = true, -- Life Tap 4 [11688] = true, -- Life Tap 5 [11689] = true, -- Life Tap 6 } -- Sets tick time to the last possible time based on the last tick local UpdateTickTime = function(now) LastTickTime = now - ((now - LastTickTime) % TickDelay) end local Update = function(self, elapsed) local element = self.EnergyManaRegen element.sinceLastUpdate = (element.sinceLastUpdate or 0) + (tonumber(elapsed) or 0) if element.sinceLastUpdate > 0.01 then local powerType = UnitPowerType('player') if powerType ~= Enum.PowerType.Energy and powerType ~= Enum.PowerType.Mana then element.Spark:Hide() return end CurrentValue = UnitPower('player', powerType) local MaxPower = UnitPowerMax('player', powerType) local Now = GetTime() if powerType == Enum.PowerType.Mana then if CurrentValue >= MaxPower then element:SetValue(0) element.Spark:Hide() return end -- Sync last tick time after 5 seconds are over if Mp5DelayWillEnd and Mp5DelayWillEnd < Now then Mp5DelayWillEnd = nil UpdateTickTime(Now) end elseif powerType == Enum.PowerType.Energy then -- If energy is not full we just wait for the next tick if Now >= LastTickTime + TickDelay and CurrentValue >= MaxPower then UpdateTickTime(Now) end end if Mp5DelayWillEnd and powerType == Enum.PowerType.Mana then -- Show 5 second indicator element.Spark:Show() element:SetMinMaxValues(0, Mp5Delay) element.Spark:SetVertexColor(1, 1, 0, 1) element:SetValue(Mp5DelayWillEnd - Now) else -- Show tick indicator element.Spark:Show() element:SetMinMaxValues(0, TickDelay) element.Spark:SetVertexColor(1, 1, 1, 1) element:SetValue(Now - LastTickTime) end element.sinceLastUpdate = 0 end end local OnUnitPowerUpdate = function() local powerType = UnitPowerType('player') if powerType ~= Enum.PowerType.Mana and powerType ~= Enum.PowerType.Energy then return end -- We also register ticks from mp5 gear within the 5-second-rule to get a more accurate sync later. -- Unfortunately this registers a tick when a mana pot or life tab is used. local CurrentValue = UnitPower('player', powerType) if CurrentValue > LastValue then LastTickTime = GetTime() end LastValue = CurrentValue end local OnUnitSpellcastSucceeded = function(_, _, _, _, spellID) local powerType = UnitPowerType('player') if powerType ~= Enum.PowerType.Mana then return end local spellCost = false local costTable = GetSpellPowerCost(spellID) for _, costInfo in next, costTable do if costInfo.cost then spellCost = true end end if not spellCost or Mp5IgnoredSpells[spellID] then return end Mp5DelayWillEnd = GetTime() + 5 end local Path = function(self, ...) return (self.EnergyManaRegen.Override or Update) (self, ...) end local Enable = function(self, unit) local element = self.EnergyManaRegen local Power = self.Power if (unit == 'player') and element and Power and myClass ~= 'WARRIOR' then element.__owner = self if(element:IsObjectType('StatusBar')) then element:SetStatusBarTexture([[Interface\Buttons\WHITE8X8]]) element:GetStatusBarTexture():SetAlpha(0) element:SetMinMaxValues(0, 2) end local spark = element.Spark if(spark and spark:IsObjectType('Texture')) then spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]]) spark:SetSize(5, 5) spark:SetBlendMode('ADD') spark:SetPoint('CENTER', element:GetStatusBarTexture(), 'RIGHT') end self:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED', OnUnitSpellcastSucceeded) self:RegisterEvent('UNIT_POWER_UPDATE', OnUnitPowerUpdate) element:SetScript('OnUpdate', function(_, elapsed) Path(self, elapsed) end) return true end end local Disable = function(self) local element = self.EnergyManaRegen local Power = self.Power if (Power) and (element) then self:UnregisterEvent('UNIT_SPELLCAST_SUCCEEDED', OnUnitSpellcastSucceeded) self:UnregisterEvent('UNIT_POWER_UPDATE', OnUnitPowerUpdate) element.Spark:Hide() element:SetScript('OnUpdate', nil) return false end end oUF:AddElement('EnergyManaRegen', Path, Enable, Disable)