Thread Tools Display Modes
09-07-12, 10:39 PM   #1
Senit24
A Fallenroot Satyr
AddOn Compiler - Click to view compilations
Join Date: Jul 2012
Posts: 28
Combo Points (and related class powers)

For days, I've been working on creating class class power (specifically combo points) bars. I'm working off some code from another layout. I've tried modifying it numerous ways, but I just can't get any result. I'm not getting any errors, it's just displaying nothing. Can anyone help me find a good sample, or solution to my problem?

Current code: --The function lib.genCPoints being called by my TargetStyle function, obviously.
Code:
do
	ComboDisplay = function(self, event, unit)
		if(unit == 'pet') then return end
		
		local cpoints = self.CPoints
		local cp
		if (UnitHasVehicleUI("player") or UnitHasVehicleUI("vehicle")) then
			cp = GetComboPoints('vehicle', 'target')
		else
			cp = GetComboPoints('player', 'target')
		end

		for i=1, MAX_COMBO_POINTS do
			if(i <= cp) then
				cpoints[i]:SetAlpha(1)
			else
				cpoints[i]:SetAlpha(0.15)
			end
		end
		
		if cpoints[1]:GetAlpha() == 1 then
			for i=1, MAX_COMBO_POINTS do
				cpoints[i]:Show()
			end
			
		else
			for i=1, MAX_COMBO_POINTS do
				cpoints[i]:Hide()
			end
			
		end
	end
end

lib.genCPoints = function(self)
	local bars = CreateFrame("Frame", nil, self)
	bars:SetPoint("BOTTOMLEFT", oUF_Player, "TOPLEFT", 0, 7)
	bars:SetWidth(210)
	bars:SetHeight(2)
	bars:SetBackdrop(backdrop)
	bars:SetBackdropBorderColor(0,0,0,0)
	bars:SetBackdropColor(0,0,0,0)
		
	for i = 1, 5 do		
	
		bars[i] = CreateFrame("StatusBar", self:GetName().."_Combo"..i, bars)
		bars[i]:SetHeight(20)					
		bars[i]:SetStatusBarTexture(config.statusbar_texture)
		bars[i]:GetStatusBarTexture():SetHorizTile(false)
							
		if i == 1 then
			bars[i]:SetPoint("LEFT", bars)
		else
			bars[i]:SetPoint("LEFT", bars[i-1], "RIGHT", 1, 0)
		end
		bars[i]:SetAlpha(1)
		bars[i]:SetWidth((210 - 4)/5)
	end
		
	bars[1]:SetStatusBarColor(0.69, 0.31, 0.31)		
	bars[2]:SetStatusBarColor(0.69, 0.31, 0.31)
	bars[3]:SetStatusBarColor(0.65, 0.63, 0.35)
	bars[4]:SetStatusBarColor(0.65, 0.63, 0.35)
	bars[5]:SetStatusBarColor(0.33, 0.59, 0.33)
		
	self.CPoints = bars
	self.CPoints.Override = ComboDisplay
		
	bars.FrameBackdrop = CreateFrame("Frame", nil, bars[1])
	bars:SetBackdrop(backdrop)
	bars.FrameBackdrop:SetBackdropBorderColor(0,0,0,1)
	bars.FrameBackdrop:SetPoint("TOPLEFT", bars, "TOPLEFT", -1, 1)
	bars.FrameBackdrop:SetPoint("BOTTOMRIGHT", bars, "BOTTOMRIGHT", 1, -1)
	bars.FrameBackdrop:SetFrameLevel(bars:GetFrameLevel() - 1)
end
  Reply With Quote
09-08-12, 02:17 AM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Erm, I have no idea why you're defining that ComboDisplay function and using it as an element Override, when it's functionally identical to oUF's standard combo point update function, but contains a lot of unnecessary redundancy. You set the alpha to 15% and then hide the frame, instead of just hiding it, for example. Try getting rid of the Override and see if it works then.

I also don't understand what you're trying to do with the bars.FrameBackdrop section at the end of the block you posted. It's just an extra frame, attached to the bars frame, with no visible anything, since you call SetBackdrop on bars instead of bars.FrameBackdrop, and anyway you're setting the same backdrop that you already set on bars, so even if you did set it on the bars.FrameBackdrop frame, you'd only see 1 pixel of it around the edges since the frames are stacked on top of each other. I'd suggest just getting rid of the whole thing. If you want a 1px border on the bars frame, just change its backdrop to include a 1px border, eg:

