mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +00:00
160 lines
9.0 KiB
Diff
160 lines
9.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
Date: Sun, 14 Aug 2022 10:28:52 +0800
|
|
Subject: [PATCH] Strip raytracing for EntityLiving#hasLineOfSight
|
|
|
|
This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish)
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
index 040ce7d50bb6aa87ae86ac35a06a9af241fcab03..e5fa2fde9ec53eac1e41bd0ded5f93b9e06258c8 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -3616,7 +3616,13 @@ public abstract class LivingEntity extends Entity {
|
|
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
|
|
|
|
// Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
|
|
- return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
|
|
+ // Leaves start - strip raytracing
|
|
+ if (top.leavesmc.leaves.LeavesConfig.entityStripRaytracing) {
|
|
+ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.rayTraceDirect(vec3d, vec3d1, net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ } else {
|
|
+ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
|
|
+ }
|
|
+ // Leaves end - strip raytracing
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
index d1eefa6ef3e9abfe7af4d8310aa64465fa2d5463..c91735828dc99af0b880a5a105025b4294c487a7 100644
|
|
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
|
@@ -73,6 +73,16 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
});
|
|
}
|
|
|
|
+ // Leaves start - broken down variant of below rayTraceBlock, used by World#rayTraceDirect
|
|
+ default net.minecraft.world.phys.BlockHitResult.Type rayTraceBlockDirect(Vec3 vec3d, Vec3 vec3d1, BlockPos blockposition, BlockState iblockdata, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) {
|
|
+ if (iblockdata.isAir()) return null; // Tuinity - optimise air cases
|
|
+ VoxelShape voxelshape = ClipContext.Block.COLLIDER.get(iblockdata, this, blockposition, voxelshapecoll);
|
|
+ net.minecraft.world.phys.BlockHitResult movingobjectpositionblock = this.clipWithInteractionOverride(vec3d, vec3d1, blockposition, voxelshape, iblockdata);
|
|
+
|
|
+ return movingobjectpositionblock == null ? null : movingobjectpositionblock.getType();
|
|
+ }
|
|
+ // Leaves end - broken down variant of below rayTraceBlock, used by World#rayTraceDirect
|
|
+
|
|
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
|
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
|
// Paper start - Prevent raytrace from loading chunks
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 4d880d9b56dc39a298e047cda3f2a31adef45cbc..daa3eb43727bbf8aefd2c69e711aa1709fba7eba 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -410,6 +410,91 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
return null;
|
|
}
|
|
|
|
+ // Leaves start - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace)
|
|
+ public net.minecraft.world.phys.BlockHitResult.Type rayTraceDirect(net.minecraft.world.phys.Vec3 vec3d, net.minecraft.world.phys.Vec3 vec3d1, net.minecraft.world.phys.shapes.CollisionContext voxelshapecoll) {
|
|
+ // most of this code comes from IBlockAccess#a(RayTrace, BiFunction, Function), but removes the needless functions
|
|
+ if (vec3d.equals(vec3d1)) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ double endX = Mth.lerp(-1.0E-7D, vec3d1.x, vec3d.x);
|
|
+ double endY = Mth.lerp(-1.0E-7D, vec3d1.y, vec3d.y);
|
|
+ double endZ = Mth.lerp(-1.0E-7D, vec3d1.z, vec3d.z);
|
|
+
|
|
+ double startX = Mth.lerp(-1.0E-7D, vec3d.x, vec3d1.x);
|
|
+ double startY = Mth.lerp(-1.0E-7D, vec3d.y, vec3d1.y);
|
|
+ double startZ = Mth.lerp(-1.0E-7D, vec3d.z, vec3d1.z);
|
|
+
|
|
+ int currentX = Mth.floor(startX);
|
|
+ int currentY = Mth.floor(startY);
|
|
+ int currentZ = Mth.floor(startZ);
|
|
+
|
|
+ BlockPos.MutableBlockPos currentBlock = new BlockPos.MutableBlockPos(currentX, currentY, currentZ);
|
|
+
|
|
+ LevelChunk chunk = this.getChunkIfLoaded(currentBlock);
|
|
+ if (chunk == null) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ net.minecraft.world.phys.BlockHitResult.Type initialCheck = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll);
|
|
+
|
|
+ if (initialCheck != null) {
|
|
+ return initialCheck;
|
|
+ }
|
|
+
|
|
+ double diffX = endX - startX;
|
|
+ double diffY = endY - startY;
|
|
+ double diffZ = endZ - startZ;
|
|
+
|
|
+ int xDirection = Mth.sign(diffX);
|
|
+ int yDirection = Mth.sign(diffY);
|
|
+ int zDirection = Mth.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 - Mth.frac(startX) : Mth.frac(startX));
|
|
+ double normalizedYDirection = normalizedY * (yDirection > 0 ? 1.0D - Mth.frac(startY) : Mth.frac(startY));
|
|
+ double normalizedZDirection = normalizedZ * (zDirection > 0 ? 1.0D - Mth.frac(startZ) : Mth.frac(startZ));
|
|
+
|
|
+ net.minecraft.world.phys.BlockHitResult.Type result;
|
|
+
|
|
+ do {
|
|
+ if (normalizedXDirection > 1.0D && normalizedYDirection > 1.0D && normalizedZDirection > 1.0D) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.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.set(currentX, currentY, currentZ);
|
|
+ if (chunk.getPos().x != currentBlock.getX() >> 4 || chunk.getPos().z != currentBlock.getZ() >> 4) {
|
|
+ chunk = this.getChunkIfLoaded(currentBlock);
|
|
+ if (chunk == null) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+ }
|
|
+ result = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getBlockState(currentBlock), voxelshapecoll);
|
|
+ } while (result == null);
|
|
+
|
|
+ return result;
|
|
+ }
|
|
+ // Leaves end - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace)
|
|
+
|
|
public boolean isInWorldBounds(BlockPos pos) {
|
|
return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
|
|
}
|
|
diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
index 64fc662bcf102df1fd971e9bc72b96ebfe3cda32..d170232e4da4c67c343f3e4393ae7153e0b3002e 100644
|
|
--- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
+++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
@@ -266,6 +266,11 @@ public final class LeavesConfig {
|
|
enableSuffocationOptimization = getBoolean("settings.performance.enable-suffocation-optimization", enableSuffocationOptimization);
|
|
}
|
|
|
|
+ public static boolean entityStripRaytracing = true;
|
|
+ private static void entityStripRaytracing() {
|
|
+ entityStripRaytracing = getBoolean("settings.performance.strip-raytracing-for-entity", entityStripRaytracing);
|
|
+ }
|
|
+
|
|
public static final class WorldConfig {
|
|
|
|
public final String worldName;
|