rtjhrt
This commit is contained in:
parent
1ad2b2a25b
commit
f68ff01825
@ -1,4 +1,5 @@
|
||||
export async function loadArena() {
|
||||
export async function loadArena(options = {}) {
|
||||
const { dailyOnly = false, onMatchComplete = null } = options;
|
||||
const ui = document.querySelector(".building-ui");
|
||||
|
||||
ui.innerHTML = `
|
||||
@ -15,6 +16,7 @@ export async function loadArena() {
|
||||
<div class="arena-mode-desc">Einzelkampf – Beweis deine Stärke im Duell</div>
|
||||
</div>
|
||||
|
||||
${!dailyOnly ? `
|
||||
<div class="arena-mode-card" data-mode="2v2">
|
||||
<div class="arena-mode-icon">⚔️</div>
|
||||
<div class="arena-mode-label">2v2</div>
|
||||
@ -26,6 +28,7 @@ export async function loadArena() {
|
||||
<div class="arena-mode-label">4v4</div>
|
||||
<div class="arena-mode-desc">Schlachtruf – Führe deine Truppe zum Sieg</div>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
</div>
|
||||
|
||||
@ -36,7 +39,7 @@ export async function loadArena() {
|
||||
`;
|
||||
|
||||
injectArenaStyles();
|
||||
initArenaModes();
|
||||
initArenaModes({ onMatchComplete });
|
||||
}
|
||||
|
||||
/* ── Styles ────────────────────────────────────────────────────────────────── */
|
||||
@ -225,13 +228,13 @@ function getSocket() {
|
||||
}
|
||||
|
||||
/* ── Klick-Handler initialisieren ─────────────────────────────────────────── */
|
||||
function initArenaModes() {
|
||||
function initArenaModes({ onMatchComplete = null } = {}) {
|
||||
document.querySelectorAll(".arena-mode-card").forEach((card) => {
|
||||
card.addEventListener("click", () => {
|
||||
const mode = card.dataset.mode;
|
||||
|
||||
if (mode === "1v1") {
|
||||
handle1v1Click(card);
|
||||
handle1v1Click(card, onMatchComplete);
|
||||
} else {
|
||||
console.log("Arena Modus gewählt:", mode);
|
||||
// Platzhalter für 2v2 / 4v4
|
||||
@ -241,7 +244,7 @@ function initArenaModes() {
|
||||
}
|
||||
|
||||
/* ── 1v1: Hauptlogik ───────────────────────────────────────────────────────── */
|
||||
async function handle1v1Click(card) {
|
||||
async function handle1v1Click(card, onMatchComplete = null) {
|
||||
const socket = getSocket();
|
||||
if (!socket) {
|
||||
showArenaError("Keine Verbindung zum Server. Bitte Seite neu laden.");
|
||||
@ -287,6 +290,9 @@ async function handle1v1Click(card) {
|
||||
setCardSearching(card, false);
|
||||
hideQueueStatus();
|
||||
|
||||
// Daily als erledigt markieren
|
||||
if (typeof onMatchComplete === "function") onMatchComplete();
|
||||
|
||||
showMatchFoundOverlay(me.name, data.opponent.name, () => {
|
||||
openArenaPopup(
|
||||
`/arena/1v1?match=${encodeURIComponent(data.matchId)}&slot=${encodeURIComponent(data.mySlot)}`,
|
||||
|
||||
@ -20,22 +20,19 @@ function rarityImgs(rarity, size = 13) {
|
||||
}
|
||||
|
||||
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
|
||||
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 `
|
||||
<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'">
|
||||
${card?.attack != null ? `<span class="bs-stat-atk">${card.attack}</span>` : ""}
|
||||
${card?.defends != null ? `<span class="bs-stat-def">${card.defends}</span>` : ""}
|
||||
${card?.cooldown != null ? `<span class="bs-stat-cd">${card.cooldown}</span>` : ""}
|
||||
${card?.rarity ? `<div class="bs-rarity">${rarityImgs(card.rarity, 11)}</div>` : ""}
|
||||
<div class="bs-card-name">${card?.name || ""}</div>
|
||||
${card?.attack != null ? `<span class="bs-stat-atk">${card.attack}</span>` : ""}
|
||||
${card?.defends != null ? `<span class="bs-stat-def">${card.defends}</span>` : ""}
|
||||
${card?.cooldown!= null ? `<span class="bs-stat-cd">${card.cooldown}</span>` : ""}
|
||||
${card?.rarity ? `<div class="bs-rarity">${rarityImgs(card.rarity, 11)}</div>` : ""}
|
||||
<div class="bs-card-name">${card?.name || ''}</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -48,40 +45,23 @@ export async function loadEvents() {
|
||||
|
||||
if (!document.querySelector('link[href="/css/events.css"]')) {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.rel = "stylesheet";
|
||||
link.href = "/css/events.css";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
|
||||
const events = [
|
||||
{
|
||||
id: 1,
|
||||
img: "/images/items/runenhaufen.png",
|
||||
label: "Booster Öffnen",
|
||||
type: "booster",
|
||||
},
|
||||
{ id: 2, img: "/images/items/1v1.png", label: "1v1" },
|
||||
{ id: 3, img: "/images/items/2v2.png", label: "2v2" },
|
||||
{
|
||||
id: 4,
|
||||
img: "/images/items/holz.png",
|
||||
label: "Holz Spenden",
|
||||
type: "wood",
|
||||
woodCost: 100,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
img: "/images/items/goldmuenze.png",
|
||||
label: "Gold Spenden",
|
||||
type: "gold",
|
||||
goldCost: 100,
|
||||
},
|
||||
{ id: 1, img: "/images/items/runenhaufen.png", label: "Booster Öffnen", type: "booster" },
|
||||
{ id: 2, img: "/images/items/runenhaufen.png", label: "1v1 Duell", type: "arena" },
|
||||
{ id: 3, img: "/images/items/runenhaufen.png", label: "Textzeile 3" },
|
||||
{ id: 4, img: "/images/items/holz.png", label: "Holz Spenden", type: "wood", woodCost: 100 },
|
||||
{ id: 5, img: "/images/items/gold.png", label: "Gold Spenden", type: "gold", goldCost: 100 },
|
||||
];
|
||||
|
||||
// Täglichen Status + Holz-Bestand parallel laden
|
||||
let completedToday = [];
|
||||
let playerWood = 0;
|
||||
let playerGold = 0;
|
||||
let playerWood = 0;
|
||||
let playerGold = 0;
|
||||
try {
|
||||
const [statusRes, hudRes] = await Promise.all([
|
||||
fetch("/api/daily/status"),
|
||||
@ -89,7 +69,7 @@ export async function loadEvents() {
|
||||
]);
|
||||
if (statusRes.ok) completedToday = (await statusRes.json()).completed || [];
|
||||
if (hudRes.ok) {
|
||||
const hud = await hudRes.json();
|
||||
const hud = await hudRes.json();
|
||||
playerWood = hud.wood || 0;
|
||||
playerGold = hud.gold || 0;
|
||||
}
|
||||
@ -99,30 +79,24 @@ export async function loadEvents() {
|
||||
|
||||
body.innerHTML = `
|
||||
<div class="events-grid" id="events-grid">
|
||||
${events
|
||||
.map((ev) => {
|
||||
const done = completedToday.includes(ev.id);
|
||||
const locked =
|
||||
!done &&
|
||||
((ev.woodCost && playerWood < ev.woodCost) ||
|
||||
(ev.goldCost && playerGold < ev.goldCost));
|
||||
const costLabel = ev.woodCost
|
||||
? `🪵 ${ev.woodCost} Holz`
|
||||
: ev.goldCost
|
||||
? `🪙 ${ev.goldCost} Gold`
|
||||
: "";
|
||||
const cls = done ? " event-done" : locked ? " event-locked" : "";
|
||||
return `
|
||||
<div class="event-card${cls}" data-event-id="${ev.id}" data-type="${ev.type || ""}" data-done="${done}" data-locked="${locked}">
|
||||
${events.map(ev => {
|
||||
const done = completedToday.includes(ev.id);
|
||||
const locked = !done && (
|
||||
(ev.woodCost && playerWood < ev.woodCost) ||
|
||||
(ev.goldCost && playerGold < ev.goldCost)
|
||||
);
|
||||
const costLabel = ev.woodCost ? `🪵 ${ev.woodCost} Holz` : ev.goldCost ? `🪙 ${ev.goldCost} Gold` : '';
|
||||
const cls = done ? ' event-done' : locked ? ' event-locked' : '';
|
||||
return `
|
||||
<div class="event-card${cls}" data-event-id="${ev.id}" data-type="${ev.type || ''}" data-done="${done}" data-locked="${locked}">
|
||||
<div class="event-card-img-wrap">
|
||||
<img src="${ev.img}" alt="${ev.label}" draggable="false">
|
||||
${done ? `<div class="event-done-overlay"></div>` : ""}
|
||||
${locked ? `<div class="event-locked-overlay"><span>${costLabel}<br>benötigt</span></div>` : ""}
|
||||
${done ? `<div class="event-done-overlay"></div>` : ''}
|
||||
${locked ? `<div class="event-locked-overlay"><span>${costLabel}<br>benötigt</span></div>` : ''}
|
||||
</div>
|
||||
<span class="event-card-label">${ev.label}</span>
|
||||
</div>`;
|
||||
})
|
||||
.join("")}
|
||||
}).join("")}
|
||||
</div>
|
||||
|
||||
<!-- Booster UI -->
|
||||
@ -134,15 +108,12 @@ export async function loadEvents() {
|
||||
<span class="booster-stapel-hint" id="booster-hint">Klicken zum Öffnen</span>
|
||||
</div>
|
||||
<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-inner">
|
||||
<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">
|
||||
</div>
|
||||
</div>`,
|
||||
).join("")}
|
||||
</div>`).join("")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -174,7 +145,7 @@ export async function loadEvents() {
|
||||
<div class="booster-stage">
|
||||
<div class="booster-left">
|
||||
<div class="wood-btn-wrap">
|
||||
<img id="gold-btn" src="/images/items/goldmuenze.png" alt="Gold Spenden" draggable="false" class="booster-stapel-img">
|
||||
<img id="gold-btn" src="/images/items/gold.png" alt="Gold Spenden" draggable="false" class="booster-stapel-img">
|
||||
<div class="gold-stamp" id="gold-stamp">Bitte Spenden</div>
|
||||
</div>
|
||||
<span class="booster-stapel-hint" id="gold-hint">100 Gold spenden</span>
|
||||
@ -200,46 +171,56 @@ export async function loadEvents() {
|
||||
</div>
|
||||
`;
|
||||
|
||||
const overlay = body.querySelector("#event-detail-overlay");
|
||||
const edpImg = body.querySelector("#edp-img");
|
||||
const edpTitle = body.querySelector("#edp-title");
|
||||
const edpBody = body.querySelector("#edp-body");
|
||||
const boosterUi = body.querySelector("#booster-ui");
|
||||
const woodUi = body.querySelector("#wood-ui");
|
||||
const goldUi = body.querySelector("#gold-ui");
|
||||
const overlay = body.querySelector("#event-detail-overlay");
|
||||
const edpImg = body.querySelector("#edp-img");
|
||||
const edpTitle = body.querySelector("#edp-title");
|
||||
const edpBody = body.querySelector("#edp-body");
|
||||
const boosterUi = body.querySelector("#booster-ui");
|
||||
const woodUi = body.querySelector("#wood-ui");
|
||||
const goldUi = body.querySelector("#gold-ui");
|
||||
const eventsGrid = body.querySelector("#events-grid");
|
||||
|
||||
/* ── Event-Karten ── */
|
||||
body.querySelectorAll(".event-card").forEach((card) => {
|
||||
body.querySelectorAll(".event-card").forEach(card => {
|
||||
card.addEventListener("click", () => {
|
||||
if (card.dataset.done === "true") return;
|
||||
if (card.dataset.locked === "true") return;
|
||||
if (card.dataset.done === "true") return;
|
||||
if (card.dataset.locked === "true") return;
|
||||
|
||||
if (card.dataset.type === "booster") {
|
||||
eventsGrid.style.display = "none";
|
||||
boosterUi.style.display = "flex";
|
||||
boosterUi.style.display = "flex";
|
||||
resetBooster();
|
||||
return;
|
||||
}
|
||||
if (card.dataset.type === "arena") {
|
||||
// Arena-Popup öffnen – nur 1v1, Daily-Callback mitgeben
|
||||
import("/js/quickmenu/arena.js").then(mod => {
|
||||
mod.loadArena({
|
||||
dailyOnly: true,
|
||||
onMatchComplete: () => markDailyComplete(2),
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (card.dataset.type === "gold") {
|
||||
eventsGrid.style.display = "none";
|
||||
goldUi.style.display = "flex";
|
||||
goldUi.style.display = "flex";
|
||||
resetGold();
|
||||
return;
|
||||
}
|
||||
if (card.dataset.type === "wood") {
|
||||
eventsGrid.style.display = "none";
|
||||
woodUi.style.display = "flex";
|
||||
woodUi.style.display = "flex";
|
||||
resetWood();
|
||||
return;
|
||||
}
|
||||
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;
|
||||
edpImg.src = ev.img;
|
||||
edpImg.alt = ev.label;
|
||||
edpImg.src = ev.img;
|
||||
edpImg.alt = ev.label;
|
||||
edpTitle.textContent = ev.label;
|
||||
edpBody.textContent = "Inhalt folgt...";
|
||||
edpBody.textContent = "Inhalt folgt...";
|
||||
overlay.classList.add("active");
|
||||
});
|
||||
});
|
||||
@ -253,24 +234,16 @@ export async function loadEvents() {
|
||||
body: JSON.stringify({ eventId }),
|
||||
});
|
||||
// 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) {
|
||||
card.dataset.done = "true";
|
||||
card.classList.add("event-done");
|
||||
const wrap = card.querySelector(".event-card-img-wrap");
|
||||
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")) {
|
||||
card.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
`<span class="event-done-label">Bereits erledigt</span>`,
|
||||
);
|
||||
card.insertAdjacentHTML("beforeend", `<span class="event-done-label">Bereits erledigt</span>`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
@ -278,12 +251,8 @@ export async function loadEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
body
|
||||
.querySelector("#edp-close-btn")
|
||||
.addEventListener("click", () => overlay.classList.remove("active"));
|
||||
overlay.addEventListener("click", (e) => {
|
||||
if (e.target === overlay) overlay.classList.remove("active");
|
||||
});
|
||||
body.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", () => {
|
||||
if (isSpinning) return;
|
||||
@ -291,7 +260,7 @@ export async function loadEvents() {
|
||||
const boosterDone = boosterCard?.dataset.done === "true";
|
||||
if (!allRevealed && !boosterDone) return;
|
||||
eventsGrid.style.display = "";
|
||||
boosterUi.style.display = "none";
|
||||
boosterUi.style.display = "none";
|
||||
clearAllIntervals();
|
||||
isSpinning = false;
|
||||
});
|
||||
@ -302,7 +271,7 @@ export async function loadEvents() {
|
||||
const woodDone = woodCard?.dataset.done === "true";
|
||||
if (!woodRevealed && !woodDone) return;
|
||||
eventsGrid.style.display = "";
|
||||
woodUi.style.display = "none";
|
||||
woodUi.style.display = "none";
|
||||
clearWoodIntervals();
|
||||
isWoodSpinning = false;
|
||||
});
|
||||
@ -313,23 +282,23 @@ export async function loadEvents() {
|
||||
const goldDone = goldCard?.dataset.done === "true";
|
||||
if (!goldRevealed && !goldDone) return;
|
||||
eventsGrid.style.display = "";
|
||||
goldUi.style.display = "none";
|
||||
goldUi.style.display = "none";
|
||||
clearGoldIntervals();
|
||||
isGoldSpinning = false;
|
||||
});
|
||||
// ESC wird zentral in quickmenu.js behandelt (verhindert Listener-Stapelung)
|
||||
|
||||
/* ── Booster Zustand ── */
|
||||
let allCards = [];
|
||||
let isSpinning = false;
|
||||
let allRevealed = false; // true sobald alle 5 Karten aufgedeckt + gespeichert
|
||||
let spinIntervals = {}; // { index: intervalId }
|
||||
let slotLocked = {}; // { index: true } → verhindert Überschreiben nach reveal
|
||||
let allCards = [];
|
||||
let isSpinning = false;
|
||||
let allRevealed = false; // true sobald alle 5 Karten aufgedeckt + gespeichert
|
||||
let spinIntervals = {}; // { index: intervalId }
|
||||
let slotLocked = {}; // { index: true } → verhindert Überschreiben nach reveal
|
||||
|
||||
function clearAllIntervals() {
|
||||
Object.values(spinIntervals).forEach((id) => clearInterval(id));
|
||||
Object.values(spinIntervals).forEach(id => clearInterval(id));
|
||||
spinIntervals = {};
|
||||
slotLocked = {};
|
||||
slotLocked = {};
|
||||
}
|
||||
|
||||
async function preloadCards() {
|
||||
@ -345,23 +314,19 @@ export async function loadEvents() {
|
||||
|
||||
function resetBooster() {
|
||||
clearAllIntervals();
|
||||
isSpinning = false;
|
||||
isSpinning = false;
|
||||
allRevealed = false;
|
||||
|
||||
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">`;
|
||||
body
|
||||
.querySelector(`#booster-slot-${i}`)
|
||||
.classList.remove("revealed", "spinning");
|
||||
body.querySelector(`#booster-slot-${i}`).classList.remove("revealed", "spinning");
|
||||
}
|
||||
|
||||
const stapel = body.querySelector("#booster-stapel");
|
||||
stapel.classList.remove("used");
|
||||
stapel.style.opacity = "1";
|
||||
stapel.style.cursor = "pointer";
|
||||
stapel.style.cursor = "pointer";
|
||||
body.querySelector("#booster-hint").textContent = "Klicken zum Öffnen";
|
||||
preloadCards();
|
||||
}
|
||||
@ -369,7 +334,7 @@ export async function loadEvents() {
|
||||
/* ── Slot drehen – 350ms, damit man die Karten erkennt ── */
|
||||
function startSpinSlot(index) {
|
||||
slotLocked[index] = false;
|
||||
const slot = body.querySelector(`#booster-slot-${index}`);
|
||||
const slot = body.querySelector(`#booster-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.add("spinning");
|
||||
|
||||
@ -384,13 +349,13 @@ export async function loadEvents() {
|
||||
|
||||
/* ── Slot enthüllen – Sperre setzen BEVOR clearInterval ── */
|
||||
function revealSlot(index, card) {
|
||||
slotLocked[index] = true; // zuerst sperren
|
||||
slotLocked[index] = true; // zuerst sperren
|
||||
clearInterval(spinIntervals[index]); // dann stoppen
|
||||
delete spinIntervals[index];
|
||||
|
||||
console.log(`[Booster] Slot ${index} enthüllt:`, card);
|
||||
|
||||
const slot = body.querySelector(`#booster-slot-${index}`);
|
||||
const slot = body.querySelector(`#booster-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.remove("spinning");
|
||||
slot.classList.add("revealed");
|
||||
@ -415,17 +380,17 @@ export async function loadEvents() {
|
||||
const stapel = body.querySelector("#booster-stapel");
|
||||
stapel.classList.add("used");
|
||||
stapel.style.opacity = "0.35";
|
||||
stapel.style.cursor = "default";
|
||||
stapel.style.cursor = "default";
|
||||
body.querySelector("#booster-hint").textContent = "Wird gezogen...";
|
||||
|
||||
// Zurück-Button während der Animation sperren
|
||||
const backBtn = body.querySelector("#booster-back-btn");
|
||||
backBtn.style.opacity = "0.35";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
|
||||
let drawnCards = [];
|
||||
try {
|
||||
const res = await fetch("/api/booster/open", { method: "POST" });
|
||||
const res = await fetch("/api/booster/open", { method: "POST" });
|
||||
const text = await res.text();
|
||||
console.log("[Booster] API Antwort raw:", text);
|
||||
const data = JSON.parse(text);
|
||||
@ -444,37 +409,32 @@ export async function loadEvents() {
|
||||
setTimeout(() => revealSlot(i, drawnCards[i]), (i + 1) * 5000);
|
||||
}
|
||||
|
||||
setTimeout(
|
||||
async () => {
|
||||
body.querySelector("#booster-hint").textContent =
|
||||
"Karten werden gespeichert...";
|
||||
isSpinning = false;
|
||||
setTimeout(async () => {
|
||||
body.querySelector("#booster-hint").textContent = "Karten werden gespeichert...";
|
||||
isSpinning = false;
|
||||
|
||||
// Karten in user_cards speichern
|
||||
try {
|
||||
const cardIds = drawnCards.map((c) => c.id);
|
||||
const saveRes = await fetch("/api/booster/save", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ cardIds }),
|
||||
});
|
||||
if (!saveRes.ok) throw new Error(saveRes.status);
|
||||
} catch (e) {
|
||||
console.error("Karten speichern fehlgeschlagen", e);
|
||||
}
|
||||
// Karten in user_cards speichern
|
||||
try {
|
||||
const cardIds = drawnCards.map(c => c.id);
|
||||
const saveRes = await fetch("/api/booster/save", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ cardIds }),
|
||||
});
|
||||
if (!saveRes.ok) throw new Error(saveRes.status);
|
||||
} catch (e) {
|
||||
console.error("Karten speichern fehlgeschlagen", e);
|
||||
}
|
||||
|
||||
// Booster-Daily als erledigt markieren (event_id = 1)
|
||||
await markDailyComplete(1);
|
||||
// Booster-Daily als erledigt markieren (event_id = 1)
|
||||
await markDailyComplete(1);
|
||||
|
||||
allRevealed = true;
|
||||
body.querySelector("#booster-hint").textContent =
|
||||
"Alle Karten erhalten! ✓";
|
||||
const backBtn = body.querySelector("#booster-back-btn");
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
},
|
||||
5 * 5000 + 500,
|
||||
);
|
||||
allRevealed = true;
|
||||
body.querySelector("#booster-hint").textContent = "Alle Karten erhalten! ✓";
|
||||
const backBtn = body.querySelector("#booster-back-btn");
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
}, 5 * 5000 + 500);
|
||||
});
|
||||
|
||||
preloadCards();
|
||||
@ -482,19 +442,19 @@ export async function loadEvents() {
|
||||
/* ================================
|
||||
Holz-Spenden Zustand
|
||||
================================ */
|
||||
let isWoodSpinning = false;
|
||||
let woodRevealed = false;
|
||||
let woodIntervals = {};
|
||||
let woodLocked = {};
|
||||
let rarity3Cards = [];
|
||||
let isWoodSpinning = false;
|
||||
let woodRevealed = false;
|
||||
let woodIntervals = {};
|
||||
let woodLocked = {};
|
||||
let rarity3Cards = [];
|
||||
|
||||
async function preloadRarity3() {
|
||||
if (rarity3Cards.length) return;
|
||||
try {
|
||||
const res = await fetch("/api/booster/cards");
|
||||
if (!res.ok) throw new Error(res.status);
|
||||
const all = await res.json();
|
||||
rarity3Cards = all.filter((c) => parseInt(c.rarity) === 3);
|
||||
const all = await res.json();
|
||||
rarity3Cards = all.filter(c => parseInt(c.rarity) === 3);
|
||||
// Fallback: wenn keine rarity-3 vorhanden alle nehmen
|
||||
if (!rarity3Cards.length) rarity3Cards = all;
|
||||
} catch (e) {
|
||||
@ -503,25 +463,25 @@ export async function loadEvents() {
|
||||
}
|
||||
|
||||
function clearWoodIntervals() {
|
||||
Object.values(woodIntervals).forEach((id) => clearInterval(id));
|
||||
Object.values(woodIntervals).forEach(id => clearInterval(id));
|
||||
woodIntervals = {};
|
||||
woodLocked = {};
|
||||
woodLocked = {};
|
||||
}
|
||||
|
||||
function resetWood() {
|
||||
clearWoodIntervals();
|
||||
isWoodSpinning = false;
|
||||
woodRevealed = false;
|
||||
woodRevealed = false;
|
||||
|
||||
const inner = body.querySelector(`#wood-slot-0 .booster-slot-inner`);
|
||||
inner.innerHTML = `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`;
|
||||
body.querySelector(`#wood-slot-0`).classList.remove("revealed", "spinning");
|
||||
|
||||
const btn = body.querySelector("#wood-btn");
|
||||
const btn = body.querySelector("#wood-btn");
|
||||
const stamp = body.querySelector("#wood-stamp");
|
||||
btn.classList.remove("used");
|
||||
btn.style.opacity = "1";
|
||||
btn.style.cursor = "pointer";
|
||||
btn.style.cursor = "pointer";
|
||||
if (stamp) stamp.style.display = "";
|
||||
body.querySelector("#wood-hint").textContent = "100 Holz spenden";
|
||||
preloadRarity3();
|
||||
@ -529,7 +489,7 @@ export async function loadEvents() {
|
||||
|
||||
function startWoodSlot(index) {
|
||||
woodLocked[index] = false;
|
||||
const slot = body.querySelector(`#wood-slot-${index}`);
|
||||
const slot = body.querySelector(`#wood-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.add("spinning");
|
||||
|
||||
@ -547,14 +507,13 @@ export async function loadEvents() {
|
||||
clearInterval(woodIntervals[index]);
|
||||
delete woodIntervals[index];
|
||||
|
||||
const slot = body.querySelector(`#wood-slot-${index}`);
|
||||
const slot = body.querySelector(`#wood-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.remove("spinning");
|
||||
slot.classList.add("revealed");
|
||||
inner.innerHTML = cardHTML(card, true);
|
||||
setTimeout(() => {
|
||||
if (slot.classList.contains("revealed"))
|
||||
inner.innerHTML = cardHTML(card, true);
|
||||
if (slot.classList.contains("revealed")) inner.innerHTML = cardHTML(card, true);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@ -565,31 +524,31 @@ export async function loadEvents() {
|
||||
|
||||
isWoodSpinning = true;
|
||||
|
||||
const btn = body.querySelector("#wood-btn");
|
||||
const btn = body.querySelector("#wood-btn");
|
||||
const stamp = body.querySelector("#wood-stamp");
|
||||
btn.classList.add("used");
|
||||
btn.style.opacity = "0.35";
|
||||
btn.style.cursor = "default";
|
||||
btn.style.opacity = "0.35";
|
||||
btn.style.cursor = "default";
|
||||
if (stamp) stamp.style.display = "none";
|
||||
body.querySelector("#wood-hint").textContent = "Wird verarbeitet...";
|
||||
|
||||
const backBtn = body.querySelector("#wood-back-btn");
|
||||
backBtn.style.opacity = "0.35";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
|
||||
// API aufrufen – 100 Holz abziehen + Karte ziehen
|
||||
let drawnCard = null;
|
||||
try {
|
||||
const res = await fetch("/api/booster/wood-donate", { method: "POST" });
|
||||
const res = await fetch("/api/booster/wood-donate", { method: "POST" });
|
||||
const data = await res.json();
|
||||
if (!res.ok) {
|
||||
body.querySelector("#wood-hint").textContent = data.error || "Fehler";
|
||||
isWoodSpinning = false;
|
||||
btn.classList.remove("used");
|
||||
btn.style.opacity = "1";
|
||||
btn.style.cursor = "pointer";
|
||||
btn.style.cursor = "pointer";
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
backBtn.style.cursor = "pointer";
|
||||
return;
|
||||
}
|
||||
drawnCard = data.card;
|
||||
@ -608,12 +567,12 @@ export async function loadEvents() {
|
||||
|
||||
body.querySelector("#wood-hint").textContent = "Karte erhalten! ✓";
|
||||
isWoodSpinning = false;
|
||||
woodRevealed = true;
|
||||
woodRevealed = true;
|
||||
|
||||
markDailyComplete(4);
|
||||
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
backBtn.style.cursor = "pointer";
|
||||
}, 5000);
|
||||
});
|
||||
|
||||
@ -623,30 +582,30 @@ export async function loadEvents() {
|
||||
Gold-Spenden Zustand
|
||||
================================ */
|
||||
let isGoldSpinning = false;
|
||||
let goldRevealed = false;
|
||||
let goldIntervals = {};
|
||||
let goldLocked = {};
|
||||
let goldRevealed = false;
|
||||
let goldIntervals = {};
|
||||
let goldLocked = {};
|
||||
|
||||
function clearGoldIntervals() {
|
||||
Object.values(goldIntervals).forEach((id) => clearInterval(id));
|
||||
Object.values(goldIntervals).forEach(id => clearInterval(id));
|
||||
goldIntervals = {};
|
||||
goldLocked = {};
|
||||
goldLocked = {};
|
||||
}
|
||||
|
||||
function resetGold() {
|
||||
clearGoldIntervals();
|
||||
isGoldSpinning = false;
|
||||
goldRevealed = false;
|
||||
goldRevealed = false;
|
||||
|
||||
const inner = body.querySelector(`#gold-slot-0 .booster-slot-inner`);
|
||||
inner.innerHTML = `<img class="booster-slot-img" src="/images/items/rueckseite.png" alt="?" draggable="false">`;
|
||||
body.querySelector(`#gold-slot-0`).classList.remove("revealed", "spinning");
|
||||
|
||||
const btn = body.querySelector("#gold-btn");
|
||||
const btn = body.querySelector("#gold-btn");
|
||||
const stamp = body.querySelector("#gold-stamp");
|
||||
btn.classList.remove("used");
|
||||
btn.style.opacity = "1";
|
||||
btn.style.cursor = "pointer";
|
||||
btn.style.cursor = "pointer";
|
||||
if (stamp) stamp.style.display = "";
|
||||
body.querySelector("#gold-hint").textContent = "100 Gold spenden";
|
||||
preloadRarity3();
|
||||
@ -654,7 +613,7 @@ export async function loadEvents() {
|
||||
|
||||
function startGoldSlot(index) {
|
||||
goldLocked[index] = false;
|
||||
const slot = body.querySelector(`#gold-slot-${index}`);
|
||||
const slot = body.querySelector(`#gold-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.add("spinning");
|
||||
|
||||
@ -672,14 +631,13 @@ export async function loadEvents() {
|
||||
clearInterval(goldIntervals[index]);
|
||||
delete goldIntervals[index];
|
||||
|
||||
const slot = body.querySelector(`#gold-slot-${index}`);
|
||||
const slot = body.querySelector(`#gold-slot-${index}`);
|
||||
const inner = slot.querySelector(".booster-slot-inner");
|
||||
slot.classList.remove("spinning");
|
||||
slot.classList.add("revealed");
|
||||
inner.innerHTML = cardHTML(card, true);
|
||||
setTimeout(() => {
|
||||
if (slot.classList.contains("revealed"))
|
||||
inner.innerHTML = cardHTML(card, true);
|
||||
if (slot.classList.contains("revealed")) inner.innerHTML = cardHTML(card, true);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@ -690,31 +648,31 @@ export async function loadEvents() {
|
||||
|
||||
isGoldSpinning = true;
|
||||
|
||||
const btn = body.querySelector("#gold-btn");
|
||||
const btn = body.querySelector("#gold-btn");
|
||||
const stamp = body.querySelector("#gold-stamp");
|
||||
btn.classList.add("used");
|
||||
btn.style.opacity = "0.35";
|
||||
btn.style.cursor = "default";
|
||||
btn.style.opacity = "0.35";
|
||||
btn.style.cursor = "default";
|
||||
if (stamp) stamp.style.display = "none";
|
||||
body.querySelector("#gold-hint").textContent = "Wird verarbeitet...";
|
||||
|
||||
const backBtn = body.querySelector("#gold-back-btn");
|
||||
backBtn.style.opacity = "0.35";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
backBtn.style.cursor = "not-allowed";
|
||||
|
||||
let drawnCard = null;
|
||||
try {
|
||||
const res = await fetch("/api/booster/gold-donate", { method: "POST" });
|
||||
const res = await fetch("/api/booster/gold-donate", { method: "POST" });
|
||||
const data = await res.json();
|
||||
if (!res.ok) {
|
||||
body.querySelector("#gold-hint").textContent = data.error || "Fehler";
|
||||
isGoldSpinning = false;
|
||||
btn.classList.remove("used");
|
||||
btn.style.opacity = "1";
|
||||
btn.style.cursor = "pointer";
|
||||
btn.style.cursor = "pointer";
|
||||
if (stamp) stamp.style.display = "";
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
backBtn.style.cursor = "pointer";
|
||||
return;
|
||||
}
|
||||
drawnCard = data.card;
|
||||
@ -730,10 +688,10 @@ export async function loadEvents() {
|
||||
revealGoldSlot(0, drawnCard);
|
||||
body.querySelector("#gold-hint").textContent = "Karte erhalten! ✓";
|
||||
isGoldSpinning = false;
|
||||
goldRevealed = true;
|
||||
goldRevealed = true;
|
||||
markDailyComplete(5);
|
||||
backBtn.style.opacity = "1";
|
||||
backBtn.style.cursor = "pointer";
|
||||
backBtn.style.cursor = "pointer";
|
||||
}, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user