diff --git a/Localization.enUS.lua b/Localization.enUS.lua
new file mode 100644
index 0000000..3db9c96
--- /dev/null
+++ b/Localization.enUS.lua
@@ -0,0 +1,2 @@
+PerfectRaidLocals = {
+}
diff --git a/PerfectRaid.lua b/PerfectRaid.lua
index a84af93..c3f5507 100644
--- a/PerfectRaid.lua
+++ b/PerfectRaid.lua
@@ -18,7 +18,7 @@
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHsqsANTABILITY AND FITNESS FOR
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
@@ -31,29 +31,19 @@
local frames = {}
local unavail = {}
-local aggro = {}
-local L
-local utils = DongleStub("DongleUtils")
+local L = PerfectRaidLocals
PerfectRaid = DongleStub("Dongle"):New("PerfectRaid")
-PerfectRaid.frames = frames
function PerfectRaid:Initialize()
self.defaults = {
profile = {
- headers = {},
- buffs = {},
- positions = {},
- simple = {
- voffset = 15,
- titles = true,
- },
- mode = "advanced",
+ headers = {
+ },
},
}
self.db = self:InitializeDB("PerfectRaidDB", self.defaults)
- L = self.LOCALS
if not ClickCastFrames then
ClickCastFrames = {}
@@ -72,19 +62,6 @@ function PerfectRaid:Enable()
self:RegisterEvent("UNIT_MAXRAGE", "UNIT_MAXMANA")
self:RegisterEvent("UNIT_MAXENERGY", "UNIT_MAXMANA")
self:RegisterEvent("UNIT_MAXFOCUS", "UNIT_MAXMANA")
- self:RegisterEvent("UNIT_AURA")
- self:RegisterEvent("RAID_TARGET_UPDATE")
-
- local mode = self.db.profile.mode
- if mode == "singleclass" then
- self:CreateSingleColumn()
- elseif mode == "singlegroup" then
- self:CreateSingleColumn("group")
- elseif mode == "double" then
- self:CreateDoubleColumn()
- elseif mode == "advanced" then
- self:CreateRaidHeaders()
- end
-- Register slash command
self.cmd = self:InitializeSlashCommand("PerfectRaid Options", "PERFECTRAID", "praid", "perfectraid")
@@ -94,97 +71,12 @@ function PerfectRaid:Enable()
self:RAID_ROSTER_UPDATE()
end
-function PerfectRaid:CreateSingleColumn(sort)
- self.column = self.column or {}
- local column = self.column
-
- local classes = {"Warrior","Priest","Druid","Shaman","Paladin","Rogue","Mage","Warlock","Hunter"}
- local voffset = self.db.profile.simple.voffset * -1
- local titles = self.db.profile.simple.titles
-
- if sort == "group" then
- classes = {"Group 1","Group 2","Group 3","Group 4","Group 5","Group 6","Group 7","Group8"}
- end
-
- for i=1,#classes do
- local filter
- if sort == "group" then
- filter = string.sub(classes[i], -1, -1)
- else
- filter = string.upper(classes[i])
- end
- local title = titles and classes[i] or nil
-
- if not column[i] then
- column[i] = self:CreateRaidFrame("PRColumn"..i, title, filter, nil, column[1])
- column[i]:Show()
- else
- self:ChangeRaidFrame("PRColumn"..i, title, filter, nil, column[1])
- column[i]:Show()
- column[i]:ClearAllPoints()
- end
- end
-
- self:RestorePosition("PRColumn1")
-
- for i=2,#classes do
- self.column[i].locked = true
- self.column[i]:SetPoint("TOP", self.column[i-1], "BOTTOM", 0, voffset)
- end
-
- if GetNumRaidMembers() <= 0 then
- for i,frame in ipairs(column) do
- frame:Hide()
- end
- end
-end
-
-function PerfectRaid:CreateDoubleColumn()
- self.column = self.column or {}
- local column = self.column
-
- local voffset = self.db.profile.simple.voffset * -1
- local titles = self.db.profile.simple.titles
- local classes = {"Group 1","Group 2","Group 3","Group 4","Group 5","Group 6","Group 7","Group8"}
-
- for i=1,#classes do
- local filter = string.sub(classes[i], -1, -1)
- local title = titles and classes[i] or nil
-
- if not column[i] then
- column[i] = self:CreateRaidFrame("PRColumn"..i, title, filter, nil, column[1])
- column[i]:Show()
- else
- self:ChangeRaidFrame("PRColumn"..i, title, filter, nil, column[1])
- column[i]:Show()
- column[i]:ClearAllPoints()
- end
- end
-
- self:RestorePosition("PRColumn1")
-
- for i=2,4 do
- column[i].locked = true
- column[i]:SetPoint("TOP", column[i-1], "BOTTOM", 0, voffset)
- end
- column[5]:SetPoint("TOPLEFT", column[1], "TOPRIGHT", 50, 0)
- for i=6,8 do
- column[i].locked = true
- column[i]:SetPoint("TOP", column[i-1], "BOTTOM", 0, voffset)
- end
- if GetNumRaidMembers() <= 0 then
- for i,frame in ipairs(column) do
- frame:Hide()
- end
- end
-end
-
function PerfectRaid:CreateRaidHeaders()
local list = self.db.profile.headers
self.headers = self.headers or {}
local inraid = GetNumRaidMembers() > 0
-
+ self:Print("Checking", #list, "headers")
for i=1,#list do
local entry = list[i]
local name = "PRHeader"..i
@@ -291,31 +183,6 @@ function PerfectRaid:CreateRaidFrame(name, title, filter, strict, dragparent)
return frame
end
-function PerfectRaid:CreatePartyFrame()
- -- Create the player frame first, in case we need it
-
- local frame = CreateFrame("Frame", "PRaidPartyHeader", UIParent, "SecurePartyHeaderTemplate")
- frame:SetAttribute("point", "TOP")
- frame:SetAttribute("template", "SecureUnitButtonTemplate")
- frame:SetAttribute("templateType", "Button")
- frame:SetAttribute("nameList", UnitName("player"))
- frame:SetAttribute("dragparent", frame)
- frame:SetAttribute("yOffset", -2)
-
- frame.initialConfigFunction = PerfectRaid.ConfigureButton
- frame:SetPoint("CENTER", 0, 0)
- frame:SetMovable(true)
- frame:SetClampedToScreen(true)
-
- local frame = CreateFrame("Button", "PRaidPlayerFrame", PRaidPartyHeader, "SecureUnitButtonTemplate")
- PerfectRaid.ConfigureButton(frame)
- frame:SetAttribute("unit", "player")
- frame:SetAttribute("dragparent", PRaidPartyHeader)
- frame:SetPoint("BOTTOM", PRaidPartyHeader, "TOP", 0, 2)
-
- PRaidPartyHeader:Show()
-end
-
function PerfectRaid:GetColoredName(unit)
local class = select(2, UnitClass(unit)) or "WARRIOR"
local color = RAID_CLASS_COLORS[class]
@@ -326,31 +193,20 @@ function PerfectRaid:UNIT_HEALTH(event, unit)
if not frames[unit] then return end
local health = UnitHealth(unit)
local max = UnitHealthMax(unit)
+
-- Hack to fix api issue
if max < health then max = health end
local deficit = max - health
local perc = UnitHealthMax(unit) / health
local class = select(2, UnitClass(unit))
local perc = (health/max) or 0
- local aggro = aggro[unit] >= 15
- if aggro then
- if deficit > 999 then
- deficit = string.format("|cFFFF1111%.1fk|r", deficit / 1000)
- elseif deficit == 0 then
- deficit = "|cFFFF1111Aggro|r"
- else
- deficit = string.format("|cFFFF1111%d|r", deficit)
- end
- else
- if deficit > 999 then
- deficit = string.format("%.1fk", deficit / 1000)
- elseif deficit == 0 then
- deficit = ""
- end
+ if deficit > 999 then
+ deficit = string.format("%.1fk", deficit / 1000)
+ elseif deficit == 0 then
+ deficit = ""
end
-
if UnitIsDead(unit) or UnitIsGhost(unit) or not UnitIsConnected(unit) then
local status
@@ -375,15 +231,10 @@ function PerfectRaid:UNIT_HEALTH(event, unit)
else
if unavail[unit] then
for frame in pairs(frames[unit]) do
- local color = frame.classcolor
--- frame.healthbar:SetStatusBarColor(color.r, color.g, color.b)
- frame.healthbar:SetStatusBarColor(utils.GetHPSeverity(perc))
frame.healthbar:SetMinMaxValues(0, UnitHealthMax(unit))
frame.healthbar:SetValue(UnitHealth(unit))
- frame:SetBackdropBorderColor(color.r, color.g, color.b)
local color = frame.manacolor
- frame.manabar:SetStatusBarColor(color.r, color.g, color.b)
frame.manabar:SetMinMaxValues(0, UnitManaMax(unit))
frame.manabar:SetValue(UnitMana(unit))
@@ -395,7 +246,6 @@ function PerfectRaid:UNIT_HEALTH(event, unit)
for frame in pairs(frames[unit]) do
local class = select(2, UnitClass(unit))
frame.healthbar:SetValue(health)
- frame.healthbar:SetStatusBarColor(utils.GetHPSeverity(perc))
frame.status:SetText(deficit)
end
end
@@ -463,12 +313,9 @@ local function OnShow(frame)
frames[unit] = frames[unit] or {}
frames[unit][frame] = true
- aggro[unit] = 0
self:UNIT_HEALTH(nil, unit)
self:UNIT_MANA(nil, unit)
- self:UNIT_AURA(nil, unit)
- self:RAID_TARGET_UPDATE(nil, unit)
end
local function OnHide(frame)
@@ -491,12 +338,14 @@ local function OnAttributeChanged(frame, name, value)
local visible = nil
for i=1,num do
local button = parent:GetAttribute("child"..i)
- if button:IsShown() then visible = true end
+ if button and button:IsShown() then visible = true end
end
- if not visible then
- parent.title:Hide()
- else
- parent.title:Show()
+ if parent.title then
+ if not visible then
+ parent.title:Hide()
+ else
+ parent.title:Show()
+ end
end
end
end
@@ -592,247 +441,212 @@ function PerfectRaid:RAID_ROSTER_UPDATE()
if self.moving then
self.moving:StopMovingOrSizing()
end
-
- -- Lets check for party leader
- for unit in pairs(frames) do
- local leader = UnitIsPartyLeader(unit)
- local looter = select(2, GetLootMethod()) == unit
- if leader and looter then looter = false end
-
- for frame in pairs(frames[unit]) do
- if leader then
- frame.leadericon:SetWidth(16)
- else
- frame.leadericon:SetWidth(0.1)
- end
- if looter then
- frame.looticon:SetWidth(16)
- else
- frame.looticon:SetWidth(0.1)
- end
- end
- end
end
-local buffcache = {}
-local work = {}
-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 i=1,40 do
- local name,rank,texture,count = UnitBuff(unit, i)
- if not name then break 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
+function PerfectRaid:ShowOptions()
+ if not PROptions then
+ self:CreateOptions()
end
+ if PROptions:IsVisible() then
+ PROptions:Show()
+ else
+ PROptions:Hide()
+ end
+end
- for k,v in pairs(work) do work[k] = nil end
+local menuItems = {}
+function PerfectRaid:CreateOptions()
+ local frame = self:CreateFrame("PROptions", UIParent)
+ frame:SetHeight(250)
+ frame:SetWidth(400)
+ frame:SetPoint("CENTER", 0, 0)
- local buffs = self.db.profile.buffs
- for i,entry in ipairs(buffs) do
- local checkcond = false
- local num = buffcache[entry.buffname]
- if entry.missing then
- if not buffcache[entry.buffname] and not buffcache[entry.groupbuff or "nil"] then
- checkcond = true
- end
- else
- if buffcache[entry.buffname] or buffcache[entry.groupbuff or "nil"] then
- checkcond = true
- end
- end
-
- local conds = self.conditions
- if checkcond then
- for i,name in pairs(entry.cond) do
- if conds[name] and conds[name](unit) then
- if num and num > 1 then
- table.insert(work, entry.colortext .. "(" .. num .. ")")
- else
- table.insert(work, entry.colortext)
- end
- end
- end
- end
- end
+ local frame = self:CreateFrame("PROptionsMenu", PROptions)
+ frame:SetWidth(150)
+ frame:SetPoint("TOPRIGHT", PROptions, "TOPLEFT", 0, 0)
+ frame:SetPoint("BOTTOMRIGHT", PROptions, "BOTTOMLEFT", 0, 0)
- local status = strjoin(" ", unpack(work))
- for frame in pairs(frames[unit]) do
- frame.aura:SetText(status)
- end
+ local frame = CreateFrame("Frame", "PROptions_General", PROptions)
+ self:AddMenuItem("General Options", 1, PROptions_General)
+
+ self:CreateFrameEditor()
end
-function PerfectRaid:RAID_TARGET_UPDATE(event, unit)
- if not frames[unit] then return end
- local index = GetRaidTargetIndex(unit)
- if not index then
- for frame in pairs(frames[unit]) do
- frame.raidicon:SetWidth(0.1)
- end
- else
- for frame in pairs(frames[unit]) do
- SetRaidTargetIconTexture(frame.raidicon, index)
- frame.raidicon:SetWidth(16)
- end
- end
+function PerfectRaid:CreateFrame(name, parent)
+ local frame = CreateFrame("Frame", name, parent)
+ frame:SetBackdrop(GameTooltip:GetBackdrop())
+ frame:SetBackdropColor(0,0,0)
+ return frame
end
-function PerfectRaid:ShowOptions()
- if not PROptions then
- self:CreateOptions()
- end
+local function sortFunction(a,b)
+ return a.order < b.order
+end
- if PROptions:IsVisible() then
- PROptions:Hide()
- else
- PROptions:Show()
+local OnClick = function(button)
+ if PROptions.current then
+ PROptions.current:Hide()
+ PROptions.lastButton:SetChecked(nil)
+ end
+ button.frame:SetAllPoints(PROptions)
+ button.frame:Show()
+ PROptions.current = button.frame
+ PROptions.lastButton = button
+end
+
+local buttons = {}
+function PerfectRaid:AddMenuItem(name, order, frame)
+ local num = #menuItems + 1
+ local button = CreateFrame("CheckButton", "PRMenuItem"..num, PROptionsMenu)
+ button:SetHeight(20)
+ button:SetWidth(140)
+ button:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+ button:SetCheckedTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+ button:SetScript("OnClick", OnClick)
+
+ local texture = button:CreateTexture(nil, "BACKGROUND")
+ texture:SetTexture(0,0,0,0.8)
+ texture:SetAllPoints()
+
+ local label = button:CreateFontString(nil, "OVERLAY")
+ label:SetFontObject(GameFontNormalSmall)
+ label:SetPoint("CENTER")
+ label:SetJustifyH("CENTER")
+ label:SetText(name)
+ button.label = label
+
+ buttons[num] = button
+
+ local entry = {}
+ entry.name = name
+ entry.order = order
+ entry.frame = frame
+
+ table.insert(menuItems, entry)
+
+ -- Re-order the menu items
+ table.sort(menuItems, sortFunction)
+ for idx,entry in ipairs(menuItems) do
+ local button = buttons[idx]
+ button.label:SetText(entry.name)
+ button.frame = entry.frame
+ end
+
+ PRMenuItem1:SetPoint("TOP", 0, -7)
+ for i=2,#menuItems do
+ local button = buttons[i]
+ button:SetPoint("TOP", buttons[i-1], "BOTTOM", 0, -2)
end
end
-local class = select(2, UnitClass("player"))
-local spells = {
- DRUID = "Healing Touch",
- SHAMAN = "Healing Wave",
- PRIEST = "Lesser Heal",
- PALADIN = "Holy Light",
-}
-
-local rangespell = spells[class]
-
-local victims = {}
-local targets = {}
-local flashing = {}
-
-if rangespell then
- local elapsed = 0
- function PerfectRaid.OnUpdate(frame, arg1)
- elapsed = elapsed + arg1
- if elapsed >= 0.5 then
- if rangespell then
- for unit,tbl in pairs(frames) do
- local range = IsSpellInRange(rangespell, unit) == 1
- local alpha = range and 1.0 or 0.3
- for frame in pairs(tbl) do
- if not flashing[frame] then
- frame:SetAlpha(alpha)
- end
- end
- end
- end
-
- -- Aggro check
- for unit,tbl in pairs(frames) do
- if not targets[unit] then
- targets[unit] = unit.."target"
- victims[unit] = unit.."targettarget"
- aggro[unit] = 0
- end
-
- local target = targets[unit]
- local victim = victims[unit]
- if UnitIsUnit(victim, unit) and UnitCanAttack(unit, target) then
- -- unit is being targeted by a hostile mob
- if aggro[unit] < 20 then
- local val = aggro[unit]
- if val >= 5 and val <= 10 then
- PerfectRaid:UNIT_HEALTH(nil, unit)
- end
- aggro[unit] = val + 10
- end
- end
-
- -- Aggro decay (thanks BanzaiLib)
- if aggro[unit] >= 5 then
- aggro[unit] = aggro[unit] - 5
- end
-
- if aggro[unit] >= 15 then
- showaggro(unit)
- end
-
- local name = UnitName(unit)
- end
+function PerfectRaid:CreateFrameEditor()
+ local frame = CreateFrame("Frame", "PROptions_Frames")
+ self:AddMenuItem("Frame Editor", 2, PROptions_Frames)
- elapsed = 0
- end
+ frame.entries = {}
+
+ local NUM_ENTRIES = 9
+ local selected,Entry_OnClick
+
+ for i=1,NUM_ENTRIES do
+ local button = CreateFrame("CheckButton", nil, frame)
+ button:SetHeight(20)
+ frame.entries[i] = button
+
+ button.idx = i
+ button.desc = button:CreateFontString(nil, "OVERLAY")
+ button.desc:SetFontObject(GameFontNormalSmall)
+ button.desc:SetPoint("LEFT", 0, 0)
+ button.desc:SetText("Description: " .. i)
+ button:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+ button:SetCheckedTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+ button:SetScript("OnClick", Entry_OnClick)
end
+
+ frame.entries[1]:SetPoint("TOPLEFT", 8, -5)
+ frame.entries[1]:SetPoint("TOPRIGHT", -28, -5)
- local frame = CreateFrame("Frame", "PRUpdateFrame")
- frame:SetScript("OnUpdate", PerfectRaid.OnUpdate)
-end
+ for i=2,NUM_ENTRIES do
+ frame.entries[i]:SetPoint("TOPLEFT", frame.entries[i-1], "BOTTOMLEFT", 0, -2)
+ frame.entries[i]:SetPoint("TOPRIGHT", frame.entries[i-1], "BOTTOMRIGHT", 0, -2)
+ end
-function showaggro(unit)
- if true then return end
- for frame in pairs(frames[unit]) do
- local name = frame:GetName()
- local texture = frame.healthbar.aggro
- if not texture then
- local bar = frame.healthbar
- texture = frame.healthbar:CreateTexture(name.."Aggro", "ARTWORK")
- texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
- texture:SetAllPoints(bar)
- frame.healthbar.aggro = texture
- end
- texture:SetVertexColor(1,0,0)
- UIFrameFlash(texture, 0.4, 0.4, 2, nil, 0.1, 0.1)
+ local OnEnter = function(button)
+ button:SetBackdropBorderColor(1,1,1)
end
-end
-local textures = {}
-local handlers = {}
-function flashbar(frame, length, wait)
- if not textures[frame] then
- texture = frame:CreateTexture(nil, "ARTWORK")
- texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
- texture:SetPoint("TOPLEFT", 0, 0)
- texture:SetPoint("BOTTOMLEFT", 0, 0)
- textures[frame] = texture
+ local OnLeave = function(button)
+ button:SetBackdropBorderColor(0.3, 0.3, 0.3)
end
-
- frame.fadeLength = length or 0.4
- frame.fadeTime = 0
- frame.waitLength = wait or 0.1
- frame.waitTime = 0
- frame.waitHalf = true
-
- if not handlers[frame] then
- local function handler(frame, arg1)
- frame.fadeTime = frame.fadeTime + arg1
- local half = frame.fadeLength / 2
- if frame.fadeTime < half then
- -- We're fading out
- local alpha = 1 - (frame.fadeTime / half)
- frame:SetAlpha(alpha)
- elseif frame.fadeTime <= frame.fadeLength then
- if frame.waitHalf then
- frame.fadeTime = frame.fadeTime - arg1
- frame.waitTime = frame.waitTime + arg1
- if frame.waitTime >= frame.waitLength then
- frame.waitHalf = false
- end
- else
- local alpha = (frame.fadeTime - half) / half
- frame:SetAlpha(alpha)
- end
- else
- frame.waitTime = frame.waitTime + arg1
- if frame.waitTime >= frame.waitLength then
- frame.fadeTime = 0
- frame.waitTime = 0
- frame.waitHalf = true
- end
- end
+
+ local createButton = function(name)
+ local button = CreateFrame("Button", "PROptions_Frames_"..name, PROptions_Frames)
+ button:SetHeight(30)
+ button:SetWidth(80)
+ button:SetBackdrop(GameTooltip:GetBackdrop())
+ button:SetBackdropColor(0,0,0)
+ button:SetBackdropBorderColor(0.3, 0.3, 0.3)
+ button:SetScript("OnEnter", OnEnter)
+ button:SetScript("OnLeave", OnLeave)
+
+ button.label = button:CreateFontString(nil, "ARTWORK")
+ button.label:SetFontObject(GameFontNormalSmall)
+ button.label:SetPoint("CENTER")
+ button.label:SetText(name)
+ button.enableText = name
+ return button
+ end
+
+ local button_new = createButton("New")
+ button_new:SetPoint("BOTTOMLEFT", 8, 5)
+
+ local button_edit = createButton("Edit")
+ button_edit:SetPoint("LEFT", button_new, "RIGHT", 5, 0)
+
+ local button_delete = createButton("Delete")
+ button_delete:SetPoint("LEFT", button_edit, "RIGHT", 5, 0)
+
+ PROptions_Frames:SetScript("OnShow", function(frame)
+ for idx,entry in ipairs(frame.entries) do
+ entry:SetChecked(nil)
+ end
+ selected = nil
+ button_edit:Disable()
+ button_delete:Disable()
+ end)
+
+ PROptions_Frames:GetScript("OnShow")(PROptions_Frames)
+
+ Entry_OnClick = function(button)
+ if selected then
+ frame.entries[selected]:SetChecked(nil)
end
- handlers[frame] = handler
+ button:SetChecked(true)
+ selected = button.idx
+ button_edit:Enable()
+ button_delete:Enable()
end
- frame:SetScript("OnUpdate", handlers[frame])
-end
+ for idx,button in ipairs(frame.entries) do
+ button:SetScript("OnClick", Entry_OnClick)
+ end
---flashbar(PlayerFrame, 2, 1)
\ No newline at end of file
+ -- Create the scroll frame
+ local scrollframe = CreateFrame("ScrollFrame", "PROptions_Frames_Scroll", PROptions_Frames, "FauxScrollFrameTemplate")
+ scrollframe:SetPoint("TOPLEFT", frame.entries[1], "TOPLEFT", 0, 0)
+ scrollframe:SetPoint("BOTTOMRIGHT", frame.entries[NUM_ENTRIES], "BOTTOMRIGHT", 0, 0)
+
+ local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
+ texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
+ texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 14, 0)
+ texture:SetPoint("BOTTOMRIGHT", 23, 0)
+ texture:SetVertexColor(0,0,0,0.3)
+
+ local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
+ texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
+ texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, 0)
+ texture:SetPoint("BOTTOMRIGHT", 14,0)
+ texture:SetVertexColor(0,0,0,0.3)
+end
+
+PerfectRaid:CreateOptions()
diff --git a/PerfectRaid.toc b/PerfectRaid.toc
index 1ba7880..27b7e58 100644
--- a/PerfectRaid.toc
+++ b/PerfectRaid.toc
@@ -4,10 +4,9 @@
## Notes: Simply powerful raid and party frames
## SavedVariables: PerfectRaidDB
## OptionalDeps: Dongle
-
Dongle.lua
DongleUtils.lua
PerfectRaid.xml
PerfectRaid.lua
-PerfectRaidOptions.lua
-Localization.en.lua
+
+
diff --git a/PerfectRaid_Aggro.lua b/PerfectRaid_Aggro.lua
new file mode 100644
index 0000000..41794d1
--- /dev/null
+++ b/PerfectRaid_Aggro.lua
@@ -0,0 +1,172 @@
+--[[-------------------------------------------------------------------------
+ Copyright (c) 2006, Jim Whitehead II <cladhaire@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of PerfectRaid nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------]]
+
+local class = select(2, UnitClass("player"))
+local spells = {
+ DRUID = "Healing Touch",
+ SHAMAN = "Healing Wave",
+ PRIEST = "Lesser Heal",
+ PALADIN = "Holy Light",
+}
+
+local rangespell = spells[class]
+
+local victims = {}
+local targets = {}
+local flashing = {}
+
+if rangespell then
+ local elapsed = 0
+ function PerfectRaid.OnUpdate(frame, arg1)
+ elapsed = elapsed + arg1
+ if elapsed >= 0.5 then
+ if rangespell then
+ for unit,tbl in pairs(frames) do
+ local range = IsSpellInRange(rangespell, unit) == 1
+ local alpha = range and 1.0 or 0.3
+ for frame in pairs(tbl) do
+ if not flashing[frame] then
+ frame:SetAlpha(alpha)
+ end
+ end
+ end
+ end
+
+ -- Aggro check
+ for unit,tbl in pairs(frames) do
+ if not targets[unit] then
+ targets[unit] = unit.."target"
+ victims[unit] = unit.."targettarget"
+ aggro[unit] = 0
+ end
+
+ local target = targets[unit]
+ local victim = victims[unit]
+ if UnitIsUnit(victim, unit) and UnitCanAttack(unit, target) then
+ -- unit is being targeted by a hostile mob
+ if aggro[unit] < 20 then
+ local val = aggro[unit]
+ if val >= 5 and val <= 10 then
+ PerfectRaid:UNIT_HEALTH(nil, unit)
+ end
+ aggro[unit] = val + 10
+ end
+ end
+
+ -- Aggro decay (thanks BanzaiLib)
+ if aggro[unit] >= 5 then
+ aggro[unit] = aggro[unit] - 5
+ end
+
+ if aggro[unit] >= 15 then
+ showaggro(unit)
+ end
+
+ local name = UnitName(unit)
+ end
+
+ elapsed = 0
+ end
+ end
+
+ local frame = CreateFrame("Frame", "PRUpdateFrame")
+ frame:SetScript("OnUpdate", PerfectRaid.OnUpdate)
+end
+
+function showaggro(unit)
+ if true then return end
+ for frame in pairs(frames[unit]) do
+ local name = frame:GetName()
+ local texture = frame.healthbar.aggro
+ if not texture then
+ local bar = frame.healthbar
+ texture = frame.healthbar:CreateTexture(name.."Aggro", "ARTWORK")
+ texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
+ texture:SetAllPoints(bar)
+ frame.healthbar.aggro = texture
+ end
+ texture:SetVertexColor(1,0,0)
+ UIFrameFlash(texture, 0.4, 0.4, 2, nil, 0.1, 0.1)
+ end
+end
+
+local textures = {}
+local handlers = {}
+function flashbar(frame, length, wait)
+ if not textures[frame] then
+ texture = frame:CreateTexture(nil, "ARTWORK")
+ texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
+ texture:SetPoint("TOPLEFT", 0, 0)
+ texture:SetPoint("BOTTOMLEFT", 0, 0)
+ textures[frame] = texture
+ end
+
+ frame.fadeLength = length or 0.4
+ frame.fadeTime = 0
+ frame.waitLength = wait or 0.1
+ frame.waitTime = 0
+ frame.waitHalf = true
+
+ if not handlers[frame] then
+ local function handler(frame, arg1)
+ frame.fadeTime = frame.fadeTime + arg1
+ local half = frame.fadeLength / 2
+ if frame.fadeTime < half then
+ -- We're fading out
+ local alpha = 1 - (frame.fadeTime / half)
+ frame:SetAlpha(alpha)
+ elseif frame.fadeTime <= frame.fadeLength then
+ if frame.waitHalf then
+ frame.fadeTime = frame.fadeTime - arg1
+ frame.waitTime = frame.waitTime + arg1
+ if frame.waitTime >= frame.waitLength then
+ frame.waitHalf = false
+ end
+ else
+ local alpha = (frame.fadeTime - half) / half
+ frame:SetAlpha(alpha)
+ end
+ else
+ frame.waitTime = frame.waitTime + arg1
+ if frame.waitTime >= frame.waitLength then
+ frame.fadeTime = 0
+ frame.waitTime = 0
+ frame.waitHalf = true
+ end
+ end
+ end
+ handlers[frame] = handler
+ end
+
+ frame:SetScript("OnUpdate", handlers[frame])
+end
+
+--flashbar(PlayerFrame, 2, 1)
\ No newline at end of file
diff --git a/PerfectRaid_Buffs.lua b/PerfectRaid_Buffs.lua
new file mode 100644
index 0000000..24112f3
--- /dev/null
+++ b/PerfectRaid_Buffs.lua
@@ -0,0 +1,84 @@
+--[[-------------------------------------------------------------------------
+ Copyright (c) 2006, Jim Whitehead II <cladhaire@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of PerfectRaid nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------]]
+
+local buffcache = {}
+local work = {}
+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 i=1,40 do
+ local name,rank,texture,count = UnitBuff(unit, i)
+ if not name then break 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
+
+ for k,v in pairs(work) do work[k] = nil end
+
+ local buffs = self.db.profile.buffs
+ for i,entry in ipairs(buffs) do
+ local checkcond = false
+ local num = buffcache[entry.buffname]
+ if entry.missing then
+ if not buffcache[entry.buffname] and not buffcache[entry.groupbuff or "nil"] then
+ checkcond = true
+ end
+ else
+ if buffcache[entry.buffname] or buffcache[entry.groupbuff or "nil"] then
+ checkcond = true
+ end
+ end
+
+ local conds = self.conditions
+ if checkcond then
+ for i,name in pairs(entry.cond) do
+ if conds[name] and conds[name](unit) then
+ if num and num > 1 then
+ table.insert(work, entry.colortext .. "(" .. num .. ")")
+ else
+ table.insert(work, entry.colortext)
+ end
+ end
+ end
+ end
+ end
+
+ local status = strjoin(" ", unpack(work))
+ for frame in pairs(frames[unit]) do
+ frame.aura:SetText(status)
+ end
+end
diff --git a/PerfectRaid_Range.lua b/PerfectRaid_Range.lua
new file mode 100644
index 0000000..41794d1
--- /dev/null
+++ b/PerfectRaid_Range.lua
@@ -0,0 +1,172 @@
+--[[-------------------------------------------------------------------------
+ Copyright (c) 2006, Jim Whitehead II <cladhaire@gmail.com>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of PerfectRaid nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------]]
+
+local class = select(2, UnitClass("player"))
+local spells = {
+ DRUID = "Healing Touch",
+ SHAMAN = "Healing Wave",
+ PRIEST = "Lesser Heal",
+ PALADIN = "Holy Light",
+}
+
+local rangespell = spells[class]
+
+local victims = {}
+local targets = {}
+local flashing = {}
+
+if rangespell then
+ local elapsed = 0
+ function PerfectRaid.OnUpdate(frame, arg1)
+ elapsed = elapsed + arg1
+ if elapsed >= 0.5 then
+ if rangespell then
+ for unit,tbl in pairs(frames) do
+ local range = IsSpellInRange(rangespell, unit) == 1
+ local alpha = range and 1.0 or 0.3
+ for frame in pairs(tbl) do
+ if not flashing[frame] then
+ frame:SetAlpha(alpha)
+ end
+ end
+ end
+ end
+
+ -- Aggro check
+ for unit,tbl in pairs(frames) do
+ if not targets[unit] then
+ targets[unit] = unit.."target"
+ victims[unit] = unit.."targettarget"
+ aggro[unit] = 0
+ end
+
+ local target = targets[unit]
+ local victim = victims[unit]
+ if UnitIsUnit(victim, unit) and UnitCanAttack(unit, target) then
+ -- unit is being targeted by a hostile mob
+ if aggro[unit] < 20 then
+ local val = aggro[unit]
+ if val >= 5 and val <= 10 then
+ PerfectRaid:UNIT_HEALTH(nil, unit)
+ end
+ aggro[unit] = val + 10
+ end
+ end
+
+ -- Aggro decay (thanks BanzaiLib)
+ if aggro[unit] >= 5 then
+ aggro[unit] = aggro[unit] - 5
+ end
+
+ if aggro[unit] >= 15 then
+ showaggro(unit)
+ end
+
+ local name = UnitName(unit)
+ end
+
+ elapsed = 0
+ end
+ end
+
+ local frame = CreateFrame("Frame", "PRUpdateFrame")
+ frame:SetScript("OnUpdate", PerfectRaid.OnUpdate)
+end
+
+function showaggro(unit)
+ if true then return end
+ for frame in pairs(frames[unit]) do
+ local name = frame:GetName()
+ local texture = frame.healthbar.aggro
+ if not texture then
+ local bar = frame.healthbar
+ texture = frame.healthbar:CreateTexture(name.."Aggro", "ARTWORK")
+ texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
+ texture:SetAllPoints(bar)
+ frame.healthbar.aggro = texture
+ end
+ texture:SetVertexColor(1,0,0)
+ UIFrameFlash(texture, 0.4, 0.4, 2, nil, 0.1, 0.1)
+ end
+end
+
+local textures = {}
+local handlers = {}
+function flashbar(frame, length, wait)
+ if not textures[frame] then
+ texture = frame:CreateTexture(nil, "ARTWORK")
+ texture:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\smooth")
+ texture:SetPoint("TOPLEFT", 0, 0)
+ texture:SetPoint("BOTTOMLEFT", 0, 0)
+ textures[frame] = texture
+ end
+
+ frame.fadeLength = length or 0.4
+ frame.fadeTime = 0
+ frame.waitLength = wait or 0.1
+ frame.waitTime = 0
+ frame.waitHalf = true
+
+ if not handlers[frame] then
+ local function handler(frame, arg1)
+ frame.fadeTime = frame.fadeTime + arg1
+ local half = frame.fadeLength / 2
+ if frame.fadeTime < half then
+ -- We're fading out
+ local alpha = 1 - (frame.fadeTime / half)
+ frame:SetAlpha(alpha)
+ elseif frame.fadeTime <= frame.fadeLength then
+ if frame.waitHalf then
+ frame.fadeTime = frame.fadeTime - arg1
+ frame.waitTime = frame.waitTime + arg1
+ if frame.waitTime >= frame.waitLength then
+ frame.waitHalf = false
+ end
+ else
+ local alpha = (frame.fadeTime - half) / half
+ frame:SetAlpha(alpha)
+ end
+ else
+ frame.waitTime = frame.waitTime + arg1
+ if frame.waitTime >= frame.waitLength then
+ frame.fadeTime = 0
+ frame.waitTime = 0
+ frame.waitHalf = true
+ end
+ end
+ end
+ handlers[frame] = handler
+ end
+
+ frame:SetScript("OnUpdate", handlers[frame])
+end
+
+--flashbar(PlayerFrame, 2, 1)
\ No newline at end of file