Skip to content

Commit

Permalink
implement EntityPositionSync
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-1 committed Dec 11, 2024
1 parent 2feef49 commit 3f32878
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 83 deletions.
13 changes: 7 additions & 6 deletions azalea-client/src/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub fn send_position(
pos: **position,
x_rot: direction.x_rot,
y_rot: direction.y_rot,
on_ground: physics.on_ground,
on_ground: physics.on_ground(),
}
.into_variant(),
)
Expand All @@ -205,7 +205,7 @@ pub fn send_position(
x: position.x,
y: position.y,
z: position.z,
on_ground: physics.on_ground,
on_ground: physics.on_ground(),
}
.into_variant(),
)
Expand All @@ -214,14 +214,14 @@ pub fn send_position(
ServerboundMovePlayerRot {
x_rot: direction.x_rot,
y_rot: direction.y_rot,
on_ground: physics.on_ground,
on_ground: physics.on_ground(),
}
.into_variant(),
)
} else if physics.last_on_ground != physics.on_ground {
} else if physics.last_on_ground() != physics.on_ground() {
Some(
ServerboundMovePlayerStatusOnly {
on_ground: physics.on_ground,
on_ground: physics.on_ground(),
}
.into_variant(),
)
Expand All @@ -238,7 +238,8 @@ pub fn send_position(
last_direction.x_rot = direction.x_rot;
}

physics.last_on_ground = physics.on_ground;
let on_ground = physics.on_ground();
physics.set_last_on_ground(on_ground);
// minecraft checks for autojump here, but also autojump is bad so

packet
Expand Down
96 changes: 88 additions & 8 deletions azalea-client/src/packet_handling/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,16 @@ pub fn process_packet_events(ecs: &mut World) {
let new_y = apply_change(position.y, p.relative.y, p.change.pos.y);
let new_z = apply_change(position.z, p.relative.z, p.change.pos.z);

let new_y_rot = apply_change(direction.y_rot, p.relative.y_rot, p.change.y_rot);
let new_x_rot = apply_change(direction.x_rot, p.relative.x_rot, p.change.x_rot);
let new_y_rot = apply_change(
direction.y_rot,
p.relative.y_rot,
p.change.look_direction.y_rot,
);
let new_x_rot = apply_change(
direction.x_rot,
p.relative.x_rot,
p.change.look_direction.x_rot,
);

let mut new_delta_from_rotations = physics.velocity;
if p.relative.rotate_delta {
Expand Down Expand Up @@ -873,12 +881,21 @@ pub fn process_packet_events(ecs: &mut World) {
let entity = entity_id_index.get(&MinecraftEntityId(p.entity_id));

if let Some(entity) = entity {
let delta = p.delta.clone();
let new_delta = p.delta.clone();
let new_on_ground = p.on_ground;
commands.entity(entity).queue(RelativeEntityUpdate {
partial_world: instance_holder.partial_instance.clone(),
update: Box::new(move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
let new_pos = physics.vec_delta_codec.decode(
new_delta.xa as i64,
new_delta.ya as i64,
new_delta.za as i64,
);
physics.vec_delta_codec.set_base(new_pos);
physics.set_on_ground(new_on_ground);

let mut position = entity_mut.get_mut::<Position>().unwrap();
let new_pos = position.with_delta(&delta);
if new_pos != **position {
**position = new_pos;
}
Expand All @@ -904,20 +921,31 @@ pub fn process_packet_events(ecs: &mut World) {
let entity = entity_id_index.get(&MinecraftEntityId(p.entity_id));

if let Some(entity) = entity {
let delta = p.delta.clone();
let new_delta = p.delta.clone();
let new_look_direction = LookDirection {
x_rot: (p.x_rot as i32 * 360) as f32 / 256.,
y_rot: (p.y_rot as i32 * 360) as f32 / 256.,
};

let new_on_ground = p.on_ground;

commands.entity(entity).queue(RelativeEntityUpdate {
partial_world: instance_holder.partial_instance.clone(),
update: Box::new(move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
let new_pos = physics.vec_delta_codec.decode(
new_delta.xa as i64,
new_delta.ya as i64,
new_delta.za as i64,
);
physics.vec_delta_codec.set_base(new_pos);
physics.set_on_ground(new_on_ground);

let mut position = entity_mut.get_mut::<Position>().unwrap();
let new_pos = position.with_delta(&delta);
if new_pos != **position {
**position = new_pos;
}

let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
if new_look_direction != *look_direction {
*look_direction = new_look_direction;
Expand Down Expand Up @@ -949,10 +977,14 @@ pub fn process_packet_events(ecs: &mut World) {
x_rot: (p.x_rot as i32 * 360) as f32 / 256.,
y_rot: (p.y_rot as i32 * 360) as f32 / 256.,
};
let new_on_ground = p.on_ground;

commands.entity(entity).queue(RelativeEntityUpdate {
partial_world: instance_holder.partial_instance.clone(),
update: Box::new(move |entity_mut| {
let mut physics = entity_mut.get_mut::<Physics>().unwrap();
physics.set_on_ground(new_on_ground);

let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
if new_look_direction != *look_direction {
*look_direction = new_look_direction;
Expand Down Expand Up @@ -1416,7 +1448,7 @@ pub fn process_packet_events(ecs: &mut World) {
system_state.apply(ecs);
}

ClientboundGamePacket::StartConfiguration(_) => {
ClientboundGamePacket::StartConfiguration(_p) => {
let mut system_state: SystemState<(Commands, EventWriter<SendPacketEvent>)> =
SystemState::new(ecs);
let (mut commands, mut packet_events) = system_state.get_mut(ecs);
Expand All @@ -1434,6 +1466,55 @@ pub fn process_packet_events(ecs: &mut World) {
system_state.apply(ecs);
}

ClientboundGamePacket::EntityPositionSync(p) => {
debug!("Got entity position sync packet {p:?}");

let mut system_state: SystemState<(
Query<&EntityIdIndex>,
Query<(
&mut Physics,
&mut Position,
&mut LastSentPosition,
&mut LookDirection,
Option<&LocalEntity>,
)>,
)> = SystemState::new(ecs);
let (mut index_query, mut query) = system_state.get_mut(ecs);
let entity_id_index = index_query.get_mut(player_entity).unwrap();
let Some(entity) = entity_id_index.get(&MinecraftEntityId(p.id)) else {
warn!(
"Got entity position sync packet for unknown entity id {}",
p.id
);
continue;
};

let Ok((
mut physics,
mut position,
mut last_sent_position,
mut look_direction,
local_entity,
)) = query.get_mut(entity)
else {
continue;
};

physics.vec_delta_codec.set_base(**position);

if local_entity.is_some() {
debug!("Ignoring entity position sync packet for local player");
continue;
}

**last_sent_position = **position;
**position = p.values.pos;

*look_direction = p.values.look_direction;

physics.set_on_ground(p.on_ground);
}

ClientboundGamePacket::SelectAdvancementsTab(_) => {}
ClientboundGamePacket::SetActionBarText(_) => {}
ClientboundGamePacket::SetBorderCenter(_) => {}
Expand Down Expand Up @@ -1476,7 +1557,6 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::ProjectilePower(_) => {}
ClientboundGamePacket::CustomReportDetails(_) => {}
ClientboundGamePacket::ServerLinks(_) => {}
ClientboundGamePacket::EntityPositionSync(_) => {}
ClientboundGamePacket::PlayerRotation(_) => {}
ClientboundGamePacket::RecipeBookAdd(_) => {}
ClientboundGamePacket::RecipeBookRemove(_) => {}
Expand Down
4 changes: 3 additions & 1 deletion azalea-core/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ macro_rules! vec3_impl {
($name:ident, $type:ty) => {
impl $name {
#[inline]
pub fn new(x: $type, y: $type, z: $type) -> Self {
pub const fn new(x: $type, y: $type, z: $type) -> Self {
Self { x, y, z }
}

Expand Down Expand Up @@ -223,6 +223,8 @@ pub struct Vec3 {
vec3_impl!(Vec3, f64);

impl Vec3 {
pub const ZERO: Vec3 = Vec3::new(0.0, 0.0, 0.0);

/// Get the distance of this vector to the origin by doing
/// `sqrt(x^2 + y^2 + z^2)`.
pub fn length(&self) -> f64 {
Expand Down
2 changes: 1 addition & 1 deletion azalea-entity/src/dimensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct EntityDimensions {
}

impl EntityDimensions {
pub fn make_bounding_box(&self, pos: &Vec3) -> AABB {
pub fn make_bounding_box(&self, pos: Vec3) -> AABB {
let radius = (self.width / 2.0) as f64;
let height = self.height as f64;
AABB {
Expand Down
61 changes: 33 additions & 28 deletions azalea-entity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod metadata;
pub mod mining;
pub mod particle;
mod plugin;
pub mod vec_delta_codec;

use std::{
fmt::Debug,
Expand All @@ -17,6 +18,7 @@ use std::{

pub use attributes::Attributes;
use azalea_block::BlockState;
use azalea_buf::AzBuf;
use azalea_core::{
aabb::AABB,
math,
Expand All @@ -30,6 +32,7 @@ use derive_more::{Deref, DerefMut};
pub use dimensions::EntityDimensions;
use plugin::indexing::EntityChunkPos;
use uuid::Uuid;
use vec_delta_codec::VecDeltaCodec;

use self::attributes::AttributeInstance;
pub use crate::plugin::*;
Expand Down Expand Up @@ -210,7 +213,7 @@ impl From<&LastSentPosition> for BlockPos {
pub struct Jumping(bool);

/// A component that contains the direction an entity is looking.
#[derive(Debug, Component, Copy, Clone, Default, PartialEq)]
#[derive(Debug, Component, Copy, Clone, Default, PartialEq, AzBuf)]
pub struct LookDirection {
/// Left and right. Aka yaw.
pub y_rot: f32,
Expand Down Expand Up @@ -245,7 +248,7 @@ impl Eq for LookDirection {}

/// The physics data relating to the entity, such as position, velocity, and
/// bounding box.
#[derive(Debug, Component, Clone)]
#[derive(Debug, Component, Clone, Default)]
pub struct Physics {
/// How fast the entity is moving.
pub velocity: Vec3,
Expand All @@ -257,8 +260,10 @@ pub struct Physics {
/// Z acceleration.
pub zza: f32,

pub on_ground: bool,
pub last_on_ground: bool,
on_ground: bool,
last_on_ground: bool,

pub vec_delta_codec: VecDeltaCodec,

/// The width and height of the entity.
pub dimensions: EntityDimensions,
Expand All @@ -274,7 +279,7 @@ pub struct Physics {
}

impl Physics {
pub fn new(dimensions: EntityDimensions, pos: &Vec3) -> Self {
pub fn new(dimensions: EntityDimensions, pos: Vec3) -> Self {
Self {
velocity: Vec3::default(),

Expand All @@ -292,8 +297,30 @@ impl Physics {

horizontal_collision: false,
vertical_collision: false,

vec_delta_codec: VecDeltaCodec::new(pos),
}
}

pub fn on_ground(&self) -> bool {
self.on_ground
}
/// Updates [`Self::on_ground`] and [`Self::last_on_ground`].
pub fn set_on_ground(&mut self, on_ground: bool) {
self.last_on_ground = self.on_ground;
self.on_ground = on_ground;
}

/// The last value of the on_ground value.
///
/// This is used by Azalea internally for physics, it might not work as you
/// expect since it can be influenced by packets sent by the server.
pub fn last_on_ground(&self) -> bool {
self.last_on_ground
}
pub fn set_last_on_ground(&mut self, last_on_ground: bool) {
self.last_on_ground = last_on_ground;
}
}

/// Marker component for entities that are dead.
Expand Down Expand Up @@ -384,7 +411,7 @@ impl EntityBundle {
position: Position(pos),
chunk_pos: EntityChunkPos(ChunkPos::from(&pos)),
last_sent_position: LastSentPosition(pos),
physics: Physics::new(dimensions, &pos),
physics: Physics::new(dimensions, pos),
eye_height: EyeHeight(eye_height),
direction: LookDirection::default(),

Expand Down Expand Up @@ -427,25 +454,3 @@ impl FluidOnEyes {

#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
pub struct OnClimbable(bool);

// #[cfg(test)]
// mod tests {
// use super::*;
// use crate::PartialWorld;

// #[test]
// fn from_mut_entity_to_ref_entity() {
// let mut world = PartialWorld::default();
// let uuid = Uuid::from_u128(100);
// world.add_entity(
// 0,
// EntityData::new(
// uuid,
// Vec3::default(),
// EntityMetadata::Player(metadata::Player::default()),
// ),
// );
// let entity: Entity = world.entity_mut(0).unwrap();
// assert_eq!(entity.uuid, uuid);
// }
// }
2 changes: 1 addition & 1 deletion azalea-entity/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ pub fn clamp_look_direction(mut query: Query<&mut LookDirection>) {
/// Cached position in the world must be updated.
pub fn update_bounding_box(mut query: Query<(&Position, &mut Physics), Changed<Position>>) {
for (position, mut physics) in query.iter_mut() {
let bounding_box = physics.dimensions.make_bounding_box(position);
let bounding_box = physics.dimensions.make_bounding_box(**position);
physics.bounding_box = bounding_box;
}
}
Expand Down
Loading

0 comments on commit 3f32878

Please sign in to comment.