use std::{fmt::Debug, hash::Hash, time::Duration}; use bevy::{asset::HandleId, prelude::*, transform::TransformSystem}; use bevy_openal::{Buffer, Sound, SoundState}; 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: f32, pub pitch: f32, pub reference_distance: f32, pub max_distance: f32, pub rolloff_factor: f32, pub interval: Option, } impl Default for SoundIcon { fn default() -> Self { let seconds = random::() + 4.5; let mut icon = Self { sound: "".into(), gain: 0.3, pitch: 1., reference_distance: 1., max_distance: f32::MAX, rolloff_factor: 1., 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 add_sound_icon_sounds( mut commands: Commands, icons: Query<(Entity, &SoundIcon), Added>, assets: Res>, ) { for (entity, icon) in icons.iter() { let buffer = assets.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_factor = icon.rolloff_factor; commands.run_if_exists(entity, move |mut entity| { entity.insert(Sound { buffer, gain, pitch, looping, state: SoundState::Stopped, reference_distance, max_distance, rolloff_factor, ..default() }); }); } } fn update( config: Res>, state: Res>, time: Res