From 13e64627ebadaf570b4a6ef47818cf18f91310ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ko=C5=88a=C5=99=C3=ADk?= Date: Sun, 27 Nov 2022 14:11:40 +0100 Subject: [PATCH] Add configurable item ordering options --- .../java/cpw/mods/inventorysorter/Config.java | 7 ++ .../mods/inventorysorter/InventorySorter.java | 13 ++++ .../InventorySorterCommand.java | 8 ++- .../mods/inventorysorter/ItemOrdering.java | 71 +++++++++++++++++++ .../mods/inventorysorter/SortingHandler.java | 9 ++- .../assets/inventorysorter/lang/en_us.json | 3 +- .../assets/inventorysorter/lang/en_us.lang | 3 +- 7 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 src/main/java/cpw/mods/inventorysorter/ItemOrdering.java diff --git a/src/main/java/cpw/mods/inventorysorter/Config.java b/src/main/java/cpw/mods/inventorysorter/Config.java index f96e66a..870843a 100644 --- a/src/main/java/cpw/mods/inventorysorter/Config.java +++ b/src/main/java/cpw/mods/inventorysorter/Config.java @@ -19,6 +19,8 @@ public class Config { final ForgeConfigSpec.ConfigValue> containerBlacklist; final ForgeConfigSpec.ConfigValue> slotBlacklist; + final ForgeConfigSpec.ConfigValue itemOrdering; + private Config(ForgeConfigSpec.Builder builder) { builder.comment("Inventory sorter blacklists"); builder.push("blacklists"); @@ -31,5 +33,10 @@ private Config(ForgeConfigSpec.Builder builder) { .translation("inventorysorter.config.slotblacklist") .defineList("slotBlacklist", new ArrayList<>(), t -> true); builder.pop(); + + itemOrdering = builder + .comment("Item ordering method") + .translation("inventorysorter.config.itemordering") + .defineEnum("itemOrdering", ItemOrdering.BY_COUNT); } } diff --git a/src/main/java/cpw/mods/inventorysorter/InventorySorter.java b/src/main/java/cpw/mods/inventorysorter/InventorySorter.java index 3499ed4..1810d35 100644 --- a/src/main/java/cpw/mods/inventorysorter/InventorySorter.java +++ b/src/main/java/cpw/mods/inventorysorter/InventorySorter.java @@ -71,6 +71,8 @@ public class InventorySorter final Set containerblacklist = new HashSet<>(); boolean configLoaded = false; + ItemOrdering itemOrdering = ItemOrdering.BY_COUNT; + public InventorySorter() { INSTANCE = this; final IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -110,6 +112,7 @@ private void updateConfig() { if (!configLoaded) return; Config.CONFIG.containerBlacklist.set(containerblacklist.stream().map(Objects::toString).collect(Collectors.toList())); Config.CONFIG.slotBlacklist.set(new ArrayList<>(slotblacklist)); + Config.CONFIG.itemOrdering.set(itemOrdering); } private void preinit(FMLCommonSetupEvent evt) { @@ -125,6 +128,8 @@ void onConfigLoad(ModConfigEvent configEvent) { this.slotblacklist.addAll(Config.CONFIG.slotBlacklist.get()); this.containerblacklist.clear(); this.containerblacklist.addAll(Config.CONFIG.containerBlacklist.get().stream().map(ResourceLocation::new).collect(Collectors.toSet())); + + itemOrdering = Config.CONFIG.itemOrdering.get(); } boolean wheelModConflicts() { @@ -192,6 +197,14 @@ static int showBlacklist(final CommandContext context) { static Stream listContainers() { return ForgeRegistries.MENU_TYPES.getEntries().stream().map(e->e.getKey().location()); + } + + static int setItemOrdering(final CommandContext context) { + final ItemOrdering newOrdering = context.getArgument("ordering", ItemOrdering.class); + INSTANCE.itemOrdering = newOrdering; + INSTANCE.updateConfig(); + context.getSource().sendSuccess(Component.translatable("inventorysorter.commands.inventorysorter.setorder.ok", newOrdering.toString()), true); + return 0; } static Stream listBlacklist() { diff --git a/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java b/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java index 153b2f5..cf1737b 100644 --- a/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java +++ b/src/main/java/cpw/mods/inventorysorter/InventorySorterCommand.java @@ -26,6 +26,7 @@ import net.minecraftforge.fml.loading.StringUtils; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; +import net.minecraftforge.server.command.EnumArgument; public class InventorySorterCommand { public static void register(final CommandDispatcher dispatcher) { @@ -49,13 +50,14 @@ private enum CommandAction { BLADD(InventorySorter::blackListAdd, 1, Commands.argument("container", new ContainerResourceLocationArgument()).suggests(suggester(InventorySorter::listContainers))), BLREMOVE(InventorySorter::blackListRemove, 4, Commands.argument("container", new ContainerResourceLocationArgument()).suggests(suggester(InventorySorter::listBlacklist))), SHOWLAST(InventorySorter::showLast, 1, null), - LIST(InventorySorter::showBlacklist, 1, null); + LIST(InventorySorter::showBlacklist, 1, null), + SETORDERING(InventorySorter::setItemOrdering, 1, Commands.argument("ordering", EnumArgument.enumArgument(ItemOrdering.class))); private final int permissionLevel; - private RequiredArgumentBuilder suggester; + private RequiredArgumentBuilder suggester; private final ToIntFunction> action; - CommandAction(final ToIntFunction> action, final int permissionLevel, final RequiredArgumentBuilder suggester) { + CommandAction(final ToIntFunction> action, final int permissionLevel, final RequiredArgumentBuilder suggester) { this.action = action; this.permissionLevel = permissionLevel; this.suggester = suggester; diff --git a/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java b/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java new file mode 100644 index 0000000..dc1956d --- /dev/null +++ b/src/main/java/cpw/mods/inventorysorter/ItemOrdering.java @@ -0,0 +1,71 @@ +/* + * Copyright © 2022 David Koňařík + * This file is part of Inventorysorter. + * + * Inventorysorter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Inventorysorter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Inventorysorter. If not, see . + */ + +package cpw.mods.inventorysorter; + +import java.util.Comparator; +import java.util.stream.Stream; + +import com.google.common.collect.Multiset; +import com.google.common.collect.Multiset.Entry; + +import net.minecraftforge.registries.ForgeRegistries; + +/** + * Enum deciding how to order items during sorting + */ +public enum ItemOrdering { + BY_COUNT, + BY_MOD_AND_NAME, + BY_NAME; + + public Stream> ordered(Multiset itemCounts) { + if (this == BY_COUNT) + return orderedByCount(itemCounts); + if (this == BY_MOD_AND_NAME) + return orderedByModAndName(itemCounts); + if (this == BY_NAME) + return orderedByName(itemCounts); + throw new IllegalStateException(); + } + + private static Stream> orderedByCount(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted((a, b) -> { + int countComp = Integer.compare(a.getCount(), b.getCount()); + if (countComp != 0) + return -countComp; // Descending + var itemA = a.getElement().is.getItem(); + var itemB = b.getElement().is.getItem(); + return ForgeRegistries.ITEMS.getKey(itemA).toString() + .compareTo(ForgeRegistries.ITEMS.getKey(itemB).toString()); + }); + } + + private static Stream> orderedByModAndName(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted(Comparator.comparing(e -> + ForgeRegistries.ITEMS.getKey(e.getElement().is.getItem()).toString())); + } + + private static Stream> orderedByName(Multiset itemCounts) { + return itemCounts.entrySet().stream() + .sorted(Comparator.comparing(e -> + ForgeRegistries.ITEMS.getKey(e.getElement().is.getItem()).getPath())); + } +} diff --git a/src/main/java/cpw/mods/inventorysorter/SortingHandler.java b/src/main/java/cpw/mods/inventorysorter/SortingHandler.java index 40b75ce..49decca 100644 --- a/src/main/java/cpw/mods/inventorysorter/SortingHandler.java +++ b/src/main/java/cpw/mods/inventorysorter/SortingHandler.java @@ -21,6 +21,8 @@ import com.google.common.base.*; import com.google.common.collect.*; import net.minecraft.core.Registry; +import com.google.common.collect.Multiset.Entry; + import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.Slot; @@ -29,6 +31,9 @@ import org.apache.logging.log4j.*; import javax.annotation.*; + +import java.util.Comparator; +import java.util.Iterator; import java.util.function.*; import net.minecraft.world.inventory.CraftingContainer; @@ -125,10 +130,10 @@ private void compactInventory(final ContainerContext context, final Multisetnew String[] {containerTypeName.toString()}); - final UnmodifiableIterator> itemsIterator; + final Iterator> itemsIterator; try { - itemsIterator = Multisets.copyHighestCountFirst(itemcounts).entrySet().iterator(); + itemsIterator = InventorySorter.INSTANCE.itemOrdering.ordered(itemcounts).iterator(); } catch (Exception e) { diff --git a/src/main/resources/assets/inventorysorter/lang/en_us.json b/src/main/resources/assets/inventorysorter/lang/en_us.json index 340f3b8..32c3511 100644 --- a/src/main/resources/assets/inventorysorter/lang/en_us.json +++ b/src/main/resources/assets/inventorysorter/lang/en_us.json @@ -22,6 +22,7 @@ "inventorysorter.commands.inventorysorter.showlast.nosort": "You have not sorted a container yet. Try sorting one!", "inventorysorter.commands.inventorysorter.showblacklist.message": "Current blacklist §e{0}§f", "inventorysorter.commands.inventorysorter.showblacklist.empty": "The blacklist is empty", + "inventorysorter.commands.inventorysorter.setorder.ok": "Set ordering method to §e{0}§f", "inventorysorter.config.containerblacklist": "Container blacklist", "inventorysorter.config.slotblacklist": "Slot type blacklist" -} \ No newline at end of file +} diff --git a/src/main/resources/assets/inventorysorter/lang/en_us.lang b/src/main/resources/assets/inventorysorter/lang/en_us.lang index 536b13f..37ccbd5 100644 --- a/src/main/resources/assets/inventorysorter/lang/en_us.lang +++ b/src/main/resources/assets/inventorysorter/lang/en_us.lang @@ -19,4 +19,5 @@ inventorysorter.commands.inventorysorter.blremove.message=Removed %1$s§f from c inventorysorter.commands.inventorysorter.show.message=Last container sorted %1$s inventorysorter.commands.inventorysorter.list.message=Current blacklist %1$s inventorysorter.commands.inventorysorter.list.empty=The blacklist is empty -inventorysorter.commands.inventorysorter.noop=§cThe last command had no effect (maybe try sorting a container?) \ No newline at end of file +inventorysorter.commands.inventorysorter.noop=§cThe last command had no effect (maybe try sorting a container?) +inventorysorter.commands.inventorysorter.setorder.ok=Set ordering method to §e{0}§f