mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Move music under audio
Also add some blank time after each track so that we get some silence between tracks.
This commit is contained in:
parent
5b46587c2d
commit
b7ce91fead
@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Added music system
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
46
assets/voxygen/audio/soundtrack.ron
Normal file
46
assets/voxygen/audio/soundtrack.ron
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
(
|
||||||
|
tracks: [
|
||||||
|
(
|
||||||
|
title: "Field Grazing",
|
||||||
|
path: "voxygen.audio.soundtrack.field_grazing",
|
||||||
|
length: 154.0,
|
||||||
|
timing: Some(Day),
|
||||||
|
artist: "Aeronic",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
title: "Wandering Voices",
|
||||||
|
path: "voxygen.audio.soundtrack.wandering_voices",
|
||||||
|
length: 137.0,
|
||||||
|
timing: Some(Night),
|
||||||
|
artist: "Aeronic",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
title: "Snowtop Volume",
|
||||||
|
path: "voxygen.audio.soundtrack.snowtop_volume",
|
||||||
|
length: 89.0,
|
||||||
|
timing: Some(Day),
|
||||||
|
artist: "Aeronic",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
title: "Mineral Deposits",
|
||||||
|
path: "voxygen.audio.soundtrack.mineral_deposits",
|
||||||
|
length: 148.0,
|
||||||
|
timing: Some(Day),
|
||||||
|
artist: "Aeronic",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
title: "Moonbeams",
|
||||||
|
path: "voxygen.audio.soundtrack.moonbeams",
|
||||||
|
length: 158.0,
|
||||||
|
timing: Some(Night),
|
||||||
|
artist: "Aeronic",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
title: "Serene Meadows",
|
||||||
|
path: "voxygen.audio.soundtrack.serene_meadows",
|
||||||
|
length: 173.0,
|
||||||
|
timing: Some(Night),
|
||||||
|
artist: "Aeronic",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
BIN
assets/voxygen/audio/soundtrack/field_grazing.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/field_grazing.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/mineral_deposits.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/mineral_deposits.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/moonbeams.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/moonbeams.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/serene_meadows.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/serene_meadows.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/snowtop_volume.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/snowtop_volume.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/wandering_voices.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/wandering_voices.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1,6 +1,5 @@
|
|||||||
use crate::audio::fader::Fader;
|
use crate::audio::fader::Fader;
|
||||||
use rodio::{Decoder, Device, Sample, Source, SpatialSink};
|
use rodio::{Device, Sample, Source, SpatialSink};
|
||||||
use std::{fs::File, io::BufReader};
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
@ -20,12 +19,19 @@ enum ChannelState {
|
|||||||
Stopped,
|
Stopped,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
|
pub enum ChannelTag {
|
||||||
|
TitleMusic,
|
||||||
|
Soundtrack,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
id: usize,
|
id: usize,
|
||||||
sink: SpatialSink,
|
sink: SpatialSink,
|
||||||
audio_type: AudioType,
|
audio_type: AudioType,
|
||||||
state: ChannelState,
|
state: ChannelState,
|
||||||
fader: Fader,
|
fader: Fader,
|
||||||
|
tag: Option<ChannelTag>,
|
||||||
pub pos: Vec3<f32>,
|
pub pos: Vec3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,41 +41,15 @@ impl Channel {
|
|||||||
pub fn new(device: &Device) -> Self {
|
pub fn new(device: &Device) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: 0,
|
id: 0,
|
||||||
sink: SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]),
|
sink: SpatialSink::new(device, [0.0; 3], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]),
|
||||||
audio_type: AudioType::None,
|
audio_type: AudioType::None,
|
||||||
state: ChannelState::Stopped,
|
state: ChannelState::Stopped,
|
||||||
fader: Fader::fade_in(0.0),
|
fader: Fader::fade_in(0.0),
|
||||||
|
tag: None,
|
||||||
pos: Vec3::zero(),
|
pos: Vec3::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn music(id: usize, device: &Device, bufr: BufReader<File>) -> Self {
|
|
||||||
let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]);
|
|
||||||
let sound = Decoder::new(bufr).unwrap();
|
|
||||||
|
|
||||||
sink.append(sound);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
sink,
|
|
||||||
audio_type: AudioType::Music,
|
|
||||||
state: ChannelState::Playing,
|
|
||||||
fader: Fader::fade_in(0.0),
|
|
||||||
pos: Vec3::zero(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sfx(id: usize, sink: SpatialSink, pos: Vec3<f32>) -> Self {
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
sink,
|
|
||||||
audio_type: AudioType::Sfx,
|
|
||||||
state: ChannelState::Playing,
|
|
||||||
fader: Fader::fade_in(0.0),
|
|
||||||
pos,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn play<S>(&mut self, source: S)
|
pub fn play<S>(&mut self, source: S)
|
||||||
where
|
where
|
||||||
S: Source + Send + 'static,
|
S: Source + Send + 'static,
|
||||||
@ -83,6 +63,10 @@ impl Channel {
|
|||||||
|
|
||||||
pub fn is_done(&self) -> bool { self.sink.empty() || self.state == ChannelState::Stopped }
|
pub fn is_done(&self) -> bool { self.sink.empty() || self.state == ChannelState::Stopped }
|
||||||
|
|
||||||
|
pub fn set_tag(&mut self, tag: Option<ChannelTag>) { self.tag = tag; }
|
||||||
|
|
||||||
|
pub fn get_tag(&self) -> Option<ChannelTag> { self.tag }
|
||||||
|
|
||||||
pub fn stop(&mut self, fader: Fader) {
|
pub fn stop(&mut self, fader: Fader) {
|
||||||
self.state = ChannelState::Stopping;
|
self.state = ChannelState::Stopping;
|
||||||
self.fader = fader;
|
self.fader = fader;
|
||||||
|
@ -30,11 +30,11 @@ impl Fader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fade_out(time: f32) -> Self {
|
pub fn fade_out(time: f32, volume_from: f32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
length: time,
|
length: time,
|
||||||
running_time: 0.0,
|
running_time: 0.0,
|
||||||
volume_from: 1.0,
|
volume_from,
|
||||||
volume_to: 0.0,
|
volume_to: 0.0,
|
||||||
is_running: true,
|
is_running: true,
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
pub mod channel;
|
pub mod channel;
|
||||||
pub mod fader;
|
pub mod fader;
|
||||||
|
pub mod music;
|
||||||
pub mod sfx;
|
pub mod sfx;
|
||||||
pub mod soundcache;
|
pub mod soundcache;
|
||||||
|
|
||||||
use channel::{AudioType, Channel};
|
use channel::{AudioType, Channel, ChannelTag};
|
||||||
use fader::Fader;
|
use fader::Fader;
|
||||||
use soundcache::SoundCache;
|
use soundcache::SoundCache;
|
||||||
|
|
||||||
@ -84,7 +85,11 @@ impl AudioFrontend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_channel(&mut self, audio_type: AudioType) -> Option<&mut Channel> {
|
pub fn get_channel(
|
||||||
|
&mut self,
|
||||||
|
audio_type: AudioType,
|
||||||
|
channel_tag: Option<ChannelTag>,
|
||||||
|
) -> Option<&mut Channel> {
|
||||||
if let Some(channel) = self.channels.iter_mut().find(|c| c.is_done()) {
|
if let Some(channel) = self.channels.iter_mut().find(|c| c.is_done()) {
|
||||||
let id = self.next_channel_id;
|
let id = self.next_channel_id;
|
||||||
self.next_channel_id += 1;
|
self.next_channel_id += 1;
|
||||||
@ -95,6 +100,7 @@ impl AudioFrontend {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel.set_id(id);
|
channel.set_id(id);
|
||||||
|
channel.set_tag(channel_tag);
|
||||||
channel.set_audio_type(audio_type);
|
channel.set_audio_type(audio_type);
|
||||||
channel.set_volume(volume);
|
channel.set_volume(volume);
|
||||||
|
|
||||||
@ -114,7 +120,7 @@ impl AudioFrontend {
|
|||||||
let left_ear = self.listener_ear_left.into_array();
|
let left_ear = self.listener_ear_left.into_array();
|
||||||
let right_ear = self.listener_ear_right.into_array();
|
let right_ear = self.listener_ear_right.into_array();
|
||||||
|
|
||||||
if let Some(channel) = self.get_channel(AudioType::Sfx) {
|
if let Some(channel) = self.get_channel(AudioType::Sfx, None) {
|
||||||
channel.set_emitter_position(calc_pos);
|
channel.set_emitter_position(calc_pos);
|
||||||
channel.set_left_ear_position(left_ear);
|
channel.set_left_ear_position(left_ear);
|
||||||
channel.set_right_ear_position(right_ear);
|
channel.set_right_ear_position(right_ear);
|
||||||
@ -127,12 +133,13 @@ impl AudioFrontend {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn play_music(&mut self, sound: &str) -> Option<usize> {
|
pub fn play_music(&mut self, sound: &str, channel_tag: Option<ChannelTag>) -> Option<usize> {
|
||||||
if self.audio_device.is_some() {
|
if self.audio_device.is_some() {
|
||||||
if let Some(channel) = self.get_channel(AudioType::Music) {
|
if let Some(channel) = self.get_channel(AudioType::Music, channel_tag) {
|
||||||
let file = assets::load_file(&sound, &["ogg"]).expect("Failed to load sound");
|
let file = assets::load_file(&sound, &["ogg"]).expect("Failed to load sound");
|
||||||
let sound = Decoder::new(file).expect("Failed to decode sound");
|
let sound = Decoder::new(file).expect("Failed to decode sound");
|
||||||
|
|
||||||
|
channel.set_emitter_position([0.0; 3]);
|
||||||
channel.play(sound);
|
channel.play(sound);
|
||||||
|
|
||||||
return Some(channel.get_id());
|
return Some(channel.get_id());
|
||||||
@ -167,8 +174,30 @@ impl AudioFrontend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn play_title_music(&mut self) -> Option<usize> {
|
||||||
|
if self.music_enabled() {
|
||||||
|
self.play_music(
|
||||||
|
"voxygen.audio.soundtrack.veloren_title_tune",
|
||||||
|
Some(ChannelTag::TitleMusic),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop_title_music(&mut self) {
|
||||||
|
let index = self.channels.iter().position(|c| {
|
||||||
|
!c.is_done() && c.get_tag().is_some() && c.get_tag().unwrap() == ChannelTag::TitleMusic
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(index) = index {
|
||||||
|
self.channels[index].stop(Fader::fade_out(1.5, self.music_volume));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stop_channel(&mut self, channel_id: usize, fader: Fader) {
|
pub fn stop_channel(&mut self, channel_id: usize, fader: Fader) {
|
||||||
let index = self.channels.iter().position(|c| c.get_id() == channel_id);
|
let index = self.channels.iter().position(|c| c.get_id() == channel_id);
|
||||||
|
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
self.channels[index].stop(fader);
|
self.channels[index].stop(fader);
|
||||||
}
|
}
|
||||||
@ -178,6 +207,10 @@ impl AudioFrontend {
|
|||||||
|
|
||||||
pub fn get_music_volume(&self) -> f32 { self.music_volume }
|
pub fn get_music_volume(&self) -> f32 { self.music_volume }
|
||||||
|
|
||||||
|
pub fn sfx_enabled(&self) -> bool { self.sfx_volume > 0.0 }
|
||||||
|
|
||||||
|
pub fn music_enabled(&self) -> bool { self.music_volume > 0.0 }
|
||||||
|
|
||||||
pub fn set_sfx_volume(&mut self, sfx_volume: f32) {
|
pub fn set_sfx_volume(&mut self, sfx_volume: f32) {
|
||||||
self.sfx_volume = sfx_volume;
|
self.sfx_volume = sfx_volume;
|
||||||
|
|
||||||
@ -193,7 +226,11 @@ impl AudioFrontend {
|
|||||||
|
|
||||||
for channel in self.channels.iter_mut() {
|
for channel in self.channels.iter_mut() {
|
||||||
if channel.get_audio_type() == AudioType::Music {
|
if channel.get_audio_type() == AudioType::Music {
|
||||||
channel.set_volume(music_volume);
|
if music_volume > 0.0 {
|
||||||
|
channel.set_volume(music_volume);
|
||||||
|
} else {
|
||||||
|
channel.stop(Fader::fade_out(0.0, 0.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
99
voxygen/src/audio/music.rs
Normal file
99
voxygen/src/audio/music.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use crate::audio::{channel::ChannelTag, AudioFrontend};
|
||||||
|
use client::Client;
|
||||||
|
use common::assets;
|
||||||
|
use rand::{seq::IteratorRandom, thread_rng};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
const DAY_START_SECONDS: u32 = 28800; // 8:00
|
||||||
|
const DAY_END_SECONDS: u32 = 70200; // 19:30
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct SoundtrackCollection {
|
||||||
|
tracks: Vec<SoundtrackItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct SoundtrackItem {
|
||||||
|
title: String,
|
||||||
|
path: String,
|
||||||
|
length: f64,
|
||||||
|
timing: Option<DayPeriod>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, PartialEq)]
|
||||||
|
enum DayPeriod {
|
||||||
|
Day, // 8:00 AM to 7:30 PM
|
||||||
|
Night, // 7:31 PM to 6:59 AM
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MusicMgr {
|
||||||
|
soundtrack: SoundtrackCollection,
|
||||||
|
began_playing: Instant,
|
||||||
|
next_track_change: f64,
|
||||||
|
current_music: Option<usize>,
|
||||||
|
last_track: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MusicMgr {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
soundtrack: Self::load_soundtrack_items(),
|
||||||
|
began_playing: Instant::now(),
|
||||||
|
next_track_change: 0.0,
|
||||||
|
current_music: None,
|
||||||
|
last_track: String::from("None"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) {
|
||||||
|
if audio.music_enabled()
|
||||||
|
&& self.began_playing.elapsed().as_secs_f64() > self.next_track_change
|
||||||
|
{
|
||||||
|
self.current_music = self.play_random_track(audio, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn play_random_track(&mut self, audio: &mut AudioFrontend, client: &Client) -> Option<usize> {
|
||||||
|
const SILENCE_BETWEEN_TRACKS_SECONDS: f64 = 45.0;
|
||||||
|
|
||||||
|
let game_time = (client.state().get_time_of_day() as u64 % 86400) as u32;
|
||||||
|
let current_period_of_day = self.get_current_day_period(game_time);
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
|
let track = self
|
||||||
|
.soundtrack
|
||||||
|
.tracks
|
||||||
|
.iter()
|
||||||
|
.filter(|track| {
|
||||||
|
!track.title.eq(&self.last_track)
|
||||||
|
&& match &track.timing {
|
||||||
|
Some(period_of_day) => period_of_day == ¤t_period_of_day,
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.choose(&mut rng)
|
||||||
|
.expect("Failed to select a random track");
|
||||||
|
|
||||||
|
self.last_track = String::from(&track.title);
|
||||||
|
self.began_playing = Instant::now();
|
||||||
|
self.next_track_change = track.length + SILENCE_BETWEEN_TRACKS_SECONDS;
|
||||||
|
|
||||||
|
audio.play_music(&track.path, Some(ChannelTag::Soundtrack))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_current_day_period(&self, game_time: u32) -> DayPeriod {
|
||||||
|
if game_time > DAY_START_SECONDS && game_time < DAY_END_SECONDS {
|
||||||
|
DayPeriod::Day
|
||||||
|
} else {
|
||||||
|
DayPeriod::Night
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_soundtrack_items() -> SoundtrackCollection {
|
||||||
|
let file = assets::load_file("voxygen.audio.soundtrack", &["ron"])
|
||||||
|
.expect("Failed to load the soundtrack config file");
|
||||||
|
|
||||||
|
ron::de::from_reader(file).expect("Error parsing soundtrack manifest")
|
||||||
|
}
|
||||||
|
}
|
@ -51,6 +51,10 @@ impl SfxMgr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) {
|
pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) {
|
||||||
|
if !audio.sfx_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.event_mapper.maintain(client, &self.triggers);
|
self.event_mapper.maintain(client, &self.triggers);
|
||||||
|
|
||||||
let ecs = client.state().ecs();
|
let ecs = client.state().ecs();
|
||||||
|
@ -44,10 +44,11 @@ impl PlayState for MainMenuState {
|
|||||||
let mut client_init: Option<ClientInit> = None;
|
let mut client_init: Option<ClientInit> = None;
|
||||||
|
|
||||||
// Kick off title music
|
// Kick off title music
|
||||||
if self.title_music_channel.is_none() && global_state.settings.audio.audio_on {
|
if self.title_music_channel.is_none()
|
||||||
self.title_music_channel = global_state
|
&& global_state.settings.audio.audio_on
|
||||||
.audio
|
&& global_state.audio.music_enabled()
|
||||||
.play_music("voxygen.audio.soundtrack.veloren_title_tune");
|
{
|
||||||
|
self.title_music_channel = global_state.audio.play_title_music();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset singleplayer server if it was running already
|
// Reset singleplayer server if it was running already
|
||||||
|
@ -5,11 +5,12 @@ pub mod terrain;
|
|||||||
use self::{
|
use self::{
|
||||||
camera::{Camera, CameraMode},
|
camera::{Camera, CameraMode},
|
||||||
figure::FigureMgr,
|
figure::FigureMgr,
|
||||||
|
music::MusicMgr,
|
||||||
terrain::Terrain,
|
terrain::Terrain,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
anim::character::SkeletonAttr,
|
anim::character::SkeletonAttr,
|
||||||
audio::{sfx::SfxMgr, AudioFrontend},
|
audio::{music, sfx::SfxMgr, AudioFrontend},
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
||||||
PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
||||||
@ -58,6 +59,7 @@ pub struct Scene {
|
|||||||
|
|
||||||
figure_mgr: FigureMgr,
|
figure_mgr: FigureMgr,
|
||||||
sfx_mgr: SfxMgr,
|
sfx_mgr: SfxMgr,
|
||||||
|
music_mgr: MusicMgr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
@ -91,6 +93,7 @@ impl Scene {
|
|||||||
|
|
||||||
figure_mgr: FigureMgr::new(),
|
figure_mgr: FigureMgr::new(),
|
||||||
sfx_mgr: SfxMgr::new(),
|
sfx_mgr: SfxMgr::new(),
|
||||||
|
music_mgr: MusicMgr::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,8 +315,9 @@ impl Scene {
|
|||||||
// Remove unused figures.
|
// Remove unused figures.
|
||||||
self.figure_mgr.clean(client.get_tick());
|
self.figure_mgr.clean(client.get_tick());
|
||||||
|
|
||||||
// Maintain sfx
|
// Maintain audio
|
||||||
self.sfx_mgr.maintain(audio, client);
|
self.sfx_mgr.maintain(audio, client);
|
||||||
|
self.music_mgr.maintain(audio, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the scene using the provided `Renderer`.
|
/// Render the scene using the provided `Renderer`.
|
||||||
|
@ -126,6 +126,9 @@ impl PlayState for SessionState {
|
|||||||
let mut clock = Clock::start();
|
let mut clock = Clock::start();
|
||||||
self.client.borrow_mut().clear_terrain();
|
self.client.borrow_mut().clear_terrain();
|
||||||
|
|
||||||
|
// Kill the title music if it is still playing
|
||||||
|
global_state.audio.stop_title_music();
|
||||||
|
|
||||||
// Send startup commands to the server
|
// Send startup commands to the server
|
||||||
if global_state.settings.send_logon_commands {
|
if global_state.settings.send_logon_commands {
|
||||||
for cmd in &global_state.settings.logon_commands {
|
for cmd in &global_state.settings.logon_commands {
|
||||||
|
Loading…
Reference in New Issue
Block a user