From 5c7332b4692986f8c0ca969d79a6eb39feca686a Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 20 Mar 2025 03:30:57 +0000 Subject: add Event::Spawn --- azalea-client/src/plugins/events.rs | 41 ++++++++++++++++++++++++---- azalea-client/src/plugins/packet/game/mod.rs | 2 +- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'azalea-client/src/plugins') diff --git a/azalea-client/src/plugins/events.rs b/azalea-client/src/plugins/events.rs index 0e30118a..011fbc4a 100644 --- a/azalea-client/src/plugins/events.rs +++ b/azalea-client/src/plugins/events.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use azalea_chat::FormattedText; use azalea_core::tick::GameTick; -use azalea_entity::Dead; +use azalea_entity::{Dead, InLoadedChunk}; use azalea_protocol::packets::game::{ ClientboundGamePacket, c_player_combat_kill::ClientboundPlayerCombatKill, }; @@ -13,10 +13,11 @@ use azalea_world::{InstanceName, MinecraftEntityId}; use bevy_app::{App, Plugin, PreUpdate, Update}; use bevy_ecs::{ component::Component, + entity::Entity, event::EventReader, - query::{Added, With}, + query::{Added, With, Without}, schedule::IntoSystemConfigs, - system::Query, + system::{Commands, Query}, }; use derive_more::{Deref, DerefMut}; use tokio::sync::mpsc; @@ -65,11 +66,23 @@ pub enum Event { /// information with `Client::set_client_information`, so the packet /// doesn't have to be sent twice. /// - /// You may want to use [`Event::Login`] instead to wait for the bot to be + /// You may want to use [`Event::Spawn`] instead to wait for the bot to be /// in the world. Init, - /// The client is now in the world. Fired when we receive a login packet. + /// Fired when we receive a login packet, which is after [`Event::Init`] but + /// before [`Event::Spawn`]. You usually want [`Event::Spawn`] instead. + /// + /// Your position will be [`Vec3::ZERO`] immediately after you receive this + /// packet, but it'll be ready by the time you get [`Event::Spawn`]. + /// + /// [`Vec3::ZERO`]: azalea_core::position::Vec3::ZERO Login, + /// Fired when the player fully spawns into the world and is ready to + /// interact with it. + /// + /// This is usually the event you should listen for when waiting for the bot + /// to be ready. + Spawn, /// A chat message was sent in the game chat. Chat(ChatPacket), /// Happens 20 times per second, but only when the world is loaded. @@ -125,6 +138,7 @@ impl Plugin for EventsPlugin { ( chat_listener, login_listener, + spawn_listener, packet_listener, add_player_listener, update_player_listener, @@ -156,6 +170,23 @@ pub fn login_listener(query: Query<&LocalPlayerEvents, Added> } } +/// A unit struct component that indicates that the entity has sent +/// [`Event::Spawn`]. +/// +/// This is just used internally by the [`spawn_listener`] system to avoid +/// sending the event twice for the same client. +#[derive(Component)] +pub struct SentSpawnEvent; +pub fn spawn_listener( + query: Query<(Entity, &LocalPlayerEvents), (Added, Without)>, + mut commands: Commands, +) { + for (entity, local_player_events) in &query { + let _ = local_player_events.send(Event::Spawn); + commands.entity(entity).insert(SentSpawnEvent); + } +} + pub fn chat_listener(query: Query<&LocalPlayerEvents>, mut events: EventReader) { for event in events.read() { let local_player_events = query diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs index 42aa0f9b..1e9232bf 100644 --- a/azalea-client/src/plugins/packet/game/mod.rs +++ b/azalea-client/src/plugins/packet/game/mod.rs @@ -1482,7 +1482,7 @@ impl GamePacketHandler<'_> { // this resets a bunch of our components like physics and stuff let entity_bundle = EntityBundle::new( game_profile.uuid, - Vec3::default(), + Vec3::ZERO, azalea_registry::EntityKind::Player, new_instance_name, ); -- cgit v1.2.3