implement trade x
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user