重构部分overlay写法,修复防弹插板数据同步问题
This commit is contained in:
parent
ec9c46dbd2
commit
7e239a2e9f
5 changed files with 427 additions and 393 deletions
|
@ -1,5 +1,8 @@
|
||||||
package com.atsuishio.superbwarfare.client;
|
package com.atsuishio.superbwarfare.client;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.client.overlay.AmmoBarOverlay;
|
||||||
|
import com.atsuishio.superbwarfare.client.overlay.AmmoCountOverlay;
|
||||||
|
import com.atsuishio.superbwarfare.client.overlay.ArmorPlateOverlay;
|
||||||
import com.atsuishio.superbwarfare.client.renderer.block.*;
|
import com.atsuishio.superbwarfare.client.renderer.block.*;
|
||||||
import com.atsuishio.superbwarfare.client.tooltip.*;
|
import com.atsuishio.superbwarfare.client.tooltip.*;
|
||||||
import com.atsuishio.superbwarfare.client.tooltip.component.*;
|
import com.atsuishio.superbwarfare.client.tooltip.component.*;
|
||||||
|
@ -9,6 +12,7 @@ import net.neoforged.bus.api.SubscribeEvent;
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||||
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
|
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent;
|
||||||
|
|
||||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
|
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
|
||||||
public class ClientRenderHandler {
|
public class ClientRenderHandler {
|
||||||
|
@ -34,4 +38,11 @@ public class ClientRenderHandler {
|
||||||
event.registerBlockEntityRenderer(ModBlockEntities.CREATIVE_CHARGING_STATION.get(), context -> new CreativeChargingStationBlockEntityRenderer());
|
event.registerBlockEntityRenderer(ModBlockEntities.CREATIVE_CHARGING_STATION.get(), context -> new CreativeChargingStationBlockEntityRenderer());
|
||||||
event.registerBlockEntityRenderer(ModBlockEntities.SMALL_CONTAINER.get(), context -> new SmallContainerBlockEntityRenderer());
|
event.registerBlockEntityRenderer(ModBlockEntities.SMALL_CONTAINER.get(), context -> new SmallContainerBlockEntityRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerOverlays(RegisterGuiLayersEvent event) {
|
||||||
|
event.registerBelowAll(ArmorPlateOverlay.ID, new ArmorPlateOverlay());
|
||||||
|
event.registerBelowAll(AmmoBarOverlay.ID, new AmmoBarOverlay());
|
||||||
|
event.registerBelowAll(AmmoCountOverlay.ID, new AmmoCountOverlay());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,38 +3,31 @@ package com.atsuishio.superbwarfare.client.overlay;
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||||
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
|
||||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
import com.atsuishio.superbwarfare.init.ModKeyMappings;
|
import com.atsuishio.superbwarfare.init.ModKeyMappings;
|
||||||
import com.atsuishio.superbwarfare.init.ModTags;
|
import com.atsuishio.superbwarfare.init.ModTags;
|
||||||
import com.atsuishio.superbwarfare.item.common.ammo.AmmoSupplierItem;
|
|
||||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||||
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
||||||
import com.atsuishio.superbwarfare.tools.AmmoType;
|
|
||||||
import com.atsuishio.superbwarfare.tools.GunsTool;
|
|
||||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||||
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
|
||||||
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
|
||||||
import com.atsuishio.superbwarfare.tools.animation.ValueAnimator;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.gui.LayeredDraw;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.FastColor;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
|
||||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
|
||||||
|
|
||||||
@EventBusSubscriber(value = Dist.CLIENT)
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
public class AmmoBarOverlay {
|
|
||||||
|
|
||||||
|
public class AmmoBarOverlay implements LayeredDraw.Layer {
|
||||||
|
public static final ResourceLocation ID = Mod.loc("ammo_bar");
|
||||||
|
|
||||||
private static final ResourceLocation LINE = Mod.loc("textures/gun_icon/fire_mode/line.png");
|
private static final ResourceLocation LINE = Mod.loc("textures/gun_icon/fire_mode/line.png");
|
||||||
private static final ResourceLocation SEMI = Mod.loc("textures/gun_icon/fire_mode/semi.png");
|
private static final ResourceLocation SEMI = Mod.loc("textures/gun_icon/fire_mode/semi.png");
|
||||||
|
@ -50,360 +43,8 @@ public class AmmoBarOverlay {
|
||||||
return InventoryTool.hasCreativeAmmoBox(player);
|
return InventoryTool.hasCreativeAmmoBox(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void renderWeaponInfo(RenderGuiEvent.Pre event) {
|
|
||||||
if (!DisplayConfig.AMMO_HUD.get()) return;
|
|
||||||
|
|
||||||
int w = event.getGuiGraphics().guiWidth();
|
|
||||||
int h = event.getGuiGraphics().guiHeight();
|
|
||||||
Player player = Minecraft.getInstance().player;
|
|
||||||
|
|
||||||
if (player == null) return;
|
|
||||||
if (player.isSpectator()) return;
|
|
||||||
|
|
||||||
ItemStack stack = player.getMainHandItem();
|
|
||||||
final var tag = NBTTool.getTag(stack);
|
|
||||||
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
|
||||||
PoseStack poseStack = event.getGuiGraphics().pose();
|
|
||||||
var data = GunData.from(stack);
|
|
||||||
|
|
||||||
// 渲染图标
|
|
||||||
event.getGuiGraphics().blit(gunItem.getGunIcon(),
|
|
||||||
w - 135,
|
|
||||||
h - 40,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
64,
|
|
||||||
16,
|
|
||||||
64,
|
|
||||||
16);
|
|
||||||
|
|
||||||
// 渲染开火模式切换按键
|
|
||||||
if (stack.getItem() != ModItems.MINIGUN.get()) {
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
"[" + ModKeyMappings.FIRE_MODE.getKey().getDisplayName().getString() + "]",
|
|
||||||
w - 111.5f,
|
|
||||||
h - 20,
|
|
||||||
0xFFFFFF,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染开火模式
|
|
||||||
ResourceLocation fireMode = getFireMode(data);
|
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.JAVELIN.get()) {
|
|
||||||
fireMode = tag.getBoolean("TopMode") ? TOP : DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
|
||||||
fireMode = MOUSE;
|
|
||||||
// 渲染加特林射速
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
data.rpm() + " RPM",
|
|
||||||
w - 111f,
|
|
||||||
h - 20,
|
|
||||||
0xFFFFFF,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
event.getGuiGraphics().blit(fireMode,
|
|
||||||
w - 126,
|
|
||||||
h - 22,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
12,
|
|
||||||
12,
|
|
||||||
12,
|
|
||||||
12);
|
|
||||||
} else {
|
|
||||||
if (stack.getItem() != ModItems.TRACHELIUM.get()) {
|
|
||||||
event.getGuiGraphics().blit(fireMode,
|
|
||||||
w - 95,
|
|
||||||
h - 21,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8);
|
|
||||||
} else {
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
tag.getBoolean("DA") ? Component.translatable("des.superbwarfare.revolver.sa").withStyle(ChatFormatting.BOLD) : Component.translatable("des.superbwarfare.revolver.da").withStyle(ChatFormatting.BOLD),
|
|
||||||
w - 96,
|
|
||||||
h - 20,
|
|
||||||
0xFFFFFF,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.getItem() != ModItems.MINIGUN.get() && stack.getItem() != ModItems.TRACHELIUM.get()) {
|
|
||||||
event.getGuiGraphics().blit(LINE,
|
|
||||||
w - 95,
|
|
||||||
h - 16,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8,
|
|
||||||
8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染当前弹药量
|
|
||||||
poseStack.pushPose();
|
|
||||||
poseStack.scale(1.5f, 1.5f, 1f);
|
|
||||||
|
|
||||||
if ((stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) && hasCreativeAmmo()) {
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
"∞",
|
|
||||||
w / 1.5f - 64 / 1.5f,
|
|
||||||
h / 1.5f - 48 / 1.5f,
|
|
||||||
0xFFFFFF,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
getGunAmmoCount(player) + "",
|
|
||||||
w / 1.5f - 64 / 1.5f,
|
|
||||||
h / 1.5f - 48 / 1.5f,
|
|
||||||
0xFFFFFF,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
poseStack.popPose();
|
|
||||||
|
|
||||||
// 渲染备弹量
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
getPlayerAmmoCount(player),
|
|
||||||
w - 64,
|
|
||||||
h - 35,
|
|
||||||
0xCCCCCC,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
poseStack.pushPose();
|
|
||||||
poseStack.scale(0.9f, 0.9f, 1f);
|
|
||||||
|
|
||||||
// 渲染物品名称
|
|
||||||
String gunName = gunItem.getGunDisplayName();
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
gunName,
|
|
||||||
w / 0.9f - (100 + Minecraft.getInstance().font.width(gunName) / 2f) / 0.9f,
|
|
||||||
h / 0.9f - 60 / 0.9f,
|
|
||||||
0xFFFFFF,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// 渲染弹药类型
|
|
||||||
String ammoName = gunItem.getAmmoDisplayName(stack);
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
ammoName,
|
|
||||||
w / 0.9f - (100 + Minecraft.getInstance().font.width(ammoName) / 2f) / 0.9f,
|
|
||||||
h / 0.9f - 51 / 0.9f,
|
|
||||||
0xC8A679,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
poseStack.popPose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(500, 2000)
|
|
||||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
|
||||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
|
||||||
private static final AnimationTimer ammoBoxTimer = new AnimationTimer(500)
|
|
||||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
|
||||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
|
||||||
|
|
||||||
private static final ValueAnimator<Integer>[] ammoCountAnimators = ValueAnimator.create(
|
|
||||||
AmmoType.values().length, 800, 0
|
|
||||||
);
|
|
||||||
private static final ValueAnimator<Integer>[] ammoBoxAnimators = ValueAnimator.create(
|
|
||||||
AmmoType.values().length, 800, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
|
||||||
*/
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void renderAmmoInfo(RenderGuiEvent.Pre event) {
|
|
||||||
boolean startRenderingAmmoInfo = false;
|
|
||||||
Player player = Minecraft.getInstance().player;
|
|
||||||
if (player == null || player.isSpectator()) return;
|
|
||||||
|
|
||||||
boolean isAmmoBox = false;
|
|
||||||
|
|
||||||
// 动画计算
|
|
||||||
var currentTime = System.currentTimeMillis();
|
|
||||||
ItemStack stack = player.getMainHandItem();
|
|
||||||
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get())
|
|
||||||
&& !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))
|
|
||||||
) {
|
|
||||||
// 刚拿出弹药物品时,视为开始弹药信息渲染
|
|
||||||
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
|
||||||
ammoInfoTimer.forward(currentTime);
|
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.AMMO_BOX.get()) {
|
|
||||||
isAmmoBox = true;
|
|
||||||
ammoBoxTimer.forward(currentTime);
|
|
||||||
} else {
|
|
||||||
ammoBoxTimer.backward(currentTime);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ammoInfoTimer.backward(currentTime);
|
|
||||||
ammoBoxTimer.backward(currentTime);
|
|
||||||
}
|
|
||||||
if (!ammoInfoTimer.isForward() && ammoInfoTimer.finished(currentTime)) return;
|
|
||||||
|
|
||||||
var poseStack = event.getGuiGraphics().pose();
|
|
||||||
poseStack.pushPose();
|
|
||||||
|
|
||||||
int w = event.getGuiGraphics().guiWidth();
|
|
||||||
int h = event.getGuiGraphics().guiHeight();
|
|
||||||
|
|
||||||
var ammoX = ammoInfoTimer.lerp(w + 120, (float) w / 2 + 40, currentTime);
|
|
||||||
final int fontHeight = 15;
|
|
||||||
var yOffset = (-h - AmmoType.values().length * fontHeight) / 2f;
|
|
||||||
|
|
||||||
// 渲染总弹药数量
|
|
||||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
|
||||||
if (cap == null) cap = new PlayerVariable();
|
|
||||||
var font = Minecraft.getInstance().font;
|
|
||||||
|
|
||||||
for (var type : AmmoType.values()) {
|
|
||||||
var index = type.ordinal();
|
|
||||||
var ammoCount = type.get(cap);
|
|
||||||
var animator = ammoCountAnimators[index];
|
|
||||||
|
|
||||||
var boxAnimator = ammoBoxAnimators[index];
|
|
||||||
var boxAmmoCount = boxAnimator.newValue();
|
|
||||||
boolean boxAmmoSelected = false;
|
|
||||||
|
|
||||||
if (isAmmoBox) {
|
|
||||||
var data = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
|
||||||
var ammoBoxType = data == null ? "All" : data.type();
|
|
||||||
|
|
||||||
boxAmmoCount = type.get(stack);
|
|
||||||
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
|
||||||
boxAnimator.forward(currentTime);
|
|
||||||
boxAmmoSelected = true;
|
|
||||||
} else {
|
|
||||||
boxAnimator.reset(boxAmmoCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
|
||||||
if (startRenderingAmmoInfo) {
|
|
||||||
animator.reset(ammoCount);
|
|
||||||
animator.endForward(currentTime);
|
|
||||||
if (isAmmoBox) {
|
|
||||||
boxAnimator.reset(type.get(stack));
|
|
||||||
boxAnimator.endForward(currentTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ammoAdd = Integer.compare(ammoCount, animator.oldValue());
|
|
||||||
// 弹药数量变化时,更新并开始播放弹药数量更改动画
|
|
||||||
animator.compareAndUpdate(ammoCount, () -> {
|
|
||||||
// 弹药数量变化时,开始播放弹药数量更改动画
|
|
||||||
animator.beginForward(currentTime);
|
|
||||||
});
|
|
||||||
|
|
||||||
var progress = animator.getProgress(currentTime);
|
|
||||||
var ammoCountStr = Integer.toString(
|
|
||||||
Math.round(animator.lerp(animator.oldValue(), ammoCount, currentTime))
|
|
||||||
);
|
|
||||||
|
|
||||||
// 弹药增加时,颜色由绿变白,否则由红变白
|
|
||||||
var fontColor = FastColor.ARGB32.lerp(progress, switch (ammoAdd) {
|
|
||||||
case 1 -> 0xFF00FF00;
|
|
||||||
case -1 -> 0xFFFF0000;
|
|
||||||
default -> 0xFFFFFFFF;
|
|
||||||
}, 0xFFFFFFFF);
|
|
||||||
|
|
||||||
RenderSystem.setShaderColor(1, 1, 1, ammoInfoTimer.lerp(0, 1, currentTime));
|
|
||||||
|
|
||||||
// 弹药数量
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
font,
|
|
||||||
ammoCountStr,
|
|
||||||
ammoX + (30 - font.width(ammoCountStr)),
|
|
||||||
h + yOffset,
|
|
||||||
fontColor,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// 弹药类型
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
font,
|
|
||||||
Component.translatable(type.translatableKey).getString(),
|
|
||||||
ammoX + 35,
|
|
||||||
h + yOffset,
|
|
||||||
fontColor,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// 弹药盒信息渲染
|
|
||||||
RenderSystem.setShaderColor(1, 1, 1, ammoBoxTimer.lerp(0, 1, currentTime));
|
|
||||||
var ammoBoxX = ammoBoxTimer.lerp(-30, (float) w / 2, currentTime);
|
|
||||||
|
|
||||||
int ammoBoxAdd = Integer.compare(boxAmmoCount, boxAnimator.oldValue());
|
|
||||||
boxAnimator.compareAndUpdate(boxAmmoCount, () -> boxAnimator.beginForward(currentTime));
|
|
||||||
|
|
||||||
// 选中时显示为黄色,否则为白色
|
|
||||||
var targetColor = boxAmmoSelected ? 0xFFFFFF00 : 0xFFFFFFFF;
|
|
||||||
|
|
||||||
var boxFontColor = FastColor.ARGB32.lerp(boxAnimator.getProgress(currentTime),
|
|
||||||
switch (ammoBoxAdd) {
|
|
||||||
case 1 -> 0xFF00FF00;
|
|
||||||
case -1 -> 0xFFFF0000;
|
|
||||||
default -> targetColor;
|
|
||||||
},
|
|
||||||
targetColor
|
|
||||||
);
|
|
||||||
|
|
||||||
// 弹药盒内弹药数量
|
|
||||||
event.getGuiGraphics().drawString(
|
|
||||||
Minecraft.getInstance().font,
|
|
||||||
Integer.toString(
|
|
||||||
Math.round(boxAnimator.lerp(boxAnimator.oldValue(), boxAmmoCount, currentTime))
|
|
||||||
),
|
|
||||||
ammoBoxX - 70,
|
|
||||||
h + yOffset,
|
|
||||||
boxFontColor,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
yOffset += fontHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderSystem.setShaderColor(1, 1, 1, 1);
|
|
||||||
poseStack.popPose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ResourceLocation getFireMode(GunData data) {
|
|
||||||
return switch (data.fireMode()) {
|
|
||||||
case 1 -> BURST;
|
|
||||||
case 2 -> AUTO;
|
|
||||||
default -> SEMI;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getGunAmmoCount(Player player) {
|
private static int getGunAmmoCount(Player player) {
|
||||||
ItemStack stack = player.getMainHandItem();
|
ItemStack stack = player.getMainHandItem();
|
||||||
var data = GunData.from(stack);
|
|
||||||
var tag = data.tag();
|
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
||||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||||
|
@ -411,28 +52,26 @@ public class AmmoBarOverlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.BOCEK.get()) {
|
if (stack.getItem() == ModItems.BOCEK.get()) {
|
||||||
return GunsTool.getGunIntTag(tag, "MaxAmmo");
|
return GunData.from(stack).data().getInt("MaxAmmo");
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.ammo();
|
return GunData.from(stack).ammo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getPlayerAmmoCount(Player player) {
|
private static String getPlayerAmmoCount(Player player) {
|
||||||
ItemStack stack = player.getMainHandItem();
|
ItemStack stack = player.getMainHandItem();
|
||||||
final var tag = NBTTool.getTag(stack);
|
|
||||||
|
|
||||||
if (stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) {
|
if (stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||||
|
if (cap == null) cap = new PlayerVariable();
|
||||||
if (!hasCreativeAmmo()) {
|
if (!hasCreativeAmmo()) {
|
||||||
|
var data = GunData.from(stack);
|
||||||
if (stack.is(ModTags.Items.LAUNCHER) || stack.getItem() == ModItems.TASER.get()) {
|
if (stack.is(ModTags.Items.LAUNCHER) || stack.getItem() == ModItems.TASER.get()) {
|
||||||
return "" + GunsTool.getGunIntTag(tag, "MaxAmmo");
|
return "" + data.data().getInt("MaxAmmo");
|
||||||
}
|
}
|
||||||
|
|
||||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
|
||||||
if (cap == null) return "";
|
|
||||||
|
|
||||||
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
|
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
|
||||||
return "" + cap.rifleAmmo;
|
return "" + cap.rifleAmmo;
|
||||||
}
|
}
|
||||||
|
@ -453,4 +92,181 @@ public class AmmoBarOverlay {
|
||||||
|
|
||||||
return "∞";
|
return "∞";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void render(GuiGraphics guiGraphics, DeltaTracker deltaTracker) {
|
||||||
|
if (!DisplayConfig.AMMO_HUD.get()) return;
|
||||||
|
|
||||||
|
int w = guiGraphics.guiWidth();
|
||||||
|
int h = guiGraphics.guiHeight();
|
||||||
|
Player player = Minecraft.getInstance().player;
|
||||||
|
|
||||||
|
if (player == null) return;
|
||||||
|
if (player.isSpectator()) return;
|
||||||
|
|
||||||
|
ItemStack stack = player.getMainHandItem();
|
||||||
|
final var tag = NBTTool.getTag(stack);
|
||||||
|
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
||||||
|
PoseStack poseStack = guiGraphics.pose();
|
||||||
|
var data = GunData.from(stack);
|
||||||
|
|
||||||
|
// 渲染图标
|
||||||
|
guiGraphics.blit(gunItem.getGunIcon(),
|
||||||
|
w - 135,
|
||||||
|
h - 40,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
64,
|
||||||
|
16,
|
||||||
|
64,
|
||||||
|
16);
|
||||||
|
|
||||||
|
// 渲染开火模式切换按键
|
||||||
|
if (stack.getItem() != ModItems.MINIGUN.get()) {
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
"[" + ModKeyMappings.FIRE_MODE.getKey().getDisplayName().getString() + "]",
|
||||||
|
w - 111.5f,
|
||||||
|
h - 20,
|
||||||
|
0xFFFFFF,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染开火模式
|
||||||
|
ResourceLocation fireMode = getFireMode(data);
|
||||||
|
|
||||||
|
if (stack.getItem() == ModItems.JAVELIN.get()) {
|
||||||
|
fireMode = tag.getBoolean("TopMode") ? TOP : DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.getItem() == ModItems.MINIGUN.get()) {
|
||||||
|
fireMode = MOUSE;
|
||||||
|
// 渲染加特林射速
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
data.rpm() + " RPM",
|
||||||
|
w - 111f,
|
||||||
|
h - 20,
|
||||||
|
0xFFFFFF,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
guiGraphics.blit(fireMode,
|
||||||
|
w - 126,
|
||||||
|
h - 22,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
12,
|
||||||
|
12,
|
||||||
|
12,
|
||||||
|
12);
|
||||||
|
} else {
|
||||||
|
if (stack.getItem() != ModItems.TRACHELIUM.get()) {
|
||||||
|
guiGraphics.blit(fireMode,
|
||||||
|
w - 95,
|
||||||
|
h - 21,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
8,
|
||||||
|
8,
|
||||||
|
8);
|
||||||
|
} else {
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
tag.getBoolean("DA") ? Component.translatable("des.superbwarfare.revolver.sa").withStyle(ChatFormatting.BOLD) : Component.translatable("des.superbwarfare.revolver.da").withStyle(ChatFormatting.BOLD),
|
||||||
|
w - 96,
|
||||||
|
h - 20,
|
||||||
|
0xFFFFFF,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.getItem() != ModItems.MINIGUN.get() && stack.getItem() != ModItems.TRACHELIUM.get()) {
|
||||||
|
guiGraphics.blit(LINE,
|
||||||
|
w - 95,
|
||||||
|
h - 16,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
8,
|
||||||
|
8,
|
||||||
|
8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染当前弹药量
|
||||||
|
poseStack.pushPose();
|
||||||
|
poseStack.scale(1.5f, 1.5f, 1f);
|
||||||
|
|
||||||
|
if ((stack.getItem() == ModItems.MINIGUN.get() || stack.getItem() == ModItems.BOCEK.get()) && hasCreativeAmmo()) {
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
"∞",
|
||||||
|
w / 1.5f - 64 / 1.5f,
|
||||||
|
h / 1.5f - 48 / 1.5f,
|
||||||
|
0xFFFFFF,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
getGunAmmoCount(player) + "",
|
||||||
|
w / 1.5f - 64 / 1.5f,
|
||||||
|
h / 1.5f - 48 / 1.5f,
|
||||||
|
0xFFFFFF,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
poseStack.popPose();
|
||||||
|
|
||||||
|
// 渲染备弹量
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
getPlayerAmmoCount(player),
|
||||||
|
w - 64,
|
||||||
|
h - 35,
|
||||||
|
0xCCCCCC,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
poseStack.pushPose();
|
||||||
|
poseStack.scale(0.9f, 0.9f, 1f);
|
||||||
|
|
||||||
|
// 渲染物品名称
|
||||||
|
String gunName = gunItem.getGunDisplayName();
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
gunName,
|
||||||
|
w / 0.9f - (100 + Minecraft.getInstance().font.width(gunName) / 2f) / 0.9f,
|
||||||
|
h / 0.9f - 60 / 0.9f,
|
||||||
|
0xFFFFFF,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// 渲染弹药类型
|
||||||
|
String ammoName = gunItem.getAmmoDisplayName(stack);
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
ammoName,
|
||||||
|
w / 0.9f - (100 + Minecraft.getInstance().font.width(ammoName) / 2f) / 0.9f,
|
||||||
|
h / 0.9f - 51 / 0.9f,
|
||||||
|
0xC8A679,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
poseStack.popPose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ResourceLocation getFireMode(GunData data) {
|
||||||
|
return switch (data.fireMode()) {
|
||||||
|
case 1 -> BURST;
|
||||||
|
case 2 -> AUTO;
|
||||||
|
default -> SEMI;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
package com.atsuishio.superbwarfare.client.overlay;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
|
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||||
|
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
|
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||||
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
|
import com.atsuishio.superbwarfare.item.common.ammo.AmmoSupplierItem;
|
||||||
|
import com.atsuishio.superbwarfare.tools.AmmoType;
|
||||||
|
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
||||||
|
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
||||||
|
import com.atsuishio.superbwarfare.tools.animation.ValueAnimator;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
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.network.chat.Component;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.FastColor;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
public class AmmoCountOverlay implements LayeredDraw.Layer {
|
||||||
|
|
||||||
|
public static final ResourceLocation ID = Mod.loc("ammo_count");
|
||||||
|
|
||||||
|
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(500, 2000)
|
||||||
|
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||||
|
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||||
|
private static final AnimationTimer ammoBoxTimer = new AnimationTimer(500)
|
||||||
|
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||||
|
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||||
|
|
||||||
|
private static final ValueAnimator<Integer>[] ammoCountAnimators = ValueAnimator.create(
|
||||||
|
AmmoType.values().length, 800, 0
|
||||||
|
);
|
||||||
|
private static final ValueAnimator<Integer>[] ammoBoxAnimators = ValueAnimator.create(
|
||||||
|
AmmoType.values().length, 800, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void render(GuiGraphics guiGraphics, DeltaTracker deltaTracker) {
|
||||||
|
boolean startRenderingAmmoInfo = false;
|
||||||
|
Player player = Minecraft.getInstance().player;
|
||||||
|
if (player == null || player.isSpectator()) return;
|
||||||
|
|
||||||
|
boolean isAmmoBox = false;
|
||||||
|
|
||||||
|
// 动画计算
|
||||||
|
var currentTime = System.currentTimeMillis();
|
||||||
|
ItemStack stack = player.getMainHandItem();
|
||||||
|
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get())
|
||||||
|
&& !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))
|
||||||
|
) {
|
||||||
|
// 刚拿出弹药物品时,视为开始弹药信息渲染
|
||||||
|
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
||||||
|
ammoInfoTimer.forward(currentTime);
|
||||||
|
|
||||||
|
if (stack.getItem() == ModItems.AMMO_BOX.get()) {
|
||||||
|
isAmmoBox = true;
|
||||||
|
ammoBoxTimer.forward(currentTime);
|
||||||
|
} else {
|
||||||
|
ammoBoxTimer.backward(currentTime);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ammoInfoTimer.backward(currentTime);
|
||||||
|
ammoBoxTimer.backward(currentTime);
|
||||||
|
}
|
||||||
|
if (!ammoInfoTimer.isForward() && ammoInfoTimer.finished(currentTime)) return;
|
||||||
|
|
||||||
|
var poseStack = guiGraphics.pose();
|
||||||
|
poseStack.pushPose();
|
||||||
|
|
||||||
|
int w = guiGraphics.guiWidth();
|
||||||
|
int h = guiGraphics.guiHeight();
|
||||||
|
|
||||||
|
var ammoX = ammoInfoTimer.lerp(w + 120, (float) w / 2 + 40, currentTime);
|
||||||
|
final int fontHeight = 15;
|
||||||
|
var yOffset = (-h - AmmoType.values().length * fontHeight) / 2f;
|
||||||
|
|
||||||
|
// 渲染总弹药数量
|
||||||
|
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||||
|
if (cap == null) cap = new PlayerVariable();
|
||||||
|
var font = Minecraft.getInstance().font;
|
||||||
|
|
||||||
|
for (var type : AmmoType.values()) {
|
||||||
|
var index = type.ordinal();
|
||||||
|
var ammoCount = type.get(cap);
|
||||||
|
var animator = ammoCountAnimators[index];
|
||||||
|
|
||||||
|
var boxAnimator = ammoBoxAnimators[index];
|
||||||
|
var boxAmmoCount = boxAnimator.newValue();
|
||||||
|
boolean boxAmmoSelected = false;
|
||||||
|
|
||||||
|
if (isAmmoBox) {
|
||||||
|
var data = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
||||||
|
var ammoBoxType = data == null ? "All" : data.type();
|
||||||
|
|
||||||
|
boxAmmoCount = type.get(stack);
|
||||||
|
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
||||||
|
boxAnimator.forward(currentTime);
|
||||||
|
boxAmmoSelected = true;
|
||||||
|
} else {
|
||||||
|
boxAnimator.reset(boxAmmoCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
||||||
|
if (startRenderingAmmoInfo) {
|
||||||
|
animator.reset(ammoCount);
|
||||||
|
animator.endForward(currentTime);
|
||||||
|
if (isAmmoBox) {
|
||||||
|
boxAnimator.reset(type.get(stack));
|
||||||
|
boxAnimator.endForward(currentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ammoAdd = Integer.compare(ammoCount, animator.oldValue());
|
||||||
|
// 弹药数量变化时,更新并开始播放弹药数量更改动画
|
||||||
|
animator.compareAndUpdate(ammoCount, () -> {
|
||||||
|
// 弹药数量变化时,开始播放弹药数量更改动画
|
||||||
|
animator.beginForward(currentTime);
|
||||||
|
});
|
||||||
|
|
||||||
|
var progress = animator.getProgress(currentTime);
|
||||||
|
var ammoCountStr = Integer.toString(
|
||||||
|
Math.round(animator.lerp(animator.oldValue(), ammoCount, currentTime))
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药增加时,颜色由绿变白,否则由红变白
|
||||||
|
var fontColor = FastColor.ARGB32.lerp(progress, switch (ammoAdd) {
|
||||||
|
case 1 -> 0xFF00FF00;
|
||||||
|
case -1 -> 0xFFFF0000;
|
||||||
|
default -> 0xFFFFFFFF;
|
||||||
|
}, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, ammoInfoTimer.lerp(0, 1, currentTime));
|
||||||
|
|
||||||
|
// 弹药数量
|
||||||
|
guiGraphics.drawString(
|
||||||
|
font,
|
||||||
|
ammoCountStr,
|
||||||
|
ammoX + (30 - font.width(ammoCountStr)),
|
||||||
|
h + yOffset,
|
||||||
|
fontColor,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药类型
|
||||||
|
guiGraphics.drawString(
|
||||||
|
font,
|
||||||
|
Component.translatable(type.translatableKey).getString(),
|
||||||
|
ammoX + 35,
|
||||||
|
h + yOffset,
|
||||||
|
fontColor,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药盒信息渲染
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, ammoBoxTimer.lerp(0, 1, currentTime));
|
||||||
|
var ammoBoxX = ammoBoxTimer.lerp(-30, (float) w / 2, currentTime);
|
||||||
|
|
||||||
|
int ammoBoxAdd = Integer.compare(boxAmmoCount, boxAnimator.oldValue());
|
||||||
|
boxAnimator.compareAndUpdate(boxAmmoCount, () -> boxAnimator.beginForward(currentTime));
|
||||||
|
|
||||||
|
// 选中时显示为黄色,否则为白色
|
||||||
|
var targetColor = boxAmmoSelected ? 0xFFFFFF00 : 0xFFFFFFFF;
|
||||||
|
|
||||||
|
var boxFontColor = FastColor.ARGB32.lerp(boxAnimator.getProgress(currentTime),
|
||||||
|
switch (ammoBoxAdd) {
|
||||||
|
case 1 -> 0xFF00FF00;
|
||||||
|
case -1 -> 0xFFFF0000;
|
||||||
|
default -> targetColor;
|
||||||
|
},
|
||||||
|
targetColor
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药盒内弹药数量
|
||||||
|
guiGraphics.drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
Integer.toString(
|
||||||
|
Math.round(boxAnimator.lerp(boxAnimator.oldValue(), boxAmmoCount, currentTime))
|
||||||
|
),
|
||||||
|
ammoBoxX - 70,
|
||||||
|
h + yOffset,
|
||||||
|
boxFontColor,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
yOffset += fontHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, 1);
|
||||||
|
poseStack.popPose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,18 +4,20 @@ import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||||
import com.atsuishio.superbwarfare.init.ModTags;
|
import com.atsuishio.superbwarfare.init.ModTags;
|
||||||
import com.atsuishio.superbwarfare.tools.NBTTool;
|
import com.atsuishio.superbwarfare.tools.NBTTool;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
import net.minecraft.client.gui.LayeredDraw;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
|
||||||
import net.neoforged.neoforge.client.event.RenderGuiEvent;
|
|
||||||
|
|
||||||
@EventBusSubscriber(value = Dist.CLIENT)
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
public class ArmorPlateOverlay {
|
|
||||||
|
|
||||||
|
public class ArmorPlateOverlay implements LayeredDraw.Layer {
|
||||||
|
public static final ResourceLocation ID = Mod.loc("armor_plate");
|
||||||
|
|
||||||
private static final ResourceLocation ICON = Mod.loc("textures/screens/armor_plate_icon.png");
|
private static final ResourceLocation ICON = Mod.loc("textures/screens/armor_plate_icon.png");
|
||||||
private static final ResourceLocation LEVEL1 = Mod.loc("textures/screens/armor_plate_level1.png");
|
private static final ResourceLocation LEVEL1 = Mod.loc("textures/screens/armor_plate_level1.png");
|
||||||
|
@ -25,12 +27,12 @@ public class ArmorPlateOverlay {
|
||||||
private static final ResourceLocation LEVEL2_FRAME = Mod.loc("textures/screens/armor_plate_level2_frame.png");
|
private static final ResourceLocation LEVEL2_FRAME = Mod.loc("textures/screens/armor_plate_level2_frame.png");
|
||||||
private static final ResourceLocation LEVEL3_FRAME = Mod.loc("textures/screens/armor_plate_level3_frame.png");
|
private static final ResourceLocation LEVEL3_FRAME = Mod.loc("textures/screens/armor_plate_level3_frame.png");
|
||||||
|
|
||||||
@SubscribeEvent
|
@Override
|
||||||
public static void onRenderGui(RenderGuiEvent.Pre event) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public void render(GuiGraphics guiGraphics, DeltaTracker deltaTracker) {
|
||||||
if (!DisplayConfig.ARMOR_PLATE_HUD.get()) return;
|
if (!DisplayConfig.ARMOR_PLATE_HUD.get()) return;
|
||||||
|
|
||||||
var gui = event.getGuiGraphics();
|
int h = guiGraphics.guiHeight();
|
||||||
int h = gui.guiHeight();
|
|
||||||
|
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
|
@ -63,16 +65,16 @@ public class ArmorPlateOverlay {
|
||||||
|
|
||||||
int length = armorLevel * 30;
|
int length = armorLevel * 30;
|
||||||
|
|
||||||
gui.pose().pushPose();
|
guiGraphics.pose().pushPose();
|
||||||
// 渲染图标
|
// 渲染图标
|
||||||
gui.blit(ICON, 10, h - 13, 0, 0, 8, 8, 8, 8);
|
guiGraphics.blit(ICON, 10, h - 13, 0, 0, 8, 8, 8, 8);
|
||||||
|
|
||||||
// 渲染框架
|
// 渲染框架
|
||||||
gui.blit(frame, 20, h - 12, 0, 0, length, 6, length, 6);
|
guiGraphics.blit(frame, 20, h - 12, 0, 0, length, 6, length, 6);
|
||||||
|
|
||||||
// 渲染盔甲值
|
// 渲染盔甲值
|
||||||
gui.blit(texture, 20, h - 12, 0, 0, (int) amount, 6, length, 6);
|
guiGraphics.blit(texture, 20, h - 12, 0, 0, (int) amount, 6, length, 6);
|
||||||
|
|
||||||
gui.pose().popPose();
|
guiGraphics.pose().popPose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ public class ArmorPlate extends Item {
|
||||||
armorLevel = 3;
|
armorLevel = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 解决数据双端同步问题
|
|
||||||
if (NBTTool.getTag(armor).getDouble("ArmorPlate") < armorLevel * 15) {
|
if (NBTTool.getTag(armor).getDouble("ArmorPlate") < armorLevel * 15) {
|
||||||
playerIn.startUsingItem(handIn);
|
playerIn.startUsingItem(handIn);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +78,9 @@ public class ArmorPlate extends Item {
|
||||||
armorLevel = 3;
|
armorLevel = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
NBTTool.getTag(armor).putDouble("ArmorPlate", Mth.clamp(NBTTool.getTag(armor).getDouble("ArmorPlate") + 15, 0, armorLevel * 15));
|
var tag = NBTTool.getTag(armor);
|
||||||
|
tag.putDouble("ArmorPlate", Mth.clamp(tag.getDouble("ArmorPlate") + 15, 0, armorLevel * 15));
|
||||||
|
NBTTool.saveTag(armor, tag);
|
||||||
|
|
||||||
if (pLivingEntity instanceof ServerPlayer serverPlayer) {
|
if (pLivingEntity instanceof ServerPlayer serverPlayer) {
|
||||||
serverPlayer.level().playSound((Entity) null, serverPlayer.getOnPos(), SoundEvents.ARMOR_EQUIP_IRON.value(), SoundSource.PLAYERS, 0.5f, 1);
|
serverPlayer.level().playSound((Entity) null, serverPlayer.getOnPos(), SoundEvents.ARMOR_EQUIP_IRON.value(), SoundSource.PLAYERS, 0.5f, 1);
|
||||||
|
|
Loading…
Add table
Reference in a new issue