Add predicate for block when raytracing (#9691)

* Add predicate for block data when raytracing blocks

* Match based on block, instead of block data

* Use instanceof instead of casting

* Use Position instead of Location, add overload for rayTraceEntities

* Implement requested changes

* Invert predicate

* Cleanup
This commit is contained in:
TonytheMacaroni
2023-11-04 18:00:51 -04:00
parent 6e88b4fa1e
commit e83e680321
4 changed files with 251 additions and 0 deletions

View File

@@ -273,6 +273,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ boolean isFine();
+
+ /**
+ * Checks if each component of this position is finite.
+ */
+ default boolean isFinite() {
+ return Double.isFinite(this.x()) && Double.isFinite(this.y()) && Double.isFinite(this.z());
+ }
+
+ /**
+ * Returns a position offset by the specified amounts.
+ *
+ * @param x x value to offset
@@ -415,6 +422,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @Override
+ public boolean isFinite() {
+ return io.papermc.paper.math.FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch());
+ }
+
+ @Override
+ public @NotNull Location toLocation(@NotNull World world) {
+ return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch());
+ }

View File

@@ -0,0 +1,119 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
Date: Wed, 6 Sep 2023 19:24:53 -0400
Subject: [PATCH] Add predicate for blocks when raytracing
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -0,0 +0,0 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate<Entity> filter);
+ // Paper start
+ /**
+ * Performs a ray trace that checks for entity collisions.
+ * <p>
+ * This may not consider entities in currently unloaded chunks. Some
+ * implementations may impose artificial restrictions on the maximum
+ * distance.
+ *
+ * @param start the start position
+ * @param direction the ray direction
+ * @param maxDistance the maximum distance
+ * @param raySize entity bounding boxes will be uniformly expanded (or
+ * shrinked) by this value before doing collision checks
+ * @param filter only entities that fulfill this predicate are considered,
+ * or <code>null</code> to consider all entities
+ * @return the closest ray trace hit result, or <code>null</code> if there
+ * is no hit
+ */
+ @Nullable
+ public RayTraceResult rayTraceEntities(@NotNull io.papermc.paper.math.Position start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate<Entity> filter);
+ // Paper end
+
/**
* Performs a ray trace that checks for block collisions using the blocks'
* precise collision shapes.
@@ -0,0 +0,0 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks);
+ // Paper start
+ /**
+ * Performs a ray trace that checks for block collisions using the blocks'
+ * precise collision shapes.
+ * <p>
+ * If collisions with passable blocks are ignored, fluid collisions are
+ * ignored as well regardless of the fluid collision mode.
+ * <p>
+ * Portal blocks are only considered passable if the ray starts within
+ * them. Apart from that collisions with portal blocks will be considered
+ * even if collisions with passable blocks are otherwise ignored.
+ * <p>
+ * This may cause loading of chunks! Some implementations may impose
+ * artificial restrictions on the maximum distance.
+ *
+ * @param start the start position
+ * @param direction the ray direction
+ * @param maxDistance the maximum distance
+ * @param fluidCollisionMode the fluid collision mode
+ * @param ignorePassableBlocks whether to ignore passable but collidable
+ * blocks (ex. tall grass, signs, fluids, ..)
+ * @param canCollide predicate for blocks the ray can potentially collide
+ * with, or <code>null</code> to consider all blocks
+ * @return the ray trace hit result, or <code>null</code> if there is no hit
+ */
+ @Nullable
+ public RayTraceResult rayTraceBlocks(@NotNull io.papermc.paper.math.Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, @Nullable Predicate<Block> canCollide);
+ // Paper end
+
/**
* Performs a ray trace that checks for both block and entity collisions.
* <p>
@@ -0,0 +0,0 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@Nullable
public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate<Entity> filter);
+ // Paper start
+ /**
+ * Performs a ray trace that checks for both block and entity collisions.
+ * <p>
+ * Block collisions use the blocks' precise collision shapes. The
+ * <code>raySize</code> parameter is only taken into account for entity
+ * collision checks.
+ * <p>
+ * If collisions with passable blocks are ignored, fluid collisions are
+ * ignored as well regardless of the fluid collision mode.
+ * <p>
+ * Portal blocks are only considered passable if the ray starts within them.
+ * Apart from that collisions with portal blocks will be considered even if
+ * collisions with passable blocks are otherwise ignored.
+ * <p>
+ * This may cause loading of chunks! Some implementations may impose
+ * artificial restrictions on the maximum distance.
+ *
+ * @param start the start position
+ * @param direction the ray direction
+ * @param maxDistance the maximum distance
+ * @param fluidCollisionMode the fluid collision mode
+ * @param ignorePassableBlocks whether to ignore passable but collidable
+ * blocks (ex. tall grass, signs, fluids, ..)
+ * @param raySize entity bounding boxes will be uniformly expanded (or
+ * shrinked) by this value before doing collision checks
+ * @param filter only entities that fulfill this predicate are considered,
+ * or <code>null</code> to consider all entities
+ * @param canCollide predicate for blocks the ray can potentially collide
+ * with, or <code>null</code> to consider all blocks
+ * @return the closest ray trace hit result with either a block or an
+ * entity, or <code>null</code> if there is no hit
+ */
+ @Nullable
+ public RayTraceResult rayTrace(@NotNull io.papermc.paper.math.Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate<Entity> filter, @Nullable Predicate<Block> canCollide);
+ // Paper end
+
/**
* Gets the default spawn {@link Location} of this world
*