Flatten sound icons.

This commit is contained in:
Nolan Darilek 2021-05-24 15:34:38 -05:00
parent 9c26f58724
commit 4b0f23c0db

View File

@ -1,11 +1,6 @@
use std::{collections::HashMap, fmt::Debug, hash::Hash, time::Duration}; use std::{collections::HashMap, fmt::Debug, hash::Hash, time::Duration};
use bevy::{ use bevy::{asset::HandleId, ecs::component::Component, prelude::*, transform::TransformSystem};
asset::{HandleId, LoadState},
ecs::component::Component,
prelude::*,
transform::TransformSystem,
};
use bevy_openal::{Buffer, Context, Sound, SoundState}; use bevy_openal::{Buffer, Context, Sound, SoundState};
use rand::random; use rand::random;
@ -133,22 +128,38 @@ fn footstep(
} }
} }
fn sound_icon<S>( fn add_sound_icon_sounds(
mut commands: Commands, mut commands: Commands,
icons: Query<(Entity, &SoundIcon), Added<SoundIcon>>,
assets: Res<Assets<Buffer>>,
) {
for (entity, icon) in icons.iter() {
let buffer = assets.get_handle(icon.sound);
let looping = icon.interval.is_none();
commands.entity(entity).insert(Sound {
buffer,
gain: icon.gain,
pitch: icon.pitch,
looping,
state: SoundState::Stopped,
..Default::default()
});
}
}
fn sound_icon<S>(
config: Res<SoundConfig<S>>, config: Res<SoundConfig<S>>,
state: Res<State<S>>, state: Res<State<S>>,
time: Res<Time>, time: Res<Time>,
asset_server: Res<AssetServer>, viewers: Query<&Viewshed, With<Player>>,
viewers: Query<(&Player, &Viewshed)>,
mut icons: Query<( mut icons: Query<(
Entity,
&mut SoundIcon, &mut SoundIcon,
Option<&Coordinates>, Option<&Coordinates>,
Option<&Parent>, Option<&Parent>,
Option<&Children>, &mut Sound,
)>, )>,
coordinates_storage: Query<&Coordinates>, coordinates_storage: Query<&Coordinates>,
mut sounds: Query<&mut Sound>, buffers: Res<Assets<Buffer>>,
) where ) where
S: Component + Clone + Debug + Eq + Hash, S: Component + Clone + Debug + Eq + Hash,
{ {
@ -157,8 +168,8 @@ fn sound_icon<S>(
return; return;
} }
} }
for (_, viewer) in viewers.iter() { for viewer in viewers.iter() {
for (entity, mut icon, coordinates, parent, children) in icons.iter_mut() { for (mut icon, coordinates, parent, mut sound) in icons.iter_mut() {
let coords = if let Some(coordinates) = coordinates { let coords = if let Some(coordinates) = coordinates {
*coordinates *coordinates
} else if let Some(parent) = parent { } else if let Some(parent) = parent {
@ -169,61 +180,27 @@ fn sound_icon<S>(
panic!("No `Coordinates` on `SoundIcon` or parent"); panic!("No `Coordinates` on `SoundIcon` or parent");
}; };
if viewer.is_visible(&coords) { if viewer.is_visible(&coords) {
let buffer = asset_server.get_handle(icon.sound); let looping = sound.looping;
if asset_server.get_load_state(&buffer) == LoadState::Loaded { if looping {
let looping = icon.interval.is_none(); sound.state = SoundState::Playing;
let sound = Sound { } else if let Some(interval) = icon.interval.as_mut() {
buffer, interval.tick(time.delta());
gain: icon.gain, if interval.finished() {
pitch: icon.pitch, sound.state = SoundState::Playing;
looping, interval.reset();
state: SoundState::Playing,
..Default::default()
};
if looping && children.is_none() {
let child = commands
.spawn()
.insert(sound)
.insert(Transform::default())
.insert(GlobalTransform::default())
.id();
commands.entity(entity).push_children(&[child]);
} else if let Some(ref mut interval) = icon.interval {
interval.tick(time.delta());
if interval.finished() {
if let Some(children) = children {
for child in children.iter() {
commands.entity(*child).despawn();
}
}
let child = commands
.spawn()
.insert(sound)
.insert(Transform::default())
.insert(GlobalTransform::default())
.id();
commands.entity(entity).push_children(&[child]);
interval.reset();
}
}
if let Some(children) = children {
if let Some(child) = children.get(0) {
if let Ok(mut sound) = sounds.get_mut(*child) {
let buffer = asset_server.get_handle(icon.sound);
if sound.buffer != buffer {
sound.stop();
sound.buffer = buffer;
sound.play();
}
sound.gain = icon.gain;
sound.pitch = icon.pitch;
sound.reference_distance = icon.reference_distance;
sound.max_distance = icon.max_distance;
sound.rolloff_factor = icon.rolloff_factor;
}
}
} }
} }
let buffer = buffers.get_handle(icon.sound);
sound.looping = icon.interval.is_none();
if sound.buffer != buffer {
sound.stop();
sound.buffer = buffer;
}
sound.gain = icon.gain;
sound.pitch = icon.pitch;
sound.reference_distance = icon.reference_distance;
sound.max_distance = icon.max_distance;
sound.rolloff_factor = icon.rolloff_factor;
} }
} }
} }
@ -303,6 +280,7 @@ where
CoreStage::PostUpdate, CoreStage::PostUpdate,
footstep.system().after(TransformSystem::TransformPropagate), footstep.system().after(TransformSystem::TransformPropagate),
) )
.add_system(add_sound_icon_sounds.system())
.add_system_to_stage( .add_system_to_stage(
CoreStage::PostUpdate, CoreStage::PostUpdate,
sound_icon::<S> sound_icon::<S>