--- a/net/minecraft/world/level/BlockGetter.java +++ b/net/minecraft/world/level/BlockGetter.java @@ -12,6 +12,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Mth; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; @@ -31,11 +32,20 @@ default Optional getBlockEntity(BlockPos pos, BlockEntityType type) { BlockEntity tileentity = this.getBlockEntity(pos); - return tileentity != null && tileentity.getType() == type ? Optional.of(tileentity) : Optional.empty(); + return tileentity != null && tileentity.getType() == type ? (Optional) Optional.of(tileentity) : Optional.empty(); // CraftBukkit - decompile error } BlockState getBlockState(BlockPos pos); + // Paper start - if loaded util + @Nullable BlockState getBlockStateIfLoaded(BlockPos blockposition); + default @Nullable Block getBlockIfLoaded(BlockPos blockposition) { + BlockState type = this.getBlockStateIfLoaded(blockposition); + return type == null ? null : type.getBlock(); + } + @Nullable FluidState getFluidIfLoaded(BlockPos blockposition); + // Paper end + FluidState getFluidState(BlockPos pos); default int getLightEmission(BlockPos pos) { @@ -59,10 +69,19 @@ }); } - default BlockHitResult clip(ClipContext context) { - return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> { - BlockState iblockdata = this.getBlockState(blockposition); - FluidState fluid = this.getFluidState(blockposition); + // 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 + BlockState iblockdata = this.getBlockStateIfLoaded(blockposition); + if (iblockdata == null) { + // copied the last function parameter (listed below) + Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); + + 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 + FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: don't need to go to world state again Vec3 vec3d = raytrace1.getFrom(); Vec3 vec3d1 = raytrace1.getTo(); VoxelShape voxelshape = raytrace1.getBlockShape(iblockdata, this, blockposition); @@ -73,6 +92,12 @@ double d1 = movingobjectpositionblock1 == null ? Double.MAX_VALUE : raytrace1.getFrom().distanceToSqr(movingobjectpositionblock1.getLocation()); return d0 <= d1 ? movingobjectpositionblock : movingobjectpositionblock1; + } + // CraftBukkit end + + default BlockHitResult clip(ClipContext context) { + return (BlockHitResult) BlockGetter.traverseBlocks(context.getFrom(), context.getTo(), context, (raytrace1, blockposition) -> { + return this.clip(raytrace1, blockposition); // CraftBukkit - moved into separate method }, (raytrace1) -> { Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo()); @@ -145,7 +170,7 @@ double d13 = d10 * (i1 > 0 ? 1.0D - Mth.frac(d4) : Mth.frac(d4)); double d14 = d11 * (j1 > 0 ? 1.0D - Mth.frac(d5) : Mth.frac(d5)); - Object object; + T object; // CraftBukkit - decompile error do { if (d12 > 1.0D && d13 > 1.0D && d14 > 1.0D) {