优化火炮HUD

This commit is contained in:
Atsuihsio 2025-03-11 17:16:35 +08:00
parent e58c8292df
commit 0f004b494e
6 changed files with 132 additions and 80 deletions

View file

@ -1,14 +1,21 @@
package com.atsuishio.superbwarfare.client.overlay; package com.atsuishio.superbwarfare.client.overlay;
import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.entity.vehicle.AnnihilatorEntity; import com.atsuishio.superbwarfare.entity.vehicle.AnnihilatorEntity;
import com.atsuishio.superbwarfare.entity.vehicle.Mk42Entity;
import com.atsuishio.superbwarfare.entity.vehicle.Mle1934Entity;
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.tools.FormatTool; import com.atsuishio.superbwarfare.tools.FormatTool;
import com.atsuishio.superbwarfare.tools.InventoryTool;
import com.atsuishio.superbwarfare.tools.TraceTool; import com.atsuishio.superbwarfare.tools.TraceTool;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Camera;
import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
@ -29,6 +36,7 @@ import org.joml.Math;
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator; import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator;
import static com.atsuishio.superbwarfare.client.overlay.VehicleHudOverlay.renderKillIndicator3P;
@Mod.EventBusSubscriber(value = Dist.CLIENT) @Mod.EventBusSubscriber(value = Dist.CLIENT)
public class CannonHudOverlay { public class CannonHudOverlay {
@ -41,91 +49,134 @@ public class CannonHudOverlay {
Player player = mc.player; Player player = mc.player;
GuiGraphics guiGraphics = event.getGuiGraphics(); GuiGraphics guiGraphics = event.getGuiGraphics();
PoseStack poseStack = guiGraphics.pose(); PoseStack poseStack = guiGraphics.pose();
Camera camera = mc.gameRenderer.getMainCamera();
Vec3 cameraPos = camera.getPosition();
if (!shouldRenderCrossHair(player)) return; if (!shouldRenderCrossHair(player)) return;
Entity cannon = player.getVehicle(); Entity vehicle = player.getVehicle();
if (cannon == null) return; if (vehicle instanceof CannonEntity cannonEntity && cannonEntity instanceof VehicleEntity cannon) {
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.pushPose(); preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/compass_white.png"), (float) w / 2 - 128, (float) 10, 128 + ((float) 64 / 45 * (Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot()))), 0, 256, 16, 512, 16);
RenderSystem.disableDepthTest(); preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/roll_ind_white.png"), w / 2 - 4, 27, 0, 0.0F, 8, 8, 8, 8);
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(event.getGuiGraphics(), ModUtils.loc("textures/screens/compass_white.png"), (float) w / 2 - 128, (float) 10, 128 + ((float) 64 / 45 * (Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot()))), 0, 256, 16, 512, 16); String angle = FormatTool.DECIMAL_FORMAT_1ZZ.format(Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot()));
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/roll_ind_white.png"), w / 2 - 4, 27, 0, 0.0F, 8, 8, 8, 8); int width = Minecraft.getInstance().font.width(angle);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(angle), w / 2 - width / 2, 40, -1, false);
String angle = FormatTool.DECIMAL_FORMAT_1ZZ.format(Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot())); preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch.png"), w / 2 + 166, h / 2 - 64, 0, 0.0F, 8, 128, 8, 128);
int width = Minecraft.getInstance().font.width(angle);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(angle), w / 2 - width / 2, 40, -1, false);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch.png"), w / 2 + 166, h / 2 - 64, 0, 0.0F, 8, 128, 8, 128); String pitch = FormatTool.DECIMAL_FORMAT_1ZZ.format(-Mth.lerp(event.getPartialTick(), cannon.xRotO, cannon.getXRot()));
int widthP = Minecraft.getInstance().font.width(pitch);
String pitch = FormatTool.DECIMAL_FORMAT_1ZZ.format(-Mth.lerp(event.getPartialTick(), cannon.xRotO, cannon.getXRot())); poseStack.pushPose();
int widthP = Minecraft.getInstance().font.width(pitch);
poseStack.pushPose(); event.getGuiGraphics().pose().translate(0, Mth.lerp(event.getPartialTick(), cannon.xRotO, cannon.getXRot()) * 0.7, 0);
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch_ind.png"), w / 2 + 158, h / 2 - 4, 0, 0.0F, 8, 8, 8, 8);
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(pitch), w / 2 + 157 - widthP, h / 2 - 4, -1, false);
poseStack.popPose();
event.getGuiGraphics().pose().translate(0, Mth.lerp(event.getPartialTick(), cannon.xRotO, cannon.getXRot()) * 0.7, 0); if (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle) {
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_pitch_ind.png"), w / 2 + 158, h / 2 - 4, 0, 0.0F, 8, 8, 8, 8); float fovAdjust = (float) 70 / Minecraft.getInstance().options.fov().get();
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.literal(pitch), w / 2 + 157 - widthP, h / 2 - 4, -1, false);
poseStack.popPose();
float fovAdjust = (float) 70 / Minecraft.getInstance().options.fov().get(); float f = (float) Math.min(w, h);
float f1 = Math.min((float) w / f, (float) h / f) * fovAdjust;
int i = Mth.floor(f * f1);
int j = Mth.floor(f * f1);
int k = (w - i) / 2;
int l = (h - j) / 2;
if (ClientEventHandler.zoomVehicle) {
Entity lookingEntity = TraceTool.findLookingEntity(player, 512);
boolean lookAtEntity = false;
float f = (float) Math.min(w, h); BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)),
float f1 = Math.min((float) w / f, (float) h / f) * fovAdjust; ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
int i = Mth.floor(f * f1); Vec3 hitPos = result.getLocation();
int j = Mth.floor(f * f1);
int k = (w - i) / 2;
int l = (h - j) / 2;
if (ClientEventHandler.zoomVehicle) {
Entity lookingEntity = TraceTool.findLookingEntity(player, 512);
boolean lookAtEntity = false;
BlockHitResult result = player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(player.getViewVector(1).scale(512)), double blockRange = player.getEyePosition(1).distanceTo(hitPos);
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player));
Vec3 hitPos = result.getLocation();
double blockRange = player.getEyePosition(1).distanceTo(hitPos); double entityRange = 0;
if (lookingEntity instanceof LivingEntity living) {
lookAtEntity = true;
entityRange = player.distanceTo(living);
}
if (lookAtEntity) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
.append(Component.literal(FormatTool.format1D(entityRange, "m ") + lookingEntity.getDisplayName().getString())),
w / 2 + 14, h / 2 - 20, -1, false);
} else {
if (blockRange > 511) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
.append(Component.literal("---m")), w / 2 + 14, h / 2 - 20, -1, false);
} else {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
.append(Component.literal(FormatTool.format1D(blockRange, "m"))),
w / 2 + 14, h / 2 - 20, -1, false);
}
}
if (cannon instanceof AnnihilatorEntity) {
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/laser_cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
} else {
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
}
float diffY = -Mth.wrapDegrees(Mth.lerp(event.getPartialTick(), player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot()));
double entityRange = 0; preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/indicator.png"), w / 2 - 4.3f + 0.45f * diffY, h / 2 - 10, 0, 0.0F, 8, 8, 8, 8);
if (lookingEntity instanceof LivingEntity living) {
lookAtEntity = true;
entityRange = player.distanceTo(living);
}
if (lookAtEntity) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
.append(Component.literal(FormatTool.format1D(entityRange, "m ") + lookingEntity.getDisplayName().getString())),
w / 2 + 14, h / 2 - 20, -1, false);
} else {
if (blockRange > 511) {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range")
.append(Component.literal("---m")), w / 2 + 14, h / 2 - 20, -1, false);
} else { } else {
event.getGuiGraphics().drawString(Minecraft.getInstance().font, Component.translatable("tips.superbwarfare.drone.range") preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
.append(Component.literal(FormatTool.format1D(blockRange, "m"))), }
w / 2 + 14, h / 2 - 20, -1, false); renderKillIndicator(guiGraphics, w, h);
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK && !ClientEventHandler.zoomVehicle) {
Vec3 p = RenderHelper.worldToScreen(new Vec3(Mth.lerp(event.getPartialTick(), player.xo, player.getX()), Mth.lerp(event.getPartialTick(), player.yo, player.getY()),
Mth.lerp(event.getPartialTick(), player.zo, player.getZ())).add(cannon.getViewVector(event.getPartialTick()).scale(128)), cameraPos);
// 第三人称准星
if (p != null) {
poseStack.pushPose();
float x = (float) p.x;
float y = (float) p.y;
poseStack.pushPose();
preciseBlit(guiGraphics, ModUtils.loc("textures/screens/drone.png"), x - 12, y - 12, 0, 0, 24, 24, 24, 24);
renderKillIndicator3P(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 (player.getVehicle() instanceof Mk42Entity || player.getVehicle() instanceof Mle1934Entity) {
if (cannonEntity.getWeaponIndex(0) == 0) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("AP SHELL " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : cannonEntity.getAmmoCount(player))), 30, -9, -1, false);
} else {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HE SHELL " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : cannonEntity.getAmmoCount(player))), 30, -9, -1, false);
}
}
// 歼灭者
if (player.getVehicle() instanceof AnnihilatorEntity annihilatorEntity) {
guiGraphics.drawString(mc.font, Component.literal("LASER " + (FormatTool.format0D((double) (100 * annihilatorEntity.getEnergy()) / annihilatorEntity.getMaxEnergy()) + "")), 30, -9, -1, false);
}
double heal = 1 - cannon.getHealth() / cannon.getMaxHealth();
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HP " +
FormatTool.format0D(100 * cannon.getHealth() / cannon.getMaxHealth())), 30, 1, Mth.hsvToRgb(0F, (float) heal, 1.0F), false);
poseStack.popPose();
poseStack.popPose();
poseStack.popPose();
} }
} }
if (cannon instanceof AnnihilatorEntity) { poseStack.popPose();
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/laser_cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
} else {
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
}
float diffY = -Mth.wrapDegrees(Mth.lerp(event.getPartialTick(), player.yHeadRotO, player.getYHeadRot()) - Mth.lerp(event.getPartialTick(), cannon.yRotO, cannon.getYRot()));
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/indicator.png"), w / 2 - 4.3f + 0.45f * diffY, h / 2 - 10, 0, 0.0F, 8, 8, 8, 8);
} else {
preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
} }
renderKillIndicator(guiGraphics, w, h);
poseStack.popPose();
} }
private static boolean shouldRenderCrossHair(Player player) { private static boolean shouldRenderCrossHair(Player player) {

View file

@ -507,7 +507,7 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
turretTurnSound(diffX, diffY, 0.8f); turretTurnSound(diffX, diffY, 0.8f);
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -0.6f, 0.6f)); this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -0.6f, 0.6f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -2f, 2f), -45, 5f)); this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -0.8f, 0.8f), -45, 5f));
} }
public void autoAim() { public void autoAim() {

View file

@ -388,11 +388,8 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, CannonEntity
@Override @Override
public int getAmmoCount(Player player) { public int getAmmoCount(Player player) {
if (player.getMainHandItem().getItem() instanceof CannonShellItem) { var ammo = getWeaponIndex(0) == 0 ? ModItems.AP_5_INCHES.get() : ModItems.HE_5_INCHES.get();
return player.getMainHandItem().getCount(); return InventoryTool.countItem(player.getInventory().items, ammo);
} else {
return -1;
}
} }
@Override @Override

View file

@ -510,11 +510,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, CannonEnt
@Override @Override
public int getAmmoCount(Player player) { public int getAmmoCount(Player player) {
if (player.getMainHandItem().getItem() instanceof CannonShellItem) { var ammo = getWeaponIndex(0) == 0 ? ModItems.AP_5_INCHES.get() : ModItems.HE_5_INCHES.get();
return player.getMainHandItem().getCount(); return InventoryTool.countItem(player.getInventory().items, ammo);
} else {
return -1;
}
} }
@Override @Override

View file

@ -1,6 +1,7 @@
package com.atsuishio.superbwarfare.mixins; package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.vehicle.*; import com.atsuishio.superbwarfare.entity.vehicle.*;
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModTags; import com.atsuishio.superbwarfare.init.ModTags;
@ -118,6 +119,12 @@ public abstract class CameraMixin {
} }
return; return;
} }
if (player.getVehicle() instanceof CannonEntity && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) {
setRotation(Mth.lerp(partialTicks, player.yRotO, player.getYRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot()));
setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ()));
info.cancel();
}
} }
} }

View file

@ -18,9 +18,9 @@
"paoguan": { "paoguan": {
"position": { "position": {
"0.0": [0, 0, 0], "0.0": [0, 0, 0],
"0.05": [0, 0, 11], "0.0167": [0, 0, 11],
"0.4917": [0, 0, 0], "0.2917": [0, 0, 0],
"0.6667": [0, 0, 0] "0.6583": [0, 0, 0]
} }
}, },
"flare": { "flare": {