From 308c125a2062cf772d8a916e5578b13acd70078d Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sat, 11 Jan 2025 17:06:21 +0100 Subject: [PATCH] parse world events at compile time --- assets/world_event.json | 1 + pumpkin-data/build/build.rs | 2 ++ pumpkin-data/build/world_event.rs | 29 +++++++++++++++++++++++++++++ pumpkin-data/src/lib.rs | 4 ++++ pumpkin/src/world/mod.rs | 9 +++++++-- 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 assets/world_event.json create mode 100644 pumpkin-data/build/world_event.rs diff --git a/assets/world_event.json b/assets/world_event.json new file mode 100644 index 000000000..cb83377c3 --- /dev/null +++ b/assets/world_event.json @@ -0,0 +1 @@ +{"DISPENSER_DISPENSES":1000,"DISPENSER_FAILS":1001,"DISPENSER_LAUNCHES_PROJECTILE":1002,"FIREWORK_ROCKET_SHOOTS":1004,"FIRE_EXTINGUISHED":1009,"JUKEBOX_STARTS_PLAYING":1010,"JUKEBOX_STOPS_PLAYING":1011,"GHAST_WARNS":1015,"GHAST_SHOOTS":1016,"ENDER_DRAGON_SHOOTS":1017,"BLAZE_SHOOTS":1018,"ZOMBIE_ATTACKS_WOODEN_DOOR":1019,"ZOMBIE_ATTACKS_IRON_DOOR":1020,"ZOMBIE_BREAKS_WOODEN_DOOR":1021,"WITHER_BREAKS_BLOCK":1022,"WITHER_SPAWNS":1023,"WITHER_SHOOTS":1024,"BAT_TAKES_OFF":1025,"ZOMBIE_INFECTS_VILLAGER":1026,"ZOMBIE_VILLAGER_CURED":1027,"ENDER_DRAGON_DIES":1028,"ANVIL_DESTROYED":1029,"ANVIL_USED":1030,"ANVIL_LANDS":1031,"TRAVEL_THROUGH_PORTAL":1032,"CHORUS_FLOWER_GROWS":1033,"CHORUS_FLOWER_DIES":1034,"BREWING_STAND_BREWS":1035,"END_PORTAL_OPENED":1038,"PHANTOM_BITES":1039,"ZOMBIE_CONVERTS_TO_DROWNED":1040,"HUSK_CONVERTS_TO_ZOMBIE":1041,"GRINDSTONE_USED":1042,"LECTERN_BOOK_PAGE_TURNED":1043,"SMITHING_TABLE_USED":1044,"POINTED_DRIPSTONE_LANDS":1045,"POINTED_DRIPSTONE_DRIPS_LAVA_INTO_CAULDRON":1046,"POINTED_DRIPSTONE_DRIPS_WATER_INTO_CAULDRON":1047,"SKELETON_CONVERTS_TO_STRAY":1048,"CRAFTER_CRAFTS":1049,"CRAFTER_FAILS":1050,"field_51787":1051,"COMPOSTER_USED":1500,"LAVA_EXTINGUISHED":1501,"REDSTONE_TORCH_BURNS_OUT":1502,"END_PORTAL_FRAME_FILLED":1503,"POINTED_DRIPSTONE_DRIPS":1504,"BONE_MEAL_USED":1505,"DISPENSER_ACTIVATED":2000,"BLOCK_BROKEN":2001,"SPLASH_POTION_SPLASHED":2002,"EYE_OF_ENDER_BREAKS":2003,"SPAWNER_SPAWNS_MOB":2004,"DRAGON_BREATH_CLOUD_SPAWNS":2006,"INSTANT_SPLASH_POTION_SPLASHED":2007,"ENDER_DRAGON_BREAKS_BLOCK":2008,"WET_SPONGE_DRIES_OUT":2009,"CRAFTER_SHOOTS":2010,"BEE_FERTILIZES_PLANT":2011,"TURTLE_EGG_PLACED":2012,"SMASH_ATTACK":2013,"END_GATEWAY_SPAWNS":3000,"ENDER_DRAGON_RESURRECTED":3001,"ELECTRICITY_SPARKS":3002,"BLOCK_WAXED":3003,"WAX_REMOVED":3004,"BLOCK_SCRAPED":3005,"SCULK_CHARGE":3006,"SCULK_SHRIEKS":3007,"BLOCK_FINISHED_BRUSHING":3008,"SNIFFER_EGG_CRACKS":3009,"TRIAL_SPAWNER_SPAWNS_MOB":3011,"TRIAL_SPAWNER_SPAWNS_MOB_AT_SPAWN_POS":3012,"TRIAL_SPAWNER_DETECTS_PLAYER":3013,"TRIAL_SPAWNER_EJECTS_ITEM":3014,"VAULT_ACTIVATES":3015,"VAULT_DEACTIVATES":3016,"VAULT_EJECTS_ITEM":3017,"COBWEB_WEAVED":3018,"OMINOUS_TRIAL_SPAWNER_DETECTS_PLAYER":3019,"TRIAL_SPAWNER_TURNS_OMINOUS":3020,"OMINOUS_ITEM_SPAWNER_SPAWNS_ITEM":3021} \ No newline at end of file diff --git a/pumpkin-data/build/build.rs b/pumpkin-data/build/build.rs index ab4d62966..329537342 100644 --- a/pumpkin-data/build/build.rs +++ b/pumpkin-data/build/build.rs @@ -14,6 +14,7 @@ mod scoreboard_slot; mod screen; mod sound; mod sound_category; +mod world_event; pub fn main() { write_generated_file(packet::build(), "packet.rs"); @@ -25,6 +26,7 @@ pub fn main() { write_generated_file(sound_category::build(), "sound_category.rs"); write_generated_file(entity_pose::build(), "entity_pose.rs"); write_generated_file(scoreboard_slot::build(), "scoreboard_slot.rs"); + write_generated_file(world_event::build(), "world_event.rs"); } pub fn array_to_tokenstream(array: Vec) -> TokenStream { diff --git a/pumpkin-data/build/world_event.rs b/pumpkin-data/build/world_event.rs new file mode 100644 index 000000000..526054abf --- /dev/null +++ b/pumpkin-data/build/world_event.rs @@ -0,0 +1,29 @@ +use std::collections::HashMap; + +use heck::ToPascalCase; +use proc_macro2::TokenStream; +use quote::quote; + +use crate::ident; + +pub(crate) fn build() -> TokenStream { + println!("cargo:rerun-if-changed=assets/world_event.json"); + + let events: HashMap = + serde_json::from_str(include_str!("../../assets/world_event.json")) + .expect("Failed to parse world_event.json"); + let mut variants = TokenStream::new(); + + for (event, id) in events.iter() { + let name = ident(event.to_pascal_case()); + variants.extend([quote! { + #name = #id, + }]); + } + quote! { + #[repr(u16)] + pub enum WorldEvent { + #variants + } + } +} diff --git a/pumpkin-data/src/lib.rs b/pumpkin-data/src/lib.rs index 00f210ae9..edd739355 100644 --- a/pumpkin-data/src/lib.rs +++ b/pumpkin-data/src/lib.rs @@ -27,6 +27,10 @@ pub mod entity { include!(concat!(env!("OUT_DIR"), "/entity_pose.rs")); } +pub mod world { + include!(concat!(env!("OUT_DIR"), "/world_event.rs")); +} + pub mod scoreboard { include!(concat!(env!("OUT_DIR"), "/scoreboard_slot.rs")); } diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 50a2d0f5c..78e57762f 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -14,6 +14,7 @@ use pumpkin_config::BasicConfiguration; use pumpkin_data::{ entity::EntityPose, sound::{Sound, SoundCategory}, + world::WorldEvent, }; use pumpkin_entity::{entity_type::EntityType, EntityId}; use pumpkin_protocol::client::play::{CBlockUpdate, CRespawn, CSoundEffect, CWorldEvent}; @@ -886,8 +887,12 @@ impl World { pub async fn break_block(&self, position: WorldPosition, cause: Option<&Player>) { let broken_block_state_id = self.set_block_state(position, 0).await; - let particles_packet = - CWorldEvent::new(2001, &position, broken_block_state_id.into(), false); + let particles_packet = CWorldEvent::new( + WorldEvent::BlockBroken as i32, + &position, + broken_block_state_id.into(), + false, + ); match cause { Some(player) => {