diff --git a/world/src/canvas.rs b/world/src/canvas.rs index b2dae0a3d1..60579ec7b4 100644 --- a/world/src/canvas.rs +++ b/world/src/canvas.rs @@ -70,7 +70,7 @@ impl<'a> CanvasInfo<'a> { // TODO: Very dumb, not this. let seed = pos.x as u32 | (pos.y as u32).wrapping_shl(16); - (wpos, spot, seed) + (wpos, spot, seed ^ 0xA801D82E) }) }) } @@ -193,15 +193,20 @@ impl<'a> Canvas<'a> { /// Note that this function should be called with identitical parameters by /// all chunks within the bounds of the structure to avoid cut-offs /// occurring at chunk borders. Deterministic RNG is advised! - pub fn blit_structure(&mut self, origin: Vec3, structure: &Structure, seed: u32) { - let aabr = Aabr { - min: origin.xy() + structure.get_bounds().min.xy(), - max: origin.xy() + structure.get_bounds().max.xy(), - }; + pub fn blit_structure( + &mut self, + origin: Vec3, + structure: &Structure, + seed: u32, + units: Vec2>, + ) { let info = self.info(); - self.foreach_col_area(aabr, |canvas, wpos2d, col| { + self.foreach_col(|canvas, wpos2d, col| { + let rpos2d = wpos2d - origin.xy(); + let rpos2d = units.x * rpos2d.x + units.y * rpos2d.y; + for z in structure.get_bounds().min.z..structure.get_bounds().max.z { - if let Ok(sblock) = structure.get((wpos2d - origin.xy()).with_z(z)) { + if let Ok(sblock) = structure.get(rpos2d.with_z(z)) { let _ = canvas.map(wpos2d.with_z(origin.z + z), |block| { if let Some(block) = block_from_structure( info.index, diff --git a/world/src/layer/spot.rs b/world/src/layer/spot.rs index a505dd0b76..331bf51a76 100644 --- a/world/src/layer/spot.rs +++ b/world/src/layer/spot.rs @@ -1,6 +1,6 @@ use crate::{ sim::{SimChunk, WorldSim}, - util::seed_expan, + util::{seed_expan, Sampler, UnitChooser}, Canvas, }; use common::{ @@ -132,6 +132,8 @@ pub fn apply_spots_to(canvas: &mut Canvas, _dynamic_rng: &mut impl Rng) { for (spot_wpos2d, spot, seed) in nearby_spots.iter().copied() { let mut rng = ChaChaRng::from_seed(seed_expan::rng_state(seed)); + let units = UnitChooser::new(seed).get(seed).into(); + #[derive(Default)] struct SpotConfig<'a> { // The manifest containing a list of possible base structures for the spot (one will be @@ -171,7 +173,7 @@ pub fn apply_spots_to(canvas: &mut Canvas, _dynamic_rng: &mut impl Rng) { .map(|c| c.alt as i32) .unwrap_or(0), ); - canvas.blit_structure(origin, &structure, seed); + canvas.blit_structure(origin, &structure, seed, units); } // Spawn entities