diff --git a/pumpkin/src/entity/living.rs b/pumpkin/src/entity/living.rs index 794d3ea52..3f6dad084 100644 --- a/pumpkin/src/entity/living.rs +++ b/pumpkin/src/entity/living.rs @@ -24,7 +24,7 @@ pub struct LivingEntity { /// The current health level of the entity. pub health: AtomicCell, /// The distance the entity has been falling - pub fall_distance: AtomicCell, + pub fall_distance: AtomicCell, } impl LivingEntity { pub const fn new(entity: Entity) -> Self { @@ -113,25 +113,21 @@ impl LivingEntity { amount > 0.0 } - pub async fn update_fall_distance(&self, dont_damage: bool) { - let y = self.entity.pos.load().y; - let last_y = self.last_pos.load().y; - let grounded = self - .entity - .on_ground - .load(std::sync::atomic::Ordering::Relaxed); - - // + => falling, - => up - let y_diff = last_y - y; - - if grounded { + pub async fn update_fall_distance( + &self, + height_difference: f64, + ground: bool, + dont_damage: bool, + ) { + if ground { let fall_distance = self.fall_distance.swap(0.0); - if dont_damage { + if fall_distance <= 0.0 || dont_damage { return; } - let mut damage = (fall_distance - 3.0).max(0.0) as f32; - damage = (damage * 2.0).round() / 2.0; + let safe_fall_distance = 3.0; + let mut damage = fall_distance - safe_fall_distance; + damage = (damage).round(); if !self.check_damage(damage) { return; } @@ -141,11 +137,10 @@ impl LivingEntity { .await; // TODO: Play block fall sound self.damage(damage, 10).await; // Fall - } else if y_diff < 0.0 { - self.fall_distance.store(0.0); - } else { - let fall_distance = self.fall_distance.load(); - self.fall_distance.store(fall_distance + y_diff); + } else if height_difference < 0.0 { + let distance = self.fall_distance.load(); + self.fall_distance + .store(distance - (height_difference as f32)); } } diff --git a/pumpkin/src/net/packet/play.rs b/pumpkin/src/net/packet/play.rs index e73227fbd..01c0ecfe2 100644 --- a/pumpkin/src/net/packet/play.rs +++ b/pumpkin/src/net/packet/play.rs @@ -148,17 +148,15 @@ impl Player { Self::clamp_horizontal(position.z), ); let entity = &self.living_entity.entity; + let last_pos = entity.pos.load(); self.living_entity.set_pos(position); - let pos = entity.pos.load(); - let last_pos = self.living_entity.last_pos.load(); - entity .on_ground .store(packet.ground, std::sync::atomic::Ordering::Relaxed); let entity_id = entity.entity_id; - let Vector3 { x, y, z } = pos; + let Vector3 { x, y, z } = position; let world = &entity.world; // let delta = Vector3::new(x - lastx, y - lasty, z - lastz); @@ -188,6 +186,16 @@ impl Player { ), ) .await; + if !self.abilities.lock().await.flying { + let height_difference = position.y - last_pos.y; + self.living_entity + .update_fall_distance( + height_difference, + packet.ground, + self.gamemode.load() == GameMode::Creative, + ) + .await; + } player_chunker::update_position(self).await; } @@ -217,11 +225,9 @@ impl Player { Self::clamp_horizontal(position.z), ); let entity = &self.living_entity.entity; + let last_pos = entity.pos.load(); self.living_entity.set_pos(position); - let pos = entity.pos.load(); - let last_pos = self.living_entity.last_pos.load(); - entity .on_ground .store(packet.ground, std::sync::atomic::Ordering::Relaxed); @@ -232,7 +238,7 @@ impl Player { ); let entity_id = entity.entity_id; - let Vector3 { x, y, z } = pos; + let Vector3 { x, y, z } = position; let yaw = (entity.yaw.load() * 256.0 / 360.0).rem_euclid(256.0); let pitch = (entity.pitch.load() * 256.0 / 360.0).rem_euclid(256.0); @@ -275,6 +281,16 @@ impl Player { &CHeadRot::new(entity_id.into(), yaw as u8), ) .await; + if !self.abilities.lock().await.flying { + let height_difference = position.y - last_pos.y; + self.living_entity + .update_fall_distance( + height_difference, + packet.ground, + self.gamemode.load() == GameMode::Creative, + ) + .await; + } player_chunker::update_position(self).await; } diff --git a/pumpkin/src/world/player_chunker.rs b/pumpkin/src/world/player_chunker.rs index de7e33858..3145103be 100644 --- a/pumpkin/src/world/player_chunker.rs +++ b/pumpkin/src/world/player_chunker.rs @@ -2,10 +2,7 @@ use std::{num::NonZeroU8, sync::Arc}; use pumpkin_config::BASIC_CONFIG; use pumpkin_protocol::client::play::{CCenterChunk, CUnloadChunk}; -use pumpkin_util::{ - math::{get_section_cord, position::BlockPos, vector3::Vector3}, - GameMode, -}; +use pumpkin_util::math::{get_section_cord, position::BlockPos, vector3::Vector3}; use pumpkin_world::cylindrical_chunk_iterator::Cylindrical; use crate::entity::player::Player; @@ -40,13 +37,6 @@ pub async fn player_join(player: &Arc) { } pub async fn update_position(player: &Arc) { - if !player.abilities.lock().await.flying { - player - .living_entity - .update_fall_distance(player.gamemode.load() == GameMode::Creative) - .await; - } - let entity = &player.living_entity.entity; let view_distance = get_view_distance(player).await;