-- Relationships PVP RelationshipsPVPCharDB = RelationshipsPVPCharDB or {} local BG_KEYS = { "AV", "WSG", "AB" } local ARENA_KEYS = { "A2", "A3", "A5", "SK" } local ALL_KEYS = { "AV", "WSG", "AB", "A2", "A3", "A5", "SK" } local BG_NAMES = { AV = "Alterac Valley", WSG = "Warsong Gulch", AB = "Arathi Basin", A2 = "2v2 Rated", A3 = "3v3 Rated", A5 = "5v5 Rated", SK = "Skirmish", } local BG_COLORS = { AV = { r = 0.6, g = 0.85, b = 1.0 }, WSG = { r = 0.6, g = 1.0, b = 0.6 }, AB = { r = 1.0, g = 0.85, b = 0.4 }, A2 = { r = 1.0, g = 0.6, b = 0.9 }, A3 = { r = 1.0, g = 0.5, b = 0.6 }, A5 = { r = 0.9, g = 0.5, b = 1.0 }, SK = { r = 0.8, g = 0.8, b = 0.8 }, } -- Arena bracket meta: teamSize + isRated (registeredMatch) local ARENA_META = { A2 = { size = 2, rated = 1 }, A3 = { size = 3, rated = 1 }, A5 = { size = 5, rated = 1 }, SK = { size = 2, rated = 0 }, -- default skirmish to 2v2 unrated } -- TurtleWoW / OctoWoW arena finder ids for JoinArenaQueue(id). -- Skirmish must be 0; passing the team size opens the Blood Ring panel -- without completing the queue. local ARENA_IDS = { SK = 0, A2 = 1, A3 = 2, A5 = 3, } local MARKS_WIN = 3 local MARKS_LOSS = 1 local currentBG = nil local endReported = {} -- Track the last arena bracket the user queued for, so we can classify -- the resulting match even on clients that don't report teamSize. local lastQueuedArena = nil -- Runtime UI (row FontStrings created dynamically) local rowStrings = {} local totalRow = nil --------------------------------------------------------------- -- Utility --------------------------------------------------------------- local function NewStatBlock() return { wins = 0, losses = 0, kills = 0, deaths = 0, hk = 0, marks = 0, honor = 0, bestKB = 0, streak = 0, bestStreak = 0, } end local function EnsureDB() local db = RelationshipsPVPCharDB db.stats = db.stats or {} db.icon = db.icon or { point = "CENTER", x = 60, y = -60 } if db.showIcon == nil then db.showIcon = true end for i = 1, table.getn(ALL_KEYS) do local k = ALL_KEYS[i] local s = db.stats[k] or NewStatBlock() if s.honor == nil then s.honor = 0 end if s.bestKB == nil then s.bestKB = 0 end if s.streak == nil then s.streak = 0 end if s.bestStreak == nil then s.bestStreak = 0 end if s.hk == nil then s.hk = 0 end if s.marks == nil then s.marks = 0 end db.stats[k] = s end return db end function RelationshipsPVP_SaveIconPos() local db = EnsureDB() local btn = RelationshipsPVPMinimapButton if not btn then return end local point, _, _, x, y = btn:GetPoint() db.icon.point = point or "CENTER" db.icon.x = x or 0 db.icon.y = y or 0 db.icon.parent = "Minimap" end local function ApplyIconVisibility() local db = EnsureDB() local btn = RelationshipsPVPMinimapButton if not btn then return end if db.showIcon then btn:Show() else btn:Hide() end end -- The Minimap frame can be briefly hidden during loading screens / entering -- battlegrounds; when it re-shows, child buttons parented to it sometimes -- stay hidden until touched. This ticker re-asserts our intended visibility -- once per second so the icon never "randomly disappears". local iconWatcher local function InstallIconWatcher() if iconWatcher then return end iconWatcher = CreateFrame("Frame") iconWatcher.elapsed = 0 iconWatcher:SetScript("OnUpdate", function() iconWatcher.elapsed = (iconWatcher.elapsed or 0) + arg1 if iconWatcher.elapsed < 1.0 then return end iconWatcher.elapsed = 0 local db = RelationshipsPVPCharDB if not db then return end local btn = RelationshipsPVPMinimapButton if not btn then return end if db.showIcon then if not btn:IsShown() then btn:Show() end else if btn:IsShown() then btn:Hide() end end end) end local function RestoreIconPos() local db = EnsureDB() local btn = RelationshipsPVPMinimapButton if not btn then return end local parent = (db.icon.parent == "UIParent") and UIParent or Minimap btn:ClearAllPoints() btn:SetPoint(db.icon.point, parent, db.icon.point, db.icon.x, db.icon.y) ApplyIconVisibility() InstallIconWatcher() end local function SavePanelPos() local db = EnsureDB() db.panel = db.panel or {} if not RelationshipsPVPFrame then return end local point, _, _, x, y = RelationshipsPVPFrame:GetPoint() db.panel.point = point or "CENTER" db.panel.x = x or 0 db.panel.y = y or 0 end local function RestorePanelPos() local db = EnsureDB() if not RelationshipsPVPFrame or not db.panel or not db.panel.point then return end RelationshipsPVPFrame:ClearAllPoints() RelationshipsPVPFrame:SetPoint(db.panel.point, UIParent, db.panel.point, db.panel.x, db.panel.y) end local function Print(msg) if DEFAULT_CHAT_FRAME then DEFAULT_CHAT_FRAME:AddMessage("|cff66ccffRelationships PVP:|r " .. msg) end end local function MapNameToKey(name) if not name then return nil end if name == BG_NAMES.AV then return "AV" end if name == BG_NAMES.WSG then return "WSG" end if name == BG_NAMES.AB then return "AB" end return nil end local function FormatNumber(n) n = n or 0 if n >= 1000000 then return string.format("%.1fm", n / 1000000) elseif n >= 10000 then return string.format("%.1fk", n / 1000) end return tostring(n) end --------------------------------------------------------------- -- BG / Arena detection --------------------------------------------------------------- local function ClassifyBattlefield(i) local status, mapName, instanceID, minLevel, maxLevel, teamSize, registered = GetBattlefieldStatus(i) if status ~= "active" then return nil end local bgKey = MapNameToKey(mapName) if bgKey then return bgKey end if teamSize and teamSize > 0 then if registered == 1 or registered == true then if teamSize == 2 then return "A2" end if teamSize == 3 then return "A3" end if teamSize == 5 then return "A5" end else return "SK" end end if lastQueuedArena then return lastQueuedArena end return nil end local function DetectCurrentBG() for i = 1, 3 do local status = GetBattlefieldStatus(i) if status == "active" then local key = ClassifyBattlefield(i) if key then return key, i end end end return nil, nil end local function RecordEnd(key, index) if not key or endReported[index] then return end endReported[index] = true local db = EnsureDB() local s = db.stats[key] if not s then return end local playerWon = false local winner = GetBattlefieldWinner() if winner then local myFaction = UnitFactionGroup("player") local wonAsAlliance = (winner == 1 and myFaction == "Alliance") local wonAsHorde = (winner == 0 and myFaction == "Horde") playerWon = wonAsAlliance or wonAsHorde if playerWon then s.wins = s.wins + 1 s.streak = s.streak + 1 if s.streak > s.bestStreak then s.bestStreak = s.streak end else s.losses = s.losses + 1 s.streak = 0 end local isBG = (key == "AV" or key == "WSG" or key == "AB") if isBG then s.marks = s.marks + (playerWon and MARKS_WIN or MARKS_LOSS) end end RequestBattlefieldScoreData() local me = UnitName("player") local rows = GetNumBattlefieldScores() or 0 for r = 1, rows do local name, killingBlows, honorableKills, deaths, honorGained = GetBattlefieldScore(r) if name == me then local kb = killingBlows or 0 local hk = honorableKills or 0 local dth = deaths or 0 local hon = honorGained or 0 s.kills = s.kills + kb s.hk = s.hk + hk s.deaths = s.deaths + dth s.honor = s.honor + hon if kb > s.bestKB then s.bestKB = kb end break end end local marksMsg = "" if key == "AV" or key == "WSG" or key == "AB" then marksMsg = " +" .. (playerWon and MARKS_WIN or MARKS_LOSS) .. " marks" end Print(BG_NAMES[key] .. " recorded (" .. (playerWon and "|cff66ff66win|r" or "|cffff6666loss|r") .. marksMsg .. ").") end --------------------------------------------------------------- -- Queue actions --------------------------------------------------------------- -- Auto-close the Blizzard PvP panels if they pop up as a side effect -- of the arena / BG queueing calls. local function HidePvPPanels() if BattlefieldFrame and BattlefieldFrame:IsVisible() then HideUIPanel(BattlefieldFrame) end if PVPBattlegroundFrame and PVPBattlegroundFrame:IsVisible() then HideUIPanel(PVPBattlegroundFrame) end if PVPFrame and PVPFrame:IsVisible() then HideUIPanel(PVPFrame) end if HonorFrame and HonorFrame:IsVisible() then HideUIPanel(HonorFrame) end end -- Suppress the PvP panel entirely while we are auto-queueing. Reference-counted -- so nested queues (Queue All BGs) do not release too early. local suppressPanels = 0 local suppressHooked = false local origBattlefieldShow, origPVPBGShow local function InstallPanelSuppressor() if suppressHooked then return end suppressHooked = true if BattlefieldFrame then origBattlefieldShow = BattlefieldFrame.Show BattlefieldFrame.Show = function(self, ...) if suppressPanels > 0 then return end origBattlefieldShow(self) end end if PVPBattlegroundFrame then origPVPBGShow = PVPBattlegroundFrame.Show PVPBattlegroundFrame.Show = function(self, ...) if suppressPanels > 0 then return end origPVPBGShow(self) end end end local function BeginSuppress() InstallPanelSuppressor() suppressPanels = suppressPanels + 1 HidePvPPanels() end local function EndSuppress() suppressPanels = suppressPanels - 1 if suppressPanels < 0 then suppressPanels = 0 end HidePvPPanels() end -- Central pending-queue state. `pendingQueue` is a FIFO of items: -- { kind = "bg"|"arena", key = , asGroup = 0/1 } -- The finder frame processes them one at a time on BATTLEFIELDS_SHOW. local pendingQueue = {} local finderFrame -- Kick the client into opening the finder for the requested queue type. -- The BATTLEFIELDS_SHOW handler below immediately completes the queue and -- hides the Blizzard/Blood Ring panel. local function KickFinderFor(job) if job.kind == "arena" then if type(JoinArenaQueue) == "function" then local id = ARENA_IDS[job.key] if id == nil then id = 0 end JoinArenaQueue(id) return true end if type(JoinBattlegroundQueue) == "function" then JoinBattlegroundQueue(BG_NAMES[job.key]) return true end return false end if type(JoinBattlegroundQueue) == "function" then JoinBattlegroundQueue(BG_NAMES[job.key]) return true end return false end local function GetFinderFrame() if finderFrame then return finderFrame end finderFrame = CreateFrame("Frame") finderFrame:SetScript("OnEvent", function() if event ~= "BATTLEFIELDS_SHOW" then return end local job = pendingQueue[1] if not job then HidePvPPanels() EndSuppress() return end table.remove(pendingQueue, 1) if SetSelectedBattlefield then SetSelectedBattlefield(0) end if job.kind == "arena" then local meta = ARENA_META[job.key] or ARENA_META.SK lastQueuedArena = job.key -- Prefer explicit arena team-size setters where available. if type(SetArenaTeamSize) == "function" then SetArenaTeamSize(meta.size) end if JoinBattlefield then -- Turtle/Octo: JoinArenaQueue(id) opens Blood Ring, then -- JoinBattlefield(0[, asGroup]) actually joins First Available. if job.asGroup == 1 then JoinBattlefield(0, 1) else JoinBattlefield(0) end end else if JoinBattlefield then if job.asGroup == 1 then JoinBattlefield(0, 1) else JoinBattlefield(0) end end end HidePvPPanels() EndSuppress() -- Chain: if more queued, kick the next one after a very short delay. if pendingQueue[1] then local nxt = pendingQueue[1] BeginSuppress() finderFrame:RegisterEvent("BATTLEFIELDS_SHOW") if not KickFinderFor(nxt) then table.remove(pendingQueue, 1) finderFrame:UnregisterEvent("BATTLEFIELDS_SHOW") EndSuppress() end else finderFrame:UnregisterEvent("BATTLEFIELDS_SHOW") end end) return finderFrame end local function IsInGroup() if RelationshipsPVPGroupCheck and RelationshipsPVPGroupCheck:GetChecked() then return 1 end return 0 end local function EnqueueAndKick(job) local f = GetFinderFrame() -- If another job is already in flight, just append; the handler will chain. if pendingQueue[1] then table.insert(pendingQueue, job) return true end table.insert(pendingQueue, job) BeginSuppress() f:UnregisterAllEvents() f:RegisterEvent("BATTLEFIELDS_SHOW") if not KickFinderFor(job) then pendingQueue = {} f:UnregisterEvent("BATTLEFIELDS_SHOW") EndSuppress() return false end return true end function RelationshipsPVP_Queue(key) if not BG_NAMES[key] then return end local asGroup = IsInGroup() if EnqueueAndKick({ kind = "bg", key = key, asGroup = asGroup }) then Print("Queued: |cffffd200" .. BG_NAMES[key] .. "|r" .. (asGroup == 1 and " |cff66ff66(group)|r" or "")) return end -- Fallback: legacy vanilla flow (visit a Battlemaster first). if not JoinBattlefield then Print("|cffff4444Battleground Finder not available on this client.|r") return end local idx if key == "AV" then idx = 1 elseif key == "WSG" then idx = 2 elseif key == "AB" then idx = 3 end JoinBattlefield(idx, asGroup) Print("Requested queue: |cffffd200" .. BG_NAMES[key] .. "|r") end --------------------------------------------------------------- -- Arena queue: fully automated, no manual panel confirmation --------------------------------------------------------------- -- Turtle/Octo Blood Ring panel: JoinArenaQueue(id) opens a custom -- frame (typically BloodRingFrame). It does NOT fire BATTLEFIELDS_SHOW -- and JoinBattlefield does not apply, so we simulate a click on the -- panel's own Join button. -- Text labels the Blood Ring / arena finder Join button may carry. local ARENA_JOIN_TEXTS = { ["join battle"] = 1, ["join queue"] = 1, ["join"] = 1, ["enter queue"] = 1, ["enter battle"] = 1, ["queue"] = 1, ["enter"] = 1, ["join arena"] = 1, ["queue up"] = 1, } local function _btnText(btn) if not btn then return nil end if btn.GetText then local t = btn:GetText() if t and t ~= "" then return t end end local name = btn.GetName and btn:GetName() if name then local fs = getglobal(name.."Text") if fs and fs.GetText then return fs:GetText() end end return nil end local function _looksLikeJoin(btn) if not btn or type(btn.GetObjectType) ~= "function" then return false end if btn:GetObjectType() ~= "Button" then return false end if btn.IsVisible and not btn:IsVisible() then return false end if btn.IsEnabled and btn:IsEnabled() == 0 then return false end local t = _btnText(btn) if not t then return false end return ARENA_JOIN_TEXTS[string.lower(t)] == 1 end -- Locate the Blood Ring frame by likely names or a visible frame carrying -- a Join-style child button. local function FindArenaFinderFrame() local names = { "BloodRingFrame", "BloodringFrame", "BloodRingArenaFrame", "ArenaFinderFrame", "ArenaQueueFrame", "SkirmishFrame", "CustomArenaFrame", "PVPArenaFrame", } for i = 1, table.getn(names) do local f = getglobal(names[i]) if f and f.IsVisible and f:IsVisible() then return f end end return nil end local function FindJoinButtonIn(frame) if not frame then return nil end -- Try predictable child names first. local name = frame.GetName and frame:GetName() if name then local suffixes = { "JoinButton", "JoinBattleButton", "QueueButton", "EnterButton", "Button1", "OKButton", "AcceptButton", } for i = 1, table.getn(suffixes) do local b = getglobal(name .. suffixes[i]) if _looksLikeJoin(b) then return b end end end -- Walk direct children. if frame.GetChildren then local kids = { frame:GetChildren() } for i = 1, table.getn(kids) do if _looksLikeJoin(kids[i]) then return kids[i] end end -- One level deeper. for i = 1, table.getn(kids) do local k = kids[i] if k and k.GetChildren then local gkids = { k:GetChildren() } for j = 1, table.getn(gkids) do if _looksLikeJoin(gkids[j]) then return gkids[j] end end end end end return nil end -- Global sweep as a last resort: scan all frames for a visible Join-style -- button attached to a visible top-level frame. local function GlobalFindArenaJoinButton() local f = EnumerateFrames() while f do if f.IsVisible and f:IsVisible() and f.GetChildren then local kids = { f:GetChildren() } for i = 1, table.getn(kids) do if _looksLikeJoin(kids[i]) then return kids[i] end end end f = EnumerateFrames(f) end return nil end local arenaPoll local arenaPollElapsed = 0 local arenaPollDeadline = 0 local function StopArenaPoll() if arenaPoll then arenaPoll:Hide() end end local function StartArenaPoll() if not arenaPoll then arenaPoll = CreateFrame("Frame") arenaPoll:Hide() arenaPoll:SetScript("OnUpdate", function() arenaPollElapsed = arenaPollElapsed + arg1 if arenaPollElapsed < 0.05 then return end arenaPollElapsed = 0 local frame = FindArenaFinderFrame() local btn = FindJoinButtonIn(frame) if not btn then btn = GlobalFindArenaJoinButton() end if btn then -- Click the button as if the user pressed it. if btn.Click then btn:Click() end if frame and frame.Hide then frame:Hide() end HidePvPPanels() StopArenaPoll() return end if GetTime() > arenaPollDeadline then -- Give up quietly; leave the panel open so the user can click. StopArenaPoll() end end) end arenaPollElapsed = 0 arenaPollDeadline = GetTime() + 3.0 arenaPoll:Show() end function RelationshipsPVP_QueueArena(key) local meta = ARENA_META[key] if not meta then return end local asGroup = IsInGroup() lastQueuedArena = key -- 1) Direct TBC-style API — no panel involved. if type(JoinArena) == "function" then if type(SetArenaTeamSize) == "function" then SetArenaTeamSize(meta.size) end JoinArena(meta.size, meta.rated, asGroup) Print("Queued arena: |cffffd200" .. BG_NAMES[key] .. "|r" .. (asGroup == 1 and " |cff66ff66(group)|r" or "")) return end -- 2) Turtle/Octo custom entry point. JoinArenaQueue(id) opens the -- Blood Ring finder; we then click its Join button ourselves. if type(JoinArenaQueue) == "function" then local id = ARENA_IDS[key]; if id == nil then id = 0 end if type(SetArenaTeamSize) == "function" then SetArenaTeamSize(meta.size) end JoinArenaQueue(id) StartArenaPoll() Print("Queued arena: |cffffd200" .. BG_NAMES[key] .. "|r" .. (asGroup == 1 and " |cff66ff66(group)|r" or "")) return end Print("|cffff4444Arena API not available on this client. Visit an Arena Battlemaster.|r") end --------------------------------------------------------------- -- Queue for all standard battlegrounds (no arenas, no rated) --------------------------------------------------------------- function RelationshipsPVP_QueueAllBGs() local asGroup = IsInGroup() local kicked = 0 for i = 1, table.getn(BG_KEYS) do local key = BG_KEYS[i] if EnqueueAndKick({ kind = "bg", key = key, asGroup = asGroup }) then kicked = kicked + 1 end end if kicked > 0 then Print("Queueing all standard battlegrounds (" .. kicked .. "): |cffffd200AV, WSG, AB|r" .. (asGroup == 1 and " |cff66ff66(group)|r" or "")) else Print("|cffff4444Battleground Finder not available on this client.|r") end end function RelationshipsPVP_LeaveAll() local left = 0 for i = 1, 3 do local status = GetBattlefieldStatus(i) if status == "queued" or status == "confirm" then AcceptBattlefieldPort(i, 0) left = left + 1 end end if left > 0 then Print("Left " .. left .. " pending queue(s).") else Print("No active queues.") end pendingQueue = {} lastQueuedArena = nil end --------------------------------------------------------------- -- Minimap icon toggle --------------------------------------------------------------- function RelationshipsPVP_ToggleMinimapIcon() local db = EnsureDB() db.showIcon = not db.showIcon ApplyIconVisibility() Print(db.showIcon and "Minimap icon |cff66ff66shown|r." or "Minimap icon |cffff6666hidden|r. Use /rpvp to open.") end --------------------------------------------------------------- -- UI: build row FontStrings inside the stats panel --------------------------------------------------------------- local COL_X = { 14, 158, 208, 258, 308, 354, 400, 446, 496, 550, 614 } local COL_W = { 140, 46, 46, 46, 46, 46, 46, 46, 50, 60, 58 } local COL_J = { "LEFT", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER" } local COL_NAMES = { "bg", "games", "win", "loss", "ratio", "kb", "hk", "dth", "kd", "honor", "mk" } local ROW_HEIGHT = 22 local ROW_TOP = -34 local function MakeRow(panel, tag, yOff, striped) local row = {} if striped then local bg = panel:CreateTexture("RPVPRowBG"..tag, "BACKGROUND") bg:SetTexture(1, 1, 1, 0.04) bg:SetWidth(660); bg:SetHeight(ROW_HEIGHT - 2) bg:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, yOff + 2) end for c = 1, table.getn(COL_NAMES) do local fs = panel:CreateFontString( "RPVPRow"..tag.."_"..COL_NAMES[c], "ARTWORK", (c == 1) and "GameFontNormal" or "GameFontHighlight" ) fs:SetWidth(COL_W[c]); fs:SetHeight(18) fs:SetJustifyH(COL_J[c]) fs:SetPoint("TOPLEFT", panel, "TOPLEFT", COL_X[c], yOff) row[COL_NAMES[c]] = fs end return row end local function BuildStatsRows() if rowStrings["_built"] then return end local panel = RelationshipsPVPStatsPanel if not panel then return end for i = 1, table.getn(ALL_KEYS) do local key = ALL_KEYS[i] local yOff = ROW_TOP - (i - 1) * ROW_HEIGHT local row = MakeRow(panel, key, yOff, (math.mod(i, 2) == 0)) local col = BG_COLORS[key] row.bg:SetText(BG_NAMES[key]) row.bg:SetTextColor(col.r, col.g, col.b) rowStrings[key] = row end local n = table.getn(ALL_KEYS) local totalY = ROW_TOP - n * ROW_HEIGHT - 4 local div = panel:CreateTexture("RPVPTotalDivider", "ARTWORK") div:SetTexture(1, 1, 1, 0.25) div:SetWidth(660); div:SetHeight(1) div:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, totalY + 2) totalRow = MakeRow(panel, "TOTAL", totalY - 6, false) totalRow.bg:SetText("Total") totalRow.bg:SetTextColor(1.0, 0.95, 0.7) rowStrings["_built"] = true end local function FormatQueueLine() local lines = "" local any = false for i = 1, 3 do local status, mapName, _, _, _, teamSize, registered = GetBattlefieldStatus(i) if status and status ~= "none" then any = true local color = "|cffffffff" if status == "queued" then color = "|cffffff66" end if status == "confirm" then color = "|cff66ff66" end if status == "active" then color = "|cff66ccff" end local label = mapName or "?" if teamSize and teamSize > 0 then label = label .. " (" .. teamSize .. "v" .. teamSize .. ((registered == 1 or registered == true) and " rated" or " skirmish") .. ")" end lines = lines .. " [" .. i .. "] " .. label .. " - " .. color .. status .. "|r\n" end end if not any then return " |cff888888(no active queues)|r\n" end return lines end local function FillRow(r, s) local games = s.wins + s.losses local pct = 0 if games > 0 then pct = math.floor((s.wins / games) * 100 + 0.5) end local kd = "-" if s.deaths > 0 then kd = string.format("%.2f", (s.kills + s.hk) / s.deaths) elseif (s.kills + s.hk) > 0 then kd = "\226\136\158" end r.games:SetText(games) r.win:SetText(s.wins) r.loss:SetText(s.losses) r.ratio:SetText(pct .. "%") r.kb:SetText(s.kills) r.hk:SetText(s.hk) r.dth:SetText(s.deaths) r.kd:SetText(kd) r.honor:SetText(FormatNumber(s.honor)) r.mk:SetText(s.marks) if games == 0 then r.ratio:SetTextColor(0.7, 0.7, 0.7) elseif pct >= 60 then r.ratio:SetTextColor(0.4, 1.0, 0.4) elseif pct >= 40 then r.ratio:SetTextColor(1.0, 0.9, 0.4) else r.ratio:SetTextColor(1.0, 0.5, 0.5) end end function RelationshipsPVP_Refresh() if not RelationshipsPVPFrame or not RelationshipsPVPFrame:IsVisible() then return end local db = EnsureDB() BuildStatsRows() local totals = NewStatBlock() for i = 1, table.getn(ALL_KEYS) do local k = ALL_KEYS[i] local s = db.stats[k] local r = rowStrings[k] if r then FillRow(r, s) end totals.wins = totals.wins + s.wins totals.losses = totals.losses + s.losses totals.kills = totals.kills + s.kills totals.hk = totals.hk + s.hk totals.deaths = totals.deaths + s.deaths totals.honor = totals.honor + s.honor totals.marks = totals.marks + s.marks if s.bestStreak > totals.bestStreak then totals.bestStreak = s.bestStreak end if s.bestKB > totals.bestKB then totals.bestKB = s.bestKB end end if totalRow then FillRow(totalRow, totals) end if RelationshipsPVPExtrasText then RelationshipsPVPExtrasText:SetText( "|cffffd200Best win streak:|r " .. totals.bestStreak .. " |cffffd200Best KBs (single match):|r " .. totals.bestKB .. " |cffffd200Total honor:|r " .. FormatNumber(totals.honor) ) end local qtext = FormatQueueLine() if currentBG then qtext = qtext .. "\n |cff66ff66Currently inside: " .. BG_NAMES[currentBG] .. "|r" end if RelationshipsPVPQueueText then RelationshipsPVPQueueText:SetText(qtext) end end --------------------------------------------------------------- -- Reset panel + minimap button to the centre of the screen --------------------------------------------------------------- function RelationshipsPVP_ResetPositions() local db = EnsureDB() if RelationshipsPVPFrame then RelationshipsPVPFrame:ClearAllPoints() RelationshipsPVPFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0) RelationshipsPVPFrame:Show() end if RelationshipsPVPMinimapButton then RelationshipsPVPMinimapButton:ClearAllPoints() RelationshipsPVPMinimapButton:SetPoint("CENTER", UIParent, "CENTER", 0, 0) db.icon.point = "CENTER" db.icon.x = 0 db.icon.y = 0 db.icon.parent = "UIParent" end db.panel = { point = "CENTER", x = 0, y = 0 } Print("Panel and minimap button reset to screen centre.") end function RelationshipsPVP_ResetStats() local db = EnsureDB() for i = 1, table.getn(ALL_KEYS) do db.stats[ALL_KEYS[i]] = NewStatBlock() end Print("PvP statistics cleared.") RelationshipsPVP_Refresh() end --------------------------------------------------------------- -- Events --------------------------------------------------------------- function RelationshipsPVP_OnLoad() this:RegisterEvent("PLAYER_LOGIN") this:RegisterEvent("PLAYER_ENTERING_WORLD") this:RegisterEvent("UPDATE_BATTLEFIELD_STATUS") this:RegisterEvent("UPDATE_BATTLEFIELD_SCORE") this:RegisterEvent("PLAYER_DEAD") this:RegisterEvent("PLAYER_REGEN_ENABLED") this:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE") this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE") SLASH_RELATIONSHIPSPVP1 = "/rpvp" SLASH_RELATIONSHIPSPVP2 = "/relpvp" SLASH_RELATIONSHIPSPVP3 = "/relationshipspvp" SlashCmdList["RELATIONSHIPSPVP"] = function(msg) msg = string.lower(msg or "") if msg == "leave" then RelationshipsPVP_LeaveAll() elseif msg == "av" then RelationshipsPVP_Queue("AV") elseif msg == "wsg" then RelationshipsPVP_Queue("WSG") elseif msg == "ab" then RelationshipsPVP_Queue("AB") elseif msg == "all" then RelationshipsPVP_QueueAllBGs() elseif msg == "2v2" then RelationshipsPVP_QueueArena("A2") elseif msg == "3v3" then RelationshipsPVP_QueueArena("A3") elseif msg == "5v5" then RelationshipsPVP_QueueArena("A5") elseif msg == "skirmish" or msg == "sk" then RelationshipsPVP_QueueArena("SK") elseif msg == "icon" or msg == "minimap" then RelationshipsPVP_ToggleMinimapIcon() elseif msg == "reset" then RelationshipsPVP_ResetPositions() elseif msg == "clear" or msg == "wipe" then RelationshipsPVP_ResetStats() else if RelationshipsPVPFrame:IsVisible() then RelationshipsPVPFrame:Hide() else RelationshipsPVPFrame:Show() end end end Print("Loaded v1.8. Type /rpvp to open, /rpvp all to queue all BGs, /rpvp icon to toggle minimap icon.") end function RelationshipsPVP_SavePanelPos() SavePanelPos() end function RelationshipsPVP_OnEvent(event) if event == "PLAYER_LOGIN" or event == "PLAYER_ENTERING_WORLD" then EnsureDB() RestoreIconPos() RestorePanelPos() local key = DetectCurrentBG() currentBG = key if not key then endReported = {} end RelationshipsPVP_Refresh() elseif event == "UPDATE_BATTLEFIELD_STATUS" then local key = DetectCurrentBG() currentBG = key RelationshipsPVP_Refresh() elseif event == "UPDATE_BATTLEFIELD_SCORE" then local key, idx = DetectCurrentBG() if key and idx and GetBattlefieldWinner() then RecordEnd(key, idx) end RelationshipsPVP_Refresh() elseif event == "PLAYER_REGEN_ENABLED" then RelationshipsPVP_Refresh() elseif event == "CHAT_MSG_BG_SYSTEM_NEUTRAL" or event == "CHAT_MSG_BG_SYSTEM_ALLIANCE" or event == "CHAT_MSG_BG_SYSTEM_HORDE" then RequestBattlefieldScoreData() end end