diff --git a/public/js/buildings/1v1.js b/public/js/buildings/1v1.js
index fc849ba..f4b0237 100644
--- a/public/js/buildings/1v1.js
+++ b/public/js/buildings/1v1.js
@@ -5,41 +5,48 @@
═══════════════════════════════════════════════════════════════ */
/* ── Konfiguration aus EJS-Bridge ────────────────────────── */
-const matchId = new URLSearchParams(window.location.search).get('match') || window.GAME_CONFIG.matchId;
-const mySlot = new URLSearchParams(window.location.search).get('slot') || window.GAME_CONFIG.mySlot;
-const amIPlayer1 = mySlot === 'player1';
+const matchId =
+ new URLSearchParams(window.location.search).get("match") ||
+ window.GAME_CONFIG.matchId;
+const mySlot =
+ new URLSearchParams(window.location.search).get("slot") ||
+ window.GAME_CONFIG.mySlot;
+const amIPlayer1 = mySlot === "player1";
/* ── Gegner-Name aus URL setzen ──────────────────────────── */
const _urlParams = new URLSearchParams(window.location.search);
-const opponentNameFromUrl = _urlParams.get('opponent');
+const opponentNameFromUrl = _urlParams.get("opponent");
if (opponentNameFromUrl) {
- const oppEl = document.getElementById(amIPlayer1 ? 'nameRight' : 'nameLeft');
+ const oppEl = document.getElementById(amIPlayer1 ? "nameRight" : "nameLeft");
if (oppEl) oppEl.textContent = decodeURIComponent(opponentNameFromUrl);
}
/* ═══════════════════════════════════════════════════════════
SPIELFELD AUFBAUEN
═══════════════════════════════════════════════════════════ */
-['row1', 'row2'].forEach(rowId => {
+["row1", "row2"].forEach((rowId) => {
const row = document.getElementById(rowId);
for (let i = 1; i <= 11; i++) {
- const s = document.createElement('div');
- s.className = 'card-slot';
- s.dataset.row = rowId;
+ const s = document.createElement("div");
+ s.className = "card-slot";
+ s.dataset.row = rowId;
s.dataset.slotIndex = i;
- s.id = `${rowId}-slot-${i}`;
- s.innerHTML = '\u2736' + i + '';
+ s.id = `${rowId}-slot-${i}`;
+ s.innerHTML =
+ '\u2736' +
+ i +
+ "";
row.appendChild(s);
}
});
-const hand = document.getElementById('handArea');
+const hand = document.getElementById("handArea");
/* ── Deck-Stapel ─────────────────────────────────────────── */
-const deckSlot = document.createElement('div');
-deckSlot.className = 'hand-slot hand-slot-deck';
-deckSlot.id = 'deck-stack';
-deckSlot.title = 'Dein Deck';
+const deckSlot = document.createElement("div");
+deckSlot.className = "hand-slot hand-slot-deck";
+deckSlot.id = "deck-stack";
+deckSlot.title = "Dein Deck";
deckSlot.innerHTML = `

@@ -51,11 +58,19 @@ deckSlot.innerHTML = `
hand.appendChild(deckSlot);
/* ── Hand-Karten-Slots ───────────────────────────────────── */
-const handCardIds = ['hand-card-1','hand-card-2','hand-card-3','hand-card-4','hand-card-5','hand-card-6','hand-card-7'];
-handCardIds.forEach(id => {
- const s = document.createElement('div');
- s.className = 'hand-slot hand-slot-card';
- s.id = id;
+const handCardIds = [
+ "hand-card-1",
+ "hand-card-2",
+ "hand-card-3",
+ "hand-card-4",
+ "hand-card-5",
+ "hand-card-6",
+ "hand-card-7",
+];
+handCardIds.forEach((id) => {
+ const s = document.createElement("div");
+ s.className = "hand-slot hand-slot-card";
+ s.id = id;
s.innerHTML = '
\uD83C\uDCCF';
hand.appendChild(s);
});
@@ -65,24 +80,26 @@ handCardIds.forEach(id => {
═══════════════════════════════════════════════════════════ */
let deckQueue = [];
const handSlotState = {};
-handCardIds.forEach(id => { handSlotState[id] = null; });
+handCardIds.forEach((id) => {
+ handSlotState[id] = null;
+});
/* ── SVG-Icons ───────────────────────────────────────────── */
const SVG_RANGE = `
`;
-const SVG_RACE = `
`;
+const SVG_RACE = `
`;
/* ── Hand-Slot rendern ───────────────────────────────────── */
function renderHandSlot(id) {
- const slot = document.getElementById(id);
+ const slot = document.getElementById(id);
const state = handSlotState[id];
if (!slot) return;
- slot.innerHTML = '';
- slot.style.backgroundImage = 'none';
- slot.style.opacity = '1';
- slot.style.filter = 'none';
- slot.style.backgroundColor = '#0a0805';
- slot.classList.remove('hand-slot-ready', 'hand-slot--filled');
+ slot.innerHTML = "";
+ slot.style.backgroundImage = "none";
+ slot.style.opacity = "1";
+ slot.style.filter = "none";
+ slot.style.backgroundColor = "#0a0805";
+ slot.classList.remove("hand-slot-ready", "hand-slot--filled");
if (!state) {
slot.innerHTML = '
\uD83C\uDCCF';
@@ -94,20 +111,23 @@ function renderHandSlot(id) {
const { card, currentCd } = state;
const isReady = currentCd <= 0;
- const atkVal = card.attack ?? null;
+ const atkVal = card.attack ?? null;
const defVal = card.defends ?? null;
- const rngVal = card.range ?? null;
- const rceVal = card.race ?? null;
+ const rngVal = card.range ?? null;
+ const rceVal = card.race ?? null;
const statsHtml = `
- ${atkVal != null ? `${atkVal}` : ''}
- ${defVal != null ? `${defVal}` : ''}
- ${card.cooldown != null ? `${isReady ? '\u2713' : currentCd}` : ''}
- ${rngVal != null ? `${SVG_RANGE} ${rngVal}` : ''}
- ${rceVal != null ? `${SVG_RACE} ${rceVal}` : ''}
+ ${atkVal != null ? `${atkVal}` : ""}
+ ${defVal != null ? `${defVal}` : ""}
+ ${card.cooldown != null ? `${isReady ? "\u2713" : currentCd}` : ""}
+ ${rngVal != null ? `${SVG_RANGE} ${rngVal}` : ""}
+ ${rceVal != null ? `${SVG_RACE} ${rceVal}` : ""}
`;
- const readyBadge = (isReady && isMyTurn) ? '
SPIELEN
' : '';
+ const readyBadge =
+ isReady && isMyTurn
+ ? '
SPIELEN
'
+ : "";
slot.innerHTML = card.image
? `

${statsHtml}${readyBadge}`
@@ -116,8 +136,8 @@ function renderHandSlot(id) {
${card.name}
${statsHtml}${readyBadge}`;
- slot.classList.toggle('hand-slot-ready', isReady);
- slot.classList.add('hand-slot--filled');
+ slot.classList.toggle("hand-slot-ready", isReady);
+ slot.classList.add("hand-slot--filled");
if (isReady && isMyTurn) {
slot.draggable = true;
@@ -129,27 +149,31 @@ function renderHandSlot(id) {
}
function setHandSlot(id, card) {
- handSlotState[id] = { card, currentCd: card.cooldown ?? 0, wasReduced: false };
+ handSlotState[id] = {
+ card,
+ currentCd: card.cooldown ?? 0,
+ wasReduced: false,
+ };
renderHandSlot(id);
}
function drawNextCard() {
if (deckQueue.length === 0) return;
- const freeSlot = handCardIds.find(id => handSlotState[id] === null);
+ const freeSlot = handCardIds.find((id) => handSlotState[id] === null);
if (!freeSlot) return;
const card = deckQueue.shift();
setHandSlot(freeSlot, card);
- const countEl = document.getElementById('deck-count');
+ const countEl = document.getElementById("deck-count");
if (countEl) countEl.textContent = deckQueue.length;
}
function tickHandCooldowns() {
- handCardIds.forEach(id => {
+ handCardIds.forEach((id) => {
const state = handSlotState[id];
if (!state) return;
const baseCd = Number(state.card.cooldown || 0);
if (state.currentCd <= 0 && !state.wasReduced) {
- state.currentCd = baseCd > 0 ? Math.max(1, Math.floor(baseCd / 2)) : 0;
+ state.currentCd = baseCd > 0 ? Math.max(1, Math.floor(baseCd / 2)) : 0;
state.wasReduced = true;
} else if (state.currentCd > 0) {
state.currentCd--;
@@ -161,43 +185,48 @@ function tickHandCooldowns() {
/* ── Deck laden ──────────────────────────────────────────── */
(async () => {
try {
- const urlP = new URLSearchParams(window.location.search);
- const deckId = urlP.get('deck') || sessionStorage.getItem('selectedDeckId');
+ const urlP = new URLSearchParams(window.location.search);
+ const deckId = urlP.get("deck") || sessionStorage.getItem("selectedDeckId");
if (!deckId) return;
- const res = await fetch('/api/decks/' + deckId + '/cards');
+ const res = await fetch("/api/decks/" + deckId + "/cards");
if (!res.ok) return;
const cards = await res.json();
const expanded = [];
- cards.forEach(c => { for (let i = 0; i < (c.amount ?? 1); i++) expanded.push(c); });
+ cards.forEach((c) => {
+ for (let i = 0; i < (c.amount ?? 1); i++) expanded.push(c);
+ });
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]];
}
- for (let i = 0; i < 3; i++) { if (expanded[i]) setHandSlot(handCardIds[i], expanded[i]); }
+ for (let i = 0; i < 3; i++) {
+ if (expanded[i]) setHandSlot(handCardIds[i], expanded[i]);
+ }
deckQueue = expanded.slice(3);
- const countEl = document.getElementById('deck-count');
+ const countEl = document.getElementById("deck-count");
if (countEl) countEl.textContent = deckQueue.length;
- } catch (e) { console.error('[Battlefield] Deck laden:', e); }
+ } catch (e) {
+ console.error("[Battlefield] Deck laden:", e);
+ }
})();
-
/* ═══════════════════════════════════════════════════════════
ZUG-TIMER
═══════════════════════════════════════════════════════════ */
const TURN_SECONDS = 30;
-const TT_CIRCUM = 2 * Math.PI * 18;
-let turnTimerInt = null;
-let turnSecsLeft = TURN_SECONDS;
-let amILeftPlayer = null;
-let isMyTurn = false;
+const TT_CIRCUM = 2 * Math.PI * 18;
+let turnTimerInt = null;
+let turnSecsLeft = TURN_SECONDS;
+let amILeftPlayer = null;
+let isMyTurn = false;
function startTurnTimer(activeName) {
clearInterval(turnTimerInt);
turnSecsLeft = TURN_SECONDS;
updateTimerUI(turnSecsLeft, activeName);
- const wrap = document.getElementById('turn-timer-wrap');
- if (wrap) wrap.style.display = 'flex';
+ const wrap = document.getElementById("turn-timer-wrap");
+ if (wrap) wrap.style.display = "flex";
turnTimerInt = setInterval(() => {
turnSecsLeft--;
updateTimerUI(turnSecsLeft, activeName);
@@ -210,21 +239,27 @@ function startTurnTimer(activeName) {
function stopTurnTimer() {
clearInterval(turnTimerInt);
- const wrap = document.getElementById('turn-timer-wrap');
- if (wrap) wrap.style.display = 'none';
+ const wrap = document.getElementById("turn-timer-wrap");
+ if (wrap) wrap.style.display = "none";
}
function updateTimerUI(secs, activeName) {
- const num = document.getElementById('turn-timer-num');
- const circle = document.getElementById('tt-circle');
- const wrap = document.getElementById('turn-timer-wrap');
- if (num) num.textContent = secs;
- if (wrap && activeName) wrap.title = activeName + ' ist am Zug';
+ const num = document.getElementById("turn-timer-num");
+ const circle = document.getElementById("tt-circle");
+ const wrap = document.getElementById("turn-timer-wrap");
+ if (num) num.textContent = secs;
+ if (wrap && activeName) wrap.title = activeName + " ist am Zug";
if (circle) {
circle.style.strokeDashoffset = TT_CIRCUM * (1 - secs / TURN_SECONDS);
- circle.style.stroke = secs > 15 ? '#27ae60' : secs > 8 ? '#f39c12' : '#e74c3c';
- if (secs <= 8) { num.style.color = '#e74c3c'; num.style.animation = 'tt-pulse 0.5s ease-in-out infinite'; }
- else { num.style.color = '#fff'; num.style.animation = 'none'; }
+ circle.style.stroke =
+ secs > 15 ? "#27ae60" : secs > 8 ? "#f39c12" : "#e74c3c";
+ if (secs <= 8) {
+ num.style.color = "#e74c3c";
+ num.style.animation = "tt-pulse 0.5s ease-in-out infinite";
+ } else {
+ num.style.color = "#fff";
+ num.style.animation = "none";
+ }
}
}
@@ -233,27 +268,27 @@ function updateTimerUI(secs, activeName) {
═══════════════════════════════════════════════════════════ */
function setTurnState(myTurn, activeName) {
isMyTurn = myTurn;
- const btn = document.getElementById('end-turn-btn');
+ const btn = document.getElementById("end-turn-btn");
if (!btn) return;
- handCardIds.forEach(id => renderHandSlot(id));
+ handCardIds.forEach((id) => renderHandSlot(id));
if (myTurn) {
- btn.disabled = false;
- btn.textContent = 'Zug beenden';
- btn.style.opacity = '1';
- document.getElementById('turn-indicator')?.remove();
- startTurnTimer(activeName || 'Du');
+ btn.disabled = false;
+ btn.textContent = "Zug beenden";
+ btn.style.opacity = "1";
+ document.getElementById("turn-indicator")?.remove();
+ startTurnTimer(activeName || "Du");
} else {
- btn.disabled = true;
- btn.style.opacity = '0.4';
+ btn.disabled = true;
+ btn.style.opacity = "0.4";
showTurnIndicator(activeName);
- startTurnTimer(activeName || 'Gegner');
+ startTurnTimer(activeName || "Gegner");
}
}
function showTurnIndicator(activeName) {
- document.getElementById('turn-indicator')?.remove();
- const ind = document.createElement('div');
- ind.id = 'turn-indicator';
+ document.getElementById("turn-indicator")?.remove();
+ const ind = document.createElement("div");
+ ind.id = "turn-indicator";
ind.style.cssText = `
position:fixed;bottom:calc(var(--s)*200);left:50%;transform:translateX(-50%);
background:linear-gradient(135deg,rgba(20,20,40,0.95),rgba(10,10,25,0.95));
@@ -262,7 +297,9 @@ function showTurnIndicator(activeName) {
font-size:calc(var(--s)*11);letter-spacing:calc(var(--s)*3);
padding:calc(var(--s)*8) calc(var(--s)*20);z-index:100;pointer-events:none;
text-transform:uppercase;box-shadow:0 4px 20px rgba(0,0,0,0.6);`;
- ind.textContent = activeName ? `\u23F3 ${activeName} ist am Zug` : '\u23F3 Gegner ist am Zug';
+ ind.textContent = activeName
+ ? `\u23F3 ${activeName} ist am Zug`
+ : "\u23F3 Gegner ist am Zug";
document.body.appendChild(ind);
}
@@ -273,10 +310,10 @@ function endMyTurn() {
setTurnState(false);
tickHandCooldowns();
drawNextCard();
- socket.emit('end_turn', { matchId, slot: mySlot });
+ socket.emit("end_turn", { matchId, slot: mySlot });
}
-document.getElementById('end-turn-btn')?.addEventListener('click', endMyTurn);
+document.getElementById("end-turn-btn")?.addEventListener("click", endMyTurn);
/* ═══════════════════════════════════════════════════════════
KARTE AUF BOARD RENDERN
@@ -290,8 +327,8 @@ document.getElementById('end-turn-btn')?.addEventListener('click', endMyTurn);
const boardState = {};
/* ── Kampf + HP Animationen ────────────────────────────── */
-(function() {
- const s = document.createElement('style');
+(function () {
+ const s = document.createElement("style");
s.textContent = `
@keyframes dmg-float {
0% { opacity:1; transform:translateX(-50%) translateY(0); }
@@ -308,34 +345,36 @@ const boardState = {};
/* ── Spieler-Farbe auf Slot oder Avatar anwenden ────────────────── */
function applyOwnerStyle(el, owner) {
if (!el || !owner) return;
- const isLeft = owner === (window._leftSlot || 'player1');
+ const isLeft = owner === (window._leftSlot || "player1");
if (isLeft) {
- el.style.borderColor = 'rgba(60, 140, 255, 0.95)';
- el.style.boxShadow = '0 0 14px rgba(60, 140, 255, 0.5), inset 0 0 10px rgba(60,140,255,0.08)';
+ el.style.borderColor = "rgba(60, 140, 255, 0.95)";
+ el.style.boxShadow =
+ "0 0 14px rgba(60, 140, 255, 0.5), inset 0 0 10px rgba(60,140,255,0.08)";
} else {
- el.style.borderColor = 'rgba(220, 60, 60, 0.95)';
- el.style.boxShadow = '0 0 14px rgba(220, 60, 60, 0.5), inset 0 0 10px rgba(220,60,60,0.08)';
+ el.style.borderColor = "rgba(220, 60, 60, 0.95)";
+ el.style.boxShadow =
+ "0 0 14px rgba(220, 60, 60, 0.5), inset 0 0 10px rgba(220,60,60,0.08)";
}
}
function buildStatsHtml(card) {
- const atk = card.attack ?? null;
+ const atk = card.attack ?? null;
const def = card.defends ?? null;
- const cd = card.cooldown ?? null;
- const rng = card.range ?? null;
- const rce = card.race ?? null;
+ const cd = card.cooldown ?? null;
+ const rng = card.range ?? null;
+ const rce = card.race ?? null;
return `Keine Punkte f\u00FCr dieses Match.