mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
add jumping
This commit is contained in:
parent
c9b4dccd7e
commit
37f9f1c6fe
7 changed files with 145 additions and 4 deletions
|
@ -1,7 +1,17 @@
|
|||
#[derive(Default)]
|
||||
pub struct BlockBehavior {
|
||||
pub has_collision: bool,
|
||||
pub friction: f32,
|
||||
pub jump_factor: f32,
|
||||
}
|
||||
|
||||
impl Default for BlockBehavior {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
has_collision: true,
|
||||
friction: 0.6,
|
||||
jump_factor: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockBehavior {
|
||||
|
@ -16,4 +26,10 @@ impl BlockBehavior {
|
|||
self.friction = friction;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn jump_factor(mut self, jump_factor: f32) -> Self {
|
||||
self.jump_factor = jump_factor;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,12 @@ pub struct PhysicsState {
|
|||
pub move_direction: MoveDirection,
|
||||
pub forward_impulse: f32,
|
||||
pub left_impulse: f32,
|
||||
|
||||
/// Whether we will jump next tick. This is purely to help with bots,
|
||||
/// realistic clients should change the `jumping` field in the player entity.
|
||||
///
|
||||
/// TODO: have a convenient way to change the `jumping` field in the player entity.
|
||||
pub jumping_once: bool,
|
||||
}
|
||||
|
||||
/// Whether we should ignore errors when decoding packets.
|
||||
|
|
|
@ -166,9 +166,16 @@ impl Client {
|
|||
|
||||
// server ai step
|
||||
{
|
||||
let physics_state = self.physics_state.lock().unwrap();
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
player_entity.xxa = physics_state.left_impulse;
|
||||
player_entity.zza = physics_state.forward_impulse;
|
||||
|
||||
// handle jumping_once
|
||||
if physics_state.jumping_once {
|
||||
player_entity.jumping = true;
|
||||
} else if player_entity.jumping {
|
||||
physics_state.jumping_once = false;
|
||||
}
|
||||
}
|
||||
|
||||
player_entity.ai_step();
|
||||
|
@ -210,10 +217,33 @@ impl Client {
|
|||
}
|
||||
}
|
||||
|
||||
/// Start walking in the given direction.
|
||||
pub fn walk(&mut self, direction: MoveDirection) {
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
physics_state.move_direction = direction;
|
||||
}
|
||||
|
||||
/// Jump once next tick. This acts as if you pressed space for one tick in
|
||||
/// vanilla. If you want to jump continuously, use `set_jumping`.
|
||||
pub fn jump(&mut self) {
|
||||
let mut physics_state = self.physics_state.lock().unwrap();
|
||||
physics_state.jumping_once = true;
|
||||
}
|
||||
|
||||
/// Toggle whether we're jumping. This acts as if you held space in
|
||||
/// vanilla. If you want to jump once, use the `jump` function.
|
||||
///
|
||||
/// If you're making a realistic client, calling this function every tick is
|
||||
/// recommended.
|
||||
pub fn set_jumping(&mut self, jumping: bool) {
|
||||
let player_lock = self.player.lock().unwrap();
|
||||
let mut dimension_lock = self.dimension.lock().unwrap();
|
||||
let mut player_entity = player_lock
|
||||
.entity_mut(&mut dimension_lock)
|
||||
.expect("Player must exist");
|
||||
|
||||
player_entity.jumping = jumping;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
|
|
|
@ -133,7 +133,7 @@ impl MovableEntity for EntityMut<'_> {
|
|||
let horizontal_collision = x_collision || z_collision;
|
||||
let vertical_collision = movement.y != collide_result.y;
|
||||
let on_ground = vertical_collision && movement.y < 0.;
|
||||
// self.on_ground = on_ground;
|
||||
self.on_ground = on_ground;
|
||||
|
||||
// TODO: minecraft checks for a "minor" horizontal collision here
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ use collision::{MovableEntity, MoverType};
|
|||
pub trait HasPhysics {
|
||||
fn travel(&mut self, acceleration: &Vec3);
|
||||
fn ai_step(&mut self);
|
||||
|
||||
fn jump_from_ground(&mut self);
|
||||
}
|
||||
|
||||
impl HasPhysics for EntityMut<'_> {
|
||||
|
@ -85,6 +87,14 @@ impl HasPhysics for EntityMut<'_> {
|
|||
self.delta.z = 0.;
|
||||
}
|
||||
|
||||
if self.jumping {
|
||||
// TODO: jumping in liquids and jump delay
|
||||
|
||||
if self.on_ground {
|
||||
self.jump_from_ground();
|
||||
}
|
||||
}
|
||||
|
||||
self.xxa *= 0.98;
|
||||
self.zza *= 0.98;
|
||||
|
||||
|
@ -97,6 +107,27 @@ impl HasPhysics for EntityMut<'_> {
|
|||
// pushEntities
|
||||
// drowning damage
|
||||
}
|
||||
|
||||
fn jump_from_ground(&mut self) {
|
||||
let jump_power: f64 = jump_power(self) as f64 + jump_boost_power(self);
|
||||
let old_delta_movement = self.delta;
|
||||
self.delta = Vec3 {
|
||||
x: old_delta_movement.x,
|
||||
y: jump_power,
|
||||
z: old_delta_movement.z,
|
||||
};
|
||||
// if self.sprinting {
|
||||
// let y_rot = self.y_rot * 0.017453292;
|
||||
// self.delta = self.delta
|
||||
// + Vec3 {
|
||||
// x: (-f32::sin(y_rot) * 0.2) as f64,
|
||||
// y: 0.,
|
||||
// z: (f32::cos(y_rot) * 0.2) as f64,
|
||||
// };
|
||||
// }
|
||||
|
||||
// self.has_impulse = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_block_pos_below_that_affects_movement(entity: &EntityData) -> BlockPos {
|
||||
|
@ -141,6 +172,54 @@ fn get_speed(entity: &EntityData, friction: f32) -> f32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the what the entity's jump should be multiplied by based on the
|
||||
/// block they're standing on.
|
||||
fn block_jump_factor(entity: &EntityMut) -> f32 {
|
||||
let block_at_pos = entity.dimension.get_block_state(&entity.pos().into());
|
||||
let block_below = entity
|
||||
.dimension
|
||||
.get_block_state(&get_block_pos_below_that_affects_movement(entity));
|
||||
|
||||
let block_at_pos_jump_factor = if let Some(block) = block_at_pos {
|
||||
Box::<dyn Block>::from(block).behavior().jump_factor
|
||||
} else {
|
||||
1.
|
||||
};
|
||||
if block_at_pos_jump_factor != 1. {
|
||||
return block_at_pos_jump_factor;
|
||||
}
|
||||
|
||||
if let Some(block) = block_below {
|
||||
Box::<dyn Block>::from(block).behavior().jump_factor
|
||||
} else {
|
||||
1.
|
||||
}
|
||||
}
|
||||
|
||||
// protected float getJumpPower() {
|
||||
// return 0.42F * this.getBlockJumpFactor();
|
||||
// }
|
||||
// public double getJumpBoostPower() {
|
||||
// return this.hasEffect(MobEffects.JUMP) ? (double)(0.1F * (float)(this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D;
|
||||
// }
|
||||
fn jump_power(entity: &EntityMut) -> f32 {
|
||||
0.42 * block_jump_factor(entity)
|
||||
}
|
||||
|
||||
fn jump_boost_power(_entity: &EntityMut) -> f64 {
|
||||
// TODO: potion effects
|
||||
// if let Some(effects) = entity.effects() {
|
||||
// if let Some(jump_effect) = effects.get(&Effect::Jump) {
|
||||
// 0.1 * (jump_effect.amplifier + 1) as f32
|
||||
// } else {
|
||||
// 0.
|
||||
// }
|
||||
// } else {
|
||||
// 0.
|
||||
// }
|
||||
0.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -260,6 +260,10 @@ pub struct EntityData {
|
|||
pub dimensions: EntityDimensions,
|
||||
/// The bounding box of the entity. This is more than just width and height, unlike dimensions.
|
||||
pub bounding_box: AABB,
|
||||
|
||||
/// Whether the entity will try to jump every tick
|
||||
/// (equivalent to the space key being held down in vanilla).
|
||||
pub jumping: bool,
|
||||
}
|
||||
|
||||
impl EntityData {
|
||||
|
@ -291,6 +295,8 @@ impl EntityData {
|
|||
// TODO: have this be based on the entity type
|
||||
bounding_box: dimensions.make_bounding_box(&pos),
|
||||
dimensions,
|
||||
|
||||
jumping: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,16 @@ async fn handle_event(event: Event, mut bot: Client) -> anyhow::Result<()> {
|
|||
match event {
|
||||
Event::Login => {
|
||||
// tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
bot.walk(MoveDirection::Forward);
|
||||
// bot.walk(MoveDirection::Forward);
|
||||
|
||||
// loop {
|
||||
// tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
||||
// }
|
||||
// bot.walk(MoveDirection::None);
|
||||
}
|
||||
Event::GameTick => {
|
||||
bot.set_jumping(true);
|
||||
}
|
||||
Event::Packet(_packet) => {}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue