diff --git a/Cargo.toml b/Cargo.toml
index bfcda5449..f00a7c4e1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -179,7 +179,7 @@ tracing-subscriber = { version = "0.3.23", default-features = false, features =
] }
slotmap = { version = "1.1", default-features = false, features = ["std"] }
temp-dir = { version = "0.2.0", default-features = false }
-thread_local = { version = "1.1.9", default-features = false }
+thread_local = { version = "1.1.10", default-features = false }
time = { version = "0.3", default-features = false, features = ["std"] }
arc-swap = { version = "1.9", default-features = false }
tokio-util = { version = "0.7.18", default-features = false }
diff --git a/pumpkin/src/block/blocks/banners.rs b/pumpkin/src/block/blocks/banners.rs
index 71fcce2dc..603686695 100644
--- a/pumpkin/src/block/blocks/banners.rs
+++ b/pumpkin/src/block/blocks/banners.rs
@@ -1,5 +1,6 @@
use crate::block::{
BlockBehaviour, BlockFuture, GetStateForNeighborUpdateArgs, OnPlaceArgs, OnScheduledTickArgs,
+ PlacedArgs,
};
use crate::entity::EntityBase;
use pumpkin_data::BlockStateId;
@@ -9,10 +10,20 @@ use pumpkin_util::math::position::BlockPos;
use pumpkin_world::tick::TickPriority;
use pumpkin_world::world::{BlockAccessor, BlockFlags};
+use crate::block::entities::banner::BannerBlockEntity;
+use std::sync::Arc;
+
#[pumpkin_block_from_tag("minecraft:banners")]
pub struct BannerBlock;
impl BlockBehaviour for BannerBlock {
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = BannerBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
+
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let mut props = WhiteBannerLikeProperties::default(args.block);
diff --git a/pumpkin/src/block/blocks/campfire.rs b/pumpkin/src/block/blocks/campfire.rs
index 85c820d9d..2e96588a2 100644
--- a/pumpkin/src/block/blocks/campfire.rs
+++ b/pumpkin/src/block/blocks/campfire.rs
@@ -9,18 +9,27 @@ use pumpkin_data::{
use pumpkin_macros::pumpkin_block_from_tag;
use pumpkin_world::tick::TickPriority;
+use crate::block::entities::campfire::CampfireBlockEntity;
use crate::{
block::{
BlockBehaviour, BlockFuture, BlockIsReplacing, GetStateForNeighborUpdateArgs,
- OnEntityCollisionArgs, OnPlaceArgs,
+ OnEntityCollisionArgs, OnPlaceArgs, PlacedArgs,
},
entity::EntityBase,
};
+use std::sync::Arc;
#[pumpkin_block_from_tag("minecraft:campfires")]
pub struct CampfireBlock;
impl BlockBehaviour for CampfireBlock {
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = CampfireBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
+
// TODO: cooking food on campfire (CampfireBlockEntity)
fn on_entity_collision<'a>(&'a self, args: OnEntityCollisionArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
diff --git a/pumpkin/src/block/blocks/conduit.rs b/pumpkin/src/block/blocks/conduit.rs
index e18582b8c..6df0299ce 100644
--- a/pumpkin/src/block/blocks/conduit.rs
+++ b/pumpkin/src/block/blocks/conduit.rs
@@ -1,7 +1,9 @@
-use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs};
+use crate::block::entities::conduit::ConduitBlockEntity;
+use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs, PlacedArgs};
use pumpkin_data::BlockStateId;
use pumpkin_data::block_properties::BlockProperties;
use pumpkin_macros::pumpkin_block;
+use std::sync::Arc;
#[pumpkin_block("minecraft:conduit")]
pub struct ConduitBlock;
@@ -16,4 +18,11 @@ impl BlockBehaviour for ConduitBlock {
props.to_state_id(args.block)
})
}
+
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = ConduitBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
}
diff --git a/pumpkin/src/block/blocks/enchanting_table.rs b/pumpkin/src/block/blocks/enchanting_table.rs
index 810d7f6fc..1bb809365 100644
--- a/pumpkin/src/block/blocks/enchanting_table.rs
+++ b/pumpkin/src/block/blocks/enchanting_table.rs
@@ -1,7 +1,8 @@
use std::sync::Arc;
+use crate::block::entities::enchanting_table::EnchantingTableBlockEntity;
use crate::block::registry::BlockActionResult;
-use crate::block::{BlockBehaviour, BlockFuture, NormalUseArgs};
+use crate::block::{BlockBehaviour, BlockFuture, NormalUseArgs, PlacedArgs};
use pumpkin_data::{Block, BlockStateId, translation};
use pumpkin_inventory::enchanting::enchanting_screen_handler::EnchantingTableScreenHandler;
use pumpkin_inventory::player::player_inventory::PlayerInventory;
@@ -18,6 +19,13 @@ use tokio::sync::Mutex;
pub struct EnchantingTableBlock;
impl BlockBehaviour for EnchantingTableBlock {
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = EnchantingTableBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
+
fn normal_use<'a>(&'a self, args: NormalUseArgs<'a>) -> BlockFuture<'a, BlockActionResult> {
Box::pin(async move {
let mut bookshelf_count = 0;
diff --git a/pumpkin/src/block/blocks/redstone/dispenser.rs b/pumpkin/src/block/blocks/redstone/dispenser.rs
index 1c4c489db..47354c322 100644
--- a/pumpkin/src/block/blocks/redstone/dispenser.rs
+++ b/pumpkin/src/block/blocks/redstone/dispenser.rs
@@ -1,8 +1,10 @@
-use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs};
+use crate::block::entities::dispenser::DispenserBlockEntity;
+use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs, PlacedArgs};
use crate::entity::EntityBase;
use pumpkin_data::BlockStateId;
use pumpkin_data::block_properties::{BlockProperties, DispenserLikeProperties};
use pumpkin_macros::pumpkin_block;
+use std::sync::Arc;
#[pumpkin_block("minecraft:dispenser")]
pub struct DispenserBlock;
@@ -15,4 +17,12 @@ impl BlockBehaviour for DispenserBlock {
props.to_state_id(args.block)
})
}
+
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let dispenser_block_entity = DispenserBlockEntity::new(*args.position);
+ args.world
+ .add_block_entity(Arc::new(dispenser_block_entity));
+ })
+ }
}
diff --git a/pumpkin/src/block/blocks/shelf.rs b/pumpkin/src/block/blocks/shelf.rs
index 93eb68a2c..b42eceba2 100644
--- a/pumpkin/src/block/blocks/shelf.rs
+++ b/pumpkin/src/block/blocks/shelf.rs
@@ -2,8 +2,10 @@ use pumpkin_data::BlockStateId;
use pumpkin_data::block_properties::{AcaciaShelfLikeProperties, BlockProperties};
use pumpkin_macros::pumpkin_block_from_tag;
-use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs};
+use crate::block::entities::shelf::ShelfBlockEntity;
+use crate::block::{BlockBehaviour, BlockFuture, OnPlaceArgs, PlacedArgs};
use crate::entity::EntityBase;
+use std::sync::Arc;
#[pumpkin_block_from_tag("minecraft:wooden_shelves")]
pub struct ShelfBlock;
@@ -19,4 +21,11 @@ impl BlockBehaviour for ShelfBlock {
properties.to_state_id(args.block)
})
}
+
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = ShelfBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
}
diff --git a/pumpkin/src/block/blocks/signs.rs b/pumpkin/src/block/blocks/signs.rs
index e991d539e..39ba4d6b6 100644
--- a/pumpkin/src/block/blocks/signs.rs
+++ b/pumpkin/src/block/blocks/signs.rs
@@ -1,6 +1,7 @@
use std::sync::Arc;
use std::sync::atomic::Ordering;
+use crate::block::entities::hanging_sign::HangingSignBlockEntity;
use crate::block::entities::sign::SignBlockEntity;
use pumpkin_data::Block;
use pumpkin_data::BlockDirection;
@@ -308,8 +309,13 @@ impl BlockBehaviour for SignBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
- args.world
- .add_block_entity(Arc::new(SignBlockEntity::empty(*args.position)));
+ if args.block.name.contains("hanging") {
+ args.world
+ .add_block_entity(Arc::new(HangingSignBlockEntity::empty(*args.position)));
+ } else {
+ args.world
+ .add_block_entity(Arc::new(SignBlockEntity::empty(*args.position)));
+ }
})
}
diff --git a/pumpkin/src/block/blocks/skull_block.rs b/pumpkin/src/block/blocks/skull_block.rs
index 03c7b728f..9f03ed976 100644
--- a/pumpkin/src/block/blocks/skull_block.rs
+++ b/pumpkin/src/block/blocks/skull_block.rs
@@ -24,7 +24,18 @@ impl BlockMetadata for SkullBlock {
}
}
+use crate::block::PlacedArgs;
+use crate::block::entities::skull::SkullBlockEntity;
+use std::sync::Arc;
+
impl BlockBehaviour for SkullBlock {
+ fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
+ Box::pin(async move {
+ let entity = SkullBlockEntity::new(*args.position);
+ args.world.add_block_entity(Arc::new(entity));
+ })
+ }
+
fn on_place<'a>(&'a self, args: OnPlaceArgs<'a>) -> BlockFuture<'a, BlockStateId> {
Box::pin(async move {
let mut props = SkeletonSkullLikeProperties::default(args.block);
diff --git a/pumpkin/src/block/blocks/wither_skull.rs b/pumpkin/src/block/blocks/wither_skull.rs
index ba92d8c7d..b078f465d 100644
--- a/pumpkin/src/block/blocks/wither_skull.rs
+++ b/pumpkin/src/block/blocks/wither_skull.rs
@@ -19,6 +19,9 @@ impl BlockBehaviour for WitherSkeletonSkullBlock {
fn placed<'a>(&'a self, args: PlacedArgs<'a>) -> BlockFuture<'a, ()> {
Box::pin(async move {
+ let entity = crate::block::entities::skull::SkullBlockEntity::new(*args.position);
+ args.world.add_block_entity(std::sync::Arc::new(entity));
+
let world = args.world;
let pos = args.position;
diff --git a/pumpkin/src/block/entities/banner.rs b/pumpkin/src/block/entities/banner.rs
new file mode 100644
index 000000000..e47f1c20a
--- /dev/null
+++ b/pumpkin/src/block/entities/banner.rs
@@ -0,0 +1,65 @@
+use super::BlockEntity;
+use pumpkin_nbt::compound::NbtCompound;
+use pumpkin_nbt::tag::NbtTag;
+use pumpkin_util::math::position::BlockPos;
+use std::pin::Pin;
+use tokio::sync::Mutex;
+
+pub struct BannerBlockEntity {
+ pub position: BlockPos,
+ pub custom_name: Mutex