diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/CannonHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/CannonHudOverlay.java index 378464092..13407618f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/CannonHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/CannonHudOverlay.java @@ -56,6 +56,7 @@ public class CannonHudOverlay implements LayeredDraw.Layer { PoseStack poseStack = guiGraphics.pose(); Camera camera = mc.gameRenderer.getMainCamera(); Vec3 cameraPos = camera.getPosition(); + Vec3 viewVec = new Vec3(camera.getLookVector()); if (!shouldRenderCrossHair(player)) return; @@ -105,7 +106,7 @@ public class CannonHudOverlay implements LayeredDraw.Layer { shootPos = cannon.driverZoomPos(deltaTracker.getRealtimeDeltaTicks()); } - Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, 512, deltaTracker.getRealtimeDeltaTicks()); + Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, viewVec, 512); boolean lookAtEntity = false; BlockHitResult result = player.level().clip(new ClipContext(shootPos, shootPos.add(player.getViewVector(1).scale(512)), diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java index 48fa66599..0fc5e42b4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java @@ -155,6 +155,7 @@ public class VehicleHudOverlay implements LayeredDraw.Layer { PoseStack poseStack = guiGraphics.pose(); Camera camera = mc.gameRenderer.getMainCamera(); Vec3 cameraPos = camera.getPosition(); + Vec3 viewVec = new Vec3(camera.getLookVector()); assert player != null; @@ -269,7 +270,7 @@ public class VehicleHudOverlay implements LayeredDraw.Layer { double entityRange = 0; - Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, 512, deltaTracker.getRealtimeDeltaTicks()); + Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, viewVec, 512); if (lookingEntity != null) { lookAtEntity = true; entityRange = player.distanceTo(lookingEntity); diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleTeamOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleTeamOverlay.java index 4824c1182..1926c790d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleTeamOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleTeamOverlay.java @@ -1,18 +1,21 @@ package com.atsuishio.superbwarfare.client.overlay; import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.client.RenderHelper; import com.atsuishio.superbwarfare.config.client.DisplayConfig; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.tools.FormatTool; import com.atsuishio.superbwarfare.tools.NBTTool; import com.atsuishio.superbwarfare.tools.TraceTool; +import com.atsuishio.superbwarfare.tools.VectorUtil; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Camera; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.LayeredDraw; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; @@ -40,6 +43,7 @@ public class VehicleTeamOverlay implements LayeredDraw.Layer { Player player = mc.player; Camera camera = mc.gameRenderer.getMainCamera(); Vec3 cameraPos = camera.getPosition(); + Vec3 viewVec = new Vec3(camera.getLookVector()); PoseStack poseStack = guiGraphics.pose(); if (player == null) return; @@ -50,28 +54,49 @@ public class VehicleTeamOverlay implements LayeredDraw.Layer { boolean lookAtEntity = false; double entityRange = 0; - Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, 512, deltaTracker.getRealtimeDeltaTicks()); + Entity lookingEntity = TraceTool.camerafFindLookingEntity(player, cameraPos, viewVec, 512); - if (lookingEntity instanceof VehicleEntity) { + if (lookingEntity != null) { lookAtEntity = true; entityRange = player.distanceTo(lookingEntity); } - if (lookAtEntity) { + if (lookAtEntity && lookingEntity instanceof VehicleEntity vehicle) { + + Vec3 pos = lookingEntity.getBoundingBox().getCenter().add(new Vec3(0, lookingEntity.getBbHeight() / 2 + 1, 0)); + Vec3 point = VectorUtil.worldToScreen(pos, cameraPos); + if (point == null) return; + + float x = (float) point.x; + float y = (float) point.y; + poseStack.pushPose(); - poseStack.scale(0.8f, 0.8f, 1); - if (lookingEntity.getFirstPassenger() instanceof Player passenger) { - guiGraphics.drawString(Minecraft.getInstance().font, - Component.literal(passenger.getDisplayName().getString() + (passenger.getTeam() == null ? "" : " <" + (passenger.getTeam().getName()) + ">")), - w / 2 + 90, h / 2 - 4, passenger.getTeamColor(), false); - guiGraphics.drawString(Minecraft.getInstance().font, - Component.literal(lookingEntity.getDisplayName().getString() + " " + FormatTool.format1D(entityRange, "m")), - w / 2 + 90, h / 2 + 5, passenger.getTeamColor(), false); + poseStack.translate(x, y - 12, 0); + + float size = (float) ((50 / VectorUtil.fov) * 0.9f * Math.max((512 - entityRange) / 512, 0.1)); + poseStack.scale(size, size, size); + var font = Minecraft.getInstance().font; + + int color = -1; + + if (lookingEntity.getFirstPassenger() instanceof Player player1) { + color = player1.getTeamColor(); + String info = player1.getDisplayName().getString() + (player1.getTeam() == null ? "" : " <" + (player1.getTeam().getName()) + ">"); + int width = Minecraft.getInstance().font.width(info); + guiGraphics.drawString(font, Component.literal(info), -width / 2, -13, color, false); } else { - guiGraphics.drawString(Minecraft.getInstance().font, - Component.literal(lookingEntity.getDisplayName().getString() + " " + FormatTool.format1D(entityRange, "M")), - w / 2 + 90, h / 2 + 5, -1, false); + String info = lookingEntity.getDisplayName().getString(); + int width = Minecraft.getInstance().font.width(info); + guiGraphics.drawString(font, Component.literal(info), -width / 2, -13, color, false); } + + String range = FormatTool.format1D(entityRange, "M"); + int width2 = Minecraft.getInstance().font.width(range); + guiGraphics.drawString(font, Component.literal(range), -width2 / 2, 7, color, false); + + RenderHelper.fill(guiGraphics, RenderType.guiOverlay(), -40, -2, 40, 2, 0, -16777216); + RenderHelper.fill(guiGraphics, RenderType.guiOverlay(), -40, -2, -40 + 80 * (vehicle.getHealth() / vehicle.getMaxHealth()), 2, 0, -1); + poseStack.popPose(); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java index 650593a13..fe496801a 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java @@ -166,11 +166,18 @@ public class TraceTool { return null; } - public static Entity camerafFindLookingEntity(Player player, Vec3 pos, double entityReach, float ticks) { + public static Entity camerafFindLookingEntity(Player player, Vec3 pos, Vec3 viewVec, double entityReach) { double distance = entityReach * entityReach; - HitResult hitResult = player.pick(entityReach, 1.0f, false); + HitResult hitResult = pickNew(pos, entityReach, viewVec, player); + + if (hitResult.getType() != HitResult.Type.MISS) { + distance = hitResult.getLocation().distanceToSqr(pos); + double blockReach = 5; + if (distance > blockReach * blockReach) { + hitResult = BlockHitResult.miss(hitResult.getLocation(), Direction.getNearest(pos.x, pos.y, pos.z), BlockPos.containing(hitResult.getLocation())); + } + } - Vec3 viewVec = player.getViewVector(ticks); Vec3 toVec = pos.add(viewVec.x * entityReach, viewVec.y * entityReach, viewVec.z * entityReach); AABB aabb = player.getBoundingBox().expandTowards(viewVec.scale(entityReach)).inflate(1.0D, 1.0D, 1.0D); EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(player, pos, toVec, aabb, p -> !p.isSpectator() @@ -182,8 +189,13 @@ public class TraceTool { && p != player && p != player.getVehicle(), distance); if (entityhitresult != null) { - hitResult = entityhitresult; - + Vec3 targetPos = entityhitresult.getLocation(); + double distanceToTarget = pos.distanceToSqr(targetPos); + if (distanceToTarget > distance || distanceToTarget > entityReach * entityReach) { + hitResult = BlockHitResult.miss(targetPos, Direction.getNearest(viewVec.x, viewVec.y, viewVec.z), BlockPos.containing(targetPos)); + } else if (distanceToTarget < distance) { + hitResult = entityhitresult; + } } if (hitResult.getType() == HitResult.Type.ENTITY) { return ((EntityHitResult) hitResult).getEntity(); @@ -197,6 +209,11 @@ public class TraceTool { return vehicle.level().clip(new ClipContext(pos, vec32, ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, vehicle)); } + public static HitResult pickNew(Vec3 pos, double pHitDistance, Vec3 viewVec, Entity entity) { + Vec3 vec32 = pos.add(viewVec.x * pHitDistance, viewVec.y * pHitDistance, viewVec.z * pHitDistance); + return entity.level().clip(new ClipContext(pos, vec32, ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, entity)); + } + public static List getBlocksAlongRay(Vec3 start, Vec3 direction, double maxDistance) { List blocks = new ArrayList<>(); diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/VectorUtil.java b/src/main/java/com/atsuishio/superbwarfare/tools/VectorUtil.java index ed692f6f2..70cbab7e2 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/VectorUtil.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/VectorUtil.java @@ -19,7 +19,7 @@ public class VectorUtil { * Codes based on @Xjqsh */ private static PoseStack cachedPoseStack = new PoseStack(); - private static double fov = 70; + public static double fov = 70; public static Vec3 worldToScreen(Vec3 pos, Vec3 cameraPos) { Minecraft mc = Minecraft.getInstance();