yog_formats/sound.rs
1//! `.ysound` — a sound event: what the game plays when it's played. The
2//! sounds themselves are `.yres` sounds (`sound: @Sounds.abacus1`) as given
3//! — any format, normalised by the build — or the game's sound files
4//! (`file: "minecraft:dig/sand1"`); this says which of them play,
5//! how loud and how high, and the subtitle shown. Its id is its path under
6//! `resources/sound/` with `/` as `.` (`resources/sound/casting/cast.ysound`
7//! is `<mod id>:casting.cast`), named elsewhere as `@sound:<id>`. Yog Data,
8//! like every source format; the build writes the game's `sounds.json`.
9
10use yog_data::{Res, Schema};
11
12/// Where `.ysound` files live, under `resources/`.
13pub const DIR: &str = yog_ids::kind::SOUND;
14
15/// A `.ysound`.
16#[derive(Schema, Debug, Clone, PartialEq)]
17pub struct SoundFile {
18 /// What plays: one of them, picked by weight.
19 pub sounds: Vec<Variant>,
20 /// The subtitle shown when it plays: a `.yres` text.
21 pub subtitle: Option<Res>,
22 /// Replaces the game's own sounds of the same event (another mod's, a resource pack's).
23 #[data(default)]
24 pub replace: bool,
25}
26
27/// One sound an event may play: the mod's own (`sound`), one of the
28/// game's (or another mod's) sound files (`file`), or a montage of them
29/// (`mix`, rendered by the build) — one of them.
30#[derive(Schema, Debug, Clone, PartialEq)]
31pub struct Variant {
32 /// The mod's sound: a `.yres` sound.
33 pub sound: Option<Res>,
34 /// A sound file the game has (`minecraft:dig/sand1`, under its
35 /// `sounds/`; no namespace: the game's).
36 pub file: Option<String>,
37 /// A sound made of others: clips on a timeline, with effects.
38 pub mix: Option<crate::montage::Mix>,
39 /// 1 if not given.
40 pub volume: Option<f32>,
41 /// 1 if not given.
42 pub pitch: Option<f32>,
43 /// How often it's picked against the others (1 if not given).
44 pub weight: Option<u32>,
45 /// Streamed, not loaded whole: long sounds (music, ambience).
46 #[data(default)]
47 pub stream: bool,
48 /// Loaded with the resources, not when first played.
49 #[data(default)]
50 pub preload: bool,
51 /// Blocks it carries (16 if not given).
52 pub attenuation_distance: Option<u32>,
53}
54
55/// An event's id from its file's path under `resources/` (`sound/casting/cast.ysound`)
56/// and the mod's id; none for a file outside `resources/sound/`.
57#[must_use]
58pub fn id_of(mod_id: &str, rel: &str) -> Option<String> {
59 crate::resource_id(mod_id, rel, DIR, yog_ids::Format::Sound)
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn an_event_is_named_by_its_path_under_sound() {
68 assert_eq!(
69 id_of("hex", "sound/casting/cast.ysound").as_deref(),
70 Some("hex:casting.cast")
71 );
72 assert_eq!(
73 id_of("hex", "sound/abacus.ysound").as_deref(),
74 Some("hex:abacus")
75 );
76 assert_eq!(id_of("hex", "block/abacus.ysound"), None);
77 assert_eq!(id_of("hex", "sound/abacus.ytexture"), None);
78 }
79}