steel_core/behavior/blocks/building/
conduit_block.rs1use 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#[block_behavior]
25pub struct ConduitBlock {
26 block: BlockRef,
27}
28
29const WATERLOGGED: &BoolProperty = &BlockStateProperties::WATERLOGGED;
30
31impl ConduitBlock {
32 #[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}