diff --git a/resources/sounds/amb/relaxed.wav b/resources/sounds/amb/relaxed.wav new file mode 100644 index 0000000..e0b706d Binary files /dev/null and b/resources/sounds/amb/relaxed.wav differ diff --git a/resources/sounds/door/blocked1.wav b/resources/sounds/door/blocked1.wav new file mode 100644 index 0000000..6fe3643 Binary files /dev/null and b/resources/sounds/door/blocked1.wav differ diff --git a/resources/sounds/door/blocked2.wav b/resources/sounds/door/blocked2.wav new file mode 100644 index 0000000..44885c7 Binary files /dev/null and b/resources/sounds/door/blocked2.wav differ diff --git a/resources/sounds/door/blocked3.wav b/resources/sounds/door/blocked3.wav new file mode 100644 index 0000000..310459b Binary files /dev/null and b/resources/sounds/door/blocked3.wav differ diff --git a/resources/sounds/door/close1.wav b/resources/sounds/door/close1.wav new file mode 100644 index 0000000..0590632 Binary files /dev/null and b/resources/sounds/door/close1.wav differ diff --git a/resources/sounds/door/close2.wav b/resources/sounds/door/close2.wav new file mode 100644 index 0000000..c3b181d Binary files /dev/null and b/resources/sounds/door/close2.wav differ diff --git a/resources/sounds/door/close3.wav b/resources/sounds/door/close3.wav new file mode 100644 index 0000000..604db8e Binary files /dev/null and b/resources/sounds/door/close3.wav differ diff --git a/resources/sounds/door/open1.wav b/resources/sounds/door/open1.wav new file mode 100644 index 0000000..c98b961 Binary files /dev/null and b/resources/sounds/door/open1.wav differ diff --git a/resources/sounds/door/open2.wav b/resources/sounds/door/open2.wav new file mode 100644 index 0000000..38b5bd3 Binary files /dev/null and b/resources/sounds/door/open2.wav differ diff --git a/resources/sounds/door/open3.wav b/resources/sounds/door/open3.wav new file mode 100644 index 0000000..1252ce8 Binary files /dev/null and b/resources/sounds/door/open3.wav differ diff --git a/src/effects/sound.rs b/src/effects/sound.rs index 4831e81..1a9f972 100644 --- a/src/effects/sound.rs +++ b/src/effects/sound.rs @@ -3,7 +3,7 @@ use notan::prelude::*; use specs::prelude::*; use std::sync::Mutex; use std::collections::HashMap; -use super::{ EffectSpawner, EffectType }; +use super::{ EffectSpawner, EffectType, Targets, add_effect }; use crate::Map; lazy_static::lazy_static! { @@ -53,6 +53,17 @@ pub fn play_sound(app: &mut App, ecs: &mut World, effect: &EffectSpawner, target } } +pub fn stop(app: &mut App) { + let mut ambience = AMBIENCE.lock().unwrap(); + if let Some(old) = ambience.take() { + app.audio.stop(&old); + } +} + +pub fn ambience(sound: &str) { + add_effect(None, EffectType::Sound { sound: sound.to_string() }, Targets::Tile { target: 0 }) +} + pub fn replace_ambience(app: &mut App, sound: &Sound) { let mut ambience = AMBIENCE.lock().unwrap(); if let Some(old) = ambience.take() { @@ -62,12 +73,21 @@ pub fn replace_ambience(app: &mut App, sound: &Sound) { } pub fn init_sounds(app: &mut App) { - let list: Vec<(&str, (&[u8], AudioType))> = vec![ - //key, (bytes, type) - audiotype determines final volume, looping, etc. - ("hit", (include_bytes!("../../resources/sounds/hit.wav"), AudioType::SFX)) + let sound_data: &[(&str, &[u8], AudioType)] = &[ + // (key, file_path, audiotype) + ("a_relax", include_bytes!("../../resources/sounds/amb/relaxed.wav"), AudioType::Ambient), + ("d_blocked1", include_bytes!("../../resources/sounds/door/blocked1.wav"), AudioType::SFX), + ("d_blocked2", include_bytes!("../../resources/sounds/door/blocked2.wav"), AudioType::SFX), + ("d_blocked3", include_bytes!("../../resources/sounds/door/blocked3.wav"), AudioType::SFX), + ("d_open1", include_bytes!("../../resources/sounds/door/open1.wav"), AudioType::SFX), + ("d_open2", include_bytes!("../../resources/sounds/door/open2.wav"), AudioType::SFX), + ("d_open3", include_bytes!("../../resources/sounds/door/open3.wav"), AudioType::SFX), + ("d_close1", include_bytes!("../../resources/sounds/door/close1.wav"), AudioType::SFX), + ("d_close2", include_bytes!("../../resources/sounds/door/close2.wav"), AudioType::SFX), + ("d_close3", include_bytes!("../../resources/sounds/door/close3.wav"), AudioType::SFX), ]; let mut sounds = SOUNDS.lock().unwrap(); - for (k, (bytes, audiotype)) in list.iter() { + for (k, bytes, audiotype) in sound_data { sounds.insert(k.to_string(), (app.audio.create_source(bytes).unwrap(), *audiotype)); } } @@ -76,3 +96,42 @@ pub fn set_volume(vol: f32) { let mut volume = VOLUME.lock().unwrap(); *volume = vol; } + +pub fn clean(app: &mut App) { + app.audio.clean(); +} + +// Shorthand functions for adding generic, frequent SFX to the effect queue. +pub fn door_open(idx: usize) { + let mut rng = RandomNumberGenerator::new(); + let sound = ( + match rng.range(0, 3) { + 0 => "d_open1", + 1 => "d_open2", + _ => "d_open3", + } + ).to_string(); + super::add_effect(None, EffectType::Sound { sound }, Targets::Tile { target: idx }); +} +pub fn door_resist(idx: usize) { + let mut rng = RandomNumberGenerator::new(); + let sound = ( + match rng.range(0, 3) { + 0 => "d_blocked1", + 1 => "d_blocked2", + _ => "d_blocked3", + } + ).to_string(); + add_effect(None, EffectType::Sound { sound }, Targets::Tile { target: idx }); +} +pub fn door_close(idx: usize) { + let mut rng = RandomNumberGenerator::new(); + let sound = ( + match rng.range(0, 3) { + 0 => "d_close1", + 1 => "d_close2", + _ => "d_close3", + } + ).to_string(); + add_effect(None, EffectType::Sound { sound }, Targets::Tile { target: idx }); +} diff --git a/src/main.rs b/src/main.rs index f067a8e..1ad708b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,7 @@ fn main() -> Result<(), String> { fn setup(app: &mut App, gfx: &mut Graphics) -> State { effects::sound::init_sounds(app); + effects::sound::ambience("a_relax"); let texture = gfx .create_texture() .from_image(include_bytes!("../resources/atlas.png")) diff --git a/src/player.rs b/src/player.rs index 4d98cff..a0139d6 100644 --- a/src/player.rs +++ b/src/player.rs @@ -34,6 +34,7 @@ use super::{ get_dest, Destination, DamageType, + effects::sound, }; use bracket_lib::prelude::*; use specs::prelude::*; @@ -93,6 +94,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { if door.open == true { let renderables = ecs.read_storage::(); if multiple_tile_content { + sound::door_resist(destination_idx); if let Some(name) = names.get(potential_target) { gamelog::Logger ::new() @@ -104,6 +106,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { .log(); } } else if rng.roll_dice(1, 6) + attributes.strength.modifier() < 2 { + sound::door_resist(destination_idx); if let Some(name) = names.get(potential_target) { gamelog::Logger ::new() @@ -115,6 +118,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { .log(); } } else { + sound::door_close(destination_idx); door.open = false; if door.blocks_vis { blocks_visibility @@ -210,6 +214,7 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState { if door.open == false { let renderables = ecs.read_storage::(); if rng.roll_dice(1, 6) + attributes.strength.modifier() < 2 { + sound::door_resist(destination_idx); if let Some(name) = names.get(potential_target) { gamelog::Logger ::new() @@ -221,6 +226,7 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState { .log(); } } else { + sound::door_open(destination_idx); door.open = true; blocks_visibility.remove(potential_target); blocks_movement.remove(potential_target);