aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-client/src/movement.rs1
-rwxr-xr-xazalea-core/src/lib.rs1
-rw-r--r--azalea-core/src/math.rs24
-rw-r--r--azalea-entity/src/lib.rs14
-rw-r--r--azalea-physics/src/lib.rs40
-rw-r--r--azalea/examples/testbot.rs4
6 files changed, 59 insertions, 25 deletions
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index 7eb7b958..351d91be 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -405,6 +405,7 @@ pub fn walk_listener(
if let Ok((mut physics_state, mut sprinting, mut attributes)) = query.get_mut(event.entity)
{
physics_state.move_direction = event.direction;
+ physics_state.trying_to_sprint = false;
set_sprinting(false, &mut sprinting, &mut attributes);
}
}
diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs
index 8ed62b06..6554d71d 100755
--- a/azalea-core/src/lib.rs
+++ b/azalea-core/src/lib.rs
@@ -1,6 +1,7 @@
#![doc = include_str!("../README.md")]
#![feature(int_roundings)]
#![feature(const_for)]
+#![feature(lazy_cell)]
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
diff --git a/azalea-core/src/math.rs b/azalea-core/src/math.rs
index 2e5e78f6..40d147e4 100644
--- a/azalea-core/src/math.rs
+++ b/azalea-core/src/math.rs
@@ -1,3 +1,27 @@
+use std::sync::LazyLock;
+
+pub static SIN: LazyLock<[f32; 65536]> = LazyLock::new(|| {
+ let mut sin = [0.0; 65536];
+ for i in 0..65536 {
+ sin[i] = f64::sin((i as f64) * 3.141592653589793 * 2.0 / 65536.0) as f32;
+ }
+ sin
+});
+
+/// A sine function that uses a lookup table.
+pub fn sin(var0: f32) -> f32 {
+ let var0 = var0 * 10430.378;
+ let var0 = var0 as usize;
+ SIN[var0 & 65535]
+}
+
+/// A cosine function that uses a lookup table.
+pub fn cos(var0: f32) -> f32 {
+ let var0 = var0 * 10430.378 + 16384.0;
+ let var0 = var0 as usize;
+ SIN[var0 & 65535]
+}
+
// TODO: make this generic
pub fn binary_search(mut min: i32, max: i32, predicate: &dyn Fn(i32) -> bool) -> i32 {
let mut diff = max - min;
diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs
index fc312f79..e13ec2f0 100644
--- a/azalea-entity/src/lib.rs
+++ b/azalea-entity/src/lib.rs
@@ -12,7 +12,7 @@ mod plugin;
use self::attributes::AttributeInstance;
pub use attributes::Attributes;
use azalea_block::BlockState;
-use azalea_core::{BlockPos, ChunkPos, ResourceLocation, Vec3, AABB};
+use azalea_core::{math, BlockPos, ChunkPos, ResourceLocation, Vec3, AABB};
use azalea_world::{ChunkStorage, InstanceName};
use bevy_ecs::{bundle::Bundle, component::Component};
pub use data::*;
@@ -44,8 +44,8 @@ pub fn input_vector(direction: &LookDirection, speed: f32, acceleration: &Vec3)
*acceleration
}
.scale(speed as f64);
- let y_rot = f32::sin(direction.y_rot * 0.017453292f32);
- let x_rot = f32::cos(direction.y_rot * 0.017453292f32);
+ let y_rot = math::sin(direction.y_rot * 0.017453292f32);
+ let x_rot = math::cos(direction.y_rot * 0.017453292f32);
Vec3 {
x: acceleration.x * (x_rot as f64) - acceleration.z * (y_rot as f64),
y: acceleration.y,
@@ -56,10 +56,10 @@ pub fn input_vector(direction: &LookDirection, speed: f32, acceleration: &Vec3)
pub fn view_vector(look_direction: &LookDirection) -> Vec3 {
let x_rot = look_direction.x_rot * 0.017453292;
let y_rot = -look_direction.y_rot * 0.017453292;
- let y_rot_cos = f32::cos(y_rot);
- let y_rot_sin = f32::sin(y_rot);
- let x_rot_cos = f32::cos(x_rot);
- let x_rot_sin = f32::sin(x_rot);
+ let y_rot_cos = math::cos(y_rot);
+ let y_rot_sin = math::sin(y_rot);
+ let x_rot_cos = math::cos(x_rot);
+ let x_rot_sin = math::sin(x_rot);
Vec3 {
x: (y_rot_sin * x_rot_cos) as f64,
y: (-x_rot_sin) as f64,
diff --git a/azalea-physics/src/lib.rs b/azalea-physics/src/lib.rs
index 673c425e..cad1c15f 100644
--- a/azalea-physics/src/lib.rs
+++ b/azalea-physics/src/lib.rs
@@ -5,7 +5,7 @@ pub mod clip;
pub mod collision;
use azalea_block::{Block, BlockState};
-use azalea_core::{BlockPos, Vec3};
+use azalea_core::{math, BlockPos, Vec3};
use azalea_entity::{
metadata::Sprinting, move_relative, Attributes, Jumping, Local, LookDirection, Physics,
Position,
@@ -30,8 +30,7 @@ pub struct PhysicsSet;
pub struct PhysicsPlugin;
impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut App) {
- app.add_event::<ForceJumpEvent>()
- .add_systems(FixedUpdate, (ai_step, travel).chain().in_set(PhysicsSet));
+ app.add_systems(FixedUpdate, (ai_step, travel).chain().in_set(PhysicsSet));
}
}
@@ -43,6 +42,7 @@ fn travel(
&mut Physics,
&mut LookDirection,
&mut Position,
+ Option<&Sprinting>,
&Attributes,
&InstanceName,
),
@@ -50,7 +50,7 @@ fn travel(
>,
instance_container: Res<InstanceContainer>,
) {
- for (mut physics, direction, mut position, attributes, world_name) in &mut query {
+ for (mut physics, direction, mut position, sprinting, attributes, world_name) in &mut query {
let world_lock = instance_container
.get(world_name)
.expect("All entities should be in a valid world");
@@ -92,6 +92,7 @@ fn travel(
&direction,
&mut position,
attributes,
+ sprinting.map(|s| **s).unwrap_or(false),
);
movement.y -= gravity;
@@ -108,7 +109,7 @@ fn travel(
} else {
physics.delta = Vec3 {
x: movement.x * inertia as f64,
- y: movement.y * 0.98f64,
+ y: movement.y * 0.9800000190734863f64,
z: movement.z * inertia as f64,
};
}
@@ -120,7 +121,6 @@ fn travel(
pub fn ai_step(
mut query: Query<
(
- Entity,
&mut Physics,
Option<&Jumping>,
&Position,
@@ -142,9 +142,7 @@ pub fn ai_step(
// )>,
instance_container: Res<InstanceContainer>,
) {
- for (entity, mut physics, jumping, position, look_direction, sprinting, instance_name) in
- &mut query
- {
+ for (mut physics, jumping, position, look_direction, sprinting, instance_name) in &mut query {
// vanilla does movement interpolation here, doesn't really matter much for a
// bot though
@@ -183,10 +181,6 @@ pub fn ai_step(
}
}
-/// Jump even if we aren't on the ground.
-#[derive(Event)]
-pub struct ForceJumpEvent(pub Entity);
-
pub fn jump_from_ground(
physics: &mut Physics,
position: &Position,
@@ -211,9 +205,9 @@ pub fn jump_from_ground(
// sprint jumping gives some extra velocity
let y_rot = look_direction.y_rot * 0.017453292;
physics.delta += Vec3 {
- x: (-f32::sin(y_rot) * 0.2) as f64,
+ x: (-math::sin(y_rot) * 0.2) as f64,
y: 0.,
- z: (f32::cos(y_rot) * 0.2) as f64,
+ z: (math::cos(y_rot) * 0.2) as f64,
};
}
@@ -236,11 +230,12 @@ fn handle_relative_friction_and_calculate_movement(
direction: &LookDirection,
position: &mut Position,
attributes: &Attributes,
+ is_sprinting: bool,
) -> Vec3 {
move_relative(
physics,
direction,
- get_friction_influenced_speed(physics, attributes, block_friction),
+ get_friction_influenced_speed(physics, attributes, block_friction, is_sprinting),
&Vec3 {
x: physics.xxa as f64,
y: physics.yya as f64,
@@ -270,14 +265,23 @@ fn handle_relative_friction_and_calculate_movement(
// private float getFrictionInfluencedSpeed(float friction) {
// return this.onGround ? this.getSpeed() * (0.21600002F / (friction *
// friction * friction)) : this.flyingSpeed; }
-fn get_friction_influenced_speed(physics: &Physics, attributes: &Attributes, friction: f32) -> f32 {
+fn get_friction_influenced_speed(
+ physics: &Physics,
+ attributes: &Attributes,
+ friction: f32,
+ is_sprinting: bool,
+) -> f32 {
// TODO: have speed & flying_speed fields in entity
if physics.on_ground {
let speed: f32 = attributes.speed.calculate() as f32;
speed * (0.216f32 / (friction * friction * friction))
} else {
// entity.flying_speed
- 0.02
+ if is_sprinting {
+ 0.025999999f32
+ } else {
+ 0.02
+ }
}
}
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs
index 14800e9c..630ddf00 100644
--- a/azalea/examples/testbot.rs
+++ b/azalea/examples/testbot.rs
@@ -11,6 +11,7 @@ use azalea::pathfinder::goals::BlockPosGoal;
use azalea::protocol::packets::game::ClientboundGamePacket;
use azalea::{prelude::*, swarm::prelude::*, BlockPos, GameProfileComponent, WalkDirection};
use azalea::{Account, Client, Event};
+use azalea_client::SprintDirection;
use azalea_core::Vec3;
use azalea_world::{InstanceName, MinecraftEntityId};
use std::time::Duration;
@@ -145,6 +146,9 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
"walk" => {
bot.walk(WalkDirection::Forward);
}
+ "sprint" => {
+ bot.sprint(SprintDirection::Forward);
+ }
"stop" => {
bot.set_jumping(false);
bot.walk(WalkDirection::None);