fix: allow spectatos to inspect containers
This commit is contained in:
parent
015091de12
commit
4e6d380bbc
@ -27,6 +27,7 @@ pub fn create_generic_9x3(
|
|||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
|
player: &dyn InventoryPlayer,
|
||||||
) -> GenericContainerScreenHandler {
|
) -> GenericContainerScreenHandler {
|
||||||
GenericContainerScreenHandler::new(
|
GenericContainerScreenHandler::new(
|
||||||
WindowType::Generic9x3,
|
WindowType::Generic9x3,
|
||||||
@ -35,6 +36,7 @@ pub fn create_generic_9x3(
|
|||||||
inventory,
|
inventory,
|
||||||
3,
|
3,
|
||||||
9,
|
9,
|
||||||
|
player.is_spectator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +47,7 @@ pub fn create_generic_9x6(
|
|||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
|
player: &dyn InventoryPlayer,
|
||||||
) -> GenericContainerScreenHandler {
|
) -> GenericContainerScreenHandler {
|
||||||
GenericContainerScreenHandler::new(
|
GenericContainerScreenHandler::new(
|
||||||
WindowType::Generic9x6,
|
WindowType::Generic9x6,
|
||||||
@ -53,6 +56,7 @@ pub fn create_generic_9x6(
|
|||||||
inventory,
|
inventory,
|
||||||
6,
|
6,
|
||||||
9,
|
9,
|
||||||
|
player.is_spectator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +67,7 @@ pub fn create_generic_3x3(
|
|||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
|
player: &dyn InventoryPlayer,
|
||||||
) -> GenericContainerScreenHandler {
|
) -> GenericContainerScreenHandler {
|
||||||
GenericContainerScreenHandler::new(
|
GenericContainerScreenHandler::new(
|
||||||
WindowType::Generic3x3,
|
WindowType::Generic3x3,
|
||||||
@ -71,6 +76,7 @@ pub fn create_generic_3x3(
|
|||||||
inventory,
|
inventory,
|
||||||
3,
|
3,
|
||||||
3,
|
3,
|
||||||
|
player.is_spectator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +85,7 @@ pub fn create_crafter_3x3(
|
|||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
|
player: &dyn InventoryPlayer,
|
||||||
) -> GenericContainerScreenHandler {
|
) -> GenericContainerScreenHandler {
|
||||||
GenericContainerScreenHandler::new(
|
GenericContainerScreenHandler::new(
|
||||||
WindowType::Crafter3x3,
|
WindowType::Crafter3x3,
|
||||||
@ -87,6 +94,7 @@ pub fn create_crafter_3x3(
|
|||||||
inventory,
|
inventory,
|
||||||
3,
|
3,
|
||||||
3,
|
3,
|
||||||
|
player.is_spectator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +105,7 @@ pub fn create_hopper(
|
|||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
|
player: &dyn InventoryPlayer,
|
||||||
) -> GenericContainerScreenHandler {
|
) -> GenericContainerScreenHandler {
|
||||||
GenericContainerScreenHandler::new(
|
GenericContainerScreenHandler::new(
|
||||||
WindowType::Hopper,
|
WindowType::Hopper,
|
||||||
@ -105,6 +114,7 @@ pub fn create_hopper(
|
|||||||
inventory,
|
inventory,
|
||||||
1,
|
1,
|
||||||
5,
|
5,
|
||||||
|
player.is_spectator(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +129,8 @@ pub struct GenericContainerScreenHandler {
|
|||||||
pub rows: u8,
|
pub rows: u8,
|
||||||
/// Number of columns in the container grid.
|
/// Number of columns in the container grid.
|
||||||
pub columns: u8,
|
pub columns: u8,
|
||||||
|
/// Whether the opener is in spectator mode.
|
||||||
|
pub is_spectator: bool,
|
||||||
/// Core screen handler behavior (slots, sync ID, listeners).
|
/// Core screen handler behavior (slots, sync ID, listeners).
|
||||||
behaviour: ScreenHandlerBehaviour,
|
behaviour: ScreenHandlerBehaviour,
|
||||||
}
|
}
|
||||||
@ -133,6 +145,7 @@ impl GenericContainerScreenHandler {
|
|||||||
/// - `inventory` - The container's inventory
|
/// - `inventory` - The container's inventory
|
||||||
/// - `rows` - Number of rows in the container
|
/// - `rows` - Number of rows in the container
|
||||||
/// - `columns` - Number of columns in the container
|
/// - `columns` - Number of columns in the container
|
||||||
|
/// - `is_spectator` - Whether the opener is a spectator
|
||||||
fn new(
|
fn new(
|
||||||
screen_type: WindowType,
|
screen_type: WindowType,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
@ -140,16 +153,19 @@ impl GenericContainerScreenHandler {
|
|||||||
inventory: Arc<dyn Inventory>,
|
inventory: Arc<dyn Inventory>,
|
||||||
rows: u8,
|
rows: u8,
|
||||||
columns: u8,
|
columns: u8,
|
||||||
|
is_spectator: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut handler = Self {
|
let mut handler = Self {
|
||||||
inventory,
|
inventory,
|
||||||
rows,
|
rows,
|
||||||
columns,
|
columns,
|
||||||
|
is_spectator,
|
||||||
behaviour: ScreenHandlerBehaviour::new(sync_id, Some(screen_type)),
|
behaviour: ScreenHandlerBehaviour::new(sync_id, Some(screen_type)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Add player entity as a parameter
|
if !is_spectator {
|
||||||
handler.inventory.on_open();
|
handler.inventory.on_open();
|
||||||
|
}
|
||||||
|
|
||||||
handler.add_inventory_slots();
|
handler.add_inventory_slots();
|
||||||
let player_inventory: Arc<dyn Inventory> = player_inventory.clone();
|
let player_inventory: Arc<dyn Inventory> = player_inventory.clone();
|
||||||
@ -190,7 +206,9 @@ impl ScreenHandler for GenericContainerScreenHandler {
|
|||||||
|
|
||||||
fn on_closed(&mut self, player: &dyn InventoryPlayer) {
|
fn on_closed(&mut self, player: &dyn InventoryPlayer) {
|
||||||
self.default_on_closed(player);
|
self.default_on_closed(player);
|
||||||
self.inventory.on_close();
|
if !self.is_spectator && !player.is_spectator() {
|
||||||
|
self.inventory.on_close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Quick move logic for generic containers.
|
/// Quick move logic for generic containers.
|
||||||
|
|||||||
@ -135,6 +135,11 @@ pub trait InventoryPlayer: Send + Sync {
|
|||||||
/// Checks if the player is in creative mode.
|
/// Checks if the player is in creative mode.
|
||||||
fn is_creative(&self) -> bool;
|
fn is_creative(&self) -> bool;
|
||||||
|
|
||||||
|
/// Checks if the player is in spectator mode.
|
||||||
|
fn is_spectator(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the player's experience level.
|
/// Gets the player's experience level.
|
||||||
fn experience_level(&self) -> i32;
|
fn experience_level(&self) -> i32;
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::block::blocks::falling::FallingBlock;
|
use crate::block::blocks::falling::FallingBlock;
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, GetStateForNeighborUpdateArgs, NormalUseArgs, OnPlaceArgs, OnScheduledTickArgs,
|
BlockBehaviour, GetScreenHandlerFactoryArgs, GetStateForNeighborUpdateArgs, NormalUseArgs,
|
||||||
PathComputationType, PlacedArgs,
|
OnPlaceArgs, OnScheduledTickArgs, PathComputationType, PlacedArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
||||||
@ -40,17 +40,32 @@ impl AnvilBlock {
|
|||||||
|
|
||||||
impl BlockBehaviour for AnvilBlock {
|
impl BlockBehaviour for AnvilBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithAnvil as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&AnvilScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithAnvil as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(AnvilScreenFactory))
|
||||||
|
}
|
||||||
|
|
||||||
fn placed(&self, args: PlacedArgs<'_>) {
|
fn placed(&self, args: PlacedArgs<'_>) {
|
||||||
FallingBlock::placed(&FallingBlock, args);
|
FallingBlock::placed(&FallingBlock, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::block::{GetComparatorOutputArgs, OnPlaceArgs, PlacedArgs};
|
use crate::block::{GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, OnPlaceArgs, PlacedArgs};
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
registry::BlockActionResult,
|
registry::BlockActionResult,
|
||||||
{BlockBehaviour, NormalUseArgs},
|
{BlockBehaviour, NormalUseArgs},
|
||||||
@ -28,9 +28,9 @@ impl ScreenHandlerFactory for BarrelScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let handler = create_generic_9x3(sync_id, player_inventory, self.0.clone());
|
let handler = create_generic_9x3(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let concrete_arc = Arc::new(Mutex::new(handler));
|
let concrete_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(concrete_arc as SharedScreenHandler)
|
Some(concrete_arc as SharedScreenHandler)
|
||||||
@ -55,21 +55,34 @@ impl BlockBehaviour for BarrelBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::OpenBarrel as i32,
|
pumpkin_data::statistic::CustomStatistic::OpenBarrel as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&BarrelScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(BarrelScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn placed(&self, args: PlacedArgs<'_>) {
|
fn placed(&self, args: PlacedArgs<'_>) {
|
||||||
let barrel_block_entity = BarrelBlockEntity::new(*args.position);
|
let barrel_block_entity = BarrelBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(barrel_block_entity));
|
args.world.add_block_entity(Arc::new(barrel_block_entity));
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::block::entities::BlockEntity;
|
|
||||||
use pumpkin_data::translation;
|
use pumpkin_data::translation;
|
||||||
use pumpkin_inventory::beacon_screen_handler::create_beacon_handler;
|
use pumpkin_inventory::beacon_screen_handler::create_beacon_handler;
|
||||||
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
||||||
@ -13,7 +12,7 @@ use pumpkin_util::text::TextComponent;
|
|||||||
use pumpkin_world::inventory::Inventory;
|
use pumpkin_world::inventory::Inventory;
|
||||||
|
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs};
|
use crate::block::{BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs};
|
||||||
|
|
||||||
// Create the factory just like ChestScreenFactory
|
// Create the factory just like ChestScreenFactory
|
||||||
struct BeaconScreenFactory(Arc<dyn Inventory>);
|
struct BeaconScreenFactory(Arc<dyn Inventory>);
|
||||||
@ -44,23 +43,34 @@ pub struct BeaconBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for BeaconBlock {
|
impl BlockBehaviour for BeaconBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
let block_entity = args.world.get_block_entity(args.position);
|
self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server: args.server,
|
||||||
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
})
|
||||||
|
.map_or(BlockActionResult::Fail, |factory| {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithBeacon as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
// Extract the inventory from the entity
|
// Open the screen using the factory
|
||||||
let Some(inventory) = block_entity.and_then(BlockEntity::get_inventory) else {
|
args.player
|
||||||
return BlockActionResult::Fail;
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
};
|
|
||||||
|
|
||||||
args.player.increment_stat(
|
BlockActionResult::Success
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
})
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithBeacon as i32,
|
}
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Open the screen using the factory
|
fn get_screen_handler_factory(
|
||||||
args.player
|
&self,
|
||||||
.open_handled_screen(&BeaconScreenFactory(inventory), Some(*args.position));
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
BlockActionResult::Success
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(BeaconScreenFactory(inventory)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,8 @@ use pumpkin_world::inventory::Inventory;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
block::{
|
block::{
|
||||||
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, NormalUseArgs, OnPlaceArgs,
|
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs,
|
||||||
PlacedArgs, registry::BlockActionResult,
|
NormalUseArgs, OnPlaceArgs, PlacedArgs, registry::BlockActionResult,
|
||||||
},
|
},
|
||||||
entity::experience_orb::ExperienceOrbEntity,
|
entity::experience_orb::ExperienceOrbEntity,
|
||||||
};
|
};
|
||||||
@ -78,27 +78,39 @@ pub struct BlastFurnaceBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for BlastFurnaceBlock {
|
impl BlockBehaviour for BlastFurnaceBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.clone().get_inventory()
|
server: args.server,
|
||||||
&& let Some(property_delegate) = block_entity.clone().to_property_delegate()
|
world: args.world,
|
||||||
&& let Some(experience_container) = block_entity.to_experience_container()
|
block: args.block,
|
||||||
{
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithBlastFurnace as i32,
|
pumpkin_data::statistic::CustomStatistic::InteractWithBlastFurnace as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let blasting_furnace_screen_factory = BlastingFurnaceScreenFactory::new(
|
|
||||||
inventory,
|
|
||||||
property_delegate,
|
|
||||||
experience_container,
|
|
||||||
);
|
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&blasting_furnace_screen_factory, Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
crate::block::registry::BlockActionResult::Consume
|
crate::block::registry::BlockActionResult::Consume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.clone().get_inventory()?;
|
||||||
|
let property_delegate = block_entity.clone().to_property_delegate()?;
|
||||||
|
let experience_container = block_entity.to_experience_container()?;
|
||||||
|
Some(Box::new(BlastingFurnaceScreenFactory::new(
|
||||||
|
inventory,
|
||||||
|
property_delegate,
|
||||||
|
experience_container,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = FurnaceLikeProperties::default(args.block);
|
let mut props = FurnaceLikeProperties::default(args.block);
|
||||||
props.facing = args
|
props.facing = args
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::block::{GetComparatorOutputArgs, PathComputationType, PlacedArgs};
|
use crate::block::{
|
||||||
|
GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, PathComputationType, PlacedArgs,
|
||||||
|
};
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
registry::BlockActionResult,
|
registry::BlockActionResult,
|
||||||
{BlockBehaviour, NormalUseArgs},
|
{BlockBehaviour, NormalUseArgs},
|
||||||
@ -48,22 +50,35 @@ pub struct BrewingStandBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for BrewingStandBlock {
|
impl BlockBehaviour for BrewingStandBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.clone().get_inventory()
|
server: args.server,
|
||||||
&& let Some(pd) = block_entity.clone().to_property_delegate()
|
world: args.world,
|
||||||
{
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithBrewingstand as i32,
|
pumpkin_data::statistic::CustomStatistic::InteractWithBrewingstand as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&BrewingScreenFactory(inventory, pd), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.clone().get_inventory()?;
|
||||||
|
let pd = block_entity.to_property_delegate()?;
|
||||||
|
Some(Box::new(BrewingScreenFactory(inventory, pd)))
|
||||||
|
}
|
||||||
|
|
||||||
fn placed(&self, args: PlacedArgs<'_>) {
|
fn placed(&self, args: PlacedArgs<'_>) {
|
||||||
let be = BrewingStandBlockEntity::new(*args.position);
|
let be = BrewingStandBlockEntity::new(*args.position);
|
||||||
args.world.add_block_entity(Arc::new(be));
|
args.world.add_block_entity(Arc::new(be));
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs};
|
use crate::block::{BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs};
|
||||||
|
|
||||||
use pumpkin_data::translation;
|
use pumpkin_data::translation;
|
||||||
use pumpkin_inventory::cartography_table_screen_handler::CartographyTableScreenHandler;
|
use pumpkin_inventory::cartography_table_screen_handler::CartographyTableScreenHandler;
|
||||||
@ -17,16 +17,31 @@ pub struct CartographyTableBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for CartographyTableBlock {
|
impl BlockBehaviour for CartographyTableBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithCartographyTable as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&CartographyTableScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithCartographyTable as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(CartographyTableScreenFactory))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CartographyTableScreenFactory;
|
struct CartographyTableScreenFactory;
|
||||||
|
|||||||
@ -23,8 +23,9 @@ use std::sync::Mutex;
|
|||||||
|
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, BrokenArgs, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
BlockBehaviour, BrokenArgs, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
||||||
GetRedstonePowerArgs, NormalUseArgs, OnPlaceArgs, OnSyncedBlockEventArgs, PathComputationType,
|
GetRedstonePowerArgs, GetScreenHandlerFactoryArgs, NormalUseArgs, OnPlaceArgs,
|
||||||
PlacedArgs, PlayerPlacedArgs, RandomTickArgs, registry::BlockActionResult,
|
OnSyncedBlockEventArgs, PathComputationType, PlacedArgs, PlayerPlacedArgs, RandomTickArgs,
|
||||||
|
registry::BlockActionResult,
|
||||||
};
|
};
|
||||||
use crate::entity::EntityBase;
|
use crate::entity::EntityBase;
|
||||||
use crate::entity::player::Player;
|
use crate::entity::player::Player;
|
||||||
@ -39,12 +40,12 @@ impl ScreenHandlerFactory for ChestScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let concrete_handler = if self.0.size() > 27 {
|
let concrete_handler = if self.0.size() > 27 {
|
||||||
create_generic_9x6(sync_id, player_inventory, self.0.clone())
|
create_generic_9x6(sync_id, player_inventory, self.0.clone(), player)
|
||||||
} else {
|
} else {
|
||||||
create_generic_9x3(sync_id, player_inventory, self.0.clone())
|
create_generic_9x3(sync_id, player_inventory, self.0.clone(), player)
|
||||||
};
|
};
|
||||||
|
|
||||||
let concrete_arc = Arc::new(Mutex::new(concrete_handler));
|
let concrete_arc = Arc::new(Mutex::new(concrete_handler));
|
||||||
@ -165,32 +166,17 @@ fn get_chest_comparator_output(args: &GetComparatorOutputArgs<'_>) -> Option<u8>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
|
fn get_chest_screen_handler_factory(
|
||||||
let stat = if args.block.id == Block::TRAPPED_CHEST.id {
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
pumpkin_data::statistic::CustomStatistic::TriggerTrappedChest
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
} else {
|
|
||||||
pumpkin_data::statistic::CustomStatistic::OpenChest
|
|
||||||
};
|
|
||||||
args.player.increment_stat(
|
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
|
||||||
stat as i32,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
let state = args.world.get_block_state_id(args.position);
|
let state = args.world.get_block_state_id(args.position);
|
||||||
let first_chest = args.world.get_block_entity(args.position);
|
let first_chest = args.world.get_block_entity(args.position);
|
||||||
|
|
||||||
// Spectators cannot open chests with a pending loot table.
|
|
||||||
// The loot is only generated on first open by a non-spectator.
|
|
||||||
let player_is_spectator = args.player.gamemode.load() == GameMode::Spectator;
|
let player_is_spectator = args.player.gamemode.load() == GameMode::Spectator;
|
||||||
if player_is_spectator
|
|
||||||
&& let Some(ref entity) = first_chest
|
|
||||||
&& entity.has_loot_table()
|
|
||||||
{
|
|
||||||
return BlockActionResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unpack deferred loot table on first open (non-spectator only).
|
// Unpack deferred loot table on first open (non-spectator only).
|
||||||
if let Some(ref entity) = first_chest
|
if !player_is_spectator
|
||||||
|
&& let Some(ref entity) = first_chest
|
||||||
&& let Some((loot_key, seed)) = entity.take_loot_table()
|
&& let Some((loot_key, seed)) = entity.take_loot_table()
|
||||||
&& let Some(table) = get_loot_table(&loot_key)
|
&& let Some(table) = get_loot_table(&loot_key)
|
||||||
&& let Some(inv) = entity.clone().get_inventory()
|
&& let Some(inv) = entity.clone().get_inventory()
|
||||||
@ -199,9 +185,7 @@ fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
|
|||||||
inv.mark_dirty();
|
inv.mark_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(first_inventory) = first_chest.and_then(BlockEntity::get_inventory) else {
|
let first_inventory = first_chest.and_then(BlockEntity::get_inventory)?;
|
||||||
return BlockActionResult::Fail;
|
|
||||||
};
|
|
||||||
|
|
||||||
let chest_props = ChestLikeProperties::from_state_id(state);
|
let chest_props = ChestLikeProperties::from_state_id(state);
|
||||||
let connected_towards = match chest_props.r#type {
|
let connected_towards = match chest_props.r#type {
|
||||||
@ -211,13 +195,13 @@ fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if is_chest_blocked(args.world, args.position) {
|
if is_chest_blocked(args.world, args.position) {
|
||||||
return BlockActionResult::Success;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(direction) = connected_towards {
|
if let Some(direction) = connected_towards {
|
||||||
let neighbor_pos = args.position.offset(direction.to_offset());
|
let neighbor_pos = args.position.offset(direction.to_offset());
|
||||||
if is_chest_blocked(args.world, &neighbor_pos) {
|
if is_chest_blocked(args.world, &neighbor_pos) {
|
||||||
return BlockActionResult::Success;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,8 +221,31 @@ fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
|
|||||||
first_inventory
|
first_inventory
|
||||||
};
|
};
|
||||||
|
|
||||||
args.player
|
Some(Box::new(ChestScreenFactory(inventory)))
|
||||||
.open_handled_screen(&ChestScreenFactory(inventory), Some(*args.position));
|
}
|
||||||
|
|
||||||
|
fn normal_use_chest_impl(args: &NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
|
let stat = if args.block.id == Block::TRAPPED_CHEST.id {
|
||||||
|
pumpkin_data::statistic::CustomStatistic::TriggerTrappedChest
|
||||||
|
} else {
|
||||||
|
pumpkin_data::statistic::CustomStatistic::OpenChest
|
||||||
|
};
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
stat as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(factory) = get_chest_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server: args.server,
|
||||||
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
@ -293,6 +300,13 @@ impl BlockBehaviour for ChestBlock {
|
|||||||
normal_use_chest_impl(&args)
|
normal_use_chest_impl(&args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
get_chest_screen_handler_factory(args)
|
||||||
|
}
|
||||||
|
|
||||||
fn broken(&self, args: BrokenArgs<'_>) {
|
fn broken(&self, args: BrokenArgs<'_>) {
|
||||||
broken_chest_impl(&args);
|
broken_chest_impl(&args);
|
||||||
}
|
}
|
||||||
@ -365,6 +379,13 @@ impl BlockBehaviour for CopperChestBlock {
|
|||||||
normal_use_chest_impl(&args)
|
normal_use_chest_impl(&args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
get_chest_screen_handler_factory(args)
|
||||||
|
}
|
||||||
|
|
||||||
fn broken(&self, args: BrokenArgs<'_>) {
|
fn broken(&self, args: BrokenArgs<'_>) {
|
||||||
broken_chest_impl(&args);
|
broken_chest_impl(&args);
|
||||||
}
|
}
|
||||||
@ -428,6 +449,13 @@ impl BlockBehaviour for TrappedChestBlock {
|
|||||||
normal_use_chest_impl(&args)
|
normal_use_chest_impl(&args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
get_chest_screen_handler_factory(args)
|
||||||
|
}
|
||||||
|
|
||||||
fn broken(&self, args: BrokenArgs<'_>) {
|
fn broken(&self, args: BrokenArgs<'_>) {
|
||||||
broken_chest_impl(&args);
|
broken_chest_impl(&args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs};
|
use crate::block::{BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs};
|
||||||
|
|
||||||
use pumpkin_data::translation;
|
use pumpkin_data::translation;
|
||||||
use pumpkin_inventory::crafting::crafting_screen_handler::CraftingTableScreenHandler;
|
use pumpkin_inventory::crafting::crafting_screen_handler::CraftingTableScreenHandler;
|
||||||
@ -17,19 +17,32 @@ pub struct CraftingTableBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for CraftingTableBlock {
|
impl BlockBehaviour for CraftingTableBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithCraftingTable as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
let recipe_manager = args.server.recipe_manager.clone();
|
player: args.player,
|
||||||
args.player.open_handled_screen(
|
}) {
|
||||||
&CraftingTableScreenFactory(recipe_manager),
|
args.player.increment_stat(
|
||||||
Some(*args.position),
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
);
|
pumpkin_data::statistic::CustomStatistic::InteractWithCraftingTable as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let recipe_manager = args.server.recipe_manager.clone();
|
||||||
|
Some(Box::new(CraftingTableScreenFactory(recipe_manager)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CraftingTableScreenFactory(Arc<crate::server::RecipeManager>);
|
struct CraftingTableScreenFactory(Arc<crate::server::RecipeManager>);
|
||||||
|
|||||||
@ -3,7 +3,9 @@ use std::sync::Mutex;
|
|||||||
|
|
||||||
use crate::block::entities::enchanting_table::EnchantingTableBlockEntity;
|
use crate::block::entities::enchanting_table::EnchantingTableBlockEntity;
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs, PathComputationType, PlacedArgs};
|
use crate::block::{
|
||||||
|
BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs, PathComputationType, PlacedArgs,
|
||||||
|
};
|
||||||
use pumpkin_data::{Block, BlockState, BlockStateId, translation};
|
use pumpkin_data::{Block, BlockState, BlockStateId, translation};
|
||||||
use pumpkin_inventory::enchanting::enchanting_screen_handler::EnchantingTableScreenHandler;
|
use pumpkin_inventory::enchanting::enchanting_screen_handler::EnchantingTableScreenHandler;
|
||||||
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
||||||
@ -25,6 +27,23 @@ impl BlockBehaviour for EnchantingTableBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server: args.server,
|
||||||
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
BlockActionResult::Success
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
let mut bookshelf_count = 0;
|
let mut bookshelf_count = 0;
|
||||||
|
|
||||||
for off_z in -1..=1 {
|
for off_z in -1..=1 {
|
||||||
@ -70,14 +89,10 @@ impl BlockBehaviour for EnchantingTableBlock {
|
|||||||
let bookshelf_count = bookshelf_count.min(15);
|
let bookshelf_count = bookshelf_count.min(15);
|
||||||
|
|
||||||
let seed = args.player.enchantment_seed();
|
let seed = args.player.enchantment_seed();
|
||||||
args.player.open_handled_screen(
|
Some(Box::new(EnchantingTableScreenFactory {
|
||||||
&EnchantingTableScreenFactory {
|
bookshelf_count,
|
||||||
bookshelf_count,
|
seed,
|
||||||
seed,
|
}))
|
||||||
},
|
|
||||||
Some(*args.position),
|
|
||||||
);
|
|
||||||
BlockActionResult::Success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
||||||
|
|||||||
@ -3,8 +3,8 @@ use std::sync::Mutex;
|
|||||||
|
|
||||||
use crate::block::entities::ender_chest::EnderChestBlockEntity;
|
use crate::block::entities::ender_chest::EnderChestBlockEntity;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, NormalUseArgs, OnPlaceArgs, OnSyncedBlockEventArgs, PathComputationType,
|
BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs, OnPlaceArgs,
|
||||||
PlacedArgs, registry::BlockActionResult,
|
OnSyncedBlockEventArgs, PathComputationType, PlacedArgs, registry::BlockActionResult,
|
||||||
};
|
};
|
||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
use pumpkin_data::block_properties::LadderLikeProperties;
|
use pumpkin_data::block_properties::LadderLikeProperties;
|
||||||
@ -30,12 +30,14 @@ impl ScreenHandlerFactory for EnderChestScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
if let Some(tracker) = &self.tracker {
|
if !player.is_spectator()
|
||||||
|
&& let Some(tracker) = &self.tracker
|
||||||
|
{
|
||||||
self.inventory.set_tracker(tracker.clone());
|
self.inventory.set_tracker(tracker.clone());
|
||||||
}
|
}
|
||||||
let handler = create_generic_9x3(sync_id, player_inventory, self.inventory.clone());
|
let handler = create_generic_9x3(sync_id, player_inventory, self.inventory.clone(), player);
|
||||||
let concrete_arc = Arc::new(Mutex::new(handler));
|
let concrete_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(concrete_arc as SharedScreenHandler)
|
Some(concrete_arc as SharedScreenHandler)
|
||||||
@ -71,8 +73,32 @@ impl BlockBehaviour for EnderChestBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server: args.server,
|
||||||
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::OpenEnderchest as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
// TODO: PiglinBrain.onGuardedBlockInteracted(serverWorld, player, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockActionResult::Success
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
if is_chest_blocked(args.world, args.position) {
|
if is_chest_blocked(args.world, args.position) {
|
||||||
return BlockActionResult::Success;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_entity = if let Some(be) = args.world.get_block_entity(args.position) {
|
let block_entity = if let Some(be) = args.world.get_block_entity(args.position) {
|
||||||
@ -83,28 +109,16 @@ impl BlockBehaviour for EnderChestBlock {
|
|||||||
be
|
be
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(block_entity) = block_entity
|
let block_entity = block_entity
|
||||||
.as_any()
|
.as_any()
|
||||||
.downcast_ref::<EnderChestBlockEntity>()
|
.downcast_ref::<EnderChestBlockEntity>()?;
|
||||||
{
|
|
||||||
args.player.increment_stat(
|
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
|
||||||
pumpkin_data::statistic::CustomStatistic::OpenEnderchest as i32,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
let tracker = block_entity.get_tracker();
|
|
||||||
let inventory = args.player.ender_chest_inventory();
|
|
||||||
args.player.open_handled_screen(
|
|
||||||
&EnderChestScreenFactory {
|
|
||||||
inventory: inventory.clone(),
|
|
||||||
tracker: Some(tracker),
|
|
||||||
},
|
|
||||||
Some(*args.position),
|
|
||||||
);
|
|
||||||
// TODO: PiglinBrain.onGuardedBlockInteracted(serverWorld, player, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockActionResult::Success
|
let tracker = block_entity.get_tracker();
|
||||||
|
let inventory = args.player.ender_chest_inventory();
|
||||||
|
Some(Box::new(EnderChestScreenFactory {
|
||||||
|
inventory: inventory.clone(),
|
||||||
|
tracker: Some(tracker),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn placed(&self, args: PlacedArgs<'_>) {
|
fn placed(&self, args: PlacedArgs<'_>) {
|
||||||
|
|||||||
@ -17,8 +17,8 @@ use pumpkin_world::inventory::Inventory;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
block::{
|
block::{
|
||||||
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, NormalUseArgs, OnPlaceArgs,
|
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs,
|
||||||
PlacedArgs, registry::BlockActionResult,
|
NormalUseArgs, OnPlaceArgs, PlacedArgs, registry::BlockActionResult,
|
||||||
},
|
},
|
||||||
entity::experience_orb::ExperienceOrbEntity,
|
entity::experience_orb::ExperienceOrbEntity,
|
||||||
};
|
};
|
||||||
@ -77,24 +77,39 @@ pub struct FurnaceBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for FurnaceBlock {
|
impl BlockBehaviour for FurnaceBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.clone().get_inventory()
|
server: args.server,
|
||||||
&& let Some(property_delegate) = block_entity.clone().to_property_delegate()
|
world: args.world,
|
||||||
&& let Some(experience_container) = block_entity.to_experience_container()
|
block: args.block,
|
||||||
{
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithFurnace as i32,
|
pumpkin_data::statistic::CustomStatistic::InteractWithFurnace as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let furnace_screen_factory =
|
|
||||||
FurnaceScreenFactory::new(inventory, property_delegate, experience_container);
|
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&furnace_screen_factory, Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
crate::block::registry::BlockActionResult::Consume
|
crate::block::registry::BlockActionResult::Consume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.clone().get_inventory()?;
|
||||||
|
let property_delegate = block_entity.clone().to_property_delegate()?;
|
||||||
|
let experience_container = block_entity.to_experience_container()?;
|
||||||
|
Some(Box::new(FurnaceScreenFactory::new(
|
||||||
|
inventory,
|
||||||
|
property_delegate,
|
||||||
|
experience_container,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = FurnaceLikeProperties::default(args.block);
|
let mut props = FurnaceLikeProperties::default(args.block);
|
||||||
props.facing = args
|
props.facing = args
|
||||||
|
|||||||
@ -19,8 +19,8 @@ use pumpkin_world::world::BlockAccessor;
|
|||||||
|
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, CanPlaceAtArgs, GetStateForNeighborUpdateArgs, NormalUseArgs, OnPlaceArgs,
|
BlockBehaviour, CanPlaceAtArgs, GetScreenHandlerFactoryArgs, GetStateForNeighborUpdateArgs,
|
||||||
PathComputationType,
|
NormalUseArgs, OnPlaceArgs, PathComputationType,
|
||||||
};
|
};
|
||||||
use pumpkin_data::BlockState;
|
use pumpkin_data::BlockState;
|
||||||
|
|
||||||
@ -31,17 +31,32 @@ pub struct GrindstoneBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for GrindstoneBlock {
|
impl BlockBehaviour for GrindstoneBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithGrindstone as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&GrindstoneScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithGrindstone as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(GrindstoneScreenFactory))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = GrindstoneLikeProperties::from_state_id(args.block.default_state.id);
|
let mut props = GrindstoneLikeProperties::from_state_id(args.block.default_state.id);
|
||||||
(props.face, props.facing) =
|
(props.face, props.facing) =
|
||||||
|
|||||||
@ -3,7 +3,8 @@ use std::sync::Mutex;
|
|||||||
|
|
||||||
use crate::block::blocks::redstone::block_receives_redstone_power;
|
use crate::block::blocks::redstone::block_receives_redstone_power;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
GetComparatorOutputArgs, OnNeighborUpdateArgs, OnPlaceArgs, PathComputationType, PlacedArgs,
|
GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, OnNeighborUpdateArgs, OnPlaceArgs,
|
||||||
|
PathComputationType, PlacedArgs,
|
||||||
};
|
};
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
registry::BlockActionResult,
|
registry::BlockActionResult,
|
||||||
@ -32,9 +33,9 @@ impl ScreenHandlerFactory for HopperBlockScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let concrete_handler = create_hopper(sync_id, player_inventory, self.0.clone());
|
let concrete_handler = create_hopper(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let concrete_arc = Arc::new(Mutex::new(concrete_handler));
|
let concrete_arc = Arc::new(Mutex::new(concrete_handler));
|
||||||
|
|
||||||
Some(concrete_arc as SharedScreenHandler)
|
Some(concrete_arc as SharedScreenHandler)
|
||||||
@ -55,21 +56,34 @@ type HopperLikeProperties = pumpkin_data::block_properties::HopperLikeProperties
|
|||||||
|
|
||||||
impl BlockBehaviour for HopperBlock {
|
impl BlockBehaviour for HopperBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InspectHopper as i32,
|
pumpkin_data::statistic::CustomStatistic::InspectHopper as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&HopperBlockScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(HopperBlockScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = HopperLikeProperties::default(args.block);
|
let mut props = HopperLikeProperties::default(args.block);
|
||||||
props.facing = match args.direction {
|
props.facing = match args.direction {
|
||||||
|
|||||||
@ -5,8 +5,8 @@ use crate::block::entities::lectern::LecternBlockEntity;
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, BrokenArgs, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
BlockBehaviour, BrokenArgs, EmitsRedstonePowerArgs, GetComparatorOutputArgs,
|
||||||
GetRedstonePowerArgs, NormalUseArgs, OnPlaceArgs, OnScheduledTickArgs, OnStateReplacedArgs,
|
GetRedstonePowerArgs, GetScreenHandlerFactoryArgs, NormalUseArgs, OnPlaceArgs,
|
||||||
PathComputationType, PlacedArgs, UseWithItemArgs,
|
OnScheduledTickArgs, OnStateReplacedArgs, PathComputationType, PlacedArgs, UseWithItemArgs,
|
||||||
};
|
};
|
||||||
use crate::entity::Entity;
|
use crate::entity::Entity;
|
||||||
use crate::entity::item::ItemEntity;
|
use crate::entity::item::ItemEntity;
|
||||||
@ -162,39 +162,50 @@ impl BlockBehaviour for LecternBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
|
self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server: args.server,
|
||||||
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
})
|
||||||
|
.map_or(BlockActionResult::Pass, |factory| {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithLectern as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
|
||||||
|
BlockActionResult::Success
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
let props =
|
let props =
|
||||||
LecternLikeProperties::from_state_id(args.world.get_block_state(args.position).id);
|
LecternLikeProperties::from_state_id(args.world.get_block_state(args.position).id);
|
||||||
if !props.has_book {
|
if !props.has_book {
|
||||||
return BlockActionResult::Pass;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(block_entity) = args.world.get_block_entity(args.position) else {
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
return BlockActionResult::Pass;
|
let inventory = block_entity.get_inventory()?;
|
||||||
};
|
|
||||||
let Some(inventory) = block_entity.get_inventory() else {
|
|
||||||
return BlockActionResult::Pass;
|
|
||||||
};
|
|
||||||
|
|
||||||
args.player.increment_stat(
|
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithLectern as i32,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
let controller = Arc::new(LecternPageController {
|
let controller = Arc::new(LecternPageController {
|
||||||
world: args.world.clone(),
|
world: args.world.clone(),
|
||||||
position: *args.position,
|
position: *args.position,
|
||||||
inventory: inventory.clone(),
|
inventory: inventory.clone(),
|
||||||
});
|
});
|
||||||
args.player.open_handled_screen(
|
|
||||||
&LecternScreenFactory {
|
|
||||||
inventory,
|
|
||||||
controller,
|
|
||||||
},
|
|
||||||
Some(*args.position),
|
|
||||||
);
|
|
||||||
|
|
||||||
BlockActionResult::Success
|
Some(Box::new(LecternScreenFactory {
|
||||||
|
inventory,
|
||||||
|
controller,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult {
|
fn use_with_item(&self, args: UseWithItemArgs<'_>) -> BlockActionResult {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs, OnPlaceArgs};
|
use crate::block::{BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs, OnPlaceArgs};
|
||||||
use crate::entity::EntityBase;
|
use crate::entity::EntityBase;
|
||||||
|
|
||||||
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
||||||
@ -34,16 +34,31 @@ impl BlockBehaviour for LoomBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithLoom as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&LoomScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithLoom as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(LoomScreenFactory))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LoomScreenFactory;
|
struct LoomScreenFactory;
|
||||||
|
|||||||
@ -7,8 +7,8 @@ use crate::block::entities::crafter::CrafterBlockEntity;
|
|||||||
use crate::block::entities::hopper::HopperBlockEntity;
|
use crate::block::entities::hopper::HopperBlockEntity;
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, GetComparatorOutputArgs, NormalUseArgs, OnNeighborUpdateArgs, OnPlaceArgs,
|
BlockBehaviour, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, NormalUseArgs,
|
||||||
OnScheduledTickArgs, PlacedArgs,
|
OnNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs, PlacedArgs,
|
||||||
};
|
};
|
||||||
use crate::entity::Entity;
|
use crate::entity::Entity;
|
||||||
use crate::entity::item::ItemEntity;
|
use crate::entity::item::ItemEntity;
|
||||||
@ -42,9 +42,9 @@ impl ScreenHandlerFactory for CrafterScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let handler = create_crafter_3x3(sync_id, player_inventory, self.0.clone());
|
let handler = create_crafter_3x3(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(screen_handler_arc as SharedScreenHandler)
|
Some(screen_handler_arc as SharedScreenHandler)
|
||||||
@ -221,15 +221,28 @@ impl CrafterBlock {
|
|||||||
|
|
||||||
impl BlockBehaviour for CrafterBlock {
|
impl BlockBehaviour for CrafterBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&CrafterScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(CrafterScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = CrafterLikeProperties::default(args.block);
|
let mut props = CrafterLikeProperties::default(args.block);
|
||||||
let facing = args.direction;
|
let facing = args.direction;
|
||||||
|
|||||||
@ -8,8 +8,8 @@ use crate::block::blocks::redstone::block_receives_redstone_power;
|
|||||||
use crate::block::blocks::tnt::TNTBlock;
|
use crate::block::blocks::tnt::TNTBlock;
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, GetComparatorOutputArgs, NormalUseArgs, OnNeighborUpdateArgs, OnPlaceArgs,
|
BlockBehaviour, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, NormalUseArgs,
|
||||||
OnScheduledTickArgs, PlacedArgs,
|
OnNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs, PlacedArgs,
|
||||||
};
|
};
|
||||||
use crate::entity::decoration::armor_stand::ArmorStandEntity;
|
use crate::entity::decoration::armor_stand::ArmorStandEntity;
|
||||||
use crate::entity::item::ItemEntity;
|
use crate::entity::item::ItemEntity;
|
||||||
@ -69,9 +69,9 @@ impl ScreenHandlerFactory for DispenserScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let handler = create_generic_3x3(sync_id, player_inventory, self.0.clone());
|
let handler = create_generic_3x3(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(screen_handler_arc as SharedScreenHandler)
|
Some(screen_handler_arc as SharedScreenHandler)
|
||||||
@ -124,20 +124,33 @@ const fn to_data3d(facing: Facing) -> i32 {
|
|||||||
|
|
||||||
impl BlockBehaviour for DispenserBlock {
|
impl BlockBehaviour for DispenserBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InspectDispenser as i32,
|
pumpkin_data::statistic::CustomStatistic::InspectDispenser as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&DispenserScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(DispenserScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = DispenserLikeProperties::default(args.block);
|
let mut props = DispenserLikeProperties::default(args.block);
|
||||||
props.facing = args.player.get_entity().get_facing().opposite();
|
props.facing = args.player.get_entity().get_facing().opposite();
|
||||||
|
|||||||
@ -5,8 +5,8 @@ use std::sync::Mutex;
|
|||||||
use crate::block::blocks::redstone::block_receives_redstone_power;
|
use crate::block::blocks::redstone::block_receives_redstone_power;
|
||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, GetComparatorOutputArgs, NormalUseArgs, OnNeighborUpdateArgs, OnPlaceArgs,
|
BlockBehaviour, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, NormalUseArgs,
|
||||||
OnScheduledTickArgs, PlacedArgs,
|
OnNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs, PlacedArgs,
|
||||||
};
|
};
|
||||||
use crate::entity::item::ItemEntity;
|
use crate::entity::item::ItemEntity;
|
||||||
use crate::entity::{Entity, EntityBase};
|
use crate::entity::{Entity, EntityBase};
|
||||||
@ -37,9 +37,9 @@ impl ScreenHandlerFactory for DropperScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let handler = create_generic_3x3(sync_id, player_inventory, self.0.clone());
|
let handler = create_generic_3x3(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(screen_handler_arc as SharedScreenHandler)
|
Some(screen_handler_arc as SharedScreenHandler)
|
||||||
@ -86,20 +86,33 @@ const fn to_data3d(facing: Facing) -> i32 {
|
|||||||
|
|
||||||
impl BlockBehaviour for DropperBlock {
|
impl BlockBehaviour for DropperBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InspectDropper as i32,
|
pumpkin_data::statistic::CustomStatistic::InspectDropper as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&DropperScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(DropperScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = DispenserLikeProperties::default(args.block);
|
let mut props = DispenserLikeProperties::default(args.block);
|
||||||
props.facing = args.player.get_entity().get_facing().opposite();
|
props.facing = args.player.get_entity().get_facing().opposite();
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::block::{GetComparatorOutputArgs, OnPlaceArgs, OnSyncedBlockEventArgs, PlacedArgs};
|
use crate::block::{
|
||||||
|
GetComparatorOutputArgs, GetScreenHandlerFactoryArgs, OnPlaceArgs, OnSyncedBlockEventArgs,
|
||||||
|
PlacedArgs,
|
||||||
|
};
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
registry::BlockActionResult,
|
registry::BlockActionResult,
|
||||||
{BlockBehaviour, NormalUseArgs},
|
{BlockBehaviour, NormalUseArgs},
|
||||||
@ -26,9 +29,9 @@ impl ScreenHandlerFactory for ShulkerBoxScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let handler = create_generic_9x3(sync_id, player_inventory, self.0.clone());
|
let handler = create_generic_9x3(sync_id, player_inventory, self.0.clone(), player);
|
||||||
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
let screen_handler_arc = Arc::new(Mutex::new(handler));
|
||||||
|
|
||||||
Some(screen_handler_arc as SharedScreenHandler)
|
Some(screen_handler_arc as SharedScreenHandler)
|
||||||
@ -68,21 +71,34 @@ impl BlockBehaviour for ShulkerBoxBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.get_inventory()
|
server: args.server,
|
||||||
{
|
world: args.world,
|
||||||
|
block: args.block,
|
||||||
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::OpenShulkerBox as i32,
|
pumpkin_data::statistic::CustomStatistic::OpenShulkerBox as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&ShulkerBoxScreenFactory(inventory), Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.get_inventory()?;
|
||||||
|
Some(Box::new(ShulkerBoxScreenFactory(inventory)))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
|
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
|
||||||
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(inventory) = block_entity.get_inventory()
|
&& let Some(inventory) = block_entity.get_inventory()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs};
|
use crate::block::{BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs};
|
||||||
|
|
||||||
use pumpkin_data::translation;
|
use pumpkin_data::translation;
|
||||||
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
||||||
@ -17,16 +17,31 @@ pub struct SmithingTableBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for SmithingTableBlock {
|
impl BlockBehaviour for SmithingTableBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithSmithingTable as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&SmithingTableScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithSmithingTable as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(SmithingTableScreenFactory))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SmithingTableScreenFactory;
|
struct SmithingTableScreenFactory;
|
||||||
|
|||||||
@ -17,8 +17,8 @@ use pumpkin_world::inventory::Inventory;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
block::{
|
block::{
|
||||||
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, NormalUseArgs, OnPlaceArgs,
|
BlockBehaviour, BrokenArgs, GetComparatorOutputArgs, GetScreenHandlerFactoryArgs,
|
||||||
PlacedArgs, registry::BlockActionResult,
|
NormalUseArgs, OnPlaceArgs, PlacedArgs, registry::BlockActionResult,
|
||||||
},
|
},
|
||||||
entity::experience_orb::ExperienceOrbEntity,
|
entity::experience_orb::ExperienceOrbEntity,
|
||||||
};
|
};
|
||||||
@ -76,24 +76,39 @@ pub struct SmokerBlock;
|
|||||||
|
|
||||||
impl BlockBehaviour for SmokerBlock {
|
impl BlockBehaviour for SmokerBlock {
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
if let Some(block_entity) = args.world.get_block_entity(args.position)
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
&& let Some(inventory) = block_entity.clone().get_inventory()
|
server: args.server,
|
||||||
&& let Some(property_delegate) = block_entity.clone().to_property_delegate()
|
world: args.world,
|
||||||
&& let Some(experience_container) = block_entity.to_experience_container()
|
block: args.block,
|
||||||
{
|
position: args.position,
|
||||||
|
player: args.player,
|
||||||
|
}) {
|
||||||
args.player.increment_stat(
|
args.player.increment_stat(
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithSmoker as i32,
|
pumpkin_data::statistic::CustomStatistic::InteractWithSmoker as i32,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
let smoker_screen_factory =
|
|
||||||
SmokerScreenFactory::new(inventory, property_delegate, experience_container);
|
|
||||||
args.player
|
args.player
|
||||||
.open_handled_screen(&smoker_screen_factory, Some(*args.position));
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
}
|
}
|
||||||
crate::block::registry::BlockActionResult::Consume
|
crate::block::registry::BlockActionResult::Consume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let block_entity = args.world.get_block_entity(args.position)?;
|
||||||
|
let inventory = block_entity.clone().get_inventory()?;
|
||||||
|
let property_delegate = block_entity.clone().to_property_delegate()?;
|
||||||
|
let experience_container = block_entity.to_experience_container()?;
|
||||||
|
Some(Box::new(SmokerScreenFactory::new(
|
||||||
|
inventory,
|
||||||
|
property_delegate,
|
||||||
|
experience_container,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
fn on_place(&self, args: OnPlaceArgs<'_>) -> BlockStateId {
|
||||||
let mut props = FurnaceLikeProperties::default(args.block);
|
let mut props = FurnaceLikeProperties::default(args.block);
|
||||||
props.facing = args
|
props.facing = args
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
use crate::block::registry::BlockActionResult;
|
use crate::block::registry::BlockActionResult;
|
||||||
use crate::block::{BlockBehaviour, NormalUseArgs, OnPlaceArgs, PathComputationType};
|
use crate::block::{
|
||||||
|
BlockBehaviour, GetScreenHandlerFactoryArgs, NormalUseArgs, OnPlaceArgs, PathComputationType,
|
||||||
|
};
|
||||||
|
|
||||||
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
use pumpkin_data::block_properties::WallTorchLikeProperties;
|
||||||
use pumpkin_data::{BlockState, BlockStateId, translation};
|
use pumpkin_data::{BlockState, BlockStateId, translation};
|
||||||
@ -30,17 +32,32 @@ impl BlockBehaviour for StonecutterBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
|
||||||
args.player.increment_stat(
|
if let Some(factory) = self.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
pumpkin_data::statistic::StatisticCategory::Custom,
|
server: args.server,
|
||||||
pumpkin_data::statistic::CustomStatistic::InteractWithStonecutter as i32,
|
world: args.world,
|
||||||
1,
|
block: args.block,
|
||||||
);
|
position: args.position,
|
||||||
args.player
|
player: args.player,
|
||||||
.open_handled_screen(&StonecutterScreenFactory, Some(*args.position));
|
}) {
|
||||||
|
args.player.increment_stat(
|
||||||
|
pumpkin_data::statistic::StatisticCategory::Custom,
|
||||||
|
pumpkin_data::statistic::CustomStatistic::InteractWithStonecutter as i32,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
args.player
|
||||||
|
.open_handled_screen(factory.as_ref(), Some(*args.position));
|
||||||
|
}
|
||||||
|
|
||||||
BlockActionResult::Success
|
BlockActionResult::Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
Some(Box::new(StonecutterScreenFactory))
|
||||||
|
}
|
||||||
|
|
||||||
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
fn is_pathfindable(&self, _state: &BlockState, _computation_type: PathComputationType) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ use pumpkin_data::BlockDirection;
|
|||||||
use pumpkin_data::block_rotation::{Mirror, Rotation};
|
use pumpkin_data::block_rotation::{Mirror, Rotation};
|
||||||
use pumpkin_data::data_component_impl::EquipmentSlot;
|
use pumpkin_data::data_component_impl::EquipmentSlot;
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_inventory::screen_handler::ScreenHandlerFactory;
|
||||||
use pumpkin_protocol::java::server::play::SUseItemOn;
|
use pumpkin_protocol::java::server::play::SUseItemOn;
|
||||||
use pumpkin_util::math::boundingbox::BoundingBox;
|
use pumpkin_util::math::boundingbox::BoundingBox;
|
||||||
use pumpkin_util::math::vector3::Vector3;
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
@ -85,6 +86,13 @@ pub trait BlockBehaviour: Send + Sync {
|
|||||||
BlockActionResult::Pass
|
BlockActionResult::Pass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
_args: GetScreenHandlerFactoryArgs<'_>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn use_with_item(&self, _args: UseWithItemArgs<'_>) -> BlockActionResult {
|
fn use_with_item(&self, _args: UseWithItemArgs<'_>) -> BlockActionResult {
|
||||||
BlockActionResult::PassToDefaultBlockAction
|
BlockActionResult::PassToDefaultBlockAction
|
||||||
}
|
}
|
||||||
@ -224,6 +232,15 @@ pub struct NormalUseArgs<'a> {
|
|||||||
pub hit: &'a BlockHitResult<'a>,
|
pub hit: &'a BlockHitResult<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct GetScreenHandlerFactoryArgs<'a> {
|
||||||
|
pub server: &'a Server,
|
||||||
|
pub world: &'a Arc<World>,
|
||||||
|
pub block: &'a Block,
|
||||||
|
pub position: &'a BlockPos,
|
||||||
|
pub player: &'a Arc<Player>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct UseWithItemArgs<'a> {
|
pub struct UseWithItemArgs<'a> {
|
||||||
pub server: &'a Server,
|
pub server: &'a Server,
|
||||||
pub world: &'a Arc<World>,
|
pub world: &'a Arc<World>,
|
||||||
|
|||||||
@ -171,9 +171,9 @@ use crate::block::fluid::lava::FlowingLava;
|
|||||||
use crate::block::fluid::water::FlowingWater;
|
use crate::block::fluid::water::FlowingWater;
|
||||||
use crate::block::{
|
use crate::block::{
|
||||||
BlockBehaviour, BlockHitResult, BlockMetadata, BonemealArgs, FluidMetadata,
|
BlockBehaviour, BlockHitResult, BlockMetadata, BonemealArgs, FluidMetadata,
|
||||||
GetInsideCollisionShapeArgs, OnEntityCollisionArgs, OnEntityStepArgs, OnLandedUponArgs,
|
GetInsideCollisionShapeArgs, GetScreenHandlerFactoryArgs, OnEntityCollisionArgs,
|
||||||
OnProjectileHitArgs, PathComputationType, UpdateEntityMovementAfterFallOnArgs,
|
OnEntityStepArgs, OnLandedUponArgs, OnProjectileHitArgs, PathComputationType,
|
||||||
stop_vertical_movement_after_fall,
|
UpdateEntityMovementAfterFallOnArgs, stop_vertical_movement_after_fall,
|
||||||
};
|
};
|
||||||
use crate::entity::EntityBase;
|
use crate::entity::EntityBase;
|
||||||
use crate::entity::player::Player;
|
use crate::entity::player::Player;
|
||||||
@ -187,6 +187,7 @@ use pumpkin_data::item::Item;
|
|||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
use pumpkin_data::tag::{self, Taggable};
|
use pumpkin_data::tag::{self, Taggable};
|
||||||
use pumpkin_data::{Block, BlockDirection, BlockId, BlockState};
|
use pumpkin_data::{Block, BlockDirection, BlockId, BlockState};
|
||||||
|
use pumpkin_inventory::screen_handler::ScreenHandlerFactory;
|
||||||
use pumpkin_protocol::java::server::play::SUseItemOn;
|
use pumpkin_protocol::java::server::play::SUseItemOn;
|
||||||
use pumpkin_util::math::boundingbox::BoundingBox;
|
use pumpkin_util::math::boundingbox::BoundingBox;
|
||||||
use pumpkin_util::math::position::BlockPos;
|
use pumpkin_util::math::position::BlockPos;
|
||||||
@ -905,6 +906,27 @@ impl BlockRegistry {
|
|||||||
BlockActionResult::Pass
|
BlockActionResult::Pass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_screen_handler_factory(
|
||||||
|
&self,
|
||||||
|
block: &Block,
|
||||||
|
player: &Arc<Player>,
|
||||||
|
position: &BlockPos,
|
||||||
|
server: &Server,
|
||||||
|
world: &Arc<World>,
|
||||||
|
) -> Option<Box<dyn ScreenHandlerFactory>> {
|
||||||
|
let pumpkin_block = self.get_pumpkin_block(block.id);
|
||||||
|
if let Some(pumpkin_block) = pumpkin_block {
|
||||||
|
return pumpkin_block.get_screen_handler_factory(GetScreenHandlerFactoryArgs {
|
||||||
|
server,
|
||||||
|
world,
|
||||||
|
block,
|
||||||
|
position,
|
||||||
|
player,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn explode(&self, block: &Block, world: &Arc<World>, position: &BlockPos) {
|
pub fn explode(&self, block: &Block, world: &Arc<World>, position: &BlockPos) {
|
||||||
let pumpkin_block = self.get_pumpkin_block(block.id);
|
let pumpkin_block = self.get_pumpkin_block(block.id);
|
||||||
if let Some(pumpkin_block) = pumpkin_block {
|
if let Some(pumpkin_block) = pumpkin_block {
|
||||||
|
|||||||
@ -7135,6 +7135,10 @@ impl InventoryPlayer for Player {
|
|||||||
self.gamemode.load() == GameMode::Creative
|
self.gamemode.load() == GameMode::Creative
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_spectator(&self) -> bool {
|
||||||
|
self.gamemode.load() == GameMode::Spectator
|
||||||
|
}
|
||||||
|
|
||||||
fn experience_level(&self) -> i32 {
|
fn experience_level(&self) -> i32 {
|
||||||
self.experience_level
|
self.experience_level
|
||||||
.load(std::sync::atomic::Ordering::Relaxed)
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
|||||||
@ -182,13 +182,13 @@ impl ScreenHandlerFactory for MinecartScreenFactory {
|
|||||||
&self,
|
&self,
|
||||||
sync_id: u8,
|
sync_id: u8,
|
||||||
player_inventory: &Arc<PlayerInventory>,
|
player_inventory: &Arc<PlayerInventory>,
|
||||||
_player: &dyn InventoryPlayer,
|
player: &dyn InventoryPlayer,
|
||||||
) -> Option<SharedScreenHandler> {
|
) -> Option<SharedScreenHandler> {
|
||||||
let inventory: Arc<dyn Inventory> = self.inventory.clone();
|
let inventory: Arc<dyn Inventory> = self.inventory.clone();
|
||||||
let handler = if self.hopper {
|
let handler = if self.hopper {
|
||||||
create_hopper(sync_id, player_inventory, inventory)
|
create_hopper(sync_id, player_inventory, inventory, player)
|
||||||
} else {
|
} else {
|
||||||
create_generic_9x3(sync_id, player_inventory, inventory)
|
create_generic_9x3(sync_id, player_inventory, inventory, player)
|
||||||
};
|
};
|
||||||
Some(Arc::new(Mutex::new(handler)) as SharedScreenHandler)
|
Some(Arc::new(Mutex::new(handler)) as SharedScreenHandler)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -159,7 +159,15 @@ impl BedrockClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if player.gamemode.load() == GameMode::Spectator {
|
if player.gamemode.load() == GameMode::Spectator {
|
||||||
// TODO: openMenu ?
|
if let Some(factory) = server.block_registry.get_screen_handler_factory(
|
||||||
|
block,
|
||||||
|
player,
|
||||||
|
&data.block_position,
|
||||||
|
&server,
|
||||||
|
&world,
|
||||||
|
) {
|
||||||
|
player.open_handled_screen(factory.as_ref(), Some(data.block_position));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,36 @@ impl JavaClient {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if player.gamemode.load() == GameMode::Spectator {
|
if player.gamemode.load() == GameMode::Spectator {
|
||||||
// TODO: openMenu
|
let entity = &player.get_entity();
|
||||||
|
let world = entity.world.load_full();
|
||||||
|
let block = world.get_block(&position);
|
||||||
|
|
||||||
|
let event = PlayerInteractEvent::new(
|
||||||
|
player,
|
||||||
|
InteractAction::RightClickBlock,
|
||||||
|
block,
|
||||||
|
Some(position),
|
||||||
|
);
|
||||||
|
|
||||||
|
send_cancellable_blocking! {{
|
||||||
|
server;
|
||||||
|
event;
|
||||||
|
'cancelled: {
|
||||||
|
let state_id = world.get_block_state_id(&position);
|
||||||
|
player.try_send_client_packet(&CBlockUpdate::new(
|
||||||
|
position,
|
||||||
|
VarInt(i32::from(state_id.as_u16())),
|
||||||
|
));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
if let Some(factory) = server
|
||||||
|
.block_registry
|
||||||
|
.get_screen_handler_factory(block, player, &position, server, &world)
|
||||||
|
{
|
||||||
|
player.open_handled_screen(factory.as_ref(), Some(position));
|
||||||
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user