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/Client/js/systems/DungeonSystem.js

463 lines
16 KiB
JavaScript

/**
* Galaxy Strike Online - Client Dungeon System
* Server-driven dungeon management client
*/
class DungeonSystem {
constructor(gameEngine) {
this.game = gameEngine;
// Current dungeon state (runtime only)
this.currentDungeon = null;
this.currentRoom = null;
this.dungeonProgress = 0;
this.isExploring = false;
// Server data loaded from server
this.serverDungeons = [];
this.roomTypes = {};
this.enemyTemplates = {};
console.log('[DUNGEON SYSTEM] Client DungeonSystem initialized - server-driven mode');
// Set up socket event listeners
this.setupSocketListeners();
}
/**
* Set up Socket.IO event listeners for dungeon data
*/
setupSocketListeners() {
if (!this.game.socket) {
console.warn('[DUNGEON SYSTEM] No socket available for event listeners');
return;
}
// Listen for dungeon data response
this.game.socket.on('dungeons_data', (data) => {
console.log('[DUNGEON SYSTEM] Received dungeons data:', data);
this.serverDungeons = data.dungeons || data;
console.log('[DUNGEON SYSTEM] Loaded grouped dungeons from server:', Object.keys(this.serverDungeons));
// Update UI when data is loaded
this.generateDungeonList();
});
// Listen for room types response
this.game.socket.on('room_types_data', (data) => {
console.log('[DUNGEON SYSTEM] Received room types data:', data);
this.roomTypes = data;
console.log('[DUNGEON SYSTEM] Loaded room types from server');
});
// Listen for enemy templates response
this.game.socket.on('enemy_templates_data', (data) => {
console.log('[DUNGEON SYSTEM] Received enemy templates data:', data);
this.enemyTemplates = data;
console.log(`[DUNGEON SYSTEM] Loaded ${Object.keys(this.enemyTemplates).length} enemy templates from server`);
// Update UI when enemy data is loaded
this.generateDungeonList();
});
// Listen for dungeon start response
this.game.socket.on('dungeon_started', (data) => {
console.log('[DUNGEON SYSTEM] Dungeon started:', data);
this.currentDungeon = data.instance;
this.isExploring = true;
this.dungeonProgress = 0;
});
// Listen for encounter response
this.game.socket.on('encounter_data', (data) => {
console.log('[DUNGEON SYSTEM] Encounter received:', data);
this.currentRoom = data.encounter;
this.dungeonProgress++;
});
// Listen for dungeon completion response
this.game.socket.on('dungeon_completed', (data) => {
console.log('[DUNGEON SYSTEM] Dungeon completed:', data);
// Reset dungeon state
this.currentDungeon = null;
this.currentRoom = null;
this.isExploring = false;
this.dungeonProgress = 0;
});
// Listen for dungeon status response
this.game.socket.on('dungeon_status', (data) => {
console.log('[DUNGEON SYSTEM] Dungeon status received:', data);
});
console.log('[DUNGEON SYSTEM] Socket event listeners set up');
}
/**
* Load dungeon data from server using Socket.IO packets
*/
async loadServerData() {
try {
console.log('[DUNGEON SYSTEM] Loading dungeon data from server via packets...');
if (!this.game.socket) {
console.error('[DUNGEON SYSTEM] No socket connection available');
return;
}
// Request dungeons from server
this.game.socket.emit('get_dungeons');
// Request room types from server
this.game.socket.emit('get_room_types');
// Request enemy templates from server
this.game.socket.emit('get_enemy_templates');
console.log('[DUNGEON SYSTEM] Server data requests sent via packets');
} catch (error) {
console.error('[DUNGEON SYSTEM] Error loading server data:', error);
}
}
/**
* Get all available dungeons
*/
getAllDungeons() {
return this.serverDungeons;
}
/**
* Get dungeons by difficulty
*/
getDungeonsByDifficulty(difficulty) {
return this.serverDungeons.filter(dungeon => dungeon.difficulty === difficulty);
}
/**
* Get specific dungeon by ID
*/
getDungeon(dungeonId) {
return this.serverDungeons.find(dungeon => dungeon.id === dungeonId);
}
/**
* Get room type by ID
*/
getRoomType(roomTypeId) {
return this.roomTypes[roomTypeId];
}
/**
* Get enemy template by ID
*/
getEnemyTemplate(enemyId) {
return this.enemyTemplates[enemyId];
}
/**
* Start exploring a dungeon using Socket.IO packets
*/
async startDungeon(dungeonId) {
try {
console.log(`[DUNGEON SYSTEM] Starting dungeon: ${dungeonId}`);
if (!this.game.socket) {
console.error('[DUNGEON SYSTEM] No socket connection available');
return null;
}
// Send packet to start dungeon
this.game.socket.emit('start_dungeon', {
dungeonId: dungeonId,
userId: this.game.player?.id || 'anonymous'
});
console.log('[DUNGEON SYSTEM] Dungeon start packet sent');
return true;
} catch (error) {
console.error('[DUNGEON SYSTEM] Error starting dungeon:', error);
return null;
}
}
/**
* Process current room encounter using Socket.IO packets
*/
async processEncounter() {
if (!this.currentDungeon || !this.isExploring) {
console.warn('[DUNGEON SYSTEM] No active dungeon to process');
return null;
}
try {
console.log(`[DUNGEON SYSTEM] Processing encounter for dungeon: ${this.currentDungeon.id}`);
if (!this.game.socket) {
console.error('[DUNGEON SYSTEM] No socket connection available');
return null;
}
// Send packet to process encounter
this.game.socket.emit('process_encounter', {
instanceId: this.currentDungeon.id,
userId: this.game.player?.id || 'anonymous'
});
console.log('[DUNGEON SYSTEM] Encounter process packet sent');
return true;
} catch (error) {
console.error('[DUNGEON SYSTEM] Error processing encounter:', error);
return null;
}
}
/**
* Complete current dungeon using Socket.IO packets
*/
async completeDungeon() {
if (!this.currentDungeon || !this.isExploring) {
console.warn('[DUNGEON SYSTEM] No active dungeon to complete');
return null;
}
try {
console.log(`[DUNGEON SYSTEM] Completing dungeon: ${this.currentDungeon.id}`);
if (!this.game.socket) {
console.error('[DUNGEON SYSTEM] No socket connection available');
return null;
}
// Send packet to complete dungeon
this.game.socket.emit('complete_dungeon', {
instanceId: this.currentDungeon.id,
userId: this.game.player?.id || 'anonymous'
});
console.log('[DUNGEON SYSTEM] Dungeon completion packet sent');
return true;
} catch (error) {
console.error('[DUNGEON SYSTEM] Error completing dungeon:', error);
return null;
}
}
/**
* Get player's current dungeon status using Socket.IO packets
*/
async getDungeonStatus() {
try {
if (!this.game.socket) {
console.error('[DUNGEON SYSTEM] No socket connection available');
return null;
}
// Send packet to get dungeon status
this.game.socket.emit('get_dungeon_status', {
userId: this.game.player?.id || 'anonymous'
});
console.log('[DUNGEON SYSTEM] Dungeon status request packet sent');
return true;
} catch (error) {
console.error('[DUNGEON SYSTEM] Error getting dungeon status:', error);
}
return null;
}
/**
* Generate dungeon list UI using server data
*/
generateDungeonList() {
console.log('[DUNGEON SYSTEM] Generating dungeon list UI with server data...');
const dungeonListElement = document.getElementById('dungeonList');
if (!dungeonListElement) {
console.error('[DUNGEON SYSTEM] Dungeon list element not found');
return;
}
// Clear existing content
dungeonListElement.innerHTML = '';
if (!this.serverDungeons || Object.keys(this.serverDungeons).length === 0) {
dungeonListElement.innerHTML = '<p>Loading dungeons from server...</p>';
return;
}
// Generate HTML for each difficulty category
let html = '';
Object.entries(this.serverDungeons).forEach(([difficulty, dungeons]) => {
if (!dungeons || dungeons.length === 0) return;
const difficultyClass = difficulty === 'tutorial' ? 'tutorial' : difficulty;
const difficultyTitle = difficulty === 'tutorial' ? 'Tutorial Dungeons' :
difficulty.charAt(0).toUpperCase() + difficulty.slice(1) + ' Dungeons';
const difficultyIcon = this.getDifficultyIcon(difficulty);
// Add difficulty header
html += `
<h3 class="difficulty-header ${difficultyClass}">
<i class="${difficultyIcon}"></i>
${difficultyTitle}
</h3>
`;
dungeons.forEach(dungeon => {
const canEnter = this.canEnterDungeon(dungeon);
const statusClass = canEnter ? 'available' : 'locked';
const energyCost = dungeon.energyCost || 0;
const healthType = dungeon.healthType || 'player';
const healthIcon = healthType === 'ship' ? '🚀' : '👤';
// Each dungeon in its own individual container using proper CSS classes
html += `
<div class="dungeon-item ${statusClass}" data-dungeon-id="${dungeon.id}">
<div class="dungeon-name">${dungeon.name}</div>
<div class="dungeon-difficulty ${difficulty}">
<i class="${difficultyIcon}"></i> ${difficulty} - ${energyCost} Energy
</div>
<div class="dungeon-description">${dungeon.description}</div>
<div class="health-type">${healthIcon}</div>
<div class="dungeon-enemies">
<strong>Enemies:</strong>
<div class="enemy-list">
${this.generateEnemyList(dungeon.enemyTypes || [])}
</div>
</div>
<button class="dungeon-btn" ${!canEnter ? 'disabled' : ''}
onclick="game.systems.dungeonSystem.startDungeon('${dungeon.id}')">
${canEnter ? 'Enter Dungeon' : 'Locked'}
</button>
</div>
`;
});
});
dungeonListElement.innerHTML = html;
console.log('[DUNGEON SYSTEM] Dungeon list UI generated successfully');
}
/**
* Get difficulty icon for dungeon
*/
getDifficultyIcon(difficulty) {
const icons = {
tutorial: 'fas fa-graduation-cap',
easy: 'fas fa-smile',
medium: 'fas fa-meh',
hard: 'fas fa-frown',
extreme: 'fas fa-skull'
};
return icons[difficulty] || 'fas fa-question';
}
/**
* Generate enemy list HTML for dungeon
*/
generateEnemyList(enemyTypes) {
if (!enemyTypes || enemyTypes.length === 0) {
return '<span class="no-enemies">No enemies</span>';
}
let html = '';
enemyTypes.forEach(enemyType => {
const enemy = this.getEnemyTemplate(enemyType);
if (enemy) {
html += `
<div class="enemy-item">
<span class="enemy-name">${enemy.name}</span>
<div class="enemy-stats">
<span class="health">❤️ ${enemy.health}</span>
<span class="attack">⚔️ ${enemy.attack}</span>
<span class="defense">🛡️ ${enemy.defense}</span>
</div>
</div>
`;
}
});
return html;
}
/**
* Check if player can enter dungeon
*/
canEnterDungeon(dungeon) {
if (!this.game.player) {
console.log('[DUNGEON SYSTEM] No player data available');
return false;
}
const playerLevel = this.game.player.stats?.level || 1;
const minLevel = dungeon.minLevel || 1;
const maxLevel = dungeon.maxLevel || 999;
const energyCost = dungeon.energyCost || 0;
const playerEnergy = this.game.player.stats?.energy || 0;
console.log(`[DUNGEON SYSTEM] Dungeon check for ${dungeon.name}:`, {
playerLevel,
minLevel,
maxLevel,
playerEnergy,
energyCost,
canEnter: playerLevel >= minLevel && playerLevel <= maxLevel && playerEnergy >= energyCost
});
return playerLevel >= minLevel &&
playerLevel <= maxLevel &&
playerEnergy >= energyCost;
}
/**
* Update UI with current dungeon information
*/
updateUI() {
if (this.game.uiManager) {
this.game.uiManager.updateDungeonUI({
currentDungeon: this.currentDungeon,
currentRoom: this.currentRoom,
progress: this.dungeonProgress,
isExploring: this.isExploring
});
}
}
/**
* Initialize system and load server data
*/
async initialize() {
console.log('[DUNGEON SYSTEM] Initializing client dungeon system...');
// Set up socket listeners if not already done
if (!this.game.socket) {
console.warn('[DUNGEON SYSTEM] Socket not available during initialization, will retry...');
// Retry after a short delay
setTimeout(() => {
if (this.game.socket) {
this.setupSocketListeners();
this.loadServerData();
} else {
console.error('[DUNGEON SYSTEM] Socket still not available after retry');
}
}, 1000);
} else {
this.setupSocketListeners();
await this.loadServerData();
}
console.log('[DUNGEON SYSTEM] Client dungeon system initialization complete');
}
}
// Export for use in GameEngine
if (typeof module !== 'undefined' && module.exports) {
module.exports = DungeonSystem;
}