From eeec59adabb8c084c8b6b847a31130eb7c37d2ee Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 12 Oct 2023 22:39:29 -0500 Subject: KnockbackEvent and rename Physics::delta to velocity --- azalea-client/src/movement.rs | 55 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'azalea-client/src/movement.rs') diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index 28628115..f4bb8836 100644 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -1,5 +1,6 @@ use crate::client::Client; use crate::local_player::SendPacketEvent; +use azalea_core::position::Vec3; use azalea_entity::{metadata::Sprinting, Attributes, Jumping}; use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position}; use azalea_physics::{ai_step, PhysicsSet}; @@ -13,6 +14,7 @@ use azalea_protocol::packets::game::{ use azalea_world::{MinecraftEntityId, MoveEntityError}; use bevy_app::{App, FixedUpdate, Plugin, Update}; use bevy_ecs::prelude::{Event, EventWriter}; +use bevy_ecs::schedule::SystemSet; use bevy_ecs::{ component::Component, entity::Entity, event::EventReader, query::With, schedule::IntoSystemConfigs, system::Query, @@ -44,7 +46,13 @@ impl Plugin for PlayerMovePlugin { fn build(&self, app: &mut App) { app.add_event::() .add_event::() - .add_systems(Update, (sprint_listener, walk_listener).chain()) + .add_event::() + .add_systems( + Update, + (handle_sprint, handle_walk, handle_knockback) + .chain() + .in_set(MoveEventsSet), + ) .add_systems( FixedUpdate, ( @@ -60,6 +68,9 @@ impl Plugin for PlayerMovePlugin { } } +#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] +pub struct MoveEventsSet; + impl Client { /// Set whether we're jumping. This acts as if you held space in /// vanilla. If you want to jump once, use the `jump` function. @@ -391,10 +402,9 @@ pub struct StartWalkEvent { pub direction: WalkDirection, } -/// Start walking in the given direction. To sprint, use -/// [`Client::sprint`]. To stop walking, call walk with -/// `WalkDirection::None`. -pub fn walk_listener( +/// The system that makes the player start walking when they receive a +/// [`StartWalkEvent`]. +pub fn handle_walk( mut events: EventReader, mut query: Query<(&mut PhysicsState, &mut Sprinting, &mut Attributes)>, ) { @@ -415,8 +425,9 @@ pub struct StartSprintEvent { pub entity: Entity, pub direction: SprintDirection, } -/// Start sprinting in the given direction. -pub fn sprint_listener( +/// The system that makes the player start sprinting when they receive a +/// [`StartSprintEvent`]. +pub fn handle_sprint( mut query: Query<&mut PhysicsState>, mut events: EventReader, ) { @@ -459,6 +470,36 @@ fn has_enough_impulse_to_start_sprinting(physics_state: &PhysicsState) -> bool { // } } +/// An event sent by the server that sets or adds to our velocity. Usually +/// `KnockbackKind::Set` is used for normal knockback and `KnockbackKind::Add` +/// is used for explosions, but some servers (notably Hypixel) use explosions +/// for knockback. +#[derive(Event)] +pub struct KnockbackEvent { + pub entity: Entity, + pub kind: KnockbackType, +} + +pub enum KnockbackType { + Set(Vec3), + Add(Vec3), +} + +pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: EventReader) { + for event in events.iter() { + if let Ok(mut physics) = query.get_mut(event.entity) { + match event.kind { + KnockbackType::Set(velocity) => { + physics.velocity = velocity; + } + KnockbackType::Add(velocity) => { + physics.velocity += velocity; + } + } + } + } +} + #[derive(Clone, Copy, Debug, Default)] pub enum WalkDirection { #[default] -- cgit v1.2.3