From 82386a57c4af314346715ec10ddc60eaabca70c2 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sat, 11 Jan 2025 15:54:26 +0100 Subject: [PATCH] parse game event at compile time --- assets/game_event.json | 1 + assets/message_type.json | 1 + pumpkin-data/build/build.rs | 2 ++ pumpkin-data/build/game_event.rs | 27 +++++++++++++++++++++++++++ pumpkin-data/src/lib.rs | 4 ++++ pumpkin/src/block/blocks/chest.rs | 4 ++-- pumpkin/src/entity/player.rs | 4 ++-- pumpkin/src/net/combat.rs | 26 +++++--------------------- pumpkin/src/world/mod.rs | 11 ++++++++--- 9 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 assets/game_event.json create mode 100644 assets/message_type.json create mode 100644 pumpkin-data/build/game_event.rs diff --git a/assets/game_event.json b/assets/game_event.json new file mode 100644 index 000000000..9bbd09957 --- /dev/null +++ b/assets/game_event.json @@ -0,0 +1 @@ +["block_activate","block_attach","block_change","block_close","block_deactivate","block_destroy","block_detach","block_open","block_place","container_close","container_open","drink","eat","elytra_glide","entity_damage","entity_die","entity_dismount","entity_interact","entity_mount","entity_place","entity_action","equip","explode","flap","fluid_pickup","fluid_place","hit_ground","instrument_play","item_interact_finish","item_interact_start","jukebox_play","jukebox_stop_play","lightning_strike","note_block_play","prime_fuse","projectile_land","projectile_shoot","sculk_sensor_tendrils_clicking","shear","shriek","splash","step","swim","teleport","unequip","resonate_1","resonate_2","resonate_3","resonate_4","resonate_5","resonate_6","resonate_7","resonate_8","resonate_9","resonate_10","resonate_11","resonate_12","resonate_13","resonate_14","resonate_15"] \ No newline at end of file diff --git a/assets/message_type.json b/assets/message_type.json new file mode 100644 index 000000000..9d2003a85 --- /dev/null +++ b/assets/message_type.json @@ -0,0 +1 @@ +{"chat":{"data":{"chat":{"translation_key":"chat.type.text","parameters":["sender","content"]},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}},"emote_command":{"data":{"chat":{"translation_key":"chat.type.emote","parameters":["sender","content"]},"narration":{"translation_key":"chat.type.emote","parameters":["sender","content"]}}},"msg_command_incoming":{"data":{"chat":{"translation_key":"commands.message.display.incoming","parameters":["sender","content"],"style":{"italic":true,"color":"gray"}},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}},"msg_command_outgoing":{"data":{"chat":{"translation_key":"commands.message.display.outgoing","parameters":["target","content"],"style":{"italic":true,"color":"gray"}},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}},"say_command":{"data":{"chat":{"translation_key":"chat.type.announcement","parameters":["sender","content"]},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}},"team_msg_command_incoming":{"data":{"chat":{"translation_key":"chat.type.team.text","parameters":["target","sender","content"]},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}},"team_msg_command_outgoing":{"data":{"chat":{"translation_key":"chat.type.team.sent","parameters":["target","sender","content"]},"narration":{"translation_key":"chat.type.text.narrate","parameters":["sender","content"]}}}} \ No newline at end of file diff --git a/pumpkin-data/build/build.rs b/pumpkin-data/build/build.rs index 33024f6cb..f893d9125 100644 --- a/pumpkin-data/build/build.rs +++ b/pumpkin-data/build/build.rs @@ -4,6 +4,7 @@ use proc_macro2::{Span, TokenStream}; use syn::Ident; mod chunk_status; +mod game_event; mod packet; mod particle; mod screen; @@ -15,6 +16,7 @@ pub fn main() { write_generated_file(particle::build(), "particle.rs"); write_generated_file(sound::build(), "sound.rs"); write_generated_file(chunk_status::build(), "chunk_status.rs"); + write_generated_file(game_event::build(), "game_event.rs"); } pub fn write_generated_file(content: TokenStream, out_file: &str) { diff --git a/pumpkin-data/build/game_event.rs b/pumpkin-data/build/game_event.rs new file mode 100644 index 000000000..aed8bf0ca --- /dev/null +++ b/pumpkin-data/build/game_event.rs @@ -0,0 +1,27 @@ +use heck::ToPascalCase; +use proc_macro2::TokenStream; +use quote::quote; + +use crate::ident; + +pub(crate) fn build() -> TokenStream { + println!("cargo:rerun-if-changed=assets/game_event.json"); + + let game_event: Vec = + serde_json::from_str(include_str!("../../assets/game_event.json")) + .expect("Failed to parse game_event.json"); + let mut variants = TokenStream::new(); + + for event in game_event.iter() { + let name = ident(event.to_pascal_case()); + variants.extend([quote! { + #name, + }]); + } + quote! { + #[repr(u8)] + pub enum GameEvent { + #variants + } + } +} diff --git a/pumpkin-data/src/lib.rs b/pumpkin-data/src/lib.rs index aa6626e34..f6fa0cd86 100644 --- a/pumpkin-data/src/lib.rs +++ b/pumpkin-data/src/lib.rs @@ -17,3 +17,7 @@ pub mod sound { pub mod chunk_status { include!(concat!(env!("OUT_DIR"), "/chunk_status.rs")); } + +pub mod game_event { + include!(concat!(env!("OUT_DIR"), "/game_event.rs")); +} diff --git a/pumpkin/src/block/blocks/chest.rs b/pumpkin/src/block/blocks/chest.rs index 7dda0bcc9..dafe43437 100644 --- a/pumpkin/src/block/blocks/chest.rs +++ b/pumpkin/src/block/blocks/chest.rs @@ -114,12 +114,12 @@ impl ChestBlock { if state == ChestState::IsClosed && num_players == 0 { player .world() - .play_block_sound(Sound::BlockChestClose as u16, location) + .play_block_sound(Sound::BlockChestClose, location) .await; } else if state == ChestState::IsOpened && num_players == 1 { player .world() - .play_block_sound(Sound::BlockChestOpen as u16, location) + .play_block_sound(Sound::BlockChestOpen, location) .await; } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 48859a35d..c7677299f 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -317,7 +317,7 @@ impl Player { { world .play_sound( - Sound::EntityPlayerAttackNodamage as u16, + Sound::EntityPlayerAttackNodamage, SoundCategory::Players, &pos, ) @@ -326,7 +326,7 @@ impl Player { } world - .play_sound(Sound::EntityPlayerHurt as u16, SoundCategory::Players, &pos) + .play_sound(Sound::EntityPlayerHurt, SoundCategory::Players, &pos) .await; let attack_type = AttackType::new(self, attack_cooldown_progress as f32).await; diff --git a/pumpkin/src/net/combat.rs b/pumpkin/src/net/combat.rs index d71b1f423..caf30b26b 100644 --- a/pumpkin/src/net/combat.rs +++ b/pumpkin/src/net/combat.rs @@ -121,7 +121,7 @@ pub async fn player_attack_sound(pos: &Vector3, world: &World, attack_type: AttackType::Knockback => { world .play_sound( - Sound::EntityPlayerAttackKnockback as u16, + Sound::EntityPlayerAttackKnockback, SoundCategory::Players, pos, ) @@ -129,38 +129,22 @@ pub async fn player_attack_sound(pos: &Vector3, world: &World, attack_type: } AttackType::Critical => { world - .play_sound( - Sound::EntityPlayerAttackCrit as u16, - SoundCategory::Players, - pos, - ) + .play_sound(Sound::EntityPlayerAttackCrit, SoundCategory::Players, pos) .await; } AttackType::Sweeping => { world - .play_sound( - Sound::EntityPlayerAttackSweep as u16, - SoundCategory::Players, - pos, - ) + .play_sound(Sound::EntityPlayerAttackSweep, SoundCategory::Players, pos) .await; } AttackType::Strong => { world - .play_sound( - Sound::EntityPlayerAttackStrong as u16, - SoundCategory::Players, - pos, - ) + .play_sound(Sound::EntityPlayerAttackStrong, SoundCategory::Players, pos) .await; } AttackType::Weak => { world - .play_sound( - Sound::EntityPlayerAttackWeak as u16, - SoundCategory::Players, - pos, - ) + .play_sound(Sound::EntityPlayerAttackWeak, SoundCategory::Players, pos) .await; } }; diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 687749c23..1f7fe097a 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -11,6 +11,7 @@ use crate::{ }; use level_time::LevelTime; use pumpkin_config::BasicConfiguration; +use pumpkin_data::sound::Sound; use pumpkin_entity::{entity_type::EntityType, pose::EntityPose, EntityId}; use pumpkin_protocol::{ client::play::CLevelEvent, @@ -155,7 +156,11 @@ impl World { } } - pub async fn play_sound( + pub async fn play_sound(&self, sound: Sound, category: SoundCategory, position: &Vector3) { + self.play_sound_raw(sound as u16, category, position).await; + } + + pub async fn play_sound_raw( &self, sound_id: u16, category: SoundCategory, @@ -176,13 +181,13 @@ impl World { .await; } - pub async fn play_block_sound(&self, sound_id: u16, position: WorldPosition) { + pub async fn play_block_sound(&self, sound: Sound, position: WorldPosition) { let new_vec = Vector3::new( f64::from(position.0.x) + 0.5, f64::from(position.0.y) + 0.5, f64::from(position.0.z) + 0.5, ); - self.play_sound(sound_id, SoundCategory::Blocks, &new_vec) + self.play_sound(sound, SoundCategory::Blocks, &new_vec) .await; }