Skip to content

Commit

Permalink
update some physics code and fix ChatType
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-1 committed Nov 27, 2024
1 parent 5825871 commit c8891dc
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 166 deletions.
4 changes: 0 additions & 4 deletions azalea-core/src/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ impl Vec3 {
}
}

pub fn length_squared(&self) -> f64 {
self.x * self.x + self.y * self.y + self.z * self.z
}

pub fn normalize(&self) -> Vec3 {
let length = f64::sqrt(self.x * self.x + self.y * self.y + self.z * self.z);
if length < 1e-4 {
Expand Down
101 changes: 47 additions & 54 deletions azalea-core/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ use std::{
hash::Hash,
io::{Cursor, Write},
ops::{Add, AddAssign, Mul, Rem, Sub},
str::FromStr,
};

use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::resource_location::ResourceLocation;
Expand All @@ -28,25 +26,25 @@ macro_rules! vec3_impl {
/// Get the distance of this vector to the origin by doing `x^2 + y^2 +
/// z^2`.
#[inline]
pub fn length_sqr(&self) -> $type {
pub fn length_squared(&self) -> $type {
self.x * self.x + self.y * self.y + self.z * self.z
}

/// Get the squared distance from this position to another position.
/// Equivalent to `(self - other).length_sqr()`.
/// Equivalent to `(self - other).length_squared()`.
#[inline]
pub fn distance_to_sqr(&self, other: &Self) -> $type {
(self - other).length_sqr()
pub fn distance_squared_to(&self, other: &Self) -> $type {
(self - other).length_squared()
}

#[inline]
pub fn horizontal_distance_sqr(&self) -> $type {
pub fn horizontal_distance_squared(&self) -> $type {
self.x * self.x + self.z * self.z
}

#[inline]
pub fn horizontal_distance_to_sqr(&self, other: &Self) -> $type {
(self - other).horizontal_distance_sqr()
pub fn horizontal_distance_squared_to(&self, other: &Self) -> $type {
(self - other).horizontal_distance_squared()
}

/// Return a new instance of this position with the y coordinate
Expand Down Expand Up @@ -272,6 +270,46 @@ impl BlockPos {
pub fn length_manhattan(&self) -> u32 {
(self.x.abs() + self.y.abs() + self.z.abs()) as u32
}

/// Make a new BlockPos with the lower coordinates for each axis.
///
/// ```
/// # use azalea_core::position::BlockPos;
/// assert_eq!(
/// BlockPos::min(
/// &BlockPos::new(1, 20, 300),
/// &BlockPos::new(50, 40, 30),
/// ),
/// BlockPos::new(1, 20, 30),
/// );
/// ```
pub fn min(&self, other: &Self) -> Self {
Self {
x: self.x.min(other.x),
y: self.y.min(other.y),
z: self.z.min(other.z),
}
}

/// Make a new BlockPos with the higher coordinates for each axis.
///
/// ```
/// # use azalea_core::position::BlockPos;
/// assert_eq!(
/// BlockPos::max(
/// &BlockPos::new(1, 20, 300),
/// &BlockPos::new(50, 40, 30),
/// ),
/// BlockPos::new(50, 40, 300),
/// );
/// ```
pub fn max(&self, other: &Self) -> Self {
Self {
x: self.x.max(other.x),
y: self.y.max(other.y),
z: self.z.max(other.z),
}
}
}

/// Chunk coordinates are used to represent where a chunk is in the world. You
Expand Down Expand Up @@ -645,51 +683,6 @@ impl AzaleaWrite for ChunkSectionPos {
}
}

fn parse_three_values<T>(s: &str) -> Result<[T; 3], &'static str>
where
T: FromStr,
<T as FromStr>::Err: fmt::Debug,
{
let parts = s.split_whitespace().collect::<Vec<_>>();
if parts.len() != 3 {
return Err("Expected three values");
}

let x = parts[0].parse().map_err(|_| "Invalid X value")?;
let y = parts[1].parse().map_err(|_| "Invalid Y value")?;
let z = parts[2].parse().map_err(|_| "Invalid Z value")?;

Ok([x, y, z])
}

/// Parses a string in the format "X Y Z" into a BlockPos.
///
/// The input string should contain three integer values separated by spaces,
/// representing the x, y, and z components of the vector respectively.
/// This can be used to parse user input or from `BlockPos::to_string`.
impl FromStr for BlockPos {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let [x, y, z] = parse_three_values::<i32>(s)?;
Ok(BlockPos { x, y, z })
}
}

/// Parses a string in the format "X Y Z" into a Vec3.
///
/// The input string should contain three floating-point values separated by
/// spaces, representing the x, y, and z components of the vector respectively.
/// This can be used to parse user input or from `Vec3::to_string`.
impl FromStr for Vec3 {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let [x, y, z] = parse_three_values::<f64>(s)?;
Ok(Vec3 { x, y, z })
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
33 changes: 7 additions & 26 deletions azalea-physics/src/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,15 @@ pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResul
context.from,
context.to,
context,
|context, block_pos| {
|ctx, block_pos| {
let block_state = chunk_storage.get_block_state(block_pos).unwrap_or_default();
// TODO: add fluid stuff to this (see getFluidState in vanilla source)
let block_shape = context.block_shape(block_state);
clip_with_interaction_override(
&context.from,
&context.to,
block_pos,
block_shape,
&block_state,
)
let block_shape = ctx.block_shape(block_state);
clip_with_interaction_override(&ctx.from, &ctx.to, block_pos, block_shape, &block_state)
// let block_distance = if let Some(block_hit_result) =
// block_hit_result { context.from.distance_to_sqr(&
// block_hit_result { context.from.distance_squared_to(&
// block_hit_result.location) } else {
// f64::MAX
// f64::INFINITY
// };
},
|context| {
Expand All @@ -90,19 +84,6 @@ pub fn clip(chunk_storage: &ChunkStorage, context: ClipContext) -> BlockHitResul
)
}

// default BlockHitResult clipWithInteractionOverride(Vec3 world, Vec3 from,
// BlockPos to, VoxelShape shape, BlockState block) {
// BlockHitResult blockHitResult = shape.clip(world, from, to);
// if (blockHitResult != null) {
// BlockHitResult var7 = block.getInteractionShape(this, to).clip(world,
// from, to); if (var7 != null
// && var7.getLocation().subtract(world).lengthSqr() <
// blockHitResult.getLocation().subtract(world).lengthSqr()) { return
// blockHitResult.withDirection(var7.getDirection()); }
// }

// return blockHitResult;
// }
fn clip_with_interaction_override(
from: &Vec3,
to: &Vec3,
Expand All @@ -119,8 +100,8 @@ fn clip_with_interaction_override(
let interaction_shape = block_state.shape();
let interaction_hit_result = interaction_shape.clip(from, to, block_pos);
if let Some(interaction_hit_result) = interaction_hit_result {
if interaction_hit_result.location.distance_to_sqr(from)
< block_hit_result.location.distance_to_sqr(from)
if interaction_hit_result.location.distance_squared_to(from)
< block_hit_result.location.distance_squared_to(from)
{
return Some(block_hit_result.with_direction(interaction_hit_result.direction));
}
Expand Down
12 changes: 8 additions & 4 deletions azalea-physics/src/collision/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics)
// let entity_collisions = world.get_entity_collisions(self,
// entity_bounding_box.expand_towards(movement));
let entity_collisions = Vec::new();
let collided_delta = if movement.length_sqr() == 0.0 {
let collided_delta = if movement.length_squared() == 0.0 {
*movement
} else {
collide_bounding_box(
Expand Down Expand Up @@ -109,12 +109,16 @@ fn collide(movement: &Vec3, world: &Instance, physics: &azalea_entity::Physics)
entity_collisions.clone(),
)
.add(directly_up_delta);
if target_movement.horizontal_distance_sqr() > step_to_delta.horizontal_distance_sqr() {
if target_movement.horizontal_distance_squared()
> step_to_delta.horizontal_distance_squared()
{
step_to_delta = target_movement;
}
}

if step_to_delta.horizontal_distance_sqr() > collided_delta.horizontal_distance_sqr() {
if step_to_delta.horizontal_distance_squared()
> collided_delta.horizontal_distance_squared()
{
return step_to_delta.add(collide_bounding_box(
&Vec3 {
x: 0.,
Expand Down Expand Up @@ -162,7 +166,7 @@ pub fn move_colliding(

let collide_result = collide(movement, world, physics);

let move_distance = collide_result.length_sqr();
let move_distance = collide_result.length_squared();

if move_distance > EPSILON {
// TODO: fall damage
Expand Down
2 changes: 1 addition & 1 deletion azalea-physics/src/collision/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ impl VoxelShape {
return None;
}
let vector = to - from;
if vector.length_sqr() < EPSILON {
if vector.length_squared() < EPSILON {
return None;
}
let right_after_start = from + &(vector * 0.0001);
Expand Down
2 changes: 1 addition & 1 deletion azalea-protocol/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
/// use azalea_protocol::connect::Connection;
/// use azalea_protocol::packets::login::{
/// ClientboundLoginPacket,
/// s_key::ServerboundKey
/// ServerboundKey
/// };
/// use uuid::Uuid;
/// # use azalea_protocol::ServerAddress;
Expand Down
90 changes: 25 additions & 65 deletions azalea-protocol/src/packets/game/c_player_chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use azalea_chat::{
use azalea_core::bitset::BitSet;
use azalea_crypto::MessageSignature;
use azalea_protocol_macros::ClientboundGamePacket;
use azalea_registry::{ChatType, OptionalRegistry};
use uuid::Uuid;

#[derive(Clone, Debug, AzBuf, ClientboundGamePacket, PartialEq)]
Expand Down Expand Up @@ -51,23 +52,35 @@ pub enum FilterMask {
PartiallyFiltered(BitSet),
}

#[derive(Copy, Clone, Debug, AzBuf, PartialEq, Eq)]
pub enum ChatType {
Chat = 0,
SayCommand = 1,
MsgCommandIncoming = 2,
MsgCommandOutgoing = 3,
TeamMsgCommandIncoming = 4,
TeamMsgCommandOutgoing = 5,
EmoteCommand = 6,
}

#[derive(Clone, Debug, AzBuf, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
pub struct ChatTypeBound {
pub chat_type: ChatType,
pub name: FormattedText,
pub target_name: Option<FormattedText>,
}
impl AzaleaRead for ChatTypeBound {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let Some(chat_type) = OptionalRegistry::<ChatType>::azalea_read(buf)?.0 else {
return Err(BufReadError::Custom("ChatType cannot be None".to_owned()));
};
let name = FormattedText::azalea_read(buf)?;
let target_name = Option::<FormattedText>::azalea_read(buf)?;

Ok(ChatTypeBound {
chat_type,
name,
target_name,
})
}
}
impl AzaleaWrite for ChatTypeBound {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
OptionalRegistry(Some(self.chat_type)).azalea_write(buf)?;
self.name.azalea_write(buf)?;
self.target_name.azalea_write(buf)?;
Ok(())
}
}

// must be in Client
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -119,29 +132,6 @@ impl ClientboundPlayerChat {
}
}

impl ChatType {
#[must_use]
pub fn chat_translation_key(&self) -> &'static str {
match self {
ChatType::Chat => "chat.type.text",
ChatType::SayCommand => "chat.type.announcement",
ChatType::MsgCommandIncoming => "commands.message.display.incoming",
ChatType::MsgCommandOutgoing => "commands.message.display.outgoing",
ChatType::TeamMsgCommandIncoming => "chat.type.team.text",
ChatType::TeamMsgCommandOutgoing => "chat.type.team.sent",
ChatType::EmoteCommand => "chat.type.emote",
}
}

#[must_use]
pub fn narrator_translation_key(&self) -> &'static str {
match self {
ChatType::EmoteCommand => "chat.type.emote",
_ => "chat.type.text.narrate",
}
}
}

impl AzaleaRead for PackedMessageSignature {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let id = u32::azalea_read_var(buf)?;
Expand All @@ -168,33 +158,3 @@ impl AzaleaWrite for PackedMessageSignature {
Ok(())
}
}

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

#[test]
fn test_read_player_chat_packet() {
let mut bytes = Cursor::new(
&[
55, 186, 28, 76, 92, 167, 177, 75, 188, 158, 200, 179, 191, 227, 16, 171, 145, 0,
0, 4, 116, 101, 115, 116, 0, 0, 1, 140, 178, 225, 89, 103, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 10, 10, 0, 10, 104, 111, 118, 101, 114, 69, 118, 101, 110, 116, 10, 0,
8, 99, 111, 110, 116, 101, 110, 116, 115, 8, 0, 4, 110, 97, 109, 101, 0, 12, 75,
97, 115, 117, 109, 105, 77, 97, 114, 105, 115, 97, 11, 0, 2, 105, 100, 0, 0, 0, 4,
186, 28, 76, 92, 167, 177, 75, 188, 158, 200, 179, 191, 227, 16, 171, 145, 8, 0, 4,
116, 121, 112, 101, 0, 16, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 112, 108,
97, 121, 101, 114, 0, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 11, 115, 104, 111,
119, 95, 101, 110, 116, 105, 116, 121, 0, 10, 0, 10, 99, 108, 105, 99, 107, 69,
118, 101, 110, 116, 8, 0, 6, 97, 99, 116, 105, 111, 110, 0, 15, 115, 117, 103, 103,
101, 115, 116, 95, 99, 111, 109, 109, 97, 110, 100, 8, 0, 5, 118, 97, 108, 117,
101, 0, 19, 47, 116, 101, 108, 108, 32, 75, 97, 115, 117, 109, 105, 77, 97, 114,
105, 115, 97, 32, 0, 9, 0, 5, 101, 120, 116, 114, 97, 8, 0, 0, 0, 3, 0, 0, 0, 12,
75, 97, 115, 117, 109, 105, 77, 97, 114, 105, 115, 97, 0, 0, 8, 0, 9, 105, 110,
115, 101, 114, 116, 105, 111, 110, 0, 12, 75, 97, 115, 117, 109, 105, 77, 97, 114,
105, 115, 97, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 0,
][..],
);
let _packet = ClientboundPlayerChat::azalea_read(&mut bytes).unwrap();
}
}
Loading

0 comments on commit c8891dc

Please sign in to comment.