Lua Code:
  1. local backdrop = {
  2.     bgFile = "Interface\\BUTTONS\\WHITE8X8", tile = true, tileSize = 8,
  3.     edgeFIle = "Interface\\BUTTONS\\WHITE8X8", edgeSize = 1,
  4.     insets = { left = 1, right = 1, top = 1, bottom = 1 },
  5. }

Finally, your genCPoints function parents bars to self, but anchors it to oUF_Player. If multiple frames call genCpoints, you'll end up with multiple objects piled on top of each other. I'd also suggest combo points be attached to the target frame, rather than the player frame. Not only does that give you more room on the player frame for class powers, but combo points also logically belong on the target, at least for druids, who can have different numbers of combo points on different targets at the same time.

Try this:
Lua Code:
  1. lib.genCPoints = function(self)
  2.     local bars = CreateFrame("Frame", nil, self)
  3.     bars:SetPoint("BOTTOMLEFT", self, "TOPLEFT", 0, 7)
  4.         -- ^^^ Attach to self, and then just call this function from the
  5.         --     frame you actually want it attached to, probably target.
  6.     bars:SetWidth(210)
  7.     bars:SetHeight(2)
  8.     bars:SetBackdrop(backdrop)
  9.     bars:SetBackdropBorderColor(0,0,0,0)
  10.     bars:SetBackdropColor(0,0,0,0)
  11.  
  12.     for i = 1, 5 do
  13.         bars[i] = CreateFrame("StatusBar", nil, bars)
  14.             -- ^^^ No reason to give this a global name.
  15.         bars[i]:SetWidth(41.2) -- (210 - 4) / 5
  16.             -- ^^^ No need to do the math on the fly since it isn't dynamic.
  17.         bars[i]:SetHeight(20)
  18.         bars[i]:SetStatusBarTexture(config.statusbar_texture)
  19.         bars[i]:GetStatusBarTexture():SetHorizTile(false)
  20.         if i == 1 then
  21.             bars[i]:SetPoint("LEFT", bars)
  22.         else
  23.             bars[i]:SetPoint("LEFT", bars[i-1], "RIGHT", 1, 0)
  24.         end
  25.     end
  26.  
  27.     bars[1]:SetStatusBarColor(0.69, 0.31, 0.31)
  28.     bars[2]:SetStatusBarColor(0.69, 0.31, 0.31)
  29.     bars[3]:SetStatusBarColor(0.65, 0.63, 0.35)
  30.     bars[4]:SetStatusBarColor(0.65, 0.63, 0.35)
  31.     bars[5]:SetStatusBarColor(0.33, 0.59, 0.33)
  32.  
  33.     self.CPoints = bars
  34. end
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 09-08-12 at 02:19 AM.
  Reply With Quote
09-08-12, 10:03 AM   #3
Senit24
A Fallenroot Satyr
AddOn Compiler - Click to view compilations
Join Date: Jul 2012
Posts: 28
It works great! The original was a rough copy of "oUF_Qulight", hence the redundancy and misfit calls and functions.

As always, thank you Phanx, for you are the reason my UI works. I'm sure you'll be all over the credits :)

Last edited by Senit24 : 09-08-12 at 11:59 PM.
  Reply With Quote
09-09-12, 01:34 PM   #4
Senit24
A Fallenroot Satyr
AddOn Compiler - Click to view compilations
Join Date: Jul 2012
Posts: 28
After hours of coding, I am more confused than I was to begin with. (Trying to create Warlock Power Bars).
What I wrote for soul shards seems to work:
Lua Code:
  1. UpdateShards = function(self, event, unit, powerType)
  2.     if(self.unit ~= unit or (powerType and powerType ~= 'SOUL_SHARDS')) and (GetSpecialization() ~= SPEC_WARLOCK_AFFLICTION) then return end
  3.         local maxshards = 3
  4.             for i = 1, GetNumGlyphSockets() do
  5.             local glyphID = select(4, GetGlyphSocketInfo(i))
  6.                 if glyphID == 63302 then maxshards = 4 end 
  7.        
  8.             local num = UnitPower(unit, SPELL_POWER_SOUL_SHARDS)
  9.             for i = 1, maxshards do
  10.                 if(i <= num) then
  11.                     self.SoulShards[i]:SetAlpha(1)
  12.                 else
  13.                     self.SoulShards[i]:SetAlpha(0)
  14.                 end    
  15.             end
  16.     end
  17. end

I tried doing the same thing for burning embers, but with no success. Does this function only work because self.SoulShards is predefined in oUF elements? Does this mean I need to write a new element for Embers/Fury/ShadowOrbs/Monks etc?

Last edited by Senit24 : 09-09-12 at 07:59 PM.
  Reply With Quote
