Skip to main content

steel_core/behavior/blocks/building/
composter_block.rs

1//! Comparator-visible composter state.
2//!
3//! Composting interactions and hopper automation are independent mechanics;
4//! comparators read the block-state fill level directly in vanilla.
5
6use steel_macros::block_behavior;
7use steel_registry::blocks::{
8    BlockRef,
9    block_state_ext::BlockStateExt as _,
10    properties::{BlockStateProperties, Direction},
11};
12use steel_utils::{BlockPos, BlockStateId};
13
14use crate::{
15    behavior::{BlockBehavior, BlockPlaceContext},
16    entity::ai::path::PathComputationType,
17    world::LevelReader,
18};
19
20/// Vanilla composter behavior required by analog signal readers.
21#[block_behavior]
22pub struct ComposterBlock {
23    block: BlockRef,
24}
25
26impl ComposterBlock {
27    /// Creates composter behavior.
28    #[must_use]
29    pub const fn new(block: BlockRef) -> Self {
30        Self { block }
31    }
32}
33
34impl BlockBehavior for ComposterBlock {
35    fn get_state_for_placement(&self, _context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
36        Some(self.block.default_state())
37    }
38
39    fn has_analog_output_signal(&self, _state: BlockStateId) -> bool {
40        true
41    }
42
43    fn get_analog_output_signal(
44        &self,
45        state: BlockStateId,
46        _world: &dyn LevelReader,
47        _pos: BlockPos,
48        _direction: Direction,
49    ) -> i32 {
50        i32::from(state.get_value(&BlockStateProperties::LEVEL_COMPOSTER))
51    }
52
53    fn is_pathfindable(
54        &self,
55        _state: BlockStateId,
56        _computation_type: PathComputationType,
57    ) -> bool {
58        false
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use steel_registry::{init_vanilla_registry, vanilla_blocks};
65
66    use super::*;
67    use crate::{
68        behavior::{BLOCK_BEHAVIORS, init_behaviors},
69        test_support::TestLevel,
70    };
71
72    #[test]
73    fn registered_composter_outputs_its_full_state_level() {
74        init_vanilla_registry();
75        init_behaviors();
76        let state = vanilla_blocks::COMPOSTER
77            .default_state()
78            .set_value(&BlockStateProperties::LEVEL_COMPOSTER, 8);
79        let behavior = BLOCK_BEHAVIORS.get_behavior(state.get_block());
80
81        assert!(behavior.has_analog_output_signal(state));
82        assert_eq!(
83            behavior.get_analog_output_signal(
84                state,
85                &TestLevel::default(),
86                BlockPos::ZERO,
87                Direction::North,
88            ),
89            8,
90        );
91    }
92}