diff --git a/world/src/land.rs b/world/src/land.rs index 0ac65cb2d4..f6bad2bd0e 100644 --- a/world/src/land.rs +++ b/world/src/land.rs @@ -38,4 +38,11 @@ impl<'a> Land<'a> { pub fn get_chunk_wpos(&self, wpos: Vec2) -> Option<&sim::SimChunk> { self.sim.and_then(|sim| sim.get_wpos(wpos)) } + + pub fn get_nearest_path( + &self, + wpos: Vec2, + ) -> Option<(f32, Vec2, sim::Path, Vec2)> { + self.sim.and_then(|sim| sim.get_nearest_path(wpos)) + } } diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs index dd5a149894..d8f15da7ca 100644 --- a/world/src/site2/mod.rs +++ b/world/src/site2/mod.rs @@ -10,6 +10,7 @@ pub use self::{ util::Dir, }; use crate::{ + sim::Path, site::{namegen::NameGen, SpawnRules}, util::{attempt, DHashSet, Grid, CARDINALS, SQUARE_4, SQUARE_9}, Canvas, Land, @@ -323,9 +324,10 @@ impl Site { Spiral2d::new() .take((SEARCH_RADIUS * 2 + 1).pow(2) as usize) .for_each(|tile| { + let wpos = self.tile_center_wpos(tile); if let Some(kind) = Spiral2d::new() .take(9) - .find_map(|rpos| wpos_is_hazard(land, self.tile_center_wpos(tile) + rpos)) + .find_map(|rpos| wpos_is_hazard(land, wpos + rpos)) { for &rpos in &SQUARE_4 { // `get_mut` doesn't increase generation bounds @@ -334,6 +336,13 @@ impl Site { .map(|tile| tile.kind = TileKind::Hazard(kind)); } } + if let Some((dist, _, Path { width }, _)) = land.get_nearest_path(wpos) { + if dist < 2.0 * width { + self.tiles + .get_mut(tile) + .map(|tile| tile.kind = TileKind::Path); + } + } }); } @@ -1004,7 +1013,7 @@ impl Site { #[allow(clippy::single_match)] match &tile.kind { - TileKind::Plaza => { + TileKind::Plaza | TileKind::Path => { let near_roads = CARDINALS.iter().filter_map(|rpos| { if self.tiles.get(tpos + rpos) == tile { Some(Aabr { diff --git a/world/src/site2/tile.rs b/world/src/site2/tile.rs index 0ffff309f8..5a3b951baa 100644 --- a/world/src/site2/tile.rs +++ b/world/src/site2/tile.rs @@ -181,6 +181,7 @@ pub enum TileKind { Field, Plaza, Road { a: u16, b: u16, w: u16 }, + Path, Building, Castle, Wall(Dir), @@ -219,7 +220,12 @@ impl Tile { pub fn is_natural(&self) -> bool { matches!(self.kind, TileKind::Empty | TileKind::Hazard(_)) } - pub fn is_road(&self) -> bool { matches!(self.kind, TileKind::Plaza | TileKind::Road { .. }) } + pub fn is_road(&self) -> bool { + matches!( + self.kind, + TileKind::Plaza | TileKind::Road { .. } | TileKind::Path + ) + } pub fn is_obstacle(&self) -> bool { matches!(self.kind, TileKind::Hazard(_)) || self.is_building()