mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Improve fall damage calculation
This commit is contained in:
@@ -24,7 +24,7 @@ pub struct LivingEntity {
|
||||
/// The current health level of the entity.
|
||||
pub health: AtomicCell<f32>,
|
||||
/// The distance the entity has been falling
|
||||
pub fall_distance: AtomicCell<f64>,
|
||||
pub fall_distance: AtomicCell<f32>,
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Player>) {
|
||||
}
|
||||
|
||||
pub async fn update_position(player: &Arc<Player>) {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user