105 lines
3.3 KiB
JavaScript
105 lines
3.3 KiB
JavaScript
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);
|
|
}
|
|
}
|