summaryrefslogtreecommitdiff
path: root/src/content/world/mines.rs
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-31 00:03:32 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-31 00:03:32 -0700
commitd68cf09f7b8e5cb783dc495097c17eaf2a4d5427 (patch)
tree59216cae8c466ad63fa6ff47dc5c7f35c64c23d2 /src/content/world/mines.rs
parent8e128d3ca24fa10dc7d871f7daf6c43eaddc385c (diff)
Diffstat (limited to 'src/content/world/mines.rs')
-rw-r--r--src/content/world/mines.rs152
1 files changed, 128 insertions, 24 deletions
diff --git a/src/content/world/mines.rs b/src/content/world/mines.rs
index ae859bc..6ed4451 100644
--- a/src/content/world/mines.rs
+++ b/src/content/world/mines.rs
@@ -1,41 +1,145 @@
+use glam::{IVec2, Vec2};
+
use crate::{
config::TILESET_SCALING,
content::materials::MaterialId,
proc_gen::{
- Biome,
- tileset_loader::{Tile, TileOrientation, TilesetPixelType},
+ Biome, TileCells,
+ tileset_loader::{Tile, TilesetPixelType},
},
- sim::cell::Cell,
+ sim::{cell::Cell, lib::marching_squares::compute_types},
};
-pub struct MinesBiome;
+const FULL: [bool; (TILESET_SCALING * TILESET_SCALING) as usize] =
+ [true; (TILESET_SCALING * TILESET_SCALING) as usize];
+
+const EMPTY: [bool; (TILESET_SCALING * TILESET_SCALING) as usize] =
+ [false; (TILESET_SCALING * TILESET_SCALING) as usize];
+
+pub struct MinesBiome {
+ pixel_expansion_by_type: [[bool; (TILESET_SCALING * TILESET_SCALING) as usize]; 16],
+}
+
+fn circular_pixel_expansion(
+ c: Vec2,
+ r: f32,
+) -> [bool; (TILESET_SCALING * TILESET_SCALING) as usize] {
+ let rs = r.powi(2);
+ let mut ret = [false; (TILESET_SCALING * TILESET_SCALING) as usize];
+
+ for y in 0..TILESET_SCALING {
+ for x in 0..TILESET_SCALING {
+ // definitely can be optimized a lot
+ let dist = Vec2::new(x as f32, y as f32).distance_squared(c);
+ if dist <= rs {
+ ret[(x + y * TILESET_SCALING) as usize] = true;
+ }
+ }
+ }
+
+ ret
+}
+
+impl MinesBiome {
+ pub fn new() -> Self {
+ MinesBiome {
+ pixel_expansion_by_type: [
+ // empty
+ EMPTY,
+ // BL
+ circular_pixel_expansion(
+ Vec2::new(0.0, TILESET_SCALING as f32 - 1.0),
+ TILESET_SCALING as f32,
+ ),
+ // BR
+ circular_pixel_expansion(
+ Vec2::new(TILESET_SCALING as f32 - 1.0, TILESET_SCALING as f32 - 1.0),
+ TILESET_SCALING as f32,
+ ),
+ // BL BR
+ FULL,
+ // TR
+ circular_pixel_expansion(
+ Vec2::new(TILESET_SCALING as f32 - 1.0, 0.0),
+ TILESET_SCALING as f32,
+ ),
+ // TR BL
+ FULL,
+ // TR BR
+ FULL,
+ // TR BR BL
+ FULL,
+ // TL
+ circular_pixel_expansion(Vec2::new(0.0, 0.0), TILESET_SCALING as f32),
+ // TL BL
+ FULL,
+ // TL BR
+ FULL,
+ // TL BR BL
+ FULL,
+ // TL TR
+ FULL,
+ // TL TR BL
+ FULL,
+ // TL TR BR
+ FULL,
+ // surrounded
+ FULL,
+ ],
+ }
+ }
+}
impl Biome for MinesBiome {
- fn derive_world_from_tile(&self, tile: &Tile) -> Vec<Cell> {
- let tp = TILESET_SCALING.pow(2) as u32;
- let mut cells =
- vec![Cell::void(); (tile.dimensions.short * tile.dimensions.long * tp) as usize];
- let ey = match tile.orientation {
- TileOrientation::Horizontal => tile.dimensions.short,
- TileOrientation::Vertical => tile.dimensions.long,
- };
- let ex = match tile.orientation {
- TileOrientation::Horizontal => tile.dimensions.long,
- TileOrientation::Vertical => tile.dimensions.short,
- };
+ fn derive_world_from_tile(&self, tile: &Tile) -> TileCells {
+ let pixels = tile.size();
+ let marched_pixels = compute_types(tile);
+ let size = pixels * TILESET_SCALING;
+ let mut cells = vec![Cell::void(); (size.x * size.y) as usize];
- for y in 0..ey {
- for x in 0..ex {
- let idx = (x + y * ex) * tp;
- for i in 0..tp {
- cells[(idx + i) as usize] = match tile.pixels[(x + y * ex) as usize] {
- TilesetPixelType::Void => Cell::void(),
- TilesetPixelType::Terrain => Cell::from_material(MaterialId::Dirt),
+ for py in 0..pixels.y {
+ for px in 0..pixels.x {
+ let pixel = tile.pixel_at(IVec2::new(px, py));
+ let variant = marched_pixels[(px + py * (pixels.x + 1)) as usize];
+
+ // let pix = marched_pixels[(px + py * pixels.x) as usize];
+ // let expansion_cells = [Cell::from_material(MaterialId::from_index(
+ // pix % MaterialId::ALL.len() as u8,
+ // ));
+ // (TILESET_SCALING * TILESET_SCALING) as usize];
+
+ // let origin = IVec2::new(px, py) * TILESET_SCALING;
+ // for i in 0..TILESET_SCALING {
+ // let y = i + origin.y;
+ // let row = (y * size.x + origin.x) as usize;
+ // cells[row..row + TILESET_SCALING as usize].copy_from_slice(
+ // &expansion_cells[i as usize..i as usize + TILESET_SCALING as usize],
+ // );
+ // }
+
+ let expansion = self.pixel_expansion_by_type[variant as usize];
+ // TODO optimize
+ let expansion_cells = expansion.map(|c| {
+ if c {
+ Cell::from_material(MaterialId::Dirt)
+ } else {
+ Cell::void()
}
+ });
+
+ let origin = IVec2::new(px, py) * TILESET_SCALING;
+ for i in 0..TILESET_SCALING {
+ let dst_y = i + origin.y;
+ let dst_row = (dst_y * size.x + origin.x) as usize;
+ let src_row = (i * TILESET_SCALING) as usize;
+
+ cells[dst_row..dst_row + TILESET_SCALING as usize].copy_from_slice(
+ &expansion_cells[src_row..src_row + TILESET_SCALING as usize],
+ );
}
}
}
- cells
+ TileCells { size, cells }
}
}