Game-Server/game-server/src/game/DungeonManager.js
2026-04-18 16:33:47 +03:00

134 lines
3.7 KiB
JavaScript

const DatapackLoader = require("./DatapackLoader");
class DungeonManager {
constructor() {
this.activeSessions = new Map();
}
startDungeon(playerId, dungeonId) {
const dungeon = DatapackLoader.getDungeon(dungeonId);
if (!dungeon || !dungeon.rooms?.length) return null;
const session = {
dungeonId,
currentRoomIndex: 0,
isFinished: false,
currentEnemyHp: undefined,
rewards: { xp: 0, credits: 0, items: [] },
};
this.activeSessions.set(playerId, session);
return this.getCurrentRoomData(playerId);
}
getCurrentRoomData(playerId) {
const session = this.activeSessions.get(playerId);
if (!session) return null;
const dungeon = DatapackLoader.getDungeon(session.dungeonId);
const roomRef = dungeon.rooms[session.currentRoomIndex];
const rawRoom = DatapackLoader.getRoom(roomRef.id);
if (!rawRoom) return null;
const hostiles = (rawRoom.hostiles || [])
.map((hId) => DatapackLoader.getEnemy(hId))
.filter(Boolean);
return {
roomIndex: session.currentRoomIndex,
totalRooms: dungeon.rooms.length,
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;
const dungeon = DatapackLoader.getDungeon(session.dungeonId);
const roomRef = dungeon.rooms[session.currentRoomIndex];
const rawRoom = DatapackLoader.getRoom(roomRef.id);
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));
}
}
if (session.currentRoomIndex < dungeon.rooms.length - 1) {
session.currentRoomIndex++;
return this.getCurrentRoomData(playerId);
}
session.isFinished = true;
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) {
this.activeSessions.delete(playerId);
}
}
module.exports = new DungeonManager();