diff options
| author | mat <git@matdoes.dev> | 2023-10-12 22:39:29 -0500 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-10-12 22:39:29 -0500 |
| commit | eeec59adabb8c084c8b6b847a31130eb7c37d2ee (patch) | |
| tree | 6ffa8e6d83ba5d6095062abf06406edf7f10d276 /azalea-client | |
| parent | 79ad1e93bf6ce2b7c2da6925a7c85b33bb76f154 (diff) | |
| download | azalea-drasl-eeec59adabb8c084c8b6b847a31130eb7c37d2ee.tar.xz | |
KnockbackEvent and rename Physics::delta to velocity
Diffstat (limited to 'azalea-client')
| -rw-r--r-- | azalea-client/src/attack.rs | 6 | ||||
| -rw-r--r-- | azalea-client/src/interact.rs | 3 | ||||
| -rw-r--r-- | azalea-client/src/mining.rs | 2 | ||||
| -rw-r--r-- | azalea-client/src/movement.rs | 55 | ||||
| -rw-r--r-- | azalea-client/src/packet_handling/game.rs | 44 |
5 files changed, 82 insertions, 28 deletions
diff --git a/azalea-client/src/attack.rs b/azalea-client/src/attack.rs index 644af5de..56f3b1d0 100644 --- a/azalea-client/src/attack.rs +++ b/azalea-client/src/attack.rs @@ -15,7 +15,7 @@ use derive_more::{Deref, DerefMut}; use crate::{ interact::SwingArmEvent, local_player::{LocalGameMode, SendPacketEvent}, - movement::walk_listener, + movement::MoveEventsSet, respawn::perform_respawn, Client, }; @@ -28,7 +28,7 @@ impl Plugin for AttackPlugin { Update, handle_attack_event .before(update_bounding_box) - .before(walk_listener) + .before(MoveEventsSet) .after(perform_respawn), ) .add_systems( @@ -106,7 +106,7 @@ pub fn handle_attack_event( ticks_since_last_attack.0 = 0; - physics.delta = physics.delta.multiply(0.6, 1.0, 0.6); + physics.velocity = physics.velocity.multiply(0.6, 1.0, 0.6); **sprinting = false; } } diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs index b7b47ec6..32b68925 100644 --- a/azalea-client/src/interact.rs +++ b/azalea-client/src/interact.rs @@ -37,6 +37,7 @@ use crate::{ local_player::{ handle_send_packet_event, LocalGameMode, PermissionLevel, PlayerAbilities, SendPacketEvent, }, + movement::MoveEventsSet, respawn::perform_respawn, Client, }; @@ -62,7 +63,7 @@ impl Plugin for InteractPlugin { .chain(), update_modifiers_for_held_item .after(InventorySet) - .after(crate::movement::walk_listener), + .after(MoveEventsSet), ), ); } diff --git a/azalea-client/src/mining.rs b/azalea-client/src/mining.rs index 806a7b91..e1193f73 100644 --- a/azalea-client/src/mining.rs +++ b/azalea-client/src/mining.rs @@ -18,6 +18,7 @@ use crate::{ }, inventory::{InventoryComponent, InventorySet}, local_player::{LocalGameMode, PermissionLevel, PlayerAbilities, SendPacketEvent}, + movement::MoveEventsSet, Client, }; @@ -43,6 +44,7 @@ impl Plugin for MinePlugin { .chain() .in_set(MiningSet) .after(InventorySet) + .after(MoveEventsSet) .before(azalea_entity::update_bounding_box) .after(azalea_entity::update_fluid_on_eyes) .after(crate::interact::update_hit_result_component) 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::<StartWalkEvent>() .add_event::<StartSprintEvent>() - .add_systems(Update, (sprint_listener, walk_listener).chain()) + .add_event::<KnockbackEvent>() + .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<StartWalkEvent>, 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<StartSprintEvent>, ) { @@ -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<KnockbackEvent>) { + 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] diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs index 6e138565..1d8c6cc9 100644 --- a/azalea-client/src/packet_handling/game.rs +++ b/azalea-client/src/packet_handling/game.rs @@ -44,6 +44,7 @@ use crate::{ GameProfileComponent, Hunger, InstanceHolder, LocalGameMode, PlayerAbilities, SendPacketEvent, TabList, }, + movement::{KnockbackEvent, KnockbackType}, raw_connection::RawConnection, ClientInformation, PlayerInfo, ReceivedRegistries, }; @@ -422,7 +423,7 @@ pub fn process_packet_events(ecs: &mut World) { continue; }; - let delta_movement = physics.delta; + let delta_movement = physics.velocity; let is_x_relative = p.relative_arguments.x; let is_y_relative = p.relative_arguments.y; @@ -459,7 +460,7 @@ pub fn process_packet_events(ecs: &mut World) { y_rot += direction.y_rot; } - physics.delta = Vec3 { + physics.velocity = Vec3 { x: delta_x, y: delta_y, z: delta_z, @@ -797,15 +798,21 @@ pub fn process_packet_events(ecs: &mut World) { continue; }; + // this is to make sure the same entity velocity update doesn't get sent + // multiple times when in swarms commands.entity(entity).add(RelativeEntityUpdate { partial_world: instance_holder.partial_instance.clone(), - update: Box::new(move |entity| { - let mut physics = entity.get_mut::<Physics>().unwrap(); - physics.delta = Vec3 { - x: p.xa as f64 / 8000., - y: p.ya as f64 / 8000., - z: p.za as f64 / 8000., - }; + update: Box::new(move |entity_mut| { + entity_mut.world_scope(|world| { + world.send_event(KnockbackEvent { + entity, + kind: KnockbackType::Set(Vec3 { + x: p.xa as f64 / 8000., + y: p.ya as f64 / 8000., + z: p.za as f64 / 8000., + }), + }) + }); }), }); @@ -1186,15 +1193,18 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::DeleteChat(_) => {} ClientboundGamePacket::Explode(p) => { trace!("Got explode packet {p:?}"); - let mut system_state: SystemState<Query<&mut Physics>> = SystemState::new(ecs); - let mut query = system_state.get_mut(ecs); - let mut physics = query.get_mut(player_entity).unwrap(); + let mut system_state: SystemState<EventWriter<KnockbackEvent>> = + SystemState::new(ecs); + let mut knockback_events = system_state.get_mut(ecs); - physics.delta += Vec3 { - x: p.knockback_x as f64, - y: p.knockback_y as f64, - z: p.knockback_z as f64, - }; + knockback_events.send(KnockbackEvent { + entity: player_entity, + kind: KnockbackType::Set(Vec3 { + x: p.knockback_x as f64, + y: p.knockback_y as f64, + z: p.knockback_z as f64, + }), + }); system_state.apply(ecs); } |
