Modules/Nameplates: Fix class power module
This commit is contained in:
@@ -0,0 +1,313 @@
|
||||
--[[
|
||||
# Element: ClassPower
|
||||
|
||||
Handles the visibility and updating of the player's class resources (like Chi Orbs or Holy Power) and combo points.
|
||||
|
||||
## Widget
|
||||
|
||||
ClassPower - An `table` consisting of as many StatusBars as the theoretical maximum return of [UnitPowerMax](http://wowprogramming.com/docs/api/UnitPowerMax.html).
|
||||
|
||||
## Sub-Widgets
|
||||
|
||||
.bg - A `Texture` used as a background. It will inherit the color of the main StatusBar.
|
||||
|
||||
## Sub-Widget Options
|
||||
|
||||
.multiplier - Used to tint the background based on the widget's R, G and B values. Defaults to 1 (number)[0-1]
|
||||
|
||||
## Notes
|
||||
|
||||
A default texture will be applied if the sub-widgets are StatusBars and don't have a texture set.
|
||||
If the sub-widgets are StatusBars, their minimum and maximum values will be set to 0 and 1 respectively.
|
||||
|
||||
Supported class powers:
|
||||
- All - Combo Points
|
||||
- Mage - Arcane Charges
|
||||
- Monk - Chi Orbs
|
||||
- Paladin - Holy Power
|
||||
- Warlock - Soul Shards
|
||||
|
||||
## Examples
|
||||
|
||||
local ClassPower = {}
|
||||
for index = 1, 10 do
|
||||
local Bar = CreateFrame('StatusBar', nil, self)
|
||||
|
||||
-- Position and size.
|
||||
Bar:SetSize(16, 16)
|
||||
Bar:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', (index - 1) * Bar:GetWidth(), 0)
|
||||
|
||||
ClassPower[index] = Bar
|
||||
end
|
||||
|
||||
-- Register with oUF
|
||||
self.ClassPower = ClassPower
|
||||
--]]
|
||||
|
||||
local _, ns = ...
|
||||
local oUF = ns.oUF
|
||||
|
||||
local _, PlayerClass = UnitClass('player')
|
||||
|
||||
-- sourced from FrameXML/Constants.lua
|
||||
local SPELL_POWER_ENERGY = 3
|
||||
local COMBO_POINTS_ID = 4
|
||||
|
||||
-- Holds the class specific stuff.
|
||||
local ClassPowerID, ClassPowerType
|
||||
local ClassPowerEnable, ClassPowerDisable
|
||||
local RequireSpec, RequirePower, RequireSpell
|
||||
|
||||
local function UpdateColor(element, powerType)
|
||||
local color = element.__owner.colors.power[powerType]
|
||||
local r, g, b = color.r, color.g, color.b
|
||||
|
||||
for i = 1, #element do
|
||||
local bar = element[i]
|
||||
bar:SetStatusBarColor(r, g, b)
|
||||
|
||||
local bg = bar.bg
|
||||
if(bg) then
|
||||
local mu = bg.multiplier or 1
|
||||
bg:SetVertexColor(r * mu, g * mu, b * mu)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Callback: ClassPower:PostUpdateColor(r, g, b)
|
||||
Called after the element color has been updated.
|
||||
|
||||
* self - the ClassPower element
|
||||
* r - the red component of the used color (number)[0-1]
|
||||
* g - the green component of the used color (number)[0-1]
|
||||
* b - the blue component of the used color (number)[0-1]
|
||||
--]]
|
||||
if(element.PostUpdateColor) then
|
||||
element:PostUpdateColor(r, g, b)
|
||||
end
|
||||
end
|
||||
|
||||
local function Update(self, event, unit, powerType)
|
||||
if(not (unit and (UnitIsUnit(unit, 'player') and (not powerType or powerType == ClassPowerType)
|
||||
or unit == 'vehicle' and powerType == 'COMBO_POINTS'))) then
|
||||
return
|
||||
end
|
||||
|
||||
local element = self.ClassPower
|
||||
|
||||
--[[ Callback: ClassPower:PreUpdate(event)
|
||||
Called before the element has been updated.
|
||||
|
||||
* self - the ClassPower element
|
||||
]]
|
||||
if(element.PreUpdate) then
|
||||
element:PreUpdate()
|
||||
end
|
||||
|
||||
local cur, max, oldMax
|
||||
if(event ~= 'ClassPowerDisable') then
|
||||
local powerID = unit == 'vehicle' and COMBO_POINTS_ID or ClassPowerID
|
||||
|
||||
powerType = powerType or ClassPowerType
|
||||
|
||||
max = powerType == 'COMBO_POINTS' and GetComboPoints(unit, 'target') or UnitPower(unit, powerID)
|
||||
cur = powerType == 'COMBO_POINTS' and GetComboPoints(unit, 'target') or UnitPower(unit, powerID)
|
||||
|
||||
local numActive = cur + 0.9
|
||||
for i = 1, max do
|
||||
if(i > numActive) then
|
||||
element[i]:Hide()
|
||||
element[i]:SetValue(0)
|
||||
else
|
||||
element[i]:Show()
|
||||
element[i]:SetValue(cur - i + 1)
|
||||
end
|
||||
end
|
||||
|
||||
oldMax = element.__max
|
||||
if(max ~= oldMax) then
|
||||
if(max < oldMax) then
|
||||
for i = max + 1, oldMax do
|
||||
element[i]:Hide()
|
||||
element[i]:SetValue(0)
|
||||
end
|
||||
end
|
||||
|
||||
element.__max = max
|
||||
end
|
||||
end
|
||||
--[[ Callback: ClassPower:PostUpdate(cur, max, hasMaxChanged, powerType)
|
||||
Called after the element has been updated.
|
||||
|
||||
* self - the ClassPower element
|
||||
* cur - the current amount of power (number)
|
||||
* max - the maximum amount of power (number)
|
||||
* hasMaxChanged - indicates whether the maximum amount has changed since the last update (boolean)
|
||||
* powerType - the active power type (string)
|
||||
--]]
|
||||
if(element.PostUpdate) then
|
||||
return element:PostUpdate(cur, max, oldMax ~= max, powerType)
|
||||
end
|
||||
end
|
||||
|
||||
local function Path(self, ...)
|
||||
--[[ Override: ClassPower.Override(self, event, unit, ...)
|
||||
Used to completely override the internal update function.
|
||||
|
||||
* self - the parent object
|
||||
* event - the event triggering the update (string)
|
||||
* unit - the unit accompanying the event (string)
|
||||
* ... - the arguments accompanying the event
|
||||
--]]
|
||||
return (self.ClassPower.Override or Update) (self, ...)
|
||||
end
|
||||
|
||||
local function Visibility(self, event, unit)
|
||||
local element = self.ClassPower
|
||||
local shouldEnable
|
||||
|
||||
if UnitHasVehicleUI('player') then
|
||||
shouldEnable = true
|
||||
unit = 'vehicle'
|
||||
elseif(not RequirePower or RequirePower == UnitPowerType('player')) then
|
||||
if(not RequireSpell or IsSpellKnown(RequireSpell)) then
|
||||
self:UnregisterEvent('SPELLS_CHANGED', Visibility)
|
||||
shouldEnable = true
|
||||
unit = 'player'
|
||||
else
|
||||
self:RegisterEvent('SPELLS_CHANGED', Visibility, true)
|
||||
end
|
||||
end
|
||||
|
||||
local isEnabled = element.__isEnabled
|
||||
local powerType = unit == 'vehicle' and 'COMBO_POINTS' or ClassPowerType
|
||||
|
||||
if(shouldEnable) then
|
||||
--[[ Override: ClassPower:UpdateColor(powerType)
|
||||
Used to completely override the internal function for updating the widgets' colors.
|
||||
|
||||
* self - the ClassPower element
|
||||
* powerType - the active power type (string)
|
||||
--]]
|
||||
(element.UpdateColor or UpdateColor) (element, powerType)
|
||||
end
|
||||
|
||||
if(shouldEnable and not isEnabled) then
|
||||
ClassPowerEnable(self)
|
||||
|
||||
--[[ Callback: ClassPower:PostVisibility(isVisible)
|
||||
Called after the element's visibility has been changed.
|
||||
|
||||
* self - the ClassPower element
|
||||
* isVisible - the current visibility state of the element (boolean)
|
||||
--]]
|
||||
if(element.PostVisibility) then
|
||||
element:PostVisibility(true)
|
||||
end
|
||||
elseif(not shouldEnable and (isEnabled or isEnabled == nil)) then
|
||||
ClassPowerDisable(self)
|
||||
|
||||
if(element.PostVisibility) then
|
||||
element:PostVisibility(false)
|
||||
end
|
||||
elseif(shouldEnable and isEnabled) then
|
||||
Path(self, event, unit, powerType)
|
||||
end
|
||||
end
|
||||
|
||||
local function VisibilityPath(self, ...)
|
||||
--[[ Override: ClassPower.OverrideVisibility(self, event, unit)
|
||||
Used to completely override the internal visibility function.
|
||||
|
||||
* self - the parent object
|
||||
* event - the event triggering the update (string)
|
||||
* unit - the unit accompanying the event (string)
|
||||
--]]
|
||||
return (self.ClassPower.OverrideVisibility or Visibility) (self, ...)
|
||||
end
|
||||
|
||||
local function ForceUpdate(element)
|
||||
return VisibilityPath(element.__owner, 'ForceUpdate', element.__owner.unit)
|
||||
end
|
||||
|
||||
do
|
||||
function ClassPowerEnable(self)
|
||||
self:RegisterEvent('UNIT_MAXPOWER', Path)
|
||||
self:RegisterEvent('UNIT_POWER_UPDATE', Path)
|
||||
self:RegisterEvent('PLAYER_TARGET_CHANGED', VisibilityPath, true)
|
||||
|
||||
self.ClassPower.__isEnabled = true
|
||||
|
||||
if UnitHasVehicleUI('player') then
|
||||
Path(self, 'ClassPowerEnable', 'vehicle', 'COMBO_POINTS')
|
||||
end
|
||||
end
|
||||
|
||||
function ClassPowerDisable(self)
|
||||
self:UnregisterEvent('UNIT_POWER_UPDATE', Path)
|
||||
self:UnregisterEvent('UNIT_MAXPOWER', Path)
|
||||
self:UnregisterEvent('PLAYER_TARGET_CHANGED', VisibilityPath)
|
||||
|
||||
local element = self.ClassPower
|
||||
for i = 1, #element do
|
||||
element[i]:Hide()
|
||||
end
|
||||
|
||||
element.__isEnabled = false
|
||||
Path(self, 'ClassPowerDisable', 'player', ClassPowerType)
|
||||
end
|
||||
|
||||
if(PlayerClass == 'ROGUE' or PlayerClass == 'DRUID' or PlayerClass == 'HERO') then
|
||||
ClassPowerType = 'COMBO_POINTS'
|
||||
|
||||
if(PlayerClass == 'DRUID') then
|
||||
RequirePower = SPELL_POWER_ENERGY
|
||||
RequireSpell = 768 -- cat form
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Enable(self, unit)
|
||||
local element = self.ClassPower
|
||||
if(element and UnitIsUnit(unit, 'player')) then
|
||||
element.__owner = self
|
||||
element.__max = #element
|
||||
element.ForceUpdate = ForceUpdate
|
||||
|
||||
if (RequireSpell and not IsSpellKnown(RequireSpell)) then
|
||||
self:RegisterEvent('SPELLS_CHANGED', VisibilityPath, true)
|
||||
end
|
||||
|
||||
if(RequirePower) then
|
||||
self:RegisterEvent('UNIT_DISPLAYPOWER', VisibilityPath)
|
||||
end
|
||||
self:RegisterEvent('UNIT_COMBO_POINTS', VisibilityPath)
|
||||
|
||||
|
||||
element.ClassPowerEnable = ClassPowerEnable
|
||||
element.ClassPowerDisable = ClassPowerDisable
|
||||
|
||||
for i = 1, #element do
|
||||
local bar = element[i]
|
||||
if bar:IsObjectType('StatusBar') then
|
||||
if not bar:GetStatusBarTexture() then
|
||||
bar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
|
||||
end
|
||||
|
||||
bar:SetMinMaxValues(0, 1)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function Disable(self)
|
||||
if(self.ClassPower) then
|
||||
ClassPowerDisable(self)
|
||||
self:UnregisterEvent('UNIT_DISPLAYPOWER', VisibilityPath)
|
||||
self:UnregisterEvent('SPELLS_CHANGED', Visibility)
|
||||
self:RegisterEvent('UNIT_COMBO_POINTS', VisibilityPath)
|
||||
end
|
||||
end
|
||||
|
||||
oUF:AddElement('ClassPower', VisibilityPath, Enable, Disable)
|
||||
@@ -33,6 +33,7 @@
|
||||
<Script file="elements\combopoints.lua"/>
|
||||
<Script file="elements\raidroleindicator.lua"/>
|
||||
<Script file="elements\happinessindicator.lua"/>
|
||||
<Script file="elements\classpower.lua"/>
|
||||
|
||||
<!-- Clique support -->
|
||||
<Button name="oUF_ClickCastUnitTemplate" virtual="true" inherits="SecureUnitButtonTemplate, SecureHandlerEnterLeaveTemplate">
|
||||
|
||||
Reference in New Issue
Block a user