Skip to main content

steel_core/behavior/blocks/building/
conduit_block.rs

1use std::sync::{Arc, Weak};
2
3use crate::{
4    behavior::{
5        BlockBehavior, BlockPlaceContext,
6        block::{BlockEntityCreation, schedule_water_tick_if_waterlogged},
7    },
8    block_entity::{BLOCK_ENTITIES, BlockEntityTicker},
9    entity::ai::path::PathComputationType,
10    fluid::{FluidStateExt as _, get_fluid_state},
11    world::{ScheduledTickAccess, World},
12};
13use steel_macros::block_behavior;
14use steel_registry::block_entity_type::BlockEntityTypeRef;
15use steel_registry::blocks::{
16    BlockRef,
17    block_state_ext::BlockStateExt,
18    properties::{BlockStateProperties, BoolProperty},
19};
20use steel_registry::vanilla_block_entity_types;
21use steel_utils::{BlockPos, BlockStateId, Direction};
22
23/// Behavior for vanilla conduit blocks.
24#[block_behavior]
25pub struct ConduitBlock {
26    block: BlockRef,
27}
28
29const WATERLOGGED: &BoolProperty = &BlockStateProperties::WATERLOGGED;
30
31impl ConduitBlock {
32    /// Creates a new conduit block behavior.
33    #[must_use]
34    pub const fn new(block: BlockRef) -> Self {
35        Self { block }
36    }
37}
38
39impl BlockBehavior for ConduitBlock {
40    fn update_shape(
41        &self,
42        state: BlockStateId,
43        world: &dyn ScheduledTickAccess,
44        pos: BlockPos,
45        _direction: Direction,
46        _neighbor_pos: BlockPos,
47        _neighbor_state: BlockStateId,
48    ) -> BlockStateId {
49        schedule_water_tick_if_waterlogged(state, world, pos);
50
51        state
52    }
53
54    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
55        let replaced_fluid_state = get_fluid_state(context.world, context.place_pos());
56        Some(self.block.default_state().set_value(
57            WATERLOGGED,
58            replaced_fluid_state.is_water() && replaced_fluid_state.is_full(),
59        ))
60    }
61
62    fn new_block_entity(
63        &self,
64        level: Weak<World>,
65        pos: BlockPos,
66        state: BlockStateId,
67    ) -> BlockEntityCreation {
68        BlockEntityCreation::from_registered_factory(BLOCK_ENTITIES.create(
69            &vanilla_block_entity_types::CONDUIT,
70            level,
71            pos,
72            state,
73        ))
74    }
75
76    fn get_block_entity_ticker(
77        &self,
78        _world: &Arc<World>,
79        _state: BlockStateId,
80        block_entity_type: BlockEntityTypeRef,
81    ) -> Option<BlockEntityTicker> {
82        BlockEntityTicker::for_matching_entity_tick(
83            block_entity_type,
84            &vanilla_block_entity_types::CONDUIT,
85        )
86    }
87
88    fn is_pathfindable(
89        &self,
90        _state: BlockStateId,
91        _computation_type: PathComputationType,
92    ) -> bool {
93        false
94    }
95}