mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'DaforLynx/event-music' into 'master'
Event music can use more than one event at a time. Added test for soundtracks. See merge request veloren/veloren!3686
This commit is contained in:
commit
97f3fa56d3
13
assets/voxygen/audio/calendar/christmas/soundtrack.ron
Normal file
13
assets/voxygen/audio/calendar/christmas/soundtrack.ron
Normal file
@ -0,0 +1,13 @@
|
||||
// Times: Some(Day or Night) or None [both]
|
||||
// Weathers: Some(Clear, Cloudy, Rain, or Storm) or None [any weather]
|
||||
// Biomes: Grassland, Forest, Desert, Snowland, Lake, Mountain, Ocean, Jungle, Savannah, Taiga
|
||||
// planned biomes: Swamp
|
||||
// Number after biome indicates weighting; higher numbers are less frequent
|
||||
// Sites: Settlement(Default, Cliff, or Desert), Cave, Dungeon(Old or Gnarling), or Void [none]
|
||||
// Music states: Activity(Explore or Combat)
|
||||
// Combat music is looped. Needs three files: start, loop, and end. Start contains leadup to the loop.
|
||||
// It's recommended to also have appropriate metadata for those who listen via the game files :)
|
||||
|
||||
(
|
||||
tracks: []
|
||||
)
|
@ -142,7 +142,7 @@
|
||||
"voxygen.audio.sfx.footsteps.stepdirt_4",
|
||||
"voxygen.audio.sfx.footsteps.stepdirt_5",
|
||||
],
|
||||
threshold: 1.6,
|
||||
threshold: 1.8,
|
||||
),
|
||||
QuadRun(Earth): (
|
||||
files: [
|
||||
@ -152,7 +152,7 @@
|
||||
"voxygen.audio.sfx.footsteps.stepdirt_4",
|
||||
"voxygen.audio.sfx.footsteps.stepdirt_5",
|
||||
],
|
||||
threshold: 0.8,
|
||||
threshold: 0.9,
|
||||
),
|
||||
Run(Grass): (
|
||||
files: [
|
||||
|
@ -1,8 +1,9 @@
|
||||
use chrono::{DateTime, Datelike, Local, TimeZone, Utc};
|
||||
use chrono_tz::Tz;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::EnumIter;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, EnumIter)]
|
||||
#[repr(u16)]
|
||||
pub enum CalendarEvent {
|
||||
Christmas = 0,
|
||||
|
@ -56,7 +56,7 @@ use hashbrown::HashMap;
|
||||
use rand::{prelude::SliceRandom, thread_rng, Rng};
|
||||
use serde::Deserialize;
|
||||
use std::time::Instant;
|
||||
use tracing::{debug, trace, warn};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
/// Collection of all the tracks
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -151,7 +151,7 @@ enum PlayState {
|
||||
/// Provides methods to control music playback
|
||||
pub struct MusicMgr {
|
||||
/// Collection of all the tracks
|
||||
soundtrack: AssetHandle<SoundtrackCollection<SoundtrackItem>>,
|
||||
soundtrack: SoundtrackCollection<SoundtrackItem>,
|
||||
/// Instant at which the current track began playing
|
||||
began_playing: Instant,
|
||||
/// Time until the next track should be played
|
||||
@ -310,7 +310,7 @@ impl MusicMgr {
|
||||
}
|
||||
|
||||
if audio.music_enabled()
|
||||
&& !self.soundtrack.read().tracks.is_empty()
|
||||
&& !self.soundtrack.tracks.is_empty()
|
||||
&& (self.began_playing.elapsed().as_secs_f32() > self.next_track_change || interrupt)
|
||||
{
|
||||
if interrupt {
|
||||
@ -378,10 +378,10 @@ impl MusicMgr {
|
||||
// too many constraints. Returning Err(()) signals that we couldn't find
|
||||
// an appropriate track for the current state, and hence the state
|
||||
// machine for the activity shouldn't be updated.
|
||||
let soundtrack = self.soundtrack.read();
|
||||
// First, filter out tracks not matching the timing, site, biome, and current
|
||||
// activity
|
||||
let mut maybe_tracks = soundtrack
|
||||
let mut maybe_tracks = self
|
||||
.soundtrack
|
||||
.tracks
|
||||
.iter()
|
||||
.filter(|track| {
|
||||
@ -487,24 +487,60 @@ impl MusicMgr {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_soundtrack_items(
|
||||
calendar: &Calendar,
|
||||
) -> AssetHandle<SoundtrackCollection<SoundtrackItem>> {
|
||||
// Cannot fail: A default value is always provided
|
||||
let mut soundtrack = SoundtrackCollection::load_expect("voxygen.audio.soundtrack");
|
||||
/// Loads default soundtrack if no events are active. Otherwise, attempts to
|
||||
/// compile and load all active event soundtracks, falling back to default
|
||||
/// if they are empty.
|
||||
fn load_soundtrack_items(calendar: &Calendar) -> SoundtrackCollection<SoundtrackItem> {
|
||||
let mut soundtrack = SoundtrackCollection::default();
|
||||
// Loads default soundtrack if no events are active
|
||||
if calendar.events().len() == 0 {
|
||||
soundtrack
|
||||
for track in SoundtrackCollection::load_expect("voxygen.audio.soundtrack")
|
||||
.read()
|
||||
.tracks
|
||||
.clone()
|
||||
{
|
||||
soundtrack.tracks.push(track)
|
||||
}
|
||||
} else {
|
||||
// Compiles event-specific soundtracks if any are active
|
||||
for event in calendar.events() {
|
||||
match event {
|
||||
CalendarEvent::Halloween => {
|
||||
soundtrack = SoundtrackCollection::load_expect(
|
||||
for track in SoundtrackCollection::load_expect(
|
||||
"voxygen.audio.calendar.halloween.soundtrack",
|
||||
);
|
||||
)
|
||||
.read()
|
||||
.tracks
|
||||
.clone()
|
||||
{
|
||||
soundtrack.tracks.push(track)
|
||||
}
|
||||
},
|
||||
CalendarEvent::Christmas => {
|
||||
for track in SoundtrackCollection::load_expect(
|
||||
"voxygen.audio.calendar.christmas.soundtrack",
|
||||
)
|
||||
.read()
|
||||
.tracks
|
||||
.clone()
|
||||
{
|
||||
soundtrack.tracks.push(track)
|
||||
}
|
||||
},
|
||||
_ => soundtrack = SoundtrackCollection::load_expect("voxygen.audio.soundtrack"),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback if events are active but give an empty tracklist
|
||||
if soundtrack.tracks.is_empty() {
|
||||
for track in SoundtrackCollection::load_expect("voxygen.audio.soundtrack")
|
||||
.read()
|
||||
.tracks
|
||||
.clone()
|
||||
{
|
||||
soundtrack.tracks.push(track)
|
||||
}
|
||||
soundtrack
|
||||
} else {
|
||||
soundtrack
|
||||
}
|
||||
}
|
||||
@ -517,13 +553,11 @@ impl assets::Asset for SoundtrackCollection<RawSoundtrackItem> {
|
||||
|
||||
impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
|
||||
fn load(_: assets::AnyCache, id: &str) -> Result<Self, assets::BoxedError> {
|
||||
let inner = || -> Result<_, assets::Error> {
|
||||
let manifest: AssetHandle<SoundtrackCollection<RawSoundtrackItem>> =
|
||||
AssetExt::load(id)?;
|
||||
let mut soundtracks = SoundtrackCollection::default();
|
||||
let manifest: AssetHandle<SoundtrackCollection<RawSoundtrackItem>> = AssetExt::load(id)?;
|
||||
let mut soundtrack = SoundtrackCollection::default();
|
||||
for item in manifest.read().tracks.iter().cloned() {
|
||||
match item {
|
||||
RawSoundtrackItem::Individual(track) => soundtracks.tracks.push(track),
|
||||
RawSoundtrackItem::Individual(track) => soundtrack.tracks.push(track),
|
||||
RawSoundtrackItem::Segmented {
|
||||
title,
|
||||
timing,
|
||||
@ -534,7 +568,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
|
||||
artist,
|
||||
} => {
|
||||
for (path, length, music_state, activity_override) in segments.into_iter() {
|
||||
soundtracks.tracks.push(SoundtrackItem {
|
||||
soundtrack.tracks.push(SoundtrackItem {
|
||||
title: title.clone(),
|
||||
path,
|
||||
length,
|
||||
@ -550,14 +584,34 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(soundtracks)
|
||||
};
|
||||
match inner() {
|
||||
Ok(soundtracks) => Ok(soundtracks),
|
||||
Err(e) => {
|
||||
warn!("Error loading soundtracks: {:?}", e);
|
||||
Ok(SoundtrackCollection::default())
|
||||
Ok(soundtrack)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[test]
|
||||
fn test_load_soundtracks() {
|
||||
let _: AssetHandle<SoundtrackCollection<SoundtrackItem>> =
|
||||
SoundtrackCollection::load_expect("voxygen.audio.soundtrack");
|
||||
for event in CalendarEvent::iter() {
|
||||
match event {
|
||||
CalendarEvent::Halloween => {
|
||||
let _: AssetHandle<SoundtrackCollection<SoundtrackItem>> =
|
||||
SoundtrackCollection::load_expect(
|
||||
"voxygen.audio.calendar.halloween.soundtrack",
|
||||
);
|
||||
},
|
||||
CalendarEvent::Christmas => {
|
||||
let _: AssetHandle<SoundtrackCollection<SoundtrackItem>> =
|
||||
SoundtrackCollection::load_expect(
|
||||
"voxygen.audio.calendar.christmas.soundtrack",
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user