Quantcast

* Renamed a number of frames to have a bit more meaning

James Whitehead II [12-19-06 - 03:56]
* Renamed a number of frames to have a bit more meaning
* Began work on buff editing window, to define custom buff sets
* Resolved a number of issues with raid units not being cleared properly, which meant multiple units were updating to the same base unit
* Add/Editing headers now works properly, and can be done anytime you are not in combat
* Headers can now have their positions restored and saved when logging in
* Added a slash command to bring up the GUI.
Filename
PerfectRaid.lua
PerfectRaidOptions.lua
diff --git a/PerfectRaid.lua b/PerfectRaid.lua
index 3bcb77e..0a8461a 100644
--- a/PerfectRaid.lua
+++ b/PerfectRaid.lua
@@ -35,6 +35,7 @@ local unavail = {}
 local L
 local utils = DongleStub("DongleUtils")
 PerfectRaid = DongleStub("Dongle"):New("PerfectRaid")
+PerfectRaid.frames = frames

 function PerfectRaid:Initialize()
 	self.defaults = {
@@ -65,22 +66,95 @@ function PerfectRaid:Enable()
 	self:RegisterEvent("UNIT_MAXENERGY", "UNIT_MAXMANA")
 	self:RegisterEvent("UNIT_MAXFOCUS", "UNIT_MAXMANA")
 	self:RegisterEvent("UNIT_AURA")
-	self:CreatePartyFrame()

-	local frame = CreateFrame("Frame", "PRaidRaidHeader", UIParent, "SecureRaidGroupHeaderTemplate")
+	self:CreateRaidHeaders()
+end
+
+function PerfectRaid:CreateRaidHeaders()
+	local list = self.db.profile.headers
+	self.headers = self.headers or {}
+
+	for i=1,#list do
+		local entry = list[i]
+		local name = "PRHeader"..i
+		local filters = strjoin(",", unpack(entry.filters))
+
+		if self.headers[i] then
+			self:ChangeRaidFrame(name, entry.name, filters)
+		else
+			self.headers[i] = self:CreateRaidFrame(name, entry.name, filters)
+			self:RestorePosition("PRHeader"..i)
+		end
+	end
+end
+
+function PerfectRaid:SavePosition(name)
+    local f = getglobal(name)
+    local x,y = f:GetLeft(), f:GetTop()
+    local s = f:GetEffectiveScale()
+
+    x,y = x*s,y*s
+
+	local opt = self.db.profile.headers[tonumber(string.sub(name, -1, -1))]
+    opt.PosX = x
+    opt.PosY = y
+end
+
+function PerfectRaid:RestorePosition(name)
+	local f = getglobal(name)
+	local opt = self.db.profile.headers[tonumber(string.sub(name, -1, -1))]
+	local x = opt.PosX
+	local y = opt.PosY
+
+    local s = f:GetEffectiveScale()
+
+    if not x or not y then
+        f:ClearAllPoints()
+        f:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+        return
+    end
+
+    x,y = x/s,y/s
+
+    f:ClearAllPoints()
+	f:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
+end
+
+function PerfectRaid:ChangeRaidFrame(name, title, filter)
+	local frame = getglobal(name)
+	frame.title:SetText(title or "")
+	frame:SetAttribute("groupFilter", filter)
+	frame:Hide()
+	frame:Show()
+end
+
+local function OnDragStart(frame)
+	local parent = frame:GetParent()
+	parent:StartMoving()
+end
+
+local function OnDragStop(frame)
+	local parent = frame:GetParent()
+	parent:StopMovingOrSizing()
+	PerfectRaid:SavePosition(parent:GetName())
+end
+
+function PerfectRaid:CreateRaidFrame(name, title, filter)
+	local frame = CreateFrame("Frame", name, UIParent, "SecureRaidGroupHeaderTemplate")
+	frame.title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
+	frame.title:SetPoint("BOTTOM", frame, "TOP", 0, 5)
+	frame.title:SetText(title or "")
 	frame:SetAttribute("point", "TOP")
-	frame:SetAttribute("groupFilter", "1,2,3,4,5,6,7,8")
+	frame:SetAttribute("groupFilter", filter)
 	frame:SetAttribute("template", "SecureUnitButtonTemplate")
 	frame:SetAttribute("templateType", "Button")
-	frame:SetAttribute("nameList", UnitName("player"))
 	frame:SetAttribute("yOffset", -2)
-	frame:SetPoint("TOP", PRaidPartyHeader, "BOTTOM", 0, -2)
+	frame:SetAttribute("sortMethod", "NAME")
 	frame.initialConfigFunction = PerfectRaid.ConfigureButton
 	frame:SetMovable(true)
 	frame:SetClampedToScreen(true)
-
-	PRaidRaidHeader:Show()
-	self:CreateOptions()
+	frame:Show()
+	return frame
 end

 function PerfectRaid:CreatePartyFrame()
@@ -108,9 +182,9 @@ function PerfectRaid:CreatePartyFrame()
 end

 function PerfectRaid:GetColoredName(unit)
-	local class = select(2, UnitClass(unit))
+	local class = select(2, UnitClass(unit)) or "WARRIOR"
 	local color = RAID_CLASS_COLORS[class]
-	return string.format("|cFF%02x%02x%02x%s|r", color.r*255, color.g*255, color.b*255, UnitName(unit))
+	return string.format("|cFF%02x%02x%02x%s|r", color.r*255, color.g*255, color.b*255, UnitName(unit) or "Unknown")
 end

 function PerfectRaid:UNIT_HEALTH(event, unit)
@@ -241,14 +315,14 @@ local function OnHide(frame)
 	frames[unit][frame] = nil
 end

-local function OnDragStart(frame)
-	local parent = frame:GetParent()
-	parent:StartMoving()
-end
+local function OnAttributeChanged(frame, name, value)
+	if name ~= "unit" then return end

-local function OnDragStop(frame)
-	local parent = frame:GetParent()
-	parent:StopMovingOrSizing()
+	for unit,tbl in pairs(frames) do
+		if tbl[frame] and frame:GetAttribute("unit") ~= unit then
+			tbl[frame] = nil
+		end
+	end
 end

 function PerfectRaid.ConfigureButton(button)
@@ -293,14 +367,30 @@ function PerfectRaid.ConfigureButton(button)
 	button:SetScript("OnShow", OnShow)
 	button:SetScript("OnDragStart", OnDragStart)
 	button:SetScript("OnDragStop", OnDragStop)
+	button:SetScript("OnAttributeChanged", OnAttributeChanged)
 end

 function PerfectRaid:RAID_ROSTER_UPDATE()
 	if GetNumRaidMembers() > 0 then
 		--PRaidPartyHeader:Hide()
+		for k,v in pairs(self.headers) do
+			v:StopMovingOrSizing()
+			v:Show()
+		end
 	else
-		PRaidPartyHeader:Show()
-	end
+		if PRaidPartyHeader then
+			PRaidPartyHeader:Show()
+		end
+		for unit,tbl in pairs(frames) do
+			for k,v in pairs(tbl) do
+				tbl[k] = nil
+			end
+		end
+
+		for k,v in pairs(self.headers) do
+			v:Hide()
+		end
+	end
 end

 local elapsed = 0
@@ -315,42 +405,45 @@ function PerfectRaid.OnUpdate(frame, arg1)
 	elapsed = 0
 end

---seterrorhandler(function(msg) PerfectRaid:Print(msg .. debugstack()) end)
-
-local manauser = function(u) return UnitPowerType(u) == 0 end
-local all = function() return true end
-
-local buffs = {
-	["Rejuvenation"] = {
-		cond = manauser,
-		text = "Rj",
-	},
-	["Regrowth"] = {
-		cond = all,
-		text = "Rg",
-	},
-}
+local frame = CreateFrame("Frame", "PRUpdateFrame")
+frame:SetScript("OnUpdate", PerfectRaid.OnUpdate)

-local work = {}
+local buffcache = {}

 function PerfectRaid:UNIT_AURA(event, unit)
 	if not frames[unit] then return end
+	for k,v in pairs(buffcache) do buffcache[k] = nil end

-	for k in pairs(work) do
-		work[k] = nil
-	end
-
-	local status = ""
 	for i=1,40 do
 		local name,rank,texture,count = UnitBuff(unit, i)
 		if not name then break end
-		if buffs[name] and buffs[name].cond(unit) then
-			table.insert(work, buffs[name].text)
-		end
+		buffcache[name] = (buffcache[name] or 0) + 1
+	end
+
+	for i=1,40 do
+		local name,rank,texture,count = UnitDebuff(unit, i)
+		if not name then break end
+		buffcache[name] = (buffcache[name] or 0) + 1
+	end
+end
+
+--seterrorhandler(function(msg) PerfectRaid:Print(msg .. debugstack()) end)
+
+SLASH_PERFECTRAID1 = "/praid"
+SLASH_PERFECTRAID2 = "/perfectraid"
+
+SlashCmdList["PERFECTRAID"] = function(msg)
+	-- Slash Command Handler
+	if InCombatLockdown() then
+		PerfectRaid:Print("You cannot change option when in combat")
+		return
 	end

-	status = strjoin(" ", unpack(work))
-	for frame in pairs(frames[unit]) do
-		frame.aura:SetText(status)
+	if not PROptions then
+		PerfectRaid:CreateOptions()
+		PROptions:Show()
+	else
+		PROptions:Show()
 	end
 end
+
diff --git a/PerfectRaidOptions.lua b/PerfectRaidOptions.lua
index 7160c25..3ba3b3b 100644
--- a/PerfectRaidOptions.lua
+++ b/PerfectRaidOptions.lua
@@ -1,4 +1,4 @@
- --[[-------------------------------------------------------------------------
+--[[-------------------------------------------------------------------------
   Copyright (c) 2006, Jim Whitehead II <cladhaire@gmail.com>
   All rights reserved.

@@ -129,15 +129,17 @@ function PerfectRaid:SkinButton(button)
 end

 function PerfectRaid:CreateOptions()
-	local frame = CreateFrame("Frame")
+	local frame = CreateFrame("Frame", "PROptions")
 	frame:SetHeight(250)
 	frame:SetWidth(350)
 	frame:SetPoint("CENTER", 0, 0)
 	self:SkinFrame(frame)
 	frame.title:SetText("PerfectRaid Configuration")

+	frame:SetScript("OnHide", function() PREditRaid:Hide() end)
+
 	local function MakeEntry(name, parent)
-		local entry = CreateFrame("CheckButton", nil, parent)
+		local entry = CreateFrame("CheckButton", name, parent)
 		entry:SetHeight(30)
 		entry:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
 		entry:SetCheckedTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
@@ -155,32 +157,32 @@ function PerfectRaid:CreateOptions()
 		return entry
 	end

-	local entry1 = MakeEntry(nil, frame)
+	local entry1 = MakeEntry("PROptionsEntry1", frame)
 	entry1:SetPoint("TOPLEFT", 15, -30)
 	entry1:SetPoint("RIGHT", 0, 0)
 	entry1.idx = 1

-	local entry2 = MakeEntry(nil, frame)
+	local entry2 = MakeEntry("PROptionsEntry1", frame)
 	entry2:SetPoint("TOPLEFT", entry1, "BOTTOMLEFT", 0, 0)
 	entry2:SetPoint("RIGHT", 0, 0)
 	entry2.idx = 2

-	local entry3 = MakeEntry(nil, frame)
+	local entry3 = MakeEntry("PROptionsEntry1", frame)
 	entry3:SetPoint("TOPLEFT", entry2, "BOTTOMLEFT", 0, 0)
 	entry3:SetPoint("RIGHT", 0, 0)
 	entry3.idx = 3

-	local entry4 = MakeEntry(nil, frame)
+	local entry4 = MakeEntry("PROptionsEntry1", frame)
 	entry4:SetPoint("TOPLEFT", entry3, "BOTTOMLEFT", 0, 0)
 	entry4:SetPoint("RIGHT", 0, 0)
 	entry4.idx = 4

-	local entry5 = MakeEntry(nil, frame)
+	local entry5 = MakeEntry("PROptionsEntry1", frame)
 	entry5:SetPoint("TOPLEFT", entry4, "BOTTOMLEFT", 0, 0)
 	entry5:SetPoint("RIGHT", 0, 0)
 	entry5.idx = 5

-	local entry6 = MakeEntry(nil, frame)
+	local entry6 = MakeEntry("PROptionsEntry1", frame)
 	entry6:SetPoint("TOPLEFT", entry5, "BOTTOMLEFT", 0, 0)
 	entry6:SetPoint("RIGHT", 0, 0)
 	entry6.idx = 6
@@ -202,23 +204,22 @@ function PerfectRaid:CreateOptions()
 		frame:SetScript("PostClick", postclick)
 	end

-
-	local button1 = CreateFrame("Button", nil, frame)
+	local button1 = CreateFrame("Button", "PRButtonAdd", frame)
 	self:SkinButton(button1)
 	button1.text:SetText("Add Frame")
 	button1:SetPoint("BOTTOMLEFT", 10, 10)

-	local button2 = CreateFrame("Button", nil, frame)
+	local button2 = CreateFrame("Button", "PRButtonEdit", frame)
 	self:SkinButton(button2)
 	button2.text:SetText("Edit Frame")
 	button2:SetPoint("LEFT", button1, "RIGHT", 10, 0)

-	local button5 = CreateFrame("Button", nil, frame)
+	local button5 = CreateFrame("Button", "PRButtonDelete", frame)
 	self:SkinButton(button5)
 	button5.text:SetText("Delete Frame")
 	button5:SetPoint("LEFT", button2, "RIGHT", 10, 0)

-	local scrollframe = CreateFrame("ScrollFrame", "PraidScrollFrame", frame, "FauxScrollFrameTemplate")
+	local scrollframe = CreateFrame("ScrollFrame", "PRScrollFrame", frame, "FauxScrollFrameTemplate")
 	scrollframe:SetPoint("TOPLEFT", entry1, "TOPLEFT", 0, 0)
 	scrollframe:SetPoint("BOTTOMRIGHT", entry6, "BOTTOMRIGHT", 0, 0)

@@ -264,14 +265,15 @@ function PerfectRaid:CreateOptions()

 	-- End main options window

-	local frame = CreateFrame("Frame")
-	frame:SetFrameStrata("DIALOG")
+	local frame = CreateFrame("Frame", "PREditRaid")
+	frame:SetFrameStrata("HIGH")
 	frame:SetHeight(400)
 	frame:SetWidth(350)
 	frame:SetPoint("CENTER", 75, -25)
 	self:SkinFrame(frame)
 	frame:Hide()
 	frame.title:SetText("Add a raid group")
+	frame:SetScript("OnHide", function() PRButtonRaidCancel:Click() end)

 	button1:SetScript("OnClick", function()
 		frame:Show()
@@ -287,6 +289,8 @@ function PerfectRaid:CreateOptions()
 	edit1.label:SetJustifyH("RIGHT")
 	edit1.label:SetText("Name:")

+	frame:SetScript("OnShow", function() edit1:SetFocus() end)
+
 	local classes = {
 		"Druid",
 		"Hunter",
@@ -374,12 +378,12 @@ function PerfectRaid:CreateOptions()
 	boxes[18].label = "(Strict)"
 	boxes[18].value = "strict"

-	local button3 = CreateFrame("Button", nil, frame)
+	local button3 = CreateFrame("Button", "PRButtonRaidSave", frame)
 	self:SkinButton(button3)
 	button3.text:SetText("Save")
 	button3:SetPoint("CENTER", frame, "BOTTOM", -40, 25)

-	local button4 = CreateFrame("Button", nil, frame)
+	local button4 = CreateFrame("Button", "PRButtonRaidCancel", frame)
 	self:SkinButton(button4)
 	button4.text:SetText("Cancel")
 	button4:SetPoint("CENTER", frame, "BOTTOM", 40, 25)
@@ -406,6 +410,7 @@ function PerfectRaid:CreateOptions()
 		end
 		button4:Click()
 		scrollframe.update()
+		self:CreateRaidHeaders()
 	end)

 	button4:SetScript("OnClick", function()
@@ -445,6 +450,140 @@ function PerfectRaid:CreateOptions()
 		selected = nil
 		scrollframe.update()
 	end)
+
+	self:CreateBuffEditWindow()
 end

+function PerfectRaid:CreateBuffEditWindow()
+	local frame = CreateFrame("Frame", "PREditBuff")
+	frame:SetFrameStrata("HIGH")
+	frame:SetHeight(400)
+	frame:SetWidth(350)
+	frame:SetPoint("CENTER", 75, -25)
+	self:SkinFrame(frame)
+	frame.title:SetText("Edit Buff Notification")
+	frame:Hide()
+
+	local buffname = CreateFrame("EditBox", nil, frame, "InputBoxTemplate")
+	buffname:SetPoint("TOPLEFT", 95, -35)
+	buffname:SetWidth(200)
+	buffname:SetHeight(25)
+	buffname:SetAutoFocus(false)
+	buffname.label = buffname:CreateFontString(nil, nil, "GameFontHighlightSmall")
+	buffname.label:SetPoint("RIGHT", buffname, "LEFT", -10, 0)
+	buffname.label:SetJustifyH("RIGHT")
+	buffname.label:SetText("Buff Name:")
+
+	local groupbuff = CreateFrame("EditBox", nil, frame, "InputBoxTemplate")
+	groupbuff:SetPoint("TOPLEFT", buffname, "BOTTOMLEFT", 0, -5)
+	groupbuff:SetWidth(200)
+	groupbuff:SetHeight(25)
+	groupbuff:SetAutoFocus(false)
+	groupbuff.label = groupbuff:CreateFontString(nil, nil, "GameFontHighlightSmall")
+	groupbuff.label:SetPoint("RIGHT", groupbuff, "LEFT", -10, 0)
+	groupbuff.label:SetJustifyH("RIGHT")
+	groupbuff.label:SetText("Group Name:")
+
+	local disptext = CreateFrame("EditBox", nil, frame, "InputBoxTemplate")
+	disptext:SetPoint("TOPLEFT", groupbuff, "BOTTOMLEFT", 0, -5)
+	disptext:SetWidth(200)
+	disptext:SetHeight(25)
+	disptext:SetAutoFocus(false)
+	disptext.label = disptext:CreateFontString(nil, nil, "GameFontHighlightSmall")
+	disptext.label:SetPoint("RIGHT", disptext, "LEFT", -10, 0)
+	disptext.label:SetJustifyH("RIGHT")
+	disptext.label:SetText("Display Text:")
+
+	buffname:SetScript("OnTabPressed", function() groupbuff:SetFocus() end)
+	groupbuff:SetScript("OnTabPressed", function() disptext:SetFocus() end)
+	disptext:SetScript("OnTabPressed", function() buffname:SetFocus() end)
+
+	frame:SetScript("OnShow", function() buffname:SetFocus() end)
+
+	function makecheck(text, value)
+		local box = CreateFrame("CheckButton", "Buff"..text, frame, "UICheckButtonTemplate")
+		box.text = getglobal(box:GetName().."Text")
+		box.text:SetText(text)
+		return box
+	end
+
+	-- Create buff condition checkboxes.
+	local boxes = {}
+	boxes[1] = makecheck("Warrior", self.conditions.Warrior)
+	boxes[1]:SetPoint("TOPLEFT", disptext, "BOTTOMLEFT", -85, -5)
+	boxes[2] = makecheck("Rogue", self.conditions.Rogue)
+	boxes[2]:SetPoint("LEFT", boxes[1], "RIGHT", 80, 0)
+	boxes[3] = makecheck("Paladin", self.conditions.Paladin)
+	boxes[3]:SetPoint("LEFT", boxes[2], "RIGHT", 80, 0)
+
+	boxes[4] = makecheck("Priest", self.conditions.Priest)
+	boxes[4]:SetPoint("TOPLEFT", boxes[1], "BOTTOMLEFT", 0, -5)
+	boxes[5] = makecheck("Shaman", self.conditions.Shaman)
+	boxes[5]:SetPoint("LEFT", boxes[4], "RIGHT", 80, 0)
+	boxes[6] = makecheck("Druid", self.conditions.Druid)
+	boxes[6]:SetPoint("LEFT", boxes[5], "RIGHT", 80, 0)
+
+	boxes[7] = makecheck("Hunter", self.conditions.Hunter)
+	boxes[7]:SetPoint("TOPLEFT", boxes[4], "BOTTOMLEFT", 0, -5)
+	boxes[8] = makecheck("Mage", self.conditions.Mage)
+	boxes[8]:SetPoint("LEFT", boxes[7], "RIGHT", 80, 0)
+	boxes[9] = makecheck("Warlock", self.conditions.Warlock)
+	boxes[9]:SetPoint("LEFT", boxes[8], "RIGHT", 80, 0)
+
+	boxes[10] = makecheck("All", self.conditions.All)
+	boxes[10]:SetPoint("TOPLEFT", boxes[7], "BOTTOMLEFT", 0, -5)
+	boxes[11] = makecheck("Melee", self.conditions.Melee)
+	boxes[11]:SetPoint("LEFT", boxes[10], "RIGHT", 80, 0)
+	boxes[12] = makecheck("Range", self.conditions.Range)
+	boxes[12]:SetPoint("LEFT", boxes[11], "RIGHT", 80, 0)
+end

+PerfectRaid.conditions = {
+	Warrior = function(u)
+		local _,class = UnitClass(u)
+		return class == "WARRIOR"
+	end,
+	Rogue = function(u)
+		local _,class = UnitClass(u)
+		return class == "ROGUE"
+	end,
+	Paladin = function(u)
+		local _,class = UnitClass(u)
+		return class == "PALADIN"
+	end,
+	Priest = function(u)
+		local _,class = UnitClass(u)
+		return class == "PRIEST"
+	end,
+	Shaman = function(u)
+		local _,class = UnitClass(u)
+		return class == "SHAMAN"
+	end,
+	Druid = function(u)
+		local _,class = UnitClass(u)
+		return class == "DRUID"
+	end,
+	Warlock = function(u)
+		local _,class = UnitClass(u)
+		return class == "WARLOCKS"
+	end,
+	Mage = function(u)
+		local _,class = UnitClass(u)
+		return class == "MAGE"
+	end,
+	Hunter = function(u)
+		local _,class = UnitClass(u)
+		return class == "HUNTER"
+	end,
+	All = function(u)
+		return true
+	end,
+	Melee = function(u)
+		local _,class = UnitClass(u)
+		return class == "WARRIOR" or class == "ROGUE" or class == "PALADIN"
+	end,
+	Range = function(u)
+		local _,class = UnitClass(u)
+		return class == "PRIEST" or class == "WARLOCK" or class == "DRUID" or class == "MAGE" or class == "HUNTER" or class == "SHAMAN"
+	end,
+}
\ No newline at end of file