1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

fix incorrect jumping

This commit is contained in:
mat 2023-09-10 17:33:10 -05:00
parent a91b62d4ca
commit 4885f848a4
5 changed files with 91 additions and 62 deletions

View file

@ -49,8 +49,7 @@ impl Plugin for MinePlugin {
.after(crate::interact::update_hit_result_component)
.after(crate::attack::handle_attack_event)
.after(crate::interact::handle_block_interact_event)
.before(crate::interact::handle_swing_arm_event)
.before(azalea_physics::handle_force_jump),
.before(crate::interact::handle_swing_arm_event),
);
}
}

View file

@ -2,7 +2,7 @@ use crate::client::Client;
use crate::local_player::{LocalPlayer, LocalPlayerInLoadedChunk};
use azalea_entity::{metadata::Sprinting, Attributes, Jumping};
use azalea_entity::{LastSentPosition, LookDirection, Physics, Position};
use azalea_physics::{handle_force_jump, PhysicsSet};
use azalea_physics::PhysicsSet;
use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket;
use azalea_protocol::packets::game::{
serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket,
@ -44,12 +44,7 @@ impl Plugin for PlayerMovePlugin {
fn build(&self, app: &mut App) {
app.add_event::<StartWalkEvent>()
.add_event::<StartSprintEvent>()
.add_systems(
Update,
(sprint_listener, walk_listener)
.chain()
.before(handle_force_jump),
)
.add_systems(Update, (sprint_listener, walk_listener).chain())
.add_systems(
FixedUpdate,
(

View file

@ -31,12 +31,6 @@ pub struct PhysicsPlugin;
impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut App) {
app.add_event::<ForceJumpEvent>()
.add_systems(
Update,
handle_force_jump
.after(azalea_entity::clamp_look_direction)
.before(azalea_entity::update_bounding_box),
)
.add_systems(FixedUpdate, (ai_step, travel).chain().in_set(PhysicsSet));
}
}
@ -125,15 +119,32 @@ fn travel(
/// stuff.
pub fn ai_step(
mut query: Query<
(Entity, &mut Physics, Option<&Jumping>),
(
Entity,
&mut Physics,
Option<&Jumping>,
&Position,
&LookDirection,
&Sprinting,
&InstanceName,
),
With<Local>,
// TODO: ai_step should only run for players in loaded chunks
// With<LocalPlayerInLoadedChunk> maybe there should be an InLoadedChunk/InUnloadedChunk
// component?
>,
mut force_jump_events: EventWriter<ForceJumpEvent>,
// mut jump_query: Query<(
// &mut Physics,
// &Position,
// &LookDirection,
// &Sprinting,
// &InstanceName,
// )>,
instance_container: Res<InstanceContainer>,
) {
for (entity, mut physics, jumping) in &mut query {
for (entity, 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
@ -152,7 +163,14 @@ pub fn ai_step(
// TODO: jumping in liquids and jump delay
if physics.on_ground {
force_jump_events.send(ForceJumpEvent(entity));
jump_from_ground(
&mut physics,
position,
look_direction,
sprinting,
instance_name,
&instance_container,
)
}
}
}
@ -169,46 +187,37 @@ pub fn ai_step(
#[derive(Event)]
pub struct ForceJumpEvent(pub Entity);
pub fn handle_force_jump(
mut query: Query<(
&mut Physics,
&Position,
&LookDirection,
&Sprinting,
&InstanceName,
)>,
instance_container: Res<InstanceContainer>,
mut events: EventReader<ForceJumpEvent>,
pub fn jump_from_ground(
physics: &mut Physics,
position: &Position,
look_direction: &LookDirection,
sprinting: &Sprinting,
instance_name: &InstanceName,
instance_container: &InstanceContainer,
) {
for event in events.iter() {
if let Ok((mut physics, position, direction, sprinting, world_name)) =
query.get_mut(event.0)
{
let world_lock = instance_container
.get(world_name)
.expect("All entities should be in a valid world");
let world = world_lock.read();
let world_lock = instance_container
.get(instance_name)
.expect("All entities should be in a valid world");
let world = world_lock.read();
let jump_power: f64 = jump_power(&world, position) as f64 + jump_boost_power();
let old_delta_movement = physics.delta;
physics.delta = Vec3 {
x: old_delta_movement.x,
y: jump_power,
z: old_delta_movement.z,
};
if **sprinting {
// sprint jumping gives some extra velocity
let y_rot = direction.y_rot * 0.017453292;
physics.delta += Vec3 {
x: (-f32::sin(y_rot) * 0.2) as f64,
y: 0.,
z: (f32::cos(y_rot) * 0.2) as f64,
};
}
physics.has_impulse = true;
}
let jump_power: f64 = jump_power(&world, position) as f64 + jump_boost_power();
let old_delta_movement = physics.delta;
physics.delta = Vec3 {
x: old_delta_movement.x,
y: jump_power,
z: old_delta_movement.z,
};
if **sprinting {
// 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,
y: 0.,
z: (f32::cos(y_rot) * 0.2) as f64,
};
}
physics.has_impulse = true;
}
fn get_block_pos_below_that_affects_movement(position: &Position) -> BlockPos {
@ -228,7 +237,6 @@ fn handle_relative_friction_and_calculate_movement(
position: &mut Position,
attributes: &Attributes,
) -> Vec3 {
trace!("handle_relative_friction_and_calculate_movement {direction:?}");
move_relative(
physics,
direction,

View file

@ -15,7 +15,7 @@ use azalea_core::{BlockPos, Vec3};
use azalea_entity::{
clamp_look_direction, metadata::Player, EyeHeight, Jumping, Local, LookDirection, Position,
};
use azalea_physics::{handle_force_jump, PhysicsSet};
use azalea_physics::PhysicsSet;
use bevy_app::{FixedUpdate, Update};
use bevy_ecs::prelude::Event;
use bevy_ecs::schedule::IntoSystemConfigs;
@ -34,10 +34,8 @@ impl Plugin for BotPlugin {
Update,
(
insert_bot,
look_at_listener
.before(handle_force_jump)
.before(clamp_look_direction),
jump_listener.before(handle_force_jump),
look_at_listener.before(clamp_look_direction),
jump_listener,
),
)
.add_systems(FixedUpdate, stop_jumping.after(PhysicsSet));

View file

@ -381,4 +381,33 @@ mod tests {
BlockPos::new(2, 71, 2)
);
}
#[test]
fn test_jump_with_sideways_momentum() {
let mut partial_chunks = PartialChunkStorage::default();
let mut simulation = setup_simulation(
&mut partial_chunks,
BlockPos::new(0, 71, 3),
BlockPos::new(5, 76, 0),
vec![
BlockPos::new(0, 70, 3),
BlockPos::new(0, 70, 2),
BlockPos::new(0, 70, 1),
BlockPos::new(0, 70, 0),
BlockPos::new(1, 71, 0),
BlockPos::new(2, 72, 0),
BlockPos::new(3, 73, 0),
BlockPos::new(4, 74, 0),
BlockPos::new(5, 75, 0),
],
);
for i in 0..120 {
simulation.tick();
info!("-- tick #{i} --")
}
assert_eq!(
BlockPos::from(simulation.position()),
BlockPos::new(5, 76, 0)
);
}
}