/* ============================================================ routes/combine.route.js POST /api/cards/combine Karten kombinieren in der Gaststätte (Gebäude 6) ============================================================ */ const express = require("express"); const router = express.Router(); const db = require("../database/database"); const { getMaxRarity } = require("../utils/rarity"); function requireLogin(req, res, next) { if (!req.session?.user) return res.status(401).json({ error: "Nicht eingeloggt" }); next(); } /* ════════════════════════════════════════════ Gaststätte-Level → benötigte Karten für 100% ════════════════════════════════════════════ */ function getRequiredCards(tavernLevel) { if (tavernLevel < 5) return 10; if (tavernLevel < 10) return 8; if (tavernLevel < 15) return 6; if (tavernLevel < 20) return 5; return 3; } /* ════════════════════════════════════════════ POST /api/cards/combine Body: { card_id: Number, amount: Number } ════════════════════════════════════════════ */ router.post("/cards/combine", requireLogin, async (req, res) => { const userId = req.session.user.id; const { card_id, amount } = req.body; if (!card_id || !amount || amount < 2) { return res.status(400).json({ error: "Mindestens 2 Karten erforderlich." }); } try { /* ── 1. Spielerlevel holen ── */ const [[account]] = await db.query( "SELECT level FROM accounts WHERE id = ?", [userId] ); const playerLevel = account?.level ?? 1; /* ── 2. Gaststätte-Level holen (building_id = 6) ── */ const [[tavern]] = await db.query( "SELECT level FROM user_buildings WHERE user_id = ? AND building_id = 6", [userId] ); const tavernLevel = tavern?.level ?? 1; /* ── 3. Chance berechnen ── */ const required = getRequiredCards(tavernLevel); const chance = Math.min((amount / required) * 100, 100); /* ── 4. Besitz prüfen ── */ const [[owned]] = await db.query( "SELECT amount FROM user_cards WHERE user_id = ? AND card_id = ?", [userId, card_id] ); if (!owned || owned.amount < amount) { return res.status(400).json({ error: "Nicht genügend Karten vorhanden." }); } /* ── 5. Eingabe-Karte laden (für Rarity) ── */ const [[inputCard]] = await db.query( "SELECT id, name, rarity FROM cards WHERE id = ?", [card_id] ); if (!inputCard) { return res.status(400).json({ error: "Karte nicht gefunden." }); } /* ── 6. Karten immer abziehen (Glücksspiel!) ── */ const remainingAfter = owned.amount - amount; if (remainingAfter <= 0) { await db.query( "DELETE FROM user_cards WHERE user_id = ? AND card_id = ?", [userId, card_id] ); } else { await db.query( "UPDATE user_cards SET amount = amount - ? WHERE user_id = ? AND card_id = ?", [amount, userId, card_id] ); } /* ── 6b. Decks synchronisieren ────────────────────────────────── Karten die durch Kombination verbraucht wurden, müssen auch aus allen Decks des Spielers entfernt / reduziert werden. Sonst steht im Deck mehr als der Spieler tatsächlich besitzt. ────────────────────────────────────────────────────────────────── */ if (remainingAfter <= 0) { // Keine Exemplare mehr vorhanden → aus allen Decks löschen await db.query( `DELETE dc FROM deck_cards dc JOIN decks d ON d.id = dc.deck_id WHERE d.user_id = ? AND dc.card_id = ?`, [userId, card_id] ); } else { // Noch welche vorhanden → Deck-Menge auf verbleibende Menge deckeln await db.query( `UPDATE deck_cards dc JOIN decks d ON d.id = dc.deck_id SET dc.amount = LEAST(dc.amount, ?) WHERE d.user_id = ? AND dc.card_id = ?`, [remainingAfter, userId, card_id] ); } /* ── 7. Zufallsroll gegen Chance ── */ const roll = Math.random() * 100; const success = roll <= chance; if (!success) { return res.json({ success: false, chance: Math.round(chance), message: "Kombinieren fehlgeschlagen – die Karten wurden verbraucht.", }); } /* ── 8. Gleiche Karte mit Rarity+1 suchen ── */ const targetRarity = parseInt(inputCard.rarity) + 1; const maxRarity = getMaxRarity(playerLevel); if (targetRarity > maxRarity) { return res.status(400).json({ error: `Dein Spielerlevel erlaubt keine Karten über Rarity ${maxRarity}.`, }); } const [[reward]] = await db.query( "SELECT id, name, image, rarity, attack, defends, cooldown FROM cards WHERE name = ? AND rarity = ?", [inputCard.name, targetRarity] ); if (!reward) { return res.status(400).json({ error: `Keine höhere Version von "${inputCard.name}" (Rarity ${targetRarity}) in der Datenbank gefunden.`, }); } /* ── 9. Belohnungskarte gutschreiben ── */ await db.query( `INSERT INTO user_cards (user_id, card_id, amount) VALUES (?, ?, 1) ON DUPLICATE KEY UPDATE amount = amount + 1`, [userId, reward.id] ); res.json({ success: true, chance: Math.round(chance), reward, message: `Kombinieren erfolgreich! Du erhältst: ${reward.name}`, }); } catch (err) { console.error("Combine Fehler:", err); res.status(500).json({ error: "DB Fehler" }); } }); /* ════════════════════════════════════════════ GET /api/cards/combine-info Gaststätte-Level + benötigte Karten für Frontend ════════════════════════════════════════════ */ router.get("/cards/combine-info", requireLogin, async (req, res) => { const userId = req.session.user.id; try { const [[tavern]] = await db.query( "SELECT level FROM user_buildings WHERE user_id = ? AND building_id = 6", [userId] ); const tavernLevel = tavern?.level ?? 1; const required = getRequiredCards(tavernLevel); res.json({ tavernLevel, required }); } catch (err) { console.error(err); res.status(500).json({ error: "DB Fehler" }); } }); module.exports = router;