-
Posted by barongarrett on Mon, 29 Mar 2010 18:11:05
Hello, I wanted to first say that I am really enjoying your book and it has helped me greatly in learning to modify some addons, as well as starting to try to build my own. I am considering buying your 2nd edition book, though since I just bought the 1st edition maybe 4 months ago, I am not sure if it would really be worth it yet. Is the 1st edition really outdated enough for it to warrant me upgrading to the 2nd edition at this point in my addon learning?
Now, on to the real issue. I am trying to modify Healium to add in Mana bars. I have been successful (I believe) in adding the XML portion, but I am having issues with the LUA part of it. It looks like the addon was built very similar to your Group Templates frames and so I was hoping you could help with what I need to add, and where. I have read through Ch 27 a few times but just not getting what I need to do. This is the XML code I added. The first statusbar was what the author had already, I added the second one for mana.
<StatusBar name="$parent_HealthBar" parentKey="HealthBar" minValue="0" maxValue="100" defaultValue="100" frameStrata="LOW"> <Size x="116" y="23"/> <Anchors> <Anchor point="TOPLEFT"> <Offset> <AbsDimension x="2" y="-2"/> </Offset> </Anchor> </Anchors> <BarTexture file="Interface\Addons\SharedMedia\statusbar\smooth.tga" /> <BarColor r="1.0" g="1.0" b="1.0"/> <Scripts > <OnLoad function="Healium_StatusBar_OnLoad" /> </Scripts> </StatusBar> <StatusBar name="$parent_ManaBar" parentKey="ManaBar" minValue="0" maxValue="100" defaultValue="100" frameStrata="LOW"> <Size x="116" y="12"/> <Anchors> <Anchor point="TOPLEFT"> <Offset> <AbsDimension x="2" y="-25"/> </Offset> </Anchor> </Anchors> <BarTexture file="Interface\Addons\SharedMedia\statusbar\smooth.tga" /> <BarColor r="1.0" g="1.0" b="1.0"/> <Scripts > <OnLoad function="Healium_StatusBar_OnLoad" /> </Scripts> </StatusBar>
This is the relevant LUA code (I think).
function HealiumUnitFrames_Button_OnShow(self) local unit = self:GetAttribute("unit") if unit then self.TargetUnit = unit for i=1, Healium_MaxButtons, 1 do local button = self.buttons[i] if not button then break end -- update cooldowns local id = Healium_ButtonIDs[i] if id then local start, duration, enable = GetSpellCooldown(Healium_ButtonIDs[i], BOOKTYPE_SPELL) CooldownFrame_SetTimer(button.cooldown, start, duration, enable) end end local name = UnitName(unit) if name then self.name:SetText(strupper(name)) else self.name:SetText("") end if not Healium_Units[unit] then Healium_Units[unit] = { } end table.insert(Healium_Units[unit], self) for i =1, MaxBuffs, 1 do self.buffs[i].unit = unit end Healium_UpdateUnitHealth(unit, self) Healium_UpdateBuffs(unit, self) end end
Any help will be greatly appreciated! Thank you in advance.
-
Posted by jnwhiteh on Tue, 30 Mar 2010 09:13:03
See, without having more context, it makes it incredibly difficult for me to just tell you what to add. If you have a specific question about something you'd like to accomplish than I can try to work that out with you.
Please let me know.
-
Posted by barongarrett on Tue, 30 Mar 2010 15:22:12
I actually decided to just start over and build the mod from the ground up with your Chapter 27 lesson. I have looked it over a few times and just don't see where I messed up though. I did decide to purchase the new edition of the book anyways, since our son wants to learn too, so I will give him my old version. So I have it on order from Amazon atm. Currently the bars will show up in game, but they will not be movable, they stay white, and I get an error. I cant post the error currently as servers are down, but I believe it was about the value being nil for OnLoad.
<UI xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <!-- Main Frame Template --> <Button name="BasicUnitFrames_ButtonTemplate" virtual="true"> <Size x="120" y="45"/> <Layers> <Layer level="ARTWORK"> <FontString name="$parent_Name" setAllPoints="true" text="Unknown Entity" inherits="GameFontHighlight"/> </Layer> </Layers> <Frames> <StatusBar name="$parent_HealthBar" minValue="0" maxValue="100" defaultValue="100" setAllPoints="true"> <BarTexture file="Interface\TargetingFrame\UI-StatusBar"/> <BarColor r="1.0" g="1.0" b="1.0"/> <Scripts> <OnLoad> self:SetFrameLevel(self:GetFrameLevel() - 1) </OnLoad> </Scripts> </StatusBar> </Frames> <Scripts> <OnLoad> BasicUnitFrames_Button_OnLoad(self) </OnLoad> <OnShow> BasicUnitFrames_Button_OnShow(self) </OnShow> <OnEvent> BasicUnitFrames_Button_OnEvent(self, event, ...) </OnEvent> <OnDragStart> BasicUnitFrames_Button_OnDragStart(self, button) </OnDragStart> <OnDragStop> BasicUnitFrames_Button_OnDragStop(self, button) </OnDragStop> <OnHide> BasicUnitFrames_Button_OnHide(self, button) </OnHide> </Scripts> </Button> <!-- Main Header Template --> <Frame name="BasicUnitFrames_Header" parent="UIParent" inherits="SecureGroupHeaderTemplate" movable="true" hidden="false"> <Anchors> <Anchor point="CENTER"/> </Anchors> <Attributes> <Attribute name="showParty" type="boolean" value="true"/> <Attribute name="showRaid" type="boolean" value="true"/> <Attribute name="showPlayer" type="boolean" value="true"/> <Attribute name="showSolo" type="boolean" value="true"/> <Attribute name="maxColumns" type="number" value="8"/> <Attribute name="unitsPerColumn" type="number" value="5"/> <Attribute name="columnAnchorPoint" type="string" value="LEFT"/> <Attribute name="point" type="string" value="TOP"/> <Attribute name="template" type="string" value="BasicUnitFrames_ButtonTemplate"/> <Attribute name="templateType" type="string" value="Button"/> </Attributes> </Frame> </UI> function BasicUnitFrames_Button_OnLoad(self) self:RegisterForDrag("LeftButton") self:RegisterForEvent("UNIT_HEALTH") self:RegisterForEvent("UNIT_MAXHEALTH") self.healthbar = getglobal(self:GetName().."_HealthBar") self.name = getglobal(self:GetName().."_Name") end function BasicUnitFrames_Button_OnShow(self) local unit = self:GetAttribute("unit") if unit then self.name:SetText(UnitName(unit)) local class = select(2, UnitClass(unit)) or "WARRIOR" local color = RAID_CLASS_COLORS[class] self.healthbar:SetStatusBarColor(color.r, color.g, color.b) end end function BasicUnitFrames_Button_OnEvent(self, event, ...) local unit = ... if self:GetAttribute("unit") == unit then if event == "UNIT_MAXHEALTH" then self.healthbar:SetMinMaxValues(0, UnitHealthMax(unit)) self.healthbar:SetValue(UnitHealth(unit)) elseif event == "UNIT_HEALTH" then self.healthbar:SetValue(UnitHealth(unit)) end end end function BasicUnitFrames_Button_OnDragStart(self, button) BasicUnitFrames_Header:StartMoving() BasicUnitFrames_Header.isMoving = true end function BasicUnitFrames_Button_OnDragStop(self, button) if BasicUnitFrames_Header.isMoving then BasicUnitFrames_Header:StopMovingOrSizing() end end
I am wondering if I just missed a small mistake or maybe the code rules have changed since book launched and I need to update some code to 3.3 standards. I will try to post error once I can log on.
Message: [string "BasicUnitFrames_HeaderUnitButton1:OnLoad"]:1: attempt to call global 'BasicUnitFrames_Button_OnLoad' (a nil value) Time: 03/30/10 11:25:09 Count: 1 Stack: [string "*:OnLoad"]:1: in function <[string "*:OnLoad"]:1> [C]: in function `CreateFrame' Interface\FrameXML\SecureTemplates.lua:774: in function <Interface\FrameXML\SecureTemplates.lua:729> Interface\FrameXML\SecureTemplates.lua:1024: in function <Interface\FrameXML\SecureTemplates.lua:905> Locals: self = BasicUnitFrames_HeaderUnitButton1 { 0 = <userdata> } (*temporary) = nil (*temporary) = BasicUnitFrames_HeaderUnitButton1 { 0 = <userdata> } (*temporary) = "attempt to call global 'BasicUnitFrames_Button_OnLoad' (a nil value)"
-
Posted by jnwhiteh on Tue, 30 Mar 2010 18:33:51
What's loading the first, the XML or the Lua? I think the Lua script will need to be loaded first due to some changes in the way script handlers are created. Let me know.
-
Posted by barongarrett on Tue, 30 Mar 2010 19:44:50
I assume you are asking which is first in the TOC? I had it set to XML first. When I swapped it to LUA first I got 13 errors. The first of which was:
**Message: Interface\AddOns\BasicUnitFrames\BasicUnitFrames.lua:4: attempt to call method 'RegisterForEvent' (a nil value) Time: 03/30/10 12:41:47 Count: 1 Stack: Interface\AddOns\BasicUnitFrames\BasicUnitFrames.lua:4: in function `BasicUnitFrames_Button_OnLoad' [string "*:OnLoad"]:1: in function <[string "*:OnLoad"]:1> [C]: in function `CreateFrame' Interface\FrameXML\SecureTemplates.lua:774: in function <Interface\FrameXML\SecureTemplates.lua:729> Interface\FrameXML\SecureTemplates.lua:1024: in function <Interface\FrameXML\SecureTemplates.lua:905> Locals: self = BasicUnitFrames_HeaderUnitButton1 { 0 = <userdata> } (*temporary) = nil (*temporary) = BasicUnitFrames_HeaderUnitButton1 { 0 = <userdata> } (*temporary) = "UNIT_HEALTH" (*temporary) = "attempt to call method 'RegisterForEvent' (a nil value)" **
And here is TOC just in case:
## Interface: 30300 ## Title: BasicUnitFrames ## Notes: Unitframe replacement mod that is inspired from ProfitUI Reborn from EQ2. BasicUnitFrames.lua BasicUnitFrames.xml
-
Posted by jnwhiteh on Tue, 30 Mar 2010 20:25:00
There is no RegisterForEvent method. It should be RegisterEvent.
-
Posted by barongarrett on Tue, 30 Mar 2010 20:52:52
Woot! Something so minor.... I looked over that code for hours and just never saw the problem. Thank you for your help! Now on to adding mana bars and other goodies!
-
Posted by barongarrett on Wed, 31 Mar 2010 03:32:29
Another issue I have run into... I wanna split the Button in half basically, top half being Healhbar and bottom being mana. I assumed what I would do is change the setAllPoints to an actual anchor snippet and then add in the same basic values for manabars, like such:
<UI xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <!-- Main Frame Template --> <Button name="BasicUnitFrames_ButtonTemplate" virtual="true"> <Size x="120" y="30"/> <Layers> <Layer level="ARTWORK"> <FontString name="$parent_Name" setAllPoints="true" text="Unknown Entity" inherits="GameFontHighlight"/> </Layer> </Layers> <Frames> <StatusBar name="$parent_HealthBar" minValue="0" maxValue="100" defaultValue="100" parent="UIParent"> <Size x="120" y="20"/> <Anchors> <Anchor point="TOPLEFT" relativeTo="BasicUnitFrames_Header"/> </Anchors> <BarTexture file="Interface\TargetingFrame\UI-StatusBar"/> <BarColor r="1.0" g="1.0" b="1.0"/> <Scripts> <OnLoad> self:SetFrameLevel(self:GetFrameLevel() - 1) </OnLoad> </Scripts> </StatusBar> <StatusBar name="$parent_ManaBar" minValue="0" maxValue="100" defaultValue="100" parent="UIParent"> <Size x="120" y="10"/> <Anchors> <Anchor point="BOTTOMLEFT" relativeTo="BasicUnitFrames_Header"/> </Anchors> <BarTexture file="Interface\TargetingFrame\UI-StatusBar"/> <BarColor r="1.0" g="1.0" b="1.0"/> <Scripts> <OnLoad> self:SetFrameLevel(self:GetFrameLevel() - 1) </OnLoad> </Scripts> </StatusBar> </Frames> <Scripts> <OnLoad> BasicUnitFrames_Button_OnLoad(self) </OnLoad> <OnShow> BasicUnitFrames_Button_OnShow(self) </OnShow> <OnEvent> BasicUnitFrames_Button_OnEvent(self, event, ...) </OnEvent> <OnDragStart> BasicUnitFrames_Button_OnDragStart(self, button) </OnDragStart> <OnDragStop> BasicUnitFrames_Button_OnDragStop(self, button) </OnDragStop> </Scripts> </Button> <!-- Main Header Template --> <Frame name="BasicUnitFrames_Header" parent="UIParent" inherits="SecureGroupHeaderTemplate" movable="true" hidden="false"> <Anchors> <Anchor point="CENTER"/> </Anchors> <Attributes> <Attribute name="showParty" type="boolean" value="true"/> <Attribute name="showRaid" type="boolean" value="true"/> <Attribute name="showPlayer" type="boolean" value="true"/> <Attribute name="showSolo" type="boolean" value="true"/> <Attribute name="maxColumns" type="number" value="8"/> <Attribute name="unitsPerColumn" type="number" value="5"/> <Attribute name="columnAnchorPoint" type="string" value="LEFT"/> <Attribute name="point" type="string" value="TOP"/> <Attribute name="template" type="string" value="BasicUnitFrames_ButtonTemplate"/> <Attribute name="templateType" type="string" value="Button"/> </Attributes> </Frame> </UI>
When I do this though, it seems to just delete the Statusbars. I used DevTools and dont even see the statusbars anywhere. All I see are the player names and the following frames:
UIParent, BasicUnitFramesHeader, BasicUnitFramesHeaderButton1
I had relativeTo wrong, now the bars show, but no longer work and aren't colorcoded. So still working on it.
-
Posted by barongarrett on Fri, 09 Apr 2010 23:30:26
I finally got the 2nd edition yesterday and it's a very nice book. I have started doing the Unti frames from Chapter 27 and all is working well so far but the power bar is just showing as black.
I just am not seeing what I did wrong in the code so far. Thanks in advance for anyone that can help.
LUA:
function PuirWow_UnitFrames_InitialConfig(frame) -- Nudge the status bar frame levels down frame.unit.healthBar:SetFrameLevel(frame.unit:GetFrameLevel()) frame.unit.powerBar:SetFrameLevel(frame.unit:GetFrameLevel()) frame.unit:RegisterForDrag("LeftButton") frame:RegisterEvent("UNIT_HEALTH") frame:RegisterEvent("UNIT_MAXHEALTH") frame:RegisterEvent("PLAYER_ENTERING_WORLD") frame:RegisterEvent("UNIT_DISPLAYPOWER") frame:RegisterEvent("UNIT_NAME_UPDATE") end function PuirWow_UnitFrames_Frame_OnShow(button) local unit = button:GetAttribute("unit") if unit then local guid = UnitGUID(unit) if guid ~= button.guid then PuirWow_UnitFrames_ResetUnitButton(button.unit, unit) button.guid = guid end end end function PuirWow_UnitFrames_ResetUnitButton(button, unit) PuirWow_UnitFrames_ResetHealthBar(button, unit) PuirWow_UnitFrames_ResetPowerBar(button, unit) PuirWow_UnitFrames_ResetName(button, unit) end function PuirWow_UnitFrames_ResetName(button, unit) local name = UnitName(unit) or UNKNOWN button.name:SetText(name) end function PuirWow_UnitFrames_ResetHealthBar(button, unit) local class = select(2, UnitClass(unit)) or "WARRIOR" local classColor = RAID_CLASS_COLORS[class] button.healthBar:SetStatusBarColor(classColor.r, classColor.g, classColor.b) button.healthBar:SetMinMaxValues(0, UnitHealthMax(unit)) button.healthBar:SetValue(UnitHealth(unit)) end function PuirWow_UnitFrames_Button_OnDragStart(self, button) PuirWow_UnitFrames_Header:StartMoving() PuirWow_UnitFrames_Header.isMoving = true end function PuirWow_UnitFrames_Button_OnDragStop(self, button) if PuirWow_UnitFrames_Header.isMoving then PuirWow_UnitFrames_Header:StopMovingOrSizing() end end function PuirWow_UnitFrames_Frame_OnEvent(self, event, arg1, ...) local unit = self:GetAttribute("unit") if not unit then return end -- Handle any events that don't accept a unit argument if event == "PLAYER_ENTERING_WORLD" then PuirWow_UnitFrames_ResetUnitButton(self.unit, unit) elseif arg1 and UnitIsUnit(unit, arg1) then local powerType, powerToken = UnitPowerType(unit) if event =="UNIT_MAXHEALTH" then self.unit.healthBar:SetMinMaxValues(0, UnitHealthMax(unit)) self.unit.healthBar:SetValue(UnitHealth(unit)) elseif event =="UNIT_HEALTH" then self.unit.healthBar:SetValue(UnitHealth(unit)) elseif event == "UNIT_DISPLAYPOWER" then PuirWow_UnitFrames_ResetPowerBar(self.unit, unit) elseif event == "UNIT_" .. powerToken then self.unit.powerBar:SetValue(UnitPower(unit)) elseif event == "UNIT_MAX" .. powerToken then self.unit.powerBar:SetMinMaxValues(0, UnitPowerMax(unit)) self.unit.powerBar:SetValue(UnitPower(unit)) elseif event == "UNIT_NAME_UPDATE" then PuirWow_UnitFrames_ResetName(self.unit, unit) end end end local function unregisterManyEvents(frame, ...) for i=1, select("#", ...) do local event = select(i, ...) frame:UnregisterEvent(event) end end function PuirWow_UnitFrames_ResetPowerBar(button, unit) local powerType, powerToken = UnitPowerType(unit) local powerColor = PowerBarColor[powerToken] local alive = not UnitIsDeadOrGhost(unit) local parent = button:GetParent() unregisterManyEvents(parent, "UNIT_MANA", "UNIT_RAGE", "UNIT_FOCUS", "UNIT_ENERGY", "UNIT_RUNIC_POWER") unregisterManyEvents(parent, "UNIT_MAXMANA", "UNIT_MAXRAGE", "UNIT_MAXFOCUS", "UNIT_MAXENERGY", "UNIT_MAXRUNIC_POWER") parent:RegisterEvent("UNIT_" .. powerToken) parent:RegisterEvent("UNIT_MAX" .. powerToken) button.powerBar:SetStatusBarColor(powerColor.r, powerColor.g, powerColor.b) button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit)) button.powerBar:SetValue(UnitPower(unit)) end PuirWow_UnitFrames_Header.initialConfigFunction = PuirWow_UnitFrames_InitialConfig PuirWow_UnitFrames_Header:Show()
The XML:
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <Frame name="PuirWow_UnitFrames_UnitTemplate" virtual="true"> <Size x="120" y="35"/> <Layers> <Layer level="BACKGROUND"> <Texture setAllPoints="true"> <Color r="0.0" g="0.0" b="0.0"/> </Texture> </Layer> </Layers> <Frames> <Button name="$parent_Unit" parentKey="unit" inherits="SecureUnitButtonTemplate"> <Size x="118" y="33"/> <Anchors> <Anchor point="TOPLEFT"> <Offset x="1" y="1"/> </Anchor> </Anchors> <Layers> <Layer level="OVERLAY"> <FontString name="$parent_Name" parentKey="name" inherits="GameFontHighlight" setAllPoints="true"/> </Layer> </Layers> <Frames> <StatusBar name="$parent_HealthBar" parentKey="healthBar"> <Size x="118" y="25"/> <Anchors> <Anchor point="TOPLEFT"/> </Anchors> <BarTexture file="Interface\Buttons\UI-Listbox-Highlight2"/> <BarColor r="1.0" g="1.0" b="1.0"/> </StatusBar> <StatusBar name="$parent_PowerBar" parentKey="powerBar"> <Size x="118" y="9"/> <Anchors> <Anchor point="TOPLEFT" relativeTo="$parent_HealthBar" relativePoint="BOTTOMLEFT"> <Offset x="0" y="-1"/> </Anchor> </Anchors> <BarTexture file="Interface\TargetingFrame-BarFill"/> <BarColor r="1.0" g="1.0" b="1.0"/> </StatusBar> </Frames> <Scripts> <OnDragStart function="PuirWow_UnitFrames_Button_OnDragStart"/> <OnDragStop function="PuirWow_UnitFrames_Button_OnDragStop"/> <OnHide function="PuirWow_UnitFrames_Button_OnDragStop"/> </Scripts> <Attributes> <Attribute name="useparent-unit" type="boolean" value="true"/> <Attribute name="*type1" type="string" value="target"/> </Attributes> </Button> </Frames> <Scripts> <OnShow function="PuirWow_UnitFrames_Frame_OnShow"/> <OnEvent function="PuirWow_UnitFrames_Frame_OnEvent"/> </Scripts> </Frame> <!-- Header Template --> <Frame name="PuirWow_UnitFrames_Header" parent="UIParent" inherits="SecureGroupHeaderTemplate" movable="true"> <Anchors> <Anchor point="CENTER"/> </Anchors> <Attributes> <Attribute name="showParty" type="boolean" value="true"/> <Attribute name="showRaid" type="boolean" value="true"/> <Attribute name="showPlayer" type="boolean" value="true"/> <Attribute name="showSolo" type="boolean" value="true"/> <Attribute name="maxColumns" type="number" value="8"/> <Attribute name="unitPerColumn" type="number" value="5"/> <Attribute name="columnAnchorPoint" type="string" value="TOP"/> <Attribute name="point" type="string" value="LEFT"/> <Attribute name="template" type="string" value="PuirWow_UnitFrames_UnitTemplate"/> <Attribute name="templateType" type="string" value="Frame"/> <Attribute name="xOffset" type="number" value="-1"/> <Attribute name="yOffset" type="number" value="1"/> </Attributes> </Frame> </Ui>
-
Posted by barongarrett on Sat, 10 Apr 2010 02:39:11
NM, I found my problem. I didn't type out the power bar XML code poperly for the BarTexture file