Improve crafting screen

This commit is contained in:
Bruno Rybársky 2024-09-08 08:23:14 +02:00
parent af56360fad
commit f1dd6b9c3c
9 changed files with 207 additions and 54 deletions

@ -11,7 +11,7 @@ loader_version=0.16.0
fabric_version=0.102.1+1.21.1 fabric_version=0.102.1+1.21.1
# Mod Properties # Mod Properties
mod_version=3.2.6 mod_version=3.2.9
maven_group=systems.brn maven_group=systems.brn
archives_base_name=Serverstorage archives_base_name=Serverstorage

@ -15,14 +15,20 @@ public class CraftingEntry {
public final ArrayList<ItemStack> outputStacks; public final ArrayList<ItemStack> outputStacks;
public final RecipeEntry<CraftingRecipe> recipeEntry; public final RecipeEntry<CraftingRecipe> recipeEntry;
public final ArrayList<RecipeEntry<CraftingRecipe>> myCraftingRecipeEntries; public final ArrayList<RecipeEntry<CraftingRecipe>> myCraftingRecipeEntries;
public final int totalMax;
public final int eachCraft;
public final int maxCrafts;
public CraftingEntry(ItemStack itemStack, RecipeEntry<CraftingRecipe> recipeEntry, HashMap<ItemStack, Integer> inputs, Integer maxCount) { public CraftingEntry(ItemStack itemStack, RecipeEntry<CraftingRecipe> recipeEntry, HashMap<ItemStack, Integer> inputs, Integer maxCount) {
maxCrafts = maxCount;
eachCraft = itemStack.getCount();
totalMax = eachCraft * maxCrafts;
ArrayList<ItemStack> tempOutputStacks = new ArrayList<>(); ArrayList<ItemStack> tempOutputStacks = new ArrayList<>();
ItemStack outputStack = itemStack.copy(); ItemStack outputStack = itemStack.copy();
outputStack.setCount(maxCount); outputStack.setCount(maxCount);
outputStack = addCountToLore(itemStack.getCount() * maxCount, outputStack, "Total max: "); outputStack = addCountToLore(totalMax, outputStack, "Total max: ");
outputStack = addCountToLore(itemStack.getCount(), outputStack, "Each craft: "); outputStack = addCountToLore(eachCraft, outputStack, "Each craft: ");
outputStack = addCountToLore(maxCount, outputStack, "Max crafts: "); outputStack = addCountToLore(maxCrafts, outputStack, "Max crafts: ");
tempOutputStacks.add(outputStack); tempOutputStacks.add(outputStack);
for (Map.Entry<ItemStack, Integer> entry : inputs.entrySet()) { for (Map.Entry<ItemStack, Integer> entry : inputs.entrySet()) {
ItemStack stackIn = entry.getKey(); ItemStack stackIn = entry.getKey();

@ -0,0 +1,5 @@
package systems.brn.serverstorage.lib;
public interface Searchable {
public void doSearch(String searchText);
}

@ -6,9 +6,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.TreeMap;
public class StorageOperations { public class StorageOperations {
// Modify getSimpleInventory to include item metadata and sort conditionally // Modify getSimpleInventory to include item metadata and sort conditionally
@ -20,7 +18,7 @@ public class StorageOperations {
} else { } else {
Map<ItemStack, Integer> filteredMap = new HashMap<>(); Map<ItemStack, Integer> filteredMap = new HashMap<>();
for (Map.Entry<ItemStack, Integer> entry : itemStackMap.entrySet()) { for (Map.Entry<ItemStack, Integer> entry : itemStackMap.entrySet()) {
if (filterItem(entry.getKey().getItem(), query)){ if (filterItem(entry.getKey().getItem(), query)) {
ItemStack stack = entry.getKey(); ItemStack stack = entry.getKey();
stack.setCount(Math.min(entry.getValue(), stack.getMaxCount())); stack.setCount(Math.min(entry.getValue(), stack.getMaxCount()));
filteredMap.put(stack, entry.getValue()); filteredMap.put(stack, entry.getValue());
@ -31,7 +29,24 @@ public class StorageOperations {
return sortedMap; return sortedMap;
} }
public static boolean filterItem(Item item, String query){ public static TreeSet<CraftingEntry> sortAndFilterEntries(ArrayList<CraftingEntry> craftingEntries, boolean sortAlphabetically, String query) {
TreeSet<CraftingEntry> sortedSet = getTreeSetCraftingEntries(sortAlphabetically);
if (query == null || query.isEmpty() || query.equals("*")) {
sortedSet.addAll(craftingEntries);
} else {
ArrayList<CraftingEntry> 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) { if (item != null) {
String itemName = String.valueOf(item); String itemName = String.valueOf(item);
return itemName == null || itemName.contains(query); return itemName == null || itemName.contains(query);
@ -62,6 +77,44 @@ public class StorageOperations {
return sortedMap; return sortedMap;
} }
private static @NotNull TreeSet<CraftingEntry> getTreeSetCraftingEntries(boolean sortAlphabetically) {
TreeSet<CraftingEntry> 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) { public static int canInsertToStack(ItemStack stack1, ItemStack stack2, int maxInsert) {
if (stack1.isEmpty() || ItemStack.areItemsEqual(stack1, stack2)) { if (stack1.isEmpty() || ItemStack.areItemsEqual(stack1, stack2)) {
int remainingSpace = stack1.isEmpty() ? stack2.getMaxCount() : stack1.getMaxCount() - stack1.getCount(); 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; int out = 0;
for (int i = 0; i < inventory.size(); i++) { for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i); ItemStack slotStack = inventory.getStack(i);

@ -5,27 +5,30 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeEntry; import net.minecraft.recipe.RecipeEntry;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.serverstorage.lib.CraftingEntry; import systems.brn.serverstorage.lib.CraftingEntry;
import systems.brn.serverstorage.lib.PagedGui; 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.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static systems.brn.serverstorage.lib.StorageOperations.*; import static systems.brn.serverstorage.lib.StorageOperations.*;
import static systems.brn.serverstorage.lib.Util.getCraftableRecipes; 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 final StorageScreen storageScreen;
private ArrayList<CraftingEntry> craftingEntries; private ArrayList<CraftingEntry> craftingEntries;
private final StorageInterfaceBlockEntity blockEntity; private final StorageInterfaceBlockEntity blockEntity;
private ArrayList<DisplayElement> recipesList; private ArrayList<DisplayElement> recipesList;
public String searchQuery;
public boolean sortAlphabetically = false;
public CraftingScreen(StorageScreen storageScreen) { public CraftingScreen(StorageScreen storageScreen) {
super(storageScreen.getPlayer(), null); super(storageScreen.getPlayer(), null);
@ -57,36 +60,40 @@ public class CraftingScreen extends PagedGui {
private ArrayList<DisplayElement> getAvailableRecipes() { private ArrayList<DisplayElement> getAvailableRecipes() {
ArrayList<DisplayElement> recipes = new ArrayList<>(); ArrayList<DisplayElement> recipes = new ArrayList<>();
TreeSet<CraftingEntry> filteredCraftingEntries = sortAndFilterEntries(craftingEntries, getAlphabeticalSorting(), getQueryString());
for (CraftingEntry craftingEntry : craftingEntries) { for (CraftingEntry craftingEntry : filteredCraftingEntries) {
ItemStack stackWithCount = craftingEntry.outputStacks.getFirst().copy(); ItemStack stackWithCount = craftingEntry.outputStacks.getFirst().copy();
if (stackWithCount.getCount() > stackWithCount.getMaxCount()) { if (stackWithCount.getCount() > stackWithCount.getMaxCount()) {
stackWithCount.setCount(stackWithCount.getMaxCount()); stackWithCount.setCount(stackWithCount.getMaxCount());
} }
recipes.add( if (stackWithCount.getItem() != null && filterItem(stackWithCount.getItem(), getQueryString())) {
DisplayElement.of(new GuiElementBuilder(stackWithCount) recipes.add(
.setCallback((i, clickType, slotActionType) -> { DisplayElement.of(new GuiElementBuilder(stackWithCount)
playClickSound(player); .setCallback((i, clickType, slotActionType) -> {
RecipeEntry<CraftingRecipe> recipeEntry = craftingEntry.recipeEntry; if (storageScreen.checkDistance()) {
playClickSound(player);
RecipeEntry<CraftingRecipe> recipeEntry = craftingEntry.recipeEntry;
// Crafting logic based on click type // Crafting logic based on click type
if (clickType.isLeft) { // put into player inventory if (clickType.isLeft) { // put into player inventory
if (clickType.shift) { // craft all if (clickType.shift) { // craft all
craftAll(player, recipeEntry, true); craftAll(player, recipeEntry, true);
} else { // craft one } else { // craft one
craftOne(player, recipeEntry, true); 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; return recipes;
} }
@ -110,6 +117,7 @@ public class CraftingScreen extends PagedGui {
} }
private boolean craftOne(PlayerEntity player, RecipeEntry<CraftingRecipe> recipeEntry, boolean toPlayerInventory) { private boolean craftOne(PlayerEntity player, RecipeEntry<CraftingRecipe> recipeEntry, boolean toPlayerInventory) {
this.storageScreen.refreshTerminals();
ArrayList<ItemStack> stacksToRemove = new ArrayList<>(); ArrayList<ItemStack> stacksToRemove = new ArrayList<>();
// Check and remove ingredients for one crafting operation // 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 @Override
public boolean open() { public boolean open() {
if (this.blockEntity != null) { if (this.blockEntity != null) {
@ -225,4 +282,35 @@ public class CraftingScreen extends PagedGui {
return DisplayElement.empty(); 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();
}
}
})
);
}
} }

@ -3,6 +3,7 @@ package systems.brn.serverstorage.screens;
import eu.pb4.sgui.api.gui.AnvilInputGui; import eu.pb4.sgui.api.gui.AnvilInputGui;
import eu.pb4.sgui.api.gui.SimpleGui; import eu.pb4.sgui.api.gui.SimpleGui;
import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.serverstorage.lib.Searchable;
public class SearchScreen extends AnvilInputGui { public class SearchScreen extends AnvilInputGui {
@ -20,10 +21,11 @@ public class SearchScreen extends AnvilInputGui {
super.onClose(); super.onClose();
parentScreen.open(); parentScreen.open();
String query = this.getInput(); String query = this.getInput();
if (parentScreen instanceof StorageScreen storageScreen) { if (parentScreen instanceof Searchable searchable) {
storageScreen.doSearch(query); searchable.doSearch(query);
} else if (parentScreen instanceof SettingsScreen settingsScreen && settingsScreen.blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) { if (parentScreen instanceof SettingsScreen settingsScreen && settingsScreen.blockEntity instanceof InventoryInterfaceBlockEntity inventoryInterfaceBlockEntity) {
inventoryInterfaceBlockEntity.doSearch(query); inventoryInterfaceBlockEntity.doSearch(query);
}
} }
} }
} }

@ -10,10 +10,11 @@ import net.minecraft.util.Formatting;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.InventoryInterfaceBlockEntity;
import systems.brn.serverstorage.lib.PagedGui; import systems.brn.serverstorage.lib.PagedGui;
import systems.brn.serverstorage.lib.Searchable;
import java.util.ArrayList; import java.util.ArrayList;
public class SettingsScreen extends PagedGui { public class SettingsScreen extends PagedGui implements Searchable {
private final SimpleGui parentScreen; private final SimpleGui parentScreen;
@ -33,6 +34,10 @@ public class SettingsScreen extends PagedGui {
this.updateDisplay(); this.updateDisplay();
} }
public void doSearch(String query) {
}
public SettingsScreen(StorageScreen parentScreen) { public SettingsScreen(StorageScreen parentScreen) {
this(parentScreen, parentScreen.getPlayer(), parentScreen.blockEntity); this(parentScreen, parentScreen.getPlayer(), parentScreen.blockEntity);
} }

@ -17,10 +17,7 @@ import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.RadioInterfaceBlockEntity;
import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity; import systems.brn.serverstorage.blockentities.StorageInterfaceBlockEntity;
import systems.brn.serverstorage.lib.PagedGui; import systems.brn.serverstorage.lib.*;
import systems.brn.serverstorage.lib.RadioDistance;
import systems.brn.serverstorage.lib.StorageNetwork;
import systems.brn.serverstorage.lib.WirelessTerminalComponents;
import java.util.Map; 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.addCountToLore;
import static systems.brn.serverstorage.lib.Util.removeCountFromLore; import static systems.brn.serverstorage.lib.Util.removeCountFromLore;
public class StorageScreen extends PagedGui { public class StorageScreen extends PagedGui implements Searchable {
private final ServerPlayerEntity player; private final ServerPlayerEntity player;
public final StorageInterfaceBlockEntity blockEntity; public final StorageInterfaceBlockEntity blockEntity;
public final StorageNetwork network; public final StorageNetwork network;
@ -249,7 +246,7 @@ public class StorageScreen extends PagedGui {
} }
public void insertItem(ItemStack stack, boolean isCursor) { public void insertItem(ItemStack stack, boolean isCursor) {
if (!checkDistance()) { if (!checkDistance() || stack.getItem() == itemStack.getItem()) {
return; return;
} }
int canPutIn = stack.getCount() - getNetwork().putItemStackRemainder(stack); int canPutIn = stack.getCount() - getNetwork().putItemStackRemainder(stack);

@ -11,10 +11,7 @@ import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import systems.brn.serverstorage.items.WirelessTerminalItem; import systems.brn.serverstorage.items.WirelessTerminalItem;
import systems.brn.serverstorage.lib.PagedGui; import systems.brn.serverstorage.lib.*;
import systems.brn.serverstorage.lib.SessionStorageClass;
import systems.brn.serverstorage.lib.Util;
import systems.brn.serverstorage.lib.WirelessTerminalComponents;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;