Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 78076b8010 | |||
| 322e7469fb | |||
| f44f5dfde4 | |||
| 4129df824d | |||
| d03a61938f | |||
| 147375b056 | |||
| 021a103dbc | |||
| 1d9d713476 | |||
| 885846b676 |
@@ -1,4 +1,4 @@
|
|||||||
<img src="https://cdn.discordapp.com/attachments/1510333697277300856/1525103487002869870/bg.png?ex=6a522ace&is=6a50d94e&hm=a0905d6bf7226f5871d6338582075e5d31e5396073909b064fb92d22ac217c90&"/>
|
<img src="https://i.postimg.cc/Prk2RKn3/bg.png"/>
|
||||||
|
|
||||||
|
|
||||||
# Relationships PVP
|
# Relationships PVP
|
||||||
|
|||||||
+340
-37
@@ -63,32 +63,203 @@ local totalRow = nil
|
|||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
local function NewStatBlock()
|
local function NewStatBlock()
|
||||||
return {
|
return {
|
||||||
wins = 0, losses = 0,
|
wins = 0, draws = 0, losses = 0,
|
||||||
kills = 0, deaths = 0, hk = 0,
|
kills = 0, deaths = 0, hk = 0,
|
||||||
marks = 0, honor = 0,
|
marks = 0, honor = 0, spend = 0,
|
||||||
bestKB = 0, streak = 0, bestStreak = 0,
|
bestKB = 0, streak = 0, bestStreak = 0,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Read the player's current spendable honor from the honor UI ("H" panel).
|
||||||
|
-- Turtle / OctoWoW (1.18.1+) credits honor immediately as a currency; the
|
||||||
|
-- value shown at the top of the honor panel is the this-week honor total
|
||||||
|
-- returned by GetPVPThisWeekStats(). Fall back to session/lifetime stats
|
||||||
|
-- and finally GetHonorCurrency() for other clients.
|
||||||
|
local function GetSpendableHonor()
|
||||||
|
if type(GetPVPThisWeekStats) == "function" then
|
||||||
|
local hk, honor = GetPVPThisWeekStats()
|
||||||
|
if honor then return honor end
|
||||||
|
end
|
||||||
|
if type(GetPVPSessionStats) == "function" then
|
||||||
|
local hk, honor = GetPVPSessionStats()
|
||||||
|
if honor then return honor end
|
||||||
|
end
|
||||||
|
if type(GetHonorCurrency) == "function" then
|
||||||
|
return GetHonorCurrency() or 0
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local function EnsureDB()
|
local function EnsureDB()
|
||||||
local db = RelationshipsPVPCharDB
|
local db = RelationshipsPVPCharDB
|
||||||
db.stats = db.stats or {}
|
db.stats = db.stats or {}
|
||||||
db.icon = db.icon or { point = "CENTER", x = 60, y = -60 }
|
db.icon = db.icon or { point = "CENTER", x = 60, y = -60 }
|
||||||
if db.showIcon == nil then db.showIcon = true end
|
if db.showIcon == nil then db.showIcon = true end
|
||||||
|
-- Snapshot of spendable honor captured on BG entry:
|
||||||
|
-- { key = <BG_KEY>, value = <spendable honor when we entered> }
|
||||||
|
-- Persisted so a disconnect/relog mid-BG still resolves to a correct delta.
|
||||||
|
db.honorSnap = db.honorSnap or nil
|
||||||
|
-- Enemy kill tracking (BGs only)
|
||||||
|
db.killedByAll = db.killedByAll or {}
|
||||||
|
db.lastMatchKilledBy = db.lastMatchKilledBy or {}
|
||||||
|
db.lastMatchKey = db.lastMatchKey or nil
|
||||||
|
db.currentMatch = db.currentMatch or nil
|
||||||
for i = 1, table.getn(ALL_KEYS) do
|
for i = 1, table.getn(ALL_KEYS) do
|
||||||
local k = ALL_KEYS[i]
|
local k = ALL_KEYS[i]
|
||||||
local s = db.stats[k] or NewStatBlock()
|
local s = db.stats[k] or NewStatBlock()
|
||||||
if s.honor == nil then s.honor = 0 end
|
if s.honor == nil then s.honor = 0 end
|
||||||
|
if s.spend == nil then s.spend = 0 end
|
||||||
if s.bestKB == nil then s.bestKB = 0 end
|
if s.bestKB == nil then s.bestKB = 0 end
|
||||||
if s.streak == nil then s.streak = 0 end
|
if s.streak == nil then s.streak = 0 end
|
||||||
if s.bestStreak == nil then s.bestStreak = 0 end
|
if s.bestStreak == nil then s.bestStreak = 0 end
|
||||||
if s.hk == nil then s.hk = 0 end
|
if s.hk == nil then s.hk = 0 end
|
||||||
if s.marks == nil then s.marks = 0 end
|
if s.marks == nil then s.marks = 0 end
|
||||||
|
if s.draws == nil then s.draws = 0 end
|
||||||
db.stats[k] = s
|
db.stats[k] = s
|
||||||
end
|
end
|
||||||
return db
|
return db
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Capture the pre-match spendable-honor value on BG entry.
|
||||||
|
local function CaptureSpendableHonor(key)
|
||||||
|
if not key then return end
|
||||||
|
local db = EnsureDB()
|
||||||
|
if db.honorSnap and db.honorSnap.key == key then return end
|
||||||
|
local v = GetSpendableHonor()
|
||||||
|
if v == nil then return end
|
||||||
|
db.honorSnap = { key = key, value = v, credited = 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add any new delta between the current spendable-honor value and the
|
||||||
|
-- snapshot into the BG's spend total. Idempotent: tracks how much has
|
||||||
|
-- already been credited so RecordEnd + the on-leave transition together
|
||||||
|
-- never double-count. `clear` = true removes the snapshot afterwards.
|
||||||
|
local function FinalizeSpendableHonor(key, clear)
|
||||||
|
if not key then return end
|
||||||
|
local db = RelationshipsPVPCharDB
|
||||||
|
if not db or not db.honorSnap or db.honorSnap.key ~= key then return end
|
||||||
|
local now = GetSpendableHonor()
|
||||||
|
if now == nil then
|
||||||
|
if clear then db.honorSnap = nil end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local base = db.honorSnap.value or 0
|
||||||
|
local prior = db.honorSnap.credited or 0
|
||||||
|
local delta = (now - base) - prior
|
||||||
|
if delta < 0 then delta = 0 end
|
||||||
|
if delta > 0 then
|
||||||
|
local s = db.stats and db.stats[key]
|
||||||
|
if s then s.spend = (s.spend or 0) + delta end
|
||||||
|
db.honorSnap.credited = prior + delta
|
||||||
|
end
|
||||||
|
if clear then db.honorSnap = nil end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle a currentBG transition: capture on enter, finalize on leave.
|
||||||
|
local function OnCurrentBGChanged(prevKey, newKey)
|
||||||
|
if newKey and newKey ~= prevKey then
|
||||||
|
if prevKey then FinalizeSpendableHonor(prevKey, true) end
|
||||||
|
CaptureSpendableHonor(newKey)
|
||||||
|
elseif prevKey and not newKey then
|
||||||
|
FinalizeSpendableHonor(prevKey, true)
|
||||||
|
FinalizeMatchKillers()
|
||||||
|
end
|
||||||
|
if newKey and newKey ~= prevKey then
|
||||||
|
-- Starting a fresh BG: clear any stale currentMatch that didn't belong to this key.
|
||||||
|
local db = RelationshipsPVPCharDB
|
||||||
|
if db and db.currentMatch and db.currentMatch.key ~= newKey then
|
||||||
|
FinalizeMatchKillers()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------
|
||||||
|
-- Enemy kill tracking (who kills you the most)
|
||||||
|
---------------------------------------------------------------
|
||||||
|
local lastAttackerName = nil
|
||||||
|
local lastAttackerTime = 0
|
||||||
|
local ATTACKER_WINDOW = 15 -- seconds a hostile hit counts as "the killer"
|
||||||
|
|
||||||
|
-- Pull an attacker name out of a hostile combat log message. Handles:
|
||||||
|
-- "Name hits you for X." (melee)
|
||||||
|
-- "Name crits you for X." (melee crit)
|
||||||
|
-- "Name's Spell hits you for X Fire damage." (direct spell)
|
||||||
|
-- "You suffer X Shadow damage from Name's Curse of Agony." (periodic)
|
||||||
|
local function ExtractAttackerName(msg)
|
||||||
|
if not msg then return nil end
|
||||||
|
local n = string.gfind and nil -- unused; keep 1.12-safe
|
||||||
|
local from = string.find(msg, "from ")
|
||||||
|
if from then
|
||||||
|
local rest = string.sub(msg, from + 5)
|
||||||
|
local nm = string.gsub(rest, "'s.*$", "")
|
||||||
|
nm = string.gsub(nm, "%..*$", "")
|
||||||
|
nm = string.gsub(nm, "%s.*$", "")
|
||||||
|
if nm and nm ~= "" then return nm end
|
||||||
|
end
|
||||||
|
-- Fall back to the first token (attacker name, possibly with "'s")
|
||||||
|
local first = msg
|
||||||
|
local space = string.find(first, " ")
|
||||||
|
if space then first = string.sub(first, 1, space - 1) end
|
||||||
|
first = string.gsub(first, "'s$", "")
|
||||||
|
if first == "" then return nil end
|
||||||
|
-- Ignore garbage tokens that clearly aren't a player name.
|
||||||
|
if string.find(first, "^[%l]") then return nil end
|
||||||
|
if first == "You" or first == "you" then return nil end
|
||||||
|
return first
|
||||||
|
end
|
||||||
|
|
||||||
|
local function NoteHostileHit(msg)
|
||||||
|
if not currentBG then return end
|
||||||
|
local name = ExtractAttackerName(msg)
|
||||||
|
if not name then return end
|
||||||
|
lastAttackerName = name
|
||||||
|
lastAttackerTime = GetTime()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called on PLAYER_DEAD while in a BG: credit the most recent hostile hit
|
||||||
|
-- as the killer. Only tracked for real battlegrounds (AV/WSG/AB), not arenas.
|
||||||
|
local function RegisterDeath()
|
||||||
|
if not currentBG then return end
|
||||||
|
if currentBG ~= "AV" and currentBG ~= "WSG" and currentBG ~= "AB" then return end
|
||||||
|
if not lastAttackerName then return end
|
||||||
|
if (GetTime() - lastAttackerTime) > ATTACKER_WINDOW then return end
|
||||||
|
local db = EnsureDB()
|
||||||
|
if not db.currentMatch or db.currentMatch.key ~= currentBG then
|
||||||
|
db.currentMatch = { key = currentBG, killedBy = {} }
|
||||||
|
end
|
||||||
|
local n = lastAttackerName
|
||||||
|
db.currentMatch.killedBy[n] = (db.currentMatch.killedBy[n] or 0) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Called when we transition out of a BG: promote currentMatch tallies to
|
||||||
|
-- "last match" and roll them into the all-time KOS table.
|
||||||
|
local function FinalizeMatchKillers()
|
||||||
|
local db = RelationshipsPVPCharDB
|
||||||
|
if not db or not db.currentMatch then return end
|
||||||
|
local cm = db.currentMatch
|
||||||
|
local hasAny = false
|
||||||
|
local newLast = {}
|
||||||
|
for name, cnt in pairs(cm.killedBy or {}) do
|
||||||
|
newLast[name] = cnt
|
||||||
|
db.killedByAll[name] = (db.killedByAll[name] or 0) + cnt
|
||||||
|
hasAny = true
|
||||||
|
end
|
||||||
|
if hasAny then
|
||||||
|
db.lastMatchKilledBy = newLast
|
||||||
|
db.lastMatchKey = cm.key
|
||||||
|
end
|
||||||
|
db.currentMatch = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function TopKiller(tbl)
|
||||||
|
if not tbl then return nil, 0 end
|
||||||
|
local best, count = nil, 0
|
||||||
|
for name, c in pairs(tbl) do
|
||||||
|
if c > count then best, count = name, c end
|
||||||
|
end
|
||||||
|
return best, count
|
||||||
|
end
|
||||||
|
|
||||||
-- Clamp a UIParent-relative CENTER offset so the button stays visible on screen.
|
-- Clamp a UIParent-relative CENTER offset so the button stays visible on screen.
|
||||||
function RelationshipsPVP_ClampScreenOffset(x, y)
|
function RelationshipsPVP_ClampScreenOffset(x, y)
|
||||||
x = x or 0
|
x = x or 0
|
||||||
@@ -309,9 +480,18 @@ local function RecordEnd(key, index)
|
|||||||
if not s then return end
|
if not s then return end
|
||||||
|
|
||||||
local playerWon = false
|
local playerWon = false
|
||||||
|
local isDraw = false
|
||||||
local winner = GetBattlefieldWinner()
|
local winner = GetBattlefieldWinner()
|
||||||
if winner then
|
if winner then
|
||||||
local myFaction = UnitFactionGroup("player")
|
local myFaction = UnitFactionGroup("player")
|
||||||
|
-- Some server builds (incl. Turtle/Octo) report a draw as a winner
|
||||||
|
-- value that is neither 0 (Horde) nor 1 (Alliance). Treat anything
|
||||||
|
-- else as a draw so it isn't miscounted as a loss.
|
||||||
|
isDraw = (winner ~= 0 and winner ~= 1)
|
||||||
|
if isDraw then
|
||||||
|
s.draws = s.draws + 1
|
||||||
|
s.streak = 0
|
||||||
|
else
|
||||||
local wonAsAlliance = (winner == 1 and myFaction == "Alliance")
|
local wonAsAlliance = (winner == 1 and myFaction == "Alliance")
|
||||||
local wonAsHorde = (winner == 0 and myFaction == "Horde")
|
local wonAsHorde = (winner == 0 and myFaction == "Horde")
|
||||||
playerWon = wonAsAlliance or wonAsHorde
|
playerWon = wonAsAlliance or wonAsHorde
|
||||||
@@ -323,12 +503,19 @@ local function RecordEnd(key, index)
|
|||||||
s.losses = s.losses + 1
|
s.losses = s.losses + 1
|
||||||
s.streak = 0
|
s.streak = 0
|
||||||
end
|
end
|
||||||
|
end
|
||||||
local isBG = (key == "AV" or key == "WSG" or key == "AB")
|
local isBG = (key == "AV" or key == "WSG" or key == "AB")
|
||||||
if isBG then
|
if isBG then
|
||||||
|
-- Draws award the loss-tier mark count.
|
||||||
s.marks = s.marks + (playerWon and MARKS_WIN or MARKS_LOSS)
|
s.marks = s.marks + (playerWon and MARKS_WIN or MARKS_LOSS)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Roll up any spendable honor gained so far this match. Snapshot is
|
||||||
|
-- kept until the currentBG->nil transition so late-credit ticks
|
||||||
|
-- (e.g. end-of-match bonus) still count.
|
||||||
|
FinalizeSpendableHonor(key, false)
|
||||||
|
|
||||||
RequestBattlefieldScoreData()
|
RequestBattlefieldScoreData()
|
||||||
local me = UnitName("player")
|
local me = UnitName("player")
|
||||||
local rows = GetNumBattlefieldScores() or 0
|
local rows = GetNumBattlefieldScores() or 0
|
||||||
@@ -352,9 +539,15 @@ local function RecordEnd(key, index)
|
|||||||
if key == "AV" or key == "WSG" or key == "AB" then
|
if key == "AV" or key == "WSG" or key == "AB" then
|
||||||
marksMsg = " +" .. (playerWon and MARKS_WIN or MARKS_LOSS) .. " marks"
|
marksMsg = " +" .. (playerWon and MARKS_WIN or MARKS_LOSS) .. " marks"
|
||||||
end
|
end
|
||||||
Print(BG_NAMES[key] .. " recorded ("
|
local outcomeStr
|
||||||
.. (playerWon and "|cff66ff66win|r" or "|cffff6666loss|r")
|
if isDraw then
|
||||||
.. marksMsg .. ").")
|
outcomeStr = "|cffffff66draw|r"
|
||||||
|
elseif playerWon then
|
||||||
|
outcomeStr = "|cff66ff66win|r"
|
||||||
|
else
|
||||||
|
outcomeStr = "|cffff6666loss|r"
|
||||||
|
end
|
||||||
|
Print(BG_NAMES[key] .. " recorded (" .. outcomeStr .. marksMsg .. ").")
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
@@ -362,41 +555,71 @@ end
|
|||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
-- Auto-close the Blizzard PvP panels if they pop up as a side effect
|
-- Auto-close the Blizzard PvP panels if they pop up as a side effect
|
||||||
-- of the arena / BG queueing calls.
|
-- of the arena / BG queueing calls.
|
||||||
|
-- NOTE: We deliberately do NOT call HideUIPanel() here. HideUIPanel on a
|
||||||
|
-- frame that Blizzard's UI panel system has slotted into a left/center
|
||||||
|
-- slot triggers a slot reflow, which is what caused Character / Friends /
|
||||||
|
-- Spellbook panels to jump to the middle of the screen after the PvP
|
||||||
|
-- panel was opened. Directly calling :Hide() bypasses the slot manager
|
||||||
|
-- entirely; the slot suppression below (SuppressUIPanelWindows) ensures
|
||||||
|
-- Blizzard never registered a slot for these frames to begin with.
|
||||||
local function HidePvPPanels()
|
local function HidePvPPanels()
|
||||||
if BattlefieldFrame and BattlefieldFrame:IsVisible() then HideUIPanel(BattlefieldFrame) end
|
if BattlefieldFrame and BattlefieldFrame:IsVisible() then BattlefieldFrame:Hide() end
|
||||||
if PVPBattlegroundFrame and PVPBattlegroundFrame:IsVisible() then HideUIPanel(PVPBattlegroundFrame) end
|
if PVPBattlegroundFrame and PVPBattlegroundFrame:IsVisible() then PVPBattlegroundFrame:Hide() end
|
||||||
if PVPFrame and PVPFrame:IsVisible() then HideUIPanel(PVPFrame) end
|
if PVPFrame and PVPFrame:IsVisible() then PVPFrame:Hide() end
|
||||||
if HonorFrame and HonorFrame:IsVisible() then HideUIPanel(HonorFrame) end
|
if HonorFrame and HonorFrame:IsVisible() then HonorFrame:Hide() end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Suppress the PvP panel entirely while we are auto-queueing. Reference-counted
|
-- Suppress the PvP panel entirely while we are auto-queueing. Reference-counted
|
||||||
-- so nested queues (Queue All BGs) do not release too early.
|
-- so nested queues (Queue All BGs) do not release too early.
|
||||||
|
--
|
||||||
|
-- IMPORTANT: We previously hijacked BattlefieldFrame.Show / PVPBattlegroundFrame.Show
|
||||||
|
-- to no-op during suppression. That was the source of the "Character / Friends
|
||||||
|
-- panels jump to the middle of the screen" bug: Blizzard's ShowUIPanel() first
|
||||||
|
-- allocates a UI panel slot (left / center / doublewide) via UIPanelWindows,
|
||||||
|
-- THEN calls frame:Show(). Silently dropping :Show() left the slot reserved by
|
||||||
|
-- an invisible frame, so the next panel the user opened (Character, Friends,
|
||||||
|
-- Spellbook, ...) got shoved into a different slot -> centered.
|
||||||
|
--
|
||||||
|
-- The correct approach on 1.12 is to temporarily remove these frames from
|
||||||
|
-- UIPanelWindows while suppressing, so ShowUIPanel treats them as plain
|
||||||
|
-- frames and never allocates a slot. When suppression ends, the original
|
||||||
|
-- UIPanelWindows entries are restored so normal Blizzard UI behaviour is
|
||||||
|
-- preserved for the rest of the session.
|
||||||
local suppressPanels = 0
|
local suppressPanels = 0
|
||||||
local suppressHooked = false
|
local savedUIPanelEntries = nil
|
||||||
local origBattlefieldShow, origPVPBGShow
|
|
||||||
|
|
||||||
local function InstallPanelSuppressor()
|
local SUPPRESSED_PANEL_NAMES = {
|
||||||
if suppressHooked then return end
|
"BattlefieldFrame",
|
||||||
suppressHooked = true
|
"PVPBattlegroundFrame",
|
||||||
if BattlefieldFrame then
|
"PVPFrame",
|
||||||
origBattlefieldShow = BattlefieldFrame.Show
|
"HonorFrame",
|
||||||
BattlefieldFrame.Show = function(self, ...)
|
}
|
||||||
if suppressPanels > 0 then return end
|
|
||||||
origBattlefieldShow(self)
|
local function SuppressUIPanelWindows()
|
||||||
end
|
if savedUIPanelEntries then return end
|
||||||
end
|
savedUIPanelEntries = {}
|
||||||
if PVPBattlegroundFrame then
|
if type(UIPanelWindows) ~= "table" then return end
|
||||||
origPVPBGShow = PVPBattlegroundFrame.Show
|
for i = 1, table.getn(SUPPRESSED_PANEL_NAMES) do
|
||||||
PVPBattlegroundFrame.Show = function(self, ...)
|
local name = SUPPRESSED_PANEL_NAMES[i]
|
||||||
if suppressPanels > 0 then return end
|
savedUIPanelEntries[name] = UIPanelWindows[name]
|
||||||
origPVPBGShow(self)
|
UIPanelWindows[name] = nil
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function RestoreUIPanelWindows()
|
||||||
|
if not savedUIPanelEntries then return end
|
||||||
|
if type(UIPanelWindows) == "table" then
|
||||||
|
for i = 1, table.getn(SUPPRESSED_PANEL_NAMES) do
|
||||||
|
local name = SUPPRESSED_PANEL_NAMES[i]
|
||||||
|
UIPanelWindows[name] = savedUIPanelEntries[name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
savedUIPanelEntries = nil
|
||||||
|
end
|
||||||
|
|
||||||
local function BeginSuppress()
|
local function BeginSuppress()
|
||||||
InstallPanelSuppressor()
|
|
||||||
suppressPanels = suppressPanels + 1
|
suppressPanels = suppressPanels + 1
|
||||||
|
SuppressUIPanelWindows()
|
||||||
HidePvPPanels()
|
HidePvPPanels()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -404,6 +627,9 @@ local function EndSuppress()
|
|||||||
suppressPanels = suppressPanels - 1
|
suppressPanels = suppressPanels - 1
|
||||||
if suppressPanels < 0 then suppressPanels = 0 end
|
if suppressPanels < 0 then suppressPanels = 0 end
|
||||||
HidePvPPanels()
|
HidePvPPanels()
|
||||||
|
if suppressPanels == 0 then
|
||||||
|
RestoreUIPanelWindows()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Central pending-queue state. `pendingQueue` is a FIFO of items:
|
-- Central pending-queue state. `pendingQueue` is a FIFO of items:
|
||||||
@@ -763,10 +989,10 @@ end
|
|||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
-- UI: build row FontStrings inside the stats panel
|
-- UI: build row FontStrings inside the stats panel
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
local COL_X = { 14, 158, 208, 258, 308, 354, 400, 446, 496, 550, 614 }
|
local COL_X = { 14, 158, 208, 258, 308, 358, 408, 458, 508, 558, 612, 668, 740 }
|
||||||
local COL_W = { 140, 46, 46, 46, 46, 46, 46, 46, 50, 60, 58 }
|
local COL_W = { 140, 46, 46, 46, 46, 46, 46, 46, 46, 50, 54, 70, 100 }
|
||||||
local COL_J = { "LEFT", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER", "CENTER" }
|
local COL_J = { "LEFT", "CENTER", "CENTER", "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 COL_NAMES = { "bg", "games", "win", "draw", "loss", "ratio", "kb", "hk", "dth", "kd", "mk", "bonus", "spend" }
|
||||||
|
|
||||||
local ROW_HEIGHT = 22
|
local ROW_HEIGHT = 22
|
||||||
local ROW_TOP = -34
|
local ROW_TOP = -34
|
||||||
@@ -776,7 +1002,7 @@ local function MakeRow(panel, tag, yOff, striped)
|
|||||||
if striped then
|
if striped then
|
||||||
local bg = panel:CreateTexture("RPVPRowBG"..tag, "BACKGROUND")
|
local bg = panel:CreateTexture("RPVPRowBG"..tag, "BACKGROUND")
|
||||||
bg:SetTexture(1, 1, 1, 0.04)
|
bg:SetTexture(1, 1, 1, 0.04)
|
||||||
bg:SetWidth(660); bg:SetHeight(ROW_HEIGHT - 2)
|
bg:SetWidth(846); bg:SetHeight(ROW_HEIGHT - 2)
|
||||||
bg:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, yOff + 2)
|
bg:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, yOff + 2)
|
||||||
end
|
end
|
||||||
for c = 1, table.getn(COL_NAMES) do
|
for c = 1, table.getn(COL_NAMES) do
|
||||||
@@ -812,7 +1038,7 @@ local function BuildStatsRows()
|
|||||||
local totalY = ROW_TOP - n * ROW_HEIGHT - 4
|
local totalY = ROW_TOP - n * ROW_HEIGHT - 4
|
||||||
local div = panel:CreateTexture("RPVPTotalDivider", "ARTWORK")
|
local div = panel:CreateTexture("RPVPTotalDivider", "ARTWORK")
|
||||||
div:SetTexture(1, 1, 1, 0.25)
|
div:SetTexture(1, 1, 1, 0.25)
|
||||||
div:SetWidth(660); div:SetHeight(1)
|
div:SetWidth(846); div:SetHeight(1)
|
||||||
div:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, totalY + 2)
|
div:SetPoint("TOPLEFT", panel, "TOPLEFT", 14, totalY + 2)
|
||||||
|
|
||||||
totalRow = MakeRow(panel, "TOTAL", totalY - 6, false)
|
totalRow = MakeRow(panel, "TOTAL", totalY - 6, false)
|
||||||
@@ -847,7 +1073,8 @@ local function FormatQueueLine()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function FillRow(r, s)
|
local function FillRow(r, s)
|
||||||
local games = s.wins + s.losses
|
local draws = s.draws or 0
|
||||||
|
local games = s.wins + draws + s.losses
|
||||||
local pct = 0
|
local pct = 0
|
||||||
if games > 0 then pct = math.floor((s.wins / games) * 100 + 0.5) end
|
if games > 0 then pct = math.floor((s.wins / games) * 100 + 0.5) end
|
||||||
local kd = "-"
|
local kd = "-"
|
||||||
@@ -859,14 +1086,23 @@ local function FillRow(r, s)
|
|||||||
|
|
||||||
r.games:SetText(games)
|
r.games:SetText(games)
|
||||||
r.win:SetText(s.wins)
|
r.win:SetText(s.wins)
|
||||||
|
r.draw:SetText(draws)
|
||||||
r.loss:SetText(s.losses)
|
r.loss:SetText(s.losses)
|
||||||
r.ratio:SetText(pct .. "%")
|
r.ratio:SetText(pct .. "%")
|
||||||
r.kb:SetText(s.kills)
|
r.kb:SetText(s.kills)
|
||||||
r.hk:SetText(s.hk)
|
r.hk:SetText(s.hk)
|
||||||
r.dth:SetText(s.deaths)
|
r.dth:SetText(s.deaths)
|
||||||
r.kd:SetText(kd)
|
r.kd:SetText(kd)
|
||||||
r.honor:SetText(FormatNumber(s.honor))
|
|
||||||
r.mk:SetText(s.marks)
|
r.mk:SetText(s.marks)
|
||||||
|
-- Bonus honor is the honor gained from the battlefield scoreboard
|
||||||
|
-- (GetBattlefieldScore -> honorGained). Tracked per-match, per-bracket.
|
||||||
|
r.bonus:SetText(FormatNumber(s.honor or 0))
|
||||||
|
r.bonus:SetTextColor(0.6, 0.85, 1.0)
|
||||||
|
-- Spendable honor is measured as the delta of the honor UI ("H" panel)
|
||||||
|
-- from BG entry -> BG exit. This is the honor actually credited to the
|
||||||
|
-- character wallet for this BG, tracked per-player from the client.
|
||||||
|
r.spend:SetText(FormatNumber(s.spend or 0))
|
||||||
|
r.spend:SetTextColor(1.0, 0.82, 0.0)
|
||||||
|
|
||||||
if games == 0 then
|
if games == 0 then
|
||||||
r.ratio:SetTextColor(0.7, 0.7, 0.7)
|
r.ratio:SetTextColor(0.7, 0.7, 0.7)
|
||||||
@@ -892,11 +1128,13 @@ function RelationshipsPVP_Refresh()
|
|||||||
if r then FillRow(r, s) end
|
if r then FillRow(r, s) end
|
||||||
|
|
||||||
totals.wins = totals.wins + s.wins
|
totals.wins = totals.wins + s.wins
|
||||||
|
totals.draws = totals.draws + (s.draws or 0)
|
||||||
totals.losses = totals.losses + s.losses
|
totals.losses = totals.losses + s.losses
|
||||||
totals.kills = totals.kills + s.kills
|
totals.kills = totals.kills + s.kills
|
||||||
totals.hk = totals.hk + s.hk
|
totals.hk = totals.hk + s.hk
|
||||||
totals.deaths = totals.deaths + s.deaths
|
totals.deaths = totals.deaths + s.deaths
|
||||||
totals.honor = totals.honor + s.honor
|
totals.honor = totals.honor + s.honor
|
||||||
|
totals.spend = (totals.spend or 0) + (s.spend or 0)
|
||||||
totals.marks = totals.marks + s.marks
|
totals.marks = totals.marks + s.marks
|
||||||
if s.bestStreak > totals.bestStreak then totals.bestStreak = s.bestStreak end
|
if s.bestStreak > totals.bestStreak then totals.bestStreak = s.bestStreak end
|
||||||
if s.bestKB > totals.bestKB then totals.bestKB = s.bestKB end
|
if s.bestKB > totals.bestKB then totals.bestKB = s.bestKB end
|
||||||
@@ -908,10 +1146,37 @@ function RelationshipsPVP_Refresh()
|
|||||||
RelationshipsPVPExtrasText:SetText(
|
RelationshipsPVPExtrasText:SetText(
|
||||||
"|cffffd200Best win streak:|r " .. totals.bestStreak
|
"|cffffd200Best win streak:|r " .. totals.bestStreak
|
||||||
.. " |cffffd200Best KBs (single match):|r " .. totals.bestKB
|
.. " |cffffd200Best KBs (single match):|r " .. totals.bestKB
|
||||||
.. " |cffffd200Total honor:|r " .. FormatNumber(totals.honor)
|
.. " |cffffd200Total bonus honor:|r |cffffd100" .. FormatNumber(totals.honor or 0) .. "|r"
|
||||||
|
.. " |cffffd200Total spendable honor:|r |cffffd100" .. FormatNumber(totals.spend or 0) .. "|r"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if RelationshipsPVPNemesisText then
|
||||||
|
local nm, cnt = TopKiller(db.lastMatchKilledBy)
|
||||||
|
if nm then
|
||||||
|
local bgTag = ""
|
||||||
|
if db.lastMatchKey and BG_NAMES[db.lastMatchKey] then
|
||||||
|
bgTag = " |cff888888(" .. BG_NAMES[db.lastMatchKey] .. ")|r"
|
||||||
|
end
|
||||||
|
RelationshipsPVPNemesisText:SetText(
|
||||||
|
"|cffff9966Last BG Nemesis:|r |cffffffff" .. nm .. "|r |cffff6666x" .. cnt .. "|r" .. bgTag
|
||||||
|
)
|
||||||
|
else
|
||||||
|
RelationshipsPVPNemesisText:SetText("|cffff9966Last BG Nemesis:|r |cff888888none yet|r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if RelationshipsPVPKOSText then
|
||||||
|
local nm, cnt = TopKiller(db.killedByAll)
|
||||||
|
if nm then
|
||||||
|
RelationshipsPVPKOSText:SetText(
|
||||||
|
"|cffff3333KOS:|r |cffffffff" .. nm .. "|r |cffff6666x" .. cnt .. "|r"
|
||||||
|
)
|
||||||
|
else
|
||||||
|
RelationshipsPVPKOSText:SetText("|cffff3333KOS:|r |cff888888none yet|r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local qtext = FormatQueueLine()
|
local qtext = FormatQueueLine()
|
||||||
if currentBG then
|
if currentBG then
|
||||||
qtext = qtext .. "\n |cff66ff66Currently inside: " .. BG_NAMES[currentBG] .. "|r"
|
qtext = qtext .. "\n |cff66ff66Currently inside: " .. BG_NAMES[currentBG] .. "|r"
|
||||||
@@ -969,6 +1234,12 @@ function RelationshipsPVP_OnLoad()
|
|||||||
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL")
|
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL")
|
||||||
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE")
|
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE")
|
||||||
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE")
|
this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE")
|
||||||
|
this:RegisterEvent("CHAT_MSG_COMBAT_HONOR_GAIN")
|
||||||
|
this:RegisterEvent("PLAYER_PVP_KILLS_CHANGED")
|
||||||
|
this:RegisterEvent("HONOR_CURRENCY_UPDATE")
|
||||||
|
this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS")
|
||||||
|
this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE")
|
||||||
|
this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE")
|
||||||
|
|
||||||
SLASH_RELATIONSHIPSPVP1 = "/rpvp"
|
SLASH_RELATIONSHIPSPVP1 = "/rpvp"
|
||||||
SLASH_RELATIONSHIPSPVP2 = "/relpvp"
|
SLASH_RELATIONSHIPSPVP2 = "/relpvp"
|
||||||
@@ -999,6 +1270,13 @@ function RelationshipsPVP_OnLoad()
|
|||||||
RelationshipsPVP_ResetPositions()
|
RelationshipsPVP_ResetPositions()
|
||||||
elseif msg == "clear" or msg == "wipe" then
|
elseif msg == "clear" or msg == "wipe" then
|
||||||
RelationshipsPVP_ResetStats()
|
RelationshipsPVP_ResetStats()
|
||||||
|
elseif msg == "clearkos" or msg == "kos" then
|
||||||
|
RelationshipsPVPCharDB.killedByAll = {}
|
||||||
|
RelationshipsPVPCharDB.lastMatchKilledBy = {}
|
||||||
|
RelationshipsPVPCharDB.lastMatchKey = nil
|
||||||
|
RelationshipsPVPCharDB.currentMatch = nil
|
||||||
|
Print("Enemy kill tracking cleared.")
|
||||||
|
RelationshipsPVP_Refresh()
|
||||||
else
|
else
|
||||||
if RelationshipsPVPFrame:IsVisible() then
|
if RelationshipsPVPFrame:IsVisible() then
|
||||||
RelationshipsPVPFrame:Hide()
|
RelationshipsPVPFrame:Hide()
|
||||||
@@ -1027,13 +1305,17 @@ function RelationshipsPVP_OnEvent(event)
|
|||||||
RestoreIconPos()
|
RestoreIconPos()
|
||||||
RestorePanelPos()
|
RestorePanelPos()
|
||||||
local key = DetectCurrentBG()
|
local key = DetectCurrentBG()
|
||||||
|
local prev = currentBG
|
||||||
currentBG = key
|
currentBG = key
|
||||||
|
OnCurrentBGChanged(prev, key)
|
||||||
if not key then endReported = {} end
|
if not key then endReported = {} end
|
||||||
RelationshipsPVP_Refresh()
|
RelationshipsPVP_Refresh()
|
||||||
|
|
||||||
elseif event == "UPDATE_BATTLEFIELD_STATUS" then
|
elseif event == "UPDATE_BATTLEFIELD_STATUS" then
|
||||||
local key = DetectCurrentBG()
|
local key = DetectCurrentBG()
|
||||||
|
local prev = currentBG
|
||||||
currentBG = key
|
currentBG = key
|
||||||
|
OnCurrentBGChanged(prev, key)
|
||||||
RelationshipsPVP_Refresh()
|
RelationshipsPVP_Refresh()
|
||||||
|
|
||||||
elseif event == "UPDATE_BATTLEFIELD_SCORE" then
|
elseif event == "UPDATE_BATTLEFIELD_SCORE" then
|
||||||
@@ -1050,5 +1332,26 @@ function RelationshipsPVP_OnEvent(event)
|
|||||||
or event == "CHAT_MSG_BG_SYSTEM_ALLIANCE"
|
or event == "CHAT_MSG_BG_SYSTEM_ALLIANCE"
|
||||||
or event == "CHAT_MSG_BG_SYSTEM_HORDE" then
|
or event == "CHAT_MSG_BG_SYSTEM_HORDE" then
|
||||||
RequestBattlefieldScoreData()
|
RequestBattlefieldScoreData()
|
||||||
|
|
||||||
|
elseif event == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"
|
||||||
|
or event == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"
|
||||||
|
or event == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE" then
|
||||||
|
NoteHostileHit(arg1)
|
||||||
|
|
||||||
|
elseif event == "PLAYER_DEAD" then
|
||||||
|
RegisterDeath()
|
||||||
|
RelationshipsPVP_Refresh()
|
||||||
|
|
||||||
|
elseif event == "CHAT_MSG_COMBAT_HONOR_GAIN"
|
||||||
|
or event == "PLAYER_PVP_KILLS_CHANGED"
|
||||||
|
or event == "HONOR_CURRENCY_UPDATE" then
|
||||||
|
-- Honor was just credited. If we're currently in a tracked BG, roll
|
||||||
|
-- the spendable-honor delta into this BG's spend total right away so
|
||||||
|
-- the value ticks live instead of only at the final scoreboard.
|
||||||
|
if currentBG then
|
||||||
|
CaptureSpendableHonor(currentBG)
|
||||||
|
FinalizeSpendableHonor(currentBG, false)
|
||||||
|
RelationshipsPVP_Refresh()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
## Title: Relationships PVP
|
## Title: Relationships PVP
|
||||||
## Notes: PvP panel with per-battleground and per-arena stats, marks, kills/deaths, honor, K/D, and queue controls. Supports the Battleground Finder and Arena on OctoWoW.
|
## Notes: PvP panel with per-battleground and per-arena stats, marks, kills/deaths, honor, K/D, and queue controls. Supports the Battleground Finder and Arena on OctoWoW.
|
||||||
## Author: Relationship
|
## Author: Relationship
|
||||||
## Version: 1.0
|
## Version: 1.4
|
||||||
## SavedVariablesPerCharacter: RelationshipsPVPCharDB
|
## SavedVariablesPerCharacter: RelationshipsPVPCharDB
|
||||||
|
|
||||||
RelationshipsPVP.xml
|
RelationshipsPVP.xml
|
||||||
|
|||||||
+48
-32
@@ -6,7 +6,7 @@
|
|||||||
============================================================ -->
|
============================================================ -->
|
||||||
<Frame name="RelationshipsPVPFrame" parent="UIParent" toplevel="true" movable="true" enableMouse="true" hidden="true" frameStrata="HIGH">
|
<Frame name="RelationshipsPVPFrame" parent="UIParent" toplevel="true" movable="true" enableMouse="true" hidden="true" frameStrata="HIGH">
|
||||||
<Size>
|
<Size>
|
||||||
<AbsDimension x="740" y="740"/>
|
<AbsDimension x="916" y="740"/>
|
||||||
</Size>
|
</Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="CENTER"/>
|
<Anchor point="CENTER"/>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</Anchors>
|
</Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
|
|
||||||
<FontString name="RelationshipsPVPActionLabel" inherits="GameFontNormal" text="Queue Battleground / Arena" justifyH="LEFT">
|
<FontString name="RelationshipsPVPActionLabel" inherits="GameFontNormal" text=" Queue Battleground / Arena" justifyH="LEFT">
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT">
|
<Anchor point="TOPLEFT">
|
||||||
<Offset><AbsDimension x="24" y="-454"/></Offset>
|
<Offset><AbsDimension x="24" y="-454"/></Offset>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
<!-- ================= Stats Panel ================= -->
|
<!-- ================= Stats Panel ================= -->
|
||||||
<Frame name="RelationshipsPVPStatsPanel">
|
<Frame name="RelationshipsPVPStatsPanel">
|
||||||
<Size><AbsDimension x="692" y="266"/></Size>
|
<Size><AbsDimension x="868" y="266"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT">
|
<Anchor point="TOPLEFT">
|
||||||
<Offset><AbsDimension x="24" y="-72"/></Offset>
|
<Offset><AbsDimension x="24" y="-72"/></Offset>
|
||||||
@@ -99,58 +99,80 @@
|
|||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="208" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="208" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrLoss" inherits="GameFontNormalSmall" text="Loss" justifyH="CENTER">
|
<FontString name="RPVPHdrDraw" inherits="GameFontNormalSmall" text="Draw" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="258" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="258" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrRatio" inherits="GameFontNormalSmall" text="Win%" justifyH="CENTER">
|
<FontString name="RPVPHdrLoss" inherits="GameFontNormalSmall" text="Loss" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="308" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="308" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
|
<FontString name="RPVPHdrRatio" inherits="GameFontNormalSmall" text="Win%" justifyH="CENTER">
|
||||||
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="358" y="-10"/></Offset></Anchor></Anchors>
|
||||||
|
</FontString>
|
||||||
<FontString name="RPVPHdrKB" inherits="GameFontNormalSmall" text="KB" justifyH="CENTER">
|
<FontString name="RPVPHdrKB" inherits="GameFontNormalSmall" text="KB" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="354" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="408" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrHK" inherits="GameFontNormalSmall" text="HK" justifyH="CENTER">
|
<FontString name="RPVPHdrHK" inherits="GameFontNormalSmall" text="HK" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="400" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="458" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrDth" inherits="GameFontNormalSmall" text="Deaths" justifyH="CENTER">
|
<FontString name="RPVPHdrDth" inherits="GameFontNormalSmall" text="Deaths" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="46" y="14"/></Size>
|
<Size><AbsDimension x="46" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="446" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="508" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrKD" inherits="GameFontNormalSmall" text="K/D" justifyH="CENTER">
|
<FontString name="RPVPHdrKD" inherits="GameFontNormalSmall" text="K/D" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="50" y="14"/></Size>
|
<Size><AbsDimension x="50" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="496" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="558" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
|
||||||
<FontString name="RPVPHdrHonor" inherits="GameFontNormalSmall" text="Honor" justifyH="CENTER">
|
|
||||||
<Size><AbsDimension x="60" y="14"/></Size>
|
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="550" y="-10"/></Offset></Anchor></Anchors>
|
|
||||||
</FontString>
|
</FontString>
|
||||||
<FontString name="RPVPHdrMk" inherits="GameFontNormalSmall" text="Marks" justifyH="CENTER">
|
<FontString name="RPVPHdrMk" inherits="GameFontNormalSmall" text="Marks" justifyH="CENTER">
|
||||||
<Size><AbsDimension x="58" y="14"/></Size>
|
<Size><AbsDimension x="54" y="14"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="614" y="-10"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="612" y="-10"/></Offset></Anchor></Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="RPVPHdrBonus" inherits="GameFontNormalSmall" text="Bonus Honor" justifyH="CENTER">
|
||||||
|
<Size><AbsDimension x="70" y="14"/></Size>
|
||||||
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="668" y="-10"/></Offset></Anchor></Anchors>
|
||||||
|
</FontString>
|
||||||
|
<FontString name="RPVPHdrSpend" inherits="GameFontNormalSmall" text=" Spendable Honor" justifyH="CENTER">
|
||||||
|
<Size><AbsDimension x="100" y="14"/></Size>
|
||||||
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="740" y="-10"/></Offset></Anchor></Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
|
|
||||||
<Texture name="RPVPHdrDivider" file="Interface\Tooltips\UI-Tooltip-Background">
|
<Texture name="RPVPHdrDivider" file="Interface\Tooltips\UI-Tooltip-Background">
|
||||||
<Size><AbsDimension x="664" y="1"/></Size>
|
<Size><AbsDimension x="846" y="1"/></Size>
|
||||||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="14" y="-28"/></Offset></Anchor></Anchors>
|
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="14" y="-28"/></Offset></Anchor></Anchors>
|
||||||
<Color r="0.6" g="0.6" b="0.6" a="0.6"/>
|
<Color r="0.6" g="0.6" b="0.6" a="0.6"/>
|
||||||
</Texture>
|
</Texture>
|
||||||
|
|
||||||
<FontString name="RelationshipsPVPExtrasText" inherits="GameFontHighlightSmall" justifyH="LEFT">
|
<FontString name="RelationshipsPVPExtrasText" inherits="GameFontHighlightSmall" justifyH="LEFT">
|
||||||
<Size><AbsDimension x="664" y="16"/></Size>
|
<Size><AbsDimension x="640" y="16"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="14" y="10"/></Offset></Anchor>
|
<Anchor point="BOTTOMLEFT"><Offset><AbsDimension x="14" y="10"/></Offset></Anchor>
|
||||||
</Anchors>
|
</Anchors>
|
||||||
</FontString>
|
</FontString>
|
||||||
|
|
||||||
|
<FontString name="RelationshipsPVPNemesisText" inherits="GameFontHighlightSmall" justifyH="CENTER">
|
||||||
|
<Size><AbsDimension x="200" y="16"/></Size>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="BOTTOM"><Offset><AbsDimension x="220" y="10"/></Offset></Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
|
|
||||||
|
<FontString name="RelationshipsPVPKOSText" inherits="GameFontHighlightSmall" justifyH="RIGHT">
|
||||||
|
<Size><AbsDimension x="80" y="16"/></Size>
|
||||||
|
<Anchors>
|
||||||
|
<Anchor point="BOTTOMRIGHT"><Offset><AbsDimension x="-14" y="10"/></Offset></Anchor>
|
||||||
|
</Anchors>
|
||||||
|
</FontString>
|
||||||
</Layer>
|
</Layer>
|
||||||
</Layers>
|
</Layers>
|
||||||
</Frame>
|
</Frame>
|
||||||
|
|
||||||
<!-- ================= Queue Status Panel ================= -->
|
<!-- ================= Queue Status Panel ================= -->
|
||||||
<Frame name="RelationshipsPVPQueuePanel">
|
<Frame name="RelationshipsPVPQueuePanel">
|
||||||
<Size><AbsDimension x="692" y="84"/></Size>
|
<Size><AbsDimension x="868" y="84"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT">
|
<Anchor point="TOPLEFT">
|
||||||
<Offset><AbsDimension x="24" y="-368"/></Offset>
|
<Offset><AbsDimension x="24" y="-368"/></Offset>
|
||||||
@@ -164,7 +186,7 @@
|
|||||||
<Layers>
|
<Layers>
|
||||||
<Layer level="ARTWORK">
|
<Layer level="ARTWORK">
|
||||||
<FontString name="RelationshipsPVPQueueText" inherits="GameFontHighlightSmall" justifyH="LEFT" justifyV="TOP">
|
<FontString name="RelationshipsPVPQueueText" inherits="GameFontHighlightSmall" justifyH="LEFT" justifyV="TOP">
|
||||||
<Size><AbsDimension x="664" y="70"/></Size>
|
<Size><AbsDimension x="846" y="70"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT"><Offset><AbsDimension x="14" y="-10"/></Offset></Anchor>
|
<Anchor point="TOPLEFT"><Offset><AbsDimension x="14" y="-10"/></Offset></Anchor>
|
||||||
</Anchors>
|
</Anchors>
|
||||||
@@ -173,15 +195,9 @@
|
|||||||
</Layers>
|
</Layers>
|
||||||
</Frame>
|
</Frame>
|
||||||
|
|
||||||
<!-- ================= Action Panel =================
|
<!-- ================= Action Panel ================= -->
|
||||||
Layout math (panel width 692, side padding 24 → usable 644):
|
|
||||||
Row 1 (3 BGs) : 3 × 200w + 2 × 22gap = 644
|
|
||||||
Row 2 (4 arena) : 4 × 149w + 3 × 16gap = 596 + 48 = 644
|
|
||||||
Row 4 (4 utility) : 4 × 149w + 3 × 16gap = 644
|
|
||||||
All rows share x=24 left edge and end at x=668 right edge.
|
|
||||||
-->
|
|
||||||
<Frame name="RelationshipsPVPActionPanel">
|
<Frame name="RelationshipsPVPActionPanel">
|
||||||
<Size><AbsDimension x="692" y="230"/></Size>
|
<Size><AbsDimension x="868" y="230"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT">
|
<Anchor point="TOPLEFT">
|
||||||
<Offset><AbsDimension x="24" y="-472"/></Offset>
|
<Offset><AbsDimension x="24" y="-472"/></Offset>
|
||||||
@@ -199,7 +215,7 @@
|
|||||||
<Size><AbsDimension x="200" y="32"/></Size>
|
<Size><AbsDimension x="200" y="32"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT">
|
<Anchor point="TOPLEFT">
|
||||||
<Offset><AbsDimension x="24" y="-18"/></Offset>
|
<Offset><AbsDimension x="112" y="-18"/></Offset>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Anchors>
|
</Anchors>
|
||||||
<Scripts><OnClick>RelationshipsPVP_Queue("AV")</OnClick></Scripts>
|
<Scripts><OnClick>RelationshipsPVP_Queue("AV")</OnClick></Scripts>
|
||||||
@@ -265,8 +281,8 @@
|
|||||||
<CheckButton name="RelationshipsPVPGroupCheck" inherits="UICheckButtonTemplate">
|
<CheckButton name="RelationshipsPVPGroupCheck" inherits="UICheckButtonTemplate">
|
||||||
<Size><AbsDimension x="32" y="32"/></Size>
|
<Size><AbsDimension x="32" y="32"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="TOPLEFT" relativeTo="RelationshipsPVPQueueA2" relativePoint="BOTTOMLEFT">
|
<Anchor point="TOP" relativeTo="RelationshipsPVPActionPanel" relativePoint="TOP">
|
||||||
<Offset><AbsDimension x="-1" y="-28"/></Offset>
|
<Offset><AbsDimension x="-76" y="-124"/></Offset>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Anchors>
|
</Anchors>
|
||||||
<Scripts>
|
<Scripts>
|
||||||
@@ -280,12 +296,12 @@
|
|||||||
</Scripts>
|
</Scripts>
|
||||||
</CheckButton>
|
</CheckButton>
|
||||||
|
|
||||||
<!-- Row 4: Utility buttons (4 equal-width columns matching arena row) -->
|
<!-- Row 4: Utility buttons -->
|
||||||
<Button name="RelationshipsPVPLeave" inherits="UIPanelButtonTemplate" text="Leave / Cancel Queue">
|
<Button name="RelationshipsPVPLeave" inherits="UIPanelButtonTemplate" text="Leave / Cancel Queue">
|
||||||
<Size><AbsDimension x="149" y="30"/></Size>
|
<Size><AbsDimension x="149" y="30"/></Size>
|
||||||
<Anchors>
|
<Anchors>
|
||||||
<Anchor point="BOTTOMLEFT">
|
<Anchor point="BOTTOMLEFT">
|
||||||
<Offset><AbsDimension x="24" y="20"/></Offset>
|
<Offset><AbsDimension x="112" y="20"/></Offset>
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Anchors>
|
</Anchors>
|
||||||
<Scripts><OnClick>RelationshipsPVP_LeaveAll()</OnClick></Scripts>
|
<Scripts><OnClick>RelationshipsPVP_LeaveAll()</OnClick></Scripts>
|
||||||
|
|||||||
Reference in New Issue
Block a user