aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics/src/collision/entity_collisions.rs
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-09-27 18:41:36 -1030
committermat <git@matdoes.dev>2025-09-27 20:26:41 -0845
commit74dcb7b37d953ec4d45dd6aac4c8e598c87def7d (patch)
tree22e6ab1849ee01d40f3d484ea0c8db52aa6649b5 /azalea-physics/src/collision/entity_collisions.rs
parent63bef6486dc1f3c9ef4b4f0d71e139d7035b6432 (diff)
downloadazalea-drasl-74dcb7b37d953ec4d45dd6aac4c8e598c87def7d.tar.xz
allow picking other bots in hit results
Diffstat (limited to 'azalea-physics/src/collision/entity_collisions.rs')
-rw-r--r--azalea-physics/src/collision/entity_collisions.rs53
1 files changed, 37 insertions, 16 deletions
diff --git a/azalea-physics/src/collision/entity_collisions.rs b/azalea-physics/src/collision/entity_collisions.rs
index 1300cf34..af2db1f0 100644
--- a/azalea-physics/src/collision/entity_collisions.rs
+++ b/azalea-physics/src/collision/entity_collisions.rs
@@ -1,13 +1,14 @@
-use azalea_core::aabb::AABB;
+use azalea_core::aabb::Aabb;
use azalea_entity::{
- LocalEntity, Physics,
+ Physics,
metadata::{AbstractBoat, Shulker},
};
use azalea_world::Instance;
use bevy_ecs::{
+ component::Component,
entity::Entity,
- query::{Or, With, Without},
- system::Query,
+ query::{Changed, Or, With},
+ system::{Commands, Query},
};
use tracing::error;
@@ -26,14 +27,34 @@ pub type CollidableEntityQuery<'world, 'state> = Query<'world, 'state, (), Colli
/// this.
pub type CollidableEntityFilter = Or<(With<AbstractBoat>, With<Shulker>)>;
-pub type PhysicsQuery<'world, 'state, 'a> =
- Query<'world, 'state, &'a Physics, Without<LocalEntity>>;
+/// A component that mirrors the Physics::bounding_box of every entity, but is
+/// updated before client-side physics is done.
+#[derive(Component)]
+pub struct LastBoundingBox(pub Aabb);
+
+pub type AabbQuery<'world, 'state, 'a> = Query<'world, 'state, &'a LastBoundingBox>;
+
+/// Update the [`LastBoundingBox`] for every entity.
+pub fn update_last_bounding_box(
+ mut commands: Commands,
+ mut query: Query<(Entity, Option<&mut LastBoundingBox>, &Physics), Changed<Physics>>,
+) {
+ for (entity, mut last_bounding_box, physics) in &mut query {
+ if let Some(last_bounding_box) = last_bounding_box.as_mut() {
+ last_bounding_box.0 = physics.bounding_box;
+ } else {
+ commands
+ .entity(entity)
+ .insert(LastBoundingBox(physics.bounding_box));
+ }
+ }
+}
pub fn get_entity_collisions(
world: &Instance,
- aabb: &AABB,
+ aabb: &Aabb,
source_entity: Option<Entity>,
- physics_query: &PhysicsQuery,
+ aabb_query: &AabbQuery,
collidable_entity_query: &CollidableEntityQuery,
) -> Vec<VoxelShape> {
if aabb.size() < 1.0E-7 {
@@ -47,7 +68,7 @@ pub fn get_entity_collisions(
source_entity,
&aabb.inflate_all(1.0E-7),
&collision_predicate,
- physics_query,
+ aabb_query,
);
collidable_entities
@@ -64,10 +85,10 @@ pub fn get_entity_collisions(
pub fn get_entities(
world: &Instance,
source_entity: Option<Entity>,
- aabb: &AABB,
+ aabb: &Aabb,
predicate: &dyn Fn(Entity) -> bool,
- physics_query: &PhysicsQuery,
-) -> Vec<(Entity, AABB)> {
+ aabb_query: &AabbQuery,
+) -> Vec<(Entity, Aabb)> {
let mut matches = Vec::new();
super::world_collisions::for_entities_in_chunks_colliding_with(
@@ -77,16 +98,16 @@ pub fn get_entities(
// now check if the entity itself collides
for &candidate in entities_in_chunk {
if Some(candidate) != source_entity && predicate(candidate) {
- let Ok(physics) = physics_query.get(candidate) else {
+ let Ok(candidate_aabb) = aabb_query.get(candidate) else {
error!(
"Entity {candidate} (found from for_entities_in_chunks_colliding_with) is missing required components."
);
continue;
};
+ let candidate_aabb = &candidate_aabb.0;
- let candidate_aabb = physics.bounding_box;
- if aabb.intersects_aabb(&candidate_aabb) {
- matches.push((candidate, physics.bounding_box));
+ if aabb.intersects_aabb(candidate_aabb) {
+ matches.push((candidate, candidate_aabb.to_owned()));
}
}
}