WoWInterface SVN PowerUp

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 5 to Rev 4
    Reverse comparison

Rev 5 → Rev 4

trunk/PowerUp/Modules/Paladin.lua
9,12 → 9,16
you entered combat and didn't use the charge, the timer will pick up where it paused prior to combat.
 
Due to latency both between one self and the servers as well as difference when the game considers you out of combat to when you're
actually out of combat (and Blizzards internal timer starts) it's not possible to make it 100% accurate. As such there's a flat .25 added
onto the timer to account for this delay, but this number can be tweaked if wanted.
actually out of combat (and Blizzards internal timer starts) it's not possible to make it 100% accurate, ergo it's guesstimating by
adding the players current latency (which itself is a average value) onto the maximum-value of the bar. While not perfect, it makes
it accurate enough to the point where you get a reliable indication of when it's going to expire.
 
It also seems like UNIT_POWER doesn't fire for new charges when you're already at the max amount. The CLEU SPELL_ENERGIZE event does
fire though.
]]
local _, PowerUp = ...
 
-- local PowerUp = _G.PowerUp
 
if PowerUp.class ~= "PALADIN" then return end
 
local db, pguid
23,130 → 27,190
-- 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:Workshop()
self:Paintshop()
self:ToggleOverlay()
self.last = 0
 
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
 
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)
-- 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("")
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")
 
if db.usehpgradient then
self.timer:SetStatusBarColor(1*(1-(value/10)), 1*(value/10), 0, db.hptimeralpha)
end
end
end
 
function PowerUp:PLAYER_ENTERING_WORLD()
pguid = UnitGUID("player")
self:RefreshPowers("player", powerType)
-- 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()
end
 
-- Timer was running, so pause it for now.
-- Save how much has already elapsed if there are charges available
function PowerUp:PLAYER_REGEN_DISABLED()
if self.overlay:IsPlaying() then
self.overlay:Pause()
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)
self.timer:Hide()
self.bars[num].wasactive = true
self.bars[num].alreadyElapsed = 10 - self.timer:GetValue()
self.timer:SetValue(0)
end
end
 
-- Resume playing
-- If there are any charges, start a timer!
function PowerUp:PLAYER_REGEN_ENABLED()
self.overlay:Play()
local num = UnitPower("player", SPELL_POWER_HOLY_POWER)
if num > 0 then
self:StartTimer()
end
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)
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
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.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
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()
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.frame:Hide()
self:Hide()
else
if num == 0 then self.timer:Hide() end
self.frame:Show()
self:Show()
end
 
self.prior = num
end
\ No newline at end of file
trunk/PowerUp/Modules/Warlock.lua
1,8 → 1,9
--[[
PowerUp - Warlock Module
]]
local _, PowerUp = ...
 
-- local PowerUp = _G.PowerUp
 
if PowerUp.class ~= "WARLOCK" then return end
 
local db
11,13 → 12,13
-- Setup frames
function PowerUp:Init()
db = PowerUpDB
db.max = 3
 
 
powerType = "SOUL_SHARDS"
powerName = SPELL_POWER_SOUL_SHARDS
 
self:Workshop()
self:Paintshop()
for i=1, #self.bars do
self.bars[i]:SetVertexColor(db.colors.warlock.r, db.colors.warlock.g, db.colors.warlock.b)
end
 
self:RegisterEvent("UNIT_POWER")
self.UNIT_POWER = self.RefreshPowers
37,9 → 38,9
local num = UnitPower("player", powerName)
 
if db.hidewhenempty and num == 0 then
self.frame:Hide()
self:Hide()
else
self.frame:Show()
self:Show()
end
 
for i = 1, db.max do
trunk/PowerUp/Options.lua
1,4 → 1,5
local addon, PowerUp = ...
local ADDON, ns = ...
local db
 