09-09-12, 09:45 PM   #5
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You must be working with an old version of oUF... get the current one from Haste's GitHub repo:
https://github.com/haste/oUF

There aren't separate elements for Soul Shards, Holy Power, etc. anymore. Instead, all of the class powers that are displayed like combo points are combined into the ClassIcons element. It covers Harmony Orbs (chi), Holy Power, Shadow Orbs, and Soul Shards. If you look at the top of the classicons.lua element file, you'll see an example. You shouldn't need to change much; mainly changing the name of the element from SoulShards to ClassIcons, getting rid of your separate HolyPower element if you have one, and if your layout uses custom textures, add a class check when you're setting up the ClassIcons element to set the appropriate textures.

Here's the ClassIcons example from the oUF/elements/classicons.lua file:
Code:
   local ClassIcons = {}
   for index = 1, 5 do
      local Icon = self:CreateTexture(nil, 'BACKGROUND')
   
      -- Position and size.
      Icon:SetSize(16, 16)
      Icon:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Icon:GetWidth(), 0)
   
      ClassIcons[index] = Icon
   end
   
   -- Register with oUF
   self.ClassIcons = ClassIcons
You don't need to worry about defining your own Update function for the element; oUF takes care of everything. It does support PreUpdate, PostUpdate, and Override methods though, if you want to change how the element updates. I'd recommend using PostUpdate, and changing only the things you want to change, instead of definining an Override and having to do all the work yourself.

The other warlock powers -- Burning Embers and Demonic Fury -- are not yet supported by oUF itself, but Haste is working on a ClassBars element that will cover those plus all other class powers that have fill values or durations. If you want to support them in the meantime, you'll have to either write your own element, or use Tukz' oUF Warlock Spec Bars plugin. If you're writing your own, feel free to look at the WarlockPower.lua file in oUF Phanx for an example.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
09-10-12, 05:32 PM   #6
Senit24
A Fallenroot Satyr
AddOn Compiler - Click to view compilations
Join Date: Jul 2012
Posts: 28
Yep. Mine was outdated; I'll get the new one. Great info as always!

p.s. I'm very close to finished with my oUF Layout. I'll be sure to post the finished product, then I can start contributing to the other lua newbs!

Edit: Dun broke the entire addon... where to start...

Edit 2: Seems like everything's working except "oUF.TagEvents", know what's up with that?

Seems like the change from
Code:
oUF.Tags = tags
oUF.TagEvents = tagEvents
oUF.UnitlessTagEvents = unitlessEvents
to
Code:
oUF.Tags = {
	Methods = tags,
	Events = tagEvents,
	SharedEvents = unitlessEvents,

}
would indicate that I need to change "oUF.Tags" to "Methods" and "oUF.TagEvents" to "Events", is there more to it than that?

Edit 3: Nevermind, figured it out! oUF.Tags.Methods and oUF.Tags.Events. Hope this helps anyone else reading!

Last edited by Senit24 : 09-11-12 at 06:30 PM.
  Reply With Quote
10-02-12, 09:29 AM   #7
Paopao001
A Fallenroot Satyr
 
Paopao001's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2011
Posts: 20
Hello.
I would like to change the width of each class icon when the max number of the resource changes.

Lua Code:
  1. local ClassIconsPostUpdate = function(element, cur, max, maxchange)
  2.     for i = 1, 5 do
  3.         if cur == max then
  4.             element[i]:SetStatusBarColor(unpack(classicon_colors[cur]))
  5.         else
  6.             element[i]:SetStatusBarColor(unpack(classicon_colors[i]))
  7.         end
  8.         if maxchange then
  9.             element[i]:SetWidth((oUF_MlightDB.width+3)/max-3)
  10.         end    
  11.     end
  12. end
