vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
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