This repository has been archived on 2026-05-04. You can view files and clone it, but cannot push or open issues or pull requests.
Galaxy-Strike-Online/game-server/src/sockets/handlers/dungeonHandler.js
2026-04-18 16:33:47 +03:00

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);
}
}