/* ============================================================ public/js/gaststaette/glucksspiel.js Glücksspiel-Tab in der Gaststätte – Karten nach Fraktion anzeigen (wie Kartendeck) – Karten gleicher ID ins Kombinier-Feld legen – "Kombinieren"-Button ============================================================ */ const CARDS_PER_PAGE = 18; const RARITY_CRYSTALS = { 1: "roter-cristal.png", 2: "blauer-cristal.png", 3: "gelber-cristal.png", 4: "gruener-cristal.png", 5: "oranger-cristal.png", 6: "violet-cristal.png", 7: "pinker-cristal.png", }; function rarityImgs(rarity, size = 13) { const file = RARITY_CRYSTALS[String(rarity)]; if (!file) return ""; const count = parseInt(rarity) || 0; const img = `Stufe ${rarity}`; return img.repeat(count); } // State let gs_groupId = null; let gs_page = 1; let gs_cards = []; // aktuelle Seite let gs_combineId = null; // card_id der Karte im Kombinier-Feld let gs_combineCards = []; // [{card_id, name, image, rarity, attack, defends, cooldown}] im Feld let gs_initialized = false; /* ══════════════════════════════════════════════ INIT ══════════════════════════════════════════════ */ export async function loadGlucksspiel() { const container = document.getElementById("gs-tab1"); if (!container) return; // Nur beim ersten Aufruf rendern if (gs_initialized) return; gs_initialized = true; container.innerHTML = renderShell(); attachCombineEvents(); try { const res = await fetch("/api/card-groups"); if (!res.ok) throw new Error(); const groups = await res.json(); renderTabs(groups); if (groups.length) { gs_groupId = groups[0].id; await loadCards(); } } catch { container.innerHTML = `

Fehler beim Laden.

