local SavedRoster = nil local XswapCount = 0 local XmoveCount = 0 local XPendingRosters = 0 local WaitingForRoster -- AdminCommands local function AdminCommands(msg) local args = {} for value in string.gfind(msg, "[^ ]+") do tinsert(args, string.lower(value)) end if (not args[1]) then XPerl_AdminFrame:Show() else if (not XPerl_AdminCommands[args[1]] or not XPerl_AdminCommands[args[1]](args[2], args[3], args[4])) then XPerl_AdminCommands.help() end end end -- DefaultVar local function DefaultVar(name, value) if (XPerl_Admin[name] == nil or (type(value) ~= type(XPerl_Admin[name]))) then XPerl_Admin[name] = value end end -- Defaults local function Defaults() if (not XPerl_Admin) then XPerl_Admin = {} end DefaultVar("AutoHideShow", 1) DefaultVar("SavedRosters", {}) DefaultVar("Transparency", 0.8) DefaultVar("Scale_ItemCheck", 1) DefaultVar("Scale_Admin", 1) end -- XPerl_AdminOnLoad function XPerl_AdminOnLoad() XPerl_Admin = {} SlashCmdList["XPERLRAIDADMIN"] = AdminCommands SLASH_XPERLRAIDADMIN1 = "/rad" SLASH_XPERLRAIDADMIN2 = "/xpadmin" SLASH_XPERLRAIDADMIN3 = "/xpad" this:RegisterEvent("VARIABLES_LOADED") this:RegisterEvent("RAID_ROSTER_UPDATE") end -- XPerl_AdminStartup local function XPerl_AdminStartup() Defaults() XPerl_AdminFrame_TitleBar_Pin:SetButtonTex() XPerl_Check_Setup() XPerl_AdminSetupFrames() end -- XPerl_SetupFrameSimple function XPerl_SetupFrameSimple(argFrame, alpha) argFrame:SetBackdropBorderColor(0.5, 0.5, 0.5, alpha or 1) argFrame:SetBackdropColor(0, 0, 0, alpha or 1) end -- XPerl_AdminSetupFrames() function XPerl_AdminSetupFrames() XPerl_SetupFrameSimple(XPerl_Check) XPerl_SetupFrameSimple(XPerl_CheckListItems) XPerl_SetupFrameSimple(XPerl_CheckListPlayers) XPerl_SetupFrameSimple(XPerl_AdminFrame) XPerl_Check:SetAlpha(XPerl_Admin.Transparency) XPerl_AdminFrame:SetAlpha(XPerl_Admin.Transparency) XPerl_Check:SetScale(XPerl_Admin.Scale_ItemCheck) XPerl_AdminFrame:SetScale(XPerl_Admin.Scale_Admin) end -- XPerl_Help local function XPerl_Help() XPerl_Message("/rad [save | load name] [auto]") end -- CheckMyRank local function CheckMyRank() if (XPerl_Admin.AutoHideShow == 1) then if (GetNumRaidMembers() > 0) then local me = UnitName("player") for i = 1,GetNumRaidMembers() do local name, rank = GetRaidRosterInfo(i) if (name == me) then if (rank > 0) then XPerl_AdminFrame:Show() else XPerl_AdminFrame:Hide() end break end end else XPerl_AdminFrame:Hide() end end end -- XPerl_ToggleAuto local function XPerl_ToggleAuto() if (XPerl_Admin.AutoHideShow == 1) then XPerl_Admin.AutoHideShow = 0 else XPerl_Admin.AutoHideShow = 1 end CheckMyRank() end -- XPerl_SaveRoster function XPerl_SaveRoster(saveName) if (not saveName or saveName == "") then local hours, mins = GetGameTime() saveName = hours..":"..mins end local Roster = {} for i = 1,GetNumRaidMembers() do local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i) Roster[name] = {group = subgroup, class = fileName} end if (not XPerl_Admin.SavedRosters) then XPerl_Admin.SavedRosters = {} end XPerl_Admin.SavedRosters[saveName] = Roster XPerl_Message(string.format(XPERL_SAVED_ROSTER, saveName)) return true end local function LoadRoster() --ChatFrame7:AddMessage("Arranging...") local swapCount = 0 local moveCount = 0 local CurrentRoster = {} local CurrentGroups = {} local FreeFloating = {} -- Store the current raid roster, and a list of players in the raid, but not in the saved roster for i = 1,GetNumRaidMembers() do local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i) CurrentRoster[name] = {index = i, group = subgroup, class = fileName} if (not SavedRoster[name]) then -- Not in the saved roster, so doesn't matter where FreeFloating[name] = {group = subgroup, class = fileName} end end local function Swap(a, b) --ChatFrame7:AddMessage("Swapping: "..a.." (Grp"..CurrentRoster[a].group..") with "..b.." (Grp"..CurrentRoster[b].group..")") SwapRaidSubgroup(CurrentRoster[a].index, CurrentRoster[b].index) local save = CurrentRoster[b].group CurrentRoster[b].group = CurrentRoster[a].group CurrentRoster[b].moved = true CurrentRoster[a].group = save CurrentRoster[a].moved = true if (FreeFloating[a]) then FreeFloating[a].group = CurrentRoster[a].group end if (FreeFloating[b]) then FreeFloating[b].group = CurrentRoster[b].group end swapCount = swapCount + 1 end local function Move(name, target) --ChatFrame7:AddMessage("Moving: "..name.." (Grp"..CurrentRoster[name].group..") to group "..target) SetRaidSubgroup(CurrentRoster[name].index, target) CurrentRoster[name].group = target CurrentRoster[name].moved = true if (FreeFloating[name]) then FreeFloating[name].group = target end moveCount = moveCount + 1 end local function GroupCount(grp) local count = 0 for name,entry in pairs(CurrentRoster) do if (entry.group == grp) then count = count + 1 end end return count end for nameSaved, saved in SavedRoster do local name = nameSaved local group = saved.group if (not CurrentRoster[name]) then -- Saved player not in raid, so find someone of the same class in the free floater list for floaterName,floater in pairs(FreeFloating) do if (floater.class == saved.class) then name = floaterName FreeFloating[name] = nil break end end end if (CurrentRoster[name] and not CurrentRoster[name].moved) then if (CurrentRoster[name].group == group) then CurrentRoster[name].moved = true; -- They're in right group already elseif (not FreeFloating[name]) then -- First see if we can directly swap any 2 players local swapName for name2, saved2 in SavedRoster do if (name ~= name2) then if (CurrentRoster[name] and CurrentRoster[name].group == saved2.group) then if (CurrentRoster[name2] and CurrentRoster[name2].group == group) then swapName = name2 break end end end end if (swapName) then Swap(name, swapName) --break else local done -- Nothing suitable found to swap, see if target group has space if (GroupCount(group) < 5) then Move(name, group) done = true --break end -- No space in target group, put them anywhere if (not done) then for i = 1,8 do if (CurrentRoster[name].group ~= i and GroupCount(i) < 5) then Move(name, i) done = true break end end end if (not done) then -- Nothing done yet, see if we can swap a free floater local free for name, group in pairs(FreeFloating) do if (group ~= CurrentRoster[name].group) then free = name break end end if (free) then Swap(CurrentRoster[name].index, CurrentRoster[free].index) --break else -- Couldn't put them anywhere, add them to floater list FreeFloating[name] = group end --else -- break end end end end --if (moveCount > 0) then -- or swapCount > 0) then -- break --end end if (moveCount == 0 and swapCount == 0) then --ChatFrame7:AddMessage("Finished!") XPerl_StopLoad() else WaitingForRoster = GetTime() XswapCount = XswapCount + swapCount XmoveCount = XmoveCount + moveCount XPendingRosters = XPendingRosters + swapCount XPendingRosters = XPendingRosters + moveCount end --ChatFrame7:AddMessage("Done arranging (swaps: "..swapCount..") (moves: "..moveCount..")") end -- XPerl_AdminOnEvent function XPerl_AdminOnEvent() CheckMyRank() if (event == "RAID_ROSTER_UPDATE") then XPerl_AdminFrame_Controls:Details() if (WaitingForRoster) then if (not XFinishedLoad) then XPendingRosters = XPendingRosters - 1 if (XPendingRosters < 1) then LoadRoster() end end end elseif (event == "VARIABLES_LOADED") then this:UnregisterEvent(event) XPerl_AdminStartup() end end -- XPerl_Admin_OnUpdate function XPerl_Admin_OnUpdate(elapsed) if (WaitingForRoster) then if (GetTime() > WaitingForRoster + 5000) then XPerl_StopLoad() end end end -- XPerl_LoadRoster function XPerl_LoadRoster(loadName) if (not XPerl_Admin.SavedRosters) then return end SavedRoster = XPerl_Admin.SavedRosters[loadName] if (SavedRoster) then XPerl_AdminFrame_Controls_StopLoad:Show() XPerl_AdminFrame_Controls_LoadRoster:Hide() XFinishedLoad = false WaitingForRoster = nil XPendingRosters = 0 LoadRoster() else if (not loadName) then XPerl_Message(XPERL_NO_ROSTER_NAME_GIVEN) else XPerl_Message(string.format(XPERL_NO_ROSTER_CALLED, loadName)) end end return true end -- XPerl_StopLoad function XPerl_StopLoad() XPerl_AdminFrame_Controls_StopLoad:Hide() XPerl_AdminFrame_Controls_LoadRoster:Show() XFinishedLoad = true WaitingForRoster = nil SavedRoster = nil XPendingRosters = 0 XPerl_AdminFrame_Controls:Details() end function XPerl_Message(msg) DEFAULT_CHAT_FRAME:AddMessage(XPERL_MSG_PREFIX.."- "..msg) end XPerl_AdminCommands = { save = XPerl_SaveRoster, load = XPerl_LoadRoster, auto = XPerl_ToggleAuto, help = XPerl_Help } -- XPerl_Admin_CountDifferences function XPerl_Admin_CountDifferences(rosterName) if (not XPerl_Admin.SavedRosters) then return end local count = 0 SavedRoster = XPerl_Admin.SavedRosters[rosterName] if (SavedRoster) then for i = 1,GetNumRaidMembers() do local name, rank, subgroup = GetRaidRosterInfo(i) if (SavedRoster[name]) then if (SavedRoster[name].group ~= subgroup) then count = count + 1 end else count = count + 1 end end return count end end function XPerl_Admin_ControlsOnLoad() this.Details = function() local name = XPerl_AdminFrame_Controls_Edit:GetText() local diff if (name) then diff = XPerl_Admin_CountDifferences(name) end if (diff) then XPerl_AdminFrame_Controls_DetailsText:SetText(string.format(XPERL_ADMIN_DIFFERENCES, diff)) XPerl_AdminFrame_Controls_Details:Show() else XPerl_AdminFrame_Controls_Details:Hide() end end this.MakeList = function() local index = 1; local find = XPerl_AdminFrame_Controls_Edit:GetText() local Offset = XPerl_AdminFrame_Controls_RosterScrollBarScrollBar:GetValue() for name,roster in pairs(XPerl_Admin.SavedRosters) do if (index - 1 >= Offset) then local f = getglobal("XPerl_AdminFrame_Controls_Roster"..index) if (f) then if (name == find) then f:LockHighlight() else f:UnlockHighlight() end f:SetText(name) f:Show() end end index = index + 1 end for i = index,5 do local f = getglobal("XPerl_AdminFrame_Controls_Roster"..i) if (f) then f:SetText("") f:UnlockHighlight() f:Hide() end end local offset = XPerl_AdminFrame_Controls_RosterScrollBarScrollBar:GetValue() if (FauxScrollFrame_Update(XPerl_AdminFrame_Controls_RosterScrollBar, index - 1, 5, 1)) then XPerl_AdminFrame_Controls_RosterScrollBar:Show() else XPerl_AdminFrame_Controls_RosterScrollBar:Hide() end XPerl_AdminFrame_Controls:Details() end this.Validate = function() XPerl_AdminFrame.Valid = false XPerl_AdminFrame_Controls_LoadRoster:Disable() XPerl_AdminFrame_Controls_DeleteRoster:Disable() local index = 1 local find = XPerl_AdminFrame_Controls_Edit:GetText() local Offset = XPerl_AdminFrame_Controls_RosterScrollBarScrollBar:GetValue() for name,roster in pairs(XPerl_Admin.SavedRosters) do if (index - 1 >= Offset) then local f = getglobal("XPerl_AdminFrame_Controls_Roster"..index) if (not f) then break end if (name == find) then f:LockHighlight() XPerl_AdminFrame.Valid = true if (IsRaidLeader()) then XPerl_AdminFrame_Controls_LoadRoster:Enable() end XPerl_AdminFrame_Controls_DeleteRoster:Enable() else f:UnlockHighlight() end end index = index + 1 end end end