Skip to main content

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}