superb-warfare/src/main/java/com/atsuishio/superbwarfare/client/overlay/AircraftOverlay.java
2025-05-07 17:28:33 +08:00

237 lines
14 KiB
Java

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);
}
}