diff --git a/public/js/quickmenu/carddeck.js b/public/js/quickmenu/carddeck.js index c405340..71249c5 100644 --- a/public/js/quickmenu/carddeck.js +++ b/public/js/quickmenu/carddeck.js @@ -4,7 +4,7 @@ let currentGroupId = null; let currentPage = 1; let currentDeckId = null; let deckCards = []; // [{card_id, amount}] -let userCardsCache = []; // aktuelle Seite: [{card_id, amount, name, image, rarity, attack, defense}] +let userCardsCache = []; // aktuelle Seite: [{card_id, amount, name, image, rarity, attack, defense, range, race}] let decks = []; // [{id, name}] /* ── Kristall-Mapping ───────────────────────── */ @@ -26,6 +26,28 @@ function rarityImgs(rarity, size = 14) { return img.repeat(count); } +/* ── Stat-Icons ─────────────────────────────── */ +function rangeIcon() { + return ` + + + + + + `; +} + +function raceIcon() { + return ` + + + + + + + `; +} + /* ══════════════════════════════════════════════ INIT ══════════════════════════════════════════════ */ @@ -439,6 +461,40 @@ function renderShell() { } .kd-deck-count-indeck { font-family: "Cinzel", serif; font-size: 13px; color: #000; font-weight: bold; text-shadow: 0 0 3px rgba(255,255,255,0.6); } + /* ── Reichweite & Laufen Badges ────────── */ + .kd-range-race { + position: absolute; + bottom: 20px; + left: 0; right: 0; + display: flex; + justify-content: center; + gap: 4px; + padding: 0 3px; + pointer-events: none; + z-index: 6; + } + .kd-badge-range, .kd-badge-race { + display: flex; + align-items: center; + gap: 2px; + padding: 1px 4px; + border-radius: 20px; + font-family: "Cinzel", serif; + font-size: 9px; + font-weight: bold; + line-height: 1; + } + .kd-badge-range { + background: rgba(30,20,0,0.82); + border: 1px solid #e8b84b; + color: #e8b84b; + } + .kd-badge-race { + background: rgba(0,25,0,0.82); + border: 1px solid #7de87d; + color: #7de87d; + } + /* ── Rarity Kristalle ───────────────────── */ .kd-rarity { position: absolute; @@ -772,6 +828,11 @@ function renderCollectionGrid(grid, cards) { × ${c.amount} ${c.rarity ? `
${rarityImgs(c.rarity, 13)}
` : ""} + ${(c.range != null || c.race != null) ? ` +
+ ${c.range != null ? `${rangeIcon()} ${c.range}` : ""} + ${c.race != null ? `${raceIcon()} ${c.race}` : ""} +
` : ""} `; }) .join(""); @@ -808,6 +869,11 @@ function renderDeckGrid(grid, cards) { 🃏 ${c.amount} ${c.rarity ? `
${rarityImgs(c.rarity, 14)}
` : ""} + ${(c.range != null || c.race != null) ? ` +
+ ${c.range != null ? `${rangeIcon()} ${c.range}` : ""} + ${c.race != null ? `${raceIcon()} ${c.race}` : ""} +
` : ""} `; }) .join(""); diff --git a/views/1v1-battlefield.ejs b/views/1v1-battlefield.ejs index 423f28f..08b0c7f 100644 --- a/views/1v1-battlefield.ejs +++ b/views/1v1-battlefield.ejs @@ -165,6 +165,34 @@ transform: translateY(-4px); transition: transform 0.15s; } + + /* ── Reichweite & Laufen Badges (Hand + Board) ── */ + .cs-range, .cs-race { + position: absolute; + display: flex; + align-items: center; + gap: 2px; + padding: 1px 4px; + border-radius: 20px; + font-family: "Cinzel", serif; + font-size: 8px; + font-weight: bold; + line-height: 1; + z-index: 6; + pointer-events: none; + } + .cs-range { + bottom: 22px; left: 3px; + background: rgba(30,20,0,0.85); + border: 1px solid #e8b84b; + color: #e8b84b; + } + .cs-race { + bottom: 6px; left: 3px; + background: rgba(0,25,0,0.85); + border: 1px solid #7de87d; + color: #7de87d; + } @@ -383,6 +411,10 @@ handSlotState[id] = null; }); + /* ── Stat-Icon SVGs ─────────────────────────────────── */ + const SVG_RANGE = ``; + const SVG_RACE = ``; + /* ── Slot rendern ──────────────────────────────────── */ function renderHandSlot(id) { const slot = document.getElementById(id); @@ -400,6 +432,8 @@ const atkVal = card.attack ?? null; const defVal = card.defends ?? null; + const rngVal = card.range ?? null; + const rceVal = card.race ?? null; const statsHtml = `
@@ -410,6 +444,8 @@ ? `${isReady ? "✓" : currentCd}` : "" } + ${rngVal != null ? `${SVG_RANGE} ${rngVal}` : ""} + ${rceVal != null ? `${SVG_RACE} ${rceVal}` : ""}
`; const readyBadge = isReady @@ -641,20 +677,27 @@ if (!slot || !card) return; const atkVal = card.attack ?? null; const defVal = card.defends ?? null; - const cdVal = card.cooldown ?? null; + const cdVal = card.cooldown ?? null; + const rngVal = card.range ?? null; + const rceVal = card.race ?? null; const hasAtk = atkVal != null; const hasDef = defVal != null; - const hasCd = cdVal != null; + const hasCd = cdVal != null; + const hasRng = rngVal != null; + const hasRce = rceVal != null; const statsHtml = - hasAtk || hasDef || hasCd + hasAtk || hasDef || hasCd || hasRng || hasRce ? `
${hasAtk ? `${atkVal}` : ""} ${hasDef ? `${defVal}` : ""} - ${hasCd ? `${cdVal}` : ""} + ${hasCd ? `${cdVal}` : ""} + ${hasRng ? `${SVG_RANGE} ${rngVal}` : ""} + ${hasRce ? `${SVG_RACE} ${rceVal}` : ""}
` : ""; + // note: SVG_RACE is defined as the walking icon above slot.classList.add("slot-occupied"); slot.innerHTML = card.image