9
0
mirror of https://github.com/SparklyPower/SparklyPaper.git synced 2025-12-23 00:49:28 +00:00
Files
SparklyPaperMC/patches/server/0005-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch
MrPowerGamerBR 241771b90f Rebuild patches
2021-03-15 07:55:29 -03:00

186 lines
9.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paul Sauve <paul@technove.co>
Date: Sat, 31 Oct 2020 18:43:02 -0500
Subject: [PATCH] Strip raytracing for EntityLiving#hasLineOfSight
The IBlockAccess#rayTrace method is very wasteful in both allocations,
and in logic. While EntityLiving#hasLineOfSight provides static
parameters for collisions with blocks and fluids, the method still does
a lot of dynamic checks for both of these, which result in extra work.
As well, since the fluid collision option is set to NONE, the entire
fluid collision system is completely unneeded, yet used anyways.
Airplane
Copyright (C) 2020 Technove LLC
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index d568db532de83a85d5c387121cec151c160f36bf..4bf86d22de3dfb5a98c0fd31f936b566a7be6d38 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -3007,7 +3007,7 @@ public abstract class EntityLiving extends Entity {
Vec3D vec3d = new Vec3D(this.locX(), this.getHeadY(), this.locZ());
Vec3D vec3d1 = new Vec3D(entity.locX(), entity.getHeadY(), entity.locZ());
- return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
+ return this.world.rayTraceDirect(vec3d, vec3d1, VoxelShapeCollision.a(this)) == MovingObjectPosition.EnumMovingObjectType.MISS; // Airplane - use direct method
}
@Override
diff --git a/src/main/java/net/minecraft/server/IBlockAccess.java b/src/main/java/net/minecraft/server/IBlockAccess.java
index 5ccf6b483fe15d4ad12ce2d3d11e9440ee9e8ab7..ec82d91804eeed49a6ef67a92fd24a06ae7ee3fb 100644
--- a/src/main/java/net/minecraft/server/IBlockAccess.java
+++ b/src/main/java/net/minecraft/server/IBlockAccess.java
@@ -44,6 +44,15 @@ public interface IBlockAccess {
return BlockPosition.a(axisalignedbb).map(this::getType);
}
+ // Airplane start - broken down variant of below rayTraceBlock, used by World#rayTraceDirect
+ default MovingObjectPosition.EnumMovingObjectType rayTraceBlockDirect(Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition, IBlockData iblockdata, VoxelShapeCollision voxelshapecoll) {
+ VoxelShape voxelshape = RayTrace.BlockCollisionOption.COLLIDER.get(iblockdata, this, blockposition, voxelshapecoll);
+ MovingObjectPositionBlock movingobjectpositionblock = this.rayTrace(vec3d, vec3d1, blockposition, voxelshape, iblockdata);
+
+ return movingobjectpositionblock == null ? null : movingobjectpositionblock.getType();
+ }
+ // Airplane end
+
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
default MovingObjectPositionBlock rayTraceBlock(RayTrace raytrace1, BlockPosition blockposition) {
// Paper start - Prevent raytrace from loading chunks
diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java
index 2e7721a650c5a351b3584665bd236f92ef577761..b3c2b461b2a654a9e37a57f2f62b3ba8b5bb1634 100644
--- a/src/main/java/net/minecraft/server/MathHelper.java
+++ b/src/main/java/net/minecraft/server/MathHelper.java
@@ -238,6 +238,7 @@ public class MathHelper {
return f - (float) d(f);
}
+ public static double getDecimals(double num) { return h(num); } // Airplane
public static double h(double d0) {
return d0 - (double) d(d0);
}
@@ -416,6 +417,7 @@ public class MathHelper {
return f1 + f * (f2 - f1);
}
+ public static double linearInterpolation(double value1, double value2, double amount) { return d(value1, value2, amount); } // Airplane - OBFHELPER
public static double d(double d0, double d1, double d2) {
return d1 + d0 * (d2 - d1);
}
@@ -432,6 +434,7 @@ public class MathHelper {
return d0 * d0 * d0 * (d0 * (d0 * 6.0D - 15.0D) + 10.0D);
}
+ public static int sign(double num) { return k(num); } // Airplane - OBFHELPER
public static int k(double d0) {
return d0 == 0.0D ? 0 : (d0 > 0.0D ? 1 : -1);
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index bf06ef09cfd4d7618365249d1332d264d8ff1377..fbe9a9d9721daf78e77736080f0c319c80bd950f 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -318,6 +318,91 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
return null;
}
+ // Airplane start - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace)
+ protected MovingObjectPosition.EnumMovingObjectType rayTraceDirect(Vec3D vec3d, Vec3D vec3d1, VoxelShapeCollision voxelshapecoll) {
+ // most of this code comes from IBlockAccess#a(RayTrace, BiFunction, Function), but removes the needless functions
+ if (vec3d.equals(vec3d1)) {
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
+ }
+
+ double endX = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.x, vec3d.x);
+ double endY = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.y, vec3d.y);
+ double endZ = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.z, vec3d.z);
+
+ double startX = MathHelper.linearInterpolation(-1.0E-7D, vec3d.x, vec3d1.x);
+ double startY = MathHelper.linearInterpolation(-1.0E-7D, vec3d.y, vec3d1.y);
+ double startZ = MathHelper.linearInterpolation(-1.0E-7D, vec3d.z, vec3d1.z);
+
+ int currentX = MathHelper.floor(startX);
+ int currentY = MathHelper.floor(startY);
+ int currentZ = MathHelper.floor(startZ);
+
+ BlockPosition.MutableBlockPosition currentBlock = new BlockPosition.MutableBlockPosition(currentX, currentY, currentZ);
+
+ Chunk chunk = this.getChunkIfLoaded(currentBlock);
+ if (chunk == null) {
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
+ }
+
+ MovingObjectPosition.EnumMovingObjectType initialCheck = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getType(currentBlock), voxelshapecoll);
+
+ if (initialCheck != null) {
+ return initialCheck;
+ }
+
+ double diffX = endX - startX;
+ double diffY = endY - startY;
+ double diffZ = endZ - startZ;
+
+ int xDirection = MathHelper.sign(diffX);
+ int yDirection = MathHelper.sign(diffY);
+ int zDirection = MathHelper.sign(diffZ);
+
+ double normalizedX = xDirection == 0 ? Double.MAX_VALUE : (double) xDirection / diffX;
+ double normalizedY = yDirection == 0 ? Double.MAX_VALUE : (double) yDirection / diffY;
+ double normalizedZ = zDirection == 0 ? Double.MAX_VALUE : (double) zDirection / diffZ;
+
+ double normalizedXDirection = normalizedX * (xDirection > 0 ? 1.0D - MathHelper.getDecimals(startX) : MathHelper.getDecimals(startX));
+ double normalizedYDirection = normalizedY * (yDirection > 0 ? 1.0D - MathHelper.getDecimals(startY) : MathHelper.getDecimals(startY));
+ double normalizedZDirection = normalizedZ * (zDirection > 0 ? 1.0D - MathHelper.getDecimals(startZ) : MathHelper.getDecimals(startZ));
+
+ MovingObjectPosition.EnumMovingObjectType result;
+
+ do {
+ if (normalizedXDirection > 1.0D && normalizedYDirection > 1.0D && normalizedZDirection > 1.0D) {
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
+ }
+
+ if (normalizedXDirection < normalizedYDirection) {
+ if (normalizedXDirection < normalizedZDirection) {
+ currentX += xDirection;
+ normalizedXDirection += normalizedX;
+ } else {
+ currentZ += zDirection;
+ normalizedZDirection += normalizedZ;
+ }
+ } else if (normalizedYDirection < normalizedZDirection) {
+ currentY += yDirection;
+ normalizedYDirection += normalizedY;
+ } else {
+ currentZ += zDirection;
+ normalizedZDirection += normalizedZ;
+ }
+
+ currentBlock.setValues(currentX, currentY, currentZ);
+ if (chunk.getPos().x != currentBlock.getX() >> 4 || chunk.getPos().z != currentBlock.getZ() >> 4) {
+ chunk = this.getChunkIfLoaded(currentBlock);
+ if (chunk == null) {
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
+ }
+ }
+ result = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getType(currentBlock), voxelshapecoll);
+ } while (result == null);
+
+ return result;
+ }
+ // Airplane end
+
public static boolean isValidLocation(BlockPosition blockposition) {
return blockposition.isValidLocation(); // Paper - use better/optimized check
}