mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-27 16:11:33 +11:00
50018a52bf
This is my first time contributing here so I was pretty unfamiliar with the codebase and may have done some things incorrectly. ## Description - Added a sound extractor to extract sound event ids and identifiers - Added a `Sound` enum (with a build script) to represent sound effects - Added a `play_sound` method to `Instance` and `Client` - Re-implemented sound effects in the parkour example ## Test Plan I tested this using the sounds I added to the parkour example. #### Related Hopefully fixes #206
120 lines
3.1 KiB
Rust
120 lines
3.1 KiB
Rust
use heck::ToPascalCase;
|
|
use proc_macro2::TokenStream;
|
|
use quote::quote;
|
|
use serde::Deserialize;
|
|
|
|
use crate::ident;
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct Sound {
|
|
id: u16,
|
|
name: String,
|
|
}
|
|
|
|
pub fn build() -> anyhow::Result<TokenStream> {
|
|
let sounds =
|
|
serde_json::from_str::<Vec<Sound>>(include_str!("../../../extracted/sounds.json"))?;
|
|
|
|
let sound_count = sounds.len();
|
|
|
|
let sound_from_raw_id_arms = sounds
|
|
.iter()
|
|
.map(|sound| {
|
|
let id = &sound.id;
|
|
let name = ident(sound.name.to_pascal_case());
|
|
|
|
quote! {
|
|
#id => Some(Self::#name),
|
|
}
|
|
})
|
|
.collect::<TokenStream>();
|
|
|
|
let sound_to_raw_id_arms = sounds
|
|
.iter()
|
|
.map(|sound| {
|
|
let id = &sound.id;
|
|
let name = ident(sound.name.to_pascal_case());
|
|
|
|
quote! {
|
|
Self::#name => #id,
|
|
}
|
|
})
|
|
.collect::<TokenStream>();
|
|
|
|
let sound_from_str_arms = sounds
|
|
.iter()
|
|
.map(|sound| {
|
|
let str_name = &sound.name;
|
|
let name = ident(str_name.to_pascal_case());
|
|
quote! {
|
|
#str_name => Some(Self::#name),
|
|
}
|
|
})
|
|
.collect::<TokenStream>();
|
|
|
|
let sound_to_str_arms = sounds
|
|
.iter()
|
|
.map(|sound| {
|
|
let str_name = &sound.name;
|
|
let name = ident(str_name.to_pascal_case());
|
|
quote! {
|
|
Self::#name => #str_name,
|
|
}
|
|
})
|
|
.collect::<TokenStream>();
|
|
|
|
let sound_variants = sounds
|
|
.iter()
|
|
.map(|sound| ident(sound.name.to_pascal_case()))
|
|
.collect::<Vec<_>>();
|
|
|
|
Ok(quote! {
|
|
/// Represents a sound from the game
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
#[repr(u16)]
|
|
pub enum Sound {
|
|
#(#sound_variants,)*
|
|
}
|
|
|
|
impl Sound {
|
|
/// Constructs a sound from a raw item ID.
|
|
///
|
|
/// If the given ID is invalid, `None` is returned.
|
|
pub const fn from_raw(id: u16) -> Option<Self> {
|
|
match id {
|
|
#sound_from_raw_id_arms
|
|
_ => None
|
|
}
|
|
}
|
|
|
|
/// Gets the raw sound ID from the sound
|
|
pub const fn to_raw(self) -> u16 {
|
|
match self {
|
|
#sound_to_raw_id_arms
|
|
}
|
|
}
|
|
|
|
/// Construct a sound from its snake_case name.
|
|
///
|
|
/// Returns `None` if the name is invalid.
|
|
#[allow(clippy::should_implement_trait)]
|
|
pub fn from_str(name: &str) -> Option<Self> {
|
|
match name {
|
|
#sound_from_str_arms
|
|
_ => None
|
|
}
|
|
}
|
|
|
|
/// Gets the snake_case name of this sound.
|
|
pub const fn to_str(self) -> &'static str {
|
|
match self {
|
|
#sound_to_str_arms
|
|
}
|
|
}
|
|
|
|
/// An array of all sounds.
|
|
pub const ALL: [Self; #sound_count] = [#(Self::#sound_variants,)*];
|
|
}
|
|
})
|
|
}
|