feat(block): implement calibrated sculk sensor resonance logic
This commit is contained in:
parent
e9958f5d64
commit
3fcbf9ba3d
@ -1,10 +1,10 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pumpkin_data::BlockStateId;
|
||||||
use pumpkin_data::block_properties::{BlockProperties, DecoratedPotLikeProperties};
|
use pumpkin_data::block_properties::{BlockProperties, DecoratedPotLikeProperties};
|
||||||
use pumpkin_data::item::Item;
|
use pumpkin_data::item::Item;
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
use pumpkin_data::sound::{Sound, SoundCategory};
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
use pumpkin_data::BlockStateId;
|
|
||||||
use pumpkin_macros::pumpkin_block;
|
use pumpkin_macros::pumpkin_block;
|
||||||
|
|
||||||
use crate::block::entities::decorated_pot::DecoratedPotBlockEntity;
|
use crate::block::entities::decorated_pot::DecoratedPotBlockEntity;
|
||||||
@ -20,10 +20,8 @@ pub struct DecoratedPotBlock;
|
|||||||
impl BlockBehaviour for DecoratedPotBlock {
|
impl BlockBehaviour for DecoratedPotBlock {
|
||||||
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
|
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let mut props = DecoratedPotLikeProperties::from_state_id(
|
let mut props =
|
||||||
args.block.default_state.id,
|
DecoratedPotLikeProperties::from_state_id(args.block.default_state.id, args.block);
|
||||||
args.block,
|
|
||||||
);
|
|
||||||
props.facing = args
|
props.facing = args
|
||||||
.player
|
.player
|
||||||
.living_entity
|
.living_entity
|
||||||
@ -60,8 +58,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||||
&& let Some(pot_entity) =
|
&& let Some(pot_entity) = block_entity
|
||||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
.as_any()
|
||||||
|
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||||
{
|
{
|
||||||
if pot_entity.try_insert_item(args.item_stack, 1).await {
|
if pot_entity.try_insert_item(args.item_stack, 1).await {
|
||||||
args.world.play_sound(
|
args.world.play_sound(
|
||||||
@ -97,8 +96,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
|||||||
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||||
&& let Some(pot_entity) =
|
&& let Some(pot_entity) = block_entity
|
||||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
.as_any()
|
||||||
|
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||||
&& let Some(contained) = pot_entity.take_item().await
|
&& let Some(contained) = pot_entity.take_item().await
|
||||||
{
|
{
|
||||||
args.world.drop_stack(args.position, contained).await;
|
args.world.drop_stack(args.position, contained).await;
|
||||||
@ -109,7 +109,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
|||||||
SoundCategory::Blocks,
|
SoundCategory::Blocks,
|
||||||
&args.position.to_f64(),
|
&args.position.to_f64(),
|
||||||
);
|
);
|
||||||
args.world.drop_stack(args.position, ItemStack::new(4, &Item::BRICK)).await;
|
args.world
|
||||||
|
.drop_stack(args.position, ItemStack::new(4, &Item::BRICK))
|
||||||
|
.await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +121,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
|||||||
) -> BlockFuture<'a, Option<u8>> {
|
) -> BlockFuture<'a, Option<u8>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||||
&& let Some(pot_entity) =
|
&& let Some(pot_entity) = block_entity
|
||||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
.as_any()
|
||||||
|
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||||
{
|
{
|
||||||
Some(pot_entity.get_comparator_output().await)
|
Some(pot_entity.get_comparator_output().await)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::block::entities::calibrated_sculk_sensor::CalibratedSculkSensorBlockEntity;
|
||||||
|
use crate::block::entities::sculk_sensor::SculkSensorBlockEntity;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, BlockFuture, BlockMetadata, EmitsRedstonePowerArgs, GetRedstonePowerArgs,
|
BlockBehaviour, BlockFuture, BlockMetadata, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
||||||
OnPlaceArgs, OnScheduledTickArgs,
|
GetRedstonePowerArgs, OnPlaceArgs, OnScheduledTickArgs, PlacedArgs,
|
||||||
};
|
};
|
||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
use pumpkin_data::block_properties::{
|
use pumpkin_data::block_properties::{
|
||||||
BlockProperties, CalibratedSculkSensorLikeProperties, SculkSensorLikeProperties,
|
BlockProperties, CalibratedSculkSensorLikeProperties, HorizontalFacing,
|
||||||
SculkSensorPhase,
|
SculkSensorLikeProperties, SculkSensorPhase,
|
||||||
};
|
};
|
||||||
use pumpkin_data::{Block, BlockId, BlockStateId};
|
use pumpkin_data::{Block, BlockDirection, BlockId, BlockStateId};
|
||||||
use pumpkin_util::math::position::BlockPos;
|
use pumpkin_util::math::position::BlockPos;
|
||||||
use pumpkin_world::tick::TickPriority;
|
use pumpkin_world::tick::TickPriority;
|
||||||
use pumpkin_world::world::BlockFlags;
|
use pumpkin_world::world::BlockFlags;
|
||||||
@ -22,12 +24,27 @@ impl BlockMetadata for SculkSensorBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn horizontal_facing_to_dir(facing: HorizontalFacing) -> BlockDirection {
|
||||||
|
match facing {
|
||||||
|
HorizontalFacing::North => BlockDirection::North,
|
||||||
|
HorizontalFacing::South => BlockDirection::South,
|
||||||
|
HorizontalFacing::West => BlockDirection::West,
|
||||||
|
HorizontalFacing::East => BlockDirection::East,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SculkSensorBlock {
|
impl SculkSensorBlock {
|
||||||
pub async fn trigger(world: &Arc<World>, pos: &BlockPos, block: &Block, power: u8) {
|
pub async fn trigger(world: &Arc<World>, pos: &BlockPos, block: &Block, power: u8) {
|
||||||
if block.id == BlockId::SCULK_SENSOR {
|
if block.id == BlockId::SCULK_SENSOR {
|
||||||
let state = world.get_block_state(pos);
|
let state = world.get_block_state(pos);
|
||||||
let mut props = SculkSensorLikeProperties::from_state_id(state.id, block);
|
let mut props = SculkSensorLikeProperties::from_state_id(state.id, block);
|
||||||
if props.sculk_sensor_phase == SculkSensorPhase::Inactive {
|
if props.sculk_sensor_phase == SculkSensorPhase::Inactive {
|
||||||
|
if let Some(be) = world.get_block_entity(pos)
|
||||||
|
&& let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>()
|
||||||
|
{
|
||||||
|
*sensor_be.last_vibration_frequency.lock().await = power as i32;
|
||||||
|
}
|
||||||
|
|
||||||
props.sculk_sensor_phase = SculkSensorPhase::Active;
|
props.sculk_sensor_phase = SculkSensorPhase::Active;
|
||||||
props.power = power;
|
props.power = power;
|
||||||
world
|
world
|
||||||
@ -40,6 +57,28 @@ impl SculkSensorBlock {
|
|||||||
let state = world.get_block_state(pos);
|
let state = world.get_block_state(pos);
|
||||||
let mut props = CalibratedSculkSensorLikeProperties::from_state_id(state.id, block);
|
let mut props = CalibratedSculkSensorLikeProperties::from_state_id(state.id, block);
|
||||||
if props.sculk_sensor_phase == SculkSensorPhase::Inactive {
|
if props.sculk_sensor_phase == SculkSensorPhase::Inactive {
|
||||||
|
let back_dir = horizontal_facing_to_dir(props.facing).opposite();
|
||||||
|
let back_pos = pos.offset(back_dir.to_offset());
|
||||||
|
let back_state = world.get_block_state(&back_pos);
|
||||||
|
let back_block = Block::from_state_id(back_state.id);
|
||||||
|
|
||||||
|
let calibrated_freq = world
|
||||||
|
.block_registry
|
||||||
|
.get_weak_redstone_power(back_block, world, &back_pos, back_state, back_dir)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if calibrated_freq > 0 && calibrated_freq != power {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(be) = world.get_block_entity(pos)
|
||||||
|
&& let Some(cal_be) = be
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<CalibratedSculkSensorBlockEntity>()
|
||||||
|
{
|
||||||
|
*cal_be.last_vibration_frequency.lock().await = power as i32;
|
||||||
|
}
|
||||||
|
|
||||||
props.sculk_sensor_phase = SculkSensorPhase::Active;
|
props.sculk_sensor_phase = SculkSensorPhase::Active;
|
||||||
props.power = power;
|
props.power = power;
|
||||||
world
|
world
|
||||||
@ -66,6 +105,18 @@ impl BlockBehaviour for SculkSensorBlock {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
|
Box::pin(async move {
|
||||||
|
if args.block.id == BlockId::CALIBRATED_SCULK_SENSOR {
|
||||||
|
let entity = CalibratedSculkSensorBlockEntity::new(*args.position);
|
||||||
|
args.world.add_block_entity(Arc::new(entity));
|
||||||
|
} else if args.block.id == BlockId::SCULK_SENSOR {
|
||||||
|
let entity = SculkSensorBlockEntity::new(*args.position);
|
||||||
|
args.world.add_block_entity(Arc::new(entity));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn emits_redstone_power<'a>(
|
fn emits_redstone_power<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
_args: EmitsRedstonePowerArgs<'a>,
|
_args: EmitsRedstonePowerArgs<'a>,
|
||||||
@ -99,6 +150,25 @@ impl BlockBehaviour for SculkSensorBlock {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_comparator_output<'a>(
|
||||||
|
&'a self,
|
||||||
|
args: GetComparatorOutputArgs<'a>,
|
||||||
|
) -> BlockFuture<'a, Option<u8>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let be = args.world.get_block_entity(args.position)?;
|
||||||
|
if let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>() {
|
||||||
|
return Some(*sensor_be.last_vibration_frequency.lock().await as u8);
|
||||||
|
}
|
||||||
|
if let Some(cal_be) = be
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<CalibratedSculkSensorBlockEntity>()
|
||||||
|
{
|
||||||
|
return Some(*cal_be.last_vibration_frequency.lock().await as u8);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
|
fn on_scheduled_tick<'a>(&'a self, args: OnScheduledTickArgs<'a>) -> BlockFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let state = args.world.get_block_state(args.position);
|
let state = args.world.get_block_state(args.position);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user