mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
feat(block): implement calibrated sculk sensor resonance logic
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use pumpkin_data::BlockStateId;
|
||||
use pumpkin_data::block_properties::{BlockProperties, DecoratedPotLikeProperties};
|
||||
use pumpkin_data::item::Item;
|
||||
use pumpkin_data::item_stack::ItemStack;
|
||||
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||
use pumpkin_data::BlockStateId;
|
||||
use pumpkin_macros::pumpkin_block;
|
||||
|
||||
use crate::block::entities::decorated_pot::DecoratedPotBlockEntity;
|
||||
@@ -20,10 +20,8 @@ pub struct DecoratedPotBlock;
|
||||
impl BlockBehaviour for DecoratedPotBlock {
|
||||
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
|
||||
Box::pin(async move {
|
||||
let mut props = DecoratedPotLikeProperties::from_state_id(
|
||||
args.block.default_state.id,
|
||||
args.block,
|
||||
);
|
||||
let mut props =
|
||||
DecoratedPotLikeProperties::from_state_id(args.block.default_state.id, args.block);
|
||||
props.facing = args
|
||||
.player
|
||||
.living_entity
|
||||
@@ -60,8 +58,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
||||
}
|
||||
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||
&& let Some(pot_entity) =
|
||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
||||
&& let Some(pot_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||
{
|
||||
if pot_entity.try_insert_item(args.item_stack, 1).await {
|
||||
args.world.play_sound(
|
||||
@@ -97,8 +96,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
||||
fn broken<'a>(&'a self, args: BrokenArgs<'a>) -> BlockFuture<'a, ()> {
|
||||
Box::pin(async move {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||
&& let Some(pot_entity) =
|
||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
||||
&& let Some(pot_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||
&& let Some(contained) = pot_entity.take_item().await
|
||||
{
|
||||
args.world.drop_stack(args.position, contained).await;
|
||||
@@ -109,7 +109,9 @@ impl BlockBehaviour for DecoratedPotBlock {
|
||||
SoundCategory::Blocks,
|
||||
&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>> {
|
||||
Box::pin(async move {
|
||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
||||
&& let Some(pot_entity) =
|
||||
block_entity.as_any().downcast_ref::<DecoratedPotBlockEntity>()
|
||||
&& let Some(pot_entity) = block_entity
|
||||
.as_any()
|
||||
.downcast_ref::<DecoratedPotBlockEntity>()
|
||||
{
|
||||
Some(pot_entity.get_comparator_output().await)
|
||||
} else {
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::block::entities::calibrated_sculk_sensor::CalibratedSculkSensorBlockEntity;
|
||||
use crate::block::entities::sculk_sensor::SculkSensorBlockEntity;
|
||||
use crate::block::{
|
||||
BlockBehaviour, BlockFuture, BlockMetadata, EmitsRedstonePowerArgs, GetRedstonePowerArgs,
|
||||
OnPlaceArgs, OnScheduledTickArgs,
|
||||
BlockBehaviour, BlockFuture, BlockMetadata, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
||||
GetRedstonePowerArgs, OnPlaceArgs, OnScheduledTickArgs, PlacedArgs,
|
||||
};
|
||||
use crate::world::World;
|
||||
use pumpkin_data::block_properties::{
|
||||
BlockProperties, CalibratedSculkSensorLikeProperties, SculkSensorLikeProperties,
|
||||
SculkSensorPhase,
|
||||
BlockProperties, CalibratedSculkSensorLikeProperties, HorizontalFacing,
|
||||
SculkSensorLikeProperties, SculkSensorPhase,
|
||||
};
|
||||
use pumpkin_data::{Block, BlockId, BlockStateId};
|
||||
use pumpkin_data::{Block, BlockDirection, BlockId, BlockStateId};
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_world::tick::TickPriority;
|
||||
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 {
|
||||
pub async fn trigger(world: &Arc<World>, pos: &BlockPos, block: &Block, power: u8) {
|
||||
if block.id == BlockId::SCULK_SENSOR {
|
||||
let state = world.get_block_state(pos);
|
||||
let mut props = SculkSensorLikeProperties::from_state_id(state.id, block);
|
||||
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.power = power;
|
||||
world
|
||||
@@ -40,6 +57,28 @@ impl SculkSensorBlock {
|
||||
let state = world.get_block_state(pos);
|
||||
let mut props = CalibratedSculkSensorLikeProperties::from_state_id(state.id, block);
|
||||
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.power = power;
|
||||
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>(
|
||||
&'a self,
|
||||
_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, ()> {
|
||||
Box::pin(async move {
|
||||
let state = args.world.get_block_state(args.position);
|
||||
|
||||
Reference in New Issue
Block a user