This commit is contained in:
cay 2026-04-07 07:58:40 +01:00
parent 498f5815d7
commit fd1b5aa507
3 changed files with 112 additions and 78 deletions

BIN
public/images/items/1v1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 MiB

BIN
public/images/items/2v2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

View File

@ -20,19 +20,22 @@ function rarityImgs(rarity, size = 13) {
} }
function cardHTML(card, isFront = true) { function cardHTML(card, isFront = true) {
if (!isFront) return `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`; if (!isFront)
return `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`;
// image zuerst, dann icon als Fallback // image zuerst, dann icon als Fallback
const imgFile = card?.image || card?.icon || null; const imgFile = card?.image || card?.icon || null;
const img = imgFile ? `/images/cards/${imgFile}` : "/images/items/rueckseite.png"; const img = imgFile
? `/images/cards/${imgFile}`
: "/images/items/rueckseite.png";
return ` return `
<img class="booster-slot-img" src="${img}" alt="${card?.name || ''}" draggable="false" <img class="booster-slot-img" src="${img}" alt="${card?.name || ""}" draggable="false"
onerror="this.src='/images/items/rueckseite.png'"> onerror="this.src='/images/items/rueckseite.png'">
${card?.attack != null ? `<span class="bs-stat-atk">${card.attack}</span>` : ""} ${card?.attack != null ? `<span class="bs-stat-atk">${card.attack}</span>` : ""}
${card?.defends != null ? `<span class="bs-stat-def">${card.defends}</span>` : ""} ${card?.defends != null ? `<span class="bs-stat-def">${card.defends}</span>` : ""}
${card?.cooldown != null ? `<span class="bs-stat-cd">${card.cooldown}</span>` : ""} ${card?.cooldown != null ? `<span class="bs-stat-cd">${card.cooldown}</span>` : ""}
${card?.rarity ? `<div class="bs-rarity">${rarityImgs(card.rarity, 11)}</div>` : ""} ${card?.rarity ? `<div class="bs-rarity">${rarityImgs(card.rarity, 11)}</div>` : ""}
<div class="bs-card-name">${card?.name || ''}</div> <div class="bs-card-name">${card?.name || ""}</div>
`; `;
} }
@ -51,9 +54,14 @@ export async function loadEvents() {
} }
const events = [ const events = [
{ id: 1, img: "/images/items/runenhaufen.png", label: "Booster Öffnen", type: "booster" }, {
{ id: 2, img: "/images/items/runenhaufen.png", label: "Textzeile 2" }, id: 1,
{ id: 3, img: "/images/items/runenhaufen.png", label: "Textzeile 3" }, img: "/images/items/runenhaufen.png",
label: "Booster Öffnen",
type: "booster",
},
{ id: 2, img: "/images/items/1v1.png", label: "Textzeile 2" },
{ id: 3, img: "/images/items/2v2.png", label: "Textzeile 3" },
{ id: 4, img: "/images/items/runenhaufen.png", label: "Textzeile 4" }, { id: 4, img: "/images/items/runenhaufen.png", label: "Textzeile 4" },
{ id: 5, img: "/images/items/runenhaufen.png", label: "Textzeile 5" }, { id: 5, img: "/images/items/runenhaufen.png", label: "Textzeile 5" },
]; ];
@ -72,18 +80,20 @@ export async function loadEvents() {
body.innerHTML = ` body.innerHTML = `
<div class="events-grid" id="events-grid"> <div class="events-grid" id="events-grid">
${events.map(ev => { ${events
.map((ev) => {
const done = completedToday.includes(ev.id); const done = completedToday.includes(ev.id);
return ` return `
<div class="event-card${done ? ' event-done' : ''}" data-event-id="${ev.id}" data-type="${ev.type || ''}" data-done="${done}"> <div class="event-card${done ? " event-done" : ""}" data-event-id="${ev.id}" data-type="${ev.type || ""}" data-done="${done}">
<div class="event-card-img-wrap"> <div class="event-card-img-wrap">
<img src="${ev.img}" alt="${ev.label}" draggable="false"> <img src="${ev.img}" alt="${ev.label}" draggable="false">
${done ? `<div class="event-done-overlay">✓</div>` : ''} ${done ? `<div class="event-done-overlay">✓</div>` : ""}
</div> </div>
<span class="event-card-label">${ev.label}</span> <span class="event-card-label">${ev.label}</span>
${done ? `<span class="event-done-label">Bereits erledigt</span>` : ''} ${done ? `<span class="event-done-label">Bereits erledigt</span>` : ""}
</div>`; </div>`;
}).join("")} })
.join("")}
</div> </div>
<!-- Booster UI --> <!-- Booster UI -->
@ -95,12 +105,15 @@ export async function loadEvents() {
<span class="booster-stapel-hint" id="booster-hint">Klicken zum Öffnen</span> <span class="booster-stapel-hint" id="booster-hint">Klicken zum Öffnen</span>
</div> </div>
<div class="booster-slots" id="booster-slots"> <div class="booster-slots" id="booster-slots">
${Array.from({length: 5}, (_, i) => ` ${Array.from(
{ length: 5 },
(_, i) => `
<div class="booster-slot" id="booster-slot-${i}"> <div class="booster-slot" id="booster-slot-${i}">
<div class="booster-slot-inner"> <div class="booster-slot-inner">
<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false"> <img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">
</div> </div>
</div>`).join("")} </div>`,
).join("")}
</div> </div>
</div> </div>
</div> </div>
@ -124,7 +137,7 @@ export async function loadEvents() {
const eventsGrid = body.querySelector("#events-grid"); const eventsGrid = body.querySelector("#events-grid");
/* ── Event-Karten ── */ /* ── Event-Karten ── */
body.querySelectorAll(".event-card").forEach(card => { body.querySelectorAll(".event-card").forEach((card) => {
card.addEventListener("click", () => { card.addEventListener("click", () => {
// Bereits erledigt → nicht anklickbar // Bereits erledigt → nicht anklickbar
if (card.dataset.done === "true") return; if (card.dataset.done === "true") return;
@ -136,7 +149,7 @@ export async function loadEvents() {
return; return;
} }
const id = Number(card.dataset.eventId); const id = Number(card.dataset.eventId);
const ev = events.find(e => e.id === id); const ev = events.find((e) => e.id === id);
if (!ev) return; if (!ev) return;
edpImg.src = ev.img; edpImg.src = ev.img;
edpImg.alt = ev.label; edpImg.alt = ev.label;
@ -155,16 +168,24 @@ export async function loadEvents() {
body: JSON.stringify({ eventId }), body: JSON.stringify({ eventId }),
}); });
// Karte visuell als erledigt markieren // Karte visuell als erledigt markieren
const card = body.querySelector(`.event-card[data-event-id="${eventId}"]`); const card = body.querySelector(
`.event-card[data-event-id="${eventId}"]`,
);
if (card) { if (card) {
card.dataset.done = "true"; card.dataset.done = "true";
card.classList.add("event-done"); card.classList.add("event-done");
const wrap = card.querySelector(".event-card-img-wrap"); const wrap = card.querySelector(".event-card-img-wrap");
if (wrap && !wrap.querySelector(".event-done-overlay")) { if (wrap && !wrap.querySelector(".event-done-overlay")) {
wrap.insertAdjacentHTML("beforeend", `<div class="event-done-overlay">✓</div>`); wrap.insertAdjacentHTML(
"beforeend",
`<div class="event-done-overlay">✓</div>`,
);
} }
if (!card.querySelector(".event-done-label")) { if (!card.querySelector(".event-done-label")) {
card.insertAdjacentHTML("beforeend", `<span class="event-done-label">Bereits erledigt</span>`); card.insertAdjacentHTML(
"beforeend",
`<span class="event-done-label">Bereits erledigt</span>`,
);
} }
} }
} catch (e) { } catch (e) {
@ -172,8 +193,12 @@ export async function loadEvents() {
} }
} }
body.querySelector("#edp-close-btn").addEventListener("click", () => overlay.classList.remove("active")); body
overlay.addEventListener("click", e => { if (e.target === overlay) overlay.classList.remove("active"); }); .querySelector("#edp-close-btn")
.addEventListener("click", () => overlay.classList.remove("active"));
overlay.addEventListener("click", (e) => {
if (e.target === overlay) overlay.classList.remove("active");
});
body.querySelector("#booster-back-btn").addEventListener("click", () => { body.querySelector("#booster-back-btn").addEventListener("click", () => {
// Gesperrt nur wenn Slot gerade läuft // Gesperrt nur wenn Slot gerade läuft
@ -199,7 +224,7 @@ export async function loadEvents() {
let slotLocked = {}; // { index: true } → verhindert Überschreiben nach reveal let slotLocked = {}; // { index: true } → verhindert Überschreiben nach reveal
function clearAllIntervals() { function clearAllIntervals() {
Object.values(spinIntervals).forEach(id => clearInterval(id)); Object.values(spinIntervals).forEach((id) => clearInterval(id));
spinIntervals = {}; spinIntervals = {};
slotLocked = {}; slotLocked = {};
} }
@ -221,9 +246,13 @@ export async function loadEvents() {
allRevealed = false; allRevealed = false;
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
const inner = body.querySelector(`#booster-slot-${i} .booster-slot-inner`); const inner = body.querySelector(
`#booster-slot-${i} .booster-slot-inner`,
);
inner.innerHTML = `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`; inner.innerHTML = `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`;
body.querySelector(`#booster-slot-${i}`).classList.remove("revealed", "spinning"); body
.querySelector(`#booster-slot-${i}`)
.classList.remove("revealed", "spinning");
} }
const stapel = body.querySelector("#booster-stapel"); const stapel = body.querySelector("#booster-stapel");
@ -312,13 +341,15 @@ export async function loadEvents() {
setTimeout(() => revealSlot(i, drawnCards[i]), (i + 1) * 5000); setTimeout(() => revealSlot(i, drawnCards[i]), (i + 1) * 5000);
} }
setTimeout(async () => { setTimeout(
body.querySelector("#booster-hint").textContent = "Karten werden gespeichert..."; async () => {
body.querySelector("#booster-hint").textContent =
"Karten werden gespeichert...";
isSpinning = false; isSpinning = false;
// Karten in user_cards speichern // Karten in user_cards speichern
try { try {
const cardIds = drawnCards.map(c => c.id); const cardIds = drawnCards.map((c) => c.id);
const saveRes = await fetch("/api/booster/save", { const saveRes = await fetch("/api/booster/save", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@ -333,11 +364,14 @@ export async function loadEvents() {
await markDailyComplete(1); await markDailyComplete(1);
allRevealed = true; allRevealed = true;
body.querySelector("#booster-hint").textContent = "Alle Karten erhalten! ✓"; body.querySelector("#booster-hint").textContent =
"Alle Karten erhalten! ✓";
const backBtn = body.querySelector("#booster-back-btn"); const backBtn = body.querySelector("#booster-back-btn");
backBtn.style.opacity = "1"; backBtn.style.opacity = "1";
backBtn.style.cursor = "pointer"; backBtn.style.cursor = "pointer";
}, 5 * 5000 + 500); },
5 * 5000 + 500,
);
}); });
preloadCards(); preloadCards();