--Inspired by Author Tekkub and his mod PicoEXP --Special thanks to Aranarth for Ara_Broker_Reputations local start, max, starttime local levels = { FACTION_STANDING_LABEL1, FACTION_STANDING_LABEL2, FACTION_STANDING_LABEL3, FACTION_STANDING_LABEL4, FACTION_STANDING_LABEL5, FACTION_STANDING_LABEL6, FACTION_STANDING_LABEL7, FACTION_STANDING_LABEL8 } local colors = { "8b0000", "ff1919", "ff8c00", "dddddd", "ffff00", "19e619", "4169e1", "9932cc", "67009a" } local GetFactionInfo, FACTION_INACTIVE = GetFactionInfo, FACTION_INACTIVE local f = CreateFrame("frame","xanReputation",UIParent) f:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end) ---------------------- -- Enable -- ---------------------- function f:PLAYER_LOGIN() if not XanREP_DB then XanREP_DB = {} end if XanREP_DB.bgShown == nil then XanREP_DB.bgShown = true end if XanREP_DB.scale == nil then XanREP_DB.scale = 1 end if XanREP_DB.autoSwitch == nil then XanREP_DB.autoSwitch = true end --check for old db if XanREP_DB["XanReputation"] then XanREP_DB["xanReputation"] = XanREP_DB["XanReputation"] XanREP_DB["XanReputation"] = nil end self:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE") self:RegisterEvent("CHAT_MSG_SYSTEM") self:RegisterEvent("UPDATE_FACTION") --create the default frame and position it self:CreateREP_Frame() self:RestoreLayout("xanReputation") SLASH_XANREPUTATION1 = "/xanrep"; SlashCmdList["XANREPUTATION"] = xanReputation_SlashCommand; local ver = GetAddOnMetadata("xanReputation","Version") or '1.0' DEFAULT_CHAT_FRAME:AddMessage(string.format("|cFF99CC33%s|r [v|cFFDF2B2B%s|r] loaded: /xanrep", "xanReputation", ver or "1.0")) self:UnregisterEvent("PLAYER_LOGIN") self.PLAYER_LOGIN = nil end function xanReputation_SlashCommand(cmd) local a,b,c=strfind(cmd, "(%S+)"); --contiguous string of non-space characters if a then if c and c:lower() == "reset" then DEFAULT_CHAT_FRAME:AddMessage("xanReputation: Frame position has been reset!"); xanReputation:ClearAllPoints() xanReputation:SetPoint("CENTER", UIParent, "CENTER", 0, 0); return true end end DEFAULT_CHAT_FRAME:AddMessage("xanReputation"); DEFAULT_CHAT_FRAME:AddMessage("/xanrep reset - resets the frame position"); end function f:CreateREP_Frame() f:SetWidth(61) f:SetHeight(27) f:SetMovable(true) f:SetClampedToScreen(true) f:SetScale(XanREP_DB.scale) if XanREP_DB.bgShown then f:SetBackdrop( { bgFile = "Interface\\TutorialFrame\\TutorialFrameBackground"; edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border"; tile = true; tileSize = 32; edgeSize = 16; insets = { left = 5; right = 5; top = 5; bottom = 5; }; } ); f:SetBackdropBorderColor(0.5, 0.5, 0.5); f:SetBackdropColor(0.5, 0.5, 0.5, 0.6) else f:SetBackdrop(nil) end f:EnableMouse(true); local iconTexture = UnitFactionGroup("player") == "Horde" and "Interface\\Icons\\Spell_Misc_HellifrePVPThrallmarFavor" or "Interface\\Icons\\Spell_Misc_HellifrePVPHonorHoldFavor" local t = f:CreateTexture("$parentIcon", "ARTWORK") t:SetTexture(iconTexture) t:SetWidth(16) t:SetHeight(16) t:SetPoint("TOPLEFT",5,-6) local g = f:CreateFontString("$parentText", "ARTWORK", "GameFontNormalSmall") g:SetJustifyH("LEFT") g:SetPoint("CENTER",8,0) g:SetText("?") f.text = g f:SetScript("OnMouseDown",function(self, button) if not button then return end if button == "LeftButton" and IsShiftKeyDown() then self.isMoving = true self:StartMoving(); elseif button == "RightButton" then self:ShowDropDown(self) end end) f:SetScript("OnMouseUp",function() if( self.isMoving ) then self.isMoving = nil self:StopMovingOrSizing() f:SaveLayout(self:GetName()); end end) f:SetScript("OnLeave",function() GameTooltip:Hide() end) f:SetScript("OnEnter",function() if XanREP_DB.factionWatched and XanREP_DB.factionIndex and XanREP_DB.factionIndex > 0 then local name, showValue, level, minVal, maxVal, value, atWar, canBeAtWar, isHeader, isCollapsed, hasRep, isWatched, isChild = GetFactionInfo(XanREP_DB.factionIndex) if not isHeader then GameTooltip:SetOwner(self, "ANCHOR_NONE") GameTooltip:SetPoint(self:GetTipAnchor(self)) GameTooltip:ClearLines() GameTooltip:AddLine("xanReputation") maxVal = maxVal - minVal value = value - minVal local percent = ceil((value / maxVal) * 100) local remainXP, toLevelPercent = 0, 0 if percent < 100 then remainXP = maxVal - value toLevelPercent = ceil((maxVal - value) / maxVal * 100) end GameTooltip:AddDoubleLine("Faction:", name, nil,nil,nil, 1,1,1) GameTooltip:AddDoubleLine("Status:", string.format("|cFF%s%s|r", colors[level], levels[level]), nil,nil,nil, 1,1,1) GameTooltip:AddDoubleLine("Current:", value, nil,nil,nil, 1,1,1) GameTooltip:AddDoubleLine("TNR:", remainXP..(" ("..toLevelPercent.."%)"), nil,nil,nil, 1,1,1) if start and starttime then GameTooltip:AddLine(string.format("%.1f hours played this session", (GetTime()-starttime)/3600), 1,1,1) GameTooltip:AddLine((value - start).." REP gained this session", 1,1,1) end GameTooltip:Show() end end end) f:Show(); end function f:UpdateREP_Frame() if XanREP_DB.factionWatched and XanREP_DB.factionIndex and XanREP_DB.factionIndex > 0 then local name, showValue, level, minVal, maxVal, value, atWar, canBeAtWar, isHeader, isCollapsed, hasRep, isWatched, isChild = GetFactionInfo(XanREP_DB.factionIndex) if not isHeader and maxVal > 0 then maxVal = maxVal - minVal value = value - minVal local percent = ceil((value / maxVal) * 100) getglobal("xanReputationText"):SetText(string.format("|cFF%s%d%%|r", colors[level], percent)) return end end getglobal("xanReputationText"):SetText("None") end function f:SaveLayout(frame) if type(frame) ~= "string" then return end if not _G[frame] then return end if not XanREP_DB then XanREP_DB = {} end local opt = XanREP_DB[frame] or nil if not opt then XanREP_DB[frame] = { ["point"] = "CENTER", ["relativePoint"] = "CENTER", ["xOfs"] = 0, ["yOfs"] = 0, } opt = XanREP_DB[frame] return end local point, relativeTo, relativePoint, xOfs, yOfs = _G[frame]:GetPoint() opt.point = point opt.relativePoint = relativePoint opt.xOfs = xOfs opt.yOfs = yOfs end function f:RestoreLayout(frame) if type(frame) ~= "string" then return end if not _G[frame] then return end if not XanREP_DB then XanREP_DB = {} end local opt = XanREP_DB[frame] or nil if not opt then XanREP_DB[frame] = { ["point"] = "CENTER", ["relativePoint"] = "CENTER", ["xOfs"] = 0, ["yOfs"] = 0, } opt = XanREP_DB[frame] end _G[frame]:ClearAllPoints() _G[frame]:SetPoint(opt.point, UIParent, opt.relativePoint, opt.xOfs, opt.yOfs) end function f:BackgroundToggle(switch) if not switch then if not XanREP_DB then XanREP_DB = {} end if XanREP_DB.bgShown == nil then XanREP_DB.bgShown = true end if not XanREP_DB.bgShown then XanREP_DB.bgShown = true DEFAULT_CHAT_FRAME:AddMessage("xanReputation: Background Shown"); elseif XanREP_DB.bgShown then XanREP_DB.bgShown = false DEFAULT_CHAT_FRAME:AddMessage("xanReputation: Background Hidden"); else XanREP_DB.bgShown = true DEFAULT_CHAT_FRAME:AddMessage("xanReputation: Background Shown"); end end --now change background if XanREP_DB.bgShown then f:SetBackdrop( { bgFile = "Interface\\TutorialFrame\\TutorialFrameBackground"; edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border"; tile = true; tileSize = 32; edgeSize = 16; insets = { left = 5; right = 5; top = 5; bottom = 5; }; } ); f:SetBackdropBorderColor(0.5, 0.5, 0.5); f:SetBackdropColor(0.5, 0.5, 0.5, 0.6) else f:SetBackdrop(nil) end end function f:GetFactionWatched(sSwitch, faction) local chkFaction = faction or XanREP_DB.factionWatched or nil if chkFaction then for i = 1, GetNumFactions() do if GetFactionInfo(i) == chkFaction then local name, showValue, level, minVal, maxVal, value, atWar, canBeAtWar, isHeader, isCollapsed, hasRep, isWatched, isChild = GetFactionInfo(i) maxVal = maxVal - minVal value = value - minVal start, max, starttime = value, maxVal, GetTime() XanREP_DB.factionIndex = i XanREP_DB.factionWatched = name if sSwitch then SetWatchedFactionIndex(i) end end end else f.text:SetText("?") SetWatchedFactionIndex(0) end XanREP_DB.factionCount = GetNumFactions() end ------------------------------ -- DropDown -- ------------------------------ local function Faded(self) self:Release() end local function FadeMenu(self) local fadeInfo = {} fadeInfo.mode = "OUT" fadeInfo.timeToFade = 0.1 fadeInfo.finishedFunc = Faded fadeInfo.finishedArg1 = self UIFrameFade(self, fadeInfo) end function f:ShowDropDown(sFrame) local dd1 = LibStub("LibDropdown-1.0") local t = { type = "group", name = "group", desc = "group", args = { reputation = { type = "group", name = "Reputation", desc = "Select a reputation", args = { --to be filled by loop below }, order = 10 }, settings = { type = "group", name = "Settings", desc = "xanReputation settings", args = { range = { type = "range", name = "Scale", desc = "Change the scale size of xanReputation", min = 1, max = 2.6, bigStep = 0.1, get = function(info) return XanREP_DB.scale end, set = function(info, v) XanREP_DB.scale = v xanReputation:SetScale(v) end, order = 10 }, toggleBG = { type = "toggle", name = "Toggle background", desc = "Toggle the xanReputation background", get = function() return XanREP_DB.bgShown end, set = function(info, v) XanREP_DB.bgShown = v f:BackgroundToggle(true) end, order = 20 }, autoSwitchBG = { type = "toggle", name = "Auto Switch", desc = "Auto switch reputation", get = function() return XanREP_DB.autoSwitch end, set = function(info, v) XanREP_DB.autoSwitch = v end, order = 30 }, }, order = 20 }, -- removeReputation = { -- type = "execute", -- name = "Remove Reputation", -- desc = "Stop tracking the current Reputation", -- func = function(self) -- XanREP_DB.factionWatched = nil -- f:GetFactionWatched(nil, nil) -- end, -- order = 30 -- }, close = { type = "execute", name = "Close", desc = "Close this menu", func = function(self) FadeMenu(f.DD) end, order = 1000 } } } --fill the reputation list local parentOrder = 1 for i = 1, GetNumFactions() do local name, showValue, level, minVal, maxVal, value, atWar, canBeAtWar, isHeader, isCollapsed, hasRep, isWatched, isChild = GetFactionInfo(i) if isHeader then --check if we have something first local processChk = false for q = 1, GetNumFactions() do local nameSub, _, _, _, _, _, _, _, isHeaderSub = GetFactionInfo(q) if isHeaderSub and nameSub == name then boolD = true elseif isHeaderSub and nameSub ~= name then boolD = false end if boolD and not isHeaderSub then processChk = true break end end if processChk then --do the child rep names for the reputation parent local boolD = false local tableValues = {} for q = 1, GetNumFactions() do local nameSub, _, _, _, _, _, _, _, isHeaderSub = GetFactionInfo(q) if isHeaderSub and nameSub == name then boolD = true elseif isHeaderSub and nameSub ~= name then boolD = false end if boolD and not isHeaderSub then table.insert(tableValues,nameSub) end end --add to reputation parent t.args.reputation.args[name] = { type = "select", name = name, desc = name, values = tableValues, order = parentOrder*10, get = function(info) for z = 1, #info.option.values do if info.option.values[z] == XanREP_DB.factionWatched then return z end end return 0 end, set = function(info, v) XanREP_DB.factionWatched = info.option.values[v] f:GetFactionWatched(true) end } parentOrder = parentOrder + 1 end end end f.DD = dd1:OpenAce3Menu(t) f.DD:SetClampedToScreen(true) f.DD:SetAlpha(1.0) f.DD:SetPoint("LEFT",sFrame,"RIGHT",0,0) f.DD:Show() f:GetFactionWatched(true) end ------------------------------ -- Event Handlers -- ------------------------------ local org_SetWatchedFactionIndex = SetWatchedFactionIndex function SetWatchedFactionIndex(...) org_SetWatchedFactionIndex(...) XanREP_DB.factionWatched = GetFactionInfo(...) XanREP_DB.factionIndex = ... if xanReputation then xanReputation:UpdateREP_Frame() end end local factionUp = gsub(FACTION_STANDING_INCREASED:gsub("%%d", "([0-9]+)"), "%%s", "(.*)") local factionDown = gsub(FACTION_STANDING_DECREASED:gsub("%%d", "([0-9]+)"), "%%s", "(.*)") local repPattern = string.gsub(FACTION_STANDING_CHANGED,"%%%d?%$?s", "(.+)") function f:CHAT_MSG_COMBAT_FACTION_CHANGE(event, msg) local faction, value, decrease = strmatch( msg, factionUp ) if not faction then faction, value = strmatch( msg, factionDown ) if not faction then return end decrease = true end if tonumber(faction) then faction, value = value, tonumber(faction) else value = tonumber(value) end if XanREP_DB.factionCount ~= GetNumFactions() then --a new faction was added so lets update the display XanREP_DB.factionCount = GetNumFactions() end if not decrease and XanREP_DB.autoSwitch then for i = 1, GetNumFactions() do if GetFactionInfo(i) == faction then return SetWatchedFactionIndex(i) end end end if faction == XanREP_DB.factionWatched then f:UpdateREP_Frame() end end function f:CHAT_MSG_SYSTEM(event, msg) if not msg or not type(msg)=="string" then return end local newstanding, withfaction = strmatch(msg, repPattern) if not newstanding then return end --since we are now a new standing lets redo the dropdown just in case we just got a new rep we didn't have if XanREP_DB.factionCount ~= GetNumFactions() then --a new faction was added so lets update the display XanREP_DB.factionCount = GetNumFactions() end end function f:UPDATE_FACTION() --now that our faction information is loaded, lets populate the dropdown and setup the display --setup startup faction information self:GetFactionWatched(true) --do rep frame update self:UpdateREP_Frame() self:UnregisterEvent("UPDATE_FACTION") self.UPDATE_FACTION = nil end ------------------------ -- Tooltip! -- ------------------------ function f:GetTipAnchor(frame) local x,y = frame:GetCenter() if not x or not y then return "TOPLEFT", "BOTTOMLEFT" end local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or "" local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM" return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf end if IsLoggedIn() then f:PLAYER_LOGIN() else f:RegisterEvent("PLAYER_LOGIN") end