From e7f98d1228c25fa29ac37ebfe673ed2401f3b3c3 Mon Sep 17 00:00:00 2001 From: MaksSlyzar Date: Sat, 18 Apr 2026 16:33:47 +0300 Subject: [PATCH] Fixed Dungeon Rewards. Updated DungeonManager --- game-server/src/game/DungeonManager.js | 99 +++++++++----- .../src/sockets/handlers/dungeonHandler.js | 126 ++++-------------- 2 files changed, 90 insertions(+), 135 deletions(-) diff --git a/game-server/src/game/DungeonManager.js b/game-server/src/game/DungeonManager.js index a6c525a..4dca3a7 100644 --- a/game-server/src/game/DungeonManager.js +++ b/game-server/src/game/DungeonManager.js @@ -26,25 +26,55 @@ class DungeonManager { const dungeon = DatapackLoader.getDungeon(session.dungeonId); const roomRef = dungeon.rooms[session.currentRoomIndex]; - const rawRoom = DatapackLoader.getRoom(roomRef.id); if (!rawRoom) return null; - const roomData = rawRoom; - const hostiles = (roomData.hostiles || []) - .map((hId) => { - return DatapackLoader.getEnemy(hId); - }) + const hostiles = (rawRoom.hostiles || []) + .map((hId) => DatapackLoader.getEnemy(hId)) .filter(Boolean); + return { roomIndex: session.currentRoomIndex, totalRooms: dungeon.rooms.length, - config: roomData, + config: rawRoom, hostiles, }; } + processCombatStep(playerId, enemyId) { + const session = this.activeSessions.get(playerId); + if (!session || session.isFinished) return null; + + const enemy = DatapackLoader.getEnemy(enemyId); + if (!enemy) return null; + + if (session.currentEnemyHp === undefined) { + session.currentEnemyHp = enemy.stats?.health || 100; + } + + const damage = Math.floor(Math.random() * 10) + 20; + session.currentEnemyHp -= damage; + + const isDefeated = session.currentEnemyHp <= 0; + let lootDropped = []; + + if (isDefeated) { + if (enemy.loot) { + lootDropped = this._generateLoot(enemy.loot); + session.rewards.items.push(...lootDropped); + } + session.currentEnemyHp = undefined; + } + + return { + damageDealt: damage, + enemyHp: Math.max(0, session.currentEnemyHp || 0), + targetDefeated: isDefeated, + loot: lootDropped, + }; + } + moveToNextRoom(playerId) { const session = this.activeSessions.get(playerId); if (!session || session.isFinished) return null; @@ -53,43 +83,46 @@ class DungeonManager { const roomRef = dungeon.rooms[session.currentRoomIndex]; const rawRoom = DatapackLoader.getRoom(roomRef.id); - if (rawRoom && rawRoom.room) { - const room = rawRoom.room; - - session.rewards.xp += room.gainXp || 0; - session.rewards.credits += room.credits || 0; - - if (room.loot && Array.isArray(room.loot)) { - room.loot.forEach((lootEntry) => { - const roll = Math.random(); - if (roll <= (lootEntry.chance || 1.0)) { - session.rewards.items.push({ - id: lootEntry.id, - count: - typeof lootEntry.count === "object" - ? Math.floor( - Math.random() * - (lootEntry.count.max - lootEntry.count.min + 1), - ) + lootEntry.count.min - : lootEntry.count || 1, - }); + if (rawRoom) { + if (rawRoom.hostiles) { + rawRoom.hostiles.forEach((hId) => { + const enemy = DatapackLoader.getEnemy(hId); + if (enemy) { + session.rewards.xp += enemy.gainXp || 0; + session.rewards.credits += enemy.credits || 0; } }); } + session.rewards.xp += rawRoom.gainXp || 0; + session.rewards.credits += rawRoom.credits || 0; + if (rawRoom.loot) { + session.rewards.items.push(...this._generateLoot(rawRoom.loot)); + } } - session.currentEnemyHp = undefined; - if (session.currentRoomIndex < dungeon.rooms.length - 1) { session.currentRoomIndex++; return this.getCurrentRoomData(playerId); } session.isFinished = true; - return { - status: "completed", - rewards: session.rewards, - }; + return { status: "completed", rewards: session.rewards }; + } + + _generateLoot(lootTable) { + const dropped = []; + lootTable.forEach((entry) => { + if (Math.random() <= (entry.chance || 1.0)) { + const count = + typeof entry.count === "object" + ? Math.floor( + Math.random() * (entry.count.max - entry.count.min + 1), + ) + entry.count.min + : entry.count || 1; + dropped.push({ id: entry.id, count }); + } + }); + return dropped; } leaveDungeon(playerId) { diff --git a/game-server/src/sockets/handlers/dungeonHandler.js b/game-server/src/sockets/handlers/dungeonHandler.js index 279f319..c1ec67a 100644 --- a/game-server/src/sockets/handlers/dungeonHandler.js +++ b/game-server/src/sockets/handlers/dungeonHandler.js @@ -9,25 +9,16 @@ module.exports = (io, socket) => { try { if (!userId) return; const dungeon = DatapackLoader.getDungeon(dungeonId); - if (!dungeon) { - return socket.emit("error", { message: "Dungeon not found" }); - } - const player = await Player.findByPk(userId); - const energyCost = dungeon.meta?.energyCost || 0; + const energyCost = dungeon?.meta?.energyCost || 0; - if (player.energy < energyCost) { + 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); - if (!firstRoom) { - return socket.emit("error", { - message: "Failed to initialize dungeon", - }); - } socket.emit("dungeon:started", { dungeonId: dungeon.id, @@ -38,92 +29,34 @@ module.exports = (io, socket) => { remainingEnergy: player.energy - energyCost, }); } catch (err) { - console.error("Dungeon Start Error:", err); socket.emit("error", { message: "Critical deployment failure" }); } }); socket.on("dungeon:combat_step", async ({ enemyId }) => { - try { - if (!userId) return; + const result = dungeonManager.processCombatStep(userId, enemyId); + if (!result) return; - const session = dungeonManager.activeSessions.get(userId); - if (!session || session.isFinished) return; - - const rawEnemy = DatapackLoader.getEnemy(enemyId); - if (!rawEnemy) { - return socket.emit("error", { message: "Target data corrupted" }); - } - - const enemy = rawEnemy; - - if (session.currentEnemyHp === undefined) { - session.currentEnemyHp = enemy.stats?.health || 100; - } - - const damage = Math.floor(Math.random() * 10) + 20; - session.currentEnemyHp -= damage; - - const isDefeated = session.currentEnemyHp <= 0; - let lootDropped = []; - - if (isDefeated && enemy.loot) { - enemy.loot.forEach((entry) => { - if (Math.random() <= (entry.chance || 1.0)) { - const count = - typeof entry.count === "object" - ? Math.floor( - Math.random() * (entry.count.max - entry.count.min + 1), - ) + entry.count.min - : entry.count || 1; - - const drop = { id: entry.id, count }; - lootDropped.push(drop); - session.rewards.items.push(drop); - } - }); - } - - socket.emit("dungeon:combat_result", { - damageDealt: damage, - enemyHp: Math.max(0, session.currentEnemyHp), - targetDefeated: isDefeated, - loot: lootDropped, - message: isDefeated - ? `Enemy eliminated!` - : `Strike successful. Dealt ${damage} damage.`, - }); - - if (isDefeated) { - session.currentEnemyHp = undefined; - } - } catch (err) { - console.error("Combat Error:", err); - } + socket.emit("dungeon:combat_result", { + ...result, + message: result.targetDefeated + ? "Enemy eliminated!" + : `Strike successful. Dealt ${result.damageDealt} damage.`, + }); }); socket.on("dungeon:next_room", async () => { try { - if (!userId) return; - const nextRoom = dungeonManager.moveToNextRoom(userId); - if (!nextRoom) { - return socket.emit("error", { - message: "Could not proceed to next room", - }); - } + if (!nextRoom) + return socket.emit("error", { message: "Navigation error" }); if (nextRoom.status === "completed") { await finalizeDungeon(socket, nextRoom.rewards); } else { - socket.emit("dungeon:room_update", { - room: nextRoom.config, - hostiles: nextRoom.hostiles, - roomIndex: nextRoom.roomIndex, - }); + socket.emit("dungeon:room_update", nextRoom); } } catch (err) { - console.error("Dungeon Progress Error:", err); socket.emit("error", { message: "Navigation system error" }); } }); @@ -138,44 +71,33 @@ async function finalizeDungeon(socket, sessionRewards) { try { const player = await Player.findByPk(userId); - if (sessionRewards.credits > 0) { + if (sessionRewards.credits > 0) await player.increment("credits", { by: sessionRewards.credits }); - } - - if (sessionRewards.xp > 0) { - await player.increment("xp", { by: sessionRewards.xp }); - } + if (sessionRewards.xp > 0) + await player.increment("experience", { by: sessionRewards.xp }); if (sessionRewards.items.length > 0) { - const consolidatedItems = sessionRewards.items.reduce((acc, curr) => { + 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(consolidatedItems)) { + 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(consolidatedItems).map( - ([id, count]) => ({ - id, - count, - }), + sessionRewards.items = Object.entries(consolidated).map( + ([id, count]) => ({ id, count }), ); } - socket.emit("dungeon:completed", { - rewards: sessionRewards, - message: "Mission successful. All objectives secured.", - }); + socket.emit("dungeon:completed", { rewards: sessionRewards }); } catch (err) { - console.error("Finalize Error:", err); - socket.emit("error", { message: "Failed to save mission rewards" }); + socket.emit("error", { message: "Failed to save rewards" }); } finally { dungeonManager.leaveDungeon(userId); }