feat(block): implement creaking heart block logic
This commit is contained in:
parent
3fcbf9ba3d
commit
c64d6cca70
136
crates/pumpkin/src/block/blocks/creaking_heart.rs
Normal file
136
crates/pumpkin/src/block/blocks/creaking_heart.rs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pumpkin_data::block_properties::{
|
||||||
|
Axis, BlockProperties, CreakingHeartLikeProperties, CreakingHeartState,
|
||||||
|
};
|
||||||
|
use pumpkin_data::item::Item;
|
||||||
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
|
use pumpkin_data::{Block, BlockStateId};
|
||||||
|
use pumpkin_macros::pumpkin_block;
|
||||||
|
use pumpkin_world::world::BlockFlags;
|
||||||
|
|
||||||
|
use crate::block::entities::creaking_heart::CreakingHeartBlockEntity;
|
||||||
|
use crate::block::{
|
||||||
|
BlockBehaviour, BlockFuture, BrokenArgs, OnNeighborUpdateArgs, OnPlaceArgs, PlacedArgs,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[pumpkin_block("minecraft:creaking_heart")]
|
||||||
|
pub struct CreakingHeartBlock;
|
||||||
|
|
||||||
|
impl CreakingHeartBlock {
|
||||||
|
fn is_pale_oak_log(block: &Block) -> bool {
|
||||||
|
block.name == "pale_oak_log" || block.name == "stripped_pale_oak_log"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_active_logs(
|
||||||
|
world: &dyn pumpkin_world::world::BlockAccessor,
|
||||||
|
pos: &pumpkin_util::math::position::BlockPos,
|
||||||
|
axis: Axis,
|
||||||
|
) -> bool {
|
||||||
|
let (pos_a, pos_b) = match axis {
|
||||||
|
Axis::X => (pos.west(), pos.east()),
|
||||||
|
Axis::Y => (pos.down(), pos.up()),
|
||||||
|
Axis::Z => (pos.north(), pos.south()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let state_a = world.get_block_state(&pos_a);
|
||||||
|
let state_b = world.get_block_state(&pos_b);
|
||||||
|
|
||||||
|
let block_a = Block::from_state_id(state_a.id);
|
||||||
|
let block_b = Block::from_state_id(state_b.id);
|
||||||
|
|
||||||
|
Self::is_pale_oak_log(block_a) && Self::is_pale_oak_log(block_b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockBehaviour for CreakingHeartBlock {
|
||||||
|
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let mut props =
|
||||||
|
CreakingHeartLikeProperties::from_state_id(args.block.default_state.id, args.block);
|
||||||
|
props.axis = match args.direction {
|
||||||
|
pumpkin_data::BlockDirection::North | pumpkin_data::BlockDirection::South => {
|
||||||
|
Axis::Z
|
||||||
|
}
|
||||||
|
pumpkin_data::BlockDirection::East | pumpkin_data::BlockDirection::West => Axis::X,
|
||||||
|
pumpkin_data::BlockDirection::Up | pumpkin_data::BlockDirection::Down => Axis::Y,
|
||||||
|
};
|
||||||
|
props.creaking_heart_state = CreakingHeartState::Uprooted;
|
||||||
|
props.to_state_id(args.block)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let entity = CreakingHeartBlockEntity::new(*args.position);
|
||||||
|
args.world.add_block_entity(Arc::new(entity));
|
||||||
|
|
||||||
|
let state_id = args.world.get_block_state_id(args.position);
|
||||||
|
let mut props = CreakingHeartLikeProperties::from_state_id(state_id, args.block);
|
||||||
|
|
||||||
|
if Self::check_active_logs(args.world.as_ref(), args.position, props.axis) {
|
||||||
|
props.creaking_heart_state = CreakingHeartState::Dormant;
|
||||||
|
args.world
|
||||||
|
.set_block_state(
|
||||||
|
args.position,
|
||||||
|
props.to_state_id(args.block),
|
||||||
|
BlockFlags::NOTIFY_ALL,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
args.world.play_sound(
|
||||||
|
Sound::BlockCreakingHeartSpawn,
|
||||||
|
SoundCategory::Blocks,
|
||||||
|
&args.position.to_f64(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_neighbor_update<'a>(&'a self, args: OnNeighborUpdateArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let state_id = args.world.get_block_state_id(args.position);
|
||||||
|
let mut props = CreakingHeartLikeProperties::from_state_id(state_id, args.block);
|
||||||
|
|
||||||
|
let active_logs =
|
||||||
|
Self::check_active_logs(args.world.as_ref(), args.position, props.axis);
|
||||||
|
let new_state = if active_logs {
|
||||||
|
if props.creaking_heart_state == CreakingHeartState::Uprooted {
|
||||||
|
args.world.play_sound(
|
||||||
|
Sound::BlockCreakingHeartSpawn,
|
||||||
|
SoundCategory::Blocks,
|
||||||
|
&args.position.to_f64(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
CreakingHeartState::Dormant
|
||||||
|
} else {
|
||||||
|
CreakingHeartState::Uprooted
|
||||||
|
};
|
||||||
|
|
||||||
|
if props.creaking_heart_state != new_state {
|
||||||
|
props.creaking_heart_state = new_state;
|
||||||
|
args.world
|
||||||
|
.set_block_state(
|
||||||
|
args.position,
|
||||||
|
props.to_state_id(args.block),
|
||||||
|
BlockFlags::NOTIFY_ALL,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
args.world.play_sound(
|
||||||
|
Sound::BlockCreakingHeartBreak,
|
||||||
|
SoundCategory::Blocks,
|
||||||
|
&args.position.to_f64(),
|
||||||
|
);
|
||||||
|
args.world
|
||||||
|
.drop_stack(args.position, ItemStack::new(1, &Item::CREAKING_HEART))
|
||||||
|
.await;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -110,6 +110,7 @@ pub mod coral;
|
|||||||
pub mod abstract_wall_mounting;
|
pub mod abstract_wall_mounting;
|
||||||
|
|
||||||
pub mod beacon;
|
pub mod beacon;
|
||||||
|
pub mod creaking_heart;
|
||||||
pub mod decorated_pot;
|
pub mod decorated_pot;
|
||||||
pub mod trial_spawner;
|
pub mod trial_spawner;
|
||||||
pub mod vault;
|
pub mod vault;
|
||||||
|
|||||||
@ -23,6 +23,7 @@ use crate::block::blocks::conduit::ConduitBlock;
|
|||||||
use crate::block::blocks::coral::coral_block::CoralBlock;
|
use crate::block::blocks::coral::coral_block::CoralBlock;
|
||||||
use crate::block::blocks::coral::coral_fan::CoralFanBlock;
|
use crate::block::blocks::coral::coral_fan::CoralFanBlock;
|
||||||
use crate::block::blocks::coral::coral_plant::CoralPlantBlock;
|
use crate::block::blocks::coral::coral_plant::CoralPlantBlock;
|
||||||
|
use crate::block::blocks::creaking_heart::CreakingHeartBlock;
|
||||||
use crate::block::blocks::decorated_pot::DecoratedPotBlock;
|
use crate::block::blocks::decorated_pot::DecoratedPotBlock;
|
||||||
use crate::block::blocks::dirt_path::DirtPathBlock;
|
use crate::block::blocks::dirt_path::DirtPathBlock;
|
||||||
use crate::block::blocks::doors::DoorBlock;
|
use crate::block::blocks::doors::DoorBlock;
|
||||||
@ -254,6 +255,7 @@ pub fn default_registry() -> Arc<BlockRegistry> {
|
|||||||
manager.register(TrialSpawnerBlock);
|
manager.register(TrialSpawnerBlock);
|
||||||
manager.register(VaultBlock);
|
manager.register(VaultBlock);
|
||||||
manager.register(DecoratedPotBlock);
|
manager.register(DecoratedPotBlock);
|
||||||
|
manager.register(CreakingHeartBlock);
|
||||||
manager.register(BushBlock);
|
manager.register(BushBlock);
|
||||||
manager.register(FlowerBlock);
|
manager.register(FlowerBlock);
|
||||||
manager.register(PotatoBlock);
|
manager.register(PotatoBlock);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user