use std::{fmt::Debug, hash::Hash, time::Duration}; use bevy::{asset::HandleId, prelude::*, transform::TransformSystem}; use bevy_synthizer::{DistanceMax, DistanceRef, Rolloff, Sound}; use rand::random; use crate::{ commands::RunIfExistsExt, core::Player, exploration::ExplorationFocused, visibility::{Visible, VisibleEntities}, }; #[derive(Component, Clone, Debug)] pub struct SoundIcon { pub sound: HandleId, pub gain: f64, pub pitch: f64, pub reference_distance: Option, pub max_distance: Option, pub rolloff: Option, pub interval: Option, } impl Default for SoundIcon { fn default() -> Self { let seconds = random::() + 4.5; let mut icon = Self { sound: "".into(), gain: 1., pitch: 1., reference_distance: None, max_distance: None, rolloff: None, interval: Some(Timer::from_seconds(seconds, true)), }; if let Some(ref mut interval) = icon.interval { let seconds = Duration::from_secs_f32(seconds - 0.1); interval.set_elapsed(seconds); } icon } } #[derive(Bundle, Clone, Debug, Default)] pub struct SoundIconBundle { pub sound_icon: SoundIcon, pub transform: Transform, pub global_transform: GlobalTransform, } fn added( mut commands: Commands, asset_server: Res, icons: Query<(Entity, &SoundIcon), Added>, ) { for (entity, icon) in icons.iter() { let buffer = asset_server.get_handle(icon.sound); let gain = icon.gain; let pitch = icon.pitch; let looping = icon.interval.is_none(); let reference_distance = icon.reference_distance; let max_distance = icon.max_distance; let rolloff = icon.rolloff; commands.run_if_exists(entity, move |mut entity| { entity.insert(Sound { buffer, gain, pitch, looping, paused: true, ..default() }); if let Some(v) = reference_distance { entity.insert(DistanceRef(v)); } if let Some(v) = max_distance { entity.insert(DistanceMax(v)); } if let Some(v) = rolloff { entity.insert(Rolloff(v)); } }); } } fn update( mut commands: Commands, config: Res>, state: Res>, time: Res