Merge pull request #2514 from kacpherek/fix/amethyst-step-chime
🤖 Agent: Merged by Ludovic's AI agent (Claude, contrib-gate-19). Thanks @kacpherek: Play the amethyst chime when walking on amethyst blocks. I checked it against vanilla 26.3, and it passed every harness it reaches in a union with your other PRs, plus lan_e2e in both modes.
This commit is contained in:
@@ -4740,6 +4740,14 @@ impl Game<'_> {
|
||||
self.audio
|
||||
.play("minecraft:entity.player.swim", Some(feet), volume, pitch);
|
||||
}
|
||||
MotionEvent::Chime { volume, pitch } => {
|
||||
self.audio.play(
|
||||
"minecraft:block.amethyst_block.chime",
|
||||
Some(feet),
|
||||
volume,
|
||||
pitch,
|
||||
);
|
||||
}
|
||||
MotionEvent::Drown => {
|
||||
// LivingEntity.makeDrownParticles: eight bubbles moving
|
||||
// with the player.
|
||||
|
||||
@@ -3403,6 +3403,14 @@ impl Game<'_> {
|
||||
self.audio
|
||||
.play("minecraft:entity.player.swim", Some(feet), volume, pitch);
|
||||
}
|
||||
horizon_client::motion::MotionEvent::Chime { volume, pitch } => {
|
||||
self.audio.play(
|
||||
"minecraft:block.amethyst_block.chime",
|
||||
Some(feet),
|
||||
volume,
|
||||
pitch,
|
||||
);
|
||||
}
|
||||
// NetherPortalBlock.entityInside on the client's own level:
|
||||
// the portal overlay and its trigger sound (the server moves
|
||||
// the player).
|
||||
|
||||
@@ -55,6 +55,8 @@ pub struct MotionResources {
|
||||
/// `BlockTags.SOUL_SPEED_BLOCKS`: what Soul Speed's effects look for.
|
||||
pub soul_speed_blocks: BTreeSet<String>,
|
||||
pub fall_reset: BTreeSet<String>,
|
||||
/// `BlockTags.CRYSTAL_SOUND_BLOCKS`: blocks that chime under footsteps.
|
||||
pub crystal_sound: BTreeSet<String>,
|
||||
pub landing: BlockLandingRegistry,
|
||||
pub health: crate::health::HealthResources,
|
||||
pub fluids: FluidResources,
|
||||
@@ -115,6 +117,7 @@ impl MotionResources {
|
||||
glide_through: tag("minecraft:can_glide_through")?,
|
||||
soul_speed_blocks: tag("minecraft:soul_speed_blocks")?,
|
||||
fall_reset: tag("minecraft:fall_damage_resetting")?,
|
||||
crystal_sound: tag("minecraft:crystal_sound_blocks")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -165,6 +168,11 @@ pub enum MotionEvent {
|
||||
state: BlockStateId,
|
||||
in_water: bool,
|
||||
},
|
||||
/// `Entity.playAmethystStepSound`: `block.amethyst_block.chime`.
|
||||
Chime {
|
||||
volume: f32,
|
||||
pitch: f32,
|
||||
},
|
||||
/// `Entity.waterSwimSound`: `entity.player.swim`.
|
||||
Swim {
|
||||
volume: f32,
|
||||
@@ -309,6 +317,10 @@ pub struct PlayerMotion {
|
||||
/// `Entity.moveDist`, `flyDist` and `nextStep`: footsteps come once per
|
||||
/// metre walked, not once per move.
|
||||
pub steps: MovementDistances,
|
||||
/// `Entity.crystalSoundIntensity` and `lastCrystalSoundPlayTick`: the
|
||||
/// amethyst chime grows with steps taken close together.
|
||||
pub crystal_sound_intensity: f32,
|
||||
pub last_crystal_sound_play_tick: i32,
|
||||
pub needs_sync: bool,
|
||||
pub sync_position: bool,
|
||||
/// Moved by an ender pearl (`ServerPlayer.teleport`): a server sends the
|
||||
@@ -501,6 +513,8 @@ impl PlayerMotion {
|
||||
next_step: 1.0,
|
||||
..MovementDistances::default()
|
||||
},
|
||||
crystal_sound_intensity: 0.0,
|
||||
last_crystal_sound_play_tick: 0,
|
||||
needs_sync: false,
|
||||
sync_position: false,
|
||||
teleported: false,
|
||||
@@ -2164,6 +2178,30 @@ impl MovementEmissionWorld for MotionWorld<'_, '_, '_> {
|
||||
state,
|
||||
in_water,
|
||||
});
|
||||
// Entity.walkingStepSound: the amethyst chime after the step.
|
||||
let name = &self
|
||||
.assets
|
||||
.registry
|
||||
.state(state)
|
||||
.ok_or("missing scene state")?
|
||||
.name;
|
||||
let tick = self.player.health.tick_count;
|
||||
if self.resources.crystal_sound.contains(name)
|
||||
&& tick >= self.player.last_crystal_sound_play_tick + 20
|
||||
{
|
||||
// Entity.playAmethystStepSound (the level random stands in for
|
||||
// the entity's).
|
||||
let elapsed = f64::from(tick - self.player.last_crystal_sound_play_tick);
|
||||
let decayed = self.player.crystal_sound_intensity * 0.997_f64.powf(elapsed) as f32;
|
||||
let intensity = 1.0_f32.min(decayed + 0.07);
|
||||
self.player.crystal_sound_intensity = intensity;
|
||||
let pitch = 0.5 + intensity * self.scene.random.next_float() * 1.2;
|
||||
let volume = 0.1 + intensity * 1.2;
|
||||
self.player
|
||||
.events
|
||||
.push(MotionEvent::Chime { volume, pitch });
|
||||
self.player.last_crystal_sound_play_tick = tick;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn step_event(&mut self, _: BlockStateId) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user