mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-23 00:58:33 +02:00
Start implementing torches and light and add some new tiles
This commit is contained in:
+88
-5
@@ -4,7 +4,19 @@ const ROT = require('./rot.js');
|
||||
* Dungeon generation utilities
|
||||
*/
|
||||
class DungeonGenerator {
|
||||
static generate(width, height) {
|
||||
static generate(width, height, options = {}) {
|
||||
// Default options for dungeon generation
|
||||
const defaultOptions = {
|
||||
floorVariation: 0.01, // 1% secondary floor tiles
|
||||
torchEnabled: true, // Enable torch placement
|
||||
torchDensity: 0.15, // 15% of wall tiles get torches
|
||||
primaryFloor: "'1", // Primary floor tile
|
||||
secondaryFloor: "'2", // Secondary floor tile
|
||||
torchTile: "torch" // Torch tile type
|
||||
};
|
||||
|
||||
const config = { ...defaultOptions, ...options };
|
||||
|
||||
// Create dungeon using ROT.js Map.Digger
|
||||
const digger = new ROT.Map.Digger(width, height, {
|
||||
roomWidth: [3, 9],
|
||||
@@ -22,6 +34,9 @@ class DungeonGenerator {
|
||||
map[y][x] = value;
|
||||
});
|
||||
|
||||
// Create enhanced map with floor variations and torches
|
||||
const enhancedMap = this.enhanceMapWithVariations(map, config);
|
||||
|
||||
// Get rooms that were created
|
||||
const rooms = digger.getRooms();
|
||||
|
||||
@@ -50,20 +65,88 @@ class DungeonGenerator {
|
||||
treasureCenter[1] + Math.floor(Math.random() * 3) - 1
|
||||
];
|
||||
|
||||
// Ensure the treasure is on a floor tile
|
||||
if (map[treasure[1]][treasure[0]] !== 0) {
|
||||
// Ensure the treasure is on a floor tile (check for both floor types)
|
||||
const treasureTile = enhancedMap[treasure[1]][treasure[0]];
|
||||
if (treasureTile !== config.primaryFloor && treasureTile !== config.secondaryFloor) {
|
||||
treasure[0] = treasureCenter[0];
|
||||
treasure[1] = treasureCenter[1];
|
||||
}
|
||||
|
||||
return {
|
||||
map: map,
|
||||
map: enhancedMap, // Return the enhanced map with variations
|
||||
rooms: rooms,
|
||||
entrance: entrance,
|
||||
exit: exit,
|
||||
treasure: treasure
|
||||
treasure: treasure,
|
||||
torches: this.getTorchPositions(enhancedMap, config) // Include torch positions
|
||||
};
|
||||
}
|
||||
|
||||
// Enhanced map creation with floor variations and torch placement
|
||||
static enhanceMapWithVariations(basicMap, config) {
|
||||
const height = basicMap.length;
|
||||
const width = basicMap[0].length;
|
||||
const enhancedMap = Array(height).fill().map(() => Array(width).fill(null));
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const cell = basicMap[y][x];
|
||||
|
||||
if (cell === 0) {
|
||||
// Floor tile - randomly choose primary or secondary
|
||||
if (Math.random() < config.floorVariation) {
|
||||
enhancedMap[y][x] = config.secondaryFloor;
|
||||
} else {
|
||||
enhancedMap[y][x] = config.primaryFloor;
|
||||
}
|
||||
} else if (cell === 1) {
|
||||
// Wall tile - maybe add a torch
|
||||
if (config.torchEnabled && this.shouldPlaceTorch(basicMap, x, y, config.torchDensity)) {
|
||||
enhancedMap[y][x] = config.torchTile;
|
||||
} else {
|
||||
enhancedMap[y][x] = '#'; // Regular wall
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enhancedMap;
|
||||
}
|
||||
|
||||
// Determine if a torch should be placed on this wall tile
|
||||
static shouldPlaceTorch(map, x, y, torchDensity) {
|
||||
// Only place torches on walls that are adjacent to floors (for lighting logic)
|
||||
const height = map.length;
|
||||
const width = map[0].length;
|
||||
|
||||
// Check if this wall tile is adjacent to at least one floor tile
|
||||
const adjacentToFloor = [
|
||||
[-1, 0], [1, 0], [0, -1], [0, 1] // Adjacent cells
|
||||
].some(([dx, dy]) => {
|
||||
const nx = x + dx;
|
||||
const ny = y + dy;
|
||||
return nx >= 0 && nx < width && ny >= 0 && ny < height && map[ny][nx] === 0;
|
||||
});
|
||||
|
||||
return adjacentToFloor && Math.random() < torchDensity;
|
||||
}
|
||||
|
||||
// Get positions of all torches for client-side rendering
|
||||
static getTorchPositions(enhancedMap, config) {
|
||||
const torches = [];
|
||||
const height = enhancedMap.length;
|
||||
const width = enhancedMap[0].length;
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
if (enhancedMap[y][x] === config.torchTile) {
|
||||
torches.push([x, y]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return torches;
|
||||
}
|
||||
|
||||
static getRandomRoomCenter(rooms, excludeFirst = false, excludeLast = false) {
|
||||
if (!rooms || rooms.length === 0) return null;
|
||||
|
||||
+17
-5
@@ -4,7 +4,7 @@ const Monster = require('./monster.js');
|
||||
const DungeonGenerator = require('./dungeon.js');
|
||||
|
||||
class Game {
|
||||
constructor(socketId, mapWidth, mapHeight) {
|
||||
constructor(socketId, mapWidth, mapHeight, gameConfig = {}) {
|
||||
this.socketId = socketId;
|
||||
this.width = mapWidth || 25; // Reduced default size to match client display
|
||||
this.height = mapHeight || 19; // Reduced default size to match client display
|
||||
@@ -16,11 +16,13 @@ class Game {
|
||||
this.fee = 0; // Amount player paid
|
||||
this.visibleTiles = {}; // Will store visible tiles
|
||||
this.fov = null; // FOV calculator
|
||||
this.gameConfig = gameConfig; // Store game configuration
|
||||
this.generateDungeon();
|
||||
}
|
||||
|
||||
generateDungeon() {
|
||||
this.dungeon = DungeonGenerator.generate(this.width, this.height);
|
||||
// Pass game configuration to dungeon generator
|
||||
this.dungeon = DungeonGenerator.generate(this.width, this.height, this.gameConfig);
|
||||
|
||||
if (this.dungeon.entrance) {
|
||||
this.player.moveTo(this.dungeon.entrance[0], this.dungeon.entrance[1]);
|
||||
@@ -33,11 +35,16 @@ class Game {
|
||||
this.monster.moveTo(center[0], center[1]);
|
||||
}
|
||||
|
||||
// Initialize FOV calculator
|
||||
// Initialize FOV calculator - need to check for multiple floor types now
|
||||
this.fov = new ROT.FOV.PreciseShadowcasting(
|
||||
(x, y) => {
|
||||
// Return true if the tile is transparent (can see through it)
|
||||
return this.dungeon.map[y] && this.dungeon.map[y][x] === 0;
|
||||
if (!this.dungeon.map[y] || this.dungeon.map[y][x] === undefined) return false;
|
||||
const tile = this.dungeon.map[y][x];
|
||||
// Check if it's any type of floor tile (primary or secondary)
|
||||
const primaryFloor = this.gameConfig.primaryFloor || "'1";
|
||||
const secondaryFloor = this.gameConfig.secondaryFloor || "'2";
|
||||
return tile === primaryFloor || tile === secondaryFloor;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -83,10 +90,14 @@ class Game {
|
||||
console.log(`Move: (${this.player.x},${this.player.y}) -> (${newX},${newY})`);
|
||||
|
||||
// Check if the move is valid (not into a wall and within map bounds)
|
||||
// Updated to handle new floor tile types
|
||||
const primaryFloor = this.gameConfig.primaryFloor || "'1";
|
||||
const secondaryFloor = this.gameConfig.secondaryFloor || "'2";
|
||||
|
||||
if (this.dungeon &&
|
||||
this.dungeon.map[newY] &&
|
||||
this.dungeon.map[newY][newX] !== undefined &&
|
||||
this.dungeon.map[newY][newX] === 0) { // 0 is floor
|
||||
(this.dungeon.map[newY][newX] === primaryFloor || this.dungeon.map[newY][newX] === secondaryFloor)) {
|
||||
|
||||
this.player.moveTo(newX, newY);
|
||||
console.log(`Player moved to ${newX},${newY} in game for socket ${this.socketId}`);
|
||||
@@ -133,6 +144,7 @@ class Game {
|
||||
entrance: this.dungeon ? this.dungeon.entrance : null,
|
||||
exit: this.dungeon ? this.dungeon.exit : null,
|
||||
treasure: this.dungeon ? this.dungeon.treasure : null,
|
||||
torches: this.dungeon ? this.dungeon.torches : [], // Include torch positions
|
||||
};
|
||||
|
||||
// Debug logging to verify entity data
|
||||
|
||||
+18
-2
@@ -43,10 +43,26 @@ function getAllUsers() {
|
||||
}
|
||||
|
||||
// Add this method to your User function/class
|
||||
User.prototype.startGame = function(width, height) {
|
||||
User.prototype.startGame = function(width, height, gameConfig = {}) {
|
||||
console.log(`Creating new game for user ${this.socketid} with dimensions ${width}x${height}`);
|
||||
|
||||
// Default game configuration - can be customized per user/game
|
||||
const defaultConfig = {
|
||||
playerType: "@", // Options: "@", "@2"
|
||||
treasureType: "$W", // Options: "$W" (Wownero), "$M" (Monero), "$B" (Bitcoin), "$" (Regular)
|
||||
monsterType: "~", // Options: "~", "~2"
|
||||
primaryFloor: "'1", // Main floor tile (99% of floors)
|
||||
secondaryFloor: "'2", // Alt floor tile (1% of floors)
|
||||
floorVariation: 0.01, // Percentage of secondary floor tiles (0.01 = 1%)
|
||||
torchEnabled: true, // Enable/disable torch placement
|
||||
torchDensity: 0.15, // Percentage of wall tiles that get torches (0.15 = 15%)
|
||||
torchTile: "torch" // Torch tile identifier
|
||||
};
|
||||
|
||||
const config = { ...defaultConfig, ...gameConfig };
|
||||
|
||||
try {
|
||||
this.game = new Game(this.socketid, width, height);
|
||||
this.game = new Game(this.socketid, width, height, config);
|
||||
return this.game;
|
||||
} catch (err) {
|
||||
console.error("Error creating game:", err);
|
||||
|
||||
Reference in New Issue
Block a user