From 5e0e9ef5b6a753569fa440de853c68d59623e0b3 Mon Sep 17 00:00:00 2001 From: wbc3467-spec Date: Sun, 7 Dec 2025 17:26:28 +0000 Subject: [PATCH] refactor: reimplemented RayTrace to make it cleaner, and more consistent with vallina code --- .../torocraft/torohealth/util/RayTrace.java | 146 +++++++----------- 1 file changed, 53 insertions(+), 93 deletions(-) diff --git a/src/main/java/net/torocraft/torohealth/util/RayTrace.java b/src/main/java/net/torocraft/torohealth/util/RayTrace.java index 66103289..25e4e0a7 100644 --- a/src/main/java/net/torocraft/torohealth/util/RayTrace.java +++ b/src/main/java/net/torocraft/torohealth/util/RayTrace.java @@ -1,120 +1,80 @@ package net.torocraft.torohealth.util; -import java.util.function.Predicate; import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.ProjectileUtil; -import net.minecraft.fluid.FluidState; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; -import net.minecraft.util.hit.HitResult.Type; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.World; import net.minecraft.world.BlockView; import net.minecraft.world.RaycastContext; -import net.minecraft.world.RaycastContext.FluidHandling; -public class RayTrace implements BlockView { - private static Predicate isVisible = entity -> !entity.isSpectator() && entity.collides(); - private static MinecraftClient minecraft = MinecraftClient.getInstance(); - @Override - public BlockEntity getBlockEntity(BlockPos pos) { - return minecraft.world.getBlockEntity(pos); - } - - @Override - public BlockState getBlockState(BlockPos pos) { - return minecraft.world.getBlockState(pos); - } - - @Override - public FluidState getFluidState(BlockPos pos) { - return minecraft.world.getFluidState(pos); - } - - public LivingEntity getEntityInCrosshair(float partialTicks, double reachDistance) { - MinecraftClient client = MinecraftClient.getInstance(); - Entity viewer = client.getCameraEntity(); +public class RayTrace { + // modified from minecraft.client.render.GameRender.updateTargetedEntity + public LivingEntity getEntityInCrosshair(float tickDelta, float reachDistance) { + MinecraftClient client = MinecraftClient.getInstance(); + Entity entity2 = client.getCameraEntity(); + if (entity2 == null) { + return null; + } + if (client.world == null) { + return null; + } + HitResult crosshairTarget = this.raycastEntity(entity2, reachDistance, tickDelta, false); + Vec3d vec3d = entity2.getCameraPosVec(tickDelta); + double e = reachDistance; - if (viewer == null) { - return null; + e *= e; + if (crosshairTarget != null) { + e = crosshairTarget.getPos().squaredDistanceTo(vec3d); + } + Vec3d vec3d2 = entity2.getRotationVec(1.0f); + Vec3d vec3d3 = vec3d.add(vec3d2.x * reachDistance, vec3d2.y * reachDistance, vec3d2.z * reachDistance); + Box box = entity2.getBoundingBox().stretch(vec3d2.multiply(reachDistance)).expand(1.0, 1.0, 1.0); + EntityHitResult entityHitResult = ProjectileUtil.raycast(entity2, vec3d, vec3d3, box, entity -> !entity.isSpectator() && entity.collides(), e); + if (entityHitResult != null) { + Entity entity22 = entityHitResult.getEntity(); + Vec3d vec3d4 = entityHitResult.getPos(); + double g = vec3d.squaredDistanceTo(vec3d4); + if (g < e || crosshairTarget == null) { + if (entity22 instanceof LivingEntity) { + return (LivingEntity) entity22; + } + } + } + return null; } - Vec3d position = viewer.getCameraPosVec(partialTicks); - Vec3d look = viewer.getRotationVec(1.0F); - Vec3d max = position.add(look.x * reachDistance, look.y * reachDistance, look.z * reachDistance); - Box searchBox = viewer.getBoundingBox().stretch(look.multiply(reachDistance)).expand(1.0D, 1.0D, 1.0D); - - EntityHitResult result = ProjectileUtil.raycast(viewer, position, max, searchBox, isVisible, reachDistance * reachDistance); - - if (result == null || result.getEntity() == null) { - return null; + // modified from net.minecraft.entity.Entity.raycast, adding ignore opaque blocks feature + private BlockHitResult raycastEntity(Entity entity, double maxDistance, float tickDelta, boolean includeFluids) { + Vec3d vec3d = entity.getCameraPosVec(tickDelta); + Vec3d vec3d2 = entity.getRotationVec(tickDelta); + Vec3d vec3d3 = vec3d.add(vec3d2.x * maxDistance, vec3d2.y * maxDistance, vec3d2.z * maxDistance); + return raycastBlockView(entity.world, new RaycastContext(vec3d, vec3d3, RaycastContext.ShapeType.OUTLINE, includeFluids ? RaycastContext.FluidHandling.ANY : RaycastContext.FluidHandling.NONE, entity)); } - if (result.getEntity() instanceof LivingEntity) { - LivingEntity target = (LivingEntity) result.getEntity(); - HitResult blockHit = raycast(setupRayTraceContext(client.player, reachDistance, FluidHandling.NONE)); - if (!blockHit.getType().equals(Type.MISS)) { - double blockDistance = blockHit.getPos().distanceTo(position); - if (blockDistance > target.distanceTo(client.player)) { - return target; - } - } else { - return target; - } + private BlockHitResult raycastBlockView(World world, RaycastContext context) { + return BlockView.raycast(context.getStart(), context.getEnd(), context, (c, pos) -> { + BlockState block = world.getBlockState(pos); + if (!block.isOpaque()) { + return null; + } + VoxelShape blockShape = c.getBlockShape(block, world, pos); + return world.raycastBlock(c.getStart(), c.getEnd(), pos, blockShape, block); + }, (c) -> { + Vec3d v = c.getStart().subtract(c.getEnd()); + return BlockHitResult.createMissed(c.getEnd(), Direction.getFacing(v.x, v.y, v.z), new BlockPos(c.getEnd())); + }); } - - return null; - } - - private RaycastContext setupRayTraceContext(PlayerEntity player, double distance, RaycastContext.FluidHandling fluidHandling) { - float pitch = player.getPitch(); - float yaw = player.getYaw(); - Vec3d fromPos = player.getCameraPosVec(1.0F); - float float_3 = MathHelper.cos(-yaw * 0.017453292F - 3.1415927F); - float float_4 = MathHelper.sin(-yaw * 0.017453292F - 3.1415927F); - float float_5 = -MathHelper.cos(-pitch * 0.017453292F); - float xComponent = float_4 * float_5; - float yComponent = MathHelper.sin(-pitch * 0.017453292F); - float zComponent = float_3 * float_5; - Vec3d toPos = fromPos.add((double)xComponent * distance, (double)yComponent * distance, (double)zComponent * distance); - return new RaycastContext(fromPos, toPos, RaycastContext.ShapeType.OUTLINE, fluidHandling, player); - } - - @Override - public BlockHitResult raycast(RaycastContext context) { - return BlockView.raycast(context.getStart(), context.getEnd(), context, (c, pos) -> { - BlockState block = this.getBlockState(pos); - if (!block.isOpaque()) { - return null; - } - VoxelShape blockShape = c.getBlockShape(block, this, pos); - return this.raycastBlock(c.getStart(), c.getEnd(), pos, blockShape, block); - }, (c) -> { - Vec3d v = c.getStart().subtract(c.getEnd()); - return BlockHitResult.createMissed(c.getEnd(), Direction.getFacing(v.x, v.y, v.z), new BlockPos(c.getEnd())); - }); - } - - @Override - public int getBottomY() { - return 0; - } - - @Override - public int getHeight() { - return 0; - } -} +} \ No newline at end of file