aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics/src
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2026-03-30 10:02:22 +0600
committermat <git@matdoes.dev>2026-05-07 08:05:58 -1200
commit4af9762854aad30b7fdc40640618e465197f2148 (patch)
treeb3f00274ed277ed4a1fb6363b1f11e9f430c7535 /azalea-physics/src
parentddef37118448b639ff56b86ae339e8913cb4ed11 (diff)
downloadazalea-drasl-4af9762854aad30b7fdc40640618e465197f2148.tar.xz
rename PhysicsState to ClientMovementState and add utility functions for it
Diffstat (limited to 'azalea-physics/src')
-rw-r--r--azalea-physics/src/client_movement.rs181
-rw-r--r--azalea-physics/src/collision/mod.rs4
-rw-r--r--azalea-physics/src/lib.rs2
-rw-r--r--azalea-physics/src/local_player.rs69
-rw-r--r--azalea-physics/src/travel.rs4
5 files changed, 186 insertions, 74 deletions
diff --git a/azalea-physics/src/client_movement.rs b/azalea-physics/src/client_movement.rs
new file mode 100644
index 00000000..a3bddb34
--- /dev/null
+++ b/azalea-physics/src/client_movement.rs
@@ -0,0 +1,181 @@
+use azalea_core::position::Vec2;
+use bevy_ecs::component::Component;
+
+/// Component for entities that can move and sprint.
+///
+/// Usually only present for [`LocalEntity`]s.
+///
+/// [`LocalEntity`]: azalea_entity::LocalEntity
+#[derive(Clone, Component, Default)]
+pub struct ClientMovementState {
+ /// Minecraft only sends a movement packet either after 20 ticks or if the
+ /// player moved enough. This is that tick counter.
+ pub position_remainder: u32,
+ pub was_sprinting: bool,
+ // Whether we're going to try to start sprinting this tick. Equivalent to
+ // holding down ctrl for a tick.
+ pub trying_to_sprint: bool,
+
+ /// Whether our player is currently trying to sneak.
+ ///
+ /// This is distinct from
+ /// [`AbstractEntityShiftKeyDown`](azalea_entity::metadata::AbstractEntityShiftKeyDown),
+ /// which is a metadata value that is controlled by the server and affects
+ /// how the nametags of other entities are displayed.
+ ///
+ /// To check whether we're actually sneaking, you can check the
+ /// [`Crouching`](azalea_entity::Crouching) or [`Pose`](azalea_entity::Pose)
+ /// components.
+ pub trying_to_crouch: bool,
+
+ pub move_direction: WalkDirection,
+ pub move_vector: Vec2,
+}
+
+/// A direction that a player can walk in, including none.
+///
+/// Superset of [`SprintDirection`].
+///
+/// This can be freely converted to and from [`DirectionStates`].
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum WalkDirection {
+ #[default]
+ None,
+ Forward,
+ Backward,
+ Left,
+ Right,
+ ForwardRight,
+ ForwardLeft,
+ BackwardRight,
+ BackwardLeft,
+}
+impl WalkDirection {
+ /// Returns true if the direction is forward, forward-right, or
+ /// forward-left.
+ pub fn forward(self) -> bool {
+ DirectionStates::from(self).forward
+ }
+ /// Returns true if the direction is backward, backward-right, or
+ /// backward-left.
+ pub fn backward(self) -> bool {
+ DirectionStates::from(self).backward
+ }
+ /// Returns true if the direction is left, forward-left, or backward-left.
+ pub fn left(self) -> bool {
+ DirectionStates::from(self).left
+ }
+ /// Returns true if the direction is right, forward-right, or
+ /// backward-right.
+ pub fn right(self) -> bool {
+ DirectionStates::from(self).right
+ }
+
+ pub fn set_forward(&mut self, value: bool) {
+ let mut d = DirectionStates::from(*self);
+ d.forward = value;
+ *self = d.into();
+ }
+ pub fn set_backward(&mut self, value: bool) {
+ let mut d = DirectionStates::from(*self);
+ d.backward = value;
+ *self = d.into();
+ }
+ pub fn set_left(&mut self, value: bool) {
+ let mut d = DirectionStates::from(*self);
+ d.left = value;
+ *self = d.into();
+ }
+ pub fn set_right(&mut self, value: bool) {
+ let mut d = DirectionStates::from(*self);
+ d.right = value;
+ *self = d.into();
+ }
+}
+/// A struct containing fields for each direction.
+///
+/// This can be freely converted to and from a [`WalkDirection`], and may
+/// simplify certain movement direction checks.
+#[derive(Default)]
+pub struct DirectionStates {
+ pub forward: bool,
+ pub backward: bool,
+ pub left: bool,
+ pub right: bool,
+}
+impl From<WalkDirection> for DirectionStates {
+ fn from(d: WalkDirection) -> Self {
+ let mut s = Self::default();
+ match d {
+ WalkDirection::None => {}
+ WalkDirection::Forward => s.forward = true,
+ WalkDirection::Backward => s.backward = true,
+ WalkDirection::Left => s.left = true,
+ WalkDirection::Right => s.right = true,
+ WalkDirection::ForwardRight => {
+ s.forward = true;
+ s.right = true
+ }
+ WalkDirection::ForwardLeft => {
+ s.forward = true;
+ s.left = true
+ }
+ WalkDirection::BackwardRight => {
+ s.backward = true;
+ s.right = true
+ }
+ WalkDirection::BackwardLeft => {
+ s.forward = true;
+ s.left = true
+ }
+ };
+ s
+ }
+}
+impl From<DirectionStates> for WalkDirection {
+ fn from(d: DirectionStates) -> Self {
+ let left = d.left && !d.right;
+ let right = d.right && !d.left;
+
+ if d.forward && !d.backward {
+ if right {
+ return Self::ForwardRight;
+ } else if left {
+ return Self::ForwardLeft;
+ }
+ return Self::Forward;
+ } else if d.backward && !d.forward {
+ if right {
+ return Self::BackwardRight;
+ } else if left {
+ return Self::BackwardLeft;
+ }
+ return Self::Backward;
+ }
+ if right {
+ return Self::Right;
+ } else if left {
+ return Self::Left;
+ }
+ return Self::None;
+ }
+}
+
+/// The directions that a player can sprint in. It's a subset of
+/// [`WalkDirection`].
+#[derive(Clone, Copy, Debug)]
+pub enum SprintDirection {
+ Forward,
+ ForwardRight,
+ ForwardLeft,
+}
+
+impl From<SprintDirection> for WalkDirection {
+ fn from(d: SprintDirection) -> Self {
+ match d {
+ SprintDirection::Forward => WalkDirection::Forward,
+ SprintDirection::ForwardRight => WalkDirection::ForwardRight,
+ SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
+ }
+ }
+}
diff --git a/azalea-physics/src/collision/mod.rs b/azalea-physics/src/collision/mod.rs
index 430b91ad..6dfe2e00 100644
--- a/azalea-physics/src/collision/mod.rs
+++ b/azalea-physics/src/collision/mod.rs
@@ -29,7 +29,7 @@ use tracing::warn;
use self::world_collisions::get_block_collisions;
use crate::{
- collision::entity_collisions::AabbQuery, local_player::PhysicsState, travel::no_collision,
+ client_movement::ClientMovementState, collision::entity_collisions::AabbQuery, travel::no_collision,
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -116,7 +116,7 @@ pub struct MoveCtx<'world, 'state, 'a, 'b> {
pub source_entity: Entity,
pub aabb_query: &'a AabbQuery<'world, 'state, 'b>,
pub collidable_entity_query: &'a CollidableEntityQuery<'world, 'state>,
- pub physics_state: Option<&'a PhysicsState>,
+ pub physics_state: Option<&'a ClientMovementState>,
pub attributes: &'a Attributes,
pub abilities: Option<&'a PlayerAbilities>,
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 491bda0e..8b0443ce 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -1,10 +1,10 @@
#![doc = include_str!("../README.md")]
#![feature(trait_alias)]
+pub mod client_movement;
pub mod clip;
pub mod collision;
pub mod fluids;
-pub mod local_player;
pub mod travel;
use std::collections::HashSet;
diff --git a/azalea-physics/src/local_player.rs b/azalea-physics/src/local_player.rs
deleted file mode 100644
index 75bbbfb9..00000000
--- a/azalea-physics/src/local_player.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use azalea_core::position::Vec2;
-use bevy_ecs::component::Component;
-
-/// Component for entities that can move and sprint.
-///
-/// Usually only present for [`LocalEntity`]s.
-///
-/// [`LocalEntity`]: azalea_entity::LocalEntity
-#[derive(Clone, Component, Default)]
-pub struct PhysicsState {
- /// Minecraft only sends a movement packet either after 20 ticks or if the
- /// player moved enough. This is that tick counter.
- pub position_remainder: u32,
- pub was_sprinting: bool,
- // Whether we're going to try to start sprinting this tick. Equivalent to
- // holding down ctrl for a tick.
- pub trying_to_sprint: bool,
-
- /// Whether our player is currently trying to sneak.
- ///
- /// This is distinct from
- /// [`AbstractEntityShiftKeyDown`](azalea_entity::metadata::AbstractEntityShiftKeyDown),
- /// which is a metadata value that is controlled by the server and affects
- /// how the nametags of other entities are displayed.
- ///
- /// To check whether we're actually sneaking, you can check the
- /// [`Crouching`](azalea_entity::Crouching) or [`Pose`](azalea_entity::Pose)
- /// components.
- pub trying_to_crouch: bool,
-
- pub move_direction: WalkDirection,
- pub move_vector: Vec2,
-}
-
-/// A direction that a player can walk in, including none.
-///
-/// Superset of [`SprintDirection`].
-#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
-pub enum WalkDirection {
- #[default]
- None,
- Forward,
- Backward,
- Left,
- Right,
- ForwardRight,
- ForwardLeft,
- BackwardRight,
- BackwardLeft,
-}
-
-/// The directions that a player can sprint in. It's a subset of
-/// [`WalkDirection`].
-#[derive(Clone, Copy, Debug)]
-pub enum SprintDirection {
- Forward,
- ForwardRight,
- ForwardLeft,
-}
-
-impl From<SprintDirection> for WalkDirection {
- fn from(d: SprintDirection) -> Self {
- match d {
- SprintDirection::Forward => WalkDirection::Forward,
- SprintDirection::ForwardRight => WalkDirection::ForwardRight,
- SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
- }
- }
-}
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs
index 257e2924..c6bc321b 100644
--- a/azalea-physics/src/travel.rs
+++ b/azalea-physics/src/travel.rs
@@ -11,6 +11,7 @@ use azalea_world::{World, WorldName, Worlds};
use bevy_ecs::prelude::*;
use crate::{
+ client_movement::ClientMovementState,
collision::{
MoveCtx, MoverType, Shapes,
entity_collisions::{AabbQuery, CollidableEntityQuery, get_entity_collisions},
@@ -18,7 +19,6 @@ use crate::{
world_collisions::{get_block_and_liquid_collisions, get_block_collisions},
},
get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement,
- local_player::PhysicsState,
};
/// Move the entity with the given acceleration while handling friction,
@@ -32,7 +32,7 @@ pub fn travel(
&WorldName,
&OnClimbable,
&Jumping,
- Option<&PhysicsState>,
+ Option<&ClientMovementState>,
Option<&Sprinting>,
Option<&Pose>,
Option<&PlayerAbilities>,