From 78f6909ff08e269a9d325d8777729b5d835ba0af Mon Sep 17 00:00:00 2001 From: Martin Robertz Date: Tue, 7 Oct 2025 10:08:56 +0200 Subject: [PATCH 01/17] update --- dependencies.gradle | 16 ++++++++-------- settings.gradle.kts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index d4a2fbb..625bcb8 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -34,13 +34,13 @@ * For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph */ dependencies { - implementation("com.github.GTNewHorizons:NotEnoughItems:2.7.77-GTNH:dev") - implementation("com.github.GTNewHorizons:GTNHLib:0.6.39:dev") - compileOnly("com.github.GTNewHorizons:BetterQuesting:3.7.11-GTNH:dev") - implementation("com.github.GTNewHorizons:ModularUI2:2.2.18-1.7.10:dev") - // implementation("com.github.GTNewHorizons:ModularUI2:99.99:dev") - implementation("com.github.GTNewHorizons:StructureLib:1.4.18:dev") - implementation("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.440:dev") + implementation("com.github.GTNewHorizons:NotEnoughItems:2.8.6-GTNH:dev") + implementation("com.github.GTNewHorizons:GTNHLib:0.7.0:dev") + compileOnly("com.github.GTNewHorizons:BetterQuesting:3.8.4-GTNH:dev") + implementation("com.github.GTNewHorizons:ModularUI2:2.2.20-1.7.10:dev") + // implementation("com.github.GTNewHorizons:ModularUI2:2.2.20-1.7.10:dev") + implementation("com.github.GTNewHorizons:StructureLib:1.4.23:dev") + implementation("com.github.GTNewHorizons:GT5-Unofficial:5.09.52.19:dev") } // deps may transitively add Baubles, so we replace it @@ -49,7 +49,7 @@ project.getConfigurations() final DependencySubstitutions ds = c.getResolutionStrategy() .getDependencySubstitution() ds.substitute(ds.module("com.github.GTNewHorizons:Baubles")) - .using(ds.module("com.github.GTNewHorizons:Baubles-Expanded:2.1.9-GTNH")) + .using(ds.module("com.github.GTNewHorizons:Baubles-Expanded:2.2.0-GTNH")) .withClassifier("dev") .because("Baubles-Expanded replaces Baubles") }) diff --git a/settings.gradle.kts b/settings.gradle.kts index cbf0d00..0966c6f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,5 +17,5 @@ pluginManagement { } plugins { - id("com.gtnewhorizons.gtnhsettingsconvention") version("1.0.41") + id("com.gtnewhorizons.gtnhsettingsconvention") version("1.0.43") } From ee6c746eed123cf52d213094a9f33b6d0193b4b1 Mon Sep 17 00:00:00 2001 From: Ranzu <66495944+Ranzuu@users.noreply.github.com> Date: Tue, 7 Oct 2025 15:54:02 +0200 Subject: [PATCH 02/17] pixels --- .../vendingmachine/textures/gui/tabs_left.png | Bin 3140 -> 3188 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources/assets/vendingmachine/textures/gui/tabs_left.png b/src/main/resources/assets/vendingmachine/textures/gui/tabs_left.png index 0c532c63b880212a322cf41a264edf3881e04bc5..9e5b665373066bd798a762a156320dd830c46589 100644 GIT binary patch literal 3188 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 DUC74X literal 3140 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 From 32e7bd24f56b9917072c4dcda45ecf21510b3c7b Mon Sep 17 00:00:00 2001 From: cubefury Date: Tue, 7 Oct 2025 22:06:45 +0800 Subject: [PATCH 03/17] Fixed structurelib display and added hint for uplink hatch in tooltip --- .../blocks/MTEVendingMachine.java | 17 +++++++++++------ .../blocks/gui/MTEVendingMachineGui.java | 17 +++++++++++------ .../assets/vendingmachine/lang/en_US.lang | 1 + 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java index 54df808..a149496 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java @@ -5,6 +5,8 @@ import static com.cubefury.vendingmachine.api.enums.Textures.VM_MACHINE_FRONT_ON_GLOW; import static com.cubefury.vendingmachine.api.enums.Textures.VM_OVERLAY; import static com.cubefury.vendingmachine.api.enums.Textures.VM_OVERLAY_ACTIVE; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofChain; import static gregtech.api.util.GTStructureUtility.ofHatchAdderOptional; import java.util.ArrayList; @@ -79,12 +81,14 @@ public class MTEVendingMachine extends MTEMultiBlockBase .addShape("main", new String[][] { { "cc", "c~", "cc" } }) .addElement( 'c', - ofHatchAdderOptional( - MTEVendingMachine::addUplinkHatch, - ((BlockCasings11) GregTechAPI.sBlockCasings11).getTextureIndex(0), - 1, - GregTechAPI.sBlockCasings11, - 0)) + ofChain( + ofBlock(GregTechAPI.sBlockCasings11, 0), + ofHatchAdderOptional( + MTEVendingMachine::addUplinkHatch, + ((BlockCasings11) GregTechAPI.sBlockCasings11).getTextureIndex(0), + 1, + GregTechAPI.sBlockCasings11, + 0))) .build(); private final ArrayList uplinkHatches = new ArrayList<>(); @@ -359,6 +363,7 @@ protected MultiblockTooltipBuilder getTooltip() { .beginStructureBlock(2, 3, 1, false) .addController("Middle") .addOtherStructurePart("Tin Item Pipe Casings", "Everything except the controller") + .addOtherStructurePart("ME Vending Uplink Hatch", "Any Pipe Casing, Optional") .addStructureInfo("Cannot be flipped onto its side") .toolTipFinisher(); } diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java index 5fcfd38..47e9bdc 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java @@ -128,7 +128,7 @@ public ModularPanel build(PosGuiData guiData, PanelSyncManager syncManager, UISe panel.child( new Column().size(20) .right(5)); - panel.child(createIOColumn(syncManager)); + panel.child(createIOColumn()); return panel; } @@ -253,7 +253,7 @@ private void doEjectItems() { ejectItems = false; } - private IWidget createIOColumn(PanelSyncManager syncManager) { + private IWidget createIOColumn() { return new ParentWidget<>().excludeAreaInNEI() .width(50) .height(178) @@ -336,10 +336,14 @@ private SlotGroupWidget createOutputSlots() { return SlotGroupWidget.builder() .matrix("II", "II", "II") .key('I', index -> { - ModularSlot ms = new ModularSlot(base.outputItems, index).accessibility(false, true) - .slotGroup("outputSlotGroup"); - ms.changeListener((newItem, onlyAmountChanged, client, init) -> {}); - return new ItemSlot().slot(ms); + /* + * ModularSlot ms = new ModularSlot(base.outputItems, index).accessibility(false, true) + * .slotGroup("outputSlotGroup"); + */ + // ms.changeListener((newItem, onlyAmountChanged, client, init) -> {}); + return new ItemSlot().slot( + new ModularSlot(base.outputItems, index).accessibility(false, true) + .slotGroup("outputSlotGroup")); }) .build(); } @@ -388,6 +392,7 @@ private IWidget createTradeUI(TradeMainPanel rootPanel, PagedWidget.Controller t builder.emptyLine(); builder.addLine(IKey.str(cur.label).style(IKey.GRAY)); + builder.addLine(IKey.str(Translator.translate("vendingmachine.gui.trade_hint")).style(IKey.GRAY)); } } } diff --git a/src/main/resources/assets/vendingmachine/lang/en_US.lang b/src/main/resources/assets/vendingmachine/lang/en_US.lang index 70de284..58623e3 100644 --- a/src/main/resources/assets/vendingmachine/lang/en_US.lang +++ b/src/main/resources/assets/vendingmachine/lang/en_US.lang @@ -14,6 +14,7 @@ vendingmachine.gui.coin_eject=Eject All Coins vendingmachine.gui.single_coin_type_eject_hint=Shift-Click to Extract vendingmachine.gui.search=Search vendingmachine.gui.required_inputs=Requires: +vendingmachine.gui.trade_hint=Shift-Click to Purchase vendingmachine.gui.cooldown_display.second=s vendingmachine.gui.cooldown_display.minute=m From 04a55e5a721e0f3570f1cc5e97a222ab638476be Mon Sep 17 00:00:00 2001 From: cubefury Date: Tue, 7 Oct 2025 23:31:47 +0800 Subject: [PATCH 04/17] Cleaned up input/output slot method naming --- .../blocks/gui/MTEVendingMachineGui.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java index 47e9bdc..f2d80ad 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java @@ -268,7 +268,7 @@ private IWidget createIOColumn() { .width(30) .height(20)) .child( - new Row().child(createInputRow().center()) + new Row().child(createInputSlots().center()) .top(20) .height(18 * 3)) .child( @@ -299,7 +299,7 @@ private IWidget createIOColumn() { .right(1)); } - private SlotGroupWidget createInputRow() { + private SlotGroupWidget createInputSlots() { return SlotGroupWidget.builder() .matrix("II", "II", "II") .key('I', index -> { @@ -336,11 +336,6 @@ private SlotGroupWidget createOutputSlots() { return SlotGroupWidget.builder() .matrix("II", "II", "II") .key('I', index -> { - /* - * ModularSlot ms = new ModularSlot(base.outputItems, index).accessibility(false, true) - * .slotGroup("outputSlotGroup"); - */ - // ms.changeListener((newItem, onlyAmountChanged, client, init) -> {}); return new ItemSlot().slot( new ModularSlot(base.outputItems, index).accessibility(false, true) .slotGroup("outputSlotGroup")); @@ -493,8 +488,8 @@ private IWidget createInventoryRow() { @Override protected void registerSyncValues(PanelSyncManager syncManager) { super.registerSyncValues(syncManager); - syncManager.registerSlotGroup("inputSlotGroup", 6, true); - syncManager.registerSlotGroup("outputSlotGroup", 4, false); + syncManager.registerSlotGroup("inputSlotGroup", 2, true); + syncManager.registerSlotGroup("outputSlotGroup", 2, false); BooleanSyncValue ejectItemsSyncer = new BooleanSyncValue(() -> this.ejectItems, val -> { this.ejectItems = val; From 9a52adde08abd574b22353a41e2b17d80b469f16 Mon Sep 17 00:00:00 2001 From: cubefury Date: Wed, 8 Oct 2025 00:17:07 +0800 Subject: [PATCH 05/17] Fixed structure hint. --- .../cubefury/vendingmachine/blocks/MTEVendingMachine.java | 7 ++++--- src/main/resources/assets/vendingmachine/lang/en_US.lang | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java index a149496..41cdc09 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingMachine.java @@ -48,6 +48,7 @@ import com.cubefury.vendingmachine.trade.TradeRequest; import com.cubefury.vendingmachine.util.BigItemStack; import com.cubefury.vendingmachine.util.OverlayHelper; +import com.cubefury.vendingmachine.util.Translator; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; @@ -82,13 +83,13 @@ public class MTEVendingMachine extends MTEMultiBlockBase .addElement( 'c', ofChain( - ofBlock(GregTechAPI.sBlockCasings11, 0), ofHatchAdderOptional( MTEVendingMachine::addUplinkHatch, ((BlockCasings11) GregTechAPI.sBlockCasings11).getTextureIndex(0), 1, GregTechAPI.sBlockCasings11, - 0))) + 0), + ofBlock(GregTechAPI.sBlockCasings11, 0))) .build(); private final ArrayList uplinkHatches = new ArrayList<>(); @@ -347,7 +348,7 @@ public boolean getDefaultHasMaintenanceChecks() { @Override public String[] getStructureDescription(ItemStack stackSize) { - return getTooltip().getStructureHint(); + return new String[] { Translator.translate("structure.vendingmachine.hint.1") }; } @Override diff --git a/src/main/resources/assets/vendingmachine/lang/en_US.lang b/src/main/resources/assets/vendingmachine/lang/en_US.lang index 58623e3..9446c0b 100644 --- a/src/main/resources/assets/vendingmachine/lang/en_US.lang +++ b/src/main/resources/assets/vendingmachine/lang/en_US.lang @@ -2,6 +2,8 @@ item.vendingmachine.placeholder.name=Placeholder Item tooltip.vendingmachine=Who's even restocking this... +structure.vendingmachine.hint.1=Hint 1 Dot: Tin Item Pipe Casing, ME Vending Uplink Hatch + vendingmachine.gui.requirementHeader=Requirements: vendingmachine.gui.requirement.unknown=Unknown Requirement vendingmachine.gui.requirement.betterquesting=Quest From 9a7af7d0ade6a6760b5b43ae06ce18333f5adfa0 Mon Sep 17 00:00:00 2001 From: cubefury Date: Wed, 8 Oct 2025 00:45:08 +0800 Subject: [PATCH 06/17] Fix edge-case NPE on load when player attempts to load tradestate for a removed tradegroup. --- .../java/com/cubefury/vendingmachine/trade/TradeDatabase.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java b/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java index a6e669a..4d16562 100644 --- a/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java +++ b/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java @@ -126,7 +126,9 @@ public void populateTradeStateFromNBT(NBTTagCompound nbt, UUID player, boolean m UUID tgId = NBTConverter.UuidValueType.TRADEGROUP.readId(state); TradeGroup tg = TradeDatabase.INSTANCE.getTradeGroupFromId(tgId); TradeHistory th = new TradeHistory(state.getLong("lastTrade"), state.getInteger("tradeCount")); - tg.setTradeState(player, th); + if (tg != null) { + tg.setTradeState(player, th); + } } TradeManager.INSTANCE.populateCurrencyFromNBT(nbt, player, merge); } From d7ab8bb5cb7634337e7cb5046f74006afca7c250 Mon Sep 17 00:00:00 2001 From: Martin Robertz Date: Wed, 8 Oct 2025 08:33:00 +0200 Subject: [PATCH 07/17] update --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 625bcb8..9bd54c8 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -36,11 +36,11 @@ dependencies { implementation("com.github.GTNewHorizons:NotEnoughItems:2.8.6-GTNH:dev") implementation("com.github.GTNewHorizons:GTNHLib:0.7.0:dev") - compileOnly("com.github.GTNewHorizons:BetterQuesting:3.8.4-GTNH:dev") + compileOnly("com.github.GTNewHorizons:BetterQuesting:3.8.8-GTNH:dev") implementation("com.github.GTNewHorizons:ModularUI2:2.2.20-1.7.10:dev") // implementation("com.github.GTNewHorizons:ModularUI2:2.2.20-1.7.10:dev") implementation("com.github.GTNewHorizons:StructureLib:1.4.23:dev") - implementation("com.github.GTNewHorizons:GT5-Unofficial:5.09.52.19:dev") + implementation("com.github.GTNewHorizons:GT5-Unofficial:5.09.52.21:dev") } // deps may transitively add Baubles, so we replace it From e0646fb6c545568c0a7e87bd15e67b8f94b14879 Mon Sep 17 00:00:00 2001 From: Omgise <106000018+Omgise@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:44:57 +0800 Subject: [PATCH 08/17] Update zh_CN.lang --- .../assets/vendingmachine/lang/zh_CN.lang | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang index 2893c68..070ba55 100644 --- a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang +++ b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang @@ -2,6 +2,8 @@ item.vendingmachine.placeholder.name=占位符物品 tooltip.vendingmachine=到底是谁在补货啊... +structure.vendingmachine.hint.1=Hint 1 Dot: Tin Item Pipe Casing, ME Vending Uplink Hatch + vendingmachine.gui.requirementHeader=需求条件: vendingmachine.gui.requirement.unknown=未知需求 vendingmachine.gui.requirement.betterquesting=任务 @@ -10,15 +12,21 @@ vendingmachine.gui.neiColor.conditionDefault=000000 vendingmachine.gui.neiColor.conditionSatisfied=55D441 vendingmachine.gui.neiColor.conditionUnsatisfied=A87A5E vendingmachine.gui.item_eject=取出物品 +vendingmachine.gui.coin_eject=取出所有代币 +vendingmachine.gui.single_coin_type_eject_hint=Shift-点击提取 vendingmachine.gui.search=搜索 vendingmachine.gui.required_inputs=需要: +vendingmachine.gui.trade_hint=Shift-Click to Purchase vendingmachine.gui.cooldown_display.second=秒 vendingmachine.gui.cooldown_display.minute=分 vendingmachine.gui.cooldown_display.hour=时 vendingmachine.gui.cooldown_display.day=天 +vendingmachine.gui.error.player_using=当前有其他玩家正在使用此自动售货机 + gt.blockmachines.multimachine.vendingmachine.name=自动售货机 +hatch.vendinguplink.me.name=ME自动售货接入接口 vendingmachine.category.unknown=未知分类 vendingmachine.category.all=全部物品 @@ -29,3 +37,18 @@ vendingmachine.category.chemistry=化工 vendingmachine.category.magic=魔法 vendingmachine.category.bees=蜜蜂 vendingmachine.category.misc=杂项 + +vendingmachine.coin.adventure=探险家代币 +vendingmachine.coin.bees=养蜂员代币 +vendingmachine.coin.blood=吸血鬼代币 +vendingmachine.coin.chemist=化学家代币 +vendingmachine.coin.cook=厨师代币 +vendingmachine.coin.darkWizard=魔法师代币 +vendingmachine.coin.farmer=农民代币 +vendingmachine.coin.flower=园艺代币 +vendingmachine.coin.forestry=护林员代币 +vendingmachine.coin.smith=匠师代币 +vendingmachine.coin.space=太空代币 +vendingmachine.coin.survivor=幸存者代币 +vendingmachine.coin.technician=技术员代币 +vendingmachine.coin.witch=巫师代币 From e1f86c51dd68d5501453099392488a2c6c832df8 Mon Sep 17 00:00:00 2001 From: Omgise <106000018+Omgise@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:50:01 +0800 Subject: [PATCH 09/17] Update zh_CN.lang --- src/main/resources/assets/vendingmachine/lang/zh_CN.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang index 070ba55..dbbc6ac 100644 --- a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang +++ b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang @@ -2,7 +2,7 @@ item.vendingmachine.placeholder.name=占位符物品 tooltip.vendingmachine=到底是谁在补货啊... -structure.vendingmachine.hint.1=Hint 1 Dot: Tin Item Pipe Casing, ME Vending Uplink Hatch +structure.vendingmachine.hint.1=提示 1:锡质物品管道外壳,ME自动售货接入接口 vendingmachine.gui.requirementHeader=需求条件: vendingmachine.gui.requirement.unknown=未知需求 @@ -16,7 +16,7 @@ vendingmachine.gui.coin_eject=取出所有代币 vendingmachine.gui.single_coin_type_eject_hint=Shift-点击提取 vendingmachine.gui.search=搜索 vendingmachine.gui.required_inputs=需要: -vendingmachine.gui.trade_hint=Shift-Click to Purchase +vendingmachine.gui.trade_hint=Shift-点击购买 vendingmachine.gui.cooldown_display.second=秒 vendingmachine.gui.cooldown_display.minute=分 From 8f27d4cc60596f807f93d112d8bc34fddaf031fb Mon Sep 17 00:00:00 2001 From: Ranzu <66495944+Ranzuu@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:54:52 +0200 Subject: [PATCH 10/17] Separate Tile name and gui title --- .../vendingmachine/blocks/gui/MTEVendingMachineGui.java | 6 +++++- src/main/resources/assets/vendingmachine/lang/en_US.lang | 1 + src/main/resources/assets/vendingmachine/lang/zh_CN.lang | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java index f2d80ad..e3a7b50 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java @@ -118,7 +118,11 @@ public ModularPanel build(PosGuiData guiData, PanelSyncManager syncManager, UISe panel.child(createCategoryTabs(this.tabController)); Flow mainColumn = new Column().width(170); if (VendingMachine.proxy.isClient()) { // client side filtering - mainColumn.child(createTitleTextStyle(base.getLocalName())) + mainColumn.child( + createTitleTextStyle( + IKey.lang("gt.blockmachines.multimachine.vendingmachine.name.gui") + .style(IKey.DARK_GRAY) + .get())) .child(this.searchBar) .child(createTradeUI((TradeMainPanel) panel, this.tabController)); mainColumn.child(createCoinInventoryRow((TradeMainPanel) panel)); diff --git a/src/main/resources/assets/vendingmachine/lang/en_US.lang b/src/main/resources/assets/vendingmachine/lang/en_US.lang index 9446c0b..0583853 100644 --- a/src/main/resources/assets/vendingmachine/lang/en_US.lang +++ b/src/main/resources/assets/vendingmachine/lang/en_US.lang @@ -26,6 +26,7 @@ vendingmachine.gui.cooldown_display.day=d vendingmachine.gui.error.player_using=Someone is using the vending machine at the moment. gt.blockmachines.multimachine.vendingmachine.name=Vending Machine +gt.blockmachines.multimachine.vendingmachine.name.gui=Vending Machine hatch.vendinguplink.me.name=ME Vending Uplink Hatch vendingmachine.category.unknown=Unknown Category diff --git a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang index dbbc6ac..40f3eea 100644 --- a/src/main/resources/assets/vendingmachine/lang/zh_CN.lang +++ b/src/main/resources/assets/vendingmachine/lang/zh_CN.lang @@ -26,6 +26,7 @@ vendingmachine.gui.cooldown_display.day=天 vendingmachine.gui.error.player_using=当前有其他玩家正在使用此自动售货机 gt.blockmachines.multimachine.vendingmachine.name=自动售货机 +gt.blockmachines.multimachine.vendingmachine.name.gui=自动售货机 hatch.vendinguplink.me.name=ME自动售货接入接口 vendingmachine.category.unknown=未知分类 From d286e856c0dab1cd77ec92651702eb6d72ae2e96 Mon Sep 17 00:00:00 2001 From: Ranzu <66495944+Ranzuu@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:29:48 +0200 Subject: [PATCH 11/17] Localize the ME Vending Uplink Hatch Overlay --- .../vendingmachine/api/enums/Textures.java | 5 ++++- .../blocks/MTEVendingUplinkHatch.java | 8 ++++---- .../vending_uplink_machine_overlay_active.png | Bin 0 -> 426 bytes .../vending_uplink_machine_overlay_inactive.png | Bin 0 -> 429 bytes 4 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/assets/vendingmachine/textures/blocks/vending_uplink_machine_overlay_active.png create mode 100644 src/main/resources/assets/vendingmachine/textures/blocks/vending_uplink_machine_overlay_inactive.png diff --git a/src/main/java/com/cubefury/vendingmachine/api/enums/Textures.java b/src/main/java/com/cubefury/vendingmachine/api/enums/Textures.java index 13af61d..59354b4 100644 --- a/src/main/java/com/cubefury/vendingmachine/api/enums/Textures.java +++ b/src/main/java/com/cubefury/vendingmachine/api/enums/Textures.java @@ -18,7 +18,10 @@ public class Textures { VM_OVERLAY_ACTIVE_0 = new CustomIcon("vendingmachine:vending_machine_overlay_active_0"), VM_OVERLAY_ACTIVE_1 = new CustomIcon("vendingmachine:vending_machine_overlay_active_1"), VM_OVERLAY_ACTIVE_2 = new CustomIcon("vendingmachine:vending_machine_overlay_active_2"), - VM_OVERLAY_ACTIVE_3 = new CustomIcon("vendingmachine:vending_machine_overlay_active_3"); + VM_OVERLAY_ACTIVE_3 = new CustomIcon("vendingmachine:vending_machine_overlay_active_3"), + + VUPLINK_OVERLAY_0 = new CustomIcon("vendingmachine:vending_uplink_machine_overlay_inactive"), + VUPLINK_OVERLAY_1 = new CustomIcon("vendingmachine:vending_uplink_machine_overlay_active"); public static final IIconContainer[] VM_OVERLAY_ACTIVE = { VM_OVERLAY_ACTIVE_0, VM_OVERLAY_ACTIVE_1, VM_OVERLAY_ACTIVE_2, VM_OVERLAY_ACTIVE_3, VM_OVERLAY_4 // bottom right not animated diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingUplinkHatch.java b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingUplinkHatch.java index 10e6d6b..d190276 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingUplinkHatch.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/MTEVendingUplinkHatch.java @@ -1,7 +1,7 @@ package com.cubefury.vendingmachine.blocks; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_INPUT_FLUID_HATCH; -import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_ME_INPUT_FLUID_HATCH_ACTIVE; +import static com.cubefury.vendingmachine.api.enums.Textures.VUPLINK_OVERLAY_0; +import static com.cubefury.vendingmachine.api.enums.Textures.VUPLINK_OVERLAY_1; import java.util.EnumSet; @@ -120,12 +120,12 @@ public void securityBreak() {} @Override public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_INPUT_FLUID_HATCH_ACTIVE) }; + return new ITexture[] { aBaseTexture, TextureFactory.of(VUPLINK_OVERLAY_1) }; } @Override public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, TextureFactory.of(OVERLAY_ME_INPUT_FLUID_HATCH) }; + return new ITexture[] { aBaseTexture, TextureFactory.of(VUPLINK_OVERLAY_0) }; } @Override diff --git a/src/main/resources/assets/vendingmachine/textures/blocks/vending_uplink_machine_overlay_active.png b/src/main/resources/assets/vendingmachine/textures/blocks/vending_uplink_machine_overlay_active.png new file mode 100644 index 0000000000000000000000000000000000000000..358ce0b7992ef1d0370b35d2795e4adb0933ccee GIT binary patch literal 426 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|+72L}gU$3-bADL{ck%Ukb*)RhGJ1^@s5pTR+Ezyvgx39K^6(gMhW>M}Gi0Lf}A zepk0~Vh1TU^mK6y(FjgXaAUr~A~AtMkI_xTfy1DYv5wJA;Fxy9LRMb}t_MsU4Y3TO d3pfponHioNS%G~10G|+72M320D^{eWr0_Z}0*XD_)N=_)v6ck+1^)*EhTq%xKn8IZctjR6 zFz_7$VMb96uLhu?M2TxeNpOBzNqJ&XDnmeGW?qS&pKFMMsh**pWlr8LJD{3vsS%!O zo}O9^96$~$gA^kx10#^-1;o-&Hpt}~jLcwhCLr68kqPXRC?GqtodqnO1!RN3r!q!{ z7eEifXf#V1fKn6K8CZZS4UCKp7#BcH1=+~D0AkVNZa7AjJlrE{-7@!O01Z%r{shCNStRx@kCY7&J20F{Y(CF-b&SU|GPR*T8Ut gHGpvz12;E=T0E0x;OV literal 0 HcmV?d00001 From 3f80365152835e6abd304ec85eff34fa451a0ae9 Mon Sep 17 00:00:00 2001 From: cubefury Date: Fri, 10 Oct 2025 01:49:37 +0800 Subject: [PATCH 12/17] Now sorts by tradegroup id before writing to file, and does not add indices for NBT arrays. This change ensures that changelogs won't be massive every time a new trade is added, from all the tradegroups and their indices getting shuffled around. --- .../vendingmachine/trade/TradeDatabase.java | 7 +-- .../vendingmachine/util/NBTConverter.java | 45 +++++-------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java b/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java index 4d16562..f1db10f 100644 --- a/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java +++ b/src/main/java/com/cubefury/vendingmachine/trade/TradeDatabase.java @@ -109,9 +109,10 @@ public void readFromNBT(NBTTagCompound nbt, boolean merge) { public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt.setInteger("version", this.version); NBTTagList tgList = new NBTTagList(); - for (TradeGroup tg : tradeGroups.values()) { - tgList.appendTag(tg.writeToNBT(new NBTTagCompound())); - } + tradeGroups.values() + .stream() + .sorted(Comparator.comparing(TradeGroup::getId)) + .forEach(tg -> tgList.appendTag(tg.writeToNBT(new NBTTagCompound()))); nbt.setTag("tradeGroups", tgList); return nbt; } diff --git a/src/main/java/com/cubefury/vendingmachine/util/NBTConverter.java b/src/main/java/com/cubefury/vendingmachine/util/NBTConverter.java index 5daf73f..d09ef91 100644 --- a/src/main/java/com/cubefury/vendingmachine/util/NBTConverter.java +++ b/src/main/java/com/cubefury/vendingmachine/util/NBTConverter.java @@ -176,20 +176,11 @@ else if (value instanceof NBTTagByteArray) { out.endArray(); } else if (value instanceof NBTTagList) { List tagList = getTagList((NBTTagList) value); - if (format) { - out.beginObject(); - for (int i = 0; i < tagList.size(); i++) { - NBTBase tag = tagList.get(i); - out.name(i + ":" + tag.getId()); - NBTtoJSON_Base(tag, true, out); - } - out.endObject(); - } else { - out.beginArray(); - for (NBTBase tag : tagList) { - NBTtoJSON_Base(tag, false, out); - } + out.beginArray(); + for (NBTBase tag : tagList) { + NBTtoJSON_Base(tag, format, out); } + out.endArray(); } else if (value instanceof NBTTagCompound) { NBTtoJSON_Compound((NBTTagCompound) value, out, format); } else { @@ -233,31 +224,15 @@ private static JsonElement NBTtoJSON_Base(NBTBase tag, boolean format) { } else if (tag instanceof NBTTagCompound) { return NBTtoJSON_Compound((NBTTagCompound) tag, new JsonObject(), format); } else if (tag instanceof NBTTagList) { - if (format) { - JsonObject jAry = new JsonObject(); - - List tagList = getTagList((NBTTagList) tag); - - for (int i = 0; i < tagList.size(); i++) { - jAry.add( - i + ":" - + tagList.get(i) - .getId(), - NBTtoJSON_Base(tagList.get(i), true)); - } - - return jAry; - } else { - JsonArray jAry = new JsonArray(); - - List tagList = getTagList((NBTTagList) tag); + JsonArray jAry = new JsonArray(); - for (NBTBase t : tagList) { - jAry.add(NBTtoJSON_Base(t, false)); - } + List tagList = getTagList((NBTTagList) tag); - return jAry; + for (NBTBase t : tagList) { + jAry.add(NBTtoJSON_Base(t, format)); } + + return jAry; } else if (tag instanceof NBTTagByteArray) { JsonArray jAry = new JsonArray(); From eb7bb00aab46fcfe11825f2854f088859bd71fa4 Mon Sep 17 00:00:00 2001 From: cubefury Date: Fri, 10 Oct 2025 03:23:56 +0800 Subject: [PATCH 13/17] Fix edge-case crash when loading trade history for an already-removed tradegroup. --- .../vendingmachine/blocks/gui/TradeMainPanel.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java index c25667b..b7812d1 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java @@ -21,6 +21,7 @@ import com.cubefury.vendingmachine.network.handlers.NetResetVMUser; import com.cubefury.vendingmachine.trade.TradeCategory; import com.cubefury.vendingmachine.trade.TradeDatabase; +import com.cubefury.vendingmachine.trade.TradeGroup; import com.cubefury.vendingmachine.trade.TradeManager; import com.cubefury.vendingmachine.util.BigItemStack; @@ -126,8 +127,11 @@ public Map> formatTrades() { Map> trades = new HashMap<>(); trades.put(TradeCategory.ALL, new ArrayList<>()); for (TradeItemDisplay tid : TradeManager.INSTANCE.tradeData) { - TradeCategory category = TradeDatabase.INSTANCE.getTradeGroupFromId(tid.tgID) - .getCategory(); + TradeGroup group = TradeDatabase.INSTANCE.getTradeGroupFromId(tid.tgID); + if (group == null) { + continue; + } + TradeCategory category = group.getCategory(); trades.putIfAbsent(category, new ArrayList<>()); trades.get(category) .add(tid); From 2dfa8592021452c057e7dc45779c84eec95cc943 Mon Sep 17 00:00:00 2001 From: cubefury Date: Fri, 10 Oct 2025 17:16:40 +0800 Subject: [PATCH 14/17] Add list trade display format --- .../com/cubefury/vendingmachine/Config.java | 13 ++ .../blocks/gui/MTEVendingMachineGui.java | 193 ++++++++++++++---- .../blocks/gui/TradeItemDisplayWidget.java | 107 ++++++++-- .../blocks/gui/TradeMainPanel.java | 2 +- .../vendingmachine/gui/GuiTextures.java | 31 ++- .../assets/vendingmachine/lang/en_US.lang | 3 + .../background/list_trade_button_pressed.png | Bin 0 -> 3183 bytes ...t_trade_button_pressed_color_corrected.png | Bin 0 -> 3210 bytes .../list_trade_button_unpressed.png | Bin 0 -> 3182 bytes ...trade_button_unpressed_color_corrected.png | Bin 0 -> 3211 bytes .../textures/gui/overlay/mode_list.png | Bin 0 -> 597 bytes .../textures/gui/overlay/mode_tile.png | Bin 0 -> 613 bytes 12 files changed, 285 insertions(+), 64 deletions(-) create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_pressed.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_pressed_color_corrected.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed_color_corrected.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_list.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_tile.png diff --git a/src/main/java/com/cubefury/vendingmachine/Config.java b/src/main/java/com/cubefury/vendingmachine/Config.java index 8972650..d9f405f 100644 --- a/src/main/java/com/cubefury/vendingmachine/Config.java +++ b/src/main/java/com/cubefury/vendingmachine/Config.java @@ -4,6 +4,8 @@ import net.minecraftforge.common.config.Configuration; +import com.cubefury.vendingmachine.blocks.gui.TradeItemDisplayWidget.DisplayType; + public class Config { private static final String CONFIG_CATEGORY_VM = "Vending Machine Settings"; @@ -13,6 +15,7 @@ public class Config { public static int gui_refresh_interval = 20; public static int dispense_frequency = 10; public static int dispense_amount = 16; + public static DisplayType display_type = DisplayType.TILE; public static File worldDir = null; @@ -36,6 +39,16 @@ public static void init(File configFile) { 1, Integer.MAX_VALUE, "Number of items per dispense cycle"); + try { + display_type = DisplayType.valueOf( + configuration.getString( + "display_type", + CONFIG_CATEGORY_VM, + "TILE", + "Default trade display format, either TILE or LIST. Case sensitive.")); + } catch (IllegalArgumentException e) { + display_type = DisplayType.TILE; + } if (configuration.hasChanged()) { configuration.save(); diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java index e3a7b50..73bc0e0 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java @@ -13,14 +13,18 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.screen.UISettings; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.IntValue; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widget.SingleChildWidget; +import com.cleanroommc.modularui.widgets.CycleButtonWidget; import com.cleanroommc.modularui.widgets.ListWidget; import com.cleanroommc.modularui.widgets.PagedWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; @@ -30,6 +34,7 @@ import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.slot.ItemSlot; import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.cubefury.vendingmachine.Config; import com.cubefury.vendingmachine.VendingMachine; import com.cubefury.vendingmachine.blocks.MTEVendingMachine; import com.cubefury.vendingmachine.gui.GuiTextures; @@ -57,7 +62,8 @@ public class MTEVendingMachineGui extends MTEMultiBlockBaseGui { private boolean ejectItems = false; private boolean ejectCoins = false; private final Map ejectSingleCoin = new HashMap<>(); - private final Map> displayedTrades = new HashMap<>(); + private final Map> displayedTradesTiles = new HashMap<>(); + private final Map> displayedTradesList = new HashMap<>(); private final List tradeCategories = new ArrayList<>(); private final List inputSlots = new ArrayList<>(); @@ -67,12 +73,17 @@ public class MTEVendingMachineGui extends MTEMultiBlockBaseGui { public static String lastSearch = ""; public static int lastPage = 0; + public static TradeItemDisplayWidget.DisplayType displayType = Config.display_type; public static final int CUSTOM_UI_HEIGHT = 320; - public static final int ITEMS_PER_ROW = 3; - public static final int ITEM_HEIGHT = 25; - public static final int ITEM_WIDTH = 47; + // Trade Item Display + public static final int TILE_ITEMS_PER_ROW = 3; + public static final int TILE_ITEM_HEIGHT = 25; + public static final int TILE_ITEM_WIDTH = 47; + public static final int LIST_ITEM_HEIGHT = 14; + public static final int LIST_ITEM_WIDTH = 153; + private static final int COIN_COLUMN_WIDTH = 40; private static final int COIN_COLUMN_ROW_COUNT = 4; @@ -88,10 +99,15 @@ public MTEVendingMachineGui(MTEVendingMachine base) { this.tradeCategories.addAll(TradeDatabase.INSTANCE.getTradeCategories()); for (TradeCategory c : this.tradeCategories) { - displayedTrades.put(c, new ArrayList<>(MTEVendingMachine.MAX_TRADES)); + displayedTradesTiles.put(c, new ArrayList<>(MTEVendingMachine.MAX_TRADES)); + for (int i = 0; i < MTEVendingMachine.MAX_TRADES; i++) { + displayedTradesTiles.get(c) + .add(new TradeItemDisplayWidget(null, TradeItemDisplayWidget.DisplayType.TILE)); + } + displayedTradesList.put(c, new ArrayList<>(MTEVendingMachine.MAX_TRADES)); for (int i = 0; i < MTEVendingMachine.MAX_TRADES; i++) { - displayedTrades.get(c) - .add(new TradeItemDisplayWidget(null)); + displayedTradesList.get(c) + .add(new TradeItemDisplayWidget(null, TradeItemDisplayWidget.DisplayType.LIST)); } } @@ -117,7 +133,8 @@ public ModularPanel build(PosGuiData guiData, PanelSyncManager syncManager, UISe .padding(4); panel.child(createCategoryTabs(this.tabController)); Flow mainColumn = new Column().width(170); - if (VendingMachine.proxy.isClient()) { // client side filtering + if (VendingMachine.proxy.isClient()) { // client side sort and filtering + panel.child(createQolButtonColumn()); mainColumn.child( createTitleTextStyle( IKey.lang("gt.blockmachines.multimachine.vendingmachine.name.gui") @@ -143,6 +160,32 @@ public void restorePreviousSettings() { this.searchBar.setText(lastSearch); } + public IWidget createQolButtonColumn() { + Flow buttonColumn = new Column().width(8) + .height(20) + .left(-17) + .top(1) + .coverChildren(); + buttonColumn.child( + new CycleButtonWidget().size(14) + .overlay( + new DynamicDrawable( + () -> displayType.getTexture() + .size(14))) + .stateCount(TradeItemDisplayWidget.DisplayType.values().length) + .value( + new IntValue.Dynamic( + () -> displayType.ordinal(), + val -> { displayType = TradeItemDisplayWidget.DisplayType.values()[val]; })) + .tooltipDynamic(builder -> { + builder.clearText(); + builder + .addLine(IKey.lang("vendingmachine.gui.display_mode") + " " + displayType.getLocalizedName()); + }) + .tooltipAutoUpdate(true)); + return buttonColumn; + } + public IWidget createCategoryTabs(PagedWidget.Controller tabController) { Flow tabColumn = new Column().width(40) .height(100) @@ -347,6 +390,45 @@ private SlotGroupWidget createOutputSlots() { .build(); } + private void constructTradeTooltip(RichTooltip builder, TradeItemDisplay cur) { + if (cur != null) { + for (BigItemStack toItem : cur.toItems) { + builder.addLine( + IKey.str( + toItem.stackSize + " " + + toItem.getBaseStack() + .getDisplayName()) + .style(IKey.AQUA)); + // builder.add(new ItemDrawable(toItem.getBaseStack())); + } + builder.emptyLine(); + builder.addLine( + IKey.str(Translator.translate("vendingmachine.gui.required_inputs")) + .style(IKey.DARK_GREEN, IKey.ITALIC)); + for (CurrencyItem currencyItem : cur.fromCurrency) { + builder.addLine( + IKey.str(currencyItem.value + " " + currencyItem.type.getLocalizedName()) + .style(IKey.DARK_GREEN)); + } + for (BigItemStack fromItem : cur.fromItems) { + builder.addLine( + IKey.str( + fromItem.stackSize + " " + + fromItem.getBaseStack() + .getDisplayName()) + .style(IKey.DARK_GREEN)); + } + + builder.emptyLine(); + builder.addLine( + IKey.str(cur.label) + .style(IKey.GRAY)); + builder.addLine( + IKey.str(Translator.translate("vendingmachine.gui.trade_hint")) + .style(IKey.GRAY)); + } + } + // spotless:off private IWidget createTradeUI(TradeMainPanel rootPanel, PagedWidget.Controller tabController) { PagedWidget paged = new PagedWidget<>() @@ -364,50 +446,60 @@ private IWidget createTradeUI(TradeMainPanel rootPanel, PagedWidget.Controller t tradeList.child(new Row().height(2)); // Higher first row top margin - Flow row = new TradeRow().height(ITEM_HEIGHT+2).left(2); + Flow row = new TradeRow().height(TILE_ITEM_HEIGHT +2).left(2); + // Tiles Display for (int i = 0; i < MTEVendingMachine.MAX_TRADES; i++) { int index = i; - displayedTrades.get(category).get(i).setRootPanel(rootPanel); - row.child(displayedTrades.get(category).get(i) + displayedTradesTiles.get(category).get(i).setRootPanel(rootPanel); + row.child(displayedTradesTiles.get(category).get(i) .tooltipDynamic(builder -> { builder.clearText(); - synchronized (displayedTrades) { - if (index < displayedTrades.get(category).size()) { - TradeItemDisplay cur = displayedTrades.get(category).get(index).getDisplay(); - if (cur != null) { - for (BigItemStack toItem : cur.toItems) { - builder.addLine(IKey.str(toItem.stackSize + " " + toItem.getBaseStack().getDisplayName()).style(IKey.AQUA)); - // builder.add(new ItemDrawable(toItem.getBaseStack())); - } - builder.emptyLine(); - builder.addLine(IKey.str(Translator.translate("vendingmachine.gui.required_inputs")).style(IKey.DARK_GREEN, IKey.ITALIC)); - for (CurrencyItem currencyItem: cur.fromCurrency) { - builder.addLine(IKey.str(currencyItem.value + " " + currencyItem.type.getLocalizedName()).style(IKey.DARK_GREEN)); - } - for (BigItemStack fromItem : cur.fromItems) { - builder.addLine(IKey.str(fromItem.stackSize + " " + fromItem.getBaseStack().getDisplayName()).style(IKey.DARK_GREEN)); - } - - builder.emptyLine(); - builder.addLine(IKey.str(cur.label).style(IKey.GRAY)); - builder.addLine(IKey.str(Translator.translate("vendingmachine.gui.trade_hint")).style(IKey.GRAY)); + synchronized (displayedTradesTiles) { + if (index < displayedTradesTiles.get(category).size()) { + constructTradeTooltip(builder, displayedTradesTiles.get(category).get(index).getDisplay()); } } - } }) .tooltipAutoUpdate(true) - .setEnabledIf(slot -> ((TradeItemDisplayWidget) slot).getDisplay() != null) + .setEnabledIf(slot -> { + TradeItemDisplayWidget display = ((TradeItemDisplayWidget) slot); + return displayType == display.displayType && display.getDisplay() != null; + }) .margin(2)); - if (i % ITEMS_PER_ROW == ITEMS_PER_ROW - 1) { + if (i % TILE_ITEMS_PER_ROW == TILE_ITEMS_PER_ROW - 1) { tradeList.child(row); - row = new TradeRow().height(ITEM_HEIGHT+2).left(2); + row = new TradeRow().height(TILE_ITEM_HEIGHT +2).left(2); } } if (row.hasChildren()) { tradeList.child(row); } + + // List Display + row = new TradeRow().height(LIST_ITEM_HEIGHT).left(2); + for (int i = 0; i < MTEVendingMachine.MAX_TRADES; i++) { + int index = i; + displayedTradesList.get(category).get(i).setRootPanel(rootPanel); + row.child(displayedTradesList.get(category).get(i) + .tooltipDynamic(builder -> { + builder.clearText(); + synchronized (displayedTradesList) { + if (index < displayedTradesList.get(category).size()) { + constructTradeTooltip(builder, displayedTradesList.get(category).get(index).getDisplay()); + } + } + }) + .tooltipAutoUpdate(true) + .setEnabledIf(slot -> { + TradeItemDisplayWidget display = ((TradeItemDisplayWidget) slot); + return displayType == display.displayType && display.getDisplay() != null; + })); + tradeList.child(row); + row = new TradeRow().height(LIST_ITEM_HEIGHT).left(2); + } + tradeList.child(new Row().height(2)); // bottom padding for last row paged.addPage(tradeList); } @@ -537,9 +629,10 @@ public static void resetForceRefresh() { forceRefresh = false; } - public void updateTradeDisplay(Map> trades) { - synchronized (displayedTrades) { - for (Map.Entry> entry : displayedTrades.entrySet()) { + private void updateTradeDisplay(Map> trades, + Map> display) { + synchronized (display) { + for (Map.Entry> entry : display.entrySet()) { int displayedSize = trades.get(entry.getKey()) == null ? 0 : trades.get(entry.getKey()) .size(); @@ -560,10 +653,16 @@ public void updateTradeDisplay(Map> trades } } - public Map> getTradeDisplayData() { + public void updateTradeDisplay(Map> trades) { + this.updateTradeDisplay(trades, displayedTradesTiles); + this.updateTradeDisplay(trades, displayedTradesList); + } + + public Map> getCurrentTradeDisplayData() { Map> currentData = new HashMap<>(); - synchronized (displayedTrades) { - this.displayedTrades.forEach((k, v) -> { + + synchronized (displayedTradesTiles) { + this.displayedTradesTiles.forEach((k, v) -> { currentData.put( k, v.stream() @@ -572,6 +671,18 @@ public Map> getTradeDisplayData() { .collect(Collectors.toList())); }); } + + synchronized (displayedTradesList) { + this.displayedTradesList.forEach((k, v) -> { + currentData.get(k) + .addAll( + v.stream() + .map(TradeItemDisplayWidget::getDisplay) + .filter(Objects::nonNull) + .collect(Collectors.toList())); + }); + } + return currentData; } diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java index 65641ef..66c1d36 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java @@ -1,5 +1,8 @@ package com.cubefury.vendingmachine.blocks.gui; +import static com.cubefury.vendingmachine.gui.GuiTextures.MODE_LIST; +import static com.cubefury.vendingmachine.gui.GuiTextures.MODE_TILE; + import net.minecraft.item.ItemStack; import org.jetbrains.annotations.NotNull; @@ -9,6 +12,8 @@ import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.drawable.GuiDraw; +import com.cleanroommc.modularui.drawable.Icon; +import com.cleanroommc.modularui.drawable.UITexture; import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.Platform; @@ -19,17 +24,51 @@ public class TradeItemDisplayWidget extends ItemDisplayWidget implements Interactable { + public enum DisplayType { + + TILE("tile", MODE_TILE), + LIST("list", MODE_LIST); + + private String type; + private Icon texture; + + DisplayType(String type, UITexture texture) { + this.type = type; + this.texture = texture.asIcon(); + } + + public String getLocalizedName() { + return IKey.lang("vendingmachine.gui.display_mode_" + this.type) + .toString(); + } + + public Icon getTexture() { + return this.texture; + } + } + private TradeMainPanel rootPanel; private boolean pressed = false; private IValue value; + public final DisplayType displayType; private TradeItemDisplay display; - public TradeItemDisplayWidget(TradeItemDisplay display) { - height(MTEVendingMachineGui.ITEM_HEIGHT); - width(MTEVendingMachineGui.ITEM_WIDTH); - background( - new DynamicDrawable(() -> pressed ? GuiTextures.TRADE_BUTTON_PRESSED : GuiTextures.TRADE_BUTTON_UNPRESSED)); + public TradeItemDisplayWidget(TradeItemDisplay display, DisplayType displayType) { + this.displayType = displayType; + if (displayType == DisplayType.TILE) { + height(MTEVendingMachineGui.TILE_ITEM_HEIGHT); + width(MTEVendingMachineGui.TILE_ITEM_WIDTH); + background( + new DynamicDrawable( + () -> pressed ? GuiTextures.TILE_TRADE_BUTTON_PRESSED : GuiTextures.TILE_TRADE_BUTTON_UNPRESSED)); + } else if (displayType == DisplayType.LIST) { + height(MTEVendingMachineGui.LIST_ITEM_HEIGHT); + width(MTEVendingMachineGui.LIST_ITEM_WIDTH); + background( + new DynamicDrawable( + () -> pressed ? GuiTextures.LIST_TRADE_BUTTON_PRESSED : GuiTextures.LIST_TRADE_BUTTON_UNPRESSED)); + } this.display = display; this.item((ItemStack) null); @@ -57,24 +96,52 @@ public TradeItemDisplay getDisplay() { public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { ItemStack item = value.getValue(); if (!Platform.isStackEmpty(item)) { - GuiDraw.drawText(" " + this.display.display.stackSize, 4, 9, 1.0f, 0x0, false); - GuiDraw.drawItem(item, 26, 4, 16, 16, context.getCurrentDrawingZ()); - if (this.display.tradeableNow) { - GuiDraw.drawOutline(1, 1, 45, 23, 0x883CFF00, 2); - } - if (this.display.hasCooldown || !this.display.enabled) { - GuiDraw.drawRoundedRect( - 1, + if (this.displayType == DisplayType.TILE) { + GuiDraw.drawText(" " + this.display.display.stackSize, 4, 9, 1.0f, 0x0, false); + GuiDraw.drawItem(item, 26, 4, 16, 16, context.getCurrentDrawingZ()); + if (this.display.tradeableNow) { + GuiDraw.drawOutline(1, 1, 45, 23, 0x883CFF00, 2); + } + if (this.display.hasCooldown || !this.display.enabled) { + GuiDraw.drawRoundedRect( + 1, + 1, + MTEVendingMachineGui.TILE_ITEM_WIDTH - 2, + MTEVendingMachineGui.TILE_ITEM_HEIGHT - 2, + 0xBB000000, + 1, + 1); + } + this.overlay( + IKey.str(display.hasCooldown ? this.display.cooldownText : "") + .style(IKey.WHITE)); + } else if (this.displayType == DisplayType.LIST) { + GuiDraw.drawText( + " " + this.display.display.stackSize + " " + this.display.display.getDisplayName(), + 4, + 4, + 0.9f, + 0x0, + false); + GuiDraw.drawRect( 1, - MTEVendingMachineGui.ITEM_WIDTH - 2, - MTEVendingMachineGui.ITEM_HEIGHT - 2, - 0xBB000000, 1, - 1); + 3, + MTEVendingMachineGui.LIST_ITEM_HEIGHT - 3, + this.display.tradeableNow ? 0x883CFF00 : 0x88333333); + if (this.display.hasCooldown || !this.display.enabled) { + GuiDraw.drawRect( + 1, + 1, + MTEVendingMachineGui.LIST_ITEM_WIDTH - 2, + MTEVendingMachineGui.LIST_ITEM_HEIGHT - 2, + 0xBB000000); + } + this.overlay( + IKey.str(display.hasCooldown ? this.display.cooldownText : "") + .style(IKey.WHITE) + .scale(0.9f)); } - this.overlay( - IKey.str(display.hasCooldown ? this.display.cooldownText : "") - .style(IKey.WHITE)); } } diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java index b7812d1..e663327 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java @@ -65,7 +65,7 @@ public boolean onKeyRelease(char typedChar, int keyCode) { public void updateGui() { if (shiftHeld) { - this.updateTradeInformation(gui.getTradeDisplayData()); + this.updateTradeInformation(gui.getCurrentTradeDisplayData()); } else { Map> trades = formatTrades(); gui.updateTradeDisplay(trades); diff --git a/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java b/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java index 8ee5829..c020280 100644 --- a/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java +++ b/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java @@ -45,20 +45,47 @@ public final class GuiTextures { .name("text_field_background") .build(); - public static final UITexture TRADE_BUTTON_UNPRESSED = UITexture.builder() + // TODO: Restore canApplyTheme to trade button textures after scrolling texture bug is fixed in MUI2 + public static final UITexture TILE_TRADE_BUTTON_UNPRESSED = UITexture.builder() .location(VendingMachine.MODID, "gui/background/trade_button_unpressed_color_corrected") .imageSize(195, 136) .adaptable(4) .name("trade_button_unpressed") .build(); - public static final UITexture TRADE_BUTTON_PRESSED = UITexture.builder() + public static final UITexture TILE_TRADE_BUTTON_PRESSED = UITexture.builder() .location(VendingMachine.MODID, "gui/background/trade_button_pressed_color_corrected") .imageSize(195, 136) .adaptable(4) .name("trade_button_pressed") .build(); + public static final UITexture LIST_TRADE_BUTTON_UNPRESSED = UITexture.builder() + .location(VendingMachine.MODID, "gui/background/list_trade_button_unpressed_color_corrected") + .imageSize(195, 136) + .adaptable(2) + .name("list_trade_button_unpressed") + .build(); + + public static final UITexture LIST_TRADE_BUTTON_PRESSED = UITexture.builder() + .location(VendingMachine.MODID, "gui/background/list_trade_button_pressed_color_corrected") + .imageSize(195, 136) + .adaptable(2) + .name("list_trade_button_pressed") + .build(); + + public static final UITexture MODE_TILE = UITexture.builder() + .location(VendingMachine.MODID, "gui/overlay/mode_tile") + .imageSize(32, 32) + .name("mode_tile") + .build(); + + public static final UITexture MODE_LIST = UITexture.builder() + .location(VendingMachine.MODID, "gui/overlay/mode_list") + .imageSize(32, 32) + .name("mode_list") + .build(); + public static final UITexture INPUT_SPRITE = UITexture.builder() .location(VendingMachine.MODID, "gui/background/input") .imageSize(30, 20) diff --git a/src/main/resources/assets/vendingmachine/lang/en_US.lang b/src/main/resources/assets/vendingmachine/lang/en_US.lang index 0583853..c5cc5ea 100644 --- a/src/main/resources/assets/vendingmachine/lang/en_US.lang +++ b/src/main/resources/assets/vendingmachine/lang/en_US.lang @@ -17,6 +17,9 @@ vendingmachine.gui.single_coin_type_eject_hint=Shift-Click to Extract vendingmachine.gui.search=Search vendingmachine.gui.required_inputs=Requires: vendingmachine.gui.trade_hint=Shift-Click to Purchase +vendingmachine.gui.display_mode=Display: +vendingmachine.gui.display_mode_tile=Tiles +vendingmachine.gui.display_mode_list=List vendingmachine.gui.cooldown_display.second=s vendingmachine.gui.cooldown_display.minute=m diff --git a/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_pressed.png b/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..aefd2f76dd49a5b1b1d181bca0e76d0831b0e7ab GIT binary patch literal 3183 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed.png b/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..48b5d2275de7fa1a5cc90b9ed44096a70153a956 GIT binary patch literal 3182 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed_color_corrected.png b/src/main/resources/assets/vendingmachine/textures/gui/background/list_trade_button_unpressed_color_corrected.png new file mode 100644 index 0000000000000000000000000000000000000000..e931d75bdf6a09fa21f0cb1fa1657e1299308aaf GIT binary patch literal 3211 zcmd5;=|9wq7ycrI>{}DrvP@ZL(%7@iU~Jh9LZb<}VJ6144zjOvL&?5mE3PComPTZc zG4?2B>mssmV^BZ$Pq^=XFV6Fv=Q+>kyg6@9lGQC^PWDUe003~BAQ3ia+<8`s=UL9s zdF~GL8J+Xex6lWGy1zJ1+|M+-nl~J76<}j*AYoz%he0%8Fh!^m1OSjp1zACMw$nlh zRI(b`DuXBa$?${wHjGG4GBRE18ib9#8F^=xjQi} z#S6{KaA6Bz@&V>>_4NiqG$Y0w#_*|BpB#RgFu8?G;^_F=m~LtZ@Vn?qvy&7Au*yzd z-l0vqfQ0+ibx`>-B+LHnx2hIHDyBnHPSH?@%zzz*+u;W}9^4wc&{%EIK)}#~$JX~5 zxy3XMzP8kKG)Q>)JgphpCX0!|o5bt&V87Ra!f(Ls5GcINfMGvkjuWZtbxFX?q!l^cG zUpN1858lmG&%i_AZfbs>p%sX(zM%!&(S@a=1e!SOuRt*&-V^DzMCB)jh=B@o3G=MR z+kO0r%sB?}dbFZk8h7Wfvgzimq|Y?o;VehSa>+}25n=%N8m|Of*gg5-O#(-cG1Czx zWh5uN;Fucyi-2k}|J5fX9ZAF(BcM%u)+P`rd2(W6(;`nb8p*un*i=P zCPsa5;<<-t$Xv9*V+MqTus~E}@x>?6HE6jPEP=(msxdI!Mf@YooT@sj(xUzV7i5Vk!K6Zn7bDF@Wd-XQ>p}G*V?>QOP*19RMV;f{nvA3sObtGDr7zQh61jrSU&2W4FLy%xsB_3-7gAxu1bXJ-1)i+g*J z3jB@0(?FS){g#-P>!CfN)}e8s>!F8xY;=WF>C?+}GToL%lSPt+nWct>#JL@>&?(UA z8h;vJo0gh(Hx+g<5TpZjxXz_Aq~>>{?STR8p_-HDDB7PQfcXfuxc=2Qbov6UUd;?r z4H1DRP%aNLFSSw<6o-Xw2^plYq==aFjb-L^`gjnXM-^ifITTwJikv`>-M4+~S4s5y zzSsi4ulEVP@pt*}+uk3;>{i$0D1Lg|bMV<^$7Qy;dihT(!OzRDm-Gb_G*rd!&M^mB=J9H#*NOa%9bxai@i;q{Wk52>A5 zaRhN98#hNSTjWJ|erukQ_fakA{^%^`S}C&BfYc@;2VwF&v{bN^|9M{No!;QyC%s5a z&0SQFTk=>Ue^+2HX0dcJZ=q6{t}xS#)9$!gqCQWTS~LtvQBs(6%x|O7__}5CWsLbo zk|0TnNt+ra`7A?wqfzCJW|d7o8%i7eg{)XsY{uqCStztg z-?3{Kvg0VMq*qRsx835f_)>ImRY#Vr!}KgY`=K3@w}R~$+IW2znovJjpIl!ykpFDm z1t!DJcf$ido${u&TXmW`9@T|-;|9%L%(Bhgl~vO`L>BrNs$kL0(>oReayx|G_im4z zJ6uO@7vFyU7L6}o{z$hUt}3q%MXl8;IqS6bU@4CpV;j96M1mWX6qLi8l{{T7(;Y@~ zpV#e2tldr#Og8LRgEjfQ_>%Y;Jf+^`y-`tRA#N5dBWzY zXz+MFSmHx<7<8DQT>COZx(r4sQI*BNh`k{Puwsn+iO;m2{d{NTj!w*)uJ~kq3`KKET!?uglvMw zu^7xq?I4muZ)r9uecAA%Gh#mC$D>3h0)_*7#n zNzcR>6QmQwBJ*hL`~yA{bJ_wLvs#O{?Z#=WuxIb~fpTJVXcw4L|KFHnQ z1Au$@1cU@g*y024d1EE)uvnjt%K2~rV0dPN(6XaeR!*?Wcl+W(we?vFd*OSQLnU}M;Xv?kr>UdpKnQEyEnZbUV$U`Tc zhUbz#rCgk&UVQ7jgoA9O-(BE==;fQ7K^MTwg!otehemf*|39Sv)9U}D@R49=L`czT lxHFk8>xk&S&qL#G1OA@!G2ei7TtB-cU}AU+@yY-l{Xc^Ew6OpH literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_list.png b/src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_list.png new file mode 100644 index 0000000000000000000000000000000000000000..039e5ef7a8733fa20e80b8c60c2b82adb5a41d7e GIT binary patch literal 597 zcmV-b0;>IqP)1q~8j=(jN5Qq=;KyRs!Nplu2UkH5`~Y!ua#D1W691PJTEuv8+>dwn9(V5mp;2L) z6&eRL-8R$7gqY2(is4rX2qB7o1Y~9zbCQ&T@A$e$fUkFPp5=e;&(W*qEd~Tc;#p>x zHt`1W^rmfa-Y1T-lB^P+6OWm6LE=ZQD;~dbF1jr6%&3`3&l5+9#bO659n4CmMm$9v zQ#GCPg{;Ra=Pk}!rN&zKyGn%>^RL6AovVi>1}_t z0nB`oUT${ujJ0}MVHvMIY#kfu;50Pkn?O*vrT7U)^?dTZ_D^a03F zSE(D|;1C!sQueyfySqDk`}a(%zaQGQa%$ya9j jfP6v#azJ+g0LTFkXY-H2qYs)-00000NkvXXu0mjf!kqM0 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_tile.png b/src/main/resources/assets/vendingmachine/textures/gui/overlay/mode_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..426e54fd832ed051320122c44661b4d207a3cf32 GIT binary patch literal 613 zcmV-r0-F7aP)1q~8j=(jN5Qq=;KyRs!Nplu2UkH5`~Y!ua#D1W691PJTEuv8+>dwn9(V5mp;2L) z6&eRL-8R$7gqY2(is4rX2qB7o1Y~9zbCQ&T@A$e$fUkFPp5=e;&(W*qEd~Tc;#p>x zHt`1W^rmfa-Y1T-lB^P+6OWm6LE=ZQD;~dbF1jr6%&3`3&l5+9#bO659n4CmMm$9v zQ#GCPg{;Ra=Pk}!rN&zKyGn%>^RL6AovVi>1}_t z0nB`oUT${ujJ0}MVHvMIY#kfu;50Pkn?O*vrT7U)^?dTZ_D^a03F zSE(D|;1C!sQueyfySqDk`}a(%zaQGQa%$yP)ITUB@t=3 z1El1xp;h7n++Pp|;9f%j0FaWqhE@Rp0C&I!j|o4}b*$wK00000NkvXXu0mjf<%9f+ literal 0 HcmV?d00001 From e9c7a7ef2d005a992ceb03c451fdaf2fa5fa506d Mon Sep 17 00:00:00 2001 From: cubefury Date: Fri, 10 Oct 2025 17:48:42 +0800 Subject: [PATCH 15/17] Added alphabetical sort order --- .../com/cubefury/vendingmachine/Config.java | 12 +++++ .../blocks/gui/MTEVendingMachineGui.java | 44 ++++++++++++++++ .../blocks/gui/TradeMainPanel.java | 49 +++++++++++------- .../vendingmachine/gui/GuiTextures.java | 12 +++++ .../assets/vendingmachine/lang/en_US.lang | 3 ++ .../textures/gui/overlay/sort_alphabet.png | Bin 0 -> 765 bytes .../textures/gui/overlay/sort_smart.png | Bin 0 -> 339 bytes 7 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_alphabet.png create mode 100644 src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_smart.png diff --git a/src/main/java/com/cubefury/vendingmachine/Config.java b/src/main/java/com/cubefury/vendingmachine/Config.java index d9f405f..d812ea9 100644 --- a/src/main/java/com/cubefury/vendingmachine/Config.java +++ b/src/main/java/com/cubefury/vendingmachine/Config.java @@ -4,6 +4,7 @@ import net.minecraftforge.common.config.Configuration; +import com.cubefury.vendingmachine.blocks.gui.MTEVendingMachineGui; import com.cubefury.vendingmachine.blocks.gui.TradeItemDisplayWidget.DisplayType; public class Config { @@ -16,6 +17,7 @@ public class Config { public static int dispense_frequency = 10; public static int dispense_amount = 16; public static DisplayType display_type = DisplayType.TILE; + public static MTEVendingMachineGui.SortMode sort_mode = MTEVendingMachineGui.SortMode.SMART; public static File worldDir = null; @@ -49,6 +51,16 @@ public static void init(File configFile) { } catch (IllegalArgumentException e) { display_type = DisplayType.TILE; } + try { + sort_mode = MTEVendingMachineGui.SortMode.valueOf( + configuration.getString( + "sort_mode", + CONFIG_CATEGORY_VM, + "SMART", + "Default sort mode, either SMART or ALPHABET. Case sensitive.")); + } catch (IllegalArgumentException e) { + sort_mode = MTEVendingMachineGui.SortMode.SMART; + } if (configuration.hasChanged()) { configuration.save(); diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java index 73bc0e0..a3d3f66 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/MTEVendingMachineGui.java @@ -1,5 +1,8 @@ package com.cubefury.vendingmachine.blocks.gui; +import static com.cubefury.vendingmachine.gui.GuiTextures.SORT_ALPHABET; +import static com.cubefury.vendingmachine.gui.GuiTextures.SORT_SMART; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -14,6 +17,8 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.drawable.Icon; +import com.cleanroommc.modularui.drawable.UITexture; import com.cleanroommc.modularui.factory.PosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.RichTooltip; @@ -74,6 +79,7 @@ public class MTEVendingMachineGui extends MTEMultiBlockBaseGui { public static String lastSearch = ""; public static int lastPage = 0; public static TradeItemDisplayWidget.DisplayType displayType = Config.display_type; + public static SortMode sortMode = Config.sort_mode; public static final int CUSTOM_UI_HEIGHT = 320; @@ -87,6 +93,29 @@ public class MTEVendingMachineGui extends MTEMultiBlockBaseGui { private static final int COIN_COLUMN_WIDTH = 40; private static final int COIN_COLUMN_ROW_COUNT = 4; + public enum SortMode { + + SMART("smart", SORT_SMART), + ALPHABET("alphabet", SORT_ALPHABET); + + private String mode; + private Icon texture; + + SortMode(String mode, UITexture texture) { + this.mode = mode; + this.texture = texture.asIcon(); + } + + public String getLocalizedName() { + return IKey.lang("vendingmachine.gui.display_sort_" + this.mode) + .toString(); + } + + public Icon getTexture() { + return this.texture; + } + } + public MTEVendingMachineGui(MTEVendingMachine base) { super(base); this.base = base; @@ -183,6 +212,21 @@ public IWidget createQolButtonColumn() { .addLine(IKey.lang("vendingmachine.gui.display_mode") + " " + displayType.getLocalizedName()); }) .tooltipAutoUpdate(true)); + buttonColumn.child( + new CycleButtonWidget().size(14) + .top(17) + .overlay( + new DynamicDrawable( + () -> sortMode.getTexture() + .size(14))) + .stateCount(SortMode.values().length) + .value(new IntValue.Dynamic(() -> sortMode.ordinal(), val -> { sortMode = SortMode.values()[val]; })) + .tooltipDynamic(builder -> { + builder.clearText(); + builder.addLine(IKey.lang("vendingmachine.gui.display_sort") + " " + sortMode.getLocalizedName()); + setForceRefresh(); + }) + .tooltipAutoUpdate(true)); return buttonColumn; } diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java index e663327..37cbccc 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeMainPanel.java @@ -126,6 +126,8 @@ public ItemStack convertToItemStack(BigItemStack stack) { public Map> formatTrades() { Map> trades = new HashMap<>(); trades.put(TradeCategory.ALL, new ArrayList<>()); + MTEVendingMachineGui.SortMode sortMode = MTEVendingMachineGui.sortMode; + for (TradeItemDisplay tid : TradeManager.INSTANCE.tradeData) { TradeGroup group = TradeDatabase.INSTANCE.getTradeGroupFromId(tid.tgID); if (group == null) { @@ -156,28 +158,35 @@ public Map> formatTrades() { if (a.display.getItem() == null) return 1; if (b.display.getItem() == null) return -1; - // enabled or has cooldown - int rankA = getRank(a); - int rankB = getRank(b); - - if (rankA != rankB) { - return Integer.compare(rankA, rankB); + if (sortMode == MTEVendingMachineGui.SortMode.ALPHABET) { + return (a.display.getDisplayName() + .compareTo(b.display.getDisplayName())); + } else if (sortMode == MTEVendingMachineGui.SortMode.SMART) { + // enabled or has cooldown + int rankA = getRank(a); + int rankB = getRank(b); + + if (rankA != rankB) { + return Integer.compare(rankA, rankB); + } + + // cooldown time + int cooldownCmp = Long.compare(b.cooldown, a.cooldown); + if (cooldownCmp != 0) return cooldownCmp; + + // display item ordering + int idCmp = Integer + .compare(Item.getIdFromItem(a.display.getItem()), Item.getIdFromItem(b.display.getItem())); + if (idCmp != 0) return idCmp; + int dmgCmp = Integer.compare(a.display.getItemDamage(), b.display.getItemDamage()); + if (dmgCmp != 0) return dmgCmp; + + // sort by tradegroup Order + return Integer.compare(a.tradeGroupOrder, b.tradeGroupOrder); } - // cooldown time - int cooldownCmp = Long.compare(b.cooldown, a.cooldown); - if (cooldownCmp != 0) return cooldownCmp; - - // display item ordering - int idCmp = Integer - .compare(Item.getIdFromItem(a.display.getItem()), Item.getIdFromItem(b.display.getItem())); - if (idCmp != 0) return idCmp; - int dmgCmp = Integer.compare(a.display.getItemDamage(), b.display.getItemDamage()); - if (dmgCmp != 0) return dmgCmp; - - // sort by tradegroup Order - return Integer.compare(a.tradeGroupOrder, b.tradeGroupOrder); - + // impossible + return 0; }); trades.replace(category, filteredTrades); } diff --git a/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java b/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java index c020280..3de4571 100644 --- a/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java +++ b/src/main/java/com/cubefury/vendingmachine/gui/GuiTextures.java @@ -86,6 +86,18 @@ public final class GuiTextures { .name("mode_list") .build(); + public static final UITexture SORT_SMART = UITexture.builder() + .location(VendingMachine.MODID, "gui/overlay/sort_smart") + .imageSize(32, 32) + .name("sort_smart") + .build(); + + public static final UITexture SORT_ALPHABET = UITexture.builder() + .location(VendingMachine.MODID, "gui/overlay/sort_alphabet") + .imageSize(32, 32) + .name("sort_alphabet") + .build(); + public static final UITexture INPUT_SPRITE = UITexture.builder() .location(VendingMachine.MODID, "gui/background/input") .imageSize(30, 20) diff --git a/src/main/resources/assets/vendingmachine/lang/en_US.lang b/src/main/resources/assets/vendingmachine/lang/en_US.lang index c5cc5ea..1162c3d 100644 --- a/src/main/resources/assets/vendingmachine/lang/en_US.lang +++ b/src/main/resources/assets/vendingmachine/lang/en_US.lang @@ -20,6 +20,9 @@ vendingmachine.gui.trade_hint=Shift-Click to Purchase vendingmachine.gui.display_mode=Display: vendingmachine.gui.display_mode_tile=Tiles vendingmachine.gui.display_mode_list=List +vendingmachine.gui.display_sort=Sort: +vendingmachine.gui.display_sort_smart=Smart +vendingmachine.gui.display_sort_alphabet=Alphabetical Order vendingmachine.gui.cooldown_display.second=s vendingmachine.gui.cooldown_display.minute=m diff --git a/src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_alphabet.png b/src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_alphabet.png new file mode 100644 index 0000000000000000000000000000000000000000..19f0991e96f6fa1ad5d77b9f1b9cf1c4de96f2df GIT binary patch literal 765 zcmV1q~8j=(jN5Qq=;KyRs!Nplu2UkH5`~Y!ua#D1W691PJTEuv8+>dwn9(V5mp;2L) z6&eRL-8R$7gqY2(is4rX2qB7o1Y~9zbCQ&T@A$e$fUkFPp5=e;&(W*qEd~Tc;#p>x zHt`1W^rmfa-Y1T-lB^P+6OWm6LE=ZQD;~dbF1jr6%&3`3&l5+9#bO659n4CmMm$9v zQ#GCPg{;Ra=Pk}!rN&zKyGn%>^RL6AovVi>1}_t z0nB`oUT${ujJ0}MVHvMIY#kfu;50Pkn?O*vrT7U)^?dTZ_D^a03F zSE(D|;1C!sQueyfySqDk`}a(%zaQGQa%$y zgCGtR6b~kj;Rx*pb`!e=35ULJU^id{H?RjWAw=bAr1ro|y!hww`w&s| zeUBqcBtQZrKmyDGWKqt_NGsvocLhMq@rbm_{~I8S^5s4-(WC-kEF_mjdA8@4s$K&a zPt>HwHm;iS_2qxbR;3Us5td9{a|VtDxB+Mv v#_LF{PfS3l_TP%5{SALr36KB@a5&%#lEEL)+t!YV00000NkvXXu0mjfu%1ND literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_smart.png b/src/main/resources/assets/vendingmachine/textures/gui/overlay/sort_smart.png new file mode 100644 index 0000000000000000000000000000000000000000..7df0dc2e83fa17a7016d234d5eb0733ec4ecd43c GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oArNM~bhqvgP*A$W zHKHUqKdq!Zu_%?nIW?!avREOwq%eANX_uGre3zY_)%z;53->dA^J4tfW_W7nJLfCULz|ZU)a8uo{>{5VakFl$`Y}y^ z&0T5F!r7uqr9N-(zRPe!p!i110#Wak3=B6F|LnM-+rTTi{^f_% Date: Fri, 10 Oct 2025 18:03:01 +0800 Subject: [PATCH 16/17] Separated Item and Item Count in list mode. --- .../blocks/gui/TradeItemDisplayWidget.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java index 66c1d36..4a4c680 100644 --- a/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java +++ b/src/main/java/com/cubefury/vendingmachine/blocks/gui/TradeItemDisplayWidget.java @@ -116,13 +116,8 @@ public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { IKey.str(display.hasCooldown ? this.display.cooldownText : "") .style(IKey.WHITE)); } else if (this.displayType == DisplayType.LIST) { - GuiDraw.drawText( - " " + this.display.display.stackSize + " " + this.display.display.getDisplayName(), - 4, - 4, - 0.9f, - 0x0, - false); + GuiDraw.drawText("" + this.display.display.stackSize, 6, 4, 0.9f, 0x0, false); + GuiDraw.drawText("" + this.display.display.getDisplayName(), 24, 4, 0.9f, 0x0, false); GuiDraw.drawRect( 1, 1, From 8711e4677e8685cc79840a8b07afff16926851a3 Mon Sep 17 00:00:00 2001 From: cubefury Date: Fri, 10 Oct 2025 22:02:54 +0800 Subject: [PATCH 17/17] Separated Item and Item Count in list mode. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c193ac2..e91cd13 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Alpha Testing This can be used as a standalone mod with several dependencies. The vending machine block and ME Vending Uplink do not come with default recipes. ### Required Dependencies: -- GT5U +- GT5Unofficial-GTNH (Not compatible with main GT5U branch!) - ModularUI 2 - NotEnoughItems - Applied Energistics 2