diff --git a/gradle.properties b/gradle.properties index fbb3dfe..c003df0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version=0.16.0 fabric_version=0.102.1+1.21.1 # Mod Properties -mod_version=3.2.6 +mod_version=3.2.9 maven_group=systems.brn archives_base_name=Serverstorage diff --git a/src/main/java/systems/brn/serverstorage/lib/CraftingEntry.java b/src/main/java/systems/brn/serverstorage/lib/CraftingEntry.java index bb8e6eb..b243040 100644 --- a/src/main/java/systems/brn/serverstorage/lib/CraftingEntry.java +++ b/src/main/java/systems/brn/serverstorage/lib/CraftingEntry.java @@ -15,14 +15,20 @@ public class CraftingEntry { public final ArrayList outputStacks; public final RecipeEntry recipeEntry; public final ArrayList> myCraftingRecipeEntries; + public final int totalMax; + public final int eachCraft; + public final int maxCrafts; public CraftingEntry(ItemStack itemStack, RecipeEntry recipeEntry, HashMap inputs, Integer maxCount) { + maxCrafts = maxCount; + eachCraft = itemStack.getCount(); + totalMax = eachCraft * maxCrafts; ArrayList tempOutputStacks = new ArrayList<>(); ItemStack outputStack = itemStack.copy(); outputStack.setCount(maxCount); - outputStack = addCountToLore(itemStack.getCount() * maxCount, outputStack, "Total max: "); - outputStack = addCountToLore(itemStack.getCount(), outputStack, "Each craft: "); - outputStack = addCountToLore(maxCount, outputStack, "Max crafts: "); + outputStack = addCountToLore(totalMax, outputStack, "Total max: "); + outputStack = addCountToLore(eachCraft, outputStack, "Each craft: "); + outputStack = addCountToLore(maxCrafts, outputStack, "Max crafts: "); tempOutputStacks.add(outputStack); for (Map.Entry entry : inputs.entrySet()) { ItemStack stackIn = entry.getKey(); diff --git a/src/main/java/systems/brn/serverstorage/lib/Searchable.java b/src/main/java/systems/brn/serverstorage/lib/Searchable.java new file mode 100644 index 0000000..8f7bc2c --- /dev/null +++ b/src/main/java/systems/brn/serverstorage/lib/Searchable.java @@ -0,0 +1,5 @@ +package systems.brn.serverstorage.lib; + +public interface Searchable { + public void doSearch(String searchText); +} diff --git a/src/main/java/systems/brn/serverstorage/lib/StorageOperations.java b/src/main/java/systems/brn/serverstorage/lib/StorageOperations.java index f6b7790..3ed7185 100644 --- a/src/main/java/systems/brn/serverstorage/lib/StorageOperations.java +++ b/src/main/java/systems/brn/serverstorage/lib/StorageOperations.java @@ -6,9 +6,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; public class StorageOperations { // Modify getSimpleInventory to include item metadata and sort conditionally @@ -20,7 +18,7 @@ public class StorageOperations { } else { Map filteredMap = new HashMap<>(); for (Map.Entry entry : itemStackMap.entrySet()) { - if (filterItem(entry.getKey().getItem(), query)){ + if (filterItem(entry.getKey().getItem(), query)) { ItemStack stack = entry.getKey(); stack.setCount(Math.min(entry.getValue(), stack.getMaxCount())); filteredMap.put(stack, entry.getValue()); @@ -31,7 +29,24 @@ public class StorageOperations { return sortedMap; } - public static boolean filterItem(Item item, String query){ + public static TreeSet sortAndFilterEntries(ArrayList craftingEntries, boolean sortAlphabetically, String query) { + TreeSet sortedSet = getTreeSetCraftingEntries(sortAlphabetically); + + if (query == null || query.isEmpty() || query.equals("*")) { + sortedSet.addAll(craftingEntries); + } else { + ArrayList filteredSet = new ArrayList<>(); + for (CraftingEntry entry : craftingEntries) { + if (!entry.outputStacks.isEmpty() && filterItem(entry.outputStacks.getFirst().getItem(), query)) { + filteredSet.add(entry); + } + } + sortedSet.addAll(filteredSet); + } + return sortedSet; + } + + public static boolean filterItem(Item item, String query) { if (item != null) { String itemName = String.valueOf(item); return itemName == null || itemName.contains(query); @@ -62,6 +77,44 @@ public class StorageOperations { return sortedMap; } + private static @NotNull TreeSet getTreeSetCraftingEntries(boolean sortAlphabetically) { + TreeSet sortedSet; + + if (sortAlphabetically) { + // Sort alphabetically by item name + sortedSet = new TreeSet<>((o1, o2) -> { + if (o1.outputStacks.isEmpty()) { + return 1; + } else if (o2.outputStacks.isEmpty()) { + return -1; + } + String name1 = String.valueOf(o1.outputStacks.getFirst().getItem()); + String name2 = String.valueOf(o2.outputStacks.getFirst().getItem()); + return name1.compareToIgnoreCase(name2); + }); + } else { + // Sort by count in descending order + sortedSet = new TreeSet<>((o1, o2) -> { + if (o1.outputStacks.isEmpty()) { + return 1; + } else if (o2.outputStacks.isEmpty()) { + return -1; + } + int count1 = o1.totalMax; + int count2 = o2.totalMax; + int countCompare = Integer.compare(count2, count1); + // If counts are equal, compare items alphabetically by name + if (countCompare == 0) { + String name1 = String.valueOf(o1.outputStacks.getFirst().getItem()); + String name2 = String.valueOf(o2.outputStacks.getFirst().getItem()); + return name1.compareToIgnoreCase(name2); + } + return countCompare; + }); + } + return sortedSet; + } + public static int canInsertToStack(ItemStack stack1, ItemStack stack2, int maxInsert) { if (stack1.isEmpty() || ItemStack.areItemsEqual(stack1, stack2)) { int remainingSpace = stack1.isEmpty() ? stack2.getMaxCount() : stack1.getMaxCount() - stack1.getCount(); @@ -145,7 +198,7 @@ public class StorageOperations { } } - public static int howMuchFits(ItemStack stack, Inventory inventory){ + public static int howMuchFits(ItemStack stack, Inventory inventory) { int out = 0; for (int i = 0; i < inventory.size(); i++) { ItemStack slotStack = inventory.getStack(i); diff --git a/src/main/java/systems/brn/serverstorage/screens/CraftingScreen.java b/src/main/java/systems/brn/serverstorage/screens/CraftingScreen.java index b965e0f..91bb94b 100644 --- a/src/main/java/systems/brn/serverstorage/screens/CraftingScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/CraftingScreen.java @@ -5,27 +5,30 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.RecipeEntry; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; import systems.brn.serverstorage.lib.CraftingEntry; import systems.brn.serverstorage.lib.PagedGui; +import systems.brn.serverstorage.lib.Searchable; +import systems.brn.serverstorage.lib.WirelessTerminalComponents; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; import static systems.brn.serverstorage.lib.StorageOperations.*; import static systems.brn.serverstorage.lib.Util.getCraftableRecipes; -public class CraftingScreen extends PagedGui { +public class CraftingScreen extends PagedGui implements Searchable { private final StorageScreen storageScreen; private ArrayList craftingEntries; private final StorageInterfaceBlockEntity blockEntity; private ArrayList recipesList; + public String searchQuery; + public boolean sortAlphabetically = false; public CraftingScreen(StorageScreen storageScreen) { super(storageScreen.getPlayer(), null); @@ -57,36 +60,40 @@ public class CraftingScreen extends PagedGui { private ArrayList getAvailableRecipes() { ArrayList recipes = new ArrayList<>(); - - for (CraftingEntry craftingEntry : craftingEntries) { + TreeSet filteredCraftingEntries = sortAndFilterEntries(craftingEntries, getAlphabeticalSorting(), getQueryString()); + for (CraftingEntry craftingEntry : filteredCraftingEntries) { ItemStack stackWithCount = craftingEntry.outputStacks.getFirst().copy(); if (stackWithCount.getCount() > stackWithCount.getMaxCount()) { stackWithCount.setCount(stackWithCount.getMaxCount()); } - recipes.add( - DisplayElement.of(new GuiElementBuilder(stackWithCount) - .setCallback((i, clickType, slotActionType) -> { - playClickSound(player); - RecipeEntry recipeEntry = craftingEntry.recipeEntry; + if (stackWithCount.getItem() != null && filterItem(stackWithCount.getItem(), getQueryString())) { + recipes.add( + DisplayElement.of(new GuiElementBuilder(stackWithCount) + .setCallback((i, clickType, slotActionType) -> { + if (storageScreen.checkDistance()) { + playClickSound(player); + RecipeEntry recipeEntry = craftingEntry.recipeEntry; - // Crafting logic based on click type - if (clickType.isLeft) { // put into player inventory - if (clickType.shift) { // craft all - craftAll(player, recipeEntry, true); - } else { // craft one - craftOne(player, recipeEntry, true); + // Crafting logic based on click type + if (clickType.isLeft) { // put into player inventory + if (clickType.shift) { // craft all + craftAll(player, recipeEntry, true); + } else { // craft one + craftOne(player, recipeEntry, true); + } + } else if (clickType.isRight) { // put back into storage + if (clickType.shift) { // craft all + craftAll(player, recipeEntry, false); + } else { // craft one + craftOne(player, recipeEntry, false); + } + } + updateDisplay(); } - } else if (clickType.isRight) { // put back into storage - if (clickType.shift) { // craft all - craftAll(player, recipeEntry, false); - } else { // craft one - craftOne(player, recipeEntry, false); - } - } - updateDisplay(); - }) - ) - ); + }) + ) + ); + } } return recipes; } @@ -110,6 +117,7 @@ public class CraftingScreen extends PagedGui { } private boolean craftOne(PlayerEntity player, RecipeEntry recipeEntry, boolean toPlayerInventory) { + this.storageScreen.refreshTerminals(); ArrayList stacksToRemove = new ArrayList<>(); // Check and remove ingredients for one crafting operation @@ -190,6 +198,55 @@ public class CraftingScreen extends PagedGui { } } + public String getQueryString() { + if (blockEntity == null) { + return storageScreen.itemStack.getOrDefault(WirelessTerminalComponents.QUERY_STRING, ""); + } else { + return blockEntity.searchString == null ? "*" : blockEntity.searchString; + } + } + + public void setQueryString(String queryString) { + if (blockEntity == null) { + storageScreen.itemStack.set(WirelessTerminalComponents.QUERY_STRING, queryString); + } else { + blockEntity.searchString = queryString; + } + } + + public boolean getAlphabeticalSorting() { + if (blockEntity == null) { + return storageScreen.itemStack.getOrDefault(WirelessTerminalComponents.SORT_ALPHABETICALLY, false); + } else { + return blockEntity.sortAlphabetically; + } + } + + public void setAlphabeticalSorting(boolean sorting) { + if (blockEntity == null) { + storageScreen.itemStack.set(WirelessTerminalComponents.SORT_ALPHABETICALLY, sorting); + } else { + blockEntity.sortAlphabetically = sorting; + } + } + + @Override + protected DisplayElement sorting() { + return DisplayElement.of( + new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.translatable(getAlphabeticalSorting() ? "A->Z" : "9->1").formatted(Formatting.WHITE)) + .hideDefaultTooltip().noDefaults() + .setSkullOwner(getAlphabeticalSorting() ? GUI_A : GUI_1) + .setCallback((x, y, z) -> { + playClickSound(getPlayer()); + if (storageScreen.checkDistance()) { + setAlphabeticalSorting(!getAlphabeticalSorting()); + updateDisplay(); + } + }) + ); + } + @Override public boolean open() { if (this.blockEntity != null) { @@ -225,4 +282,35 @@ public class CraftingScreen extends PagedGui { return DisplayElement.empty(); } } + + @Override + public void doSearch(String searchText) { + setQueryString(searchText); + this.updateDisplay(); + } + + @Override + protected DisplayElement search() { + String searchString = getQueryString(); + if (searchString == null || searchString.isEmpty() || searchString.equals("*")) { + searchString = "Filter not set"; + } + return DisplayElement.of( + new GuiElementBuilder(Items.PLAYER_HEAD) + .setName(Text.literal(searchString).formatted(Formatting.WHITE)) + .hideDefaultTooltip().noDefaults() + .setSkullOwner(GUI_QUESTION_MARK) + .setCallback((x, y, z) -> { + playClickSound(getPlayer()); + if (storageScreen.checkDistance()) { + if (y.isRight) { + doSearch(""); + } else if (y.isLeft) { + SearchScreen searchScreen = new SearchScreen(this, ""); + searchScreen.open(); + } + } + }) + ); + } } diff --git a/src/main/java/systems/brn/serverstorage/screens/SearchScreen.java b/src/main/java/systems/brn/serverstorage/screens/SearchScreen.java index ed967b0..c388e1c 100644 --- a/src/main/java/systems/brn/serverstorage/screens/SearchScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/SearchScreen.java @@ -3,6 +3,7 @@ package systems.brn.serverstorage.screens; import eu.pb4.sgui.api.gui.AnvilInputGui; import eu.pb4.sgui.api.gui.SimpleGui; import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; +import systems.brn.serverstorage.lib.Searchable; public class SearchScreen extends AnvilInputGui { @@ -20,10 +21,11 @@ public class SearchScreen extends AnvilInputGui { super.onClose(); parentScreen.open(); String query = this.getInput(); - if (parentScreen instanceof StorageScreen storageScreen) { - storageScreen.doSearch(query); - } else if (parentScreen instanceof SettingsScreen settingsScreen && settingsScreen.blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) { - inventoryInterfaceBlockEntity.doSearch(query); + if (parentScreen instanceof Searchable searchable) { + searchable.doSearch(query); + if (parentScreen instanceof SettingsScreen settingsScreen && settingsScreen.blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) { + inventoryInterfaceBlockEntity.doSearch(query); + } } } } diff --git a/src/main/java/systems/brn/serverstorage/screens/SettingsScreen.java b/src/main/java/systems/brn/serverstorage/screens/SettingsScreen.java index 6238429..ee034a8 100644 --- a/src/main/java/systems/brn/serverstorage/screens/SettingsScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/SettingsScreen.java @@ -10,10 +10,11 @@ import net.minecraft.util.Formatting; import org.jetbrains.annotations.Nullable; import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; import systems.brn.serverstorage.lib.PagedGui; +import systems.brn.serverstorage.lib.Searchable; import java.util.ArrayList; -public class SettingsScreen extends PagedGui { +public class SettingsScreen extends PagedGui implements Searchable { private final SimpleGui parentScreen; @@ -33,6 +34,10 @@ public class SettingsScreen extends PagedGui { this.updateDisplay(); } + public void doSearch(String query) { + + } + public SettingsScreen(StorageScreen parentScreen) { this(parentScreen, parentScreen.getPlayer(), parentScreen.blockEntity); } diff --git a/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java b/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java index 33153dc..ea8ecb1 100644 --- a/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/StorageScreen.java @@ -17,10 +17,7 @@ import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; -import systems.brn.serverstorage.lib.PagedGui; -import systems.brn.serverstorage.lib.RadioDistance; -import systems.brn.serverstorage.lib.StorageNetwork; -import systems.brn.serverstorage.lib.WirelessTerminalComponents; +import systems.brn.serverstorage.lib.*; import java.util.Map; @@ -30,7 +27,7 @@ import static systems.brn.serverstorage.lib.StorageOperations.*; import static systems.brn.serverstorage.lib.Util.addCountToLore; import static systems.brn.serverstorage.lib.Util.removeCountFromLore; -public class StorageScreen extends PagedGui { +public class StorageScreen extends PagedGui implements Searchable { private final ServerPlayerEntity player; public final StorageInterfaceBlockEntity blockEntity; public final StorageNetwork network; @@ -249,7 +246,7 @@ public class StorageScreen extends PagedGui { } public void insertItem(ItemStack stack, boolean isCursor) { - if (!checkDistance()) { + if (!checkDistance() || stack.getItem() == itemStack.getItem()) { return; } int canPutIn = stack.getCount() - getNetwork().putItemStackRemainder(stack); diff --git a/src/main/java/systems/brn/serverstorage/screens/WirelessTerminalSelectorScreen.java b/src/main/java/systems/brn/serverstorage/screens/WirelessTerminalSelectorScreen.java index 7e6ba55..25a9f65 100644 --- a/src/main/java/systems/brn/serverstorage/screens/WirelessTerminalSelectorScreen.java +++ b/src/main/java/systems/brn/serverstorage/screens/WirelessTerminalSelectorScreen.java @@ -11,10 +11,7 @@ import net.minecraft.util.Formatting; import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; import systems.brn.serverstorage.items.WirelessTerminalItem; -import systems.brn.serverstorage.lib.PagedGui; -import systems.brn.serverstorage.lib.SessionStorageClass; -import systems.brn.serverstorage.lib.Util; -import systems.brn.serverstorage.lib.WirelessTerminalComponents; +import systems.brn.serverstorage.lib.*; import java.util.ArrayList; import java.util.List;