tdjdey
This commit is contained in:
parent
3f1467adff
commit
a516399e84
@ -659,6 +659,44 @@ body {
|
||||
border-color: rgba(255, 215, 80, 0.6);
|
||||
}
|
||||
|
||||
/* Hand-Slot: Karte ist spielbereit (CD = 0) */
|
||||
.hand-slot.hand-slot-ready {
|
||||
border-color: rgba(80, 220, 80, 0.9) !important;
|
||||
border-style: solid !important;
|
||||
box-shadow:
|
||||
0 0 calc(var(--s) * 18) rgba(60, 200, 60, 0.5),
|
||||
0 calc(var(--s) * 4) calc(var(--s) * 12) rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
/* CD-Badge wenn Karte spielbereit */
|
||||
.cs-cd.cs-cd-ready {
|
||||
background: rgba(20, 140, 20, 0.9);
|
||||
border-color: #60ff60;
|
||||
color: #b0ffb0;
|
||||
font-size: calc(var(--s) * 7);
|
||||
}
|
||||
|
||||
/* "SPIELEN" Badge oben-mittig wenn CD = 0 */
|
||||
.hand-slot-ready-badge {
|
||||
position: absolute;
|
||||
top: calc(var(--s) * 4);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: linear-gradient(135deg, rgba(20,120,20,0.92), rgba(10,80,10,0.92));
|
||||
border: 1px solid #60d060;
|
||||
border-radius: calc(var(--s) * 4);
|
||||
color: #a0ffa0;
|
||||
font-family: "Cinzel", serif;
|
||||
font-size: calc(var(--s) * 7);
|
||||
font-weight: bold;
|
||||
letter-spacing: calc(var(--s) * 1);
|
||||
padding: calc(var(--s) * 2) calc(var(--s) * 5);
|
||||
pointer-events: none;
|
||||
z-index: 6;
|
||||
white-space: nowrap;
|
||||
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
/* Spielfeld-Sperre */
|
||||
#board-lock-overlay {
|
||||
position: absolute;
|
||||
|
||||
@ -224,14 +224,13 @@
|
||||
<span class="deck-count" id="deck-count">—</span>`;
|
||||
hand.appendChild(deckSlot);
|
||||
|
||||
// ── Slots 2–4: aufgedeckte Handkarten ────────────────
|
||||
// ── Slots 2–4: aufgedeckte Handkarten (leer bis API lädt) ───
|
||||
const handCardIds = ["hand-card-1", "hand-card-2", "hand-card-3"];
|
||||
handCardIds.forEach(id => {
|
||||
const s = document.createElement("div");
|
||||
s.className = "hand-slot hand-slot-card";
|
||||
s.id = id;
|
||||
s.innerHTML = `<img src="/images/cards/Silberklinge.png"
|
||||
style="width:100%;height:100%;object-fit:cover;border-radius:7px;">`;
|
||||
s.innerHTML = '<span class="hs-icon">🃏</span>';
|
||||
hand.appendChild(s);
|
||||
});
|
||||
|
||||
@ -243,73 +242,133 @@
|
||||
hand.appendChild(s);
|
||||
}
|
||||
|
||||
// ── Deck via API laden und Karten anzeigen ────────────
|
||||
// ══════════════════════════════════════════════════════
|
||||
// HAND & DECK SYSTEM
|
||||
// ══════════════════════════════════════════════════════
|
||||
|
||||
let deckQueue = [];
|
||||
|
||||
// State pro Slot: { card, currentCd } oder null = leer
|
||||
const handSlotState = {};
|
||||
handCardIds.forEach(id => { handSlotState[id] = null; });
|
||||
|
||||
/* ── Slot rendern ──────────────────────────────────── */
|
||||
function renderHandSlot(id) {
|
||||
const slot = document.getElementById(id);
|
||||
const state = handSlotState[id];
|
||||
if (!slot) return;
|
||||
|
||||
if (!state) {
|
||||
slot.innerHTML = '<span class="hs-icon">🃏</span>';
|
||||
slot.classList.remove("hand-slot-ready");
|
||||
return;
|
||||
}
|
||||
|
||||
const { card, currentCd } = state;
|
||||
const isReady = currentCd <= 0;
|
||||
|
||||
const atkVal = card.attack ?? null;
|
||||
const defVal = card.defends ?? null;
|
||||
|
||||
const statsHtml = `
|
||||
<div class="card-stat-overlay">
|
||||
${atkVal != null ? `<span class="cs-atk">${atkVal}</span>` : ""}
|
||||
${defVal != null ? `<span class="cs-def">${defVal}</span>` : ""}
|
||||
${card.cooldown != null
|
||||
? `<span class="cs-cd ${isReady ? "cs-cd-ready" : ""}">${isReady ? "✓" : currentCd}</span>`
|
||||
: ""}
|
||||
</div>`;
|
||||
|
||||
const readyBadge = isReady
|
||||
? `<div class="hand-slot-ready-badge">SPIELEN</div>`
|
||||
: "";
|
||||
|
||||
slot.innerHTML = card.image
|
||||
? `<img src="/images/cards/${card.image}"
|
||||
onerror="this.src='/images/items/rueckseite.png'"
|
||||
title="${card.name}"
|
||||
style="width:100%;height:100%;object-fit:cover;border-radius:7px;display:block;">
|
||||
${statsHtml}${readyBadge}`
|
||||
: `<div style="display:flex;flex-direction:column;align-items:center;
|
||||
justify-content:center;height:100%;gap:4px;font-family:Cinzel,serif;">
|
||||
<span style="font-size:18px;">⚔️</span>
|
||||
<span style="font-size:9px;color:#f0d9a6;text-align:center;">${card.name}</span>
|
||||
</div>${statsHtml}${readyBadge}`;
|
||||
|
||||
slot.classList.toggle("hand-slot-ready", isReady);
|
||||
}
|
||||
|
||||
/* ── Karte in Hand-Slot legen ──────────────────────── */
|
||||
function setHandSlot(id, card) {
|
||||
handSlotState[id] = { card, currentCd: card.cooldown ?? 0 };
|
||||
renderHandSlot(id);
|
||||
}
|
||||
|
||||
/* ── Karte vom Deck ziehen ─────────────────────────── */
|
||||
function drawNextCard() {
|
||||
if (deckQueue.length === 0) return;
|
||||
const freeSlot = handCardIds.find(id => handSlotState[id] === null);
|
||||
if (!freeSlot) return; // alle Slots belegt → Karte bleibt im Deck
|
||||
const card = deckQueue.shift();
|
||||
setHandSlot(freeSlot, card);
|
||||
const countEl = document.getElementById("deck-count");
|
||||
if (countEl) countEl.textContent = deckQueue.length;
|
||||
}
|
||||
|
||||
/* ── Cooldowns beim Zug-Ende reduzieren ────────────── */
|
||||
function tickHandCooldowns() {
|
||||
handCardIds.forEach(id => {
|
||||
const state = handSlotState[id];
|
||||
if (!state) return;
|
||||
if (state.currentCd > 0) state.currentCd--;
|
||||
renderHandSlot(id);
|
||||
});
|
||||
}
|
||||
|
||||
/* ── Deck laden ────────────────────────────────────── */
|
||||
(async () => {
|
||||
try {
|
||||
// Deck-ID aus URL-Parameter (von arena.js mitgegeben)
|
||||
const urlP = new URLSearchParams(window.location.search);
|
||||
const deckId = urlP.get("deck") || sessionStorage.getItem("selectedDeckId");
|
||||
if (!deckId) return;
|
||||
|
||||
const [deckRes, cardsRes] = await Promise.all([
|
||||
fetch("/api/decks"),
|
||||
fetch("/api/decks/" + deckId + "/cards")
|
||||
]);
|
||||
if (!deckRes.ok || !cardsRes.ok) return;
|
||||
const cardsRes = await fetch("/api/decks/" + deckId + "/cards");
|
||||
if (!cardsRes.ok) return;
|
||||
const cards = await cardsRes.json();
|
||||
|
||||
const decks = await deckRes.json();
|
||||
const deck = decks.find(d => d.id == deckId);
|
||||
if (deck) {
|
||||
const countEl = document.getElementById("deck-count");
|
||||
if (countEl) countEl.textContent = deck.card_count;
|
||||
// Karten nach amount auffalten
|
||||
const expanded = [];
|
||||
cards.forEach(card => {
|
||||
for (let i = 0; i < (card.amount ?? 1); i++) expanded.push(card);
|
||||
});
|
||||
|
||||
// Mischen (Fisher-Yates)
|
||||
for (let i = expanded.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[expanded[i], expanded[j]] = [expanded[j], expanded[i]];
|
||||
}
|
||||
|
||||
const cards = await cardsRes.json();
|
||||
// DEBUG: alle Karten-Felder anzeigen
|
||||
console.log("[Battlefield] Karten aus API:", cards.slice(0,3).map(c => ({
|
||||
name: c.name, attack: c.attack, defends: c.defends, cooldown: c.cooldown
|
||||
})));
|
||||
// Erste 3 Karten aufgedeckt anzeigen
|
||||
// Erste 3 in die Hand
|
||||
handCardIds.forEach((id, i) => {
|
||||
const card = cards[i];
|
||||
const slot = document.getElementById(id);
|
||||
if (!slot || !card) return;
|
||||
|
||||
// Feldnamen aus der API (attack, defends, cooldown)
|
||||
const atkVal = card.attack ?? null;
|
||||
const defVal = card.defends ?? null;
|
||||
const cdVal = card.cooldown ?? null;
|
||||
|
||||
const hasAtk = atkVal != null;
|
||||
const hasDef = defVal != null;
|
||||
const hasCd = cdVal != null;
|
||||
const showStats = hasAtk || hasDef || hasCd;
|
||||
|
||||
const statsHtml = showStats ? `
|
||||
<div class="card-stat-overlay">
|
||||
${hasAtk ? `<span class="cs-atk">${atkVal}</span>` : ""}
|
||||
${hasDef ? `<span class="cs-def">${defVal}</span>` : ""}
|
||||
${hasCd ? `<span class="cs-cd">${cdVal}</span>` : ""}
|
||||
</div>` : "";
|
||||
|
||||
slot.innerHTML = card.image
|
||||
? `<img src="/images/cards/${card.image}"
|
||||
onerror="this.src='/images/items/rueckseite.png'"
|
||||
title="${card.name}"
|
||||
style="width:100%;height:100%;object-fit:cover;border-radius:7px;display:block;">
|
||||
${statsHtml}`
|
||||
: `<div style="display:flex;flex-direction:column;align-items:center;
|
||||
justify-content:center;height:100%;gap:4px;font-family:Cinzel,serif;">
|
||||
<span style="font-size:18px;">⚔️</span>
|
||||
<span style="font-size:9px;color:#f0d9a6;text-align:center;">${card.name}</span>
|
||||
</div>
|
||||
${statsHtml}`;
|
||||
if (expanded[i]) setHandSlot(id, expanded[i]);
|
||||
});
|
||||
|
||||
// Rest als Deck-Queue
|
||||
deckQueue = expanded.slice(3);
|
||||
const countEl = document.getElementById("deck-count");
|
||||
if (countEl) countEl.textContent = deckQueue.length;
|
||||
|
||||
} catch(e) {
|
||||
console.error("[Battlefield] Deck laden:", e);
|
||||
}
|
||||
})();
|
||||
|
||||
/* ── Zug beenden: CD ticken + Karte ziehen ─────────── */
|
||||
document.getElementById("end-turn-btn")?.addEventListener("click", () => {
|
||||
tickHandCooldowns();
|
||||
drawNextCard();
|
||||
});
|
||||
|
||||
/* ── Hilfsfunktion: Karte mit Stats in einen Slot rendern ── */
|
||||
function renderCardInSlot(slot, card) {
|
||||
if (!slot || !card) return;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user