-- Broker_RaidMakeup.lua -- Written by KyrosKrane Sylvanblade (kyros@kyros.info) -- Copyright (c) 2018 KyrosKrane Sylvanblade -- Licensed under the MIT License, as per the included file. --######################################### --# Description --######################################### -- This add-on creates a LibDataBroker object that shows you the makeup of your raid (tanks, healers, and dps). -- Requires an LDB display to show the info. -- No configuration or setup. --######################################### --# Globals and utilities --######################################### -- Get a local reference to speed up execution. local _G = _G local string = string local print = print local setmetatable = setmetatable local select = select local type = type local pairs = pairs -- Define a global for our namespace local BRM = {} --######################################### --# Frame for event handling --######################################### -- Create the frame to hold our event catcher, and the list of events. BRM.Frame, BRM.Events = CreateFrame("Frame"), {} --######################################### --# Slash command options and settings --######################################### BRM.OptionsTable = { type = "group", args = { showcounts = { name = "Show counts in tooltip", desc = "Show the role counts in the tooltip as well as in the broker display", type = "toggle", set = function(info,val) BRM.DB.ShowCountInTooltip = val end, get = function(info) return BRM.DB.ShowCountInTooltip end, descStyle = "inline", width = "full", }, minimapicon = { name = "Show minimap icon", desc = "Show a minimap icon for " .. BRM.USER_ADDON_NAME, type = "toggle", set = function(info,val) BRM:SetMinimapButton(val) end, get = function(info) return (not BRM.DB.MinimapSettings.hide) end, descStyle = "inline", width = "full", }, -- minimapicon debug = { name = "Enable debug output", desc = "Prints extensive debugging output about everything " .. BRM.USER_ADDON_NAME .. " does", type = "toggle", set = function(info,val) BRM:SetDebugMode(val) end, get = function(info) return BRM.DebugMode end, descStyle = "inline", width = "full", hidden = true, }, -- debug } -- args } -- BRM.OptionsTable -- Process the options and create the AceConfig options table BRM.AceConfig = LibStub("AceConfig-3.0") BRM.AceConfig:RegisterOptionsTable(BRM.ADDON_NAME, BRM.OptionsTable, {"brm"}) -- Create the frame to set the options and add it to the Blizzard settings BRM.ConfigFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(BRM.ADDON_NAME, BRM.USER_ADDON_NAME) --######################################### --# Debugging setup --######################################### -- Debug settings -- This is needed to debug stuff before the addon loads. After the addon loads, the permanent value is stored in BRM.DB.DebugMode BRM.DebugMode = false --@alpha@ BRM.DebugMode = true --@end-alpha@ -- Print debug output to the chat frame. function BRM:DebugPrint(...) if not BRM.DebugMode then return end print ("|cff" .. "a00000" .. "BRM Debug:|r", ...) end -- BRM:DebugPrint -- Print regular output to the chat frame. function BRM:ChatPrint(...) print ("|cff" .. "0066ff" .. "BRM:|r", ...) end -- BRM:DebugPrint -- Debugging code to see what the hell is being passed in... function BRM:PrintVarArgs(...) if not BRM.DebugMode then return end local n = select('#', ...) BRM:DebugPrint ("There are ", n, " items in varargs.") local msg for i = 1, n do msg = select(i, ...) BRM:DebugPrint ("Item ", i, " is ", msg) end end -- BRM:PrintVarArgs() -- Dumps a table into chat. Not intended for production use. function BRM:DumpTable(tab, indent) if not BRM.DebugMode then return end if not indent then indent = 0 end if indent > 10 then BRM:DebugPrint("Recursion is at 11 already; aborting.") return end for k, v in pairs(tab) do local s = "" if indent > 0 then for i = 0, indent do s = s .. " " end end if "table" == type(v) then s = s .. "Item " .. k .. " is sub-table." BRM:DebugPrint(s) indent = indent + 1 BRM:DumpTable(v, indent) indent = indent - 1 else s = s .. "Item " .. k .. " is " .. tostring(v) BRM:DebugPrint(s) end end end -- BRM:DumpTable() -- Sets the debug mode and writes the setting to the DB function BRM:SetDebugMode(setting) BRM.DebugMode = setting BRM.DB.DebugMode = setting end --######################################### --# Icon class setup --######################################### -- The normal way of handling icons is to create a texture, load the icon file into that, set the region you want, and done. -- However, we need to embed icons into a text string for display in the LDB label. -- So, we create a custom object to hold icon information, and give it a method to create a text string to display that icon. -- That text string can then be embedded in the LDB label to show the icon. -- Create the object class -- Adapted from http://lua-users.org/wiki/ObjectOrientationTutorial local IconClass = {} IconClass.__index = IconClass setmetatable(IconClass, { __call = function (cls, ...) return cls.new(...) end, }) -- Create the constructor function IconClass.new(iconfile, IconFileX, IconFileY, StartX, EndX, StartY, EndY) local self = setmetatable({}, IconClass) -- The caller has to specify an iconfile before actually using the class, or the results will not be what is expected. self.IconFile = iconfile or "" -- the game file that has the icon we want -- The initial values are sane defaults, but they should be updated for each icon. -- These settings control the display of the icon self.SizeOne = 0 -- SizeOne and SizeTwo jointly control the size of the icon. The logic is not intuitive. self.SizeTwo = nil -- For more details on the SizeOne and SizeTwo parameters, see http://wowwiki.wikia.com/wiki/UI_escape_sequences#Textures -- For the purposes of our icons, they should always be 0 and nil (indicating a square sized to the height of the text). self.OffsetX = 0 -- This moves the image n pixels horizontally in the final display. For our icons, it's always 0. self.OffsetY = 0 -- This moves the image n pixels vertically in the final display. For our icons, it's always 0. -- These settings control the extraction of the icon from a bigger texture file self.IconFileX = IconFileX or 0 -- the total X (horizontal) pixels in the image file - not just the icon we want self.IconFileY = IconFileY or 0 -- the total Y (vertical) pixels in the image file self.StartX = StartX or 0 -- The starting point in the file where the icon begins, counted from the left border, in pixels self.EndX = EndX or 0 -- The ending point in the file where the icon ends, counted from the left border, in pixels self.StartY = StartY or 0 -- The starting point in the file where the icon begins, counted from the top border, in pixels self.EndY = EndY or 0 -- The ending point in the file where the icon ends, counted from the top border, in pixels return self end -- IconClass.new() function IconClass:GetIconStringInner() -- Icon strings effectively have to be built right to left, since if the rightmost parameters are required, then the ones to the left are also required. -- This function constructs the inner part of the icon string, without the control codes to cause it to display as an actual icon. -- This is mostly useful for debugging. In actual use, you'd want the GetIconString() function. local required = false -- tells us whether the remaining parameters are required local OutputString = ""; if required or self.StartX > 0 or self.StartY > 0 or self.EndX > 0 or self.EndY > 0 then required = true OutputString = string.format(":%d:%d:%d:%d", self.StartX, self.EndX, self.StartY, self.EndY) end if required or self.IconFileX > 0 or self.IconFileY > 0 then required = true OutputString = string.format(":%d:%d%s", self.IconFileX, self.IconFileY, OutputString) end if required or self.OffsetX > 0 or self.OffsetY > 0 then required = true OutputString = string.format(":%d:%d%s", self.OffsetX, self.OffsetY, OutputString) end -- Size2 can be nil, so to avoid comparing or concatenating a nil, we have some special handling local localsizetwo = self.SizeTwo or "" if required or (self.SizeTwo and self.SizeTwo >= 0) then OutputString = string.format(":%s%s", localsizetwo, OutputString) end -- Size1 and the icon path are required. OutputString = string.format("%s:%d%s", self.IconFile, self.SizeOne, OutputString) return OutputString end -- IconClass:GetIconStringInner() function IconClass:GetIconString() -- This function wraps the icon string in the control code that causes it to display as an icon return string.format("\124T%s\124t", self:GetIconStringInner()) end -- IconClass:GetIconString() -- @TODO: Add method to get the TexCoords of an icon for inclusion in the LDB object's iconCoords parameter. -- See: -- https://wow.gamepedia.com/API_Texture_SetTexCoord -- https://github.com/tekkub/libdatabroker-1-1/wiki/Data-Specifications --######################################### --# Select the actual icons used --######################################### -- The icons to use when displaying in the broker display BRM.MainIcon = IconClass("Interface\\Icons\\Inv_helm_robe_raidpriest_k_01") -- Placeholder icon to use until we determine the faction later. BRM.AllianceIcon = IconClass("Interface\\Calendar\\UI-Calendar-Event-PVP02") BRM.HordeIcon = IconClass("Interface\\Calendar\\UI-Calendar-Event-PVP01") -- Role icons BRM.TankIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 0, 0+19, 22, 22+19) BRM.HealerIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 19, 19+19, 1, 1+19) BRM.DPSIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-PORTRAITROLES.blp", 64, 64, 19, 19+19, 22, 22+19) BRM.UnknownIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-ROLES.blp", 256, 256, 135, 135+64, 67, 67+64) -- Icons I considered but didn't like --BRM.AllianceIcon = "Interface\\Icons\\Inv_misc_head_human_02" --BRM.HordeIcon = "Interface\\Icons\\Achievement_femalegoblinhead" --BRM.HealerIcon = "Interface\\Icons\\Spell_holy_flashheal.blp" --BRM.AllianceIcon = IconClass("Interface\\Icons\\Inv_tabard_a_78wrynnvanguard") --BRM.HordeIcon = IconClass("Interface\\Icons\\Inv_tabard_a_77voljinsspear") --BRM.TankIcon = IconClass("Interface\\Icons\\Inv_shield_06.blp") --BRM.HealerIcon = IconClass("Interface\\Icons\\spell_chargepositive.blp") --BRM.DPSIcon = IconClass("Interface\\Icons\\Inv_sword_27.blp") --BRM.UnknownIcon = IconClass("Interface\\Icons\\Inv_misc_questionmark.blp") -- These high res icons don't look very good when squished down to a broker display. The low-res ones above are better. --BRM.TankIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-ROLES.blp", 256, 256, 0, 0+64, 68, 68+64) --BRM.HealerIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-ROLES.blp", 256, 256, 68, 68+64, 0, 0+64) --BRM.DPSIcon = IconClass("Interface\\LFGFRAME\\UI-LFG-ICON-ROLES.blp", 256, 256, 68, 68+64, 68, 68+64) --######################################### --# Constants --######################################### -- The strings that define the addon BRM.ADDON_NAME="Broker_RaidMakeup" -- the internal addon name for LibStub and other addons BRM.USER_ADDON_NAME="Broker_RaidMakeup" -- the name displayed to the user -- The strings used by the game to represent the roles. I don't think these are localized in the game. BRM.ROLE_HEALER = "HEALER" BRM.ROLE_TANK = "TANK" BRM.ROLE_DPS = "DAMAGER" BRM.ROLE_NONE = "NONE" -- The faction strings. Again, probably not localized BRM.FACTION_ALLIANCE = "Alliance" BRM.FACTION_HORDE = "Horde" -- The version of this add-on BRM.Version = "@project-version@" --######################################### --# Variables for tracking raid members --######################################### BRM.TankCount = 0 BRM.HealerCount = 0 BRM.DPSCount = 0 BRM.UnknownCount = 0 BRM.TotalCount = 0 -- The game is firing the ACTIVE_TALENT_GROUP_CHANGED event before the PLAYER_ENTERING_WORLD event. -- Since we're not fully in the world yet at that point, the group and raid query functions are returning unexpected results. -- So, we use this variable to track whether the add-on is loaded and active. -- We turn it on in the PLAYER_ENTERING_WORLD event. BRM.IsActive = false --######################################### --# Count display and utility functions --######################################### function BRM:GetDisplayString() local OutputString = string.format("%d %s %d %s %d %s %d", BRM.TotalCount, BRM.TankIcon:GetIconString(), BRM.TankCount, BRM.HealerIcon:GetIconString(), BRM.HealerCount, BRM.DPSIcon:GetIconString(), BRM.DPSCount) if BRM.UnknownCount > 0 then OutputString = string.format("%s %s %d", OutputString, BRM.UnknownIcon:GetIconString(), BRM.UnknownCount) end return OutputString end -- BRM:GetDisplayString() function BRM:IncrementRole(role) -- Handle case of nil roles - can happen when the game has not fully loaded and we try to do a role check if not role then role = "unknown" end if BRM.ROLE_HEALER == role then BRM.HealerCount = BRM.HealerCount + 1 elseif BRM.ROLE_TANK == role then BRM.TankCount = BRM.TankCount + 1 elseif BRM.ROLE_DPS == role then BRM.DPSCount = BRM.DPSCount + 1 else BRM.UnknownCount = BRM.UnknownCount + 1 end BRM.TotalCount = BRM.TotalCount + 1 end -- BRM:IncrementRole() function BRM:UpdateComposition() BRM:DebugPrint("in BRM:UpdateComposition") -- If the addon is not yet active, then just exit if not BRM.IsActive then BRM:DebugPrint("Addon is not active. Exiting without updating.") return end -- Zero out the counts so we can start fresh BRM.TankCount = 0 BRM.HealerCount = 0 BRM.DPSCount = 0 BRM.UnknownCount = 0 BRM.TotalCount = 0 -- Figure out how many members in our group. Ungrouped returns zero. local members = GetNumGroupMembers() BRM:DebugPrint("members is " .. members) -- Variable for holding the role of each member we check, and a random iterator local Role, i if members and members > 0 then BRM:DebugPrint("I am in some kind of Group.") local CheckWord = IsInRaid() and "raid" or "party" -- this probably isn't localized in the game. BRM:DebugPrint("CheckWord is " .. CheckWord) -- OK, this is bloody screwy. -- If I'm in a party, then the addon has to check player and party1 to party4. -- But if I'm in a raid, the addon has to check raid1 to raid40, with no need to check player! if "raid" == CheckWord then -- Raid - iterate and count by role for i=1,members do Role = UnitGroupRolesAssigned(CheckWord .. i) if Role then BRM:DebugPrint("Group member " .. CheckWord .. i .. " has role " .. Role) BRM:IncrementRole(Role) else BRM:DebugPrint("Group member " .. CheckWord .. i .. " has no role") BRM:IncrementRole("unknown") end end -- for raid members else -- Party - iterate and count by role for i = 1, members - 1 do Role = UnitGroupRolesAssigned(CheckWord .. i) if Role then BRM:DebugPrint("Group member " .. CheckWord .. i .. " has role " .. Role) BRM:IncrementRole(Role) else BRM:DebugPrint("Group member " .. CheckWord .. i .. " has no role") BRM:IncrementRole("unknown") end end -- for party members -- Now repeat all that for the player. Role = UnitGroupRolesAssigned("player") if Role then BRM:DebugPrint("player has role " .. Role) BRM:IncrementRole(Role) else BRM:DebugPrint("player has no role") BRM:IncrementRole("unknown") end end -- if raid/party else BRM:DebugPrint("I am not in any kind of Group.") -- When not grouped, there is no role to check. So instead, we go off the player's specialization. -- get player role Role = select(5, GetSpecializationInfo(GetSpecialization())) -- GetSpecializationInfo returns: id, name, description, icon, background, role. if Role then BRM:DebugPrint("My role is " .. Role) BRM:IncrementRole(Role) else BRM:DebugPrint("Did not get role from specialization check") BRM:IncrementRole("unknown") end end BRM:DebugPrint("At end of role check, tanks = " .. BRM.TankCount .. ", healers = " .. BRM.HealerCount .. ", dps = " .. BRM.DPSCount .. ", other = " .. BRM.UnknownCount) BRM.LDO.text = BRM:GetDisplayString() end -- BRM:UpdateComposition() -- This function handles refreshing the role counts and checking for count errors function BRM:RefreshCounts() -- I'm trying to capture which situations don't result in an automatic update. -- That essentially indicates either an event I missed coding for, or some kind of bug that resulted in invalid role counts. local old_TankCount = BRM.TankCount local old_HealerCount = BRM.HealerCount local old_DPSCount = BRM.DPSCount local old_UnknownCount = BRM.UnknownCount local old_TotalCount = BRM.TotalCount -- Refresh the counts BRM:UpdateComposition() -- Check if the counts changed, indicating the error above. if old_TankCount ~= BRM.TankCount or old_HealerCount ~= BRM.HealerCount or old_DPSCount ~= BRM.DPSCount or old_UnknownCount ~= BRM.UnknownCount or old_TotalCount ~= BRM.TotalCount then BRM:DebugPrint("Counts are different after click.") BRM:DebugPrint("old_TankCount is " .. (old_TankCount or "nil") .. ", new TankCount is " .. (BRM.TankCount or "nil")) BRM:DebugPrint("old_HealerCount is " .. (old_HealerCount or "nil") .. ", new DPSCount is " .. (BRM.DPSCount or "nil")) BRM:DebugPrint("old_DPSCount is " .. (old_DPSCount or "nil") .. ", new DPSCount is " .. (BRM.DPSCount or "nil")) BRM:DebugPrint("old_UnknownCount is " .. (old_UnknownCount or "nil") .. ", new UnknownCount is " .. (BRM.UnknownCount or "nil")) BRM:DebugPrint("old_TotalCount is " .. (old_TotalCount or "nil") .. ", new TotalCount is " .. (BRM.TotalCount or "nil")) -- @TODO: Capture some info and give the player a way to report it. -- Also schedule an update in five seconds to ensure we capture any additional changes C_Timer.After(5, function() BRM:UpdateComposition() end) end end -- BRM:RefreshCounts() --######################################### --# Actual LibDataBroker object --######################################### BRM.LDO = _G.LibStub("LibDataBroker-1.1"):NewDataObject(BRM.ADDON_NAME, { type = "data source", text = BRM:GetDisplayString(), value = "0", icon = BRM.MainIcon:GetIconString(), label = BRM.USER_ADDON_NAME, OnTooltipShow = function(tooltip) -- make sure we have a real tooltip if not tooltip or not tooltip.AddLine then BRM:DebugPrint("Got invalid tooltip, exiting OnTooltipShow") return end BRM:DebugPrint("Showing tooltip") -- delete existing lines tooltip:ClearLines() -- headline tooltip:AddLine(BRM.USER_ADDON_NAME) -- If the user wants the counts in the tooltip, add them. if BRM.DB.ShowCountInTooltip then BRM:DebugPrint("Preparing tooltip") local DisplayString = "" -- faction handling if BRM.FACTION_HORDE == BRM.Faction then DisplayString = BRM.HordeIcon:GetIconString() elseif BRM.FACTION_ALLIANCE == BRM.Faction then DisplayString = BRM.AllianceIcon:GetIconString() else -- What the hell? BRM:DebugPrint("Unknown faction detected - " .. BRM.Faction) DisplayString = BRM.MainIcon:GetIconString() end DisplayString = DisplayString .. BRM:GetDisplayString() tooltip:AddLine(DisplayString) end -- Add instructions tooltip:AddLine("Click to refresh") tooltip:AddLine("Right click for options") end, }) -- BRM.LDO creation -- Handler for if user clicks on the display function BRM.LDO:OnClick(button) BRM:DebugPrint("Got click on LDB object") if button == "LeftButton" then BRM:DebugPrint("Got left button") BRM:RefreshCounts() elseif button == "RightButton" then BRM:DebugPrint("Got right button") -- toggle showing the count InterfaceOptionsFrame_OpenToCategory(BRM.ConfigFrame) InterfaceOptionsFrame_OpenToCategory(BRM.ConfigFrame) -- Yes, this should be here twice. Workaround for a Blizzard bug. -- When you first open the options panel, it opens to the Game control tab, not the Addons control tab. -- Calling this twice bypasses that. else BRM:DebugPrint("Got some other button") end end -- BRM.LDO:OnClick() --######################################### --# Minimap icon handling --######################################### function BRM:CreateMinimapButton() if not BRM.MinimapIcon then BRM:DebugPrint("Creating minimap icon") BRM.MinimapIcon = LibStub("LibDBIcon-1.0") BRM.MinimapIcon:Register(BRM.ADDON_NAME, BRM.LDO, BRM.DB.MinimapSettings) end end -- BRM:CreateMinimapButton() function BRM:ShowMinimapButton() BRM:DebugPrint("Showing minimap icon") BRM.DB.MinimapSettings.hide = false BRM.MinimapIcon:Show(BRM.ADDON_NAME) end -- BRM:ShowMinimapButton() function BRM:HideMinimapButton() BRM:DebugPrint("Hiding minimap icon") BRM.DB.MinimapSettings.hide = true BRM.MinimapIcon:Hide(BRM.ADDON_NAME) end -- BRM:HideMinimapButton() -- This function is for calling from the options panel. Pass in true to show the icon, false to hide it (which matches the values of the checkbox in the config panel) function BRM:SetMinimapButton(state) if true == state then BRM:ShowMinimapButton() else BRM:HideMinimapButton() end end -- BRM:SetMinimapButton() --######################################### --# Load saved settings --######################################### -- Get existing settings from the DB, or create default settings. function BRM.LoadSettings() BRM:DebugPrint("Loading or creating DB") if BRM_DB then -- Load the settings saved by the game. BRM:DebugPrint ("Restoring existing BRM DB") BRM.DB = BRM_DB -- These situations should only occur during development or upgrade situations if not BRM.DB.MinimapSettings then BRM.DB.MinimapSettings = {} end if not BRM.DB.ShowCountInTooltip then BRM.DB.ShowCountInTooltip = false end if not BRM.DB.DebugMode then BRM.DB.DebugMode = false end else -- Initialize settings on first use BRM:DebugPrint ("Creating new BRM DB") BRM.DB = {} BRM.DB.Version = 1 BRM.DB.MinimapSettings = {} BRM.DB.ShowCountInTooltip = false BRM.DB.DebugMode = false end BRM.DebugMode = BRM.DB.DebugMode BRM:DebugPrint ("DB contents follow") BRM:DumpTable(BRM.DB) BRM:DebugPrint ("End DB contents") end -- BRM.LoadSettings() --######################################### --# Events to register and handle --######################################### -- This event is only for debugging. -- Note that PLAYER_LOGIN is triggered after all ADDON_LOADED events function BRM.Events:PLAYER_LOGIN(...) BRM:DebugPrint("Got PLAYER_LOGIN event") end -- BRM.Events:PLAYER_LOGIN() -- This event is for loading our saved settings. function BRM.Events:ADDON_LOADED(addon) BRM:DebugPrint("Got ADDON_LOADED for " .. addon) if addon ~= BRM.ADDON_NAME then return end -- Load saved settings BRM.LoadSettings() -- Minimap button for LDB object BRM:CreateMinimapButton() -- Creating the minimap icon requires somewhere to save the data - namely, the addon DB. -- We don't load that until this event. -- So, this is the earliest point we can create the minimap icon. -- Note that initial state of whether to display the icon is handled auto-magically by the LDBIcon library, based on the variable storage you pass it. end -- BRM.Events:ADDON_LOADED() -- This triggers when someone joins or leaves a group, or changes their spec or role in the group. function BRM.Events:GROUP_ROSTER_UPDATE(...) BRM:DebugPrint("Got GROUP_ROSTER_UPDATE") BRM:UpdateComposition() end -- BRM.Events:GROUP_ROSTER_UPDATE() -- This triggers when the player changes their talent spec. function BRM.Events:ACTIVE_TALENT_GROUP_CHANGED(...) BRM:DebugPrint("Got ACTIVE_TALENT_GROUP_CHANGED") BRM:UpdateComposition() end -- BRM.Events:ACTIVE_TALENT_GROUP_CHANGED() -- On-load handler for addon initialization. function BRM.Events:PLAYER_ENTERING_WORLD(...) -- Announce our load. BRM:DebugPrint("Got PLAYER_ENTERING_WORLD") -- It's now safe to turn on the addon and get counts. BRM:DebugPrint("Activating " .. BRM.USER_ADDON_NAME) BRM.IsActive = true BRM:UpdateComposition() -- Get the main app icon based on the player's faction BRM:DebugPrint("Determining faction") BRM.Faction, _ = UnitFactionGroup("player") if not BRM.Faction then BRM:DebugPrint("Faction is nil") return end if BRM.FACTION_HORDE == BRM.Faction then BRM:DebugPrint("Faction is Horde") BRM:DebugPrint("Inner string is " .. BRM.HordeIcon:GetIconStringInner()) BRM.LDO.icon = BRM.HordeIcon.IconFile elseif BRM.FACTION_ALLIANCE == BRM.Faction then BRM:DebugPrint("Faction is Alliance") BRM:DebugPrint("Inner string is " .. BRM.AllianceIcon:GetIconStringInner()) BRM.LDO.icon = BRM.AllianceIcon.IconFile else -- What the hell? BRM:DebugPrint("Unknown faction detected - " .. BRM.Faction) end end -- BRM.Events:PLAYER_ENTERING_WORLD() -- Save the db on logout. function BRM.Events:PLAYER_LOGOUT(...) BRM:DebugPrint ("In PLAYER_LOGOUT, saving DB.") BRM_DB = BRM.DB end -- BRM.Events:PLAYER_LOGOUT() --######################################### --# Implement the event handlers --######################################### -- Create the event handler function. BRM.Frame:SetScript("OnEvent", function(self, event, ...) BRM.Events[event](self, ...) -- call one of the functions above end) -- Register all events for which handlers have been defined for k, v in pairs(BRM.Events) do BRM:DebugPrint("Registering event ", k) BRM.Frame:RegisterEvent(k) end