Skip to main content

steel_core/worldgen/feature/
state.rs

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