-- Defaults
local defaults = {
8,14 → 9,15
point = "CENTER",
x = 0,
y = 200,
max = 3,
hidewhenempty = true, -- hides the frame when empty
colors = {
WARLOCK = {
warlock = {
r = .58,
g = .51,
b = .79,
},
PALADIN = {
paladin = {
r = 1,
g = 1,
b = 0,
26,118 → 28,10
b = 0,
}
},
showOverlay = true, -- positions an overlay on top of the holypowers guesstimating when the next power will expire
overlayAlpha = .5, -- the alpha of the overlay
useGradient = true, -- if true, the overlay will fade from green (@max) to red (@min), otherwise the color below is used
hideBlizz = true, -- hide default Blizzard powerbars
showhptimer = true, -- positions an overlay on top of the holypowers guesstimating when the next power will expire
showtimertext = false, -- shows a textual-timer next to the bar, only works if 'showhptimer' is true
hptimeralpha = .5, -- the alpha of the overlay
usehpgradient = true, -- if true, the overlay will fade from green (@max) to red (@min), otherwise the color below is used
hideblizz = true, -- hide default Blizzard powerbars
}
 
PowerUp.defaults = defaults
 
local title, desc = select(2, GetAddOnInfo(addon))
local f = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
PowerUp.panel = f
f.name = title
f:Hide()
 
f:SetScript("OnShow", function(self)
db = PowerUpDB
 
-- Header
local header = self:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
header:SetPoint("TOPLEFT", 16, -16)
header:SetText(title)
 
-- Tagline
local tag = self:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
tag:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -5)
tag:SetText(desc)
 
-- Hide when empty
local hide = CreateFrame("CheckButton", "PowerUpHideCheck", f, "InterfaceOptionsCheckButtonTemplate")
hide:SetChecked(db.hidewhenempty)
hide:SetScript("OnClick", function(self)
db.hidewhenempty = not db.hidewhenempty
PowerUp:PLAYER_ENTERING_WORLD()
end)
hide:SetPoint("TOPLEFT", tag, "BOTTOMLEFT", 0, -20)
_G[hide:GetName() .. "Text"]:SetText("Hide the bar when empty")
hide.tooltipText = "Hide"
hide.tooltipRequirement = "Toggle to hide the bar when you have no charges."
 
-- Hide Blizzard
local hb = CreateFrame("CheckButton", "PowerUpHideBlizzCheck", f, "InterfaceOptionsCheckButtonTemplate")
hb:SetChecked(db.hideBlizz)
hb:SetScript("OnClick", function(self)
db.hideBlizz = not db.hideBlizz
PowerUp:HideBlizzard()
end)
hb:SetPoint("TOPLEFT", hide, "BOTTOMLEFT", 0, -2)
_G[hb:GetName() .. "Text"]:SetText("Hide Blizzard frames")
hb.tooltipText = "Hide Blizzard"
hb.tooltipRequirement = "Toggle to hide Blizzards own frames."
 
local width = CreateFrame("Slider", "PowerUpWidthSlider", f, "OptionsSliderTemplate")
width.text = _G[width:GetName() .. "Text"]
width:SetValueStep(1)
width:SetMinMaxValues(50, 300)
width:SetScript("OnValueChanged", function(self)
db.width = self:GetValue()
width.text:SetText(string.format("Width: %d", db.width))
PowerUp:Paintshop()
end)
width:SetPoint("TOPLEFT", hb, "BOTTOMLEFT", 0, -20)
width:SetValue(db.width)
width.text:SetText(string.format("Width: %d", db.width))
width.tooltipText = "Width"
width.tooltipRequirement = "Set the width of the frame."
 
local height = CreateFrame("Slider", "PowerUpHeightSlider", f, "OptionsSliderTemplate")
height.text = _G[height:GetName() .. "Text"]
height:SetValueStep(1)
height:SetMinMaxValues(5, 25)
height:SetScript("OnValueChanged", function(self)
db.height = self:GetValue()
height.text:SetText(string.format("Height: %d", db.height))
PowerUp:Paintshop()
end)
height:SetPoint("LEFT", width, "RIGHT", 50, 0)
height:SetValue(db.height)
height.text:SetText(string.format("Height: %d", db.height))
height.tooltipText = "Height"
height.tooltipRequirement = "Set the height of the frame."
 
if PowerUp.class == "PALADIN" then
local header = self:CreateFontString(nil, "ARTWORK", "GameFontNormal")
header:SetText("Paladin")
header:SetPoint("TOPLEFT", width, "BOTTOMLEFT", 0, -50)
 
-- Overlay
local overlay = CreateFrame("CheckButton", "PowerUpOverlayCheck", f, "InterfaceOptionsCheckButtonTemplate")
overlay:SetChecked(db.showOverlay)
overlay:SetScript("OnClick", function(self)
db.showOverlay = not db.showOverlay
PowerUp:ToggleOverlay()
end)
overlay:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -5)
_G[overlay:GetName() .. "Text"]:SetText("Show overlay")
overlay.tooltipText = "Overlay"
overlay.tooltipRequirement = "Toggle to display the overlay. Please note that you might have to lose or gain a charge for this to take proper effect."
 
-- Gradient
local gradient = CreateFrame("CheckButton", "PowerUpGradientCheck", f, "InterfaceOptionsCheckButtonTemplate")
gradient:SetChecked(db.useGradient)
gradient:SetScript("OnClick", function(self)
db.useGradient = not db.useGradient
PowerUp:ToggleOverlay()
end)
gradient:SetPoint("TOPLEFT", overlay, "BOTTOMLEFT", 0, -2)
_G[gradient:GetName() .. "Text"]:SetText("Color overlay with gradient")
gradient.tooltipText = "Gradient"
gradient.tooltipRequirement = "Toggle to color the overlay with a gradient ranging from green to red."
end
 
self:SetScript("OnShow", nil)
end)
 
InterfaceOptions_AddCategory(f)
\ No newline at end of file +ns.defaults = defaults \ No newline at end of file
trunk/PowerUp/PowerUp.lua
9,94 → 9,78
Thanks to lorelye over @ wowace forums for name suggestion
]]
 
