steel_core/worldgen/feature/
state.rs1use super::prelude::*;
2use super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5 pub(super) fn block_matches_holder_set(block: BlockRef, blocks: &BlockHolderSet) -> bool {
6 match blocks {
7 BlockHolderSet::Tag(tag) => block.has_tag(tag),
8 BlockHolderSet::Entries(entries) => entries.contains(&block),
9 }
10 }
11
12 pub(super) fn fluid_state_from_data(data: &FluidStateData) -> FluidState {
13 let mut amount = Self::default_fluid_amount(data.fluid);
14 let mut falling = false;
15
16 for &(property, value) in data.properties {
17 match property {
18 "falling" if !data.fluid.is_empty => {
19 falling = Self::parse_fluid_bool_property(&data.fluid.key, property, value);
20 }
21 "level" if !data.fluid.is_empty && !data.fluid.is_source => {
22 amount = Self::parse_flowing_fluid_level(&data.fluid.key, value);
23 }
24 _ => {
25 panic!(
26 "fluid state provider references unknown property {property} on {}",
27 data.fluid.key
28 );
29 }
30 }
31 }
32
33 FluidState::new(data.fluid, amount, falling)
34 }
35
36 pub(super) const fn default_fluid_amount(fluid: FluidRef) -> u8 {
37 if fluid.is_empty {
38 0
39 } else if fluid.is_source {
40 8
41 } else {
42 1
43 }
44 }
45
46 pub(super) fn parse_fluid_bool_property(
47 fluid_name: &steel_utils::Identifier,
48 property: &str,
49 value: &str,
50 ) -> bool {
51 match value {
52 "true" => true,
53 "false" => false,
54 _ => panic!(
55 "fluid state provider references invalid boolean value {value} for property {property} on {fluid_name}"
56 ),
57 }
58 }
59
60 pub(super) fn parse_flowing_fluid_level(
61 fluid_name: &steel_utils::Identifier,
62 value: &str,
63 ) -> u8 {
64 let Ok(level) = value.parse::<u8>() else {
65 panic!("fluid state provider references invalid flowing level {value} on {fluid_name}");
66 };
67 assert!(
68 (1..=8).contains(&level),
69 "fluid state provider references flowing level {level} outside 1..=8 on {fluid_name}"
70 );
71 level
72 }
73
74 pub(super) fn legacy_block_from_fluid_state(
75 registry: &Registry,
76 fluid_state: FluidState,
77 ) -> BlockStateId {
78 let Some(block) = registry.blocks.by_key(&fluid_state.fluid_id.block) else {
79 panic!(
80 "fluid {} references unknown legacy block {}",
81 fluid_state.fluid_id.key, fluid_state.fluid_id.block
82 );
83 };
84
85 let mut state = registry.blocks.get_default_state_id(block);
86 if registry
87 .blocks
88 .try_get_property(state, &BlockStateProperties::LEVEL)
89 .is_some()
90 {
91 state = BlockStateProviderEvaluator::set_int_property_by_name(
92 registry,
93 state,
94 "level",
95 i32::from(Self::legacy_fluid_block_level(fluid_state)),
96 );
97 }
98 state
99 }
100
101 pub(super) fn legacy_fluid_block_level(fluid_state: FluidState) -> u8 {
102 if fluid_state.fluid_id.is_source {
103 return 0;
104 }
105
106 let amount = fluid_state.amount.min(8);
107 if fluid_state.falling {
108 8 + (8 - amount)
109 } else {
110 8 - amount
111 }
112 }
113}