mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-31 08:22:33 +00:00
85
pumpkin/src/block/blocks/plant/gourds/attached_stem.rs
Normal file
85
pumpkin/src/block/blocks/plant/gourds/attached_stem.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use async_trait::async_trait;
|
||||
use pumpkin_data::{
|
||||
Block,
|
||||
block_properties::{
|
||||
BlockProperties, EnumVariants, Integer0To7, WallTorchLikeProperties, WheatLikeProperties,
|
||||
},
|
||||
};
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_world::{BlockStateId, world::BlockAccessor};
|
||||
|
||||
use crate::block::{
|
||||
BlockBehaviour, BlockMetadata, CanPlaceAtArgs, GetStateForNeighborUpdateArgs,
|
||||
blocks::plant::PlantBlockBase,
|
||||
};
|
||||
|
||||
type AttachedStemProperties = WallTorchLikeProperties;
|
||||
|
||||
type StemProperties = WheatLikeProperties;
|
||||
pub struct AttachedStemBlock;
|
||||
|
||||
impl BlockMetadata for AttachedStemBlock {
|
||||
fn namespace(&self) -> &'static str {
|
||||
"minecraft"
|
||||
}
|
||||
|
||||
fn ids(&self) -> &'static [&'static str] {
|
||||
&[
|
||||
Block::ATTACHED_PUMPKIN_STEM.name,
|
||||
Block::ATTACHED_MELON_STEM.name,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl AttachedStemBlock {
|
||||
fn get_stem(block: &Block) -> &Block {
|
||||
match block.id {
|
||||
id if id == Block::ATTACHED_PUMPKIN_STEM.id => &Block::PUMPKIN_STEM,
|
||||
id if id == Block::ATTACHED_MELON_STEM.id => &Block::MELON_STEM,
|
||||
_ => &Block::MELON_STEM, // Should never happen
|
||||
}
|
||||
}
|
||||
|
||||
fn get_gourd(block: &Block) -> &Block {
|
||||
match block.id {
|
||||
id if id == Block::ATTACHED_PUMPKIN_STEM.id => &Block::PUMPKIN,
|
||||
id if id == Block::ATTACHED_MELON_STEM.id => &Block::MELON,
|
||||
_ => &Block::MELON, // Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl BlockBehaviour for AttachedStemBlock {
|
||||
async fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
|
||||
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
|
||||
}
|
||||
|
||||
async fn get_state_for_neighbor_update(
|
||||
&self,
|
||||
args: GetStateForNeighborUpdateArgs<'_>,
|
||||
) -> BlockStateId {
|
||||
let props = AttachedStemProperties::from_state_id(args.state_id, args.block);
|
||||
if args.direction.to_horizontal_facing() == Some(props.facing)
|
||||
&& args.neighbor_state_id != Self::get_gourd(args.block).default_state.id
|
||||
{
|
||||
let mut props = StemProperties::default(Self::get_stem(args.block));
|
||||
props.age = Integer0To7::from_index(7);
|
||||
return props.to_state_id(Self::get_stem(args.block));
|
||||
}
|
||||
<Self as PlantBlockBase>::get_state_for_neighbor_update(
|
||||
self,
|
||||
args.world,
|
||||
args.position,
|
||||
args.state_id,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl PlantBlockBase for AttachedStemBlock {
|
||||
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
|
||||
let block = block_accessor.get_block(pos).await;
|
||||
block == &Block::FARMLAND
|
||||
}
|
||||
}
|
||||
2
pumpkin/src/block/blocks/plant/gourds/mod.rs
Normal file
2
pumpkin/src/block/blocks/plant/gourds/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod attached_stem;
|
||||
pub mod stem;
|
||||
134
pumpkin/src/block/blocks/plant/gourds/stem.rs
Normal file
134
pumpkin/src/block/blocks/plant/gourds/stem.rs
Normal file
@@ -0,0 +1,134 @@
|
||||
use crate::block::{
|
||||
BlockBehaviour, BlockMetadata, CanPlaceAtArgs, GetStateForNeighborUpdateArgs, RandomTickArgs,
|
||||
blocks::plant::PlantBlockBase,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use pumpkin_data::{
|
||||
Block, BlockDirection,
|
||||
block_properties::{
|
||||
BlockProperties, EnumVariants, Integer0To7, WallTorchLikeProperties, WheatLikeProperties,
|
||||
},
|
||||
tag,
|
||||
tag::Taggable,
|
||||
};
|
||||
use pumpkin_util::{
|
||||
math::position::BlockPos,
|
||||
random::{RandomGenerator, xoroshiro128::Xoroshiro},
|
||||
};
|
||||
use pumpkin_world::{
|
||||
BlockStateId,
|
||||
world::{BlockAccessor, BlockFlags},
|
||||
};
|
||||
use rand::Rng;
|
||||
|
||||
type StemProperties = WheatLikeProperties;
|
||||
type AttachedStemProperties = WallTorchLikeProperties;
|
||||
|
||||
pub struct StemBlock;
|
||||
|
||||
impl BlockMetadata for StemBlock {
|
||||
fn namespace(&self) -> &'static str {
|
||||
"minecraft"
|
||||
}
|
||||
|
||||
fn ids(&self) -> &'static [&'static str] {
|
||||
&[Block::PUMPKIN_STEM.name, Block::MELON_STEM.name]
|
||||
}
|
||||
}
|
||||
|
||||
impl StemBlock {
|
||||
fn state_with_age(block: &Block, state: u16, age: i32) -> BlockStateId {
|
||||
let mut props = StemProperties::from_state_id(state, block);
|
||||
props.age = Integer0To7::from_index(age as u16);
|
||||
props.to_state_id(block)
|
||||
}
|
||||
|
||||
fn get_attached_stem(dir: BlockDirection, block: &Block) -> BlockStateId {
|
||||
let attached_block = match block.id {
|
||||
id if id == Block::PUMPKIN_STEM.id => &Block::ATTACHED_PUMPKIN_STEM,
|
||||
id if id == Block::MELON_STEM.id => &Block::ATTACHED_MELON_STEM,
|
||||
_ => &Block::ATTACHED_MELON_STEM, // Should never happen
|
||||
};
|
||||
let mut props = AttachedStemProperties::default(attached_block);
|
||||
props.facing = dir.to_horizontal_facing().unwrap();
|
||||
props.to_state_id(attached_block)
|
||||
}
|
||||
|
||||
fn get_gourd(block: &Block) -> &Block {
|
||||
match block.id {
|
||||
id if id == Block::PUMPKIN_STEM.id => &Block::PUMPKIN,
|
||||
id if id == Block::MELON_STEM.id => &Block::MELON,
|
||||
_ => &Block::MELON, // Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl BlockBehaviour for StemBlock {
|
||||
async fn can_place_at(&self, args: CanPlaceAtArgs<'_>) -> bool {
|
||||
<Self as PlantBlockBase>::can_place_at(self, args.block_accessor, args.position).await
|
||||
}
|
||||
|
||||
async fn get_state_for_neighbor_update(
|
||||
&self,
|
||||
args: GetStateForNeighborUpdateArgs<'_>,
|
||||
) -> BlockStateId {
|
||||
<Self as PlantBlockBase>::get_state_for_neighbor_update(
|
||||
self,
|
||||
args.world,
|
||||
args.position,
|
||||
args.state_id,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn random_tick(&self, args: RandomTickArgs<'_>) {
|
||||
// TODO add light level and moisture check
|
||||
let f = 5;
|
||||
if rand::rng().random_range(0..=(25 / f)) == 0 {
|
||||
let (block, state) = args.world.get_block_and_state_id(args.position).await;
|
||||
let props = StemProperties::from_state_id(state, block);
|
||||
let age = i32::from(props.age.to_index());
|
||||
if age < 7 {
|
||||
args.world
|
||||
.set_block_state(
|
||||
args.position,
|
||||
Self::state_with_age(block, state, age + 1),
|
||||
BlockFlags::NOTIFY_NEIGHBORS,
|
||||
)
|
||||
.await;
|
||||
} else {
|
||||
let dir = BlockDirection::random_horizontal(&mut RandomGenerator::Xoroshiro(
|
||||
Xoroshiro::from_seed(rand::rng().random()),
|
||||
));
|
||||
let plant_block_pos = args.position.offset(dir.to_offset());
|
||||
let plant_block_state = args.world.get_block_state(&plant_block_pos).await;
|
||||
let under_block: &Block = args.world.get_block(&plant_block_pos.down()).await;
|
||||
if plant_block_state.is_air()
|
||||
&& (under_block == &Block::FARMLAND
|
||||
|| under_block.is_tagged_with_by_tag(&tag::Block::MINECRAFT_DIRT))
|
||||
{
|
||||
let attached_stem = Self::get_attached_stem(dir, block);
|
||||
let gourd = Self::get_gourd(block);
|
||||
args.world
|
||||
.set_block_state(
|
||||
&plant_block_pos,
|
||||
gourd.default_state.id,
|
||||
BlockFlags::NOTIFY_NEIGHBORS,
|
||||
)
|
||||
.await;
|
||||
args.world
|
||||
.set_block_state(args.position, attached_stem, BlockFlags::NOTIFY_NEIGHBORS)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PlantBlockBase for StemBlock {
|
||||
async fn can_plant_on_top(&self, block_accessor: &dyn BlockAccessor, pos: &BlockPos) -> bool {
|
||||
let block = block_accessor.get_block(pos).await;
|
||||
block == &Block::FARMLAND
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ pub mod crop;
|
||||
pub mod dry_vegetation;
|
||||
pub mod flower;
|
||||
pub mod flowerbed;
|
||||
pub mod gourds;
|
||||
pub mod leaf_litter;
|
||||
pub mod lily_pad;
|
||||
pub mod mushroom_plant;
|
||||
|
||||
@@ -267,6 +267,7 @@ pub trait FlowingFluid {
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO check if source
|
||||
if self.is_same_fluid(fluid, state_id) {
|
||||
let props = FlowingFluidProperties::from_state_id(state_id, fluid);
|
||||
return props.level == Level::L8 && props.falling != Falling::True;
|
||||
|
||||
@@ -107,6 +107,8 @@ use crate::block::blocks::redstone::dispenser::DispenserBlock;
|
||||
use crate::block::blocks::redstone::dropper::DropperBlock;
|
||||
|
||||
use super::BlockIsReplacing;
|
||||
use super::blocks::plant::gourds::attached_stem::AttachedStemBlock;
|
||||
use super::blocks::plant::gourds::stem::StemBlock;
|
||||
use super::fluid::FluidBehaviour;
|
||||
use super::{
|
||||
BrokenArgs, CanPlaceAtArgs, CanUpdateAtArgs, EmitsRedstonePowerArgs, ExplodeArgs,
|
||||
@@ -201,6 +203,8 @@ pub fn default_registry() -> Arc<BlockRegistry> {
|
||||
manager.register(SkullBlock);
|
||||
manager.register(ChiseledBookshelfBlock);
|
||||
manager.register(LecternBlock);
|
||||
manager.register(StemBlock);
|
||||
manager.register(AttachedStemBlock);
|
||||
|
||||
// Fire
|
||||
manager.register(SoulFireBlock);
|
||||
|
||||
Reference in New Issue
Block a user