feat: Implement TakeItemActor for bedrock (#2239)

* fix: only send TakeItem packet to tracking players. implement TakeItemActor packet for bedrock

* fix: clippy warnings

* feat: introduce macros for VarLong and VarULong

* chore: change source

---------

Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
This commit is contained in:
Greened
2026-06-06 18:10:51 +04:00
committed by GitHub
parent c17e7124d8
commit 1bd6eef2a4
5 changed files with 67 additions and 42 deletions

View File

@@ -34,6 +34,7 @@ pub mod set_player_gamemode;
pub mod set_time;
pub mod set_title;
pub mod start_game;
pub mod take_item_actor;
pub mod transfer;
pub mod update_abilities;
pub mod update_attributes;

View File

@@ -0,0 +1,19 @@
use crate::{codec::var_ulong::VarULong, serial::PacketWrite};
use pumpkin_macros::packet;
#[derive(PacketWrite)]
#[packet(17)]
pub struct CTakeItemActor {
// https://github.com/Sandertv/gophertunnel/blob/master/minecraft/protocol/packet/take_item_actor.go
pub item_runtime_id: VarULong,
pub actor_runtime_id: VarULong,
}
impl CTakeItemActor {
#[must_use]
pub const fn new(item_runtime_id: VarULong, actor_runtime_id: VarULong) -> Self {
Self {
item_runtime_id,
actor_runtime_id,
}
}
}

View File

@@ -52,24 +52,19 @@ impl VarLong {
Err(ReadingError::TooLarge("VarLong".to_string()))
}
}
impl From<i64> for VarLong {
fn from(value: i64) -> Self {
Self(value)
}
macro_rules! gen_from {
($ty: ty) => {
impl From<$ty> for VarLong {
fn from(value: $ty) -> Self {
VarLong(value.into())
}
}
};
}
impl From<u32> for VarLong {
fn from(value: u32) -> Self {
Self(i64::from(value))
}
}
impl From<u8> for VarLong {
fn from(value: u8) -> Self {
Self(i64::from(value))
}
}
gen_from!(u8);
gen_from!(u32);
gen_from!(i64);
impl From<usize> for VarLong {
fn from(value: usize) -> Self {

View File

@@ -65,30 +65,35 @@ impl VarULong {
Err(ReadingError::TooLarge("VarLong".to_string()))
}
}
impl From<u64> for VarULong {
fn from(value: u64) -> Self {
Self(value)
}
macro_rules! gen_from {
($ty: ty) => {
impl From<$ty> for VarULong {
fn from(value: $ty) -> Self {
VarULong(value.into())
}
}
};
}
gen_from!(u8);
gen_from!(u16);
gen_from!(u32);
gen_from!(u64);
impl From<u32> for VarULong {
fn from(value: u32) -> Self {
Self(u64::from(value))
}
}
macro_rules! gen_try_from {
($ty: ty) => {
impl TryFrom<$ty> for VarULong {
type Error = <u64 as TryFrom<$ty>>::Error;
impl From<u8> for VarULong {
fn from(value: u8) -> Self {
Self(u64::from(value))
}
}
impl From<usize> for VarULong {
fn from(value: usize) -> Self {
Self(value as u64)
}
fn try_from(value: $ty) -> Result<Self, Self::Error> {
Ok(VarULong(value.try_into()?))
}
}
};
}
gen_try_from!(i32);
gen_try_from!(i64);
gen_try_from!(isize);
gen_try_from!(usize);
impl From<VarULong> for u64 {
fn from(value: VarULong) -> Self {

View File

@@ -6,6 +6,7 @@ use pumpkin_data::tracked_data::{TrackedData, TrackedId};
use pumpkin_inventory::build_equipment_slots;
use pumpkin_inventory::player::player_inventory::PlayerInventory;
use pumpkin_inventory::screen_handler::InventoryPlayer;
use pumpkin_protocol::bedrock::client::take_item_actor::CTakeItemActor;
use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent};
use pumpkin_util::GameMode;
use pumpkin_util::Hand;
@@ -199,15 +200,19 @@ impl LivingEntity {
/// Picks up and Item entity or XP Orb
pub fn pickup(&self, item: &Entity, stack_amount: u32) {
// TODO: Only nearby
self.entity
.world
.load()
.broadcast_packet_all(&CTakeItemEntity::new(
let chunk_pos = self.entity.chunk_pos.load();
self.entity.world.load().broadcast_to_chunk_editioned_sync(
chunk_pos,
&CTakeItemEntity::new(
item.entity_id.into(),
self.entity.entity_id.into(),
stack_amount.try_into().unwrap(),
));
),
&CTakeItemActor::new(
item.entity_id.try_into().unwrap(),
self.entity.entity_id.try_into().unwrap(),
),
);
}
/// Sends the Hand animation to all others, used when Eating for example