summaryrefslogtreecommitdiff
path: root/src/proc_gen/mod.rs
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-30 20:10:07 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-30 20:10:07 -0700
commit8e128d3ca24fa10dc7d871f7daf6c43eaddc385c (patch)
treec4b32bfb559941041965418daefda1deffafd8e9 /src/proc_gen/mod.rs
parent56bba5560be95c1e05bfec11e4fc085654f3589d (diff)
wip biome abstraction
Diffstat (limited to 'src/proc_gen/mod.rs')
-rw-r--r--src/proc_gen/mod.rs60
1 files changed, 47 insertions, 13 deletions
diff --git a/src/proc_gen/mod.rs b/src/proc_gen/mod.rs
index 7913d22..049ad1a 100644
--- a/src/proc_gen/mod.rs
+++ b/src/proc_gen/mod.rs
@@ -4,34 +4,68 @@ pub mod tileset_loader;
use glam::IVec2;
use crate::{
- config::CHUNK_SIZE,
+ config::{CHUNK_SIZE, TILESET_SCALING},
proc_gen::{
- herringbone::get_cell_at_position,
- tileset_loader::{Tileset, load_tileset},
+ herringbone::tiles_overlapping,
+ tileset_loader::{Tile, TileOrientation, Tileset, load_tileset},
},
- sim::cell_manager::chunk::Chunk,
+ sim::{cell::Cell, cell_manager::chunk::Chunk, entity::EntityDef},
};
+pub trait Biome {
+ fn derive_world_from_tile(&self, _tile: &Tile) -> Vec<Cell> {
+ Vec::new()
+ }
+ fn derive_entities_from_tile(&self, _tile: &Tile) -> Vec<EntityDef> {
+ Vec::new()
+ }
+}
+
pub struct TilesetWorldGenerator {
tileset: Tileset,
+ biome: Box<dyn Biome>,
}
impl TilesetWorldGenerator {
pub fn generate_chunk(&self, chunk_position: IVec2) -> Chunk {
let mut chunk = Chunk::void();
- for x in 0..CHUNK_SIZE {
- for y in 0..CHUNK_SIZE {
- let cell = get_cell_at_position(
- chunk_position * CHUNK_SIZE + IVec2::new(x, y),
- &self.tileset,
- );
- chunk.set_cell_at_local_position(x as u8, y as u8, cell);
+
+ let a = chunk_position * CHUNK_SIZE;
+ let b = (chunk_position + 1) * CHUNK_SIZE;
+ let tiles = tiles_overlapping(a * TILESET_SCALING, b * TILESET_SCALING, &self.tileset);
+ let world_tiles = tiles.map(|(p, t, o)| (p, self.biome.derive_world_from_tile(t), o));
+
+ for (tp, t, o) in world_tiles {
+ let p = tp * self.tileset.dimensions.short as i32 * TILESET_SCALING;
+ let ta = p.max(a);
+ let tb = p.min(b);
+ if ta.x >= tb.x || ta.y >= tb.y {
+ continue;
+ }
+
+ for y in ta.y..tb.y {
+ for x in ta.x..tb.x {
+ let sw = match o {
+ TileOrientation::Horizontal => {
+ self.tileset.dimensions.long as i32 * TILESET_SCALING
+ }
+ TileOrientation::Vertical => {
+ self.tileset.dimensions.short as i32 * TILESET_SCALING
+ }
+ };
+
+ let src = (y - p.y) * sw + (x - p.x);
+ let dst = (y - a.y) * CHUNK_SIZE + (x - a.x);
+ chunk.cells[dst as usize] = t[src as usize];
+ }
}
}
+
chunk
}
- pub fn new(tileset_path: &str) -> Self {
+
+ pub fn new(tileset_path: &str, biome: Box<dyn Biome>) -> Self {
let tileset = load_tileset(tileset_path);
- TilesetWorldGenerator { tileset }
+ TilesetWorldGenerator { tileset, biome }
}
}