diff options
| author | mat <git@matdoes.dev> | 2026-03-30 10:02:22 +0600 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2026-05-07 08:05:58 -1200 |
| commit | 4af9762854aad30b7fdc40640618e465197f2148 (patch) | |
| tree | b3f00274ed277ed4a1fb6363b1f11e9f430c7535 /azalea-physics/src | |
| parent | ddef37118448b639ff56b86ae339e8913cb4ed11 (diff) | |
| download | azalea-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.rs | 181 | ||||
| -rw-r--r-- | azalea-physics/src/collision/mod.rs | 4 | ||||
| -rw-r--r-- | azalea-physics/src/lib.rs | 2 | ||||
| -rw-r--r-- | azalea-physics/src/local_player.rs | 69 | ||||
| -rw-r--r-- | azalea-physics/src/travel.rs | 4 |
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>, |
