steel_core/behavior/blocks/vegetation/
dirt_path_block.rs1use std::sync::Arc;
2
3use steel_macros::block_behavior;
4use steel_registry::blocks::BlockRef;
5use steel_registry::blocks::block_state_ext::BlockStateExt;
6use steel_registry::vanilla_block_tags::BlockTag;
7use steel_registry::vanilla_blocks;
8use steel_utils::{BlockPos, BlockStateId, Direction};
9
10use crate::behavior::block::{BlockBehavior, push_entities_up};
11use crate::behavior::context::BlockPlaceContext;
12use crate::entity::ai::path::PathComputationType;
13use crate::world::{LevelReader, ScheduledTickAccess, World};
14
15use super::turn_to_dirt;
16
17#[block_behavior]
19pub struct DirtPathBlock {
20 block: BlockRef,
21}
22
23impl DirtPathBlock {
24 #[must_use]
26 pub const fn new(block: BlockRef) -> Self {
27 Self { block }
28 }
29}
30
31impl BlockBehavior for DirtPathBlock {
32 fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
33 let path_state = self.block.default_state();
34 let pos = context.place_pos();
35 if self.can_survive(path_state, context.world, pos) {
36 Some(path_state)
37 } else {
38 Some(push_entities_up(
39 path_state,
40 vanilla_blocks::DIRT.default_state(),
41 context.world,
42 pos,
43 ))
44 }
45 }
46
47 fn can_survive(&self, _state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
48 let above = world.get_block_state(pos.above());
49 !above.is_solid() || above.get_block().has_tag(&BlockTag::FENCE_GATES)
50 }
51
52 fn update_shape(
53 &self,
54 state: BlockStateId,
55 world: &dyn ScheduledTickAccess,
56 pos: BlockPos,
57 direction: Direction,
58 _neighbor_pos: BlockPos,
59 _neighbor_state: BlockStateId,
60 ) -> BlockStateId {
61 if direction == Direction::Up && !self.can_survive(state, world, pos) {
62 let _ = world.schedule_block_tick_default(pos, self.block, 1);
63 }
64 state
65 }
66
67 fn tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos) {
68 turn_to_dirt(state, world, pos, None);
69 }
70
71 fn is_pathfindable(
72 &self,
73 _state: BlockStateId,
74 _computation_type: PathComputationType,
75 ) -> bool {
76 false
77 }
78}