diff --git a/world/src/site2/gen.rs b/world/src/site2/gen.rs index 6fc0aa7e93..59c5776699 100644 --- a/world/src/site2/gen.rs +++ b/world/src/site2/gen.rs @@ -216,6 +216,7 @@ pub enum Fill { Sprite(SpriteKind), RotatedSprite(SpriteKind, u8), RotatedSpriteWithCfg(SpriteKind, u8, SpriteCfg), + ResourceSprite(SpriteKind, u8), Block(Block), Brick(BlockKind, Rgb, u8), Gradient(util::gradient::Gradient, BlockKind), @@ -465,16 +466,18 @@ impl Fill { } else { old_block.with_sprite(*sprite) }), - Fill::RotatedSprite(sprite, ori) => Some(if old_block.is_filled() { - Block::air(*sprite) - .with_ori(*ori) - .unwrap_or_else(|| Block::air(*sprite)) - } else { - old_block - .with_sprite(*sprite) - .with_ori(*ori) - .unwrap_or_else(|| old_block.with_sprite(*sprite)) - }), + Fill::RotatedSprite(sprite, ori) | Fill::ResourceSprite(sprite, ori) => { + Some(if old_block.is_filled() { + Block::air(*sprite) + .with_ori(*ori) + .unwrap_or_else(|| Block::air(*sprite)) + } else { + old_block + .with_sprite(*sprite) + .with_ori(*ori) + .unwrap_or_else(|| old_block.with_sprite(*sprite)) + }) + }, Fill::RotatedSpriteWithCfg(sprite, ori, cfg) => Some({ *sprite_cfg = Some(cfg.clone()); if old_block.is_filled() { @@ -1085,6 +1088,17 @@ impl Painter { .fill(Fill::RotatedSpriteWithCfg(sprite, ori, cfg)) } + /// Places a sprite at the provided location with the provided orientation + /// which will be tracked by rtsim nature if the sprite has an associated + /// [`ChunkResource`]. + pub fn resource_sprite(&self, pos: Vec3, sprite: SpriteKind, ori: u8) { + self.aabb(Aabb { + min: pos, + max: pos + 1, + }) + .fill(Fill::ResourceSprite(sprite, ori)) + } + /// Returns a `PrimitiveRef` of the largest pyramid with a slope of 1 that /// fits in the provided Aabb. pub fn pyramid(&self, aabb: Aabb) -> PrimitiveRef { diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs index 874d87ac91..fd7cf5c2d1 100644 --- a/world/src/site2/mod.rs +++ b/world/src/site2/mod.rs @@ -1656,7 +1656,8 @@ impl Site { let pos = Vec3::new(x, y, z); let mut sprite_cfg = None; - canvas.map(pos, |block| { + + let map = |block| { let current_block = fill.sample_at( &prim_tree, prim, @@ -1671,7 +1672,13 @@ impl Site { } last_block = current_block; current_block.unwrap_or(block) - }); + }; + + match fill { + Fill::ResourceSprite { .. } => canvas.map_resource(pos, map), + _ => canvas.map(pos, map), + }; + if let Some(sprite_cfg) = sprite_cfg { canvas.set_sprite_cfg(pos, sprite_cfg); } diff --git a/world/src/site2/plot/giant_tree.rs b/world/src/site2/plot/giant_tree.rs index e6aa5c832b..96327fb862 100644 --- a/world/src/site2/plot/giant_tree.rs +++ b/world/src/site2/plot/giant_tree.rs @@ -92,6 +92,7 @@ impl Structure for GiantTree { light, fast_noise.get((self.wpos.map(|e| e as f64) * 0.05) * 0.5 + 0.5), ); + let mut rng = rand::thread_rng(); self.tree.walk(|branch, parent| { let aabr = Aabr { min: self.wpos.xy() + branch.get_aabb().min.xy().as_(), @@ -130,8 +131,9 @@ impl Structure for GiantTree { let displacement = (branch_direction * branch.get_leaf_radius()).map(|e| e.round() as i32); let pos = self.wpos + branch_end.as_() + displacement; - if rand::thread_rng().gen_range(0..100) < 7 { - painter.sprite(pos.map(|e| e), SpriteKind::Ironwood); + if rng.gen_bool(0.07) { + let ori = rng.gen_range(0..=3) * 2; + painter.resource_sprite(pos, SpriteKind::Ironwood, ori); } } true