diff --git a/README.md b/README.md
index 44268b6..c6fec3d 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,8 @@ The game is built using Node.js for the backend, with Express and Socket.io for
- **Monster AI**: Evade monster as you navigate the dungeon
- **Treasure hunting**: Find treasure for bonus rewards
- **Wownero integration**: Players pay an entrance fee (10-100 WOW) and can win rewards
+- **Chat system**: Players can communicate in real-time during gameplay
+- **View other players' game states**: Spectate other players' dungeons in real-time
### Technology Stack:
- Backend: Node.js with Express and Socket.io
diff --git a/game.js b/game.js
index 2e68745..02df8d8 100644
--- a/game.js
+++ b/game.js
@@ -157,7 +157,9 @@ class Game {
}
if (this.dungeon.treasure && newX === this.dungeon.treasure[0] && newY === this.dungeon.treasure[1] && !this.player.hasTreasure) {
this.player.hasTreasure = true;
- // Remove treasure from map or mark as collected
+ // Remove treasure from dungeon so it won't be sent in future updates
+ this.dungeon.treasure = null;
+ console.log(`Player ${this.socketId} collected treasure! hasTreasure: ${this.player.hasTreasure}`);
return { status: 'moved', event: 'treasure_found', player: this.player, visibleTiles: this.visibleTiles };
}
@@ -214,19 +216,20 @@ class Game {
// So, no conversion to relative coordinates is needed here for visibleTiles.
// Just ensure this.visibleTiles is correctly populated by updateFOV.
- // console.log("getState called. Player:", this.player, "Visible tiles keys:", Object.keys(this.visibleTiles || {}).length);
-
- return {
+ const state = {
gameState: this.gameState,
player: { ...this.player }, // Send a copy of player object
monster: this.monster ? { ...this.monster } : null, // Send a copy if monster exists
- // items: { ...this.items }, // If you have items, send them too
visibleTiles: { ...this.visibleTiles }, // Send a copy of visible tiles
- // You might also want to send entrance/exit if they are always known or become known
- // entrance: this.dungeon ? this.dungeon.entrance : null,
- // exit: this.dungeon ? this.dungeon.exit : null,
- // treasure: this.dungeon ? this.dungeon.treasure : null
+ entrance: this.dungeon ? this.dungeon.entrance : null,
+ exit: this.dungeon ? this.dungeon.exit : null,
+ treasure: this.dungeon ? this.dungeon.treasure : null,
};
+
+ // Debug logging to verify entity data
+ console.log("🎮 getState() sending entities - Monster:", state.monster, "Entrance:", state.entrance, "Exit:", state.exit, "Treasure:", state.treasure);
+
+ return state;
}
}
@@ -249,4 +252,5 @@ function checkMonsterKill(player, monster) {
return false; // Player is safe
}
-module.exports = Game;
\ No newline at end of file
+module.exports = Game;
+module.exports.checkMonsterKill = checkMonsterKill;
\ No newline at end of file
diff --git a/html/index.html b/html/index.html
index 8de62d3..55aecf5 100644
--- a/html/index.html
+++ b/html/index.html
@@ -19,7 +19,16 @@
+
+
+
+
+
@@ -110,6 +119,21 @@
scrollChat();
});
+ // Handle waiting status updates
+ socket.on('waiting_status', function(data) {
+ console.log("🕒 WAITING STATUS received:", data);
+
+ if (data.status === 'waiting') {
+ $('#messages').append($('
').text(data.message));
+
+ // Show waiting screen
+ if (typeof Game !== 'undefined' && Game.drawWaitingScreen) {
+ Game.drawWaitingScreen();
+ }
+ }
+ scrollChat();
+ });
+
socket.on('message', function(msg) {
$('#messages').append($('').text(msg));
scrollChat();
@@ -120,31 +144,28 @@
console.log("🎮 Game start received with data:", data);
$('#messages').append($('').text("Starting game..."));
- if (typeof Game !== 'undefined') {
+ if (typeof Game !== 'undefined' && Game.stopWaitingScreen) {
Game.stopWaitingScreen();
}
if (!data) {
$('#messages').append($('').text("Error: No game data received from server."));
- if (typeof Game !== 'undefined') Game._drawWelcomeScreen();
+ if (typeof Game !== 'undefined' && Game._drawWelcomeScreen) Game._drawWelcomeScreen();
return;
}
try {
- // Pass player, map, monsters, items, and initialVisibleTiles if available
- var success = Game.startGame(
- data.player,
- data.map,
- data.monsters,
- data.items,
- data.visibleTiles // Pass initial visible tiles from server
- );
+ // Use the original game.js structure
+ var success = Game.startGame(data.player, data.map, data.monster, data.items, data.visibleTiles);
console.log("Game start result:", success ? "SUCCESS" : "FAILED");
if (!success) {
$('#messages').append($('').text("Game start failed. Check console for details."));
- if (typeof Game !== 'undefined') Game._drawWelcomeScreen();
+ if (typeof Game !== 'undefined' && Game._drawWelcomeScreen) Game._drawWelcomeScreen();
} else {
+ // Draw the initial game screen - the game draws itself after startGame()
+ console.log("Game started successfully, initial screen should be drawn");
+
// Shift focus to the game display area after successful game start
$('#game-display').focus();
updateFocusIndicator();
@@ -160,20 +181,8 @@
socket.on('game_update', function(data) {
// console.log("🎮 GAME UPDATE received:", data); // Reduced verbosity
- if (typeof Game !== 'undefined' && Game._gameActive) { // Ensure game is active
- if (data.player) Game._player = data.player;
- if (data.visibleTiles) {
- Game._visibleTiles = data.visibleTiles;
- Game._updateExploredTiles(); // Update explored based on new visibility
- }
- if (data.monster) Game._monster = data.monster; // Update monster data
- if (data.items) Game._items = data.items; // Update items data
- // Potentially update _entrance, _exit, _treasure if they are part of game_update
- // Game._entrance = data.entrance;
- // Game._exit = data.exit;
- // Game._treasure = data.treasure;
-
- Game._drawGameScreen();
+ if (typeof Game !== 'undefined' && Game._gameActive) { // Use Game._gameActive instead of gameState
+ Game.updateGameState(data); // Call updateGameState directly on Game object
} else {
// console.log("Game not active or Game undefined, skipping game_update draw.");
}
@@ -198,7 +207,7 @@
console.log("🔑 'ENTER' COMMAND DETECTED - expecting game_start response");
// Show waiting screen
- if (typeof Game !== 'undefined') {
+ if (typeof Game !== 'undefined' && Game.drawWaitingScreen) {
Game.drawWaitingScreen();
}
// Focus will be shifted in the 'game_start' handler after success
@@ -221,11 +230,11 @@
$('#game-display').attr('tabindex', '-1'); // Make it focusable
$(document).on('keydown', function(e) {
- // console.log(`Keydown event: ${e.key}`, "Active element:", document.activeElement, "Game active?:", Game ? Game._gameActive : "Game undefined");
+ // console.log(`Keydown event: ${e.key}`, "Active element:", document.activeElement, "Game active?:", Game && Game.gameState ? Game.gameState.gameActive : "Game undefined");
if (document.activeElement === $('#game-display')[0]) {
// console.log("Game display has focus.");
- if (Game && Game._gameActive) {
+ if (Game && Game._gameActive) { // Use Game._gameActive
// console.log("Game is active. Processing key:", e.key);
let dx = 0;
let dy = 0;
@@ -248,7 +257,7 @@
// console.log("Key pressed on game display, but not a movement key:", e.key);
}
} else {
- console.log("Game display has focus, but Game is not active. Game object:", Game, "Game._gameActive:", Game ? Game._gameActive : "N/A");
+ console.log("Game display has focus, but Game is not active. Game object:", Game, "Game._gameActive:", Game && Game.gameState ? Game.gameState.gameActive : "N/A");
}
} else if (e.key === 'Enter' && document.activeElement !== $('#chatInput')[0]) {
// console.log("Enter pressed, focusing chat input.");
@@ -374,22 +383,10 @@ $(function() {
document.getElementById('toggle-mode').addEventListener('click', function() {
try {
var button = document.getElementById('toggle-mode');
- // Check current mode and toggle accordingly
- if (Game && Game._isTileMode) { // If currently in Tile Mode
- console.log("Switching to ASCII mode...");
- if (typeof Game.switchToAsciiMode === 'function') {
- Game.switchToAsciiMode();
- button.textContent = 'Switch to Tile Mode';
- } else { console.error("Game.switchToAsciiMode is not defined"); }
- } else if (Game) { // If currently in ASCII mode (or Game object exists and not in tile mode)
- console.log("Switching to TILE mode...");
- if (typeof Game.switchToTileMode === 'function') {
- Game.switchToTileMode();
- button.textContent = 'Switch to ASCII Mode';
- } else { console.error("Game.switchToTileMode is not defined"); }
- } else {
- console.error("Game object not available to toggle mode.");
- }
+ // Display mode switching has been removed - ASCII and tile modes are now equivalent
+ console.log("Display mode switching is no longer needed - modes are equivalent");
+ button.textContent = 'Mode switching disabled';
+ button.disabled = true;
} catch (e) {
console.error("Error switching display mode:", e);
}
@@ -402,15 +399,10 @@ document.getElementById('toggle-mode').addEventListener('click', function() {
socket.on('queue_cancelled', function() {
console.log("Queue cancelled, returning to welcome screen");
- if (typeof Game !== 'undefined') {
- // Try different naming patterns for compatibility
- if (typeof Game._drawWelcomeScreen === 'function') {
- Game._drawWelcomeScreen();
- } else if (typeof Game.drawWelcomeScreen === 'function') {
- Game.drawWelcomeScreen();
- } else {
- console.error("Welcome screen function not found");
- }
+ if (typeof Game !== 'undefined' && Game._drawWelcomeScreen) {
+ Game._drawWelcomeScreen();
+ } else {
+ console.error("Game or _drawWelcomeScreen not available");
}
});
@@ -447,16 +439,32 @@ socket.on('game_over', function(data) {
$('#messages').append($('').text(message));
// Draw lose screen
- Game.drawLoseScreen(reason);
+ if (Game && Game.drawLoseScreen) {
+ Game.drawLoseScreen(reason);
+ }
}
// Set game as inactive to prevent further movement
- Game._gameActive = false;
+ if (Game) {
+ Game._gameActive = false;
+ }
}
scrollChat();
});
+
+
+