From fc1973f596d79d093335cdcaca5319176126501d Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Sat, 12 Jul 2025 01:18:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8C=87=E7=A4=BA=E5=99=A8gu?= =?UTF-8?q?i?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screens/ArtilleryIndicatorScreen.java | 225 ++++++++++++++++++ .../item/ArtilleryIndicator.java | 58 ++--- .../send/FiringParametersEditMessage.java | 2 +- 3 files changed, 246 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/client/screens/ArtilleryIndicatorScreen.java diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/ArtilleryIndicatorScreen.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/ArtilleryIndicatorScreen.java new file mode 100644 index 000000000..98b2a8147 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/ArtilleryIndicatorScreen.java @@ -0,0 +1,225 @@ +package com.atsuishio.superbwarfare.client.screens; + +import com.atsuishio.superbwarfare.Mod; +import com.atsuishio.superbwarfare.component.ModDataComponents; +import com.atsuishio.superbwarfare.network.message.send.FiringParametersEditMessage; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.Renderable; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.network.PacketDistributor; +import org.jetbrains.annotations.NotNull; + +@OnlyIn(Dist.CLIENT) +public class ArtilleryIndicatorScreen extends Screen { + + private static final ResourceLocation TEXTURE = Mod.loc("textures/gui/artillery_indicator.png"); + + private final ItemStack stack; + private final InteractionHand hand; + + public EditBox posX; + public EditBox posY; + public EditBox posZ; + public EditBox radius; + + public boolean isDepressed; + + private boolean init = false; + + protected int imageWidth = 176; + protected int imageHeight = 84; + + public ArtilleryIndicatorScreen(ItemStack stack, InteractionHand hand) { + super(Component.translatable("item.superbwarfare.artillery_indicator")); + this.stack = stack; + this.hand = hand; + if (!stack.isEmpty()) { + var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); + this.isDepressed = parameters != null && parameters.isDepressed(); + } + } + + @Override + public void tick() { + super.tick(); + if (!this.init) { + if (!this.stack.isEmpty()) { + var parameters = stack.get(ModDataComponents.FIRING_PARAMETERS); + if (parameters != null) { + var pos = parameters.pos(); + this.posX.setValue("" + pos.getX()); + this.posY.setValue("" + pos.getY()); + this.posZ.setValue("" + pos.getZ()); + this.radius.setValue("" + Math.max(0, parameters.radius())); + } else { + this.posX.setValue("0"); + this.posY.setValue("0"); + this.posZ.setValue("0"); + this.radius.setValue("0"); + } + } + this.init = true; + } + } + + @Override + public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { + this.renderBackground(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + this.renderBg(pGuiGraphics, pMouseX, pMouseY); + for (Renderable renderable : this.renderables) { + renderable.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + } + this.renderPositions(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + } + + protected void renderPositions(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { + var poseStack = pGuiGraphics.pose(); + + poseStack.pushPose(); + + this.posX.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + this.posY.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + this.posZ.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + this.radius.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + + poseStack.popPose(); + } + + protected void renderBg(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) { + int i = (this.width - this.imageWidth) / 2; + int j = (this.height - this.imageHeight) / 2; + pGuiGraphics.blit(TEXTURE, i, j, 0, 0, this.imageWidth, this.imageHeight, 256, 256); + + if (pMouseX >= i + 98 && pMouseX <= i + 162 && pMouseY >= j + 19 && pMouseY <= j + 49) { + pGuiGraphics.renderTooltip(this.font, + this.isDepressed ? + Component.translatable("tips.superbwarfare.mortar.target_pos.depressed_trajectory").withStyle(ChatFormatting.WHITE) : + Component.translatable("tips.superbwarfare.mortar.target_pos.lofted_trajectory").withStyle(ChatFormatting.WHITE), + pMouseX, pMouseY); + } + + pGuiGraphics.drawString(this.font, this.title, i + 6, j + 6, 4210752, false); + } + + @Override + protected void init() { + super.init(); + this.subInit(); + + int i = (this.width - this.imageWidth) / 2; + int j = (this.height - this.imageHeight) / 2; + + var modeButton = new ModeButton(i + 99, j + 19, 64, 30); + this.addRenderableWidget(modeButton); + + var doneButton = new DoneButton(i + 113, j + 54, 48, 15); + this.addRenderableWidget(doneButton); + } + + protected void subInit() { + int i = (this.width - this.imageWidth) / 2; + int j = (this.height - this.imageHeight) / 2; + + this.posX = new EditBox(this.font, i + 24, j + 20, 40, 12, Component.empty()); + this.initEditBox(this.posX); + + this.posY = new EditBox(this.font, i + 24, j + 33, 40, 12, Component.empty()); + this.initEditBox(this.posY); + + this.posZ = new EditBox(this.font, i + 24, j + 46, 40, 12, Component.empty()); + this.initEditBox(this.posZ); + + this.radius = new EditBox(this.font, i + 24, j + 59, 40, 12, Component.empty()); + this.initEditBox(this.radius); + this.radius.setFilter(s -> s.matches("\\d*")); + } + + protected void initEditBox(EditBox editBox) { + editBox.setCanLoseFocus(true); + editBox.setTextColor(-1); + editBox.setTextColorUneditable(-1); + editBox.setBordered(false); + editBox.setMaxLength(10); + this.addWidget(editBox); + editBox.setEditable(true); + editBox.setFilter(s -> s.matches("-?\\d*")); + } + + @OnlyIn(Dist.CLIENT) + class ModeButton extends AbstractButton { + + public ModeButton(int pX, int pY, int pWidth, int pHeight) { + super(pX, pY, pWidth, pHeight, Component.empty()); + } + + @Override + public void onPress() { + ArtilleryIndicatorScreen.this.isDepressed = !ArtilleryIndicatorScreen.this.isDepressed; + } + + @Override + protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { + boolean isDepressed = ArtilleryIndicatorScreen.this.isDepressed; + pGuiGraphics.blit(TEXTURE, this.getX(), isDepressed ? this.getY() + 14 : this.getY(), 177, isDepressed ? 62 : 33, + 61, isDepressed ? 14 : 28, 256, 256); + } + + @Override + protected void updateWidgetNarration(@NotNull NarrationElementOutput pNarrationElementOutput) { + } + } + + @OnlyIn(Dist.CLIENT) + class DoneButton extends AbstractButton { + + public DoneButton(int pX, int pY, int pWidth, int pHeight) { + super(pX, pY, pWidth, pHeight, Component.empty()); + } + + @Override + public void onPress() { + if (!ArtilleryIndicatorScreen.this.init) return; + if (ArtilleryIndicatorScreen.this.minecraft != null) { + ArtilleryIndicatorScreen.this.minecraft.setScreen(null); + } + PacketDistributor.sendToServer( + new FiringParametersEditMessage( + getEditBoxValue(ArtilleryIndicatorScreen.this.posX.getValue()), + getEditBoxValue(ArtilleryIndicatorScreen.this.posY.getValue()), + getEditBoxValue(ArtilleryIndicatorScreen.this.posZ.getValue()), + Math.max(0, getEditBoxValue(ArtilleryIndicatorScreen.this.radius.getValue())), + ArtilleryIndicatorScreen.this.isDepressed, + ArtilleryIndicatorScreen.this.hand == InteractionHand.MAIN_HAND + ) + ); + } + + @Override + protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { + pGuiGraphics.blit(TEXTURE, this.getX(), this.getY(), 177, this.isHovered ? 16 : 0, 48, 15, 256, 256); + } + + @Override + protected void updateWidgetNarration(@NotNull NarrationElementOutput pNarrationElementOutput) { + } + + public int getEditBoxValue(String value) { + if (value.equals("-")) return 0; + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return 0; + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/item/ArtilleryIndicator.java b/src/main/java/com/atsuishio/superbwarfare/item/ArtilleryIndicator.java index a0078823f..3820b0708 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/ArtilleryIndicator.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/ArtilleryIndicator.java @@ -1,26 +1,30 @@ package com.atsuishio.superbwarfare.item; +import com.atsuishio.superbwarfare.client.TooltipTool; +import com.atsuishio.superbwarfare.client.screens.ArtilleryIndicatorScreen; import com.atsuishio.superbwarfare.tools.NBTTool; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.UseAnim; +import net.minecraft.world.item.*; import net.minecraft.world.level.Level; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; import java.util.List; -public class ArtilleryIndicator extends Item { +public class ArtilleryIndicator extends Item implements ItemScreenProvider { public static final String TAG_CANNON = "Cannons"; @@ -28,6 +32,12 @@ public class ArtilleryIndicator extends Item { super(new Properties().stacksTo(1).rarity(Rarity.UNCOMMON)); } + @Override + @ParametersAreNonnullByDefault + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + TooltipTool.addScreenProviderText(tooltipComponents); + } + @Override @ParametersAreNonnullByDefault public int getUseDuration(ItemStack stack, LivingEntity entity) { @@ -110,37 +120,9 @@ public class ArtilleryIndicator extends Item { return flag; } -// @Override -// @ParametersAreNonnullByDefault -// public @NotNull InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { -// if (!player.isCrouching()) return InteractionResultHolder.pass(player.getItemInHand(usedHand)); -// -// var stack = player.getItemInHand(usedHand); -// var isDepressed = !stack.getOrCreateTag().getBoolean("IsDepressed"); -// -// stack.getOrCreateTag().putBoolean("IsDepressed", isDepressed); -// -// player.displayClientMessage(Component.translatable( -// isDepressed -// ? "tips.superbwarfare.mortar.target_pos.depressed_trajectory" -// : "tips.superbwarfare.mortar.target_pos.lofted_trajectory" -// ).withStyle(ChatFormatting.GREEN), true); -// -// return InteractionResultHolder.success(stack); -// } -// -// @Override -// public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List pTooltipComponents, TooltipFlag pIsAdvanced) { -// pTooltipComponents.add(Component.translatable("tips.superbwarfare.mortar.target_pos").withStyle(ChatFormatting.GRAY) -// .append(Component.literal("[" + pStack.getOrCreateTag().getInt("TargetX") -// + "," + pStack.getOrCreateTag().getInt("TargetY") -// + "," + pStack.getOrCreateTag().getInt("TargetZ") + "]"))); -// -// -// pTooltipComponents.add(Component.translatable( -// pStack.getOrCreateTag().getBoolean("IsDepressed") -// ? "tips.superbwarfare.mortar.target_pos.depressed_trajectory" -// : "tips.superbwarfare.mortar.target_pos.lofted_trajectory" -// ).withStyle(ChatFormatting.GRAY)); -// } + @OnlyIn(Dist.CLIENT) + @Override + public @Nullable Screen getItemScreen(ItemStack stack, Player player, InteractionHand hand) { + return new ArtilleryIndicatorScreen(stack, hand); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/send/FiringParametersEditMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FiringParametersEditMessage.java index 39aa77987..4e7e2bbdc 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/send/FiringParametersEditMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/send/FiringParametersEditMessage.java @@ -33,7 +33,7 @@ public record FiringParametersEditMessage( var player = context.player(); ItemStack stack = message.mainHand ? player.getMainHandItem() : player.getOffhandItem(); - if (!stack.is(ModItems.FIRING_PARAMETERS.get())) return; + if (!stack.is(ModItems.FIRING_PARAMETERS.get()) || !stack.is(ModItems.ARTILLERY_INDICATOR.get())) return; var parameters = new FiringParameters.Parameters(new BlockPos(message.x, message.y, message.z), message.radius, message.isDepressed); stack.set(ModDataComponents.FIRING_PARAMETERS, parameters);