mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Check collision before block place (#251)
* Add bounding box to entities) * Try to update boundingbox when changin pos * Remove unused imports * Update / recalc boundingbox when changing pos * Add collision when placing check * Add todo: Check collision with every entity in pos * Change BoundingBox::new() args * Seperate bounding box width and height * Change intersect fn name * Clean up code
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use super::{position::WorldPosition, vector3::Vector3};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct BoundingBox {
|
||||
pub min_x: f64,
|
||||
pub min_y: f64,
|
||||
@@ -10,14 +11,30 @@ pub struct BoundingBox {
|
||||
}
|
||||
|
||||
impl BoundingBox {
|
||||
pub fn new(min_x: f64, min_y: f64, min_z: f64, max_x: f64, max_y: f64, max_z: f64) -> Self {
|
||||
pub fn new_default(size: &BoundingBoxSize) -> Self {
|
||||
Self::new_from_pos(0., 0., 0., size)
|
||||
}
|
||||
|
||||
pub fn new_from_pos(x: f64, y: f64, z: f64, size: &BoundingBoxSize) -> Self {
|
||||
let f = size.width / 2.;
|
||||
Self {
|
||||
min_x,
|
||||
min_y,
|
||||
min_z,
|
||||
max_x,
|
||||
max_y,
|
||||
max_z,
|
||||
min_x: x - f,
|
||||
min_y: y,
|
||||
min_z: z - f,
|
||||
max_x: x + f,
|
||||
max_y: y + size.height,
|
||||
max_z: z + f,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(min: Vector3<f64>, max: Vector3<f64>) -> Self {
|
||||
Self {
|
||||
min_x: min.x,
|
||||
min_y: min.y,
|
||||
min_z: min.z,
|
||||
max_x: max.x,
|
||||
max_y: max.y,
|
||||
max_z: max.z,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +50,15 @@ impl BoundingBox {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intersects(&self, other: &BoundingBox) -> bool {
|
||||
self.min_x < other.max_x
|
||||
&& self.max_x > other.min_x
|
||||
&& self.min_y < other.max_y
|
||||
&& self.max_y > other.min_y
|
||||
&& self.min_z < other.max_z
|
||||
&& self.max_z > other.min_z
|
||||
}
|
||||
|
||||
pub fn squared_magnitude(&self, pos: Vector3<f64>) -> f64 {
|
||||
let d = f64::max(f64::max(self.min_x - pos.x, pos.x - self.max_x), 0.0);
|
||||
let e = f64::max(f64::max(self.min_y - pos.y, pos.y - self.max_y), 0.0);
|
||||
@@ -40,3 +66,9 @@ impl BoundingBox {
|
||||
super::squared_magnitude(d, e, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct BoundingBoxSize {
|
||||
pub width: f64,
|
||||
pub height: f64,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
};
|
||||
use num_traits::FromPrimitive;
|
||||
use pumpkin_config::ADVANCED_CONFIG;
|
||||
use pumpkin_core::math::position::WorldPosition;
|
||||
use pumpkin_core::math::{boundingbox::BoundingBox, position::WorldPosition};
|
||||
use pumpkin_core::{
|
||||
math::{vector3::Vector3, wrap_degrees},
|
||||
text::TextComponent,
|
||||
@@ -577,12 +577,13 @@ impl Player {
|
||||
}
|
||||
}
|
||||
|
||||
world
|
||||
.set_block(
|
||||
WorldPosition(location.0 + face.to_offset()),
|
||||
block.default_state_id,
|
||||
)
|
||||
.await;
|
||||
let world_pos = WorldPosition(location.0 + face.to_offset());
|
||||
let block_bounding_box = BoundingBox::from_block(&world_pos);
|
||||
let bounding_box = entity.bounding_box.load();
|
||||
//TODO: Make this check for every entity in that posistion
|
||||
if !bounding_box.intersects(&block_bounding_box) {
|
||||
world.set_block(world_pos, block.default_state_id).await;
|
||||
}
|
||||
}
|
||||
self.client
|
||||
.send_packet(&CAcknowledgeBlockChange::new(use_item_on.sequence))
|
||||
|
||||
@@ -3,7 +3,11 @@ use std::sync::{atomic::AtomicBool, Arc};
|
||||
use crossbeam::atomic::AtomicCell;
|
||||
use num_derive::FromPrimitive;
|
||||
use pumpkin_core::math::{
|
||||
get_section_cord, position::WorldPosition, vector2::Vector2, vector3::Vector3,
|
||||
boundingbox::{BoundingBox, BoundingBoxSize},
|
||||
get_section_cord,
|
||||
position::WorldPosition,
|
||||
vector2::Vector2,
|
||||
vector3::Vector3,
|
||||
};
|
||||
use pumpkin_entity::{entity_type::EntityType, pose::EntityPose, EntityId};
|
||||
use pumpkin_protocol::{
|
||||
@@ -50,6 +54,10 @@ pub struct Entity {
|
||||
pub standing_eye_height: f32,
|
||||
/// The entity's current pose (e.g., standing, sitting, swimming).
|
||||
pub pose: AtomicCell<EntityPose>,
|
||||
/// The bounding box of an entity (hitbox)
|
||||
pub bounding_box: AtomicCell<BoundingBox>,
|
||||
///The size (width and height) of the bounding box
|
||||
pub bounding_box_size: AtomicCell<BoundingBoxSize>,
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
@@ -58,6 +66,8 @@ impl Entity {
|
||||
world: Arc<World>,
|
||||
entity_type: EntityType,
|
||||
standing_eye_height: f32,
|
||||
bounding_box: AtomicCell<BoundingBox>,
|
||||
bounding_box_size: AtomicCell<BoundingBoxSize>,
|
||||
) -> Self {
|
||||
Self {
|
||||
entity_id,
|
||||
@@ -77,6 +87,8 @@ impl Entity {
|
||||
velocity: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)),
|
||||
standing_eye_height,
|
||||
pose: AtomicCell::new(EntityPose::Standing),
|
||||
bounding_box,
|
||||
bounding_box_size,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +101,13 @@ impl Entity {
|
||||
if pos.x != x || pos.y != y || pos.z != z {
|
||||
self.pos.store(Vector3::new(x, y, z));
|
||||
|
||||
self.bounding_box.store(BoundingBox::new_from_pos(
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
&self.bounding_box_size.load(),
|
||||
));
|
||||
|
||||
let floor_x = x.floor() as i32;
|
||||
let floor_y = y.floor() as i32;
|
||||
let floor_z = z.floor() as i32;
|
||||
|
||||
@@ -13,7 +13,12 @@ use itertools::Itertools;
|
||||
use num_derive::FromPrimitive;
|
||||
use pumpkin_config::ADVANCED_CONFIG;
|
||||
use pumpkin_core::{
|
||||
math::{boundingbox::BoundingBox, position::WorldPosition, vector2::Vector2, vector3::Vector3},
|
||||
math::{
|
||||
boundingbox::{BoundingBox, BoundingBoxSize},
|
||||
position::WorldPosition,
|
||||
vector2::Vector2,
|
||||
vector3::Vector3,
|
||||
},
|
||||
text::TextComponent,
|
||||
GameMode,
|
||||
};
|
||||
@@ -177,12 +182,19 @@ impl Player {
|
||||
|profile| profile,
|
||||
);
|
||||
let config = client.config.lock().await.clone().unwrap_or_default();
|
||||
let bounding_box_size = BoundingBoxSize {
|
||||
width: 0.6,
|
||||
height: 1.8,
|
||||
};
|
||||
|
||||
Self {
|
||||
living_entity: LivingEntity::new(Entity::new(
|
||||
entity_id,
|
||||
world,
|
||||
EntityType::Player,
|
||||
1.62,
|
||||
AtomicCell::new(BoundingBox::new_default(&bounding_box_size)),
|
||||
AtomicCell::new(bounding_box_size),
|
||||
)),
|
||||
config: Mutex::new(config),
|
||||
gameprofile,
|
||||
|
||||
Reference in New Issue
Block a user