This commit is contained in:
cay 2026-04-09 14:39:54 +01:00
parent e1e275f1f7
commit 79fe5b2a38
2 changed files with 108 additions and 98 deletions

View File

@ -2,28 +2,66 @@ export async function loadArena() {
const ui = document.querySelector(".building-ui");
if (!ui) return;
// Decks sofort laden
let decks = [];
try {
const res = await fetch("/api/decks");
if (res.ok) decks = await res.json();
} catch (e) { console.error("[Arena] Decks:", e); }
const deckOptions = decks.length === 0
? `<option value=""> Erst Deck erstellen </option>`
: `<option value=""> Deck wählen </option>` +
decks.filter(d => d.card_count > 0)
.map(d => `<option value="${d.id}">${d.name} (${d.card_count} Karten)</option>`)
.join("") +
(decks.some(d => d.card_count === 0)
? decks.filter(d => d.card_count === 0)
.map(d => `<option value="" disabled>⚠ ${d.name} (leer)</option>`)
.join("")
: "");
ui.innerHTML = `
<div id="arena-ui">
<!-- Modus-Auswahl -->
<div id="arena-mode-screen">
<div class="arena-title"> Kampfarena</div>
<p class="arena-subtitle">Wähle deinen Kampfmodus</p>
<p class="arena-subtitle">Wähle Deck und Kampfmodus</p>
<div class="arena-modes">
<div class="arena-mode-card" data-mode="1v1">
<div class="arena-mode-icon">🗡</div>
<div class="arena-mode-label">1v1</div>
<div class="arena-mode-desc">Einzelkampf Beweis deine Stärke im Duell</div>
<div class="arena-mode-wrap">
<div class="arena-mode-card arena-mode-locked" data-mode="1v1">
<div class="arena-mode-icon">🗡</div>
<div class="arena-mode-label">1v1</div>
<div class="arena-mode-desc">Einzelkampf Duell</div>
</div>
<select class="arena-deck-select" data-mode="1v1">
${deckOptions}
</select>
</div>
<div class="arena-mode-card" data-mode="2v2">
<div class="arena-mode-icon"></div>
<div class="arena-mode-label">2v2</div>
<div class="arena-mode-desc">Verbünde dich mit einem Kameraden im Kampf</div>
<div class="arena-mode-wrap">
<div class="arena-mode-card arena-mode-locked" data-mode="2v2">
<div class="arena-mode-icon"></div>
<div class="arena-mode-label">2v2</div>
<div class="arena-mode-desc">Team-Kampf</div>
</div>
<select class="arena-deck-select" data-mode="2v2">
${deckOptions}
</select>
</div>
<div class="arena-mode-card" data-mode="4v4">
<div class="arena-mode-icon">🛡</div>
<div class="arena-mode-label">4v4</div>
<div class="arena-mode-desc">Schlachtruf Führe deine Truppe zum Sieg</div>
<div class="arena-mode-wrap">
<div class="arena-mode-card arena-mode-locked" data-mode="4v4">
<div class="arena-mode-icon">🛡</div>
<div class="arena-mode-label">4v4</div>
<div class="arena-mode-desc">Schlachtruf</div>
</div>
<select class="arena-deck-select" data-mode="4v4">
${deckOptions}
</select>
</div>
</div>
<!-- Level-Range Auswahl (nur 1v1) -->
@ -36,6 +74,10 @@ export async function loadArena() {
</label>
</div>
${decks.length === 0
? `<div class="arena-no-deck-hint">⚠️ Kein Deck vorhanden gehe zur <strong>Burg → Kartendeck</strong></div>`
: ""}
<div id="arena-queue-status" style="display:none;"></div>
</div>
@ -104,6 +146,35 @@ function injectArenaStyles() {
#arena-ui { display:flex; flex-direction:column; height:100%; }
/* ── Deck+Mode Layout ── */
.arena-modes { gap:8px; }
.arena-mode-wrap {
flex:1; min-width:80px; max-width:130px;
display:flex; flex-direction:column; gap:6px;
}
.arena-mode-locked {
opacity:.45; cursor:not-allowed !important;
border-color:#3a2810 !important;
}
.arena-mode-locked:hover { transform:none !important; border-color:#3a2810 !important; }
.arena-deck-select {
width:100%; background:#1a0f04; border:1px solid #6b4b2a;
border-radius:6px; color:#f0d9a6; font-family:"Cinzel",serif;
font-size:10px; padding:5px 6px; cursor:pointer;
appearance:none; -webkit-appearance:none;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23a08060'/%3E%3C/svg%3E");
background-repeat:no-repeat; background-position:right 6px center;
padding-right:20px;
}
.arena-deck-select:focus { outline:none; border-color:#c8960c; }
.arena-deck-select option { background:#1a0f04; color:#f0d9a6; }
.arena-no-deck-hint {
margin-top:10px; padding:8px 12px; border-radius:7px;
background:rgba(231,76,60,.1); border:1px solid rgba(231,76,60,.3);
color:#e07060; font-family:"Cinzel",serif; font-size:11px; text-align:center;
}
.arena-no-deck-hint strong { color:#f0c84a; }
#arena-mode-screen { display:flex; flex-direction:column; align-items:center; padding:16px; }
.arena-title { font-family:"Cinzel",serif; font-size:18px; color:#f0d060; letter-spacing:3px; text-align:center; margin-bottom:4px; }
.arena-subtitle { font-family:"Cinzel",serif; font-size:11px; color:#a08060; margin:0 0 14px; }
@ -296,12 +367,32 @@ let selectedDeckId = null; // Gewähltes Deck für das nächste Match
/* ── Modus-Initialisierung ─────────────────────────────────*/
function initArenaModes() {
// Deck-Dropdown: Card freischalten wenn Deck gewählt
document.querySelectorAll(".arena-deck-select").forEach(select => {
select.addEventListener("change", () => {
const mode = select.dataset.mode;
const card = document.querySelector(`.arena-mode-card[data-mode="${mode}"]`);
if (!card) return;
if (select.value) {
card.classList.remove("arena-mode-locked");
selectedDeckId = Number(select.value);
} else {
card.classList.add("arena-mode-locked");
}
});
});
document.querySelectorAll(".arena-mode-card").forEach(card => {
card.addEventListener("click", () => {
if (card.classList.contains("arena-mode-locked")) return;
// Deck aus dem zugehörigen Dropdown lesen
const mode = card.dataset.mode;
if (mode === "1v1") showDeckSelector(() => handle1v1Click(card));
else if (mode === "2v2") showDeckSelector(() => openTeamLobby("2v2"));
else if (mode === "4v4") showDeckSelector(() => openTeamLobby("4v4"));
const select = document.querySelector(`.arena-deck-select[data-mode="${mode}"]`);
selectedDeckId = select ? Number(select.value) : null;
if (!selectedDeckId) return;
if (mode === "1v1") handle1v1Click(card);
else if (mode === "2v2") openTeamLobby("2v2");
else if (mode === "4v4") openTeamLobby("4v4");
});
});
@ -328,88 +419,7 @@ function initArenaModes() {
});
}
/* ── Deck-Auswahl Popup ────────────────────────────────────*/
async function showDeckSelector(onConfirm) {
// Deck-Screen direkt im arena-mode-screen anzeigen (kein Overlay, kein z-index Problem)
const modeScreen = document.getElementById("arena-mode-screen");
if (!modeScreen) return;
// Decks laden
let decks = [];
try {
const res = await fetch("/api/decks");
if (!res.ok) throw new Error("HTTP " + res.status);
decks = await res.json();
} catch (err) {
console.error("[Arena] Deck-Ladefehler:", err);
showArenaError("Decks konnten nicht geladen werden.");
return;
}
// Originalinhalt merken und ersetzen
const originalHTML = modeScreen.innerHTML;
function restore() {
modeScreen.innerHTML = originalHTML;
// Event-Listener auf die wiederhergestellten Karten neu anhängen
modeScreen.querySelectorAll(".arena-mode-card").forEach(card => {
card.addEventListener("click", () => {
const mode = card.dataset.mode;
if (mode === "1v1") showDeckSelector(() => handle1v1Click(card));
else if (mode === "2v2") showDeckSelector(() => openTeamLobby("2v2"));
else if (mode === "4v4") showDeckSelector(() => openTeamLobby("4v4"));
});
});
selectedDeckId = null;
}
if (decks.length === 0) {
modeScreen.innerHTML = `
<div class="arena-title" style="margin-bottom:8px;"> Kein Deck vorhanden</div>
<p class="arena-subtitle" style="text-align:center;line-height:1.7;max-width:280px;">
Du musst zuerst ein Deck erstellen<br>bevor du kämpfen kannst.<br>
Gehe zur <strong style="color:#f0c84a;">Burg Kartendeck</strong>.
</p>
<button class="arena-btn-create" id="deck-back-btn" style="margin-top:12px;"> Zurück</button>`;
document.getElementById("deck-back-btn").addEventListener("click", restore);
return;
}
const deckRows = decks.map(d => `
<div class="deck-select-row ${d.card_count === 0 ? "deck-empty" : ""}" data-id="${d.id}">
<span class="deck-select-name">🃏 ${d.name}</span>
<span class="deck-select-count">${d.card_count} Karten</span>
${d.card_count === 0 ? "<span class='deck-select-warn'>Leer</span>" : ""}
</div>`).join("");
modeScreen.innerHTML = `
<div class="arena-title" style="margin-bottom:4px;"> Deck auswählen</div>
<p class="arena-subtitle">Mit welchem Deck möchtest du kämpfen?</p>
<div class="deck-select-list" style="width:100%;max-height:220px;overflow-y:auto;">${deckRows}</div>
<div class="deck-select-actions" style="width:100%;display:flex;gap:10px;justify-content:flex-end;margin-top:10px;">
<button class="deck-select-cancel" id="deck-cancel-btn"> Zurück</button>
<button class="deck-select-confirm deck-btn-disabled" id="deck-confirm-btn" disabled>Kämpfen </button>
</div>`;
modeScreen.querySelectorAll(".deck-select-row:not(.deck-empty)").forEach(row => {
row.addEventListener("click", () => {
modeScreen.querySelectorAll(".deck-select-row").forEach(r => r.classList.remove("deck-selected"));
row.classList.add("deck-selected");
selectedDeckId = Number(row.dataset.id);
const btn = document.getElementById("deck-confirm-btn");
btn.disabled = false;
btn.classList.remove("deck-btn-disabled");
});
});
document.getElementById("deck-cancel-btn").addEventListener("click", restore);
document.getElementById("deck-confirm-btn").addEventListener("click", () => {
if (!selectedDeckId) return;
restore();
onConfirm();
});
}
/* ── 1v1 ───────────────────────────────────────────────────*/
async function handle1v1Click(card) {

View File

@ -1,4 +1,4 @@
import { loadArena } from "./buildings/arena.js?v=2";
import { loadArena } from "./buildings/arena.js?v=3";
import { loadCharacterHouse } from "./buildings/character-house.js?v=2";
import { loadBlackmarket } from "./buildings/blackmarket.js?v=2";
import { loadMine } from "./buildings/mine.js?v=2";