Fixed Dungeon Rewards. Updated DungeonManager
This commit is contained in:
parent
3307503086
commit
e7f98d1228
@ -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,32 +83,22 @@ 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++;
|
||||
@ -86,10 +106,23 @@ class DungeonManager {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@ -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 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
const result = dungeonManager.processCombatStep(userId, enemyId);
|
||||
if (!result) return;
|
||||
|
||||
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.`,
|
||||
...result,
|
||||
message: result.targetDefeated
|
||||
? "Enemy eliminated!"
|
||||
: `Strike successful. Dealt ${result.damageDealt} damage.`,
|
||||
});
|
||||
|
||||
if (isDefeated) {
|
||||
session.currentEnemyHp = undefined;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Combat Error:", err);
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user