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
# Mod Properties
mod_version=3.2.6
mod_version=3.2.9
maven_group=systems.brn
archives_base_name=Serverstorage

@ -15,14 +15,20 @@ public class CraftingEntry {
public final ArrayList<ItemStack> outputStacks;
public final RecipeEntry<CraftingRecipe> recipeEntry;
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) {
maxCrafts = maxCount;
eachCraft = itemStack.getCount();
totalMax = eachCraft * maxCrafts;
ArrayList<ItemStack> 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<ItemStack, Integer> entry : inputs.entrySet()) {
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 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<ItemStack, Integer> filteredMap = new HashMap<>();
for (Map.Entry<ItemStack, Integer> 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<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) {
String itemName = String.valueOf(item);
return itemName == null || itemName.contains(query);
@ -62,6 +77,44 @@ public class StorageOperations {
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) {
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);

@ -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<CraftingEntry> craftingEntries;
private final StorageInterfaceBlockEntity blockEntity;
private ArrayList<DisplayElement> 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<DisplayElement> getAvailableRecipes() {
ArrayList<DisplayElement> recipes = new ArrayList<>();
for (CraftingEntry craftingEntry : craftingEntries) {
TreeSet<CraftingEntry> 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<CraftingRecipe> 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<CraftingRecipe> 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<CraftingRecipe> recipeEntry, boolean toPlayerInventory) {
this.storageScreen.refreshTerminals();
ArrayList<ItemStack> 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();
}
}
})
);
}
}

@ -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);
}
}
}
}

@ -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);
}

@ -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);

@ -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;