PaperMC/patches/server/0887-Add-predicate-for-blocks-when-raytracing.patch
Bjarne Koll da7138233f
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#11702)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
ed0ec489 SPIGOT-7965: Unknown TransformReason for Hoglins
9db03457 SPIGOT-7964: Fix typo in Deprecation annotation
d14119af PR-1082: Add "since" to Deprecation annotations
e8a318d4 PR-1067: Add method to get Advancement requirements

CraftBukkit Changes:
40dd796db SPIGOT-7971: NotSerializableException on serialize CraftUseCooldownComponent
fa85c5e0a SPIGOT-7968: ProjectileHitEvent not trigerred when arrow hits entity
b75b792ec SPIGOT-7970: World#getMaxHeight() returning incorrect value
2b9a094bb SPIGOT-7965: Unknown TransformReason for Hoglins
fd3f5a380 SPIGOT-7966: Some trees do not generate with #generateTree
f2822317c PR-1515: Add a Class reader and Class node argument provider
07abf6852 PR-1514: Add a test case for ClassTraverser
a7577cb24 Fix Inventory#addItem not respecting max stack size
066a74e74 PR-1490: Add method to get Advancement requirements
4a1df30e4 PR-1512: Test Art class based on specific values instead of the implementation, to better catch implementation changes
53254c56f PR-1503: Simplify CAS loop to getAndSet
e9447dc5e Make BlockDataMeta#setBlockData hide unspecified states
dd08a7120 SPIGOT-7960: Fix inconsistency between natural item drop coordinates
e9e8ed753 SPIGOT-7960: Improve natural item drop methods

Spigot Changes:
60c9969b Rebuild patches
2024-12-03 15:47:48 +01:00

116 lines
8.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TonytheMacaroni <tonythemacaroni123@gmail.com>
Date: Wed, 6 Sep 2023 19:24:16 -0400
Subject: [PATCH] Add predicate for blocks when raytracing
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
index 7e1a332168357b9af14dbe3299549c2c93903fa6..93738c7dea1ea3d19013a47380391274612a719b 100644
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
@@ -71,6 +71,12 @@ public interface BlockGetter extends LevelHeightAccessor {
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
+ // Paper start - Add predicate for blocks when raytracing
+ return clip(raytrace1, blockposition, null);
+ }
+
+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
+ // Paper end - Add predicate for blocks when raytracing
// Paper start - Prevent raytrace from loading chunks
BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
if (iblockdata == null) {
@@ -80,7 +86,7 @@ public interface BlockGetter extends LevelHeightAccessor {
return BlockHitResult.miss(raytrace1.getTo(), Direction.getApproximateNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo()));
}
// Paper end - Prevent raytrace from loading chunks
- if (iblockdata.isAir()) return null; // Paper - Perf: optimise air cases
+ if (iblockdata.isAir() || (canCollide != null && this instanceof LevelAccessor levelAccessor && !canCollide.test(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, blockposition)))) return null; // Paper - Perf: optimise air cases & check canCollide predicate
FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again
Vec3 vec3d = raytrace1.getFrom();
Vec3 vec3d1 = raytrace1.getTo();
@@ -96,8 +102,14 @@ public interface BlockGetter extends LevelHeightAccessor {
// CraftBukkit end
default BlockHitResult clip(ClipContext context) {
+ // Paper start - Add predicate for blocks when raytracing
+ return clip(context, (java.util.function.Predicate<org.bukkit.block.Block>) null);
+ }
+
+ default BlockHitResult clip(ClipContext context, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
+ // Paper end - Add predicate for blocks when raytracing
return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> {
- return this.clip(raytrace1, blockposition); // CraftBukkit - moved into separate method
+ return this.clip(raytrace1, blockposition, canCollide); // CraftBukkit - moved into separate method // Paper - Add predicate for blocks when raytracing
}, (raytrace1) -> {
Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 01c06c0287e8c6538adac33f9e3755d062545a01..e3db170099b674c46248509daba332c771c3f750 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1097,9 +1097,15 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
+ // Paper start - Add predicate for blocks when raytracing
+ return rayTraceEntities((io.papermc.paper.math.Position) start, direction, maxDistance, raySize, filter);
+ }
+
+ public RayTraceResult rayTraceEntities(io.papermc.paper.math.Position start, Vector direction, double maxDistance, double raySize, Predicate<? super Entity> filter) {
Preconditions.checkArgument(start != null, "Location start cannot be null");
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
- start.checkFinite();
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
+ // Paper end - Add predicate for blocks when raytracing
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
direction.checkFinite();
@@ -1149,9 +1155,16 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) {
+ // Paper start - Add predicate for blocks when raytracing
+ return this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, null);
+ }
+
+ @Override
+ public RayTraceResult rayTraceBlocks(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, Predicate<? super Block> canCollide) {
Preconditions.checkArgument(start != null, "Location start cannot be null");
- Preconditions.checkArgument(this.equals(start.getWorld()), "Location start cannot be in a different world");
- start.checkFinite();
+ Preconditions.checkArgument(!(start instanceof Location location) || this.equals(location.getWorld()), "Location start cannot be in a different world");
+ Preconditions.checkArgument(start.isFinite(), "Location start is not finite");
+ // Paper end - Add predicate for blocks when raytracing
Preconditions.checkArgument(direction != null, "Vector direction cannot be null");
direction.checkFinite();
@@ -1164,16 +1177,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
}
Vector dir = direction.clone().normalize().multiply(maxDistance);
- Vec3 startPos = CraftLocation.toVec3D(start);
+ Vec3 startPos = io.papermc.paper.util.MCUtil.toVec3(start); // Paper - Add predicate for blocks when raytracing
Vec3 endPos = startPos.add(dir.getX(), dir.getY(), dir.getZ());
- HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()));
+ HitResult nmsHitResult = this.getHandle().clip(new ClipContext(startPos, endPos, ignorePassableBlocks ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), CollisionContext.empty()), canCollide); // Paper - Add predicate for blocks when raytracing
return CraftRayTraceResult.fromNMS(this, nmsHitResult);
}
@Override
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter) {
- RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks);
+ // Paper start - Add predicate for blocks when raytracing
+ return this.rayTrace(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, raySize, filter, null);
+ }
+
+ @Override
+ public RayTraceResult rayTrace(io.papermc.paper.math.Position start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<? super Entity> filter, Predicate<? super Block> canCollide) {
+ RayTraceResult blockHit = this.rayTraceBlocks(start, direction, maxDistance, fluidCollisionMode, ignorePassableBlocks, canCollide);
+ // Paper end - Add predicate for blocks when raytracing
Vector startVec = null;
double blockHitDistance = maxDistance;