const { Player, Inventory } = require("../../models"); const DatapackLoader = require("../../game/DatapackLoader"); const dungeonManager = require("../../game/DungeonManager"); module.exports = (io, socket) => { const userId = socket.user?.id; socket.on("dungeon:start", async ({ dungeonId }) => { try { if (!userId) return; const dungeon = DatapackLoader.getDungeon(dungeonId); const player = await Player.findByPk(userId); const energyCost = dungeon?.meta?.energyCost || 0; if (!dungeon) return socket.emit("error", { message: "Dungeon not found" }); if (player.energy < energyCost) return socket.emit("error", { message: "Insufficient energy" }); await player.decrement("energy", { by: energyCost }); const firstRoom = dungeonManager.startDungeon(userId, dungeonId); socket.emit("dungeon:started", { dungeonId: dungeon.id, room: firstRoom.config, hostiles: firstRoom.hostiles, roomIndex: firstRoom.roomIndex, totalRooms: firstRoom.totalRooms, remainingEnergy: player.energy - energyCost, }); } catch (err) { socket.emit("error", { message: "Critical deployment failure" }); } }); socket.on("dungeon:combat_step", async ({ enemyId }) => { const result = dungeonManager.processCombatStep(userId, enemyId); if (!result) return; socket.emit("dungeon:combat_result", { ...result, message: result.targetDefeated ? "Enemy eliminated!" : `Strike successful. Dealt ${result.damageDealt} damage.`, }); }); socket.on("dungeon:next_room", async () => { try { const nextRoom = dungeonManager.moveToNextRoom(userId); if (!nextRoom) return socket.emit("error", { message: "Navigation error" }); if (nextRoom.status === "completed") { await finalizeDungeon(socket, nextRoom.rewards); } else { socket.emit("dungeon:room_update", nextRoom); } } catch (err) { socket.emit("error", { message: "Navigation system error" }); } }); socket.on("dungeon:leave", () => { if (userId) dungeonManager.leaveDungeon(userId); }); }; async function finalizeDungeon(socket, sessionRewards) { const userId = socket.user.id; try { const player = await Player.findByPk(userId); if (sessionRewards.credits > 0) await player.increment("credits", { by: sessionRewards.credits }); if (sessionRewards.xp > 0) await player.increment("experience", { by: sessionRewards.xp }); if (sessionRewards.items.length > 0) { const consolidated = sessionRewards.items.reduce((acc, curr) => { acc[curr.id] = (acc[curr.id] || 0) + curr.count; return acc; }, {}); for (const [itemId, totalCount] of Object.entries(consolidated)) { const [invItem] = await Inventory.findOrCreate({ where: { playerId: userId, itemId: itemId }, defaults: { quantity: 0 }, }); await invItem.increment("quantity", { by: totalCount }); } sessionRewards.items = Object.entries(consolidated).map( ([id, count]) => ({ id, count }), ); } socket.emit("dungeon:completed", { rewards: sessionRewards }); } catch (err) { socket.emit("error", { message: "Failed to save rewards" }); } finally { dungeonManager.leaveDungeon(userId); } }