Skip to content

Commit

Permalink
blocks now drop on breakage
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryntet committed Oct 22, 2024
1 parent 73ac380 commit b7b7da3
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 29 deletions.
1 change: 1 addition & 0 deletions pumpkin-world/src/block/block_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl BlockId {
.find(|(_, val)| val.states.iter().any(|state| state.id == *self))
.map(|(key, _)| key.as_str())
.unwrap();
dbg!(id);
get_item_protocol_id(id)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pumpkin-world/src/item/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod item_categories;
mod item_registry;
pub use item_registry::ITEMS;
pub use item_registry::{get_item_protocol_id, ITEMS};
#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
/// Item Rarity
Expand Down
28 changes: 19 additions & 9 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@ impl Player {
// Block break & block break sound
// TODO: currently this is always dirt replace it
let entity = &self.living_entity.entity;
let world = &entity.world;
world.break_block(location).await;
let world = entity.world.clone();
world.break_block(location, server.clone()).await;
}
}
Status::CancelledDigging => {
Expand Down Expand Up @@ -510,8 +510,8 @@ impl Player {
// Block break & block break sound
// TODO: currently this is always dirt replace it
let entity = &self.living_entity.entity;
let world = &entity.world;
world.break_block(location).await;
let world = entity.world.clone();
world.break_block(location, server.clone()).await;
// TODO: Send this every tick
self.client
.send_packet(&CAcknowledgeBlockChange::new(player_action.sequence))
Expand All @@ -521,7 +521,12 @@ impl Player {
let mut inventory = self.inventory.lock().await;
let slot = inventory.held_item_mut();
if let Some(item) = slot {
ItemEntity::spawn(&self.living_entity.entity, *item, server.clone()).await;
ItemEntity::spawn_from_player(
&self.living_entity.entity,
*item,
server.clone(),
)
.await;
*slot = None;
}
}
Expand All @@ -533,10 +538,14 @@ impl Player {
held_item.item_count -= 1;
let mut item = *held_item;
item.item_count = 1;
ItemEntity::spawn(&self.living_entity.entity, item, server.clone())
.await;
ItemEntity::spawn_from_player(
&self.living_entity.entity,
item,
server.clone(),
)
.await;
} else {
ItemEntity::spawn(
ItemEntity::spawn_from_player(
&self.living_entity.entity,
*held_item,
server.clone(),
Expand Down Expand Up @@ -651,7 +660,8 @@ impl Player {
let item = None;
self.carried_item.swap(item);
if let Some(item) = item {
ItemEntity::spawn(&self.living_entity.entity, item, server.clone()).await;
ItemEntity::spawn_from_player(&self.living_entity.entity, item, server.clone())
.await;
}
Ok(())
}
Expand Down
50 changes: 39 additions & 11 deletions pumpkin/src/entity/item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::entity::player::Player;
use crate::entity::{random_float, Entity};
use crate::server::Server;
use crate::world::World;
use crossbeam::atomic::AtomicCell;
use pumpkin_core::math::vector3::Vector3;
use pumpkin_entity::entity_type::EntityType;
Expand All @@ -23,7 +24,13 @@ pub struct ItemEntity {
}

impl ItemEntity {
pub async fn spawn(player_entity: &Entity, item_stack: ItemStack, server: Arc<Server>) {
pub async fn spawn(
pos: Vector3<f64>,
velocity: Vector3<f64>,
world: Arc<World>,
item_stack: ItemStack,
server: Arc<Server>,
) {
let is_able_to_be_picked_up = Arc::new(AtomicBool::new(false));
{
let is_able_to_be_picked_up = is_able_to_be_picked_up.clone();
Expand All @@ -33,25 +40,24 @@ impl ItemEntity {
});
}

let player_pos = player_entity.pos.load();
let pos = Vector3 {
x: player_pos.x,
y: player_pos.y + player_entity.standing_eye_height as f64 - 0.3,
z: player_pos.z,
let empty = Vector3 {
x: 0.,
y: 0.,
z: 0.,
};

let entity = Arc::new(Entity {
entity_id: server.new_entity_id(),
uuid: Uuid::new_v4(),
entity_type: EntityType::Item,
world: player_entity.world.clone(),
pos: AtomicCell::new(pos),
block_pos: player_entity.block_pos.load().into(),
chunk_pos: player_entity.chunk_pos.load().into(),
world,
pos: AtomicCell::new(empty),
block_pos: AtomicCell::new(Default::default()),
chunk_pos: AtomicCell::new(Default::default()),
sneaking: false.into(),
sprinting: false.into(),
fall_flying: false.into(),
velocity: toss_velocity(player_entity).into(),
velocity: AtomicCell::new(velocity),
on_ground: false.into(),
in_ground: false.into(),
yaw: 0.0.into(),
Expand All @@ -60,6 +66,8 @@ impl ItemEntity {
standing_eye_height: 0.0,
pose: EntityPose::Standing.into(),
});
entity.set_pos(pos.x, pos.y, pos.z);

let item_entity = Self {
item_stack,
is_able_to_be_picked_up,
Expand All @@ -81,6 +89,26 @@ impl ItemEntity {
})
.await;
}
pub async fn spawn_from_player(
player_entity: &Entity,
item_stack: ItemStack,
server: Arc<Server>,
) {
let player_pos = player_entity.pos.load();
let pos = Vector3 {
x: player_pos.x,
y: player_pos.y + player_entity.standing_eye_height as f64 - 0.3,
z: player_pos.z,
};
Self::spawn(
pos,
toss_velocity(player_entity).into(),
player_entity.world.clone(),
item_stack,
server,
)
.await
}

pub(self) async fn check_pickup(self) -> PickupEvent {
if !self.is_able_to_be_picked_up.load(Ordering::Relaxed) {
Expand Down
40 changes: 32 additions & 8 deletions pumpkin/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ use std::{collections::HashMap, sync::Arc};

pub mod player_chunker;

use crate::entity::item::ItemEntity;
use crate::server::Server;
use crate::{
client::Client,
entity::{player::Player, Entity},
};
use num_traits::ToPrimitive;
use pumpkin_config::BasicConfiguration;
use pumpkin_core::math::position::WorldPosition;
use pumpkin_core::math::vector2::Vector2;
use pumpkin_core::math::vector3::Vector3;
use pumpkin_entity::EntityId;
use pumpkin_protocol::client::play::{CBlockUpdate, CWorldEvent};
use pumpkin_protocol::{
Expand All @@ -18,16 +25,12 @@ use pumpkin_protocol::{
use pumpkin_world::block::BlockId;
use pumpkin_world::chunk::ChunkData;
use pumpkin_world::coordinates::ChunkRelativeBlockCoordinates;
use pumpkin_world::item::ItemStack;
use pumpkin_world::level::Level;
use scoreboard::Scoreboard;
use tokio::sync::Mutex;
use tokio::sync::{mpsc, RwLock};

use crate::entity::item::ItemEntity;
use crate::{
client::Client,
entity::{player::Player, Entity},
};
pub mod scoreboard;

/// Represents a Minecraft world, containing entities, players, and the underlying level data.
Expand Down Expand Up @@ -373,14 +376,35 @@ impl World {
.unwrap()
}

pub async fn break_block(&self, position: WorldPosition) {
pub async fn break_block(self: &Arc<Self>, position: WorldPosition, server: Arc<Server>) {
let block_id = self.get_block_id(position).await;
self.set_block(position, BlockId { data: 0 }).await;

let item_id = block_id.get_as_item_id();
let fake_item_stack = ItemStack {
item_id,
item_count: 1,
};
ItemEntity::spawn(
Vector3 {
x: position.0.x as f64,
y: position.0.y as f64,
z: position.0.z as f64,
},
Vector3 {
x: 0.,
y: 0.,
z: 0.,
},
self.clone(),
fake_item_stack,
server,
)
.await;
self.broadcast_packet_all(&CWorldEvent::new(2001, &position, 11, false))
.await;
}

pub async fn get_block(&self, position: WorldPosition) -> BlockId {
pub async fn get_block_id(&self, position: WorldPosition) -> BlockId {
let (chunk, relative) = position.chunk_and_chunk_relative_position();
let relative = ChunkRelativeBlockCoordinates::from(relative);
self.get_chunks(vec![chunk]).await[0]
Expand Down

0 comments on commit b7b7da3

Please sign in to comment.