From 5c7332b4692986f8c0ca969d79a6eb39feca686a Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 20 Mar 2025 03:30:57 +0000 Subject: [PATCH] add Event::Spawn --- azalea-client/src/plugins/events.rs | 41 +++++++++++++++++--- azalea-client/src/plugins/packet/game/mod.rs | 2 +- azalea-entity/src/lib.rs | 4 +- azalea-physics/src/fluids.rs | 2 +- 4 files changed, 40 insertions(+), 9 deletions(-) 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, ); diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs index 32b0a19f..88a1cfff 100644 --- a/azalea-entity/src/lib.rs +++ b/azalea-entity/src/lib.rs @@ -50,7 +50,7 @@ pub fn move_relative( pub fn input_vector(direction: &LookDirection, speed: f32, acceleration: &Vec3) -> Vec3 { let distance = acceleration.length_squared(); if distance < 1.0E-7 { - return Vec3::default(); + return Vec3::ZERO; } let acceleration = if distance > 1.0 { acceleration.normalize() @@ -307,7 +307,7 @@ pub struct Physics { impl Physics { pub fn new(dimensions: EntityDimensions, pos: Vec3) -> Self { Self { - velocity: Vec3::default(), + velocity: Vec3::ZERO, vec_delta_codec: VecDeltaCodec::new(pos), old_position: pos, diff --git a/azalea-physics/src/fluids.rs b/azalea-physics/src/fluids.rs index f8643b9c..c4716a27 100644 --- a/azalea-physics/src/fluids.rs +++ b/azalea-physics/src/fluids.rs @@ -109,7 +109,7 @@ fn update_fluid_height_and_do_fluid_pushing( let mut min_height_touching = 0.; let is_entity_pushable_by_fluid = true; let mut touching_fluid = false; - let mut additional_player_delta = Vec3::default(); + let mut additional_player_delta = Vec3::ZERO; let mut num_fluids_being_touched = 0; for cur_x in min_x..max_x {