package com.atsuishio.superbwarfare.client.overlay; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.client.ClickHandler; import com.atsuishio.superbwarfare.client.RenderHelper; import com.atsuishio.superbwarfare.entity.vehicle.A10Entity; import com.atsuishio.superbwarfare.entity.vehicle.base.AircraftEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.tools.FormatTool; import com.atsuishio.superbwarfare.tools.InventoryTool; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import net.minecraft.client.Camera; import net.minecraft.client.CameraType; 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.GameRenderer; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import org.joml.Math; import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; import static com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity.HEAT; @OnlyIn(Dist.CLIENT) public class AircraftOverlay implements LayeredDraw.Layer { public static final ResourceLocation ID = Mod.loc("aircraft_hud"); private static float scopeScale = 1; private static float lerpVy = 1; @Override public void render(GuiGraphics guiGraphics, @NotNull DeltaTracker deltaTracker) { int screenWidth = guiGraphics.guiWidth(); int screenHeight = guiGraphics.guiHeight(); Minecraft mc = Minecraft.getInstance(); Player player = mc.player; Camera camera = mc.gameRenderer.getMainCamera(); Vec3 cameraPos = camera.getPosition(); PoseStack poseStack = guiGraphics.pose(); var partialTick = deltaTracker.getGameTimeDeltaPartialTick(true); if (player == null) return; if (ClickHandler.isEditing) return; if (player.getVehicle() instanceof AircraftEntity aircraftEntity && aircraftEntity instanceof MobileVehicleEntity mobileVehicle && aircraftEntity.isDriver(player) && player.getVehicle() instanceof WeaponVehicleEntity weaponVehicle) { poseStack.pushPose(); RenderSystem.disableDepthTest(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); RenderSystem.setShaderColor(1, 1, 1, 1); lerpVy = (float) Mth.lerp(0.021f * partialTick, lerpVy, mobileVehicle.getDeltaMovement().y()); float diffY = Mth.wrapDegrees(Mth.lerp(partialTick, player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(partialTick, mobileVehicle.yRotO, mobileVehicle.getYRot())) * 0.5f; float diffX = Mth.wrapDegrees(Mth.lerp(partialTick, player.xRotO, player.getXRot()) - Mth.lerp(partialTick, mobileVehicle.xRotO, mobileVehicle.getXRot())) * 0.5f; float fovAdjust2 = (float) (Minecraft.getInstance().options.fov().get() / 30) - 1; double zoom = 0.96 * 3 + 0.06 * fovAdjust2; Vec3 pos = aircraftEntity.shootPos(partialTick).add(mobileVehicle.getViewVector(partialTick).scale(192)); Vec3 posCross = aircraftEntity.shootPos(partialTick).add(aircraftEntity.shootVec(partialTick).scale(192)); Vec3 lookAngle = player.getViewVector(partialTick).normalize().scale(pos.distanceTo(cameraPos) * (1 - 1.0 / zoom)); var cPos = cameraPos.add(lookAngle); Vec3 p = RenderHelper.worldToScreen(pos, ClientEventHandler.zoomVehicle ? cPos : cameraPos); Vec3 pCross = RenderHelper.worldToScreen(posCross, ClientEventHandler.zoomVehicle ? cPos : cameraPos); if (p != null) { poseStack.pushPose(); float x = (float) p.x; float y = (float) p.y; if (mc.options.getCameraType() == CameraType.FIRST_PERSON) { RenderSystem.disableDepthTest(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); RenderSystem.setShaderColor(1, 1, 1, 1); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/hud_base.png"), x - 160, y - 160, 0, 0, 320, 320, 320, 320); //指南针 preciseBlit(guiGraphics, Mod.loc("textures/screens/compass.png"), x - 128, y - 122, 128 + ((float) 64 / 45 * mobileVehicle.getYRot()), 0, 256, 16, 512, 16); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/compass_ind.png"), x - 4, y - 123, 0, 0, 8, 8, 8, 8); //滚转指示 poseStack.pushPose(); poseStack.rotateAround(Axis.ZP.rotationDegrees(aircraftEntity.getRotZ(partialTick)), x, y + 48, 0); preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/roll_ind.png"), x - 4, y + 144, 0, 0, 8, 8, 8, 8); poseStack.popPose(); //时速 guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(mobileVehicle.getDeltaMovement().dot(mobileVehicle.getViewVector(1)) * 72)), (int) x - 105, (int) y - 61, 0x66FF00, false); //高度 guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(mobileVehicle.getY())), (int) x + 111 - 36, (int) y - 61, 0x66FF00, false); //框 preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x - 108, y - 64, 0, 0, 36, 12, 36, 12); preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x + 108 - 36, y - 64, 0, 0, 36, 12, 36, 12); //垂直速度 guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(lerpVy * 20)), (int) x - 96, (int) y + 60, 0x66FF00, false); // 热诱弹 guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("IR FLARES " + aircraftEntity.getDecoy()), (int) x + 72, (int) y, 0x66FF00, false); if (mobileVehicle instanceof A10Entity a10Entity) { if (weaponVehicle.getWeaponIndex(0) == 0) { double heat = 1 - a10Entity.getEntityData().get(HEAT) / 100.0F; String name = "30MM CANNON"; int width = Minecraft.getInstance().font.width(name); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(name), (int) x - width / 2, (int) y + 67, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false); String count = InventoryTool.hasCreativeAmmoBox(player) ? "∞" : String.valueOf(aircraftEntity.getAmmoCount(player)); int width2 = Minecraft.getInstance().font.width(count); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false); } else { String name = "70MM ROCKET"; int width = Minecraft.getInstance().font.width(name); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(name), (int) x - width / 2, (int) y + 67, 0x66FF00, false); String count = String.valueOf(aircraftEntity.getAmmoCount(player)); int width2 = Minecraft.getInstance().font.width(count); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, 0x66FF00, false); } } //角度 poseStack.pushPose(); RenderSystem.disableDepthTest(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); RenderSystem.setShaderColor(1, 1, 1, 1); poseStack.rotateAround(Axis.ZP.rotationDegrees(-aircraftEntity.getRotZ(partialTick)), x, y, 0); float pitch = aircraftEntity.getRotX(partialTick); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/hud_line.png"), x - 96 + diffY, y - 128, 0, 448 + 4.10625f * pitch, 192, 256, 192, 1152); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/hud_ind.png"), x - 18 + diffY, y - 12, 0, 0, 36, 24, 36, 24); poseStack.popPose(); //能量警告 if (mobileVehicle.getEnergy() < 0.02 * mobileVehicle.getMaxEnergy()) { guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("NO POWER!"), (int) x - 144, (int) y + 14, -65536, false); } else if (mobileVehicle.getEnergy() < 0.2 * mobileVehicle.getMaxEnergy()) { guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("LOW POWER"), (int) x - 144, (int) y + 14, 0xFF6B00, false); } } } // 准星 if (pCross != null) { poseStack.pushPose(); float x = (float) pCross.x; float y = (float) pCross.y; if (mc.options.getCameraType() == CameraType.FIRST_PERSON) { RenderSystem.disableDepthTest(); RenderSystem.depthMask(false); RenderSystem.enableBlend(); RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); RenderSystem.setShaderColor(1, 1, 1, 1); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/hud_base2.png"), x - 72 + diffX, y - 72 + diffY, 0, 0, 144, 144, 144, 144); preciseBlit(guiGraphics, Mod.loc("textures/screens/aircraft/crosshair_ind.png"), x - 16, y - 16, 0, 0, 32, 32, 32, 32); renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f))); } else if (mc.options.getCameraType() == CameraType.THIRD_PERSON_BACK) { poseStack.pushPose(); poseStack.rotateAround(Axis.ZP.rotationDegrees(aircraftEntity.getRotZ(partialTick)), x, y, 0); preciseBlit(guiGraphics, Mod.loc("textures/screens/drone.png"), x - 8, y - 8, 0, 0, 16, 16, 16, 16); renderKillIndicator(guiGraphics, x - 7.5f + (float) (2 * (Math.random() - 0.5f)), y - 7.5f + (float) (2 * (Math.random() - 0.5f))); poseStack.pushPose(); poseStack.translate(x, y, 0); poseStack.scale(0.75f, 0.75f, 1); if (mobileVehicle instanceof A10Entity a10Entity) { if (weaponVehicle.getWeaponIndex(0) == 0) { double heat = a10Entity.getEntityData().get(HEAT) / 100.0F; guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("30MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : aircraftEntity.getAmmoCount(player))), 25, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false); } else { guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + aircraftEntity.getAmmoCount(player)), 25, -9, -1, false); } } guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("IR FLARES " + aircraftEntity.getDecoy()), 25, 1, -1, false); poseStack.popPose(); poseStack.popPose(); } poseStack.popPose(); } poseStack.popPose(); } } private static void renderKillIndicator(GuiGraphics guiGraphics, float posX, float posY) { VehicleHudOverlay.renderKillIndicator3P(guiGraphics, posX, posY); } public static double length(double x, double y, double z) { return Math.sqrt(x * x + y * y + z * z); } }