mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add new version of combat soundtrack, and change details of how transitions between tracks work.
This commit is contained in:
parent
0e16c23707
commit
f1b022cdee
6
assets/voxygen/audio/music_transition_manifest.ron
Normal file
6
assets/voxygen/audio/music_transition_manifest.ron
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(
|
||||||
|
combat_nearby_radius: 40.0,
|
||||||
|
combat_health_factor: 1000,
|
||||||
|
combat_nearby_high_thresh: 4,
|
||||||
|
combat_nearby_low_thresh: 1,
|
||||||
|
)
|
@ -374,21 +374,20 @@
|
|||||||
artist: "badbbad",
|
artist: "badbbad",
|
||||||
)),
|
)),
|
||||||
Segmented(
|
Segmented(
|
||||||
title: "Combat1",
|
title: "Barred Paths",
|
||||||
author: "DaforLynx",
|
author: "DaforLynx",
|
||||||
timing: None,
|
timing: None,
|
||||||
biomes: [],
|
biomes: [],
|
||||||
site: Some(Dungeon),
|
site: Some(Dungeon),
|
||||||
segments: [
|
segments: [
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-hi-loop", 54.0, State(Combat(High))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-end", 6.0, Transition(Combat(High), Explore), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-hi-start", 55.0, Transition(Explore, Combat(High))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-loop", 54.0, State(Combat(High)), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-lo-loop", 7.0, State(Combat(Low))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-hi-start", 55.0, Transition(Explore, Combat(High)), Some(Combat(High))),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-lo-start", 10.0, Transition(Explore, Combat(Low))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-end", 3.0, Transition(Combat(Low), Explore), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-trans-hi-lo", 10.0, Transition(Combat(High), Combat(Low))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-loop", 7.0, State(Combat(Low)), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-trans-lo-hi", 7.0, Transition(Combat(Low), Combat(High))),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-lo-start", 10.0, Transition(Explore, Combat(Low)), None),
|
||||||
// temporary until more assets exist:
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-trans-hi-lo", 10.0, Transition(Combat(High), Combat(Low)), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-trans-hi-lo", 10.0, Transition(Combat(High), Explore)),
|
("voxygen.audio.soundtrack.barred_paths.barred_paths-trans-lo-hi", 7.0, Transition(Combat(Low), Combat(High)), None),
|
||||||
("voxygen.audio.soundtrack.combat1.combat1-lo-loop", 7.0, Transition(Combat(Low), Explore)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-end.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-end.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-loop.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-loop.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-start.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-hi-start.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-end.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-end.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-loop.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-loop.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-start.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-lo-start.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-trans-hi-lo.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-trans-hi-lo.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-trans-lo-hi.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/soundtrack/barred_paths/barred_paths-trans-lo-hi.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-hi-loop.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-hi-loop.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-hi-start.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-hi-start.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-lo-loop.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-lo-loop.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-lo-start.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-lo-start.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-trans-hi-lo.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-trans-hi-lo.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-trans-lo-hi.ogg
(Stored with Git LFS)
BIN
assets/voxygen/audio/soundtrack/combat1/combat1-trans-lo-hi.ogg
(Stored with Git LFS)
Binary file not shown.
@ -50,6 +50,7 @@ use common::{
|
|||||||
terrain::{BiomeKind, SitesKind},
|
terrain::{BiomeKind, SitesKind},
|
||||||
};
|
};
|
||||||
use common_sys::state::State;
|
use common_sys::state::State;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use rand::{prelude::SliceRandom, thread_rng, Rng};
|
use rand::{prelude::SliceRandom, thread_rng, Rng};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
@ -84,6 +85,11 @@ pub struct SoundtrackItem {
|
|||||||
/// What the player is doing when the track is played (i.e. exploring,
|
/// What the player is doing when the track is played (i.e. exploring,
|
||||||
/// combat)
|
/// combat)
|
||||||
activity: MusicActivity,
|
activity: MusicActivity,
|
||||||
|
/// What activity to override the activity state with, if any (e.g. to make
|
||||||
|
/// a long combat intro also act like the loop for the purposes of outro
|
||||||
|
/// transitions)
|
||||||
|
#[serde(default)]
|
||||||
|
activity_override: Option<MusicActivityState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
@ -94,7 +100,7 @@ enum RawSoundtrackItem {
|
|||||||
timing: Option<DayPeriod>,
|
timing: Option<DayPeriod>,
|
||||||
biomes: Vec<(BiomeKind, u8)>,
|
biomes: Vec<(BiomeKind, u8)>,
|
||||||
site: Option<SitesKind>,
|
site: Option<SitesKind>,
|
||||||
segments: Vec<(String, f32, MusicActivity)>,
|
segments: Vec<(String, f32, MusicActivity, Option<MusicActivityState>)>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +152,47 @@ pub struct MusicMgr {
|
|||||||
/// being played twice in a row
|
/// being played twice in a row
|
||||||
last_track: String,
|
last_track: String,
|
||||||
/// The previous track's activity kind, for transitions
|
/// The previous track's activity kind, for transitions
|
||||||
last_activity: MusicActivityState,
|
last_activity: MusicActivity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct MusicTransitionManifest {
|
||||||
|
/// Within what radius do enemies count towards combat music?
|
||||||
|
combat_nearby_radius: f32,
|
||||||
|
/// Each multiple of this factor that an enemy has health counts as an extra
|
||||||
|
/// enemy
|
||||||
|
combat_health_factor: u32,
|
||||||
|
/// How many nearby enemies trigger High combat music
|
||||||
|
combat_nearby_high_thresh: u32,
|
||||||
|
/// How many nearby enemies trigger Low combat music
|
||||||
|
combat_nearby_low_thresh: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MusicTransitionManifest {
|
||||||
|
fn default() -> MusicTransitionManifest {
|
||||||
|
MusicTransitionManifest {
|
||||||
|
combat_nearby_radius: 40.0,
|
||||||
|
combat_health_factor: 1000,
|
||||||
|
combat_nearby_high_thresh: 3,
|
||||||
|
combat_nearby_low_thresh: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl assets::Asset for MusicTransitionManifest {
|
||||||
|
type Loader = assets::RonLoader;
|
||||||
|
|
||||||
|
const EXTENSION: &'static str = "ron";
|
||||||
|
|
||||||
|
fn default_value(id: &str, e: assets::Error) -> Result<MusicTransitionManifest, assets::Error> {
|
||||||
|
warn!("Error loading MusicTransitionManifest {:?}: {:?}", id, e);
|
||||||
|
Ok(MusicTransitionManifest::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref MUSIC_TRANSITION_MANIFEST: AssetHandle<MusicTransitionManifest> =
|
||||||
|
AssetExt::load_expect("voxygen.audio.music_transition_manifest");
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MusicMgr {
|
impl Default for MusicMgr {
|
||||||
@ -156,7 +202,7 @@ impl Default for MusicMgr {
|
|||||||
began_playing: Instant::now(),
|
began_playing: Instant::now(),
|
||||||
next_track_change: 0.0,
|
next_track_change: 0.0,
|
||||||
last_track: String::from("None"),
|
last_track: String::from("None"),
|
||||||
last_activity: MusicActivityState::Explore,
|
last_activity: MusicActivity::State(MusicActivityState::Explore),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,34 +231,41 @@ impl MusicMgr {
|
|||||||
let positions = ecs.read_component::<Pos>();
|
let positions = ecs.read_component::<Pos>();
|
||||||
let healths = ecs.read_component::<Health>();
|
let healths = ecs.read_component::<Health>();
|
||||||
let groups = ecs.read_component::<Group>();
|
let groups = ecs.read_component::<Group>();
|
||||||
|
let mtm = MUSIC_TRANSITION_MANIFEST.read();
|
||||||
if let Some(player_pos) = positions.get(player) {
|
if let Some(player_pos) = positions.get(player) {
|
||||||
const NEARBY_RADIUS: f32 = 50.0;
|
|
||||||
const HEALTH_FACTOR: u32 = 100;
|
|
||||||
let num_nearby_entities: u32 = (&entities, &positions, &healths, &groups)
|
let num_nearby_entities: u32 = (&entities, &positions, &healths, &groups)
|
||||||
.join()
|
.join()
|
||||||
.map(|(entity, pos, health, group)| {
|
.map(|(entity, pos, health, group)| {
|
||||||
if entity != player
|
if entity != player
|
||||||
&& group == &ENEMY
|
&& group == &ENEMY
|
||||||
&& (player_pos.0 - pos.0).magnitude_squared() < NEARBY_RADIUS.powf(2.0)
|
&& (player_pos.0 - pos.0).magnitude_squared()
|
||||||
|
< mtm.combat_nearby_radius.powf(2.0)
|
||||||
{
|
{
|
||||||
(health.maximum() / HEALTH_FACTOR).max(1)
|
(health.maximum() / mtm.combat_health_factor).max(1)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
if num_nearby_entities > 2 {
|
if num_nearby_entities >= mtm.combat_nearby_high_thresh {
|
||||||
activity_state = Combat(CombatIntensity::High);
|
activity_state = Combat(CombatIntensity::High);
|
||||||
} else if num_nearby_entities >= 1 {
|
} else if num_nearby_entities >= mtm.combat_nearby_low_thresh {
|
||||||
activity_state = Combat(CombatIntensity::Low);
|
activity_state = Combat(CombatIntensity::Low);
|
||||||
}
|
}
|
||||||
|
trace!(
|
||||||
|
"in audio maintain: {:?} {:?}",
|
||||||
|
activity_state,
|
||||||
|
num_nearby_entities
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let activity = if self.last_activity != activity_state {
|
let activity = match self.last_activity {
|
||||||
MusicActivity::Transition(self.last_activity, activity_state)
|
MusicActivity::State(prev) if prev != activity_state => {
|
||||||
} else {
|
MusicActivity::Transition(prev, activity_state)
|
||||||
MusicActivity::State(activity_state)
|
},
|
||||||
|
MusicActivity::Transition(_, next) => MusicActivity::State(next),
|
||||||
|
_ => MusicActivity::State(activity_state),
|
||||||
};
|
};
|
||||||
|
|
||||||
let interrupt = matches!(activity, MusicActivity::Transition(_, _));
|
let interrupt = matches!(activity, MusicActivity::Transition(_, _));
|
||||||
@ -221,9 +274,13 @@ impl MusicMgr {
|
|||||||
&& !self.soundtrack.read().tracks.is_empty()
|
&& !self.soundtrack.read().tracks.is_empty()
|
||||||
&& (self.began_playing.elapsed().as_secs_f32() > self.next_track_change || interrupt)
|
&& (self.began_playing.elapsed().as_secs_f32() > self.next_track_change || interrupt)
|
||||||
{
|
{
|
||||||
trace!("in audio maintain: {:?} {:?}", self.last_activity, activity);
|
trace!(
|
||||||
if let Ok(()) = self.play_random_track(audio, state, client, &activity) {
|
"pre-play_random_track: {:?} {:?}",
|
||||||
self.last_activity = activity_state;
|
self.last_activity,
|
||||||
|
activity
|
||||||
|
);
|
||||||
|
if let Ok(next_activity) = self.play_random_track(audio, state, client, &activity) {
|
||||||
|
self.last_activity = next_activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +291,7 @@ impl MusicMgr {
|
|||||||
state: &State,
|
state: &State,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
activity: &MusicActivity,
|
activity: &MusicActivity,
|
||||||
) -> Result<(), ()> {
|
) -> Result<MusicActivity, ()> {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
// Adds a bit of randomness between plays
|
// Adds a bit of randomness between plays
|
||||||
@ -254,7 +311,7 @@ impl MusicMgr {
|
|||||||
// too many constraints. Returning Err(()) signals that we couldn't find
|
// too many constraints. Returning Err(()) signals that we couldn't find
|
||||||
// an appropriate track for the current state, and hence the state
|
// an appropriate track for the current state, and hence the state
|
||||||
// machine for the activity shouldn't be updated.
|
// machine for the activity shouldn't be updated.
|
||||||
let mut res = Ok(());
|
let mut res = Ok(*activity);
|
||||||
let soundtrack = self.soundtrack.read();
|
let soundtrack = self.soundtrack.read();
|
||||||
// First, filter out tracks not matching the timing, site, and biome
|
// First, filter out tracks not matching the timing, site, and biome
|
||||||
let mut maybe_tracks = soundtrack
|
let mut maybe_tracks = soundtrack
|
||||||
@ -339,16 +396,15 @@ impl MusicMgr {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(track) = new_maybe_track {
|
if let Ok(track) = new_maybe_track {
|
||||||
|
if let Some(state) = track.activity_override {
|
||||||
|
res = Ok(MusicActivity::State(state));
|
||||||
|
}
|
||||||
//println!("Now playing {:?}", track.title);
|
//println!("Now playing {:?}", track.title);
|
||||||
self.last_track = String::from(&track.title);
|
self.last_track = String::from(&track.title);
|
||||||
self.began_playing = Instant::now();
|
self.began_playing = Instant::now();
|
||||||
self.next_track_change = track.length + silence_between_tracks_seconds;
|
self.next_track_change = track.length + silence_between_tracks_seconds;
|
||||||
|
|
||||||
let tag = if matches!(
|
let tag = if matches!(activity, MusicActivity::State(MusicActivityState::Explore)) {
|
||||||
activity,
|
|
||||||
MusicActivity::State(MusicActivityState::Explore)
|
|
||||||
| MusicActivity::Transition(_, MusicActivityState::Explore)
|
|
||||||
) {
|
|
||||||
MusicChannelTag::Exploration
|
MusicChannelTag::Exploration
|
||||||
} else {
|
} else {
|
||||||
MusicChannelTag::Combat
|
MusicChannelTag::Combat
|
||||||
@ -398,7 +454,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
|
|||||||
site,
|
site,
|
||||||
segments,
|
segments,
|
||||||
} => {
|
} => {
|
||||||
for (path, length, activity) in segments.into_iter() {
|
for (path, length, activity, activity_override) in segments.into_iter() {
|
||||||
soundtracks.tracks.push(SoundtrackItem {
|
soundtracks.tracks.push(SoundtrackItem {
|
||||||
title: title.clone(),
|
title: title.clone(),
|
||||||
path,
|
path,
|
||||||
@ -407,6 +463,7 @@ impl assets::Compound for SoundtrackCollection<SoundtrackItem> {
|
|||||||
biomes: biomes.clone(),
|
biomes: biomes.clone(),
|
||||||
site,
|
site,
|
||||||
activity,
|
activity,
|
||||||
|
activity_override,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user