Skip to content

Commit

Permalink
KnockbackEvent and rename Physics::delta to velocity
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-1 committed Oct 13, 2023
1 parent 79ad1e9 commit eeec59a
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 58 deletions.
6 changes: 3 additions & 3 deletions azalea-client/src/attack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -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(
Expand Down Expand Up @@ -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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion azalea-client/src/interact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use crate::{
local_player::{
handle_send_packet_event, LocalGameMode, PermissionLevel, PlayerAbilities, SendPacketEvent,
},
movement::MoveEventsSet,
respawn::perform_respawn,
Client,
};
Expand All @@ -62,7 +63,7 @@ impl Plugin for InteractPlugin {
.chain(),
update_modifiers_for_held_item
.after(InventorySet)
.after(crate::movement::walk_listener),
.after(MoveEventsSet),
),
);
}
Expand Down
2 changes: 2 additions & 0 deletions azalea-client/src/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
},
inventory::{InventoryComponent, InventorySet},
local_player::{LocalGameMode, PermissionLevel, PlayerAbilities, SendPacketEvent},
movement::MoveEventsSet,
Client,
};

Expand All @@ -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)
Expand Down
55 changes: 48 additions & 7 deletions azalea-client/src/movement.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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,
Expand Down Expand Up @@ -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,
(
Expand All @@ -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.
Expand Down Expand Up @@ -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)>,
) {
Expand All @@ -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>,
) {
Expand Down Expand Up @@ -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]
Expand Down
44 changes: 27 additions & 17 deletions azalea-client/src/packet_handling/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::{
GameProfileComponent, Hunger, InstanceHolder, LocalGameMode, PlayerAbilities,
SendPacketEvent, TabList,
},
movement::{KnockbackEvent, KnockbackType},
raw_connection::RawConnection,
ClientInformation, PlayerInfo, ReceivedRegistries,
};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.,
}),
})
});
}),
});

Expand Down Expand Up @@ -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);
}
Expand Down
7 changes: 4 additions & 3 deletions azalea-entity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn move_relative(
acceleration: &Vec3,
) {
let input_vector = input_vector(direction, speed, acceleration);
physics.delta += input_vector;
physics.velocity += input_vector;
}

pub fn input_vector(direction: &LookDirection, speed: f32, acceleration: &Vec3) -> Vec3 {
Expand Down Expand Up @@ -208,7 +208,8 @@ pub struct LookDirection {
/// bounding box.
#[derive(Debug, Component, Clone)]
pub struct Physics {
pub delta: Vec3,
/// How fast the entity is moving.
pub velocity: Vec3,

/// X acceleration.
pub xxa: f32,
Expand All @@ -232,7 +233,7 @@ pub struct Physics {
impl Physics {
pub fn new(dimensions: EntityDimensions, pos: &Vec3) -> Self {
Self {
delta: Vec3::default(),
velocity: Vec3::default(),

xxa: 0.,
yya: 0.,
Expand Down
6 changes: 3 additions & 3 deletions azalea-physics/src/collision/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ pub fn move_colliding(
// if self.isRemoved() { return; }

if horizontal_collision {
let delta_movement = &physics.delta;
physics.delta = Vec3 {
let delta_movement = &physics.velocity;
physics.velocity = Vec3 {
x: if x_collision { 0. } else { delta_movement.x },
y: delta_movement.y,
z: if z_collision { 0. } else { delta_movement.z },
Expand All @@ -213,7 +213,7 @@ pub fn move_colliding(
// blockBelow.updateEntityAfterFallOn(this.level, this);
// the default implementation of updateEntityAfterFallOn sets the y movement to
// 0
physics.delta.y = 0.;
physics.velocity.y = 0.;
}

if on_ground {
Expand Down
30 changes: 15 additions & 15 deletions azalea-physics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ fn travel(

// if should_discard_friction(self) {
if false {
physics.delta = movement;
physics.velocity = movement;
} else {
physics.delta = Vec3 {
physics.velocity = Vec3 {
x: movement.x * inertia as f64,
y: movement.y * 0.9800000190734863f64,
z: movement.z * inertia as f64,
Expand Down Expand Up @@ -145,14 +145,14 @@ pub fn ai_step(
// vanilla does movement interpolation here, doesn't really matter much for a
// bot though

if physics.delta.x.abs() < 0.003 {
physics.delta.x = 0.;
if physics.velocity.x.abs() < 0.003 {
physics.velocity.x = 0.;
}
if physics.delta.y.abs() < 0.003 {
physics.delta.y = 0.;
if physics.velocity.y.abs() < 0.003 {
physics.velocity.y = 0.;
}
if physics.delta.z.abs() < 0.003 {
physics.delta.z = 0.;
if physics.velocity.z.abs() < 0.003 {
physics.velocity.z = 0.;
}

if let Some(jumping) = jumping {
Expand Down Expand Up @@ -194,16 +194,16 @@ pub fn jump_from_ground(
let world = world_lock.read();

let jump_power: f64 = jump_power(&world, position) as f64 + jump_boost_power();
let old_delta_movement = physics.delta;
physics.delta = Vec3 {
let old_delta_movement = physics.velocity;
physics.velocity = Vec3 {
x: old_delta_movement.x,
y: jump_power,
z: old_delta_movement.z,
};
if **sprinting {
// sprint jumping gives some extra velocity
let y_rot = look_direction.y_rot * 0.017453292;
physics.delta += Vec3 {
physics.velocity += Vec3 {
x: (-math::sin(y_rot) * 0.2) as f64,
y: 0.,
z: (math::cos(y_rot) * 0.2) as f64,
Expand Down Expand Up @@ -245,7 +245,7 @@ fn handle_relative_friction_and_calculate_movement(
// entity.delta = entity.handle_on_climbable(entity.delta);
move_colliding(
&MoverType::Own,
&physics.delta.clone(),
&physics.velocity.clone(),
world,
position,
physics,
Expand All @@ -259,7 +259,7 @@ fn handle_relative_friction_and_calculate_movement(
// Vec3(var3.x, 0.2D, var3.z); }
// TODO: powdered snow

physics.delta
physics.velocity
}

// private float getFrictionInfluencedSpeed(float friction) {
Expand Down Expand Up @@ -400,7 +400,7 @@ mod tests {
// delta is applied before gravity, so the first tick only sets the delta
assert_eq!(entity_pos.y, 70.);
let entity_physics = app.world.get::<Physics>(entity).unwrap();
assert!(entity_physics.delta.y < 0.);
assert!(entity_physics.velocity.y < 0.);
}
app.world.run_schedule(FixedUpdate);
app.update();
Expand Down Expand Up @@ -463,7 +463,7 @@ mod tests {
// delta will change, but it won't move until next tick
assert_eq!(entity_pos.y, 70.);
let entity_physics = app.world.get::<Physics>(entity).unwrap();
assert!(entity_physics.delta.y < 0.);
assert!(entity_physics.velocity.y < 0.);
}
app.world.run_schedule(FixedUpdate);
app.update();
Expand Down
Loading

0 comments on commit eeec59a

Please sign in to comment.