steel_core/behavior/blocks/vegetation/
nether_wart.rs1use std::sync::Arc;
2
3use steel_macros::block_behavior;
4use steel_registry::{
5 blocks::{
6 BlockRef,
7 block_state_ext::BlockStateExt,
8 properties::{BlockStateProperties, IntProperty},
9 },
10 item_stack::ItemStack,
11 vanilla_block_tags::BlockTag,
12 vanilla_items,
13};
14use steel_utils::{BlockPos, BlockStateId, types::UpdateFlags};
15
16use crate::{
17 behavior::{
18 BlockBehavior, BlockPlaceContext,
19 blocks::vegetation::{
20 Vegetation,
21 vegetation_block::{survival_update_shape, vegetation_can_survive},
22 },
23 },
24 world::{LevelReader, ScheduledTickAccess, World},
25};
26
27const AGE_PROPERTY: IntProperty = BlockStateProperties::AGE_3;
28
29#[block_behavior]
31pub struct NetherWartBlock {
32 block: BlockRef,
33}
34
35impl NetherWartBlock {
36 #[must_use]
38 pub const fn new(block: BlockRef) -> Self {
39 Self { block }
40 }
41}
42
43impl BlockBehavior for NetherWartBlock {
44 fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
45 if self.may_place_on(
46 context.world.get_block_state(context.place_pos().below()),
47 context.world,
48 context.place_pos().below(),
49 ) {
50 Some(self.block.default_state())
51 } else {
52 None
53 }
54 }
55
56 fn update_shape(
57 &self,
58 state: BlockStateId,
59 world: &dyn ScheduledTickAccess,
60 pos: BlockPos,
61 _direction: steel_utils::Direction,
62 _neighbor_pos: BlockPos,
63 _neighbor_state: BlockStateId,
64 ) -> BlockStateId {
65 survival_update_shape(self, state, world, pos)
66 }
67
68 fn can_survive(&self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
69 vegetation_can_survive(self, state, world, pos)
70 }
71
72 fn random_tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos) {
73 let age = state.get_value(&AGE_PROPERTY);
74 if age > 2 || rand::random_range(0..10) != 0 {
75 return;
76 }
77
78 world.set_block(
79 pos,
80 state.set_value(&AGE_PROPERTY, age + 1),
81 UpdateFlags::UPDATE_CLIENTS,
82 );
83 }
84
85 fn get_clone_item_stack(
86 &self,
87 _block: BlockRef,
88 _state: BlockStateId,
89 _include_data: bool,
90 ) -> Option<ItemStack> {
91 Some(ItemStack::new(&vanilla_items::NETHER_WART))
92 }
93}
94
95impl Vegetation for NetherWartBlock {
96 fn may_place_on(&self, state: BlockStateId, _world: &dyn LevelReader, _pos: BlockPos) -> bool {
97 state.get_block().has_tag(&BlockTag::SUPPORTS_NETHER_WART)
98 }
99}