better messages

This commit is contained in:
seb
2026-04-27 23:32:00 +02:00
parent cf1a069675
commit 2504f5405d
4 changed files with 123 additions and 12 deletions

View File

@@ -24,7 +24,8 @@ public class Configs implements IConfigHandler {
"Select buy/sell items with item frames (max. distance 3) with items nametagged \"buy\" or \"sell\"");
public static final ConfigBoolean GLASS_BLOCK = new ConfigBoolean("selectUsingGlassBlock", false,
"Select input and output containers by placing red (input) and blue (output) stained glass blocks <selectionBlockOffset> blocks above them (or below if negative)");
public static final ConfigInteger SELECTOR_OFFSET = new ConfigInteger("selectionBlockOffset", 3, -10, 10, "");
public static final ConfigInteger SELECTOR_OFFSET = new ConfigInteger("selectionBlockOffset", 3, -10, 10,
"x Blocks below a red stained glass block will be input container, x Blocks below a blue stained glass block will be output container (or above, if x is negative)");
public static final ConfigBoolean ENABLE_SELL = new ConfigBoolean("enableSell", false,
"Enable selling (if disabled emeralds are taken from the input container)");
public static final ConfigString SELL_ITEM = new ConfigString("sellItem", "minecraft:gold_ingot",
@@ -37,7 +38,7 @@ public class Configs implements IConfigHandler {
"The item to buy using emerald. Optional suffix #enc1=lv&enc2=lv matches exact enchantments (use set-buy hotkey with the book in hand).");
public static final ConfigInteger BUY_LIMIT = new ConfigInteger("buyLimit", 64, 1, 64, "max price to buy for");
public static final ConfigInteger MAX_INPUT_ITEMS = new ConfigInteger("maxInputStacks", 9, 1, 35,
"stacks to take from input container (or emerald container in buy-only mode)");
"stacks to take from input container (or emerald container in buy-only mode), also the max amount of input and emerald kept.");
public static final ConfigInteger INPUT_CONTAINER_X = new ConfigInteger("inputContainerX", 0, -30000000,
30000000, "Input container X (not used when sell disabled)");
public static final ConfigInteger INPUT_CONTAINER_Y = new ConfigInteger("inputContainerY", 0, -64, 320,

View File

@@ -270,6 +270,8 @@ final class AutoTradeClientTick {
menu.setSelectionHint(i);
mc.player.connection.send(new ServerboundSelectTradePacket(i));
AutoTrade.bought += offer.getMaxUses();
InfoUtils.showGuiOrInGameMessage(Message.MessageType.INFO, "autotrade.message.trade_bought",
formatItemCountAndName(offer.getResult()), formatOfferPrice(offer));
try {
ContainerIoHelper.quickMoveResultSlot(mc, menu, slot.index);
} catch (Exception e) {
@@ -283,6 +285,9 @@ final class AutoTradeClientTick {
menu.setSelectionHint(i);
AutoTrade.sold += offer.getMaxUses();
mc.player.connection.send(new ServerboundSelectTradePacket(i));
InfoUtils.showGuiOrInGameMessage(Message.MessageType.INFO, "autotrade.message.trade_sold",
formatItemCountAndName(offer.getCostA()) + formatOptionalSecondCost(offer),
formatItemCountAndName(offer.getResult()));
try {
ContainerIoHelper.quickMoveResultSlot(mc, menu, slot.index);
} catch (Exception e) {
@@ -293,4 +298,27 @@ final class AutoTradeClientTick {
}
screen.onClose();
}
/** e.g. "3× Book" */
private static String formatItemCountAndName(ItemStack stack) {
return stack.getCount() + "× " + stack.getHoverName().getString();
}
/** For buying: the stacks you pay (first + optional second slot). */
private static String formatOfferPrice(MerchantOffer offer) {
String a = offer.getCostA().isEmpty() ? null : formatItemCountAndName(offer.getCostA());
if (offer.getCostB().isEmpty()) {
return a != null ? a : "";
}
String b = formatItemCountAndName(offer.getCostB());
return a == null ? b : a + " + " + b;
}
/** If the trade has a second input item, show it with " + " */
private static String formatOptionalSecondCost(MerchantOffer offer) {
if (offer.getCostB().isEmpty()) {
return "";
}
return " + " + formatItemCountAndName(offer.getCostB());
}
}

View File

@@ -2,11 +2,14 @@ package com.github.sebseb7.autotrade.event;
import com.github.sebseb7.autotrade.config.Configs;
import com.github.sebseb7.autotrade.util.TradeItemSpec;
import fi.dy.masa.malilib.gui.Message;
import fi.dy.masa.malilib.util.InfoUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerInput;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
final class ContainerIoHelper {
private ContainerIoHelper() {
@@ -17,28 +20,38 @@ final class ContainerIoHelper {
mc.gameMode.handleContainerInput(menu.containerId, slot.index, 0, ContainerInput.QUICK_MOVE, mc.player);
}
private static final String EMERALD_SPEC = "minecraft:emerald";
static void processOutput(AbstractContainerMenu menu, Inventory playerInv) {
String itemToPlace = "minecraft:emerald";
if (Configs.Generic.ENABLE_BUY.getBooleanValue()) {
itemToPlace = Configs.Generic.BUY_ITEM.getStringValue();
}
Minecraft mc = Minecraft.getInstance();
for (int i = 0; i < menu.slots.size(); i++) {
Slot s = menu.getSlot(i);
if (s.container == playerInv) {
if (TradeItemSpec.matches(s.getItem(), itemToPlace)) {
int maxKeep = Configs.Generic.MAX_INPUT_ITEMS.getIntegerValue() * 64;
if (Configs.Generic.ENABLE_BUY.getBooleanValue()) {
String buySpec = Configs.Generic.BUY_ITEM.getStringValue();
for (int i = 0; i < menu.slots.size(); i++) {
Slot s = menu.getSlot(i);
if (s.container == playerInv && TradeItemSpec.matches(s.getItem(), buySpec)) {
ItemStack stack = s.getItem();
if (stack.isEmpty()) {
continue;
}
try {
quickMoveResultSlot(mc, menu, i);
InfoUtils.showGuiOrInGameMessage(Message.MessageType.INFO,
"autotrade.message.moved_bought_to_output", formatStackForMessage(stack));
} catch (Exception e) {
System.out.println("err " + e);
}
}
}
}
quickMovePlayerExcessOverCap(mc, menu, playerInv, EMERALD_SPEC, maxKeep);
if (Configs.Generic.ENABLE_SELL.getBooleanValue()) {
quickMovePlayerExcessOverCap(mc, menu, playerInv, Configs.Generic.SELL_ITEM.getStringValue(), maxKeep);
}
}
static void processInput(AbstractContainerMenu menu, Inventory playerInv) {
String itemToTake = "minecraft:emerald";
String itemToTake = EMERALD_SPEC;
if (Configs.Generic.ENABLE_SELL.getBooleanValue()) {
itemToTake = Configs.Generic.SELL_ITEM.getStringValue();
}
@@ -58,8 +71,14 @@ final class ContainerIoHelper {
if (TradeItemSpec.matches(s.getItem(), itemToTake)) {
if (inputCount < (Configs.Generic.MAX_INPUT_ITEMS.getIntegerValue() * 64)) {
inputCount += s.getItem().getCount();
ItemStack stack = s.getItem();
if (stack.isEmpty()) {
continue;
}
try {
quickMoveResultSlot(mc, menu, i);
InfoUtils.showGuiOrInGameMessage(Message.MessageType.INFO, "autotrade.message.moved_from_input",
formatStackForMessage(stack));
} catch (Exception e) {
System.out.println("err " + e);
}
@@ -67,4 +86,60 @@ final class ContainerIoHelper {
}
}
}
private static int countMatchingOnPlayer(AbstractContainerMenu menu, Inventory playerInv, String spec) {
int n = 0;
for (int i = 0; i < menu.slots.size(); i++) {
Slot s = menu.getSlot(i);
if (s.container == playerInv && TradeItemSpec.matches(s.getItem(), spec)) {
n += s.getItem().getCount();
}
}
return n;
}
/**
* Quick-move player stacks until at most {@code maxKeep} matching items remain
* (same cap as processInput).
*/
private static void quickMovePlayerExcessOverCap(Minecraft mc, AbstractContainerMenu menu, Inventory playerInv,
String spec, int maxKeep) {
while (true) {
int before = countMatchingOnPlayer(menu, playerInv, spec);
if (before <= maxKeep) {
break;
}
boolean moved = false;
for (int i = 0; i < menu.slots.size(); i++) {
Slot s = menu.getSlot(i);
if (s.container != playerInv || !TradeItemSpec.matches(s.getItem(), spec)) {
continue;
}
ItemStack stack = s.getItem();
if (stack.isEmpty()) {
continue;
}
try {
quickMoveResultSlot(mc, menu, i);
InfoUtils.showGuiOrInGameMessage(Message.MessageType.INFO,
"autotrade.message.moved_excess_to_output", formatStackForMessage(stack));
} catch (Exception e) {
System.out.println("err " + e);
}
moved = true;
break;
}
if (!moved) {
break;
}
int after = countMatchingOnPlayer(menu, playerInv, spec);
if (after >= before) {
break;
}
}
}
private static String formatStackForMessage(ItemStack stack) {
return stack.getCount() + "× " + stack.getHoverName().getString();
}
}

View File

@@ -11,5 +11,12 @@
"autotrade.message.sell_item_set": "Item to sell: %s",
"autotrade.message.buy_item_set": "Item to buy: %s",
"autotrade.message.input_container_set": "Input Container now at: %d %d %d",
"autotrade.message.output_container_set": "Output Container now at: %d %d %d"
"autotrade.message.output_container_set": "Output Container now at: %d %d %d",
"autotrade.message.trade_bought": "Bought %s (price: %s)",
"autotrade.message.trade_sold": "Sold %s for %s",
"autotrade.message.moved_bought_to_output": "To output: moved %s from player",
"autotrade.message.moved_excess_to_output": "To output: moved excess %s",
"autotrade.message.moved_from_input": "To inventory: took %s from input"
}