Lua Code:
  1. local _, class = UnitClass("player")
  2.        
  3.         -- Runes, Shards, HolyPower and so on --
  4.         if multicheck(class, "DEATHKNIGHT", "WARLOCK", "PALADIN", "MONK", "SHAMAN", "PRIEST", "MAGE", "ROGUE", "DRUID") then
  5.             local count
  6.             if class == "DEATHKNIGHT" then
  7.                 count = 6
  8.             elseif class == "WARLOCK" then
  9.                 count = 4
  10.             elseif class == "PALADIN" or class == "PRIEST" or class == "MONK" then
  11.                 count = 5
  12.             elseif class == "SHAMAN" then
  13.                 count = 4
  14.             elseif class == "MAGE" then
  15.                 count = 6
  16.             elseif class == "ROGUE" or class == "DRUID" then
  17.                 count = 5 -- combopoints
  18.             end
  19.  
  20.             local bars = CreateFrame("Frame", nil, self)
  21.             bars:SetPoint("BOTTOMLEFT", self, "TOPLEFT", 0, 3)
  22.             bars:SetSize(oUF_MlightDB.width, 10)
  23.  
  24.             for i = 1, count do
  25.                 bars[i] = createStatusbar(bars, texture, nil, oUF_MlightDB.height*-(oUF_MlightDB.hpheight-1), (oUF_MlightDB.width+2)/count-3, 1, 1, 1, 1)
  26.  
  27.                 if i == 1 then
  28.                     bars[i]:SetPoint("BOTTOMLEFT", bars, "BOTTOMLEFT")
  29.                 else
  30.                     bars[i]:SetPoint("LEFT", bars[i-1], "RIGHT", 3, 0)
  31.                 end
  32.  
  33.                 bars[i].bd = createBackdrop(bars[i], bars[i], 1)
  34.             end
  35.  
  36.             if class == "DEATHKNIGHT" then
  37.                 self.Runes = bars
  38.             elseif class == "WARLOCK" then
  39.                 self.WarlockSpecBars = bars
  40.             elseif class == "PALADIN" or class == "PRIEST" or class == "MONK" then
  41.                 self.ClassIcons = bars
  42.                 self.ClassIcons.UpdateTexture = function() end
  43.                 self.ClassIcons.PostUpdate = ClassIconsPostUpdate
  44.             elseif class == "SHAMAN" then
  45.                 self.TotemBar = bars
  46.             elseif class == "MAGE" then
  47.                 self.ArcaneCharge = bars
  48.             elseif class == "ROGUE" or class == "DRUID" then
  49.                 self.CPoints = bars
  50.                 self.CPoints.PostUpdate = CpointsPostUpdate
  51.             end
  52.         end

When the max number of power changes, it works properly. But there's a problem when log-in.
If the player is shadow priest. The width of each element is 1/5 of the width of player frame.
I would like it to be 1/3. A paladin under lvl 85 ,a warlock with 3 soul shards and a monk with 4 chis got the same problem.
The solution I found is to change element.__max to 5 in oUF\elements\classicons.lua(because I can't find a right place to make it in my layout).
This means: when I create the frames/textures for the element, I set the width of each icon suppose the player got 5 class icons. When PLAYER_TALENT_UPDATE fires, oUF update the element and oldMax ~= max is true in element:PostUpdate(cur, max, oldMax ~= max). So the layout can change the width of each icon when log-in.

Haste, I really appreciate if you could set element.__max to 5 in oUF\elements\classicons.lua or make it easier to change element.__max in layout.
__________________

I hope you could understand my broken English.
If I offended you it was unwitting.
  Reply With Quote
10-02-12, 04:28 PM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Well, the obvious problem in your login code is that you are dividing the total width by 5, not by 3...
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
10-02-12, 09:06 PM   #9
Paopao001
A Fallenroot Satyr
 
Paopao001's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2011
Posts: 20
Originally Posted by Phanx View Post
Well, the obvious problem in your login code is that you are dividing the total width by 5, not by 3...
Then should I divided it by PRIEST_BAR_NUM_ORBS for shadow priest, by 4 for monk, by 3 for warlock, by HOLY_POWER_FULL for paladin? I think that's different from the intent of combine them together in some way.
__________________

I hope you could understand my broken English.
If I offended you it was unwitting.
  Reply With Quote
10-02-12, 11:55 PM   #10
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Paopao001 View Post
Then should I divided it by PRIEST_BAR_NUM_ORBS for shadow priest, by 4 for monk, by 3 for warlock, by HOLY_POWER_FULL for paladin? I think that's different from the intent of combine them together in some way.
They're only combined into one element so Haste isn't copy/pasting the same code 3+ times and just changing the name. You don't have to treat them all exactly the same, all the time. ShadowOrbs isn't going to get upset if you pick HolyPower first for the team.

Simply updating the width in your PostUpdate should work, though you may need to set some kind of flag on the element, and update the width if it's set even if oUF didn't think the max changed, to catch that initial update:
Code:
self.ClassIcons.PostUpdate = ClassIconsPostUpdate
self.ClassIcons.forceUpdate = true
Then, in your ClassIconsPostUpdate function:
Code:
if maxchange or element.forceUpdate then
     element.forceUpdate = nil
     element[i]:SetWidth((oUF_MlightDB.width+3)/max-3)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote

WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Combo Points (and related class powers)


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off