-- Setup frames |
function PowerUp:Init() |
db = PowerUpDB |
db.max = 3 |
|
powerType = "HOLY_POWER" |
powerName = SPELL_POWER_HOLY_POWER |
|
for i=1, #self.bars do |
self.bars[i]:SetVertexColor(db.colors.paladin.r, db.colors.paladin.g, db.colors.paladin.b) |
end |
|
-- create overlay if enabled |
if db.showhptimer then |
self.timer = self.timer or CreateFrame("StatusBar", "PowerUpTimer", self) |
|
self.timer:SetAllPoints(self) |
self.timer:SetMinMaxValues(0, 10) |
self.timer:SetValue(0) |
|
self.timer:SetStatusBarTexture(self.bars[1]:GetTexture()) |
self.timer:SetStatusBarColor(db.colors.overlay.r, db.colors.overlay.g, db.colors.overlay.b, db.hptimeralpha) |
|
self.timer.text = self.timer.text or self.timer:CreateFontString(nil, "OVERLAY") |
self.timer.text:SetFontObject(GameFontHighlight) |
self.timer.text:SetPoint("LEFT", self.timer, "RIGHT", 5, 0) |
|
-- we need this to account for pausing and whatnot |
self:RegisterEvent("PLAYER_REGEN_ENABLED") |
self:RegisterEvent("PLAYER_REGEN_DISABLED") |
end |
|
self.last = 0 |
self:Workshop() |
self:Paintshop() |
self:ToggleOverlay() |
|
self:RegisterEvent("UNIT_POWER") |
self.UNIT_POWER = self.RefreshPowers |
|
self.prior = 0 |
|
-- update powers at login/zoning in case we have some already |
-- if a power disappears during loading screen, it wont update |
-- properly otherwise. |
self:RegisterEvent("PLAYER_ENTERING_WORLD") |
end |
|
-- Throttle? Not really necessary maybe, since it's not running for |
-- excessive amounts of time. |
local function onUpdate(self, elapsed) |
local value = self.timer:GetValue() |
local new = value - elapsed |
|
if value <= 0 then |
self.timer:Hide() |
self:SetScript("OnUpdate", nil) |
else |
self.timer:SetValue(new) |
|
if db.showtimertext then |
self.timer.text:SetFormattedText("%.1f", new) |
else |
self.timer.text:SetText("") |
function PowerUp:ToggleOverlay() |
if db.showOverlay then |
if not self.timer then |
self.timer = CreateFrame("Frame", nil, self.frame) |
self.timer.color = self.timer:CreateTexture(nil, "OVERLAY") |
self.timer.color:SetTexture(db.texture) |
self.timer.color:SetAllPoints(self.timer) |
self.timer:SetAllPoints(self.frame) |
|
self.overlay = self.timer:CreateAnimationGroup() |
self.animation = self.overlay:CreateAnimation("Scale") |
self.animation:SetDuration(10.25) |
self.animation:SetMaxFramerate(30) -- looks nice enough |
self.animation:SetOrigin("LEFT", 0, 0) |
self.animation:SetScale(0, 1) |
|
self.overlay.Restart = function() self.overlay:Stop() self.overlay:Play() end |
self.overlay:SetScript("OnFinished", function() self.timer:Hide() end) |
self.overlay:SetScript("OnPlay", function() self.timer:Show() end) |
end |
|
if db.usehpgradient then |
self.timer:SetStatusBarColor(1*(1-(value/10)), 1*(value/10), 0, db.hptimeralpha) |
end |
if db.useGradient then |
self.overlay:SetScript("OnUpdate", function(f, elapsed) |
local p = self.overlay:GetProgress() |
self.timer.color:SetVertexColor(p, 1-p, 0, db.overlayAlpha) |
end) |
else |
self.timer.color:SetVertexColor(db.colors.overlay.r, db.colors.overlay.g, db.colors.overlay.b, db.overlayAlpha) |
self.overlay:SetScript("OnUpdate", nil) |
end |
self:RegisterEvent("PLAYER_REGEN_ENABLED") |
self:RegisterEvent("PLAYER_REGEN_DISABLED") |
else |
if self.timer then self.timer:Hide() end |
self:UnregisterEvent("PLAYER_REGEN_ENABLED") |
self:UnregisterEvent("PLAYER_REGEN_DISABLED") |
end |
end |
|
-- All the latency-stuff is there to offset possible fluctuations in lag causing the timer |
-- to not be exactly 10s every time. See note above for a few more details. That also |
-- explains why we're first checking if there was any active prior to combat. |
function PowerUp:StartTimer() |
if InCombatLockdown() then return end |
|
local prior = nil |
local num = UnitPower("player", SPELL_POWER_HOLY_POWER) |
|
for i=1, num do |
if self.bars[i].wasactive then |
prior = i |
end |
end |
|
local _, _, latency = GetNetStats() |
latency = format("%.02f", (latency/1000)) |
|
if not prior then |
self.timer:SetMinMaxValues(0, 10+latency) |
self.timer:SetValue(10+latency) |
else |
self.timer:SetMinMaxValues(0, (10+latency)-self.bars[prior].alreadyElapsed) |
self.timer:SetValue((10+latency) - self.bars[prior].alreadyElapsed) |
end |
self:SetScript("OnUpdate", onUpdate) |
self.timer:Show() |
function PowerUp:PLAYER_ENTERING_WORLD() |
pguid = UnitGUID("player") |
self:RefreshPowers("player", powerType) |
end |
|
-- Save how much has already elapsed if there are charges available |
-- Timer was running, so pause it for now. |
function PowerUp:PLAYER_REGEN_DISABLED() |
local num = UnitPower("player", SPELL_POWER_HOLY_POWER) |
if self.timer:IsVisible() and num > 0 then |
local min, max = self.timer:GetMinMaxValues() |
self:SetScript("OnUpdate", nil) |
if self.overlay:IsPlaying() then |
self.overlay:Pause() |
self.timer:Hide() |
self.bars[num].wasactive = true |
self.bars[num].alreadyElapsed = 10 - self.timer:GetValue() |
self.timer:SetValue(0) |
end |
end |
|
-- If there are any charges, start a timer! |
-- Resume playing |
function PowerUp:PLAYER_REGEN_ENABLED() |
local num = UnitPower("player", SPELL_POWER_HOLY_POWER) |
if num > 0 then |
self:StartTimer() |
end |
self.overlay:Play() |
end |
|
function PowerUp:PLAYER_ENTERING_WORLD() |
pguid = UnitGUID("player") |
self:RefreshPowers("player", powerType) |
end |
|
-- use CLEU when at max charges |
function PowerUp:COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, spellId, spellName, _, _, powerType) |
if sourceGUID == pguid and event == "SPELL_ENERGIZE" and powerType == 9 then |
if InCombatLockdown() then |
self.bars[db.max].wasactive = false |
else |
self:StartTimer() |
end |
-- Watch for changes when @ max |
function PowerUp:COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, _, _, _, _, power) |
if sourceGUID == pguid and event == "SPELL_ENERGIZE" and power == 9 then |
self:RefreshPowers("player", powerType) |
end |
end |
|
function PowerUp:RefreshPowers(unit, power) |
if unit ~= "player" or (power and power ~= powerType) then return end |
local num = UnitPower("player", powerName) |
|
|
for i = 1, db.max do |
if(i <= num) then |
self.bars[i]:SetAlpha(1) |
-- we have more than 1, so check if the prior one was active before we |
-- entered combat and remove the flag if true. |
if num > 1 and db.showhptimer then |
if self.bars[num-1].wasactive then |
self.bars[num-1].wasactive = false |
end |
end |
else |
self.bars[i]:SetAlpha(0) |
-- Check if the charge was active before combat and make a note |
-- that it expired during combat. |
if db.showhptimer and self.bars[i].wasactive then |
self.bars[i].wasactive = false |
end |
end |
end |
|
if db.showhptimer and not InCombatLockdown() then |
if num == 0 then -- hiiiide |
self.timer:SetValue(0) |
self.timer:Hide() |
self:SetScript("OnUpdate", nil) |
elseif num > self.last then |
-- increase, start new timer if applicable |
|
self:StartTimer() |
elseif num < self.last then |
-- decrease |
self:StartTimer() |
if db.showOverlay then |
if num ~= self.prior or num == db.max then |
-- If paused it means it was running but is now invalid, so stop it |
if self.overlay:IsPaused() then self.overlay:Stop() end |
if not InCombatLockdown() then |
if num < self.prior then -- lost a charge, check if timer should still be running |
if num > 0 then |
self.overlay:Restart() |
end |
elseif num > self.prior then -- gained a charge, restart timer |
self.overlay:Restart() |
end |
|
if num == db.max then |
self.overlay:Restart() |
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
else |
self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
end |
end |
end |
elseif not db.showhptimer and self.timer:IsVisible() then |
self.timer:Hide() |
self:SetScript("OnUpdate", nil) |
end |
|
-- if we're at max, UNIT_POWER won't fire until one charge expires, |
-- which means the timer won't update properly. |
if num == db.max then |
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
else |
self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
end |
|
self.last = num |
|
if db.hidewhenempty and num == 0 then |
self:Hide() |
self.frame:Hide() |
else |
self:Show() |
if num == 0 then self.timer:Hide() end |
self.frame:Show() |
end |
|
self.prior = num |
end |