diff --git a/assets/map/elements/item/grenade/fuse.ogg b/assets/map/elements/item/grenade/fuse.ogg new file mode 100644 index 0000000000..1d3007e825 Binary files /dev/null and b/assets/map/elements/item/grenade/fuse.ogg differ diff --git a/assets/map/elements/item/grenade/grenade.element.yaml b/assets/map/elements/item/grenade/grenade.element.yaml index ae776c6e0c..fc36419068 100644 --- a/assets/map/elements/item/grenade/grenade.element.yaml +++ b/assets/map/elements/item/grenade/grenade.element.yaml @@ -11,7 +11,7 @@ builtin: !Grenades explosion_frames: 12 explosion_fps: 8 explosion_sound: ./explosion.ogg - + fuse_sound: ./fuse.ogg body_size: [18, 18] grab_offset: [-7, -6] body_offset: [0, 2] diff --git a/src/assets.rs b/src/assets.rs index eb8e290580..3fb511d934 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -423,6 +423,8 @@ impl AssetLoader for MapElementMetaLoader { explosion_atlas_handle, explosion_sound, explosion_sound_handle, + fuse_sound, + fuse_sound_handle, .. } => { for (atlas, atlas_handle) in [ @@ -433,10 +435,15 @@ impl AssetLoader for MapElementMetaLoader { *atlas_handle = AssetHandle::new(path.clone(), handle.typed()); dependencies.push(path); } - let (sound_path, sound_handle) = - get_relative_asset(load_context, self_path, explosion_sound); - dependencies.push(sound_path); - *explosion_sound_handle = sound_handle.typed(); + for (sound, handle) in [ + (explosion_sound, explosion_sound_handle), + (fuse_sound, fuse_sound_handle), + ] { + let (sound_path, sound_handle) = + get_relative_asset(load_context, self_path, sound); + dependencies.push(sound_path); + *handle = sound_handle.typed(); + } } } diff --git a/src/map/elements/grenade.rs b/src/map/elements/grenade.rs index 5f3a815c22..bc16a9cd8d 100644 --- a/src/map/elements/grenade.rs +++ b/src/map/elements/grenade.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use super::*; pub struct GrenadePlugin; @@ -22,6 +24,7 @@ impl Default for IdleGrenade { pub struct LitGrenade { /// The entity ID of the map element that spawned the grenade spawner: Entity, + fuse_sound: Handle, age: f32, } @@ -29,6 +32,7 @@ impl Default for LitGrenade { fn default() -> Self { Self { spawner: crate::utils::invalid_entity(), + fuse_sound: default(), age: 0.0, } } @@ -131,6 +135,7 @@ fn update_idle_grenades( >, mut ridp: ResMut, element_assets: ResMut>, + effects: Res>, ) { let mut items = grenades.iter_mut().collect::>(); items.sort_by_key(|x| x.0.id()); @@ -148,7 +153,13 @@ fn update_idle_grenades( ) in items { let meta = element_assets.get(meta_handle).unwrap(); - let BuiltinElementKind::Grenades { grab_offset, atlas_handle, throw_velocity, .. } = &meta.builtin else { + let BuiltinElementKind::Grenades { + grab_offset, + atlas_handle, + throw_velocity, + fuse_sound_handle, + .. + } = &meta.builtin else { unreachable!(); }; @@ -198,6 +209,7 @@ fn update_idle_grenades( .insert(body.clone()) .insert(LitGrenade { spawner: grenade.spawner, + fuse_sound: effects.play(fuse_sound_handle.clone_weak()).handle(), ..default() }) .insert(KinematicBody { @@ -252,6 +264,7 @@ fn update_lit_grenades( element_assets: ResMut>, player_inputs: Res, effects: Res>, + mut audio_instances: ResMut>, ) { let mut items = grenades.iter_mut().collect::>(); items.sort_by_key(|x| x.0.id()); @@ -276,6 +289,9 @@ fn update_lit_grenades( if grenade.age >= *fuse_time { if player_inputs.is_confirmed { effects.play(explosion_sound_handle.clone_weak()); + audio_instances + .get_mut(&grenade.fuse_sound) + .map(|x| x.stop(AudioTween::linear(Duration::from_secs_f32(0.1)))); } // Despawn the grenade diff --git a/src/metadata/map.rs b/src/metadata/map.rs index 0dc4d741ce..7b0aaf7a16 100644 --- a/src/metadata/map.rs +++ b/src/metadata/map.rs @@ -221,6 +221,9 @@ pub enum BuiltinElementKind { explosion_sound: String, #[serde(skip)] explosion_sound_handle: Handle, + fuse_sound: String, + #[serde(skip)] + fuse_sound_handle: Handle, /// The time in seconds before a grenade explodes fuse_time: f32, #[serde(default)]