`; } } /* ══════════════════════════════════════════════ SHELL ══════════════════════════════════════════════ */ function renderShell() { return `
Meine Karten
Lade Karten...
Kombinieren
Klicke auf eine Karte links um sie hier zu platzieren.
Nur Karten gleicher Art können kombiniert werden.
`; } /* ══════════════════════════════════════════════ FRAKTIONS-TABS ══════════════════════════════════════════════ */ function renderTabs(groups) { const container = document.getElementById("gs-faction-tabs"); if (!container) return; container.innerHTML = groups .map((g, i) => { const color = g.color || "#6b4b2a"; return ` `; }) .join(""); container.querySelectorAll(".gs-tab").forEach((btn) => { btn.addEventListener("click", async () => { const color = btn.style.borderColor; container.querySelectorAll(".gs-tab").forEach((b) => { b.classList.remove("gs-tab-active"); b.style.background = ""; }); btn.classList.add("gs-tab-active"); btn.style.background = `${color}33`; gs_groupId = parseInt(btn.dataset.group); gs_page = 1; await loadCards(); }); }); } /* ══════════════════════════════════════════════ KARTEN LADEN ══════════════════════════════════════════════ */ async function loadCards() { const grid = document.getElementById("gs-grid"); const pagination = document.getElementById("gs-pagination"); if (!grid) return; grid.innerHTML = `
Lade Karten...
`; if (pagination) pagination.innerHTML = ""; try { const res = await fetch( `/api/user-cards?group_id=${gs_groupId}&page=${gs_page}&limit=${CARDS_PER_PAGE}` ); if (!res.ok) throw new Error(); const data = await res.json(); gs_cards = data.cards || []; renderGrid(grid, gs_cards); renderPagination(pagination, data.totalPages, data.total); } catch { grid.innerHTML = `
Keine Karten gefunden.
`; } } /* ══════════════════════════════════════════════ KARTEN-GRID RENDERN ══════════════════════════════════════════════ */ function renderGrid(grid, cards) { if (!cards || !cards.length) { grid.innerHTML = `
Keine Karten in dieser Gruppe.
`; return; } grid.innerHTML = cards.map((c) => { // Karte deaktivieren wenn sie nicht zur aktuellen Kombination passt const disabled = gs_combineId !== null && c.card_id !== gs_combineId; // Anzahl bereits im Kombinier-Feld const inField = gs_combineCards.filter(x => x.card_id === c.card_id).length; const available = c.amount - inField; return `
${c.name} ${c.attack != null ? `${c.attack}` : ""} ${c.defends != null ? `${c.defends}` : ""} ${c.rarity ? `
${rarityImgs(c.rarity, 12)}
` : ""}
`; }).join(""); grid.querySelectorAll(".gs-card:not(.gs-card-disabled)").forEach((el) => { el.addEventListener("click", () => { const card = cards.find((c) => c.card_id === parseInt(el.dataset.cardId)); if (!card) return; const inField = gs_combineCards.filter(x => x.card_id === card.card_id).length; if (inField >= card.amount) { showToast("Keine weiteren Exemplare verfügbar."); return; } addToField(card); }); }); } /* ══════════════════════════════════════════════ KARTE ZUM KOMBINIER-FELD HINZUFÜGEN ══════════════════════════════════════════════ */ function addToField(card) { gs_combineId = card.card_id; gs_combineCards.push({ ...card }); renderCombineField(); renderGrid(document.getElementById("gs-grid"), gs_cards); } /* ══════════════════════════════════════════════ KARTE AUS FELD ENTFERNEN ══════════════════════════════════════════════ */ function removeFromField(index) { gs_combineCards.splice(index, 1); if (gs_combineCards.length === 0) gs_combineId = null; renderCombineField(); renderGrid(document.getElementById("gs-grid"), gs_cards); } /* ══════════════════════════════════════════════ KOMBINIER-FELD RENDERN ══════════════════════════════════════════════ */ function renderCombineField() { const grid = document.getElementById("gs-combine-grid"); const hint = document.getElementById("gs-combine-hint"); const count = document.getElementById("gs-combine-count"); const btn = document.getElementById("gs-combine-btn"); if (!grid) return; if (!gs_combineCards.length) { grid.innerHTML = ""; hint.style.display = "block"; count.textContent = ""; btn.disabled = true; return; } hint.style.display = "none"; // Karten als gestapelter Stapel – jede Karte leicht versetzt const offset = Math.min(6, 40 / gs_combineCards.length); // max 6px versatz const stackHeight = offset * (gs_combineCards.length - 1); // extra höhe für stapel const stackCards = gs_combineCards.map((c, i) => `
${c.name} ${c.cooldown != null ? `${c.cooldown}` : ""}
`).join(""); grid.innerHTML = `
${stackCards}
`; // Klick auf Stapel → oberste Karte entfernen grid.querySelector(".gs-card-stack").addEventListener("click", () => { removeFromField(gs_combineCards.length - 1); }); count.textContent = `${gs_combineCards.length} Karte${gs_combineCards.length !== 1 ? "n" : ""} im Stapel`; btn.disabled = gs_combineCards.length < 2; } /* ══════════════════════════════════════════════ KOMBINIEREN-BUTTON ══════════════════════════════════════════════ */ function attachCombineEvents() { // Wird nach renderShell aufgerufen setTimeout(() => { const btn = document.getElementById("gs-combine-btn"); if (!btn) return; btn.addEventListener("click", async () => { if (gs_combineCards.length < 2) return; btn.disabled = true; btn.textContent = "Kombiniere..."; try { const res = await fetch("/api/cards/combine", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ card_id: gs_combineId, amount: gs_combineCards.length, }), }); const data = await res.json(); if (!res.ok) { showToast(data.error || "Kombinieren fehlgeschlagen."); btn.disabled = false; btn.textContent = "Kombinieren"; return; } showToast("Kombinieren erfolgreich! 🎉"); gs_combineCards = []; gs_combineId = null; gs_initialized = false; // Neu laden erzwingen renderCombineField(); await loadCards(); } catch { showToast("Verbindungsfehler."); btn.disabled = false; btn.textContent = "Kombinieren"; } finally { btn.textContent = "Kombinieren"; } }); }, 50); } /* ══════════════════════════════════════════════ PAGINATION ══════════════════════════════════════════════ */ function renderPagination(pagination, totalPages, total) { if (!pagination || !totalPages || totalPages <= 1) return; pagination.innerHTML = ` ${Array.from({ length: totalPages }, (_, i) => i + 1) .map((p) => ``) .join("")} ${total} Karten`; pagination.querySelector("#gs-prev")?.addEventListener("click", async () => { if (gs_page > 1) { gs_page--; await loadCards(); } }); pagination.querySelector("#gs-next")?.addEventListener("click", async () => { if (gs_page < totalPages) { gs_page++; await loadCards(); } }); pagination.querySelectorAll("[data-page]").forEach((btn) => { btn.addEventListener("click", async () => { gs_page = parseInt(btn.dataset.page); await loadCards(); }); }); } /* ══════════════════════════════════════════════ TOAST ══════════════════════════════════════════════ */ function showToast(msg) { const existing = document.querySelector(".gs-toast"); if (existing) existing.remove(); const t = document.createElement("div"); t.className = "gs-toast"; t.textContent = msg; t.style.cssText = ` position:fixed;bottom:80px;left:50%;transform:translateX(-50%); background:linear-gradient(#4a2808,#2a1004);border:2px solid #8b6a3c; border-radius:8px;color:#f0d9a6;font-family:"Cinzel",serif;font-size:13px; padding:10px 22px;z-index:9999;pointer-events:none;`; document.body.appendChild(t); setTimeout(() => t.remove(), 2800); }