aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2024-12-11 19:51:12 -0600
committerGitHub <noreply@github.com>2024-12-11 19:51:12 -0600
commite9136c9cbbf9010b8352127e129c1cd290f377bd (patch)
treedb83316a273153106dd3b343c9d6d4fce234d132
parent23932003d98db0f5f976146aa9a11e5d04a74695 (diff)
downloadazalea-drasl-e9136c9cbbf9010b8352127e129c1cd290f377bd.tar.xz
Implement EntityPositionSync (#196)
* implement EntityPositionSync * fix EntityPositionSync setting the wrong vec_delta_codec and also move into a RelativeEntityUpdate
-rw-r--r--azalea-client/src/movement.rs13
-rw-r--r--azalea-client/src/packet_handling/game.rs142
-rwxr-xr-xazalea-core/src/position.rs4
-rwxr-xr-xazalea-entity/src/dimensions.rs2
-rw-r--r--azalea-entity/src/lib.rs61
-rw-r--r--azalea-entity/src/plugin/mod.rs2
-rw-r--r--azalea-entity/src/vec_delta_codec.rs60
-rw-r--r--azalea-physics/src/collision/mod.rs4
-rw-r--r--azalea-physics/src/lib.rs6
-rwxr-xr-xazalea-protocol/src/packets/game/c_entity_position_sync.rs11
-rwxr-xr-xazalea-protocol/src/packets/game/c_player_position.rs8
-rw-r--r--azalea-world/src/world.rs5
-rw-r--r--azalea/src/auto_tool.rs22
-rw-r--r--azalea/src/pathfinder/mod.rs2
-rw-r--r--azalea/src/pathfinder/simulation.rs2
15 files changed, 238 insertions, 106 deletions
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index 03183e24..bdc29f2f 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -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(),
)
@@ -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(),
)
@@ -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(),
)
@@ -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
diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs
index d4d84f75..0c505d07 100644
--- a/azalea-client/src/packet_handling/game.rs
+++ b/azalea-client/src/packet_handling/game.rs
@@ -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 {
@@ -829,30 +837,29 @@ pub fn process_packet_events(ecs: &mut World) {
let (mut commands, mut query) = system_state.get_mut(ecs);
let (entity_id_index, instance_holder) = query.get_mut(player_entity).unwrap();
- let entity = entity_id_index.get(&MinecraftEntityId(p.id));
-
- if let Some(entity) = entity {
- let new_pos = p.position;
- 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.,
- };
- commands.entity(entity).queue(RelativeEntityUpdate {
- partial_world: instance_holder.partial_instance.clone(),
- update: Box::new(move |entity| {
- let mut position = entity.get_mut::<Position>().unwrap();
- if new_pos != **position {
- **position = new_pos;
- }
- let mut look_direction = entity.get_mut::<LookDirection>().unwrap();
- if new_look_direction != *look_direction {
- *look_direction = new_look_direction;
- }
- }),
- });
- } else {
+ let Some(entity) = entity_id_index.get(&MinecraftEntityId(p.id)) else {
warn!("Got teleport entity packet for unknown entity id {}", p.id);
- }
+ continue;
+ };
+
+ let new_pos = p.position;
+ 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.,
+ };
+ commands.entity(entity).queue(RelativeEntityUpdate {
+ partial_world: instance_holder.partial_instance.clone(),
+ update: Box::new(move |entity| {
+ let mut position = entity.get_mut::<Position>().unwrap();
+ if new_pos != **position {
+ **position = new_pos;
+ }
+ let mut look_direction = entity.get_mut::<LookDirection>().unwrap();
+ if new_look_direction != *look_direction {
+ *look_direction = new_look_direction;
+ }
+ }),
+ });
system_state.apply(ecs);
}
@@ -870,15 +877,26 @@ pub fn process_packet_events(ecs: &mut World) {
let (mut commands, mut query) = system_state.get_mut(ecs);
let (entity_id_index, instance_holder) = query.get_mut(player_entity).unwrap();
+ debug!("Got move entity pos packet {p:?}");
+
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;
}
@@ -901,23 +919,36 @@ pub fn process_packet_events(ecs: &mut World) {
let (mut commands, mut query) = system_state.get_mut(ecs);
let (entity_id_index, instance_holder) = query.get_mut(player_entity).unwrap();
+ debug!("Got move entity pos rot packet {p:?}");
+
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;
@@ -949,10 +980,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;
@@ -1416,7 +1451,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);
@@ -1434,6 +1469,52 @@ pub fn process_packet_events(ecs: &mut World) {
system_state.apply(ecs);
}
+ ClientboundGamePacket::EntityPositionSync(p) => {
+ let mut system_state: SystemState<(
+ Commands,
+ Query<(&EntityIdIndex, &InstanceHolder)>,
+ )> = SystemState::new(ecs);
+ let (mut commands, mut query) = system_state.get_mut(ecs);
+ let (entity_id_index, instance_holder) = query.get_mut(player_entity).unwrap();
+
+ let Some(entity) = entity_id_index.get(&MinecraftEntityId(p.id)) else {
+ warn!("Got teleport entity packet for unknown entity id {}", p.id);
+ continue;
+ };
+
+ let new_position = p.values.pos;
+ let new_on_ground = p.on_ground;
+ let new_look_direction = p.values.look_direction;
+
+ commands.entity(entity).queue(RelativeEntityUpdate {
+ partial_world: instance_holder.partial_instance.clone(),
+ update: Box::new(move |entity_mut| {
+ let is_local_entity = entity_mut.get::<LocalEntity>().is_some();
+ let mut physics = entity_mut.get_mut::<Physics>().unwrap();
+
+ physics.vec_delta_codec.set_base(new_position);
+
+ if is_local_entity {
+ debug!("Ignoring entity position sync packet for local player");
+ return;
+ }
+
+ physics.set_on_ground(new_on_ground);
+
+ let mut last_sent_position =
+ entity_mut.get_mut::<LastSentPosition>().unwrap();
+ **last_sent_position = new_position;
+ let mut position = entity_mut.get_mut::<Position>().unwrap();
+ **position = new_position;
+
+ let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap();
+ *look_direction = new_look_direction;
+ }),
+ });
+
+ system_state.apply(ecs);
+ }
+
ClientboundGamePacket::SelectAdvancementsTab(_) => {}
ClientboundGamePacket::SetActionBarText(_) => {}
ClientboundGamePacket::SetBorderCenter(_) => {}
@@ -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(_) => {}
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs
index 9b800e28..14ecfcc1 100755
--- a/azalea-core/src/position.rs
+++ b/azalea-core/src/position.rs
@@ -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 }
}
@@ -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 {
diff --git a/azalea-entity/src/dimensions.rs b/azalea-entity/src/dimensions.rs
index b5a3f310..5236b80f 100755
--- a/azalea-entity/src/dimensions.rs
+++ b/azalea-entity/src/dimensions.rs
@@ -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 {
diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs
index 1334ee0f..95a2ed3c 100644
--- a/azalea-entity/src/lib.rs
+++ b/azalea-entity/src/lib.rs
@@ -9,6 +9,7 @@ pub mod metadata;
pub mod mining;
pub mod particle;
mod plugin;
+pub mod vec_delta_codec;
use std::{
fmt::Debug,
@@ -17,6 +18,7 @@ use std::{
pub use attributes::Attributes;
use azalea_block::BlockState;
+use azalea_buf::AzBuf;
use azalea_core::{
aabb::AABB,
math,
@@ -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::*;
@@ -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,
@@ -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,
@@ -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,
@@ -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(),
@@ -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.
@@ -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(),
@@ -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);
-// }
-// }
diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs
index 67763484..90d7f1c5 100644
--- a/azalea-entity/src/plugin/mod.rs
+++ b/azalea-entity/src/plugin/mod.rs
@@ -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;
}
}
diff --git a/azalea-entity/src/vec_delta_codec.rs b/azalea-entity/src/vec_delta_codec.rs
new file mode 100644
index 00000000..51aa7cea
--- /dev/null
+++ b/azalea-entity/src/vec_delta_codec.rs
@@ -0,0 +1,60 @@
+use azalea_core::position::Vec3;
+
+#[derive(Debug, Clone, Default)]
+pub struct VecDeltaCodec {
+ base: Vec3,
+}
+
+impl VecDeltaCodec {
+ pub fn new(base: Vec3) -> Self {
+ Self { base }
+ }
+
+ pub fn decode(&self, x: i64, y: i64, z: i64) -> Vec3 {
+ if x == 0 && y == 0 && z == 0 {
+ return self.base;
+ }
+
+ let new_x = if x == 0 {
+ self.base.x
+ } else {
+ decode(encode(self.base.x) + x)
+ };
+ let new_y = if y == 0 {
+ self.base.y
+ } else {
+ decode(encode(self.base.y) + y)
+ };
+ let new_z = if z == 0 {
+ self.base.z
+ } else {
+ decode(encode(self.base.z) + z)
+ };
+
+ Vec3::new(new_x, new_y, new_z)
+ }
+
+ pub fn encode_x(&self, pos: Vec3) -> i64 {
+ encode(pos.x) - encode(self.base.x)
+ }
+ pub fn encode_y(&self, pos: Vec3) -> i64 {
+ encode(pos.y) - encode(self.base.y)
+ }
+ pub fn encode_z(&self, pos: Vec3) -> i64 {
+ encode(pos.z) - encode(self.base.z)
+ }
+
+ pub fn set_base(&mut self, pos: Vec3) {
+ self.base = pos;
+ }
+ pub fn base(&self) -> Vec3 {
+ self.base
+ }
+}
+
+fn encode(value: f64) -> i64 {
+ (value * 4096.).round() as i64
+}
+fn decode(value: i64) -> f64 {
+ (value as f64) / 4096.
+}
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 7d7ddc5e..913cedac 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -73,7 +73,7 @@ fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics)
let y_collision = movement.y != collided_delta.y;
let z_collision = movement.z != collided_delta.z;
- let on_ground = physics.on_ground || y_collision && movement.y < 0.;
+ let on_ground = physics.on_ground() || y_collision && movement.y < 0.;
let max_up_step = 0.6;
if max_up_step > 0. && on_ground && (x_collision || z_collision) {
@@ -192,7 +192,7 @@ pub fn move_colliding(
physics.horizontal_collision = horizontal_collision;
physics.vertical_collision = vertical_collision;
- physics.on_ground = on_ground;
+ physics.set_on_ground(on_ground);
// TODO: minecraft checks for a "minor" horizontal collision here
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index c50095e4..2ca64b1f 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -100,7 +100,7 @@ fn travel(
let block_below: Box<dyn Block> = block_state_below.into();
let block_friction = block_below.behavior().friction;
- let inertia = if physics.on_ground {
+ let inertia = if physics.on_ground() {
block_friction * 0.91
} else {
0.91
@@ -178,7 +178,7 @@ pub fn ai_step(
if **jumping {
// TODO: jumping in liquids and jump delay
- if physics.on_ground {
+ if physics.on_ground() {
jump_from_ground(
&mut physics,
position,
@@ -358,7 +358,7 @@ fn get_friction_influenced_speed(
is_sprinting: bool,
) -> f32 {
// TODO: have speed & flying_speed fields in entity
- if physics.on_ground {
+ if physics.on_ground() {
let speed: f32 = attributes.speed.calculate() as f32;
speed * (0.216f32 / (friction * friction * friction))
} else {
diff --git a/azalea-protocol/src/packets/game/c_entity_position_sync.rs b/azalea-protocol/src/packets/game/c_entity_position_sync.rs
index c5cde322..6347ec5e 100755
--- a/azalea-protocol/src/packets/game/c_entity_position_sync.rs
+++ b/azalea-protocol/src/packets/game/c_entity_position_sync.rs
@@ -1,7 +1,8 @@
use azalea_buf::AzBuf;
-use azalea_core::position::Vec3;
use azalea_protocol_macros::ClientboundGamePacket;
+use super::c_player_position::PositionMoveRotation;
+
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
pub struct ClientboundEntityPositionSync {
#[var]
@@ -9,11 +10,3 @@ pub struct ClientboundEntityPositionSync {
pub values: PositionMoveRotation,
pub on_ground: bool,
}
-
-#[derive(AzBuf, Clone, Debug)]
-pub struct PositionMoveRotation {
- pub position: Vec3,
- pub delta_movement: Vec3,
- pub y_rot: f32,
- pub x_rot: f32,
-}
diff --git a/azalea-protocol/src/packets/game/c_player_position.rs b/azalea-protocol/src/packets/game/c_player_position.rs
index c6a2e3f9..8d19ce36 100755
--- a/azalea-protocol/src/packets/game/c_player_position.rs
+++ b/azalea-protocol/src/packets/game/c_player_position.rs
@@ -2,6 +2,7 @@ use std::io::{Cursor, Write};
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
use azalea_core::{bitset::FixedBitSet, position::Vec3};
+use azalea_entity::LookDirection;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, AzBuf, ClientboundGamePacket)]
@@ -18,9 +19,12 @@ pub struct ClientboundPlayerPosition {
pub struct PositionMoveRotation {
pub pos: Vec3,
/// The updated delta movement (velocity).
+ ///
+ /// This is unused when included in a [`ClientboundEntityPositionSync`].
+ ///
+ /// [`ClientboundEntityPositionSync`]: super::c_entity_position_sync::ClientboundEntityPositionSync
pub delta: Vec3,
- pub y_rot: f32,
- pub x_rot: f32,
+ pub look_direction: LookDirection,
}
#[derive(Debug, Clone)]
diff --git a/azalea-world/src/world.rs b/azalea-world/src/world.rs
index 066981e5..0a09d387 100644
--- a/azalea-world/src/world.rs
+++ b/azalea-world/src/world.rs
@@ -1,4 +1,5 @@
use std::fmt::Formatter;
+use std::hash::{Hash, Hasher};
use std::{
collections::{HashMap, HashSet},
fmt::Debug,
@@ -44,8 +45,8 @@ impl PartialInstance {
#[derive(Component, Copy, Clone, Debug, PartialEq, Eq, Deref, DerefMut)]
pub struct MinecraftEntityId(pub u32);
-impl std::hash::Hash for MinecraftEntityId {
- fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
+impl Hash for MinecraftEntityId {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
hasher.write_u32(self.0);
}
}
diff --git a/azalea/src/auto_tool.rs b/azalea/src/auto_tool.rs
index 5fcb8037..768d3089 100644
--- a/azalea/src/auto_tool.rs
+++ b/azalea/src/auto_tool.rs
@@ -31,24 +31,10 @@ impl AutoToolClientExt for Client {
/// or in water, use [`accurate_best_tool_in_hotbar_for_block`] instead if you
/// care about those things.
pub fn best_tool_in_hotbar_for_block(block: BlockState, menu: &Menu) -> BestToolResult {
- accurate_best_tool_in_hotbar_for_block(
- block,
- menu,
- &Physics {
- on_ground: true,
- velocity: Default::default(),
- xxa: Default::default(),
- yya: Default::default(),
- zza: Default::default(),
- last_on_ground: Default::default(),
- dimensions: Default::default(),
- bounding_box: Default::default(),
- has_impulse: Default::default(),
- horizontal_collision: Default::default(),
- vertical_collision: Default::default(),
- },
- &FluidOnEyes::new(Fluid::Empty),
- )
+ let mut physics = Physics::default();
+ physics.set_on_ground(true);
+
+ accurate_best_tool_in_hotbar_for_block(block, menu, &physics, &FluidOnEyes::new(Fluid::Empty))
}
pub fn accurate_best_tool_in_hotbar_for_block(
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index eab07348..78aafc2f 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -516,7 +516,7 @@ pub fn check_node_reached(
let x_difference_from_center = position.x - (movement.target.x as f64 + 0.5);
let z_difference_from_center = position.z - (movement.target.z as f64 + 0.5);
// this is to make sure we don't fall off immediately after finishing the path
- physics.on_ground
+ physics.on_ground()
&& BlockPos::from(position) == movement.target
// adding the delta like this isn't a perfect solution but it helps to make
// sure we don't keep going if our delta is high
diff --git a/azalea/src/pathfinder/simulation.rs b/azalea/src/pathfinder/simulation.rs
index ca15fb7a..630dd591 100644
--- a/azalea/src/pathfinder/simulation.rs
+++ b/azalea/src/pathfinder/simulation.rs
@@ -32,7 +32,7 @@ impl SimulatedPlayerBundle {
SimulatedPlayerBundle {
position: Position::new(position),
- physics: Physics::new(dimensions, &position),
+ physics: Physics::new(dimensions, position),
physics_state: PhysicsState::default(),
look_direction: LookDirection::new(0.0, 0.0),
attributes: Attributes {