steel_core/worldgen/feature/features/
bonus_chest.rs1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3use steel_registry::vanilla_block_entity_types;
4
5const SPAWN_BONUS_CHEST: &str = "minecraft:chests/spawn_bonus_chest";
6
7impl FeatureDecorationRunner {
8 pub(in crate::worldgen::feature) fn place_bonus_chest_feature(
9 region: &WorldGenRegion<'_>,
10 random: &mut WorldgenRandom,
11 origin: BlockPos,
12 ) -> bool {
13 let chunk_x = SectionPos::block_to_section_coord(origin.x());
14 let chunk_z = SectionPos::block_to_section_coord(origin.z());
15 let mut x_positions =
16 Self::shuffled_inclusive_range(chunk_x << 4, (chunk_x << 4) + 15, random);
17 let z_positions = Self::shuffled_inclusive_range(chunk_z << 4, (chunk_z << 4) + 15, random);
18 let chest = vanilla_blocks::CHEST.default_state();
19 let torch = vanilla_blocks::TORCH.default_state();
20
21 for x in x_positions.drain(..) {
22 for &z in &z_positions {
23 let y = region.height_at(HeightmapType::MotionBlockingNoLeaves, x, z);
24 let chest_pos = BlockPos::new(x, y, z);
25 let state = region.block_state(chest_pos);
26 if state.is_air() || state.get_collision_shape_at(chest_pos).is_empty() {
27 let _ = region.set_block_state(chest_pos, chest, UpdateFlags::UPDATE_CLIENTS);
28 Self::set_loot_table_block_entity(
29 region,
30 chest_pos,
31 &vanilla_block_entity_types::CHEST,
32 chest,
33 SPAWN_BONUS_CHEST,
34 random.next_i64(),
35 );
36
37 let torch_behavior = BLOCK_BEHAVIORS.get_behavior(torch.get_block());
38 for direction in Self::VANILLA_HORIZONTAL_DIRECTIONS {
39 let torch_pos = chest_pos.relative(direction);
40 if torch_behavior.can_survive(torch, region, torch_pos) {
41 let _ = region.set_block_state(
42 torch_pos,
43 torch,
44 UpdateFlags::UPDATE_CLIENTS,
45 );
46 }
47 }
48
49 return true;
50 }
51 }
52 }
53
54 false
55 }
56
57 fn shuffled_inclusive_range(start: i32, end: i32, random: &mut WorldgenRandom) -> Vec<i32> {
58 let mut values: Vec<i32> = (start..=end).collect();
59 for i in (1..values.len()).rev() {
60 let bound = (i + 1) as i32;
61 let j = random.next_i32_bounded(bound) as usize;
62 values.swap(i, j);
63 }
64 values
65 }
66}