aerghe
This commit is contained in:
parent
5940dfb01a
commit
3fd04e2211
@ -35,6 +35,9 @@ export async function loadArena() {
|
||||
<div class="arena-title" style="margin:0;">⚔️ 2v2 Team-Lobby</div>
|
||||
</div>
|
||||
|
||||
<!-- Fehlermeldung auf dem 2v2-Screen -->
|
||||
<div id="arena-2v2-error" style="display:none;"></div>
|
||||
|
||||
<!-- Team-Panel (erscheint nach Beitritt) -->
|
||||
<div id="arena-team-panel" style="display:none;">
|
||||
<div class="arena-team-box">
|
||||
@ -62,7 +65,7 @@ export async function loadArena() {
|
||||
initArenaModes();
|
||||
}
|
||||
|
||||
/* ── Styles ────────────────────────────────────────────────────────────────── */
|
||||
/* ── Styles ─────────────────────────────────────────────────────────────────── */
|
||||
function injectArenaStyles() {
|
||||
if (document.getElementById("arena-popup-styles")) return;
|
||||
|
||||
@ -105,8 +108,19 @@ function injectArenaStyles() {
|
||||
text-decoration: underline;
|
||||
animation: none;
|
||||
}
|
||||
#arena-queue-status .qs-cancel:hover {
|
||||
#arena-queue-status .qs-cancel:hover { color: #e74c3c; }
|
||||
|
||||
/* ── 2v2 Fehlermeldung ── */
|
||||
#arena-2v2-error {
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
background: rgba(231,76,60,0.12);
|
||||
border: 1px solid rgba(231,76,60,0.4);
|
||||
color: #e74c3c;
|
||||
font-family: "Cinzel", serif;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* ── Backdrop ── */
|
||||
@ -152,21 +166,6 @@ function injectArenaStyles() {
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
#arena-popup-titlebar .ap-dots {
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
}
|
||||
#arena-popup-titlebar .ap-dot {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
transition: filter 0.15s;
|
||||
}
|
||||
#arena-popup-titlebar .ap-dot:hover { filter: brightness(1.3); }
|
||||
#arena-popup-titlebar .ap-dot.close { background: #e74c3c; border: 1px solid rgba(0,0,0,0.25); }
|
||||
#arena-popup-titlebar .ap-dot.min { background: #f1c40f; border: 1px solid rgba(0,0,0,0.25); }
|
||||
#arena-popup-titlebar .ap-dot.expand { background: #2ecc71; border: 1px solid rgba(0,0,0,0.25); }
|
||||
#arena-popup-titlebar .ap-title {
|
||||
font-family: "Cinzel", serif;
|
||||
font-size: 13px;
|
||||
@ -381,13 +380,12 @@ function injectArenaStyles() {
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/* ── Socket-Referenz holen ─────────────────────────────────────────────────── */
|
||||
/* ── Socket-Referenz holen ──────────────────────────────────────────────────── */
|
||||
function getSocket() {
|
||||
// Wird von der Haupt-App als window._socket bereitgestellt
|
||||
return window._socket || null;
|
||||
}
|
||||
|
||||
/* ── Klick-Handler initialisieren ─────────────────────────────────────────── */
|
||||
/* ── Klick-Handler initialisieren ──────────────────────────────────────────── */
|
||||
function initArenaModes() {
|
||||
document.querySelectorAll(".arena-mode-card").forEach((card) => {
|
||||
card.addEventListener("click", () => {
|
||||
@ -406,31 +404,40 @@ function initArenaModes() {
|
||||
/* ══════════════════════════════════════════════════════════
|
||||
2v2 LOBBY
|
||||
══════════════════════════════════════════════════════════ */
|
||||
let my2v2TeamId = null;
|
||||
let myArenaData = null;
|
||||
let my2v2TeamId = null;
|
||||
let myArenaData = null;
|
||||
|
||||
async function open2v2Lobby() {
|
||||
const socket = getSocket();
|
||||
if (!socket) { showArenaError("Keine Verbindung zum Server."); return; }
|
||||
|
||||
// Screen ZUERST wechseln – so sind Fehlermeldungen sichtbar
|
||||
document.getElementById("arena-mode-screen").style.display = "none";
|
||||
document.getElementById("arena-2v2-screen").style.display = "flex";
|
||||
|
||||
if (!socket) {
|
||||
console.error("[2v2] Kein Socket – window._socket:", window._socket);
|
||||
show2v2Error("Keine Verbindung zum Server. Bitte Seite neu laden.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Spielerdaten laden
|
||||
if (!myArenaData) {
|
||||
try {
|
||||
console.log("[2v2] Lade Spielerdaten…");
|
||||
const res = await fetch("/arena/me");
|
||||
if (!res.ok) throw new Error(res.status);
|
||||
if (!res.ok) throw new Error("HTTP " + res.status);
|
||||
myArenaData = await res.json();
|
||||
} catch {
|
||||
showArenaError("Spielerdaten konnten nicht geladen werden.");
|
||||
console.log("[2v2] Spielerdaten:", myArenaData);
|
||||
} catch (err) {
|
||||
console.error("[2v2] Spielerdaten Fehler:", err);
|
||||
show2v2Error("Spielerdaten konnten nicht geladen werden. (Eingeloggt?)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Screen wechseln
|
||||
document.getElementById("arena-mode-screen").style.display = "none";
|
||||
document.getElementById("arena-2v2-screen").style.display = "flex";
|
||||
|
||||
// Lobbyliste anfordern
|
||||
socket.emit("get_2v2_lobbies");
|
||||
console.log("[2v2] get_2v2_lobbies gesendet");
|
||||
|
||||
// Zurück-Button
|
||||
document.getElementById("arena-2v2-back").onclick = () => {
|
||||
@ -442,6 +449,7 @@ async function open2v2Lobby() {
|
||||
|
||||
// Team erstellen
|
||||
document.getElementById("arena-create-team-btn").onclick = () => {
|
||||
console.log("[2v2] Team erstellen geklickt – sende create_2v2_team mit:", myArenaData);
|
||||
socket.emit("create_2v2_team", myArenaData);
|
||||
};
|
||||
|
||||
@ -454,12 +462,17 @@ async function open2v2Lobby() {
|
||||
socket.off("match_found_2v2");
|
||||
socket.off("2v2_error");
|
||||
|
||||
socket.on("2v2_lobbies", (list) => render2v2LobbyList(list, socket));
|
||||
socket.on("2v2_lobbies", (list) => {
|
||||
console.log("[2v2] Lobbies empfangen:", list);
|
||||
render2v2LobbyList(list, socket);
|
||||
});
|
||||
|
||||
socket.on("2v2_team_joined", (data) => {
|
||||
console.log("[2v2] Team joined:", data);
|
||||
my2v2TeamId = data.teamId;
|
||||
document.getElementById("arena-team-panel").style.display = "block";
|
||||
document.getElementById("arena-lobby-section").style.display = "none";
|
||||
hide2v2Error();
|
||||
});
|
||||
|
||||
socket.on("2v2_team_update", (data) => render2v2TeamPanel(data, socket));
|
||||
@ -467,7 +480,6 @@ async function open2v2Lobby() {
|
||||
socket.on("2v2_partner_left", (data) => {
|
||||
const status = document.getElementById("arena-team-status");
|
||||
if (status) status.innerHTML = `<span style="color:#e74c3c;">⚠️ ${data.name} hat das Team verlassen.</span>`;
|
||||
// Bereit-Button zurücksetzen
|
||||
render2v2TeamPanel({ teamId: my2v2TeamId, players: [{ name: myArenaData.name, level: myArenaData.level, ready: false }], count: 1 }, socket);
|
||||
});
|
||||
|
||||
@ -496,8 +508,8 @@ async function open2v2Lobby() {
|
||||
});
|
||||
|
||||
socket.on("2v2_error", (data) => {
|
||||
const status = document.getElementById("arena-team-status");
|
||||
if (status) { status.innerHTML = `<span style="color:#e74c3c;">❌ ${data.message}</span>`; }
|
||||
console.warn("[2v2] Fehler vom Server:", data.message);
|
||||
show2v2Error(data.message);
|
||||
});
|
||||
}
|
||||
|
||||
@ -527,9 +539,9 @@ function render2v2LobbyList(list, socket) {
|
||||
}
|
||||
|
||||
function render2v2TeamPanel(data, socket) {
|
||||
const playersEl = document.getElementById("arena-team-players");
|
||||
const actionsEl = document.getElementById("arena-team-actions");
|
||||
const statusEl = document.getElementById("arena-team-status");
|
||||
const playersEl = document.getElementById("arena-team-players");
|
||||
const actionsEl = document.getElementById("arena-team-actions");
|
||||
const statusEl = document.getElementById("arena-team-status");
|
||||
if (!playersEl || !actionsEl) return;
|
||||
|
||||
playersEl.innerHTML = data.players.map(p => `
|
||||
@ -544,7 +556,7 @@ function render2v2TeamPanel(data, socket) {
|
||||
actionsEl.innerHTML = `<div class="arena-waiting-partner">Warte auf Partner…</div>`;
|
||||
if (statusEl) statusEl.innerHTML = "";
|
||||
} else {
|
||||
const myEntry = data.players.find(p => p.name === myArenaData?.name);
|
||||
const myEntry = data.players.find(p => p.name === myArenaData?.name);
|
||||
const iAmReady = myEntry?.ready;
|
||||
actionsEl.innerHTML = iAmReady
|
||||
? `<button class="arena-btn-ready active" disabled>✅ Du bist bereit</button>`
|
||||
@ -572,7 +584,21 @@ function leave2v2Team(socket) {
|
||||
socket.off("2v2_error");
|
||||
}
|
||||
|
||||
/* ── 1v1: Hauptlogik ───────────────────────────────────────────────────────── */
|
||||
/* ── 2v2 Fehlermeldung ──────────────────────────────────────────────────────── */
|
||||
function show2v2Error(msg) {
|
||||
const el = document.getElementById("arena-2v2-error");
|
||||
if (!el) return;
|
||||
el.textContent = "❌ " + msg;
|
||||
el.style.display = "block";
|
||||
setTimeout(() => { el.style.display = "none"; }, 4000);
|
||||
}
|
||||
|
||||
function hide2v2Error() {
|
||||
const el = document.getElementById("arena-2v2-error");
|
||||
if (el) el.style.display = "none";
|
||||
}
|
||||
|
||||
/* ── 1v1: Hauptlogik ────────────────────────────────────────────────────────── */
|
||||
async function handle1v1Click(card) {
|
||||
const socket = getSocket();
|
||||
if (!socket) {
|
||||
@ -580,30 +606,25 @@ async function handle1v1Click(card) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bereits in Suche?
|
||||
if (card.classList.contains("searching")) return;
|
||||
|
||||
// Spielerdaten laden
|
||||
let me;
|
||||
try {
|
||||
const res = await fetch("/arena/me");
|
||||
if (!res.ok) throw new Error("Status " + res.status);
|
||||
me = await res.json();
|
||||
} catch (err) {
|
||||
console.error("[1v1] Spielerdaten konnten nicht geladen werden:", err);
|
||||
console.error("[1v1] Spielerdaten Fehler:", err);
|
||||
showArenaError("Spielerdaten konnten nicht geladen werden. (Eingeloggt?)");
|
||||
return;
|
||||
}
|
||||
|
||||
// UI: Suche läuft
|
||||
setCardSearching(card, true);
|
||||
showQueueStatus(me.level);
|
||||
|
||||
// Sicherstellen, dass keine alten Listener hängen
|
||||
socket.off("match_found");
|
||||
socket.off("queue_status");
|
||||
|
||||
// Queue-Status empfangen
|
||||
socket.on("queue_status", (data) => {
|
||||
if (data.status === "waiting") {
|
||||
showQueueStatus(me.level, data.poolSize);
|
||||
@ -613,7 +634,6 @@ async function handle1v1Click(card) {
|
||||
}
|
||||
});
|
||||
|
||||
// Match gefunden
|
||||
socket.once("match_found", (data) => {
|
||||
socket.off("queue_status");
|
||||
setCardSearching(card, false);
|
||||
@ -628,15 +648,14 @@ async function handle1v1Click(card) {
|
||||
});
|
||||
});
|
||||
|
||||
// Matchmaking starten
|
||||
socket.emit("join_1v1", {
|
||||
id: me.id,
|
||||
name: me.name,
|
||||
id: me.id,
|
||||
name: me.name,
|
||||
level: me.level,
|
||||
});
|
||||
}
|
||||
|
||||
/* ── Queue abbrechen ───────────────────────────────────────────────────────── */
|
||||
/* ── Queue abbrechen ────────────────────────────────────────────────────────── */
|
||||
function cancelQueue(card) {
|
||||
const socket = getSocket();
|
||||
if (socket) {
|
||||
@ -648,9 +667,8 @@ function cancelQueue(card) {
|
||||
hideQueueStatus();
|
||||
}
|
||||
|
||||
/* ── Match-Found Splash ────────────────────────────────────────────────────── */
|
||||
/* ── Match-Found Splash ─────────────────────────────────────────────────────── */
|
||||
function showMatchFoundOverlay(myName, opponentName, onDone) {
|
||||
// Verhindert doppeltes Öffnen
|
||||
if (document.getElementById("match-found-overlay")) return;
|
||||
|
||||
const overlay = document.createElement("div");
|
||||
@ -662,22 +680,19 @@ function showMatchFoundOverlay(myName, opponentName, onDone) {
|
||||
`;
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
// Ladebalken animieren
|
||||
requestAnimationFrame(() => {
|
||||
const bar = document.getElementById("mfBar");
|
||||
if (bar) bar.style.width = "100%";
|
||||
});
|
||||
|
||||
// Nach 1.6s zum Spielfeld
|
||||
setTimeout(() => {
|
||||
overlay.remove();
|
||||
onDone();
|
||||
}, 1600);
|
||||
}
|
||||
|
||||
/* ── Popup öffnen ──────────────────────────────────────────────────────────── */
|
||||
/* ── Popup öffnen ───────────────────────────────────────────────────────────── */
|
||||
function openArenaPopup(src, opponentName, matchId) {
|
||||
// Vorhandenen Popup schließen (falls mehrfach)
|
||||
document.getElementById("arena-backdrop")?.remove();
|
||||
document.getElementById("arena-popup")?.remove();
|
||||
|
||||
@ -688,8 +703,8 @@ function openArenaPopup(src, opponentName, matchId) {
|
||||
popup.id = "arena-popup";
|
||||
|
||||
const title = opponentName
|
||||
? `⚔️ 1v1 · vs ${opponentName}`
|
||||
: "⚔️ Arena · 1v1";
|
||||
? `⚔️ Arena · vs ${opponentName}`
|
||||
: "⚔️ Arena";
|
||||
|
||||
popup.innerHTML = `
|
||||
<div id="arena-popup-titlebar">
|
||||
@ -703,23 +718,21 @@ function openArenaPopup(src, opponentName, matchId) {
|
||||
|
||||
document.body.appendChild(backdrop);
|
||||
document.body.appendChild(popup);
|
||||
|
||||
// Backdrop-Klick deaktiviert – Fenster nur über Aufgeben/Spielende schließbar
|
||||
}
|
||||
|
||||
/* ── UI Hilfsfunktionen ────────────────────────────────────────────────────── */
|
||||
/* ── UI Hilfsfunktionen ─────────────────────────────────────────────────────── */
|
||||
function setCardSearching(card, searching) {
|
||||
const label = card.querySelector(".arena-mode-label");
|
||||
const desc = card.querySelector(".arena-mode-desc");
|
||||
const desc = card.querySelector(".arena-mode-desc");
|
||||
|
||||
if (searching) {
|
||||
card.classList.add("searching");
|
||||
label.textContent = "⏳ Suche…";
|
||||
desc.textContent = "Warte auf passenden Gegner…";
|
||||
desc.textContent = "Warte auf passenden Gegner…";
|
||||
} else {
|
||||
card.classList.remove("searching");
|
||||
label.textContent = "1v1";
|
||||
desc.textContent = "Einzelkampf – Beweis deine Stärke im Duell";
|
||||
desc.textContent = "Einzelkampf – Beweis deine Stärke im Duell";
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,9 +740,8 @@ function showQueueStatus(myLevel, poolSize) {
|
||||
const box = document.getElementById("arena-queue-status");
|
||||
if (!box) return;
|
||||
|
||||
const range = 5;
|
||||
const min = Math.max(1, myLevel - range);
|
||||
const max = myLevel + range;
|
||||
const min = Math.max(1, myLevel - 5);
|
||||
const max = myLevel + 5;
|
||||
const pool = poolSize ? ` · ${poolSize} Spieler im Pool` : "";
|
||||
|
||||
box.style.display = "block";
|
||||
@ -739,7 +751,6 @@ function showQueueStatus(myLevel, poolSize) {
|
||||
<span class="qs-cancel" id="qs-cancel-btn">Suche abbrechen</span>
|
||||
`;
|
||||
|
||||
// Cancel-Button – Card-Referenz über data-attribute
|
||||
document.getElementById("qs-cancel-btn")?.addEventListener("click", () => {
|
||||
const card = document.querySelector(".arena-mode-card[data-mode='1v1']");
|
||||
if (card) cancelQueue(card);
|
||||
@ -754,15 +765,15 @@ function hideQueueStatus() {
|
||||
function showArenaError(msg) {
|
||||
const box = document.getElementById("arena-queue-status");
|
||||
if (!box) return;
|
||||
box.style.display = "block";
|
||||
box.style.animation = "none";
|
||||
box.style.display = "block";
|
||||
box.style.animation = "none";
|
||||
box.style.borderColor = "rgba(231,76,60,0.5)";
|
||||
box.style.color = "#e74c3c";
|
||||
box.textContent = "❌ " + msg;
|
||||
box.style.color = "#e74c3c";
|
||||
box.textContent = "❌ " + msg;
|
||||
setTimeout(() => {
|
||||
box.style.display = "none";
|
||||
box.style.animation = "";
|
||||
box.style.display = "none";
|
||||
box.style.animation = "";
|
||||
box.style.borderColor = "";
|
||||
box.style.color = "";
|
||||
box.style.color = "";
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user