item pickup: one sound per item, played by the client at the item

The server sent its own pickup sound beside TakeItemEntity, so single player heard two. Fixes #3029, fixes #2861.
This commit is contained in:
iLostName committed 2026-10-28 06:52:27 +01:00
1 parent 56f968e11c
commit 0112a6feac
2 files changed
+18 -9

No files matched your search

@@ -3041,10 +3041,10 @@ impl Game<'_> {
Some(_) => {}
}
}
// Entity.take: the clients play the pickup sound themselves
// (handleTakeItemEntity).
for (item, count) in taken {
host.hub.take_item(item as i32, id, count as i32, position);
host.hub
.sound("minecraft:entity.item.pickup", position, 0.2, 1.4, 7, None);
}
}
+16 -7
View File
@@ -2235,21 +2235,30 @@ impl Game<'_> {
}
}
C::TakeItemEntity(p) => {
// An orb's sound comes from the server, at the orb.
// ClientPacketListener.handleTakeItemEntity: the pickup sound at
// the item, whoever collects it (the server sends none). An
// orb's sound comes from the server, at the orb; an arrow this
// client does not track as an item sounds at this player.
let orb = self.orbs.iter().any(|o| o.id == p.item as u32);
if !orb
&& self
let item = self.dropped.iter().find(|d| d.id == p.item as u32);
let at = match item {
Some(d) => Some([d.position.x, d.position.y, d.position.z]),
None if self
.remote
.as_ref()
.is_some_and(|r| r.entity_id == p.player)
&& let Some(eye) = self.eye_position()
{
.is_some_and(|r| r.entity_id == p.player) =>
{
self.eye_position()
}
None => None,
};
if !orb && let Some(at) = at {
let pitch = ((self.world.random.next_float() - self.world.random.next_float())
* 0.7
+ 1.0)
* 2.0;
self.audio
.play("minecraft:entity.item.pickup", Some(eye), 0.2, pitch);
.play("minecraft:entity.item.pickup", Some(at), 0.2, pitch);
}
// ItemPickupParticle toward the collector (this player, another one or a mob).
let collector = if self