Added more side rooms, 8-10 per level

This commit is contained in:
2026-02-07 14:30:53 +11:00
parent 319ce20b6a
commit 72c4251fc4

View File

@@ -236,50 +236,89 @@ 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
let rx, ry; const distances = [5, 6, 7, 8];
const sides = [-1, 1];
let placed = false;
if (random() < 0.5) { for (const dist of distances) {
rx = source.x + (side * Math.floor(rw / 2 + 3)); for (const side of sides) {
ry = source.y - Math.floor(rh / 2); let rx, ry;
} else { if (random() < 0.5) { // Try horizontal offset
rx = source.x - Math.floor(rw / 2); rx = source.x + (side * dist);
ry = source.y + (side * Math.floor(rh / 2 + 3)); ry = source.y - Math.floor(rh / 2);
} } else { // Try vertical offset
rx = source.x - Math.floor(rw / 2);
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;
for (let y = ry + 1; y < ry + rh - 1; y++) { // 1. Check overlap with existing rooms (strict padding)
for (let x = rx + 1; x < rx + rw - 1; x++) { 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));
tiles[y * width + x] = TileType.EMPTY; 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 x = rx + 1; x < rx + rw - 1; x++) {
tiles[y * width + x] = TileType.EMPTY;
}
}
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 ey = ry + (source.y <= ry ? 0 : rh - 1);
if (source.x < rx) {
ex = rx; 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;
rooms.push(room);
placed = true;
break;
} }
if (placed) break;
} }
digCorridor(width, tiles, source.x, source.y, rx + Math.floor(rw / 2), ry + Math.floor(rh / 2));
let ex = rx + Math.floor(rw / 2);
let ey = ry + (source.y <= ry ? 0 : rh - 1);
if (Math.abs(source.x - (rx + rw / 2)) > Math.abs(source.y - (ry + rh / 2))) {
ex = (source.x <= rx ? 0 : rw - 1) + rx;
ey = ry + Math.floor(rh / 2);
}
tiles[ey * width + ex] = TileType.DOOR_CLOSED;
rooms.push(room);
} }
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];
tiles[lastNode.y * width + lastNode.x] = TileType.EXIT; tiles[lastNode.y * width + lastNode.x] = TileType.EXIT;
@@ -298,7 +337,10 @@ 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;
} }
tiles[currY * width + currX] = TileType.EMPTY; // Only dig if it's currently a wall
if (tiles[currY * width + currX] === TileType.WALL) {
tiles[currY * width + currX] = TileType.EMPTY;
}
} }
} }