Added more side rooms, 8-10 per level
This commit is contained in:
@@ -236,32 +236,57 @@ function generateTrackLevel(width: number, height: number, tiles: Tile[], _floor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. Branch Side Rooms off the main path
|
// 4. Branch Side Rooms off the main path
|
||||||
const numSideRooms = 25 + Math.floor(random() * 15);
|
const targetSideRooms = 10;
|
||||||
for (let i = 0; i < numSideRooms; i++) {
|
let attempts = 0;
|
||||||
|
const maxAttempts = 300;
|
||||||
|
|
||||||
|
while (rooms.length < targetSideRooms + anchors.length && attempts < maxAttempts) {
|
||||||
|
attempts++;
|
||||||
const sourcePathIdx = Math.floor(random() * trackPath.length);
|
const sourcePathIdx = Math.floor(random() * trackPath.length);
|
||||||
const source = trackPath[sourcePathIdx];
|
const source = trackPath[sourcePathIdx];
|
||||||
|
|
||||||
const rw = 5 + Math.floor(random() * 7);
|
const rw = 5 + Math.floor(random() * 5); // Slightly smaller rooms to fit better
|
||||||
const rh = 4 + Math.floor(random() * 7);
|
const rh = 4 + Math.floor(random() * 5);
|
||||||
|
|
||||||
const side = random() < 0.5 ? -1 : 1;
|
// Try multiple offsets to find a gap
|
||||||
|
const distances = [5, 6, 7, 8];
|
||||||
|
const sides = [-1, 1];
|
||||||
|
let placed = false;
|
||||||
|
|
||||||
|
for (const dist of distances) {
|
||||||
|
for (const side of sides) {
|
||||||
let rx, ry;
|
let rx, ry;
|
||||||
|
if (random() < 0.5) { // Try horizontal offset
|
||||||
if (random() < 0.5) {
|
rx = source.x + (side * dist);
|
||||||
rx = source.x + (side * Math.floor(rw / 2 + 3));
|
|
||||||
ry = source.y - Math.floor(rh / 2);
|
ry = source.y - Math.floor(rh / 2);
|
||||||
} else {
|
} else { // Try vertical offset
|
||||||
rx = source.x - Math.floor(rw / 2);
|
rx = source.x - Math.floor(rw / 2);
|
||||||
ry = source.y + (side * Math.floor(rh / 2 + 3));
|
ry = source.y + (side * dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
rx = Math.max(1, Math.min(width - rw - 1, rx));
|
rx = Math.max(1, Math.min(width - rw - 1, rx));
|
||||||
ry = Math.max(1, Math.min(height - rh - 1, ry));
|
ry = Math.max(1, Math.min(height - rh - 1, ry));
|
||||||
|
|
||||||
const room = { x: rx, y: ry, width: rw, height: rh };
|
const room = { x: rx, y: ry, width: rw, height: rh };
|
||||||
const overlap = rooms.some(r => !(room.x + room.width < r.x - 1 || room.x > r.x + r.width + 1 || room.y + room.height < r.y - 1 || room.y > r.y + r.height + 1));
|
|
||||||
if (overlap) continue;
|
|
||||||
|
|
||||||
|
// 1. Check overlap with existing rooms (strict padding)
|
||||||
|
const overlapRooms = rooms.some(r => !(room.x + room.width < r.x - 1 || room.x > r.x + r.width + 1 || room.y + room.height < r.y - 1 || room.y > r.y + r.height + 1));
|
||||||
|
if (overlapRooms) continue;
|
||||||
|
|
||||||
|
// 2. Check overlap with existing core structures (EMPTY tiles)
|
||||||
|
let overlapEmpty = false;
|
||||||
|
for (let y = ry - 1; y < ry + rh + 1; y++) {
|
||||||
|
for (let x = rx - 1; x < rx + rw + 1; x++) {
|
||||||
|
if (tiles[y * width + x] === TileType.EMPTY) {
|
||||||
|
overlapEmpty = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (overlapEmpty) break;
|
||||||
|
}
|
||||||
|
if (overlapEmpty) continue;
|
||||||
|
|
||||||
|
// Valid spot found!
|
||||||
for (let y = ry + 1; y < ry + rh - 1; y++) {
|
for (let y = ry + 1; y < ry + rh - 1; y++) {
|
||||||
for (let x = rx + 1; x < rx + rw - 1; x++) {
|
for (let x = rx + 1; x < rx + rw - 1; x++) {
|
||||||
tiles[y * width + x] = TileType.EMPTY;
|
tiles[y * width + x] = TileType.EMPTY;
|
||||||
@@ -270,15 +295,29 @@ function generateTrackLevel(width: number, height: number, tiles: Tile[], _floor
|
|||||||
|
|
||||||
digCorridor(width, tiles, source.x, source.y, rx + Math.floor(rw / 2), ry + Math.floor(rh / 2));
|
digCorridor(width, tiles, source.x, source.y, rx + Math.floor(rw / 2), ry + Math.floor(rh / 2));
|
||||||
|
|
||||||
|
// Place door at room boundary
|
||||||
let ex = rx + Math.floor(rw / 2);
|
let ex = rx + Math.floor(rw / 2);
|
||||||
let ey = ry + (source.y <= ry ? 0 : rh - 1);
|
let ey = ry + (source.y <= ry ? 0 : rh - 1);
|
||||||
if (Math.abs(source.x - (rx + rw / 2)) > Math.abs(source.y - (ry + rh / 2))) {
|
if (source.x < rx) {
|
||||||
ex = (source.x <= rx ? 0 : rw - 1) + rx;
|
ex = rx; ey = ry + Math.floor(rh / 2);
|
||||||
ey = ry + Math.floor(rh / 2);
|
} else if (source.x >= rx + rw) {
|
||||||
|
ex = rx + rw - 1; ey = ry + Math.floor(rh / 2);
|
||||||
|
} else if (source.y < ry) {
|
||||||
|
ex = rx + Math.floor(rw / 2); ey = ry;
|
||||||
|
} else if (source.y >= ry + rh) {
|
||||||
|
ex = rx + Math.floor(rw / 2); ey = ry + rh - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles[ey * width + ex] = TileType.DOOR_CLOSED;
|
tiles[ey * width + ex] = TileType.DOOR_CLOSED;
|
||||||
rooms.push(room);
|
rooms.push(room);
|
||||||
|
placed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (placed) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[generator] Final side rooms placed: ${rooms.length - anchors.length} after ${attempts} attempts.`);
|
||||||
|
|
||||||
// Place visual exit at track end
|
// Place visual exit at track end
|
||||||
const lastNode = trackPath[trackPath.length - 1];
|
const lastNode = trackPath[trackPath.length - 1];
|
||||||
@@ -298,9 +337,12 @@ function digCorridor(width: number, tiles: Tile[], x1: number, y1: number, x2: n
|
|||||||
} else if (currY !== y2) {
|
} else if (currY !== y2) {
|
||||||
currY += y2 > currY ? 1 : -1;
|
currY += y2 > currY ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
// Only dig if it's currently a wall
|
||||||
|
if (tiles[currY * width + currX] === TileType.WALL) {
|
||||||
tiles[currY * width + currX] = TileType.EMPTY;
|
tiles[currY * width + currX] = TileType.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user