vanilla-wow-addons – Rev 1
?pathlinks?
local XPerl_Raid_Events = {}
local RaidGroupCounts = {0,0,0,0,0,0,0,0,0}
local FrameArray = {}
local PulloutFrameArray = {}
local perlSetupDone = nil
local ResArray = {}
local MovingMember = nil
local RosterUpdate = nil
local RaidPositions = {}
local oldRaidFrameDropDown_Initialize
XPERL_RAIDGRP_PREFIX = "XPerl_Raid_Grp"
XPERL_RAIDMEMBER_PREFIX = "XPerl_raid"
local CELL_MOTION_SPEED = 0.8 -- Motion offset mulitplied by this per frame (TODO, make this time based)
-- Hold some raid roster information (AFK, DND etc.)
-- Is also stored between sessions to maintain timers and flags
XPerl_Roster = {}
local Last_Roster = {}
-- Uses some variables from FrameXML\RaidFrame.lua:
-- MAX_RAID_MEMBERS = 40
-- NUM_RAID_GROUPS = 8
-- MEMBERS_PER_RAID_GROUP = 5
-- This array will be built up on the fly whenever we pick up a localized class name that we don't already have.
-- The UnitClass function returns both english and localized versions, so it won't matter where the mod is run.
local ClassNames = {}
----------------------
-- Loading Function --
----------------------
-- XPerl_Raid_OnLoad
function XPerl_Raid_OnLoad()
this:RegisterEvent("PLAYER_ENTERING_WORLD")
this:RegisterEvent("PLAYER_LEAVING_WORLD")
this:RegisterEvent("VARIABLES_LOADED")
this:RegisterEvent("RAID_ROSTER_UPDATE")
this:RegisterEvent("ADDON_LOADED")
this.time = 0
this.Array = {}
end
-- GetRaidGroup
local function GetRaidGroup(num, createIfAbsent)
local frame = getglobal(XPERL_RAIDGRP_PREFIX..num)
if (not frame and createIfAbsent) then
frame = CreateFrame("Frame", XPERL_RAIDGRP_PREFIX..num, XPerl_Raid_Frame, "XPerl_Raid_TitleFrameTemplate")
frame:SetScale(XPerlConfig.Scale_Raid)
frame = getglobal(XPERL_RAIDGRP_PREFIX..num.."_NameFrame_NameBarText")
frame:SetText("Group "..num)
end
return frame
end
-- Setup1RaidFrame
local function Setup1RaidFrame(frame)
local frameStats = getglobal(frame:GetName().."_StatsFrame")
local frameMana = getglobal(frame:GetName().."_StatsFrame_ManaBar")
if (XPerlConfig.RaidMana == 1) then
frameStats:SetHeight(30)
frameMana:Show()
else
frameStats:SetHeight(25)
frameMana:Hide()
end
end
-- GetRaidUnit
local function GetRaidUnit(num, createIfAbsent)
local frame = getglobal(XPERL_RAIDMEMBER_PREFIX..num)
if (not frame and createIfAbsent) then
frame = CreateFrame("Frame", XPERL_RAIDMEMBER_PREFIX..num, XPerl_Raid_Frame, "XPerl_Raid_FrameTemplate")
frame:SetScale(XPerlConfig.Scale_Raid)
Setup1RaidFrame(frame)
end
return frame
end
-- Non local by request
Perl_Raid_FindID = XPerl_Frame_FindID
local function Perl_Raid_FindNum(partyid)
local _, _, num = strfind(partyid, "(%d+)")
return tonumber(num)
end
local function Spacing()
return XPerlConfig.RaidVerticalSpacing + ((-1 + XPerlConfig.RaidMana) * 5)
end
-- XPerl_Raid_Group_OnLoad
function XPerl_Raid_Group_OnLoad()
local id = XPerl_Frame_FindID(this)
this:SetID(id)
local x, y
if (XPerlConfig.RaidPositions) then
local pos = XPerlConfig.RaidPositions[this:GetName()]
if (pos and pos.left and pos.top) then
x = pos.left
y = pos.top
end
end
if (not (x and y)) then
y = 565
x = (id - 1) * 77
end
this:ClearAllPoints()
this:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y)
function this:SavePosition()
XPerlConfig.RaidPositions[this:GetName()] = {top = this:GetTop(), left = this:GetLeft()}
end
end
-- SaveAllPositions
local function SaveAllPositions()
for i = 1,NUM_RAID_GROUPS do
local frame = GetRaidGroup(i)
if (frame) then
XPerlConfig.RaidPositions[frame:GetName()] = {top = frame:GetTop(), left = frame:GetLeft()}
end
end
end
-- XPerl_Raid_Single_OnLoad
function XPerl_Raid_Single_OnLoad()
if (strsub(this:GetName(), 1, 5) == "XPerl") then
local id = XPerl_Frame_FindID(this)
this:SetID(id)
this.partyid = "raid"..this:GetID()
FrameArray[this.partyid] = this
else
this:SetID(99)
end
this.showing = 0
XPerl_RegisterHighlight(getglobal(this:GetName().."_CastClickOverlay"), 2)
XPerl_RegisterPerlFrames(this, {"NameFrame", "StatsFrame"})
this.FlashFrames = {getglobal(this:GetName().."_NameFrame"), getglobal(this:GetName().."_StatsFrame")}
end
local events = {"UNIT_FACTION", "UNIT_FLAGS", "UNIT_DYNAMIC_FLAGS", "UNIT_AURA",
"UNIT_SPELLMISS", "CHAT_MSG_ADDON", "CHAT_MSG_RAID", "CHAT_MSG_RAID_LEADER",
"CHAT_MSG_PARTY"}
-- XPerl_Raid_RegisterSome
local function XPerl_Raid_RegisterSome()
for i,event in pairs(events) do
this:RegisterEvent(event)
end
XPerl_RegisterBasics()
this:UnregisterEvent("UNIT_LEVEL") -- Don't care about player level
end
-- XPerl_Raid_UnregisterSome
local function XPerl_Raid_UnregisterSome()
for i,event in pairs(events) do
this:UnregisterEvent(event)
end
XPerl_UnregisterBasics()
end
-- XPerl_Raid_UpdateName
local function XPerl_Raid_UpdateName(thisFrame)
local name = UnitName(thisFrame.partyid)
if (name or thisFrame.pet) then
local frame = getglobal(thisFrame:GetName().."_NameFrame_NameBarText")
local frameParent = getglobal(thisFrame:GetName().."_NameFrame")
if (thisFrame.pet and name) then
thisFrame.petname = name -- Store it for when pet is absent
end
if (not name) then
if (thisFrame.petname) then
name = thisFrame.petname
else
name = UnitName(thisFrame.petOwner).."'s "..PET
end
end
frame:SetText(name)
local remCount = 1
while ((frame:GetStringWidth() >= (frameParent:GetWidth() - 6)) and (string.len(name) > remCount)) do
name = string.sub(name, 1, string.len(name) - remCount)..".."
remCount = 3
frame:SetText(name)
end
if (thisFrame.pet) then
color = XPerlConfig.ColourReactionNone
frame:SetTextColor(color.r, color.g, color.b)
else
XPerl_ColourFriendlyUnit(frame, thisFrame.partyid)
end
end
end
-- XPerl_Raid_CheckFlags
local function XPerl_Raid_CheckFlags(partyid)
local unitName = UnitName(partyid)
local resser
for i,name in pairs(ResArray) do
if (name == unitName) then
resser = i
break
end
end
if (resser) then
-- Verify they're dead..
if (UnitIsDeadOrGhost(partyid)) then
return {flag = resser.." ressing", bgcolor = {r = 0, g = 0.5, b = 1}}
end
ResArray[resser] = nil
end
local unitInfo = XPerl_Roster[unitName]
if (unitInfo) then
if (unitInfo.afk) then
return {flag = "AFK"}
elseif (unitInfo.dnd) then
return {flag = "DND"}
elseif (unitInfo.ressed) then
if (UnitIsDead(partyid)) then
if (unitInfo.ressed == 2) then
return {flag = XPERL_LOC_SS_AVAILABLE, bgcolor = {r = 0, g = 1, b = 0.5}}
else
return {flag = XPERL_LOC_RESURRECTED, bgcolor = {r = 0, g = 0.5, b = 1}}
end
else
unitInfo.ressed = nil
XPerl_Raid_UpdateManaType(FrameArray[partyid], true)
end
end
end
end
-- XPerl_Raid_UpdateManaType
function XPerl_Raid_UpdateManaType(thisFrame, skipFlags)
local flags
if (not skipFlags) then
flags = XPerl_Raid_CheckFlags(thisFrame.partyid)
end
if (not flags) then
if (XPerlConfig.RaidMana == 1) then
local frame = getglobal(thisFrame:GetName().."_StatsFrame_ManaBar")
local frameBG = getglobal(thisFrame:GetName().."_StatsFrame_ManaBarBG")
XPerl_SetManaBarType(thisFrame.partyid, frame, frameBG)
end
end
end
-- XPerl_Raid_ShowFlags
local function XPerl_Raid_ShowFlags(thisFrame, flags)
--thisFrame.flags = flags
local f, color, bgcolor
if (flags.bgcolor) then
bgcolor = flags.bgcolor
else
bgcolor = {r = 0.5, g = 0.5, b = 0.5}
end
if (flags.color) then
color = flags.color
else
color = {r = 1, g = 1, b = 1}
end
f = getglobal(thisFrame:GetName().."_StatsFrame_HealthBar"); if (f) then f:SetStatusBarColor(bgcolor.r, bgcolor.g, bgcolor.b); end
f = getglobal(thisFrame:GetName().."_StatsFrame_HealthBarBG"); if (f) then f:SetVertexColor(bgcolor.r, bgcolor.g, bgcolor.b, 0.5); end
f = getglobal(thisFrame:GetName().."_StatsFrame_ManaBar"); if (f) then f:SetStatusBarColor(bgcolor.r, bgcolor.g, bgcolor.b); end
f = getglobal(thisFrame:GetName().."_StatsFrame_ManaBarBG"); if (f) then f:SetVertexColor(bgcolor.r, bgcolor.g, bgcolor.b, 0.5); end
f = getglobal(thisFrame:GetName().."_StatsFrame_HealthBarText")
if (f) then
f:SetText(flags.flag)
f:SetTextColor(color.r, color.g, color.b)
end
end
-- XPerl_IsFeignDeath(unit)
function XPerl_IsFeignDeath(unit)
for i = 1,20 do
local buff = UnitBuff(unit, i)
if (buff) then
if (strfind(strlower(buff), "feigndeath")) then
return true
end
else
break
end
end
end
-- XPerl_Raid_UpdateHealth
local function XPerl_Raid_UpdateHealth(thisFrame)
local partyid = thisFrame.partyid
local health = UnitHealth(partyid)
local healthmax = UnitHealthMax(partyid)
local healthBar = getglobal(thisFrame:GetName().."_StatsFrame_HealthBar")
local frameText = getglobal(thisFrame:GetName().."_StatsFrame_HealthBarText")
healthBar:SetMinMaxValues(0, healthmax)
if (XPerlConfig.InverseBars == 1) then
healthBar:SetValue(healthmax - health)
else
healthBar:SetValue(health)
end
local name = UnitName(partyid)
local myRoster = XPerl_Roster[name]
local feigning
if (name and UnitIsConnected(partyid)) then
if (myRoster and myRoster.fd and health > 0) then
-- Seems we don't always get the UNIT_AURA messages, so we'll check their health on updates.
-- health > 0 means they can't be FD
myRoster.fd = nil
end
local flags = XPerl_Raid_CheckFlags(partyid)
if (flags) then
XPerl_Raid_ShowFlags(thisFrame, flags)
if (UnitIsDeadOrGhost(partyid)) then
thisFrame.dead = true
XPerl_Raid_UpdateName(thisFrame)
end
return
elseif (UnitIsDead(partyid) or myRoster and myRoster.fd) then
if (myRoster and myRoster.fd) then --XPerl_IsFeignDeath(partyid)) then
feigning = true
healthBar:SetMinMaxValues(0, 1)
healthBar:SetValue(0)
frameText:SetText(XPERL_LOC_FEIGNDEATH)
XPerl_SetSmoothBarColor(healthBar, 0)
else
thisFrame.dead = true
XPerl_Raid_ShowFlags(thisFrame, {flag = XPERL_LOC_DEAD})
XPerl_Raid_UpdateName(thisFrame)
end
elseif (UnitIsGhost(partyid)) then
thisFrame.dead = true
XPerl_Raid_ShowFlags(thisFrame, {flag = XPERL_LOC_GHOST})
XPerl_Raid_UpdateName(thisFrame)
else
if (thisFrame.dead or (myRoster and (myRoster.fd or myRoster.ressed))) then
XPerl_Raid_UpdateManaType(thisFrame, true)
end
thisFrame.dead = nil
local percentHp = health / healthmax
local phealthPct = string.format("%3.0f", percentHp * 100)
if (XPerlConfig.HealerMode == 1) then
frameText:SetText(-(healthmax - health))
else
frameText:SetText(phealthPct.."%")
end
XPerl_SetSmoothBarColor(healthBar, percentHp)
if (myRoster) then
myRoster.resCount = nil
if (myRoster.ressed) then
myRoster.ressed = nil
XPerl_Raid_UpdateManaType(thisFrame, true)
end
end
end
else
thisFrame.dead = nil
XPerl_Raid_ShowFlags(thisFrame, {flag = XPERL_LOC_OFFLINE})
if (name and myRoster and not myRoster.offline) then
myRoster.offline = GetTime()
myRoster.afk = nil
myRoster.dnd = nil
end
end
if (myRoster) then
if (not feigning) then
myRoster.fd = nil
end
end
end
-- XPerl_Raid_UpdateMana
local function XPerl_Raid_UpdateMana(thisFrame)
local mana = UnitMana(thisFrame.partyid)
local manamax = UnitManaMax(thisFrame.partyid)
local manaBar = getglobal(thisFrame:GetName().."_StatsFrame_ManaBar")
local manaBarText = getglobal(thisFrame:GetName().."_StatsFrame_ManaBarText")
if (UnitPowerType(thisFrame.partyid) == 0 and not thisFrame.pet) then
local pmanaPct = (mana * 100.0) / manamax
manaBarText:SetText(string.format("%3.0f%%", pmanaPct))
else
manaBarText:SetText("")
end
manaBar:SetMinMaxValues(0, manamax)
manaBar:SetValue(mana)
end
-- XPerl_Raid_CombatFlash
local function XPerl_Raid_CombatFlash(thisFrame, elapsed, argNew, argGreen)
if (XPerl_CombatFlashSet (elapsed, thisFrame, argNew, argGreen)) then
XPerl_CombatFlashSetFrames(thisFrame)
end
end
-- UpdateUnitByName
local function UpdateUnitByName(name,flagsOnly)
local id = XPerl_GetRaidPosition(name)
if (id) then
local frame = FrameArray["raid"..id]
if (frame) then
if (flagsOnly) then
XPerl_Raid_UpdateHealth(frame)
else
XPerl_Raid_UpdateDisplay(frame)
end
end
for k,v in pairs(PulloutFrameArray) do
if (v.partyid == "raid"..id) then
if (flagsOnly) then
XPerl_Raid_UpdateHealth(frame)
else
XPerl_Raid_UpdateDisplay(frame)
end
end
end
end
end
-- Raid_Motion
local function Raid_Motion(cell)
local motion = cell.motion
motion.currentLeft = motion.currentLeft * CELL_MOTION_SPEED
if (motion.currentLeft > -1 and motion.currentLeft < 1) then
motion.currentLeft = 0
end
motion.currentTop = motion.currentTop * CELL_MOTION_SPEED
if (motion.currentTop > -1 and motion.currentTop < 1) then
motion.currentTop = 0
end
cell:ClearAllPoints()
if (XPerlConfig.RaidUpward == 1) then
cell:SetPoint("BOTTOMLEFT", motion.parent, "TOPLEFT", motion.currentLeft, motion.targetTop - motion.currentTop)
else
cell:SetPoint("TOPLEFT", motion.parent, "BOTTOMLEFT", motion.currentLeft, motion.targetTop + motion.currentTop)
end
if (motion.currentLeft == 0 and motion.currentTop == 0) then
cell.motion = nil
end
end
-------------------
-- Raid movement --
-------------------
-- XPerl_Raid_StartMovingMember
function XPerl_Raid_StartMovingMember()
if (not MovingMember) then
local frame = this:GetParent()
if (frame:GetID() ~= 99) then
HideDropDownMenu(1)
MovingMember = frame
frame:StartMoving()
frame:SetAlpha(XPerlConfig.Transparency / 2)
XPerl_RaidTitles()
end
end
end
-- XPerl_Raid_CheckMovingMember
local function XPerl_Raid_CheckMovingMember()
local x = MovingMember:GetLeft() + ((MovingMember:GetRight() - MovingMember:GetLeft()) / 2)
local y = MovingMember:GetBottom() + ((MovingMember:GetTop() - MovingMember:GetBottom()) / 2)
XPerl_Raid_Mover:ClearAllPoints()
XPerl_Raid_Mover:Hide()
XPerl_Raid_Mover:SetScale(XPerlConfig.Scale_Raid)
for i,cell in pairs(FrameArray) do
getglobal(cell:GetName().."_CastClickOverlay"):UnlockHighlight()
end
local name = UnitName(MovingMember.partyid)
local spacing = Spacing()
for i = 1,NUM_RAID_GROUPS do
if (i ~= RaidPositions[name].group) then
local frame = GetRaidGroup(i, true)
if (frame) then
local left = (frame:GetLeft() or 0)
local right = (frame:GetRight() or 0)
local top
if (XPerlConfig.RaidUpward == 1) then
top = frame:GetTop() or 0
else
top = frame:GetBottom() or 0
end
if (left) then
local bottom
if (XPerlConfig.RaidUpward == 1) then
bottom = top + (MEMBERS_PER_RAID_GROUP * spacing)
local t = top
top = bottom
bottom = t
else
bottom = top - (MEMBERS_PER_RAID_GROUP * spacing)
end
if (x >= left and x <= right and y >= bottom and y <= top) then
if (XPerlConfig.RaidUpward == 1) then
XPerl_Raid_Mover:SetPoint("BOTTOMLEFT", frame, "TOPLEFT", 0, 0)
XPerl_Raid_Mover:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -(bottom - top))
else
XPerl_Raid_Mover:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, 0)
XPerl_Raid_Mover:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, (bottom - top))
end
XPerl_Raid_Mover:Show()
local size = (bottom - top) / 5
local sub = math.floor((y - top - size) / size) + 2
if (sub < 1) then
sub = 1
elseif (sub > 5) then
sub = 5
end
if (XPerlConfig.RaidUpward == 1) then
sub = 6 - sub
end
for j,cell in pairs(FrameArray) do
local pos = RaidPositions[UnitName(cell.partyid)]
if (pos and cell ~= MovingMember and pos.group == i and pos.row == sub) then
getglobal(cell:GetName().."_CastClickOverlay"):LockHighlight()
break
end
end
return i, sub
end
end
end
end
end
end
-- XPerl_Raid_StopMovingMember
function XPerl_Raid_StopMovingMember(commit)
if (MovingMember) then
local good
MovingMember:StopMovingOrSizing()
if (commit) then
local group,subpos = XPerl_Raid_CheckMovingMember()
--ChatFrame7:AddMessage("group "..(group or "nil").." row "..(subpos or "nil"))
if (group) then
local pos = RaidPositions[UnitName(MovingMember.partyid)]
if (pos and group ~= pos.group) then
local unit
for i,cell in pairs(FrameArray) do
local cellPos = RaidPositions[UnitName(cell.partyid)]
if (cellPos and cellPos.group == group and cellPos.row == subpos) then
unit = cell
break
end
end
local index = Perl_Raid_FindNum(MovingMember.partyid)
--ChatFrame7:AddMessage(" index "..(index or "nil"))
if (unit) then
local targetIndex = Perl_Raid_FindNum(unit.partyid)
--ChatFrame7:AddMessage(" targetIndex "..(targetIndex or "nil"))
SwapRaidSubgroup(index, targetIndex)
else
SetRaidSubgroup(index, group)
end
good = true
else
--ChatFrame7:AddMessage("Cancelled, same as my current group")
end
else
--ChatFrame7:AddMessage("Cancelled, no group")
end
end
for i,cell in pairs(FrameArray) do
getglobal(cell:GetName().."_CastClickOverlay"):UnlockHighlight()
end
if (not good) then
local pos = RaidPositions[UnitName(MovingMember.partyid)]
if (pos) then
local parentGroup = GetRaidGroup(pos.group)
MovingMember:ClearAllPoints()
if (XPerlConfig.RaidUpward == 1) then
MovingMember:SetPoint("BOTTOMLEFT", parentGroup, "TOPLEFT", 0, -2 + ((pos.row - 1) * Spacing()))
else
MovingMember:SetPoint("TOPLEFT", parentGroup, "BOTTOMLEFT", 0, 2 - ((pos.row - 1) * Spacing()))
end
end
end
if (UnitIsConnected(MovingMember.partyid)) then
MovingMember:SetAlpha(XPerlConfig.Transparency)
else
MovingMember:SetAlpha(XPerlConfig.Transparency / 2)
end
MovingMember = nil
XPerl_RaidTitles()
XPerl_Raid_Mover:Hide()
end
end
-- XPerl_Raid_OnUpdate
-- 1.8.3 Converted OnUpdate to 1 single routine for all frames, instead of calling
-- potentially the same function 40 times Globally, this is more efficient on time
-- and memory usage. It does remove from the concept of object oriented updates
-- and such, but X-Perl is a rather intensive mod that is the focus of much of the
-- user interface, so I felt it was important to be over cautious.
function XPerl_Raid_OnUpdate()
if (RosterUpdate) then
RosterUpdate = nil
XPerl_Raid_Position()
if (GetNumRaidMembers() == 0) then
ResArray = {}
XPerl_Roster = {}
RaidPositions = {}
end
end
local updateTanker
if (XPerlConfig.RaidHighlightTanker == 1) then
if arg1 then this.time = this.time + arg1; end
if this.time >= 0.2 then
this.time = 0
updateTanker = true
end
end
for i,frame in pairs(FrameArray) do
if (frame.showing == 1) then
if (frame.PlayerFlash) then
XPerl_Raid_CombatFlash(frame, arg1, false) -- << Frame
end
if (frame.motion) then
Raid_Motion(frame)
end
if (updateTanker) then
local set
if (UnitExists("target")) then
if (UnitCanAttack("player", "target")) then
if (UnitInRaid("targettarget")) then
set = UnitIsUnit("targettarget", frame.partyid)
end
elseif (UnitCanAttack("player", "targettarget")) then
if (UnitInRaid("targettargettarget")) then
set = UnitIsUnit("targettargettarget", frame.partyid)
end
end
end
local highlightFrame = getglobal(frame:GetName().."_CastClickOverlay")
if (XPerlConfig.HighlightSelection == 0) then
if (set) then
highlightFrame:SetHighlightTexture("Interface\\Addons\\XPerl\\Images\\XPerl_Highlight", "ADD")
local tex = highlightFrame:GetHighlightTexture(); tex:SetTexCoord(0.25, 0.75, 0, 0.5)
tex:SetVertexColor(0.86, 0.82, 0.41)
else
highlightFrame:SetHighlightTexture("")
end
else
highlightFrame:SetHighlightTexture("Interface\\Addons\\XPerl\\Images\\XPerl_Highlight", "ADD")
local tex = highlightFrame:GetHighlightTexture(); tex:SetTexCoord(0.25, 0.75, 0, 0.5)
tex:SetVertexColor(0.86, 0.82, 0.41)
end
if (set) then
highlightFrame:LockHighlight()
else
highlightFrame:UnlockHighlight()
end
end
end
end
if (MovingMember) then
XPerl_Raid_CheckMovingMember()
end
end
-- GetBuffButton(thisFrame, buffnum, debuff, createIfAbsent)
-- debuff must be 1 or 0, as it's used in size calc
local function GetBuffButton(thisFrame, buffnum, createIfAbsent)
local name = thisFrame:GetName().."_BuffFrame_Buff"..buffnum
local button = getglobal(name)
if (not button and createIfAbsent) then
button = CreateFrame("Button", name, getglobal(thisFrame:GetName().."_BuffFrame"), "XPerl_BuffTemplate")
button:SetID(buffnum)
button:SetHeight(10)
button:SetWidth(10)
local icon = getglobal(name.."Icon")
icon:SetTexCoord(0.078125, 0.921875, 0.078125, 0.921875)
button:SetScript("OnEnter", XPerl_Raid_SetBuffTooltip)
button:SetScript("OnLeave", XPerl_PlayerTipHide)
end
return button
end
-- GetShowCast
local function GetShowCast(thisFrame)
local show,cureCast
if (thisFrame:GetID() == 99) then
-- Pullout frames all have ID 99
local RaidPullout = thisFrame:GetParent()
if (RaidPullout.showBuffs == 1) then
show = "b"
else
show = "d"
end
if (RaidPullout.cureCast) then
cureCast = 1
else
cureCast = 0
end
else
if (XPerlConfig.RaidBuffs == 1) then
show = "b"
elseif (XPerlConfig.RaidDebuffs == 1) then
show = "d"
end
cureCast = XPerlConfig.BuffsCastableCurable
end
return show,cureCast
end
-- UpdateBuffs
local function UpdateBuffs(thisFrame)
local partyid = thisFrame.partyid
local cursed, color = XPerl_CheckDebuffs(partyid, {getglobal(thisFrame:GetName().."_NameFrame"), getglobal(thisFrame:GetName().."_StatsFrame")})
local frameText = getglobal(thisFrame:GetName().."_NameFrame_NameBarText")
if (cursed) then
frameText:SetTextColor(1,0,0)
else
XPerl_ColourFriendlyUnit(frameText, partyid)
end
local buffCount = 0
local maxBuff = 8 - ((abs(1 - XPerlConfig.RaidMana) * 2) * XPerlConfig.RaidBuffsRight)
local show, cureCast = GetShowCast(thisFrame)
if (show) then
for buffnum=1,maxBuff do
local buff, count
if (show == "b") then
buff = XPerl_UnitBuff(partyid, buffnum, cureCast)
else
buff = XPerl_UnitDebuff(partyid, buffnum, cureCast)
end
local button = GetBuffButton(thisFrame, buffnum, buff) -- 'buff' flags whether to create icon
if (button) then
local icon = getglobal(button:GetName().."Icon")
if (buff) then
buffCount = buffCount + 1
icon:SetTexture(buff)
button:Show()
else
button:Hide()
end
end
end
for buffnum=maxBuff+1,8 do
local button = getglobal(thisFrame:GetName().."_BuffFrame_Buff"..buffnum)
if (button) then
button:Hide()
end
end
end
--local myRoster = XPerl_Roster[UnitName(partyid)]
--if (myRoster and XPerlConfig.RaidBuffs == 1 and buffCount == 0 and cureCast == 0) then
-- if (UnitIsConnected(partyid)) then
-- -- Already scanned raid buffs and there are none
-- myRoster.Buffs = nil
-- end
--else
-- CheckRosterBuffs(partyid)
--end
local buffFrame = getglobal(thisFrame:GetName().."_BuffFrame")
local nameFrame = getglobal(thisFrame:GetName().."_NameFrame")
local statsFrame = getglobal(thisFrame:GetName().."_StatsFrame")
if (buffCount > 0) then
buffFrame:ClearAllPoints()
buffFrame:Show()
local id = thisFrame:GetID()
if (XPerlConfig.RaidBuffsRight == 1 or id == 99) then
buffFrame:SetPoint("BOTTOMLEFT", thisFrame:GetName().."_StatsFrame", "BOTTOMRIGHT", -2, 2)
if (XPerlConfig.RaidBuffsInside == 1 and id ~= 99) then
if (buffCount > 5 + XPerlConfig.RaidMana) then
nameFrame:SetWidth(60)
elseif (buffCount > 2) then
nameFrame:SetWidth(70)
else
nameFrame:SetWidth(80)
end
if (buffCount > 3 + XPerlConfig.RaidMana) then
statsFrame:SetWidth(60)
else
statsFrame:SetWidth(70)
end
else
nameFrame:SetWidth(80)
statsFrame:SetWidth(80)
end
getglobal(thisFrame:GetName().."_BuffFrame_Buff1"):ClearAllPoints()
getglobal(thisFrame:GetName().."_BuffFrame_Buff1"):SetPoint("BOTTOMLEFT", 0, 0)
for i = 2,buffCount do
if (i > buffCount) then break end
local buffI = getglobal(thisFrame:GetName().."_BuffFrame_Buff"..i)
buffI:ClearAllPoints()
if (i == 4 + XPerlConfig.RaidMana) then
if (XPerlConfig.RaidBuffsInside == 1 and id ~= 99) then
buffI:SetPoint("BOTTOMLEFT", 0, 0)
getglobal(thisFrame:GetName().."_BuffFrame_Buff1"):SetPoint("BOTTOMLEFT", buffI, "BOTTOMRIGHT", 0, 0)
else
buffI:SetPoint("BOTTOMLEFT", thisFrame:GetName().."_BuffFrame_Buff"..(i-(4 - abs(1 - XPerlConfig.RaidMana))), "BOTTOMRIGHT", 0, 0)
end
else
buffI:SetPoint("BOTTOMLEFT", thisFrame:GetName().."_BuffFrame_Buff"..(i-1), "TOPLEFT", 0, 0)
end
end
else
nameFrame:SetWidth(80)
statsFrame:SetWidth(80)
buffFrame:SetPoint("TOPLEFT", thisFrame:GetName().."_StatsFrame", "BOTTOMLEFT", 0, 2)
local prevBuff
for i = 1,buffCount do
local buff = getglobal(thisFrame:GetName().."_BuffFrame_Buff"..i)
buff:ClearAllPoints()
if (prevBuff) then
buff:SetPoint("TOPLEFT", prevBuff, "TOPRIGHT", 0, 0)
else
buff:SetPoint("TOPLEFT", 0, 0)
end
prevBuff = buff
end
end
else
nameFrame:SetWidth(80)
statsFrame:SetWidth(80)
buffFrame:Hide()
end
local myRoster = XPerl_Roster[UnitName(partyid)]
if (myRoster) then
local _,class = UnitClass(partyid)
if (class == "HUNTER") then
if (XPerl_IsFeignDeath(partyid)) then
if (not myRoster.fd) then
myRoster.fd = GetTime()
XPerl_Raid_UpdateHealth(thisFrame)
end
elseif (myRoster.fd) then
myRoster.fd = nil
XPerl_Raid_UpdateManaType(thisFrame, true)
end
end
end
end
-- UpdateRosterBuffs
-- Scans a unit's buffs and sets up initial buff time remaining entries
local duplicateTextures = {
["Interface\\Icons\\Spell_Nature_Regeneration"] = true,
["Interface\\Icons\\Spell_Nature_LightningShield"] = true
};
local function UpdateRosterBuffs(thisFrame)
local unit = thisFrame.partyid
local myRoster = XPerl_Roster[unit]
if (myRoster) then
if (not myRoster.Buffs) then
myRoster.Buffs = {}
end
local oldAuras = {}
for k, v in pairs(myRoster.Buffs) do
oldAuras[k] = 1
end
local num, buff = 0, UnitBuff(unit, 1);
while (buff) do
num = num + 1;
if (not duplicateTextures[buff]) then
for k, v in pairs(XPerl_CTBuffTextures) do
if ("Interface\\Icons\\"..v[1] == buff) then
buffName = k
break
end
end
else
PerlBuffStatusTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
PerlBuffStatusTooltipTextLeft1:SetText("")
PerlBuffStatusTooltip:SetUnitBuff(unit, num)
local tooltipName = PerlBuffStatusTooltipTextLeft1:GetText()
if (strlen(tooltipName or "") > 0 and XPerl_CTBuffTextures[tooltipName]) then
buffName = tooltipName
end
end
if (buffName) then
oldAuras[buffName] = nil
if (not myRoster.Buffs[buffName]) then
-- We store the fade time of raid member's buffs
local duration = XPerl_CTBuffTextures[buffName][2]
if (not duration) then
duration = 5*60
end
myRoster.Buffs[buffName] = GetTime() + duration
end
end
buff = UnitBuff(unit, num + 1)
end
for k, v in pairs(oldAuras) do
myRoster.Buffs[k] = nil
end
end
end
-- XPerl_Raid_Update_Control
local function XPerl_Raid_Update_Control(thisFrame)
if (UnitIsVisible(thisFrame.partyid) and UnitIsCharmed(thisFrame.partyid)) then
getglobal(thisFrame:GetName().."_NameFrame_Warning"):Show()
else
getglobal(thisFrame:GetName().."_NameFrame_Warning"):Hide()
end
end
-- XPerl_Raid_UpdateCombat
local function XPerl_Raid_UpdateCombat(thisFrame)
local frame = getglobal(thisFrame:GetName().."_NameFrame_ActivityStatus")
if (not (frame == nil)) then
if (UnitExists(thisFrame.partyid) and UnitAffectingCombat(thisFrame.partyid)) then
frame:Show()
else
frame:Hide()
end
end
end
-------------------------
-- The Update Function --
-------------------------
function XPerl_Raid_UpdateDisplay(thisFrame)
if (thisFrame.showing == 1) then
if (UnitExists(thisFrame.partyid) or thisFrame.pet) then
if (UnitIsConnected(thisFrame.partyid) and MovingMember ~= thisFrame) then
thisFrame:SetAlpha(XPerlConfig.Transparency)
else
thisFrame:SetAlpha(XPerlConfig.Transparency/2)
getglobal(thisFrame:GetName().."_StatsFrame_HealthBarText"):SetText("Offine")
end
local manaBarText = getglobal(thisFrame:GetName().."_StatsFrame_ManaBarText")
local healthBarText = getglobal(thisFrame:GetName().."_StatsFrame_HealthBarText")
if (XPerlConfig.ShowRaidPercents==0) then
manaBarText:Hide()
healthBarText:Hide()
else
manaBarText:Show()
healthBarText:Show()
end
-- Health must be updated after mana, since ctra flag checks are done here.
XPerl_Raid_UpdateManaType(thisFrame)
XPerl_Raid_UpdateMana(thisFrame)
XPerl_Raid_UpdateHealth(thisFrame) -- <<< -- AFTER MANA -- <<< --
XPerl_Raid_UpdateName(thisFrame)
XPerl_Raid_UpdateCombat(thisFrame)
XPerl_Raid_Update_Control(thisFrame)
UpdateBuffs(thisFrame)
else
thisFrame:StopMovingOrSizing()
thisFrame:Hide()
end
else
thisFrame:StopMovingOrSizing()
thisFrame:Hide()
end
end
-------------------
-- Event Handler --
-------------------
function XPerl_Raid_OnEvent()
local func = XPerl_Raid_Events[event]
if (func) then
func()
else
XPerl_ShowMessage("EXTRA EVENT")
end
end
function XPerl_Raid_Events:ADDON_LOADED()
if (arg1 == "Blizzard_RaidUI") then
if (not oldRaidFrameDropDown_Initialize) then
oldRaidFrameDropDown_Initialize = RaidFrameDropDown_Initialize
RaidFrameDropDown_Initialize = XPerl_RaidFrameDropDown_Initialize
end
if (CT_RATab_newRaidFrameDropDown_Initialize) then
if (not oldCT_RATab_newRaidFrameDropDown_Initialize) then
oldCT_RATab_newRaidFrameDropDown_Initialize = CT_RATab_newRaidFrameDropDown_Initialize
CT_RATab_newRaidFrameDropDown_Initialize = XPerl_CT_RATab_newRaidFrameDropDown_Initialize
--RaidFrameDropDown_Initialize = XPerl_CTRaidFrameDropDown_Initialize
end
end
XPerl_ReplaceBlizzardPullouts()
this:UnregisterEvent("ADDON_LOADED")
end
end
function XPerl_Raid_Events:VARIABLES_LOADED()
this:UnregisterEvent("VARIABLES_LOADED")
XPerl_Raid_RegisterSome()
if (GetNumRaidMembers() == 0) then
ResArray = {}
XPerl_Roster = {}
RaidPositions = {}
else
local myRoster = XPerl_Roster[UnitName("player")]
if (myRoster) then
myRoster.afk, myRoster.dnd, myRoster.dnd, myRoster.ressed, myRoster.resCount = nil, nil, nil, nil, nil
end
end
XPerl_ScaleRaid(XPerlConfig.Scale_Raid)
XPerl_RaidTitles()
end
-- PLAYER_ENTERING_WORLD
function XPerl_Raid_Events:PLAYER_ENTERING_WORLD()
XPerl_Raid_RegisterSome()
if (not XPerl_raid1 and GetNumRaidMembers() > 0) then
XPerl_Raid_Position()
end
end
-- PLAYER_LEAVING_WORLD
function XPerl_Raid_Events:PLAYER_LEAVING_WORLD()
XPerl_Raid_UnregisterSome()
end
-- RAID_ROSTER_UPDATE
function XPerl_Raid_Events:RAID_ROSTER_UPDATE()
if (MovingMember) then
XPerl_Raid_StopMovingMember()
end
if (not XPerl_raid1 or XPerl_raid1.showing == 0) then
-- If no raid yet, just setup anyway
XPerl_Raid_Position()
if (GetNumRaidMembers() == 0) then
ResArray = {}
XPerl_Roster = {}
RaidPositions = {}
end
if (XPerl_SendModules) then
XPerl_SendModules() -- Let other X-Perl users know which version we're running
end
else
-- Otherwise, we defer the roster update until the next frame for
-- cases where we get more than 1 RAID_ROSTER_UPDATE per data packet
RosterUpdate = true
end
end
-- UNIT_FLAGS
function XPerl_Raid_Events:UNIT_FLAGS()
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_UpdateCombat(f)
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_UpdateCombat(f)
end
end
end
end
XPerl_Raid_Events.UNIT_DYNAMIC_FLAGS = XPerl_Raid_Events.UNIT_FLAGS
-- UNIT_FACTION
function XPerl_Raid_Events:UNIT_FACTION()
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_Update_Control(f)
XPerl_Raid_UpdateName(f)
end
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_Update_Control(f)
XPerl_Raid_UpdateName(f)
end
end
end
-- UNIT_COMBAT
function XPerl_Raid_Events:UNIT_COMBAT()
local f = FrameArray[arg1]
if (f) then
if (arg2 == "HEAL") then
XPerl_Raid_CombatFlash(f, 0, true, true)
elseif (arg4 and arg4 > 0) then
XPerl_Raid_CombatFlash(f, 0, true)
end
end
end
-- UNIT_HEALTH
function XPerl_Raid_Events:UNIT_HEALTH()
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_UpdateHealth(f)
XPerl_Raid_UpdateCombat(f)
end
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_UpdateHealth(f)
end
end
end
XPerl_Raid_Events.UNIT_MAXHEALTH = XPerl_Raid_Events.UNIT_HEALTH
function XPerl_Raid_Events:UNIT_DISPLAYPOWER()
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_UpdateManaType(f)
XPerl_Raid_UpdateMana(f)
end
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_UpdateManaType(f)
XPerl_Raid_UpdateMana(f)
end
end
end
-- UNIT_MANA
function XPerl_Raid_Events:UNIT_MANA()
if (XPerlConfig.RaidMana == 1) then
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_UpdateMana(f)
end
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_UpdateMana(f)
end
end
end
end
XPerl_Raid_Events.UNIT_MAXMANA = XPerl_Raid_Events.UNIT_MANA
XPerl_Raid_Events.UNIT_RAGE = XPerl_Raid_Events.UNIT_MANA
XPerl_Raid_Events.UNIT_MAXRAGE = XPerl_Raid_Events.UNIT_MANA
XPerl_Raid_Events.UNIT_ENERGY = XPerl_Raid_Events.UNIT_MANA
XPerl_Raid_Events.UNIT_MAXENERGY = XPerl_Raid_Events.UNIT_MANA
-- UNIT_NAME_UPDATE
function XPerl_Raid_Events:UNIT_NAME_UPDATE()
local f = FrameArray[arg1]
if (f) then
XPerl_Raid_UpdateName(f)
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
XPerl_Raid_UpdateName(f)
end
end
end
end
-- UNIT_AURA
function XPerl_Raid_Events:UNIT_AURA()
local f = FrameArray[arg1]
if (f) then
UpdateRosterBuffs(f)
UpdateBuffs(f)
for name,f in pairs(PulloutFrameArray) do
if (f.partyid == arg1 and f:IsShown()) then
UpdateBuffs(f)
end
end
end
end
-- UNIT_PET
function XPerl_Raid_Events:UNIT_PET()
if (strsub(arg1, 1, 4) == "raid") then
for k,v in pairs(PulloutFrameArray) do
if (v.petOwner == arg1) then
XPerl_Raid_UpdateDisplay(v)
end
end
end
end
-- SetRes
local function SetResStatus(resserName, resTargetName)
--frame.beingRessed = true
local resEnd
if (resTargetName) then
ResArray[resserName] = resTargetName
else
resEnd = true
for i,name in pairs(ResArray) do
if (i == resserName) then
resTargetName = name
break
end
end
ResArray[resserName] = nil
end
if (resTargetName) then
if (XPerl_Roster[resTargetName]) then
if (resEnd) then
if (not XPerl_Roster[resTargetName].resCount) then
XPerl_Roster[resTargetName].resCount = 1
else
XPerl_Roster[resTargetName].resCount = XPerl_Roster[resTargetName].resCount + 1
end
end
UpdateUnitByName(resTargetName)
end
end
end
-- Direct string matches can be done via table lookup
local QuickFuncs = {
AFK = function(m) m.afk = GetTime(); m.dnd = nil; end,
UNAFK = function(m) m.afk = nil; end,
DND = function(m) m.dnd = GetTime(); m.afk = nil; end,
UNDND = function(m) m.dnd = nil; end,
RESNO = function(m,n) SetResStatus(n) end,
RESSED = function(m) m.ressed = 1; end,
CANRES = function(m) m.ressed = 2; end,
NORESSED= function(m) m.ressed = nil; m.resCount = nil; end,
SR = XPerl_SendModules
}
-- ProcessCTRAMessage
local function ProcessCTRAMessage(unitName, msg)
local myRoster = XPerl_Roster[unitName]
if (not myRoster) then
return
end
local update = true
local func = QuickFuncs[msg]
if (func) then
func(myRoster, unitName)
else
if (strsub(msg, 1, 4) == "RES ") then
SetResStatus(unitName, strsub(msg, 5))
return
elseif (strsub(msg, 1, 3) == "RN ") then
-- Buff durations
local _, _, secsLeft, buffIndex, buffSub = strfind(msg, "^RN ([^%s]+) ([^%s]+) ([^%s]+)$")
if (secsLeft and buffIndex and buffSub) then
secsLeft = tonumber(secsLeft)
buffIndex = tonumber(buffIndex)
buffSub = tonumber(buffSub)
local buff = XPerl_CTBuffArray[buffIndex]
if (buff) then
local buffName
-- Shouldn't come with string and sub index > 0, but it does.. Will investigate when and why
-- Druid Thorns... /shrug
if (buffSub == 0 or type(buff.name) == "string") then
buffName = buff.name
else
buffName = buff.name[buffSub]
end
if (buffName) then
if (not myRoster.Buffs) then
myRoster.Buffs = {}
end
myRoster.Buffs[buffName] = GetTime() + secsLeft
--CheckRosterBuffs(unitName)
end
end
end
update = nil
elseif (strsub(msg, 1, 3) == "CD ") then
local _, _, num, cooldown = strfind(msg, "^CD (%d+) (%d+)$")
if ( num == "1" ) then
myRoster.Rebirth = GetTime() + tonumber(cooldown)*60
elseif ( num == "2" ) then
myRoster.Reincarnation = GetTime() + tonumber(cooldown)*60
elseif ( num == "3" ) then
myRoster.Soulstone = GetTime() + tonumber(cooldown)*60
end
update = nil
elseif (strsub(msg, 1, 2) == "V ") then
myRoster.version = strsub(msg, 3)
update = nil
else
update = nil
end
end
if (update) then
UpdateUnitByName(unitName)
end
end
-- ProcessoRAMessage
local function ProcessoRAMessage(unitName, msg)
local myRoster = XPerl_Roster[unitName]
if (not myRoster) then
return
end
if (strsub(msg, 1, 5) == "oRAV ") then
myRoster.oRAversion = strsub(msg, 6)
end
end
-- XPerl_Raid_Events:CHAT_MSG_RAID
-- Check for AFK/DND flags in chat
function XPerl_Raid_Events:CHAT_MSG_RAID()
local myRoster = XPerl_Roster[arg4]
if (myRoster) then
if (arg6 == "AFK") then
if (not myRoster.afk) then
myRoster.afk = GetTime()
myRoster.dnd = nil
end
elseif (arg6 == "DND") then
if (not myRoster.dnd) then
myRoster.dnd = GetTime()
myRoster.afk = nil
end
else
myRoster.dnd, myRoster.afk = nil, nil
end
end
end
XPerl_Raid_Events.CHAT_MSG_RAID_LEADER = XPerl_Raid_Events.CHAT_MSG_RAID
XPerl_Raid_Events.CHAT_MSG_PARTY = XPerl_Raid_Events.CHAT_MSG_RAID
-- CHAT_MSG_ADDON
function XPerl_Raid_Events:CHAT_MSG_ADDON()
XPerl_Raid_Events.CHAT_MSG_RAID()
if (arg3 == "RAID") then
if (arg1 == "CTRA") then
XPerl_ParseCTRA(arg4, arg2, ProcessCTRAMessage)
elseif (arg1 == "oRA") then
XPerl_ParseCTRA(arg4, arg2, ProcessoRAMessage)
end
end
end
-- SetRaidRoster
local function SetRaidRoster()
local NewRoster = {}
Last_Roster = XPerl_Roster
for i = 1,GetNumRaidMembers() do
local name = UnitName("raid"..i)
if (XPerl_Roster[name]) then
NewRoster[name] = XPerl_Roster[name]
else
NewRoster[name] = {}
end
if (Last_Roster[name]) then
if (RaidPositions[name]) then
Last_Roster[name].lastPos = RaidPositions[name]
else
Last_Roster[name].lastPos = nil
end
end
end
RaidPositions = {}
XPerl_Roster = NewRoster
end
--------------------
-- Raid Functions --
--------------------
-- MoveCell
local function MoveCell(cell, grp, wasShowing)
local parentGroup = getglobal(XPERL_RAIDGRP_PREFIX..grp)
local name = UnitName(cell.partyid)
local noMotion = true
if (wasShowing == 1) then
if (cell.lastPos) then
if (cell.lastPos.group ~= grp or cell.lastPos.row ~= RaidGroupCounts[grp] + 1) then
noMotion = false
end
end
local oldCell = Last_Roster[name]
if (oldCell) then
if (oldCell.lastPos) then
if (oldCell.lastPos.group ~= grp or oldCell.lastPos.row ~= RaidGroupCounts[grp] + 1) then
noMotion = false
end
end
end
end
RaidPositions[name] = {group = grp, row = RaidGroupCounts[grp] + 1}
local t
if (XPerlConfig.RaidUpward == 1) then
t = -2 + (RaidGroupCounts[grp] * Spacing())
else
t = 2 - (RaidGroupCounts[grp] * Spacing())
end
if (cell.motion or (not noMotion and cell.showing == 1 and cell:IsShown() and XPerlConfig.RaidMotion == 1)) then
if (XPerlConfig.RaidUpward == 1) then
cell.motion = {
targetTop = t,
parent = parentGroup,
currentLeft = cell:GetLeft() - parentGroup:GetLeft(),
currentTop = parentGroup:GetTop() - cell:GetBottom() + t
}
else
cell.motion = {
targetTop = t,
parent = parentGroup,
currentLeft = cell:GetLeft() - parentGroup:GetLeft(),
currentTop = cell:GetTop() - parentGroup:GetBottom() - t
}
end
else
cell:ClearAllPoints()
if (XPerlConfig.RaidUpward == 1) then
cell:SetPoint("BOTTOMLEFT", parentGroup, "TOPLEFT", 0, t)
else
cell:SetPoint("TOPLEFT", parentGroup, "BOTTOMLEFT", 0, t)
end
end
end
-- XPerl_Raid_Classes
local function XPerl_Raid_Classes()
local groups = {WARRIOR = 1, MAGE = 2, PRIEST = 3, WARLOCK = 4, DRUID = 5, ROGUE = 6, HUNTER = 7, PALADIN = 8, SHAMAN = 9}
for num=1,MAX_RAID_MEMBERS do
local localClass, class = UnitClass("raid"..num)
if (class) then
if (not ClassNames[class]) then
ClassNames[class] = localClass
end
local frame = GetRaidUnit(num, true)
local subgroup = groups[class]
if (subgroup) then
if (subgroup == 9) then -- Burning Crusade - REMOVE THIS
subgroup = 8
end
GetRaidGroup(subgroup, true)
local wasShowing = frame.showing
frame.showing = XPerlConfig["ShowGroup"..subgroup]
MoveCell(frame, subgroup, wasShowing)
RaidGroupCounts[subgroup] = RaidGroupCounts[subgroup] + 1
end
else
local frame = GetRaidUnit(num)
if (frame) then
frame.showing = 0
end
end
end
for name,index in pairs(groups) do
local frame = getglobal(XPERL_RAIDGRP_PREFIX..index.."_NameFrame_NameBarText")
if (frame) then
if (index == 8) then -- Burning Crusade - REMOVE THIS
if (UnitFactionGroup("player") == "Horde") then
frame:SetText(ClassNames["SHAMAN"])
else
frame:SetText(ClassNames["PALADIN"])
end
break
end
frame:SetText(ClassNames[name])
end
end
end
-- XPerl_Raid_Groups
local function XPerl_Raid_Groups()
for num=1,MAX_RAID_MEMBERS do
local name, rank, subgroup= GetRaidRosterInfo(num)
if (name and subgroup) then
local frame = GetRaidUnit(num, true)
if (frame) then
GetRaidGroup(subgroup, true)
local localClass, class = UnitClass("raid"..num)
if (class and not ClassNames[class]) then
ClassNames[class] = localClass
end
if (name and subgroup and subgroup >= 1 and subgroup <= NUM_RAID_GROUPS) then
local wasShowing = frame.showing
frame.showing = XPerlConfig["ShowGroup"..subgroup]
MoveCell(frame, subgroup, wasShowing)
RaidGroupCounts[subgroup] = RaidGroupCounts[subgroup] + 1
else
frame.showing = 0
end
end
else
local frame = GetRaidUnit(num)
if (frame) then
frame.showing = 0
end
end
end
for index = 1,NUM_RAID_GROUPS do
local frame = getglobal(XPERL_RAIDGRP_PREFIX..index.."_NameFrame_NameBarText")
if (frame) then
frame:SetText(string.format(XPERL_RAID_GROUP, index))
end
end
end
-- XPerl_Raid_Position()
function XPerl_Raid_Position()
SetRaidRoster()
RaidGroupCounts = {0,0,0,0,0,0,0,0,0}
if (XPerlConfig.SortRaidByClass==1) then
XPerl_Raid_Classes()
else
XPerl_Raid_Groups()
end
if (GetNumRaidMembers() == 0 or XPerlConfig.ShowRaid == 0) then
XPerl_Raid_Frame:Hide()
else
XPerl_Raid_Frame:Show()
for num=1,MAX_RAID_MEMBERS do
local frame = getglobal(XPERL_RAIDMEMBER_PREFIX..num)
if (frame) then
if (frame.showing == 1) then
frame:Show()
XPerl_Raid_UpdateDisplay(frame)
else
frame:Hide()
end
end
end
end
XPerl_RaidTitles()
Last_Roster = nil
for i,unit in XPerl_Roster do
unit.lastPos = nil
end
end
--------------------
-- Click Handlers --
--------------------
function XPerl_CT_RATab_newRaidFrameDropDown_Initialize()
XPerl_RaidFrameDropDown_Initialize(true)
end
function XPerl_RaidFrameDropDown_Initialize(ct)
if (type(UIDROPDOWNMENU_MENU_VALUE) == "table" and UIDROPDOWNMENU_MENU_VALUE[1] == "Main Tanks") then
local info = {}
info.text = XPERL_RAID_DROPDOWN_MAINTANKS
info.isTitle = 1
UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL)
for i = 1,10 do
info = {}
if (XPerl_MainTanks[i] and XPerl_MainTanks[i][2] == UIDROPDOWNMENU_MENU_VALUE[2]) then
info.text = string.format("|c00FFFF80"..XPERL_RAID_DROPDOWN_REMOVEMT.."|r", i)
info.value = {UIDROPDOWNMENU_MENU_VALUE[1], UIDROPDOWNMENU_MENU_VALUE[2], i, 1}
else
info.text = string.format(XPERL_RAID_DROPDOWN_SETMT, i)
info.value = {UIDROPDOWNMENU_MENU_VALUE[1], UIDROPDOWNMENU_MENU_VALUE[2], i}
end
info.func = XPerl_MainTankSet_OnClick
UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL)
end
return
end
oldRaidFrameDropDown_Initialize()
if (IsRaidOfficer()) then
if (DropDownList1.numButtons > 0) then
-- We want our MT option above the Cancel option, so we trick the menu into thinking it's got 1 less button
DropDownList1.numButtons = DropDownList1.numButtons - 1
end
info = {}
info.text = XPERL_RAID_DROPDOWN_MAINTANKS
info.value = {"Main Tanks", this.name}
info.hasArrow = 1
info.notCheckable = 1
UIDropDownMenu_AddButton(info)
-- Re-add the cancel button after our MT option
info = {}
info.text = CANCEL
info.value = "CANCEL"
info.owner = "RAID"
info.func = UnitPopup_OnClick
info.notCheckable = 1
UIDropDownMenu_AddButton(info)
end
if (ct and CT_RATab_AutoPromotions) then
local info = {}
info.text = "Auto-Promote"
info.checked = CT_RATab_AutoPromotions[this.name]
info.value = this.id
info.func = CT_RATab_AutoPromote_OnClick
UIDropDownMenu_AddButton(info)
end
end
-- XPerl_MainTankSet_OnClick
function XPerl_MainTankSet_OnClick()
if (this.value[1] == "Main Tanks") then
if (this.value[4]) then
SendAddonMessage("CTRA", "R "..this.value[2], "RAID")
else
SendAddonMessage("CTRA", "SET "..this.value[3].." "..this.value[2], "RAID")
end
end
CloseMenus()
end
-- ShowPopup
local function ShowPopup(thisFrame)
HideDropDownMenu(1)
FriendsDropDown.initialize = RaidFrameDropDown_Initialize
FriendsDropDown.displayMode = "MENU"
this.unit = thisFrame.partyid
this.name = UnitName(thisFrame.partyid)
local _, _, id = strfind(thisFrame.partyid, "(%d+)")
this.id = id
ToggleDropDownMenu(1, nil, FriendsDropDown, thisFrame:GetName(), 0, 0)
this.unit, this.name, this.id = nil, nil, nil
end
-- XPerl_Raid_OnClick
function XPerl_Raid_OnClick()
local thisFrame = this:GetParent()
local unitid = thisFrame.partyid
if (not XPerl_OnClick_Handler(arg1, unitid)) then
if (arg1 == "RightButton" and not thisFrame.pet) then
ShowPopup(thisFrame)
end
end
end
-- XPerl_ScaleRaid
function XPerl_ScaleRaid(num)
for frame=1,NUM_RAID_GROUPS do
local f = GetRaidGroup(frame)
if (f) then
f:SetScale(num)
end
end
for id,f in pairs(FrameArray) do
f:SetScale(num)
end
for name,f in pairs(PulloutFrameArray) do
f:SetScale(num)
end
end
-- XPerl_RaidTitles
function XPerl_RaidTitles()
for i = 1,NUM_RAID_GROUPS do
local frame = GetRaidGroup(i)
if (frame) then
frame:SetAlpha(XPerlConfig.Transparency)
if (MovingMember or XPerlLocked == 0 or (XPerlConfig.ShowRaidTitles == 1 and RaidGroupCounts[i] > 0 and XPerlConfig["ShowGroup"..i] == 1)) then
frame:Show()
else
frame:Hide()
end
end
end
end
-- XPerl_RaidShowAllTitles
function XPerl_RaidShowAllTitles()
for i = 1,NUM_RAID_GROUPS do
GetRaidGroup(i, true)
end
XPerl_RaidTitles()
end
-- Moving stuff
function XPerl_Raid_GetGap()
if (XPerl_Raid_Grp1 and XPerl_Raid_Grp2) then
return math.floor((math.floor((XPerl_Raid_Grp2:GetLeft() - XPerl_Raid_Grp1:GetRight() + 0.01) * 100) / 100) + 4)
end
return (0)
end
-- InterestingFrames
local function InterestingFrames()
local interest = XPerl_Options.raidAlign
local ret = {}
if (interest == "all") then
for i = 1,NUM_RAID_GROUPS do
tinsert(ret, GetRaidGroup(i, true))
end
elseif (interest == "odd") then
for i = 1,NUM_RAID_GROUPS,2 do
tinsert(ret, GetRaidGroup(i, true))
end
elseif (interest == "even") then
for i = 2,NUM_RAID_GROUPS,2 do
tinsert(ret, GetRaidGroup(i, true))
end
elseif (interest == "first4") then
for i = 1,4 do
tinsert(ret, GetRaidGroup(i, true))
end
elseif (interest == "last4") then
for i = 5,NUM_RAID_GROUPS do
tinsert(ret, GetRaidGroup(i, true))
end
end
return ret
end
-- XPerl_Raid_SetGap
function XPerl_Raid_SetGap(newGap)
if (not XPerl_Raid_Grp1) then
return
end
if (type(newGap) == "number") then
local frames = InterestingFrames()
local left = frames[1]:GetLeft()
local framePrev
for i,frame in pairs(frames) do
if (framePrev and frame) then
local right = framePrev:GetRight()
local top = frame:GetTop()
frame:ClearAllPoints()
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", right + newGap - 4, top)
end
framePrev = frame
end
SaveAllPositions()
end
end
-- XPerl_Raid_AlignTop
function XPerl_Raid_AlignTop()
if (not XPerl_Raid_Grp1) then
return
end
local frames = InterestingFrames()
local top = frames[1]:GetTop()
for i,frame in pairs(frames) do
local left = frame:GetLeft()
frame:ClearAllPoints()
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", left, top)
end
SaveAllPositions()
end
-- XPerl_Raid_SetBuffTooltip
function XPerl_Raid_SetBuffTooltip ()
local partyid = this:GetParent():GetParent().partyid
GameTooltip:SetOwner(this,"ANCHOR_BOTTOMRIGHT",30,0)
local show, cureCast = GetShowCast(this:GetParent():GetParent())
if (show == "b") then
XPerl_TooltipSetUnitBuff(GameTooltip, partyid, this:GetID(), cureCast)
XPerl_Raid_AddBuffDuration(partyid)
elseif (show == "d") then
XPerl_TooltipSetUnitDebuff(GameTooltip, partyid, this:GetID(), cureCast)
end
end
------- XPerl_ToggleRaidBuffs -------
-- Raid Buff Key Binding function --
function XPerl_ToggleRaidBuffs(castable)
if (castable) then
if (XPerlConfig.BuffsCastableCurable == 1) then
XPerlConfig.BuffsCastableCurable = 0
XPerl_Notice(XPERL_KEY_NOTICE_RAID_BUFFANY)
else
XPerlConfig.BuffsCastableCurable = 1
XPerl_Notice(XPERL_KEY_NOTICE_RAID_BUFFCURECAST)
end
else
if (XPerlConfig.RaidBuffs == 1) then
XPerlConfig.RaidBuffs = 0
XPerlConfig.RaidDebuffs = 1
XPerl_Notice(XPERL_KEY_NOTICE_RAID_DEBUFFS)
elseif (XPerlConfig.RaidDebuffs == 1) then
XPerlConfig.RaidDebuffs = 0
XPerlConfig.RaidBuffs = 0
XPerl_Notice(XPERL_KEY_NOTICE_RAID_NOBUFFS)
else
XPerlConfig.RaidBuffs = 1
XPerlConfig.RaidDebuffs = 0
XPerl_Notice(XPERL_KEY_NOTICE_RAID_BUFFS)
end
end
for i = 1,GetNumRaidMembers() do
local frame = GetRaidUnit(i)
if (frame) then
XPerl_Raid_UpdateDisplay(frame)
end
end
end
-- GetCombatRezzerList()
local normalRezzers = {PRIEST = true, SHAMAN = true, PALADIN = true}
local function GetCombatRezzerList()
local anyCombat = 0
local anyAlive = 0
for i = 1,GetNumRaidMembers() do
local _, class = UnitClass("raid"..i)
if (normalRezzers[class]) then
if (UnitAffectingCombat("raid"..i)) then
anyCombat = anyCombat + 1
end
if (not UnitIsDeadOrGhost("raid"..i) and UnitIsConnected("raid"..i)) then
anyAlive = anyAlive + 1
end
end
end
-- We only need to know about battle rezzers if any normal rezzers are in combat
if (anyCombat > 0) then
local ret = {}
local t = GetTime()
for i = 1,GetNumRaidMembers() do
if (not UnitIsDeadOrGhost("raid"..i) and UnitIsVisible("raid"..i)) then
local name, rank, subgroup, level, _, fileName, zone, online, isDead = GetRaidRosterInfo(i)
local good
if (not UnitAffectingCombat("raid"..i)) then
if (fileName == "PRIEST" or fileName == "SHAMAN" or fileName == "PALADIN") then
tinsert(ret, {["name"] = name, class = fileName, cd = 0})
end
else
if (fileName == "DRUID") then
local myRoster = XPerl_Roster[name]
if (myRoster) then
if (myRoster.Rebirth and myRoster.Rebirth - t <= 0) then
myRoster.Rebirth = nil -- Check for expired cooldown
end
if (myRoster.Rebirth) then
if (myRoster.Rebirth - t < 120) then
tinsert(ret, {["name"] = name, cd = myRoster.Rebirth - t})
end
else
tinsert(ret, {["name"] = name, class = fileName, cd = 0})
end
end
end
end
end
end
if (getn(ret) > 0) then
sort(ret, function(a,b) return a.cd < b.cd end)
local list = ""
for k,v in pairs(ret) do
local name = XPerlColourTable[v.class]..v.name.."|r"
if (v.cd > 0) then
name = name.." (in "..SecondsToTime(v.cd)..")"
end
if (list == "") then
list = name
else
list = list..", "..name
end
end
return list
else
return "|c00FF0000"..NONE.."|r"
end
end
if (anyAlive == 0) then
return "|c00FF0000"..NONE.."|r"
elseif (anyCombat == 0) then
return "|c00FFFFFF"..ALL.."|r"
end
end
-- XPerl_RaidTipExtra
function XPerl_RaidTipExtra(unitid)
if (UnitInRaid(unitid)) then
local unitName = UnitName(unitid)
local zone
local name, rank, subgroup, level, class, fileName, zone, online, isDead
for i = 1,GetNumRaidMembers() do
name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i)
if (name == unitName) then
break
end
zone = ""
end
local stats = XPerl_Roster[unitName]
if (stats) then
local t = GetTime()
if (stats.version) then
if (stats.oRAversion) then
GameTooltip:AddLine("CTRA "..stats.version.." (oRA "..stats.oRAversion..")", 1, 1, 1)
else
GameTooltip:AddLine("CTRA "..stats.version, 1, 1, 1)
end
else
GameTooltip:AddLine(XPERL_RAID_TOOLTIP_NOCTRA, 0.7, 0.7, 0.7)
end
if (stats.offline and UnitIsConnected(unitid)) then
stats.offline = nil
end
if (stats.offline) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_OFFLINE, SecondsToTime(t - stats.offline)))
elseif (stats.afk) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_AFK, SecondsToTime(t - stats.afk)))
elseif (stats.dnd) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_DND, SecondsToTime(t - stats.dnd)))
elseif (stats.fd) then
if (not UnitIsDead(unitid)) then
stats.fd = nil
else
local x = stats.fd + 360 - t
if (x > 0) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_DYING, SecondsToTime(x)))
end
end
end
if (stats.Rebirth) then
if (stats.Rebirth - t > 0) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_REBIRTH, SecondsToTime(stats.Rebirth - t)))
else
stats.Rebirth = nil
end
elseif (stats.Reincarnation) then
if (stats.Reincarnation - t > 0) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_ANKH, SecondsToTime(stats.Reincarnation - t)))
else
stats.Reincarnation = nil
end
elseif (stats.Soulstone) then
if (stats.Soulstone - t > 0) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_SOULSTONE, SecondsToTime(stats.Soulstone - t)))
else
stats.Soulstone = nil
end
end
if (UnitIsDeadOrGhost(unitid)) then
if (stats.resCount) then
GameTooltip:AddLine(XPERL_LOC_RESURRECTED.." x"..stats.resCount)
end
local Rezzers = GetCombatRezzerList()
if (Rezzers) then
GameTooltip:AddLine("Rezzers Available: "..Rezzers, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
end
end
end
GameTooltip:Show()
end
end
-- GetNamesWithoutBuff
local function GetNamesWithoutBuff(tex, with)
local matches = {
{"Holy_WordFortitude", "Holy_PrayerOfFortitude"},
{"Holy_MagicalSentry", "Holy_ArcaneIntellect"},
{"Shadow_AntiShadow", "Holy_PrayerofShadowProtection"},
{"Holy_DivineSpirit", "Holy_PrayerofSpirit"},
{"Holy_FistOfJustice", "Holy_GreaterBlessingofKings"},
{"Holy_SealOfWisdom", "Holy_GreaterBlessingofWisdom"},
{"Magic_MageArmor", "Magic_GreaterBlessingofKings"},
{"Holy_SealOfSalvation", "Holy_GreaterBlessingofSalvation"},
{"Holy_PrayerOfHealing02", "Holy_GreaterBlessingofLight"},
{"Nature_LightningShield", "Holy_GreaterBlessingofSanctuary"}
}
local count = 0
local names
local checkExpiring
local _, class = UnitClass("player")
if (IsRaidOfficer()) then
checkExpiring = {all = 5}
elseif (class == "PRIEST") then
checkExpiring = {Spell_Holy_WordFortitude = 5, Spell_Holy_PrayerOfFortitude = 5,
Spell_Holy_DivineSpirit = 2, Spell_Holy_PrayerofSpirit = 2,
Spell_Shadow_AntiShadow = 2, Spell_Holy_PrayerofShadowProtection = 2}
elseif (class == "DRUID") then
checkExpiring = {Spell_Nature_Regeneration = 5, Spell_Nature_Thorns = 2}
elseif (class == "MAGE") then
checkExpiring = {Spell_Holy_MagicalSentry = 5, Spell_Holy_ArcaneIntellect = 5, Spell_Holy_FlashHeal = 2, Spell_Nature_AbolishMagic = 2}
elseif (class == "PALADIN") then
checkExpiring = {Spell_Holy_Excorcism = 2,
Spell_Holy_FistOfJustice = 1, Spell_Holy_GreaterBlessingofKings = 1,
Spell_Holy_SealOfWisdom = 1, Spell_Holy_GreaterBlessingofWisdom = 1,
Spell_Magic_MageArmor = 1, Spell_Magic_GreaterBlessingofKings = 1,
Spell_Holy_SealOfSalvation = 1, Spell_Holy_GreaterBlessingofSalvation = 1,
Spell_Holy_PrayerOfHealing02 = 1, Spell_Holy_GreaterBlessingofLight = 1,
Spell_Nature_LightningShield = 1, Spell_Holy_GreaterBlessingofSanctuary = 1}
end
for i = 1,GetNumRaidMembers() do
local name = UnitName("raid"..i)
local _, unitClass = UnitClass("raid"..i)
if (name and UnitIsConnected("raid"..i) and not UnitIsDeadOrGhost("raid"..i)) then
local hasBuff
for num = 1,25 do
local buffTexture = UnitBuff("raid"..i, num)
if (not buffTexture) then
break
end
if (buffTexture == tex) then
hasBuff = true
break
else
for dups,pair in pairs(matches) do
if (tex == "Interface\\Icons\\Spell_"..pair[1] or tex == "Interface\\Icons\\Spell_"..pair[2]) then
if (buffTexture == "Interface\\Icons\\Spell_"..pair[1] or buffTexture == "Interface\\Icons\\Spell_"..pair[2]) then
hasBuff = true
end
end
end
if (hasBuff) then
if (without and checkExpiring) then
local found = checkExpiring.all
if (not found) then
found = checkExpiring[strsub(buffTexture, 23)]
end
if (found) then
local myRoster = XPerl_Roster[name]
if (myRoster and myRoster.Buffs) then
local buffName
for k,v in pairs(XPerl_CTBuffTextures) do
if (v[1] == "Interface\\Icons\\"..buffTexture) then
buffName = k
break
end
end
if (buffName) then
if (myRoster.Buffs[buffName]) then
local expire = myRoster.Buffs[buffName]
if (expire > GetTime() + (found*60)) then
GameTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_BUFFEXPIRING, XPerlColourTable[unitClass]..name.."|c", buffName, SecondsToTime(buff - GetTime())), 1, 0.2, 0)
end
end
end
end
end
end
break
end
end
end
if ((with and hasBuff) or (not with and not hasBuff)) then
count = count + 1
local _, class = UnitClass("raid"..i)
if (class) then
names = (names or "")..XPerlColourTable[class]..name.." "
else
names = (names or "")..name.." "
end
end
end
end
return names, count
end
-- XPerl_Raid_AddBuffDuration
function XPerl_Raid_AddBuffDuration(partyid, x)
local XTooltip
if (x) then
XTooltip = x
else
XTooltip = GameTooltip
end
if (UnitInRaid("player") and XTooltip:IsOwned(this)) then
if (partyid ~= "player") then
local stats = XPerl_Roster[UnitName(partyid)]
if (stats and stats.Buffs) then
local buffName = getglobal("GameTooltipTextLeft1"):GetText()
if (buffName) then
local buff = stats.Buffs[buffName]
if (buff) then
if (buff > GetTime()) then
XTooltip:AddLine(SecondsToTime(buff - GetTime())..XPERL_RAID_TOOLTIP_REMAINING, 1, 0.82, 0)
end
end
end
end
end
if (XPerlConfig.BuffTooltipHelper == 1 and partyid and UnitInRaid(partyid)) then
local icon = getglobal(this:GetName().."Icon")
if (icon) then
local tex = icon:GetTexture()
if (tex) then
local names, count = GetNamesWithoutBuff(tex, IsAltKeyDown())
if (names) then
if (IsAltKeyDown()) then
XTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_WITHBUFF, count), 0.3, 1, 0.2)
else
XTooltip:AddLine(string.format(XPERL_RAID_TOOLTIP_WITHOUTBUFF, count), 1, 0.3, 0.1)
end
XTooltip:AddLine(names, 0.8, 0.5, 0.4, 1)
end
end
end
end
XTooltip:Show()
end
end
-- XPerl_Raid_Set_Bits
function XPerl_Raid_Set_Bits()
local msgs = { "UNIT_DISPLAYPOWER",
"UNIT_MANA", "UNIT_MAXMANA",
"UNIT_ENERGY", "UNIT_MAXENERGY",
"UNIT_RAGE", "UNIT_MAXRAGE"}
for i,msg in pairs(msgs) do
if (XPerlConfig.RaidMana == 1) then
XPerl_Raid_Frame:RegisterEvent(msg)
else
XPerl_Raid_Frame:UnregisterEvent(msg)
end
end
for i,frame in pairs(FrameArray) do
Setup1RaidFrame(frame)
if (frame.showing == 1) then
XPerl_Raid_UpdateName(frame)
end
end
for i,frame in pairs(PulloutFrameArray) do
Setup1RaidFrame(frame)
if (frame.showing == 1) then
XPerl_Raid_UpdateName(frame)
end
end
end
-- Blizzard raid pullout replacements
local PetClasses = {HUNTER = true, WARLOCK = true}
function XPerl_ReplaceBlizzardPullouts()
-- RaidPullout_GenerateGroupFrame(groupID)
RaidPullout_GenerateGroupFrame = function(groupID)
local pets = (IsControlKeyDown() == 1)
-- construct the button listing
if ( not groupID ) then
groupID = this:GetParent():GetID()
end
-- Get a handle on a pullout frame
local pullOutFrame = RaidPullout_GetFrame(groupID)
if ( pullOutFrame ) then
pullOutFrame.filterID = groupID
pullOutFrame.showBuffs = nil
-- Set pullout name
local title = GROUP.." "..groupID
if (pets) then
title = title.." "..PET
end
getglobal(pullOutFrame:GetName().."Name"):SetText(title)
-- TODO Title scale to 0.75, but we can't set scale of a fontstring
if (RaidPullout_Update(pullOutFrame, pets)) then
return pullOutFrame
end
end
end
RaidPullout_GenerateClassFrame = function(class, fileName)
local pets = (IsControlKeyDown() == 1)
-- construct the button listing
if ( not class ) then
class = this:GetParent().class;
end
if (pets and not PetClasses[fileName]) then -- not AnyPets(fileName)) then
return
end
-- Get a handle on a pullout frame
local pullOutFrame = RaidPullout_GetFrame(fileName);
if ( pullOutFrame ) then
pullOutFrame.filterID = fileName;
pullOutFrame.showBuffs = nil;
-- Set pullout name
if (pets) then
class = class.." "..PET
end
getglobal(pullOutFrame:GetName().."Name"):SetText(class);
-- TODO Title scale to 0.75, but we can't set scale of a fontstring
if ( RaidPullout_Update(pullOutFrame, pets) ) then
return pullOutFrame;
end
end
end
RaidPullout_GetFrame = function(groupID)
-- Grab an available pullout frame
local frame;
for i=1, NUM_RAID_PULLOUT_FRAMES do
frame = getglobal("RaidPullout"..i);
-- if frame is visible see if its group id is already taken
if ( frame:IsVisible() and filterID == frame.filterID ) then
return nil;
end
end
for i=1, NUM_RAID_PULLOUT_FRAMES do
frame = getglobal("RaidPullout"..i);
if ( not frame:IsVisible() ) then
return frame;
end
end
NUM_RAID_PULLOUT_FRAMES = NUM_RAID_PULLOUT_FRAMES + 1;
frame = CreateFrame("Button", "RaidPullout"..NUM_RAID_PULLOUT_FRAMES, UIParent, "RaidPulloutFrameTemplate");
frame.numPulloutButtons = 0;
local f = getglobal("RaidPullout"..NUM_RAID_PULLOUT_FRAMES.."MenuBackdrop")
f:Hide()
return frame;
end
RaidPullout_Update = function(pullOutFrame, pets)
if ( not pullOutFrame ) then
pullOutFrame = this
end
if (pets ~= nil) then
pullOutFrame.pets = pets
end
pets = pullOutFrame.pets
local filterID = pullOutFrame.filterID
local numPulloutEntries = 0
if ( RAID_SUBGROUP_LISTS[filterID] ) then
numPulloutEntries = getn(RAID_SUBGROUP_LISTS[filterID])
end
local pulloutList = RAID_SUBGROUP_LISTS[filterID]
-- Hide the pullout if no entries
if ( numPulloutEntries == 0 ) then
pullOutFrame:Hide()
return nil
end
-- Fill out the buttons
local pulloutButton, pulloutButtonName, color, unit, pulloutHealthBar, pulloutManaBar, unitHPMin, unitHPMax
local name, rank, subgroup, level, class, fileName, zone, online, isDead
local debuff
if (numPulloutEntries > pullOutFrame.numPulloutButtons) then
local index = pullOutFrame.numPulloutButtons + 1
local relative
for i = index, numPulloutEntries do
pulloutButton = CreateFrame("Frame", pullOutFrame:GetName().."Button"..i, pullOutFrame, "XPerl_Raid_FrameTemplate")
PulloutFrameArray[pulloutButton:GetName()] = pulloutButton
if (i == 1) then
pulloutButton:SetPoint("TOP", pullOutFrame, "TOP", 0, 0)
else
relative = getglobal(pullOutFrame:GetName().."Button"..(i-1).."_StatsFrame")
pulloutButton:SetPoint("TOP", relative, "BOTTOM", 0, 4)
end
end
pullOutFrame.numPulloutButtons = numPulloutEntries;
end
local j = 1
for i = 1,numPulloutEntries do
pulloutButton = getglobal(pullOutFrame:GetName().."Button"..j)
if (pulloutButton) then
local _, ownerClass = UnitClass("raid"..pulloutList[i])
if (not pets or PetClasses[ownerClass]) then
pulloutButton.showing = 1
pulloutButton:SetScale(XPerlConfig.Scale_Raid)
Setup1RaidFrame(pulloutButton)
pulloutButton.petname = nil
if (pets) then
XPerl_Raid_Frame:RegisterEvent("UNIT_PET")
pulloutButton.partyid = "raidpet"..pulloutList[i]
pulloutButton.petOwner = "raid"..pulloutList[i]
pulloutButton.pet = true
else
pulloutButton.partyid = "raid"..pulloutList[i]
pulloutButton.pet = nil
pulloutButton.petOwner = nil
end
XPerl_Raid_UpdateDisplay(pulloutButton)
pulloutButton:Show()
j = j + 1
end
end
end
for i = j,pullOutFrame.numPulloutButtons do
pulloutButton = getglobal(pullOutFrame:GetName().."Button"..i)
if (pulloutButton) then
pulloutButton.showing = 0
pulloutButton:Hide()
end
end
pullOutFrame:SetHeight(1)
pullOutFrame:Show()
return 1
end
RaidPulloutDropDown_Initialize = function()
if ( not UIDROPDOWNMENU_OPEN_MENU or not getglobal(UIDROPDOWNMENU_OPEN_MENU).raidPulloutDropDown ) then
return;
end
local currentPullout = getglobal(UIDROPDOWNMENU_OPEN_MENU):GetParent();
local info;
-- Show buffs or debuffs they are exclusive for now
info = {};
info.text = SHOW_BUFFS;
info.func = function()
currentPullout.showBuffs = 1;
RaidPullout_Update(currentPullout);
end;
if ( currentPullout.showBuffs ) then
info.checked = 1;
end
UIDropDownMenu_AddButton(info);
info = {};
info.text = SHOW_DEBUFFS;
info.func = function()
currentPullout.showBuffs = nil;
RaidPullout_Update(currentPullout);
end;
if ( not currentPullout.showBuffs ) then
info.checked = 1;
end
UIDropDownMenu_AddButton(info);
-- Castable/Curable
info = {};
if (currentPullout.showBuffs) then
info.text = SHOW_CASTABLE_BUFFS_TEXT
else
info.text = SHOW_DISPELLABLE_DEBUFFS_TEXT
end
info.func = function()
currentPullout.cureCast = not currentPullout.cureCast
RaidPullout_Update(currentPullout);
end;
if (currentPullout.cureCast) then
info.checked = 1;
end
UIDropDownMenu_AddButton(info);
-- Pets
info = {}
if (currentPullout.pets) then
info.text = "Show Owners"
else
info.text = "Show Pets"
end
info.func = function()
currentPullout.pets = not currentPullout.pets
RaidPullout_Update(currentPullout)
local titleFrame = getglobal(currentPullout:GetName().."Name")
local title = titleFrame:GetText()
if (currentPullout.pets) then
title = title.." "..PET
else
title = string.gsub(title, " "..PET, "")
end
titleFrame:SetText(title)
end;
if (currentPullout.pets) then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
-- Close option
info = {};
info.text = CLOSE;
info.func = function()
currentPullout:Hide();
end;
UIDropDownMenu_AddButton(info);
end
end