diff --git a/css/analysis.css b/css/analysis.css index 7ad6076..351296c 100644 --- a/css/analysis.css +++ b/css/analysis.css @@ -20,6 +20,17 @@ .player-card:hover { border-color: var(--borderem); } .player-card.player-hidden { opacity: 0.35; border-style: dashed; } +.player-card--ref { border-color: rgba(100, 160, 255, 0.35); } +.player-card--ref:hover { border-color: rgba(100, 160, 255, 0.7); } + +.ref-player-label { + font-size: 11px; + color: var(--t3); + text-transform: uppercase; + letter-spacing: 0.06em; + margin: 10px 0 6px; +} + .player-job-icon { width: 28px; height: 28px; diff --git a/js/analysis.js b/js/analysis.js index 9a5ba35..5dfe911 100644 --- a/js/analysis.js +++ b/js/analysis.js @@ -85,12 +85,15 @@ let phaseFilter = { startTime: 0, endTime: Infinity }; let refEvents = []; let refFightStart = 0; + let refPlayers = []; + let currentPlayers = []; let extFights = []; let extReportCode = ''; // ── Player grid ────────────────────────────────────────────────────────── function renderPlayers(players) { + currentPlayers = players; const grid = document.getElementById('player-grid'); const order = { healer: 0, dps: 1, tank: 2 }; players.sort((a, b) => { @@ -112,6 +115,53 @@ `).join(''); } + function renderRefPlayers() { + const section = document.getElementById('ref-player-section'); + const grid = document.getElementById('ref-player-grid'); + + if (!refPlayers.length) { section.style.display = 'none'; return; } + + const currentNames = new Set(currentPlayers.map(p => p.name)); + if (!refPlayers.some(p => !currentNames.has(p.name))) { + section.style.display = 'none'; + return; + } + + const order = { healer: 0, dps: 1, tank: 2 }; + const sorted = [...refPlayers].sort((a, b) => { + const roleCmp = (order[a.role] ?? 2) - (order[b.role] ?? 2); + return roleCmp !== 0 ? roleCmp : a.name.localeCompare(b.name); + }); + + sorted.filter(p => p.role === 'tank').forEach(p => hiddenPlayerNames.add(p.name)); + + grid.innerHTML = sorted.map(p => ` +
+
${abbr(p.type)}
+
+
${p.name}
+
${p.type}
+
+
+ `).join(''); + + section.style.display = ''; + } + + document.getElementById('ref-player-grid').addEventListener('click', e => { + const card = e.target.closest('.player-card'); + if (!card) return; + const name = card.dataset.playerName; + if (hiddenPlayerNames.has(name)) { + hiddenPlayerNames.delete(name); + card.classList.remove('player-hidden'); + } else { + hiddenPlayerNames.add(name); + card.classList.add('player-hidden'); + } + renderTimeline(lastEvents, lastFightStart); + }); + document.getElementById('player-grid').addEventListener('click', e => { const card = e.target.closest('.player-card'); if (!card) return; @@ -284,6 +334,8 @@ if (!refId) { refEvents = []; refFightStart = 0; + refPlayers = []; + renderRefPlayers(); renderTimeline(lastEvents, lastFightStart); return; } @@ -310,9 +362,11 @@ if (!json.error && !json.reauth) { refEvents = json.aoe_events ?? []; refFightStart = json.fight_start ?? fight.startTime; + refPlayers = json.players ?? []; } } catch { } refExtFightSelect.disabled = false; + renderRefPlayers(); renderTimeline(lastEvents, lastFightStart); }); @@ -584,8 +638,10 @@ lastFightId = null; refEvents = []; refFightStart = 0; + refPlayers = []; extFights = []; extReportCode = ''; + document.getElementById('ref-player-section').style.display = 'none'; refFightSelect.value = ''; refFightSelect.style.display = 'none'; refExtFightSelect.value = ''; diff --git a/templates/tab-analysis.php b/templates/tab-analysis.php index f4f546b..b0a7d53 100644 --- a/templates/tab-analysis.php +++ b/templates/tab-analysis.php @@ -18,6 +18,10 @@
+