Merge pull request #8719 from xxaxio/fix/8628-sniffer-digging

🤖 Agent: vanilla Sniffer/ClientPacketListener event 63 and SnifferSoundInstance checked; with the head merged into main, ambient_sound, server_entities, sound_engine, sound_event and dedicated_server pass on playhorizon.
This commit is contained in:
Ludovic Marie authored and GitHub committed 2026-11-04 08:54:21 +01:00
commit 017c84f1fe
4 files changed
+31 -10

No files matched your search

+4
View File
@@ -2668,6 +2668,10 @@ impl Game<'_> {
if self.audio.capture.is_some() {
self.lan_entity_events.push((id, event, at));
}
// Event 63: a sniffer's digging sound loop starts (ClientPacketListener.handleEntityEvent 63).
if event == 63 && self.options.execution_role.is_client() {
self.start_sniffer_digging_sound(id as u32);
}
// Event 21: a window that simulates the world itself is its own
// client, and hears the guardian's hum too.
if event == 21 && self.options.execution_role.is_client() {
@@ -133,4 +133,21 @@ impl Game<'_> {
let instance = SoundInstance::guardian_attack(&sound, SoundEngine::unseeded());
self.audio.play_instance(instance, false);
}
/// `ClientPacketListener.handleEntityEvent` 63: a sniffer's digging
/// sound loop starts (`SnifferSoundInstance`).
pub(super) fn start_sniffer_digging_sound(&mut self, id: u32) {
let Some(m) = self
.mobs
.iter()
.find(|m| m.id == id && m.species() == Species::Sniffer)
else {
return;
};
if m.silent {
return;
}
let instance = SoundInstance::sniffer(id, SoundEngine::unseeded());
self.audio.play_instance(instance, false);
}
}
+4
View File
@@ -4007,6 +4007,10 @@ impl Game<'_> {
if p.event == 69 {
self.remote_ravager_roar(p.id);
}
// ClientPacketListener.handleEntityEvent 63: a sniffer's digging sound.
if p.event == 63 {
self.start_sniffer_digging_sound(p.id as u32);
}
// ClientPacketListener.handleEntityEvent 21: a guardian's hum.
if p.event == 21 {
self.start_guardian_sound(p.id as u32);
+6 -10
View File
@@ -5,7 +5,6 @@ use super::Game;
use horizon_client::{
items::ItemStack,
mobs::{Mob, Species, sniffer},
sound_engine::{SoundEngine, SoundInstance, Sounds},
};
use horizon_core::{geometry::Vec3, random::RandomSource};
@@ -56,15 +55,15 @@ impl Game<'_> {
let m = &self.mobs[i];
if m.species() != Species::Sniffer
|| !m.alive()
|| m.silent
|| !players
.iter()
.any(|p| m.position.distance_squared(p.position) <= 32.0 * 32.0)
{
continue;
}
let id = m.id;
let at = [m.position.x, m.position.y, m.position.z];
if sniffer::state(m) == sniffer::SEARCHING && m.age.is_multiple_of(20) {
if !m.silent && sniffer::state(m) == sniffer::SEARCHING && m.age.is_multiple_of(20) {
self.audio
.play("minecraft:entity.sniffer.searching", Some(at), 1.0, 1.0);
continue;
@@ -76,16 +75,13 @@ impl Game<'_> {
continue;
};
if ms == 0 {
// ClientPacketListener.handleEntityEvent 63: a
// SnifferSoundInstance that follows the sniffer.
let id = self.mobs[i].id;
let instance = SoundInstance::sniffer(id, SoundEngine::unseeded());
self.audio.play_instance(instance, false);
// Sniffer.onDiggingStart: broadcast entity event 63.
self.lan_entity_event(id as i32, 63, at);
}
if ms <= 1700 || ms >= 6000 {
continue;
}
let head = sniffer::head_block(m);
let head = sniffer::head_block(&self.mobs[i]);
let below = self.world.block(head[0], head[1] - 1, head[2]);
if self
.particle_sprite(below, [head[0], head[1] - 1, head[2]])
@@ -101,7 +97,7 @@ impl Game<'_> {
// Drawn in this window when it has one, and sent to the players
// within 32 blocks (the server thread's window is one of them).
self.landing_dust(None, below, Vec3::new(dust[0], dust[1], dust[2]), 30, 0.0);
if self.mobs[i].age.is_multiple_of(10) {
if !self.mobs[i].silent && self.mobs[i].age.is_multiple_of(10) {
let hit = self.res.facts().get(below).sounds.hit.clone();
self.audio.play(&hit, Some(at), 0.5, 0.5);
}