Skip to main content

steel_worldgen/
state_resolver.rs

1use steel_registry::blocks::BlockRef;
2use steel_registry::feature;
3use steel_registry::shared_structs;
4use steel_registry::{Registry, RegistryExt};
5use steel_utils::BlockStateId;
6
7/// Resolves vanilla JSON/NBT block-state data to Steel block-state ids.
8pub struct WorldgenStateResolver;
9
10impl WorldgenStateResolver {
11    /// Resolves a block state from data.
12    ///
13    /// # Panics
14    /// Panics if the block is not in the registry or if the state properties are invalid.
15    #[must_use]
16    pub fn block_state_from_data(
17        registry: &Registry,
18        data: &shared_structs::BlockStateData,
19        context: &str,
20    ) -> BlockStateId {
21        let Some(block) = registry.blocks.by_key(&data.name) else {
22            panic!("{context} references unknown block {}", data.name);
23        };
24        Self::block_state_from_parts(
25            registry,
26            block,
27            &data.name,
28            data.properties
29                .iter()
30                .map(|(key, value)| (key.as_str(), value.as_str())),
31            context,
32        )
33    }
34
35    /// Resolves a feature block state from data.
36    ///
37    /// # Panics
38    /// Panics if the state properties are invalid.
39    #[must_use]
40    pub fn feature_block_state_from_data(
41        registry: &Registry,
42        data: &feature::BlockStateData,
43        context: &str,
44    ) -> BlockStateId {
45        Self::block_state_from_parts(
46            registry,
47            data.block,
48            &data.block.key,
49            data.properties.iter().copied(),
50            context,
51        )
52    }
53
54    fn block_state_from_parts<'a>(
55        registry: &Registry,
56        block: BlockRef,
57        block_name: &steel_utils::Identifier,
58        data_properties: impl IntoIterator<Item = (&'a str, &'a str)>,
59        context: &str,
60    ) -> BlockStateId {
61        let Some(state) = registry
62            .blocks
63            .state_id_from_block_defaulted_properties(block, data_properties)
64        else {
65            panic!("{context} references unknown or invalid state {block_name}");
66        };
67        state
68    }
69}