02-21-12, 08:37 AM | #1 |
Creating a Shadow Orb element for oUF
Hey everyone! Requesting some more of your help I don't know if I'm supposed to post this here or in the actual oUF part of the forum, but I'm gonna give this place a try. It's LUA, after all
What I want to do is rather simple. I want a tracker that tracks a players shadow orbs, shown as 1-3 bars. I have an example here, this is soul shards on my warlock; I'm using the soulshard-element for oUF to create this, using this code in my layout; Code:
if LeUI.Class == 'WARLOCK' then self.SoulShards = CreateFrame('Frame', nil, self) for i = 1, 3 do self.SoulShards[i] = CreateFrame('StatusBar', self:GetName()..'_SoulShards'..i, self) self.SoulShards[i]:SetSize(60, 12) self.SoulShards[i]:SetStatusBarTexture(LeUI.media.texture) self.SoulShards[i]:SetStatusBarColor(LeUI.Classcolor.r, LeUI.Classcolor.g, LeUI.Classcolor.b) if(i == 1) then self.SoulShards[i]:SetPoint('CENTER', UIParent, 'BOTTOM', -70, 96) else self.SoulShards[i]:SetPoint('TOPLEFT', self.SoulShards[i-1], 'TOPRIGHT', 10, 0) end CreateBorderLight(self.SoulShards[i], LeUI.media.bordersize, LeUI.bordercolor, LeUI.bordercolor, LeUI.bordercolor, 4) self.SoulShards[i]:SetBackdrop(backdrop) self.SoulShards[i]:SetBackdropColor(unpack(LeUI.media.backdropcolor)) end end I thought it wouldn't be harder than to copy the Soulshard element lua-file and basically edit it for Shadow Orbs, but I can't seem to get it to work. Here's the code I ended up with _after_ editing soulshards.lua in oUF elements; Code:
if(select(2, UnitClass('player')) ~= 'PRIEST') then return end local parent, ns = ... local oUF = ns.oUF local SPELL_POWER_SHADOW_ORBS = SPELL_POWER_SHADOW_ORBS local MAX_SHADOW_ORBS = MAX_SHADOW_ORBS local Update = function(self, event, unit, powerType) if(self.unit ~= unit or (powerType and powerType ~= 'SHADOW_ORBS')) then return end local so = self.ShadowOrbs if(so.PreUpdate) then so:PreUpdate(unit) end local num = UnitPower('player', SPELL_POWER_SHADOW_ORBS) for i = 1, MAX_SHADOW_ORBS do if(i <= num) then so[i]:SetAlpha(1) else so[i]:SetAlpha(0) end end if(so.PostUpdate) then return so:PostUpdate(unit) end end local Path = function(self, ...) return (self.ShadowOrbs.Override or Update) (self, ...) end local ForceUpdate = function(element) return Path(element.__owner, 'ForceUpdate', element.__owner.unit, 'SHADOW_ORBS') end local function Enable(self) local so = self.ShadowOrbs if(so) then so.__owner = self so.ForceUpdate = ForceUpdate self:RegisterEvent('UNIT_POWER', Path) return true end end local function Disable(self) local so = self.ShadowOrbs if(so) then self:UnregisterEvent('UNIT_POWER', Path) end end oUF:AddElement('ShadowOrbs', Path, Enable, Disable) Code:
...\LeUI\Modules\Unitframes\oUF\elements\shadoworbs.lua:16: 'for' limit must be a number I'll have to point out that I'm no more than a rookie to LUA, and this is taking water over my head. But I really hope I can get it working with some help from you guys, like many times before |
|
02-21-12, 10:04 AM | #2 |
When Blizzard implemented the Soul Shards / Holy Power / Eclipse as a new energy type they provided APIs and events to access the relevant information.
Unfortunately Shadow Orbs are buffs rather than a new energy type, so you cannot really base your oUF element on the existing Soul Shards element. Instead you would need to handle UNIT_AURA events and filter for the events associated with your own shadow orb buffs. I use some custom elements within my own layout that would be closer to what you are trying to do with shadow orbs: https://github.com/Evilpaul/oUF_EP/b...arthShield.lua |
|
02-21-12, 11:56 AM | #3 |
Oh, sweet, that explains some things!
Thanks for that code, I'll see what I can do with it and report back later |
|
02-21-12, 11:02 PM | #4 |
I already implemented this in my oUF layout, but haven't published it yet. In my version, I display each Shadow Orb as an orb texture (kind of like combo point dots, but bigger), but you could easily make them look like bars instead. I use the same framework for combo points, Maelstrom Weapon stacks, holy power, and soul shards. It may be a bit more complex than what you need, but feel free to use some/all of it:
Code:
ns.CreateOrbs = function(parent, num, size) local orbs = {} for i = 1, num do local orb = CreateFrame("Frame", nil, parent) orb:SetSize(size or 20, size or 20) orb.bg = orb:CreateTexture(nil, "BACKGROUND") orb.bg:SetAllPoints(true) orb.bg:SetTexture("Interface\\AddOns\\oUF_Phanx\\media\\OrbBG") orb.fg = orb:CreateTexture(nil, "ARTWORK") orb.fg:SetAllPoints(true) orb.fg:SetTexture("Interface\\AddOns\\oUF_Phanx\\media\\OrbFG") orbs[i] = orb end return orbs end Code:
if unit == "player" and (playerClass == "PALADIN" or playerClass == "PRIEST" or playerClass == "SHAMAN" or playerClass == "WARLOCK") then local color = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[playerClass] local element, max, buff, power ---------------- -- Holy power -- ---------------- if playerClass == "PALADIN" then element, max = "HolyPower", MAX_HOLY_POWER power = SPELL_POWER_HOLY_POWER ---------------- -- Shadow Orb -- ---------------- elseif playerClass == "PRIEST" then element, max = "PowerStack", 3 buff = GetSpellInfo(77487) ---------------------- -- Maelstrom Weapon -- ---------------------- elseif playerClass == "SHAMAN" then element, max = "PowerStack", 5 buff = GetSpellInfo(53817) ----------------- -- Soul shards -- ----------------- elseif playerClass == "WARLOCK" then element, max = "SoulShards", SHARD_BAR_NUM_SHARDS power = SPELL_POWER_SOUL_SHARDS end local SetAlpha if power then SetAlpha = function(self, alpha) if alpha == 1 then self.bg:SetVertexColor(0.25, 0.25, 0.25) self.bg:SetAlpha(1) self.fg:Show() else local num = UnitPower("player", power) self.bg:SetVertexColor(0.4, 0.4, 0.4) self.bg:SetAlpha(num > 0 and 0.5 or 0) self.fg:Hide() end end else SetAlpha = function(orb, alpha) if alpha == 1 then orb.bg:SetVertexColor(0.25, 0.25, 0.25) orb.bg:SetAlpha(1) orb.fg:Show() else orb.bg:SetVertexColor(0.4, 0.4, 0.4) orb.bg:SetAlpha(0.5) orb.fg:Hide() end end end local t = ns.CreateOrbs(self.overlay, max, 20) for i = 1, max do local orb = t[i] if i == 1 then orb:SetPoint("BOTTOMRIGHT", self, "TOPRIGHT", 2, -5) else orb:SetPoint("BOTTOMRIGHT", t[i - 1], "BOTTOMLEFT", 2, 0) end orb.bg:SetVertexColor(0.25, 0.25, 0.25) orb.fg:SetVertexColor(color.r, color.g, color.b) orb.SetAlpha = SetAlpha end t.buff = buff self[element] = t end If you're using bars this probably isn't necessary since presumably the element will be full-width, with each bar inside it being 1/3 of the width, but it's there if you want it. The PowerStack element is a custom element I wrote for my layout to support treating stackable buffs like Shadow Orb and Maelstrom Weapon in basically the same way the core combo point, holy power, and soul shard elements work. Code:
--[[ oUF_PowerStack by Phanx <[email protected]> Adds a graphical counter element for Maelstrom Weapon or Shadow Orb. --]] local _, ns = ... local oUF = ns.oUF or oUF if not oUF then return end local UnitBuff = UnitBuff local prev local Update = function(self, event, unit) if unit ~= "player" then return end local element = self.PowerStack local max = #element local _, _, _, count = UnitBuff("player", element.buff) if not count then count = 0 end -- print("PowerStack: Update", event, unit, element.buff, count, max) if count == prev then return end if count == 0 then for i = 1, max do element[i]:Hide() end else for i = 1, max do local obj = element[i] obj:Show() if i <= count then obj:SetAlpha(1) else obj:SetAlpha(0.25) end end end prev = count end local Path = function(self, ...) return (self.PowerStack.Override or Update)(self, ...) end local ForceUpdate = function(element) return Path(element.__owner, "ForceUpdate", element.__owner.unit) end local Enable = function(self) local element = self.PowerStack if not element then return end element.__owner = self element.ForceUpdate = ForceUpdate self:RegisterEvent("UNIT_AURA", Path) for i = 1, #element do local obj = element[i] if obj:IsObjectType("Texture") and not obj:GetTexture() then obj:SetTexture([[Interface\ComboFrame\ComboPoint]]) obj:SetTexCoord(0, 0.375, 0, 1) end end return true end local Disable = function(self) local element = self.PowerStack if not element then return end self:UnregisterEvent("UNIT_AURA", Path) end oUF:AddElement("PowerStack", Path, Enable, Disable) |
|
02-22-12, 03:22 AM | #5 |
Phanx, that's awesome! I'll have a look at this and I'm pretty sure I'll use most, if not all, of it if I manage to get it working! Thanks a lot Super nice
|
|
02-22-12, 05:51 AM | #6 |
I'm sorry Phanx but I'm not really sure in what LUA-files I should put these different codes. I guess some of it goes into oUF/elements/powerstack.lua and some of it into my oUF_LeUI layout, but having a hard time figuring out which goes where. Mind giving me a hint?
|
|
02-22-12, 06:33 AM | #7 | |
His last code snippet is the oUF plugin/module for maelstrom/shadow orbs. You can either embed it in your layout (as an embedded module) or use it to create an oUF module from it. (Check other oUF modules)
The first snippets are the createOrbs functions and the actual setup. Both have to be added to whereever you spawn your player frame.
__________________
| Simple is beautiful. | WoWI AddOns | GitHub | Zork (WoW)
|
||
02-22-12, 08:22 AM | #8 |
I still can't seem to get it working, though I'm not getting any LUA errors.
I created a new LUA file and pasted the last snipped in it, and placed it inside my oUF_Plugins folder. I put the first snippet in my layou, oUF_LeUI and changed the texture paths to my own, using a statusbar texture for testing only. I pasted the second snippet in my oUF_LeUI too. Nothing happens ingame :/ |
|
02-22-12, 04:44 PM | #9 |
Third snippet goes in its own file. Doesn't matter what you call it, as long as it gets loaded before your layout files.
Second snippet goes inside the function you pass to oUF:Spawn. Third snippet goes in your layout file, in the main chunk (outside of any functions). If you do not define your addon's private namespace table as "ns" then you will need to change the function definitions in the first snippet, and the calls to those functions in the second snippet. Also, you probably need to define the "playerClass" variable for the second snippet. Edit: If it doesn't work there's probably an error. Install BugSack if you don't already have it, and then check it for any errors. Edit #2: I also don't have a priest, so I've never actually tested the Shadow Orb display, but it's basically the same codepath as the Maelstrom Weapon display, which definitely works. Edit #3: Also, in my code, the orbs are parented to "self.overlay" which is an invisible frame I create over the top of the unit frame so I can attach text/icons to it without having to worry about frame layering even if I hide some elements. You probably need to change that also (second snippet, call to ns.CreateOrbs). Last edited by Phanx : 02-22-12 at 06:12 PM. |
|
WoWInterface » Developer Discussions » Lua/XML Help » Creating a Shadow Orb element for oUF |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|