local addon, PowerUp = ...
local ADDON, ns = ...
local db
 
PowerUp = CreateFrame("Frame", "PowerUpFrame", UIParent)
PowerUp.class = select(2, UnitClass("player"))
 
PowerUp:SetScript("OnEvent", function(self, event, ...)
self[event](self, ...)
end)
 
PowerUp:RegisterEvent("ADDON_LOADED")
 
function PowerUp:ADDON_LOADED(name)
if name ~= addon then return end
if name ~= ADDON then return end
 
if (self.class == "PALADIN" or self.class == "WARLOCK") then
PowerUpDB = PowerUpDB or self.defaults
if (PowerUp.class == "PALADIN" or PowerUp.class == "WARLOCK") then
PowerUpDB = PowerUpDB or ns.defaults
 
-- in case there's a new option (trial)
for k,v in pairs(self.defaults) do
for k,v in pairs(ns.defaults) do
if type(PowerUpDB[k]) == "nil" then
PowerUpDB[k] = v
end
end
db = PowerUpDB
 
self.frame:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", insets = {top = -1, left = -1, bottom = -1, right = -1},})
self.frame:SetBackdropColor(0, 0, 0, .5)
self.frame:SetPoint(db.point, UIParent, db.x, db.y)
self.bars = {}
 
self:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", insets = {top = -1, left = -1, bottom = -1, right = -1},})
self:SetBackdropColor(0, 0, 0, .5)
self:SetSize(db.width, db.height)
self:SetPoint(db.point, UIParent, db.x, db.y)
 
for i=1, db.max do
local t = self:CreateTexture(nil, "OVERLAY")
if i == 1 then
t:SetPoint("LEFT", self, "LEFT")
else
t:SetPoint("TOPLEFT", self.bars[i - 1], "TOPRIGHT", 1, 0)
end
t:SetTexture(db.texture)
t:SetVertexColor(0, 1, 0)
t:SetWidth((db.width-2)/db.max)
t:SetHeight(db.height)
 
self.frame:SetMovable(true)
self.frame:SetScript("OnMouseDown", function()
t.wasactive = false
self.bars[i] = t
end
 
self:SetMovable(true)
self:SetScript("OnMouseDown", function()
if(IsShiftKeyDown()) then
self.frame:ClearAllPoints()
self.frame:StartMoving()
self:ClearAllPoints()
self:StartMoving()
end
end)
 
self.frame:SetScript("OnMouseUp", function()
self.frame:StopMovingOrSizing()
db.point, _, _, db.x, db.y = self.frame:GetPoint()
self:SetScript("OnMouseUp", function()
self:StopMovingOrSizing()
db.point, _, _, db.x, db.y = self:GetPoint()
end)
 
self:HideBlizzard()
-- Hide Blizzard if applicable
if (PaladinPowerBar:IsVisible() or ShardBarFrame:IsVisible()) and db.hideblizz then
PaladinPowerBar:Hide()
PaladinPowerBar:UnregisterAllEvents()
ShardBarFrame:Hide()
ShardBarFrame:UnregisterAllEvents()
end
 
self:Init()
end
 
self:UnregisterEvent("ADDON_LOADED")
end
 
function PowerUp:HideBlizzard()
if db.hideBlizz then
PaladinPowerBar:Hide()
PaladinPowerBar:UnregisterAllEvents()
ShardBarFrame:Hide()
ShardBarFrame:UnregisterAllEvents()
else
PaladinPowerBar_OnLoad(PaladinPowerBar)
ShardBar_OnLoad(ShardBarFrame)
end
end
 
-- Create frames
function PowerUp:Workshop()
self.bars = {}
 
for i=1, db.max do
local t = self.frame:CreateTexture(nil, "OVERLAY")
if i == 1 then
t:SetPoint("LEFT", self.frame, "LEFT")
else
t:SetPoint("TOPLEFT", self.bars[i - 1], "TOPRIGHT", 1, 0)
end
 
self.bars[i] = t
end
end
 
-- Style bars
function PowerUp:Paintshop()
self.frame:SetSize(db.width, db.height)
 
for i=1, #self.bars do
self.bars[i]:SetTexture(db.texture)
self.bars[i]:SetVertexColor(db.colors[self.class].r, db.colors[self.class].g, db.colors[self.class].b)
self.bars[i]:SetWidth((db.width-2)/db.max)
self.bars[i]:SetHeight(db.height)
end
end
 
PowerUp.frame = CreateFrame("Frame", nil, UIParent)
PowerUp.frame:SetScript("OnEvent", function(self, event, ...) return PowerUp[event] and PowerUp[event](PowerUp, ...) end)
 
function PowerUp:RegisterEvent(event) return self.frame:RegisterEvent(event) end
function PowerUp:UnregisterEvent(event) return self.frame:UnregisterEvent(event) end
 
PowerUp:RegisterEvent("ADDON_LOADED")
\ No newline at end of file +end \ No newline at end of file