Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Buffoon by Jzar / Spirestone
- -- Adds info to buff tooltips showing who granted you that buff, who else has it, and who's missing it.
- local ADDON_NAME = "Buffoon"
- local ADDON_VERSION = "1.4"
- local ADDON_COLOR = "00a2d9"
- local _
- local f = CreateFrame("FRAME", ADDON_NAME)
- f.Defaults = {
- debug = false, -- Display notification upon loading and debug status messages
- enabled = true, -- Do anything
- groupSize = "party", -- Only display caster and other information when in this type of group or larger
- showCaster = true, -- Show the caster's name. Core functionality IMO, but I guess some people want to turn it off. :/
- showBuffed = false, -- Show people that DO have the buff you're hovering over
- showUnbuffed = true, -- Show people that DO NOT have the buff you're hovering over
- showInGroups = false, -- Show people grouped by what party they're in, rather than packed tightly together
- showExtras = false, -- Show everyone in raid past the first 10 / 25 players, depending on your current raid difficulty
- }
- f:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end)
- function f:Print(text) if text then DEFAULT_CHAT_FRAME:AddMessage("|cff" .. ADDON_COLOR .. ADDON_NAME .. "|r: " .. tostring(text)) end end
- function f:Debug(text) if self.Options.debug and text then DEFAULT_CHAT_FRAME:AddMessage("|cff" .. ADDON_COLOR .. ADDON_NAME .. "|r: " .. tostring(text)) end end
- f:RegisterEvent("ADDON_LOADED")
- function f:ADDON_LOADED(event, addon)
- if addon == ADDON_NAME then
- if not _G[ADDON_NAME .. "DB"] then _G[ADDON_NAME .. "DB"] = {} end
- -- Recursively create / update options table with default options if not yet set
- local function updateTable(source, dest)
- if not dest then dest = {} end
- for key, val in pairs(source) do
- if type(val) == "table" then
- updateTable(val, dest[key])
- else
- if dest[key] == nil then dest[key] = val end
- end
- end
- end
- updateTable(self.Defaults, _G[ADDON_NAME .. "DB"])
- self.Options = _G[ADDON_NAME .. "DB"]
- self:Debug(ADDON_NAME .. " v" .. ADDON_VERSION .. " loaded.")
- -- Prepare to register a slash command based on the capitolized letters in the addon's name
- local abbreviatedName = ""
- for i = 1, #ADDON_NAME do
- if ADDON_NAME:sub(i, i) ~= ADDON_NAME:lower():sub(i, i) then
- abbreviatedName = abbreviatedName .. ADDON_NAME:lower():sub(i, i)
- end
- end
- _G["SLASH_" .. ADDON_NAME .. "1"] = "/" .. ADDON_NAME:lower()
- if #abbreviatedName > 2 then _G["SLASH_" .. ADDON_NAME .. "2"] = "/" .. abbreviatedName end
- SlashCmdList[ADDON_NAME] = function(msg) self:SlashCommandHandler(msg) end
- self:UnregisterEvent("ADDON_LOADED")
- self.ADDON_LOADED = nil
- end
- end
- -- Using table to emulate a switch statement for slash command handling
- f.SlashCommandTable = {
- ["debug"] = function() f.Options.debug = not f.Options.debug; f:Print("Debug: " .. (f.Options.debug and "Enabled" or "Disabled")) end,
- ["default"] = function()
- f:Print(ADDON_NAME .. " " .. ADDON_VERSION);
- f:Print(" /buffoon {toggle | on | off}");
- f:Print(" /buffoon {solo | party | raid}");
- f:Print(" /buffoon {caster | buffed | unbuffed}");
- f:Print(" /buffoon {extras}"); end,
- ["status"] = function()
- f:Print(f.Options.enabled and "Enabled" or "Disabled");
- f:Print("Show when " .. f.Options.groupSize);
- f:Print("Buffed - " .. (f.Options.showBuffed and "True" or "False"));
- f:Print("Unbuffed - " .. (f.Options.showUnbuffed and "True" or "False"));
- f:Print("Groups - " .. (f.Options.showInGroups and "True" or "False")); end,
- ["toggle"] = function() f.Options.enabled = not f.Options.enabled; f:Print(f.Options.enabled and "Enabled" or "Disabled") end,
- ["on"] = function() f.Options.enabled = true; f:Print("Enabled") end,
- ["off"] = function() f.Options.enabled = false; f:Print("Disabled") end,
- ["solo"] = function() f.Options.groupSize = "solo"; f:Print("Groupsize: " .. f.Options.groupSize) end,
- ["party"] = function() f.Options.groupSize = "party"; f:Print("Groupsize: " .. f.Options.groupSize) end,
- ["raid"] = function() f.Options.groupSize = "raid"; f:Print("Groupsize: " .. f.Options.groupSize) end,
- ["caster"] = function() f.Options.showCaster = not f.Options.showCaster; f:Print("Show caster: " .. (f.Options.showCaster and "True" or "False")) end,
- ["buffed"] = function() f.Options.showBuffed = not f.Options.showBuffed; f:Print("Show buffed: " .. (f.Options.showBuffed and "True" or "False")) end,
- ["unbuffed"] = function() f.Options.showUnbuffed = not f.Options.showUnbuffed; f:Print("Show unbuffed: " .. (f.Options.showUnbuffed and "True" or "False")) end,
- ["groups"] = function() f.Options.showInGroups = not f.Options.showInGroups; f:Print("Show in groups: " .. (f.Options.showInGroups and "True" or "False")) end,
- ["extras"] = function() f.Options.showExtras = not f.Options.showExtras; f:Print("Show extras in raid: " .. (f.Options.showExtras and "True" or "False")) end,
- ["rl"] = function() ReloadUI() end,
- }
- function f:SlashCommandHandler(msg)
- if self.SlashCommandTable[msg:lower()] then
- self.SlashCommandTable[msg:lower()]()
- else
- self.SlashCommandTable["default"]()
- end
- end
- -- Hook Gametooltip when it shows unit auras, and add our buff text to the bottom
- function f:SetUnitAura(_, unitId, auraIndex)
- local showCaster = false
- if self.Options.groupSize == "solo" then showCaster = true end
- if self.Options.groupSize == "party" and GetNumSubgroupMembers() > 0 then showCaster = true end
- if self.Options.groupSize == "raid" and IsInRaid() then showCaster = true end
- if self.Options.enabled and showCaster then
- local function wrapWhite(text) return ("|cffffffff%s|r"):format(text) end
- local auraName = select(1, UnitAura(unitId, auraIndex)) or select(1, UnitAura(unitId, auraIndex, "HARMFUL"))
- local caster = select(8, UnitAura(unitId, auraIndex)) or select(8, UnitAura(unitId, auraIndex, "HARMFUL"))
- local consol = select(10, UnitAura(unitId, auraIndex)) or select(10, UnitAura(unitId, auraIndex, "HARMFUL"))
- local blankAdded = false
- if self.Options.showCaster and caster then
- GameTooltip:AddLine(" ")
- blankAdded = true
- GameTooltip:AddLine(wrapWhite("Caster: ") .. self:colorByClass(caster))
- end
- if self.Options.showBuffed or self.Options.showUnbuffed and UnitIsFriend("player", unitId) then
- local buffed, unbuffed
- if GetNumGroupMembers() > 0 and IsInRaid() then
- buffed, unbuffed = self:findAura(auraName, "raid", GetNumGroupMembers())
- elseif GetNumSubgroupMembers() > 0 then
- buffed, unbuffed = self:findAura(auraName, "party", GetNumSubgroupMembers())
- tempBuffed, tempUnbuffed = self:findAura(auraName, "player")
- if tempBuffed[1] and not buffed[1] then buffed[1] = {} end
- if tempBuffed[1] then table.insert(buffed[1], 1, tempBuffed[1][1]) end
- if tempUnbuffed[1] and not unbuffed[1] then unbuffed[1] = {} end
- if tempUnbuffed[1] then table.insert(unbuffed[1], 1, tempUnbuffed[1][1]) end
- else
- buffed, unbuffed = self:findAura(auraName, "player")
- end
- if self.Options.showBuffed and table.maxn(buffed) > 0 and consol then
- if not blankAdded then GameTooltip:AddLine(" "); blankAdded = true end
- GameTooltip:AddLine(wrapWhite("Buffed: ") .. self:buildList(buffed))
- end
- if self.Options.showUnbuffed and table.maxn(unbuffed) > 0 and consol then
- if not blankAdded then GameTooltip:AddLine(" "); blankAdded = true end
- GameTooltip:AddLine(wrapWhite("Unbuffed: ") .. self:buildList(unbuffed))
- end
- end
- end
- GameTooltip:Show()
- end
- hooksecurefunc(GameTooltip, "SetUnitAura", function(...) f:SetUnitAura(...) end)
- -- Search the group (up to limit number of players) for auraName, and return a 2 dimensional
- -- table with parties and player names of those holding and missing the buff
- function f:findAura(auraName, group, limit)
- local buffed, unbuffed = {}, {}
- for i = 1, limit or 1 do
- local maxMembers = (group == "raid") and ((GetRaidDifficulty() == 1 or GetRaidDifficulty() == 3) and 10 or 25) or 1
- if GetNumGroupMembers() == 0 or select(3, GetRaidRosterInfo(i)) * 5 <= maxMembers or f.Options.showExtras then -- 3rd argument from GetRaidRosterInfo is the raid member's subgroup
- local unitId = limit and (group .. i) or group
- local party = (group == "raid") and select(3, GetRaidRosterInfo(i)) or 1
- local hasBuff = false
- for j = 1, 40 do
- local groupAuraName = UnitAura(unitId, j)
- if not groupAuraName then break end
- if auraName == groupAuraName then
- hasBuff = true
- if not buffed[party] then buffed[party] = {} end
- table.insert(buffed[party], unitId)
- end
- end
- if not hasBuff then
- if not unbuffed[party] then unbuffed[party] = {} end
- table.insert(unbuffed[party], unitId)
- end
- end
- end
- return buffed, unbuffed
- end
- -- Take a table of parties and unitIds, and build a formatted list of players
- function f:buildList(list)
- local returnList = ""
- local totalEntries = 0
- for i = 1, table.maxn(list) do
- if list[i] then
- totalEntries = totalEntries + #list[i]
- end
- end
- -- Show groups in raid
- if self.Options.showInGroups and table.maxn(list) > 1 then
- returnList = returnList .. totalEntries
- for i = 1, table.maxn(list) do
- if list[i] then
- local tempList = ""
- for j = 1, #list[i] do
- if tempList == "" then
- tempList = "\r\n " .. i .. ". " .. self:colorByClass(list[i][j])
- else
- tempList = tempList .. ", " .. self:colorByClass(list[i][j])
- end
- end
- returnList = returnList .. tempList
- end
- end
- -- Show all together in raid
- elseif table.maxn(list) > 1 then
- local wordsOnLine = 0
- for i = 1, table.maxn(list) do
- if list[i] then
- for j = 1, #list[i] do
- if wordsOnLine == 0 then
- returnList = self:colorByClass(list[i][j])
- wordsOnLine = 2
- elseif wordsOnLine == 5 then
- returnList = returnList .. "\r\n " .. self:colorByClass(list[i][j])
- wordsOnLine = 1
- else
- returnList = returnList .. ", " .. self:colorByClass(list[i][j])
- wordsOnLine = wordsOnLine + 1
- end
- end
- end
- end
- -- Show all on single line
- else
- for i = 1, #list[1] do
- if returnList == "" then
- returnList = self:colorByClass(list[1][i])
- else
- returnList = returnList .. ", " .. self:colorByClass(list[1][i])
- end
- end
- end
- return returnList
- end
- -- Input a unitId, identify its class, then return the target's name wrapped in class specific color codes
- function f:colorByClass(unitId)
- if not unitId then return end
- local color = RAID_CLASS_COLORS[select(2, UnitClass(unitId))] or {r = 1.0, g = 1.0, b = 1.0}
- return ("|cff%02x%02x%02x%s|r"):format(color.r * 255, color.g * 255, color.b * 255, UnitName(unitId))
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement