Change black empty tile to grass and make it destructable
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { type World, type EntityId, type RunState, type Tile, type Actor, type Vec2 } from "../../core/types";
|
||||
import { TileType } from "../../core/terrain";
|
||||
import { idx } from "./world-logic";
|
||||
import { GAME_CONFIG } from "../../core/config/GameConfig";
|
||||
import { seededRandom } from "../../core/math";
|
||||
@@ -20,7 +21,7 @@ interface Room {
|
||||
export function generateWorld(floor: number, runState: RunState): { world: World; playerId: EntityId } {
|
||||
const width = GAME_CONFIG.map.width;
|
||||
const height = GAME_CONFIG.map.height;
|
||||
const tiles: Tile[] = new Array(width * height).fill(GAME_CONFIG.terrain.wall);
|
||||
const tiles: Tile[] = new Array(width * height).fill(TileType.WALL);
|
||||
|
||||
const random = seededRandom(floor * 12345);
|
||||
|
||||
@@ -103,7 +104,7 @@ function generateRooms(width: number, height: number, tiles: Tile[], floor: numb
|
||||
dungeon.create((x: number, y: number, value: number) => {
|
||||
if (value === 0) {
|
||||
// 0 = floor, 1 = wall
|
||||
tiles[y * width + x] = GAME_CONFIG.terrain.empty;
|
||||
tiles[y * width + x] = TileType.EMPTY;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -148,7 +149,7 @@ function extractRoomsFromCave(width: number, height: number, tiles: Tile[]): Roo
|
||||
for (let y = 1; y < height - 1; y++) {
|
||||
for (let x = 1; x < width - 1; x++) {
|
||||
const idx = y * width + x;
|
||||
if (tiles[idx] === GAME_CONFIG.terrain.empty && !visited.has(idx)) {
|
||||
if (tiles[idx] === TileType.EMPTY && !visited.has(idx)) {
|
||||
const cluster = floodFill(width, height, tiles, x, y, visited);
|
||||
|
||||
// Only consider clusters larger than 20 tiles
|
||||
@@ -206,7 +207,7 @@ function floodFill(width: number, height: number, tiles: Tile[], startX: number,
|
||||
for (const { nx, ny } of neighbors) {
|
||||
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
|
||||
const nIdx = ny * width + nx;
|
||||
if (tiles[nIdx] === GAME_CONFIG.terrain.empty && !visited.has(nIdx)) {
|
||||
if (tiles[nIdx] === TileType.EMPTY && !visited.has(nIdx)) {
|
||||
queue.push(nIdx);
|
||||
}
|
||||
}
|
||||
@@ -220,53 +221,53 @@ function decorate(width: number, height: number, tiles: Tile[], random: () => nu
|
||||
const world = { width, height };
|
||||
|
||||
// Set exit tile
|
||||
tiles[idx(world as any, exit.x, exit.y)] = GAME_CONFIG.terrain.exit;
|
||||
tiles[idx(world as any, exit.x, exit.y)] = TileType.EXIT;
|
||||
|
||||
// Use Simplex noise for natural-looking water distribution
|
||||
const waterNoise = new ROT.Noise.Simplex();
|
||||
// Use Simplex noise for natural-looking grass distribution
|
||||
const grassNoise = new ROT.Noise.Simplex();
|
||||
const decorationNoise = new ROT.Noise.Simplex();
|
||||
|
||||
// Offset noise to get different patterns for water vs decorations
|
||||
const waterOffset = random() * 1000;
|
||||
// Offset noise to get different patterns for grass vs decorations
|
||||
const grassOffset = random() * 1000;
|
||||
const decorOffset = random() * 1000;
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const i = idx(world as any, x, y);
|
||||
|
||||
if (tiles[i] === GAME_CONFIG.terrain.empty) {
|
||||
// Water lakes: use noise to create organic shapes
|
||||
const waterValue = waterNoise.get((x + waterOffset) / 15, (y + waterOffset) / 15);
|
||||
if (tiles[i] === TileType.EMPTY) {
|
||||
// Grass patches: use noise to create organic shapes
|
||||
const grassValue = grassNoise.get((x + grassOffset) / 15, (y + grassOffset) / 15);
|
||||
|
||||
// Create water patches where noise is above threshold
|
||||
if (waterValue > 0.35) {
|
||||
tiles[i] = GAME_CONFIG.terrain.water;
|
||||
// Create grass patches where noise is above threshold
|
||||
if (grassValue > 0.35) {
|
||||
tiles[i] = TileType.GRASS;
|
||||
} else {
|
||||
// Floor decorations (moss/grass): clustered distribution
|
||||
// Floor decorations (moss/rocks): clustered distribution
|
||||
const decoValue = decorationNoise.get((x + decorOffset) / 8, (y + decorOffset) / 8);
|
||||
|
||||
// Dense clusters where noise is high
|
||||
if (decoValue > 0.5) {
|
||||
tiles[i] = GAME_CONFIG.terrain.emptyDeco;
|
||||
tiles[i] = TileType.EMPTY_DECO;
|
||||
} else if (decoValue > 0.3 && random() < 0.3) {
|
||||
// Sparse decorations at medium noise levels
|
||||
tiles[i] = GAME_CONFIG.terrain.emptyDeco;
|
||||
tiles[i] = TileType.EMPTY_DECO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wall decorations (algae near water)
|
||||
// Wall decorations (moss near grass)
|
||||
for (let y = 0; y < height - 1; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const i = idx(world as any, x, y);
|
||||
const nextY = idx(world as any, x, y + 1);
|
||||
|
||||
if (tiles[i] === GAME_CONFIG.terrain.wall &&
|
||||
tiles[nextY] === GAME_CONFIG.terrain.water &&
|
||||
if (tiles[i] === TileType.WALL &&
|
||||
tiles[nextY] === TileType.GRASS &&
|
||||
random() < 0.25) {
|
||||
tiles[i] = GAME_CONFIG.terrain.wallDeco;
|
||||
tiles[i] = TileType.WALL_DECO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user