diff --git a/gradle.properties b/gradle.properties index c7b174c..448520d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ loader_version=0.15.11 fabric_version=0.100.4+1.21 # Mod Properties -mod_version=2.6.2 +mod_version=3.0.0 maven_group=systems.brn archives_base_name=Server_storage diff --git a/src/main/java/systems/brn/server_storage/ServerStorage.java b/src/main/java/systems/brn/server_storage/ServerStorage.java index 6a1252b..7707255 100644 --- a/src/main/java/systems/brn/server_storage/ServerStorage.java +++ b/src/main/java/systems/brn/server_storage/ServerStorage.java @@ -56,9 +56,6 @@ public class ServerStorage implements ModInitializer { public static List DRIVES; public static List HEADS; - public static final GameRules.Key ServerStorage_Crafting_Enable = - GameRuleRegistry.register("enableServerStorageCrafting", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(false)); - public static Identifier id(String path) { return Identifier.of(MOD_ID, path); diff --git a/src/main/java/systems/brn/server_storage/blockentities/StorageInterfaceBlockEntity.java b/src/main/java/systems/brn/server_storage/blockentities/StorageInterfaceBlockEntity.java index f739f03..d3a29f5 100644 --- a/src/main/java/systems/brn/server_storage/blockentities/StorageInterfaceBlockEntity.java +++ b/src/main/java/systems/brn/server_storage/blockentities/StorageInterfaceBlockEntity.java @@ -6,6 +6,7 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.math.BlockPos; import systems.brn.server_storage.lib.StorageNetwork; +import systems.brn.server_storage.screens.CraftingScreen; import systems.brn.server_storage.screens.StorageScreen; import java.util.ArrayList; @@ -14,22 +15,19 @@ import static systems.brn.server_storage.ServerStorage.STORAGE_INTERFACE_BLOCK_E public class StorageInterfaceBlockEntity extends BlockEntity { - public void removeScreen(StorageScreen storageScreenToDelete) { - openStorageScreens.remove(storageScreenToDelete); - } - public Boolean sortAlphabetically = false; public String searchString = ""; public int page = 0; public StorageNetwork network; public final ArrayList openStorageScreens = new ArrayList<>(); + public final ArrayList openCraftingScreens = new ArrayList<>(); public StorageInterfaceBlockEntity(BlockPos pos, BlockState state) { super(STORAGE_INTERFACE_BLOCK_ENTITY, pos, state); } - public void justReindexDrives() { + public void reindexDrives() { if (this.network != null) { this.network.reindexNetwork(world, this.pos, sortAlphabetically, searchString); } else { @@ -37,8 +35,8 @@ public class StorageInterfaceBlockEntity extends BlockEntity { } } - public void reindexDrives() { - justReindexDrives(); + public void refreshTerminals() { + reindexDrives(); this.network.updateDisplays(); } @@ -46,6 +44,9 @@ public class StorageInterfaceBlockEntity extends BlockEntity { for (StorageScreen screen : openStorageScreens) { screen.updateDisplay(); } + for (CraftingScreen screen : openCraftingScreens) { + screen.updateDisplay(); + } } // Serialize the BlockEntity diff --git a/src/main/java/systems/brn/server_storage/lib/StorageNetwork.java b/src/main/java/systems/brn/server_storage/lib/StorageNetwork.java index ae59146..673a730 100644 --- a/src/main/java/systems/brn/server_storage/lib/StorageNetwork.java +++ b/src/main/java/systems/brn/server_storage/lib/StorageNetwork.java @@ -180,7 +180,7 @@ public class StorageNetwork { } public boolean canRemove(ItemStack stackToRemove) { - return canRemoveCount(stackToRemove, itemStackMap) == 0; + return canRemoveRemainingCount(stackToRemove, itemStackMap) == 0; } public ItemStack removeItemStack(ItemStack stackToRemove) { diff --git a/src/main/java/systems/brn/server_storage/lib/StorageOperations.java b/src/main/java/systems/brn/server_storage/lib/StorageOperations.java index 31c824a..5ec351c 100644 --- a/src/main/java/systems/brn/server_storage/lib/StorageOperations.java +++ b/src/main/java/systems/brn/server_storage/lib/StorageOperations.java @@ -159,7 +159,7 @@ public class StorageOperations { return out; } - public static int canRemoveCount(ItemStack stackToRemove, Map itemsMap) { + public static int canRemoveRemainingCount(ItemStack stackToRemove, Map itemsMap) { int remainingToRemove = stackToRemove.getCount(); for (Map.Entry entry : itemsMap.entrySet()) { diff --git a/src/main/java/systems/brn/server_storage/lib/Util.java b/src/main/java/systems/brn/server_storage/lib/Util.java index e120eed..d363bb9 100644 --- a/src/main/java/systems/brn/server_storage/lib/Util.java +++ b/src/main/java/systems/brn/server_storage/lib/Util.java @@ -112,95 +112,58 @@ public class Util { ArrayList craftingEntries = new ArrayList<>(); for (RecipeEntry recipe : allRecipes) { - int maxAmount = -1; + int maxAmount = Integer.MAX_VALUE; boolean canMake = true; - boolean needToAdd = true; - CraftingEntry finalEntry; HashMap finalInputs = new HashMap<>(); + Map ingredientCounts = new HashMap<>(); + + // Count the occurrences of each ingredient in the recipe for (Ingredient ingredient : recipe.value().getIngredients()) { - HashMap inputsTemp = new HashMap<>(); for (ItemStack stack : ingredient.getMatchingStacks()) { - if (stack.isEmpty()) { - break; - } else { - //if inventory contains stack - boolean foundUsableStack = false; - for (Map.Entry entry : inputsTemp.entrySet()) { - ItemStack stackIn = entry.getKey(); - Integer count = entry.getValue(); - if (stackIn.getItem() == stack.getItem()) { - count += stack.getCount(); - entry.setValue(count); // Update the value in the map - foundUsableStack = true; - break; - } - } - if (!foundUsableStack) { - inputsTemp.put(stack, stack.getCount()); - } - } - } - HashMap inputs = new HashMap<>(); - for (Map.Entry entry : inputsTemp.entrySet()) { - ItemStack stackIn = entry.getKey(); - Integer count = entry.getValue(); - stackIn.setCount(count); - inputs.put(stackIn, stackIn.getCount()); - } - for (Map.Entry entry : inputs.entrySet()) { - ItemStack stackIn = entry.getKey(); - Integer count = entry.getValue(); - boolean itemFound = false; - for (Map.Entry itemEntry : itemStackMap.entrySet()){ - Item slotItem = itemEntry.getKey().getItem(); - int slotCount = itemEntry.getValue(); - if (stackIn.getItem() == slotItem) { - count -= slotCount; - entry.setValue(count); - itemFound = true; - } - } - if (!itemFound) { - maxAmount = 0; - } - } - for (Map.Entry entry : inputs.entrySet()) { - ItemStack stackIn = entry.getKey(); - Integer count = entry.getValue(); - if (count > 0) { - canMake = false; - } else { - int thisMaxAmount = Math.floorDivExact(Math.abs(count), stackIn.getCount()); - if (maxAmount == -1) { - maxAmount = thisMaxAmount; - } else { - maxAmount = Math.min(maxAmount, thisMaxAmount); - } - } - } - if (maxAmount > 0 && canMake && needToAdd) { - ItemStack outputItem = recipe.value().getResult(server.getRegistryManager()).copy(); - finalEntry = new CraftingEntry(outputItem, recipe, inputs, maxAmount); - finalInputs.putAll(inputs); - for (int i = 0; i < craftingEntries.size(); i++) { - CraftingEntry entryLoop = craftingEntries.get(i); - for (ItemStack outputStack : entryLoop.outputStacks) { - if (ItemStack.areItemsAndComponentsEqual(outputStack, outputItem)) { - needToAdd = false; - if (maxAmount > outputStack.getCount()) { - craftingEntries.set(i, finalEntry); - break; - } - } - } - } - } else { - break; + if (stack.isEmpty()) continue; + ingredientCounts.put(stack.getItem(), ingredientCounts.getOrDefault(stack.getItem(), 0) + 1); } } - if (needToAdd && maxAmount > 0) { + + boolean usesAnyIngredient = false; + + for (Ingredient ingredient : recipe.value().getIngredients()) { + int totalAvailable = 0; + HashMap inputsTemp = new HashMap<>(); + + for (ItemStack stack : ingredient.getMatchingStacks()) { + if (stack.isEmpty()) continue; + for (Map.Entry entry : itemStackMap.entrySet()) { + ItemStack inventoryStack = entry.getKey(); + int inventoryCount = entry.getValue(); + + if (ItemStack.areItemsEqual(stack, inventoryStack)) { + totalAvailable += inventoryCount; + inputsTemp.put(stack, inventoryCount); + usesAnyIngredient = true; + } + } + } + + if (totalAvailable == 0) { + canMake = false; + break; + } + + int requiredCount = ingredient.getMatchingStacks()[0].getCount(); + int occurrences = ingredientCounts.get(ingredient.getMatchingStacks()[0].getItem()); + maxAmount = Math.min(maxAmount, totalAvailable / (requiredCount * occurrences)); + + for (Map.Entry entry : inputsTemp.entrySet()) { + ItemStack stackIn = entry.getKey(); + int count = entry.getValue(); + finalInputs.put(stackIn, count); + } + } + + if (canMake && maxAmount > 0 && usesAnyIngredient) { ItemStack outputItem = recipe.value().getResult(server.getRegistryManager()).copy(); - finalEntry = new CraftingEntry(outputItem, recipe, finalInputs, maxAmount); + CraftingEntry finalEntry = new CraftingEntry(outputItem, recipe, finalInputs, maxAmount); craftingEntries.add(finalEntry); } } diff --git a/src/main/java/systems/brn/server_storage/screens/CraftingScreen.java b/src/main/java/systems/brn/server_storage/screens/CraftingScreen.java index c9f745f..6c0295c 100644 --- a/src/main/java/systems/brn/server_storage/screens/CraftingScreen.java +++ b/src/main/java/systems/brn/server_storage/screens/CraftingScreen.java @@ -23,11 +23,8 @@ import static systems.brn.server_storage.lib.Util.getCraftableRecipes; public class CraftingScreen extends PagedGui { private final StorageScreen storageScreen; - private ArrayList craftingEntries; - private final StorageInterfaceBlockEntity blockEntity; - private ArrayList recipesList; public CraftingScreen(StorageScreen storageScreen) { @@ -39,8 +36,8 @@ public class CraftingScreen extends PagedGui { } @Override - public void updateDisplay(){ - blockEntity.reindexDrives(); + public void updateDisplay() { + blockEntity.reindexDrives(); // Use justReindexDrives to avoid looping Map itemStackMap = new HashMap<>(); addInventoryToMap(storageScreen.getPlayer().getInventory(), itemStackMap); itemStackMap.putAll(blockEntity.network.itemStackMap); @@ -54,7 +51,7 @@ public class CraftingScreen extends PagedGui { ArrayList recipes = new ArrayList<>(); for (CraftingEntry craftingEntry : craftingEntries) { - ItemStack stackWithCount = craftingEntry.outputStacks.getFirst().copy(); + ItemStack stackWithCount = craftingEntry.outputStacks.get(0).copy(); if (stackWithCount.getCount() > stackWithCount.getMaxCount()) { stackWithCount.setCount(stackWithCount.getMaxCount()); } @@ -68,14 +65,14 @@ public class CraftingScreen extends PagedGui { if (clickType.isLeft) { // put into player inventory if (clickType.shift) { // craft all craftAll(player, recipeEntry, true); - } else { // craft one stack - craftOneStack(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 stack - craftOneStack(player, recipeEntry, false); + } else { // craft one + craftOne(player, recipeEntry, false); } } updateDisplay(); @@ -88,7 +85,7 @@ public class CraftingScreen extends PagedGui { private void craftAll(PlayerEntity player, RecipeEntry recipeEntry, boolean toPlayerInventory) { while (canCraft(recipeEntry)) { - if (craftOneStack(player, recipeEntry, toPlayerInventory)) { + if (craftOne(player, recipeEntry, toPlayerInventory)) { return; } } @@ -96,94 +93,109 @@ public class CraftingScreen extends PagedGui { private boolean canCraft(RecipeEntry recipeEntry) { for (Ingredient ingredient : recipeEntry.value().getIngredients()) { - ItemStack stackToRemove = findMatchingStack(ingredient); - if (stackToRemove == null) { - return false; - } - int requiredCount = canRemoveCount(stackToRemove, this.blockEntity.network.itemStackMap); - - Map playerInventory = new HashMap<>(); - addInventoryToMap(this.storageScreen.getPlayer().getInventory(), playerInventory); - if (requiredCount > 0 && canRemoveCount(stackToRemove, playerInventory) < requiredCount) { + if (findMatchingStack(ingredient) == null) { return false; } } return true; } - private boolean craftOneStack(PlayerEntity player, RecipeEntry recipeEntry, boolean toPlayerInventory) { - if (!canCraft(recipeEntry)) { - return true; //stop - } - + private boolean craftOne(PlayerEntity player, RecipeEntry recipeEntry, boolean toPlayerInventory) { ArrayList stacksToRemove = new ArrayList<>(); - // Check and remove ingredients - if (!canCraft(recipeEntry)) { - return true; - } + // Check and remove ingredients for one crafting operation for (Ingredient ingredient : recipeEntry.value().getIngredients()) { ItemStack stackToRemove = findMatchingStack(ingredient); + if (stackToRemove == null) { + return false; // Unable to find required ingredient + } stacksToRemove.add(stackToRemove); } + // Remove ingredients from inventory and network for (ItemStack stack : stacksToRemove) { removeItems(stack); } - // Add the result to the appropriate inventory + // Add crafted item to the appropriate inventory ItemStack outputStack = recipeEntry.value().getResult(storageScreen.getPlayer().getRegistryManager()).copy(); + int maxStackSize = outputStack.getMaxCount(); + if (toPlayerInventory) { PlayerInventory playerInventory = player.getInventory(); - if (canInsertItemIntoInventory(playerInventory, outputStack) == outputStack.getCount()) { - playerInventory.insertStack(outputStack); + ItemStack insertStack = outputStack.copy(); + if (canInsertItemIntoInventory(playerInventory, insertStack) == insertStack.getCount()) { + playerInventory.insertStack(insertStack); } else { - return true; + return true; // Inventory full or unable to insert all items } } else { - if (this.blockEntity.network.canAddItemStack(outputStack)) { - this.blockEntity.network.putItemStackRemainder(outputStack); + ItemStack insertStack = outputStack.copy(); + if (this.blockEntity.network.canAddItemStack(insertStack)) { + this.blockEntity.network.putItemStackRemainder(insertStack); } else { - return true; + return true; // Storage full or unable to insert all items } } - // Remove ingredients - for (Ingredient ingredient : recipeEntry.value().getIngredients()) { - ItemStack stackToRemove = findMatchingStack(ingredient); - if (stackToRemove == null){ - return false; - } - removeItems(stackToRemove); - } - return false; + return false; // Crafted one item successfully } private ItemStack findMatchingStack(Ingredient ingredient) { + // Check player's inventory first + PlayerInventory playerInventory = storageScreen.getPlayer().getInventory(); + for (int i = 0; i < playerInventory.size(); i++) { + ItemStack playerStack = playerInventory.getStack(i); + if (ingredient.test(playerStack)) { + ItemStack stackToRemove = playerStack.copy(); + for (ItemStack matchingStack : ingredient.getMatchingStacks()){ + if (matchingStack.getItem() == stackToRemove.getItem()) { + stackToRemove.setCount(matchingStack.getCount()); // Set count to ingredient requirement + break; + } + } + return stackToRemove; + } + } + + // Check storage network for (ItemStack stack : ingredient.getMatchingStacks()) { if (this.blockEntity.network.canRemove(stack)) { - return stack; + ItemStack stackToRemove = stack.copy(); + stackToRemove.setCount(ingredient.getMatchingStacks()[0].getCount()); // Set count to ingredient requirement + return stackToRemove; } } return null; } private void removeItems(ItemStack stack) { - // Logic to remove items from the storage - ItemStack fromPlayer = this.blockEntity.network.removeItemStack(stack); - if (fromPlayer != null && fromPlayer.getCount() > 0) { + ItemStack removedFromStorage = this.blockEntity.network.removeItemStack(stack); + ItemStack fromPlayer = stack.copy(); + fromPlayer.setCount(stack.getCount() - removedFromStorage.getCount()); + if (fromPlayer.getCount() > 0) { Inventory playerInventory = player.getInventory(); for (int i = 0; i < playerInventory.size(); i++) { - if (playerInventory.getStack(i).equals(fromPlayer)) { - playerInventory.removeStack(i); + if (ItemStack.areItemsEqual(playerInventory.getStack(i), fromPlayer)) { + playerInventory.removeStack(i, fromPlayer.getCount()); + break; // Only remove one stack per crafting iteration } } } } + @Override + public boolean open() { + page = blockEntity.page; + this.blockEntity.openCraftingScreens.add(this); + blockEntity.updateDisplays(); + return super.open(); + } + @Override public void onClose() { super.onClose(); + this.blockEntity.openCraftingScreens.remove(this); storageScreen.open(); } @@ -194,10 +206,9 @@ public class CraftingScreen extends PagedGui { @Override protected DisplayElement getElement(int id) { - if (id >=0 && id < recipesList.size()) { + if (id >= 0 && id < recipesList.size()) { return recipesList.get(id); - } - else { + } else { return DisplayElement.empty(); } } diff --git a/src/main/java/systems/brn/server_storage/screens/StorageScreen.java b/src/main/java/systems/brn/server_storage/screens/StorageScreen.java index 7f02cf6..7614abe 100644 --- a/src/main/java/systems/brn/server_storage/screens/StorageScreen.java +++ b/src/main/java/systems/brn/server_storage/screens/StorageScreen.java @@ -15,7 +15,6 @@ import org.jetbrains.annotations.Nullable; import systems.brn.server_storage.blockentities.StorageInterfaceBlockEntity; import systems.brn.server_storage.lib.PagedGui; -import static systems.brn.server_storage.ServerStorage.ServerStorage_Crafting_Enable; import static systems.brn.server_storage.lib.StorageOperations.*; import static systems.brn.server_storage.lib.Util.addCountToLore; import static systems.brn.server_storage.lib.Util.removeCountFromLore; @@ -42,7 +41,7 @@ public class StorageScreen extends PagedGui { @Override public void updateDisplay() { - blockEntity.justReindexDrives(); + blockEntity.reindexDrives(); String title = blockEntity.network.driveUsedSlots + "u/" + blockEntity.network.driveTotalSlots + @@ -71,7 +70,7 @@ public class StorageScreen extends PagedGui { ItemStack itemStackKey = (ItemStack) blockEntity.network.itemStackMap.keySet().toArray()[id]; ItemStack aestheticStack = itemStackKey.copy(); int count = blockEntity.network.itemStackMap.get(itemStackKey); - aestheticStack.setCount(Math.max(aestheticStack.getMaxCount(), count)); + aestheticStack.setCount(Math.min(aestheticStack.getMaxCount(), count)); ItemStack newStack = addCountToLore(count, aestheticStack, null); GuiElementBuilder guiElement = new GuiElementBuilder(newStack); return DisplayElement.of(guiElement); @@ -108,11 +107,11 @@ public class StorageScreen extends PagedGui { int insertCount = canInsertItemIntoInventory(playerInventory, noLoreStack); ItemStack insertingStack = noLoreStack.copy(); insertingStack.setCount(insertCount); - blockEntity.reindexDrives(); + blockEntity.refreshTerminals(); if (blockEntity.network.canRemove(noLoreStack) && insertCount > 0) { playerInventory.insertStack(insertingStack.copy()); blockEntity.network.removeItemStack(insertingStack); - blockEntity.reindexDrives(); + blockEntity.refreshTerminals(); } } } else if (!cursorStack.isEmpty()) { @@ -125,13 +124,13 @@ public class StorageScreen extends PagedGui { int canPutIn = stack.getCount() - blockEntity.network.putItemStackRemainder(stack); if (canPutIn > 0) { removeFromInventory(player.getInventory(), stack, canPutIn); - blockEntity.reindexDrives(); + blockEntity.refreshTerminals(); } } @Override public boolean insertItem(ItemStack stack, int startIndex, int endIndex, boolean fromLast) { - blockEntity.reindexDrives(); + blockEntity.refreshTerminals(); insertItem(stack); return super.insertItem(stack, startIndex, endIndex, fromLast); } @@ -167,7 +166,7 @@ public class StorageScreen extends PagedGui { .setCallback((x, y, z) -> { this.blockEntity.sortAlphabetically ^= true; playClickSound(getPlayer()); - this.blockEntity.reindexDrives(); + this.blockEntity.refreshTerminals(); }) ); } @@ -192,9 +191,6 @@ public class StorageScreen extends PagedGui { @Override protected DisplayElement crafting() { - if (!this.getPlayer().getWorld().getGameRules().getBoolean(ServerStorage_Crafting_Enable)) { - return DisplayElement.filler(); - } return DisplayElement.of( new GuiElementBuilder(Items.PLAYER_HEAD) .setName(Text.translatable("container.crafting").formatted(Formatting.WHITE)) @@ -211,7 +207,7 @@ public class StorageScreen extends PagedGui { public void doSearch(String query) { this.blockEntity.searchString = query; - this.blockEntity.reindexDrives(); + this.blockEntity.refreshTerminals(); this.page = 0; } @@ -226,7 +222,7 @@ public class StorageScreen extends PagedGui { playClickSound(player); this.page = 0; this.blockEntity.searchString = ""; - this.blockEntity.reindexDrives(); + this.blockEntity.refreshTerminals(); }) ); } @@ -235,7 +231,7 @@ public class StorageScreen extends PagedGui { public void onClose() { this.blockEntity.page = page; this.blockEntity.markDirty(); - this.blockEntity.removeScreen(this); + this.blockEntity.openStorageScreens.remove(this); super.onClose(); } }