implement trade x

This commit is contained in:
trunksbomb
2026-03-25 02:00:28 -04:00
parent 2c157be8cb
commit ebce4e852d

View File

@@ -12,6 +12,7 @@ import java.util.List;
import java.util.UUID;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
@@ -47,7 +48,11 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
private static final int DEBUG_BUTTON_HEIGHT = 20;
private static final int DEBUG_BUTTON_GAP = 4;
private static final int DEBUG_SMALL_BUTTON_WIDTH = 41;
private static final int AMOUNT_PROMPT_WIDTH = 90;
private static final int AMOUNT_PROMPT_HEIGHT = 44;
private ContextMenu contextMenu;
private EditBox amountInput;
private AmountPrompt amountPrompt;
public TradeScreen(TradeMenu menu, Inventory inventory, Component title) {
super(menu, inventory, title);
@@ -70,6 +75,12 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
super.init();
titleLabelX = BANNER_X;
titleLabelY = BANNER_Y;
amountInput = new EditBox(font, leftPos + 0, topPos + 0, 54, 14, Component.literal("Trade Amount"));
amountInput.setVisible(false);
amountInput.setCanLoseFocus(false);
amountInput.setMaxLength(3);
amountInput.setFilter(value -> value.isEmpty() || value.chars().allMatch(Character::isDigit));
addRenderableWidget(amountInput);
addRenderableWidget(Button.builder(Component.literal("Accept"), button -> sendAction(TradeAction.ACCEPT, -1, 1))
.bounds(leftPos + CENTER_COLUMN_X + 3, topPos + ACCEPT_BUTTON_Y, ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT)
@@ -110,6 +121,19 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (amountPrompt != null) {
if (keyCode == 256) {
closeAmountPrompt();
return true;
}
if (keyCode == 257 || keyCode == 335) {
submitAmountPrompt();
return true;
}
if (amountInput != null && amountInput.keyPressed(keyCode, scanCode, modifiers)) {
return true;
}
}
if (minecraft != null && minecraft.options.keyInventory.matches(keyCode, scanCode)) {
onClose();
return true;
@@ -130,6 +154,17 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (amountPrompt != null) {
if (isInsideAmountPrompt(mouseX, mouseY)) {
if (amountInput != null && amountInput.mouseClicked(mouseX, mouseY, button)) {
return true;
}
return true;
}
closeAmountPrompt();
return true;
}
if (contextMenu != null) {
if (handleContextMenuClick(mouseX, mouseY)) {
return true;
@@ -197,6 +232,7 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
super.render(guiGraphics, mouseX, mouseY, partialTick);
renderContextMenu(guiGraphics, mouseX, mouseY);
renderAmountPrompt(guiGraphics);
renderTooltip(guiGraphics, mouseX, mouseY);
}
@@ -274,9 +310,7 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
ContextOption option = contextMenu.options().get(index);
if (option.amount() < 0) {
if (minecraft != null && minecraft.player != null) {
minecraft.player.displayClientMessage(Component.literal(option.label() + " is not implemented yet."), true);
}
openAmountPrompt(contextMenu.action(), contextMenu.slot(), contextMenu.mouseX(), contextMenu.mouseY());
} else {
sendAction(contextMenu.action(), contextMenu.slot(), option.amount());
}
@@ -314,6 +348,84 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
pose.popPose();
}
private void openAmountPrompt(TradeAction action, int slot, int mouseX, int mouseY) {
amountPrompt = new AmountPrompt(action, slot, mouseX, mouseY);
if (amountInput != null) {
amountInput.setValue("");
amountInput.setFocused(true);
amountInput.setVisible(true);
setFocused(amountInput);
}
}
private void submitAmountPrompt() {
if (amountPrompt == null || amountInput == null) {
return;
}
String value = amountInput.getValue().trim();
if (value.isEmpty()) {
return;
}
try {
int amount = Integer.parseInt(value);
if (amount > 0) {
sendAction(amountPrompt.action(), amountPrompt.slot(), amount);
closeAmountPrompt();
}
} catch (NumberFormatException ignored) {
// Filter should prevent this, but ignore invalid input safely.
}
}
private void closeAmountPrompt() {
amountPrompt = null;
if (amountInput != null) {
amountInput.setValue("");
amountInput.setFocused(false);
amountInput.setVisible(false);
}
setFocused(null);
}
private void renderAmountPrompt(GuiGraphics guiGraphics) {
if (amountPrompt == null || amountInput == null) {
return;
}
var pose = guiGraphics.pose();
pose.pushPose();
pose.translate(0.0F, 0.0F, 450.0F);
int promptX = amountPromptX();
int promptY = amountPromptY();
guiGraphics.fill(promptX, promptY, promptX + AMOUNT_PROMPT_WIDTH, promptY + AMOUNT_PROMPT_HEIGHT, 0xF0101010);
guiGraphics.fill(promptX + 1, promptY + 1, promptX + AMOUNT_PROMPT_WIDTH - 1, promptY + AMOUNT_PROMPT_HEIGHT - 1, 0xFF2B2B2B);
guiGraphics.drawString(font, amountPrompt.action() == TradeAction.ADD_ITEM ? "Trade amount" : "Remove amount", promptX + 6, promptY + 6, 0xFFFFFF, false);
guiGraphics.drawString(font, "Enter to confirm", promptX + 6, promptY + 30, 0xAAAAAA, false);
amountInput.setPosition(promptX + 6, promptY + 16);
amountInput.render(guiGraphics, 0, 0, 0.0F);
pose.popPose();
}
private boolean isInsideAmountPrompt(double mouseX, double mouseY) {
int promptX = amountPromptX();
int promptY = amountPromptY();
return mouseX >= promptX && mouseX < promptX + AMOUNT_PROMPT_WIDTH && mouseY >= promptY && mouseY < promptY + AMOUNT_PROMPT_HEIGHT;
}
private int amountPromptX() {
int preferredX = amountPrompt == null ? leftPos + 8 : Math.min(amountPrompt.mouseX(), this.width - AMOUNT_PROMPT_WIDTH - 4);
return Math.max(4, preferredX);
}
private int amountPromptY() {
int preferredY = amountPrompt == null ? topPos + 8 : Math.min(amountPrompt.mouseY(), this.height - AMOUNT_PROMPT_HEIGHT - 4);
return Math.max(4, preferredY);
}
private int contextMenuX() {
int width = contextMenuWidth();
return Math.min(contextMenu.mouseX(), this.width - width - 4);
@@ -349,6 +461,8 @@ public class TradeScreen extends AbstractContainerScreen<TradeScreen.TradeMenu>
private record ContextOption(String label, int amount) {}
private record AmountPrompt(TradeAction action, int slot, int mouseX, int mouseY) {}
public static class TradeMenu extends AbstractContainerMenu {
private static final int OFFER_COLUMNS = 6;
private static final int OFFER_ROWS = 6;