UNFINISHED
Add Crafting, improve autosuck //TODO: - add into SettingsScreen all containers with taking out, autosuck and putting in - add block to store hard drives, because chests are too expensive to index - fix crafting
This commit is contained in:
parent
5473358a75
commit
48479c9a88
@ -8,7 +8,7 @@ yarn_mappings=1.20.6+build.3
|
||||
loader_version=0.15.11
|
||||
|
||||
# Mod Properties
|
||||
mod_version=2.3
|
||||
mod_version=2.4
|
||||
maven_group=systems.brn
|
||||
archives_base_name=Server_storage
|
||||
|
||||
|
@ -25,6 +25,7 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
|
||||
|
||||
public Boolean sortAlphabetically = false;
|
||||
public Boolean allInventories = false;
|
||||
public Boolean autoSuck = false;
|
||||
public String searchString = "";
|
||||
public int page = 0;
|
||||
public ConnectedChests chests;
|
||||
@ -37,6 +38,9 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
|
||||
|
||||
public void rescanChests() {
|
||||
this.chests = new ConnectedChests(world, this.pos, sortAlphabetically, searchString, allInventories);
|
||||
if(autoSuck){
|
||||
this.chests.autoSuck();
|
||||
}
|
||||
this.updateDisplays();
|
||||
}
|
||||
|
||||
@ -158,6 +162,7 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
|
||||
nbt.putBoolean("sortAlphabetically", sortAlphabetically);
|
||||
nbt.putString("searchString", searchString);
|
||||
nbt.putBoolean("allInventories", allInventories);
|
||||
nbt.putBoolean("autoSuck", autoSuck);
|
||||
|
||||
super.writeNbt(nbt, wrapperLookup);
|
||||
}
|
||||
@ -171,5 +176,6 @@ public class StorageBlockEntity extends BlockEntity implements Inventory, SidedI
|
||||
sortAlphabetically = nbt.getBoolean("sortAlphabetically");
|
||||
searchString = nbt.getString("searchString");
|
||||
allInventories = nbt.getBoolean("allInventories");
|
||||
autoSuck = nbt.getBoolean("autoSuck");
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import static systems.brn.server_storage.lib.StorageOperations.*;
|
||||
|
||||
public class ConnectedChests {
|
||||
public final List<Inventory> inventories;
|
||||
public final List<Inventory> hoppers;
|
||||
public final Inventory inventory;
|
||||
|
||||
public final int containerCount;
|
||||
@ -24,11 +25,13 @@ public class ConnectedChests {
|
||||
|
||||
public ConnectedChests(World world, BlockPos startPos, boolean sortAlphabetically, String searchString, boolean allInventories) {
|
||||
List<Inventory> inventories = new ArrayList<>();
|
||||
List<Inventory> hoppers = new ArrayList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
|
||||
getConnectedChestsHelper(world, startPos, inventories, visited, allInventories);
|
||||
getConnectedChestsHelper(world, startPos, inventories, hoppers, visited, allInventories);
|
||||
|
||||
this.inventories = inventories;
|
||||
this.hoppers = hoppers;
|
||||
this.containerCount = inventories.size();
|
||||
this.inventory = getCombinedInventory(sortAlphabetically, searchString);
|
||||
|
||||
@ -58,13 +61,18 @@ public class ConnectedChests {
|
||||
blockEntity instanceof ShulkerBoxBlockEntity;
|
||||
}
|
||||
|
||||
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, Set<BlockPos> visited, Boolean allContainers) {
|
||||
private static void getConnectedChestsHelper(World world, BlockPos pos, List<Inventory> inventories, List<Inventory> hoppers, Set<BlockPos> visited, Boolean allContainers) {
|
||||
if (visited.contains(pos)) {
|
||||
return;
|
||||
}
|
||||
visited.add(pos);
|
||||
|
||||
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
|
||||
if (isEnabledHopper(blockEntity)) {
|
||||
hoppers.add((Inventory) blockEntity);
|
||||
}
|
||||
|
||||
if (isEnabledContainer(blockEntity, allContainers) || blockEntity instanceof StorageBlockEntity) {
|
||||
if (isEnabledContainer(blockEntity, allContainers) && !(blockEntity instanceof StorageBlockEntity)) {
|
||||
inventories.add((Inventory) blockEntity);
|
||||
@ -72,7 +80,7 @@ public class ConnectedChests {
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
BlockPos nextPos = pos.offset(direction);
|
||||
getConnectedChestsHelper(world, nextPos, inventories, visited, allContainers);
|
||||
getConnectedChestsHelper(world, nextPos, inventories, hoppers, visited, allContainers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,27 +89,7 @@ public class ConnectedChests {
|
||||
private SimpleInventory getCombinedInventory(boolean sortAlphabetically, String query) {
|
||||
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
|
||||
for (Inventory inventory : inventories) {
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
ItemStack stack = inventory.getStack(i);
|
||||
if (!stack.isEmpty()) {
|
||||
// Check if there's an existing ItemStack with the same item and metadata
|
||||
boolean found = false;
|
||||
for (Map.Entry<ItemStack, Integer> entry : itemStackMap.entrySet()) {
|
||||
ItemStack existingStack = entry.getKey();
|
||||
if (ItemStack.areItemsAndComponentsEqual(stack, existingStack)) {
|
||||
int count = entry.getValue() + stack.getCount();
|
||||
itemStackMap.put(existingStack.copy(), count);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If no existing stack with the same item and metadata, add a new entry
|
||||
if (!found) {
|
||||
ItemStack copiedStack = stack.copy();
|
||||
itemStackMap.put(copiedStack, stack.getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
addInventoryToMap(inventory, itemStackMap);
|
||||
}
|
||||
return filterInventory(getSimpleInventory(itemStackMap.size(), itemStackMap, sortAlphabetically), query, sortAlphabetically);
|
||||
}
|
||||
@ -119,7 +107,7 @@ public class ConnectedChests {
|
||||
if (!filteredStack.isEmpty()) {
|
||||
itemCount++;
|
||||
int count = itemStackMap.getOrDefault(filteredStack, 0) + filteredStack.getCount();
|
||||
itemStackMap.put(filteredStack.copy(), count);
|
||||
itemStackMap.put(filteredStack, count);
|
||||
}
|
||||
}
|
||||
return getSimpleInventory(itemCount, itemStackMap, sortAlphabetically);
|
||||
@ -141,6 +129,15 @@ public class ConnectedChests {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isEnabledHopper(BlockEntity blockEntity) {
|
||||
return blockEntity instanceof HopperBlockEntity ||
|
||||
blockEntity instanceof TrappedChestBlockEntity ||
|
||||
blockEntity instanceof FurnaceBlockEntity ||
|
||||
blockEntity instanceof BlastFurnaceBlockEntity ||
|
||||
blockEntity instanceof SmokerBlockEntity ||
|
||||
blockEntity instanceof BrewingStandBlockEntity;
|
||||
}
|
||||
|
||||
public boolean canAddItemStack(ItemStack stack) {
|
||||
// Iterate over each chest to check if it's possible to insert the ItemStack
|
||||
for (Inventory chest : inventories) {
|
||||
@ -155,29 +152,30 @@ public class ConnectedChests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it's not possible to insert into any chest, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canRemove(ItemStack stackToRemove) {
|
||||
int remainingToRemove = stackToRemove.getCount();
|
||||
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
ItemStack slotStack = inventory.getStack(i);
|
||||
if (canCombine(slotStack, stackToRemove)) {
|
||||
// If the slot contains the same item type
|
||||
if (slotStack.getCount() >= remainingToRemove) {
|
||||
// If the count in the slot is sufficient to remove the requested amount
|
||||
return true;
|
||||
public void autoSuck() {
|
||||
for (Inventory chest : hoppers) {
|
||||
for (int i = 0; i < chest.size(); i++) {
|
||||
ItemStack slotStack = chest.getStack(i);
|
||||
if (!slotStack.isEmpty()) {
|
||||
if (this.canAddItemStack(slotStack)) {
|
||||
if (this.tryPutItemStack(slotStack)) {
|
||||
removeFromInventory(chest, slotStack, slotStack.getCount());
|
||||
}
|
||||
;
|
||||
} else {
|
||||
// If the count in the slot is not sufficient, update remainingToRemove
|
||||
remainingToRemove -= slotStack.getCount();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no matching stack with sufficient count is found, return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canRemove(ItemStack stackToRemove) {
|
||||
return canRemoveCount(stackToRemove, inventory) == 0;
|
||||
}
|
||||
|
||||
public ItemStack removeItemStack(ItemStack stackToRemove) {
|
||||
|
@ -0,0 +1,14 @@
|
||||
package systems.brn.server_storage.lib;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.CraftingRecipe;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
|
||||
public class CraftingEntry {
|
||||
public final ItemStack itemStack;
|
||||
public final RecipeEntry<CraftingRecipe> recipeEntry;
|
||||
public CraftingEntry(ItemStack itemStack, RecipeEntry<CraftingRecipe> recipeEntry) {
|
||||
this.itemStack = itemStack;
|
||||
this.recipeEntry = recipeEntry;
|
||||
}
|
||||
}
|
@ -31,7 +31,11 @@ public abstract class PagedGui extends SimpleGui {
|
||||
public static final String GUI_A = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGU0MTc0ODEyMTYyNmYyMmFlMTZhNGM2NjRjNzMwMWE5ZjhlYTU5MWJmNGQyOTg4ODk1NzY4MmE5ZmRhZiJ9fX0=";
|
||||
public static final String GUI_1 = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2E1MTZmYmFlMTYwNThmMjUxYWVmOWE2OGQzMDc4NTQ5ZjQ4ZjZkNWI2ODNmMTljZjVhMTc0NTIxN2Q3MmNjIn19fQ==";
|
||||
public static final String GUI_STORE_ALL = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMWFkNmM4MWY4OTlhNzg1ZWNmMjZiZTFkYzQ4ZWFlMmJjZmU3NzdhODYyMzkwZjU3ODVlOTViZDgzYmQxNGQifX19";
|
||||
public static final String GUI_SETTINGS = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2EzYzhjNmQzYWFhOTYzNjNkNGJlZjI1NzhmMTAyNDc4MWVhMTRlOWQ4NWE5ZGNmYzA5MzU4NDdhNmZiNWM4ZCJ9fX0=";
|
||||
public static final String GUI_CONTAINERS = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2EzYzhjNmQzYWFhOTYzNjNkNGJlZjI1NzhmMTAyNDc4MWVhMTRlOWQ4NWE5ZGNmYzA5MzU4NDdhNmZiNWM4ZCJ9fX0=";
|
||||
public static final String GUI_SETTINGS = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTRkNDliYWU5NWM3OTBjM2IxZmY1YjJmMDEwNTJhNzE0ZDYxODU0ODFkNWIxYzg1OTMwYjNmOTlkMjMyMTY3NCJ9fX0=";
|
||||
public static final String GUI_CRAFTING = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWQyYzBjZWRmYzMyZTNiZWVlOTU1Y2FiZDY2ZmQ0ZDc2NWVlZGEzYWRjYzg0YmM0NTFjOWZkYmVjZjNjYjdjMiJ9fX0=";
|
||||
public static final String GUI_AUTOSUCK_OFF = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGViODFlZjg5MDIzNzk2NTBiYTc5ZjQ1NzIzZDZiOWM4ODgzODhhMDBmYzRlMTkyZjM0NTRmZTE5Mzg4MmVlMSJ9fX0=";
|
||||
public static final String GUI_AUTOSUCK_ON = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMThjNDQzYWRhNmUzOWZjYTgzN2EwMzgzYjBhNWUzZTU1NDc3M2I5NjYwYzQ4NzNmNTkxMDMyZGJlOWFkY2RmOCJ9fX0=";
|
||||
|
||||
public static final int PAGE_SIZE = 9 * 5;
|
||||
protected final Runnable closeCallback;
|
||||
@ -112,17 +116,18 @@ public abstract class PagedGui extends SimpleGui {
|
||||
protected DisplayElement getNavElement(int id) {
|
||||
return switch (id) {
|
||||
case 0 -> DisplayElement.previousPage(this);
|
||||
case 2 -> this.search();
|
||||
case 3 -> this.sorting();
|
||||
case 4 -> this.refresh();
|
||||
case 5 -> this.storeAll();
|
||||
case 6 -> this.settings();
|
||||
case 1 -> this.search();
|
||||
case 2 -> this.sorting();
|
||||
case 3 -> this.refresh();
|
||||
case 4 -> this.storeAll();
|
||||
case 5 -> this.settings();
|
||||
case 6 -> this.crafting();
|
||||
case 7 -> DisplayElement.nextPage(this);
|
||||
case 8 -> DisplayElement.of(
|
||||
new GuiElementBuilder(Items.STRUCTURE_VOID)
|
||||
.setName(Text.translatable(this.closeCallback != null ? "gui.back" : "mco.selectServer.close").formatted(Formatting.RED))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setCallback((x, y, z) -> {
|
||||
.setCallback((i, clickType, slotActionType) -> {
|
||||
playClickSound(this.player);
|
||||
this.close();
|
||||
})
|
||||
@ -135,9 +140,14 @@ public abstract class PagedGui extends SimpleGui {
|
||||
return DisplayElement.filler();
|
||||
}
|
||||
|
||||
protected DisplayElement crafting() {
|
||||
return DisplayElement.filler();
|
||||
}
|
||||
|
||||
protected DisplayElement search(){
|
||||
return DisplayElement.filler();
|
||||
}
|
||||
|
||||
protected DisplayElement sorting(){
|
||||
return DisplayElement.filler();
|
||||
}
|
||||
|
@ -134,7 +134,48 @@ public class StorageOperations {
|
||||
return remainingToRemove;
|
||||
}
|
||||
|
||||
public static int canRemoveCount(ItemStack stackToRemove, Inventory inventory) {
|
||||
int remainingToRemove = stackToRemove.getCount();
|
||||
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
ItemStack slotStack = inventory.getStack(i);
|
||||
if (canCombine(slotStack, stackToRemove)) {
|
||||
// If the slot contains the same item type
|
||||
if (slotStack.getCount() >= remainingToRemove) {
|
||||
// If the count in the slot is sufficient to remove the requested amount
|
||||
return 0;
|
||||
} else {
|
||||
// If the count in the slot is not sufficient, update remainingToRemove
|
||||
remainingToRemove -= slotStack.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no matching stack with sufficient count is found, return false
|
||||
return remainingToRemove;
|
||||
}
|
||||
|
||||
public static boolean canCombine(ItemStack stack1, ItemStack stack2) {
|
||||
return !stack1.isEmpty() && stack1.getItem() == stack2.getItem() && ItemStack.areItemsAndComponentsEqual(stack1, stack2);
|
||||
}
|
||||
|
||||
public static void addInventoryToMap(Inventory inventory, Map<ItemStack, Integer> itemStackMap) {
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
ItemStack stack = inventory.getStack(i);
|
||||
if (!stack.isEmpty()) {
|
||||
addToMap(itemStackMap, stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToMap(Map<ItemStack, Integer> itemStackMap, ItemStack stack) {
|
||||
for (Map.Entry<ItemStack, Integer> entry : itemStackMap.entrySet()) {
|
||||
ItemStack existingStack = entry.getKey();
|
||||
if (ItemStack.areItemsAndComponentsEqual(stack, existingStack)) {
|
||||
int newCount = entry.getValue() + stack.getCount();
|
||||
itemStackMap.put(existingStack, newCount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
itemStackMap.put(stack.copy(), stack.getCount());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import net.minecraft.component.type.LoreComponent;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.*;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.text.RawFilteredPair;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
@ -99,4 +101,60 @@ public class Util {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<CraftingEntry> getCraftableRecipes(Inventory inventory, MinecraftServer server) {
|
||||
RecipeManager recipeManager = server.getRecipeManager();
|
||||
List<RecipeEntry<CraftingRecipe>> allRecipes = recipeManager.listAllOfType(RecipeType.CRAFTING);
|
||||
|
||||
ArrayList<CraftingEntry> craftingEntries = new ArrayList<>();
|
||||
|
||||
for (RecipeEntry<CraftingRecipe> recipe : allRecipes) {
|
||||
int maxAmount = -1;
|
||||
boolean canMake = true;
|
||||
for (Ingredient ingredient : recipe.value().getIngredients()) {
|
||||
for (ItemStack stack : ingredient.getMatchingStacks()) {
|
||||
if (stack.isEmpty()) {
|
||||
break;
|
||||
} else {
|
||||
//if inventory contains stack
|
||||
boolean foundUsableStack = false;
|
||||
for (int i = 0; i < inventory.size(); i++) {
|
||||
if (inventory.getStack(i).getItem().equals(stack.getItem())) {
|
||||
if (maxAmount == -1) {
|
||||
maxAmount = inventory.getStack(i).getCount();
|
||||
} else {
|
||||
maxAmount = Math.min(maxAmount, inventory.getStack(i).getCount());
|
||||
}
|
||||
foundUsableStack = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundUsableStack) {
|
||||
canMake = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxAmount > 1 && canMake) {
|
||||
Item outputItem = recipe.value().getResult(server.getRegistryManager()).getItem();
|
||||
CraftingEntry entry = new CraftingEntry(new ItemStack(outputItem, maxAmount), recipe);
|
||||
boolean needToAdd = true;
|
||||
for (int i = 0; i < craftingEntries.size(); i++) {
|
||||
CraftingEntry entryLoop = craftingEntries.get(i);
|
||||
if (entryLoop.itemStack.getItem().equals(outputItem)) {
|
||||
needToAdd = false;
|
||||
if (maxAmount > entryLoop.itemStack.getCount()) {
|
||||
craftingEntries.set(i, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needToAdd) {
|
||||
craftingEntries.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return craftingEntries;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,199 @@
|
||||
package systems.brn.server_storage.screens;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.CraftingRecipe;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
import net.minecraft.text.Text;
|
||||
import systems.brn.server_storage.lib.CraftingEntry;
|
||||
import systems.brn.server_storage.lib.PagedGui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
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.getCraftableRecipes;
|
||||
|
||||
public class CraftingScreen extends PagedGui {
|
||||
private final StorageScreen storageScreen;
|
||||
|
||||
private ArrayList<CraftingEntry> craftingEntries;
|
||||
|
||||
private ArrayList<DisplayElement> recipesList;
|
||||
|
||||
public CraftingScreen(StorageScreen storageScreen) {
|
||||
super(storageScreen.getPlayer(), null);
|
||||
this.storageScreen = storageScreen;
|
||||
this.setTitle(Text.translatable("container.crafting"));
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDisplay(){
|
||||
storageScreen.blockEntity.rescanChests();
|
||||
Map<ItemStack, Integer> itemStackMap = new HashMap<>();
|
||||
addInventoryToMap(storageScreen.getPlayer().getInventory(), itemStackMap);
|
||||
addInventoryToMap(storageScreen.blockEntity.chests.inventory, itemStackMap);
|
||||
Inventory inventory = getSimpleInventory(itemStackMap.size(), itemStackMap, false);
|
||||
this.craftingEntries = getCraftableRecipes(inventory, Objects.requireNonNull(player.getServer()));
|
||||
this.recipesList = getAvailableRecipes();
|
||||
super.updateDisplay();
|
||||
}
|
||||
|
||||
private ArrayList<DisplayElement> getAvailableRecipes() {
|
||||
ArrayList<DisplayElement> recipes = new ArrayList<>();
|
||||
|
||||
for (CraftingEntry craftingEntry : craftingEntries) {
|
||||
ItemStack stackWithCount = addCountToLore(craftingEntry.itemStack.getCount(), craftingEntry.itemStack);
|
||||
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;
|
||||
|
||||
// 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 stack
|
||||
craftOneStack(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);
|
||||
}
|
||||
}
|
||||
updateDisplay();
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
return recipes;
|
||||
}
|
||||
|
||||
private void craftAll(PlayerEntity player, RecipeEntry<CraftingRecipe> recipeEntry, boolean toPlayerInventory) {
|
||||
while (canCraft(recipeEntry)) {
|
||||
if (craftOneStack(player, recipeEntry, toPlayerInventory)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean craftOneStack(PlayerEntity player, RecipeEntry<CraftingRecipe> recipeEntry, boolean toPlayerInventory) {
|
||||
if (!canCraft(recipeEntry)) {
|
||||
return true; //stop
|
||||
}
|
||||
|
||||
// Check and remove ingredients
|
||||
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
|
||||
ItemStack stackToRemove = findMatchingStack(ingredient);
|
||||
if (stackToRemove == null){
|
||||
return false;
|
||||
}
|
||||
int requiredCount = canRemoveCount(stackToRemove, this.storageScreen.blockEntity.chests.inventory);
|
||||
|
||||
if (requiredCount > 0 && canRemoveCount(stackToRemove, this.storageScreen.getPlayer().getInventory()) < requiredCount) {
|
||||
return true;
|
||||
} else {
|
||||
removeItems(stackToRemove, requiredCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the result to the appropriate inventory
|
||||
ItemStack outputStack = recipeEntry.value().getResult(storageScreen.getPlayer().getRegistryManager());
|
||||
if (toPlayerInventory) {
|
||||
if (canInsertItemIntoPlayerInventory(player, outputStack) == outputStack.getCount()) {
|
||||
player.getInventory().insertStack(outputStack);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (this.storageScreen.blockEntity.chests.canAddItemStack(outputStack)) {
|
||||
this.storageScreen.blockEntity.chests.tryPutItemStack(outputStack);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove ingredients
|
||||
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
|
||||
ItemStack stackToRemove = findMatchingStack(ingredient);
|
||||
if (stackToRemove == null){
|
||||
return false;
|
||||
}
|
||||
removeItems(stackToRemove, stackToRemove.getCount());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean canCraft(RecipeEntry<CraftingRecipe> recipeEntry) {
|
||||
for (Ingredient ingredient : recipeEntry.value().getIngredients()) {
|
||||
ItemStack stackToRemove = findMatchingStack(ingredient);
|
||||
if (stackToRemove == null){
|
||||
return false;
|
||||
}
|
||||
int requiredCount = canRemoveCount(stackToRemove, this.storageScreen.blockEntity.chests.inventory);
|
||||
|
||||
if (requiredCount > 0 && canRemoveCount(stackToRemove, this.storageScreen.getPlayer().getInventory()) < requiredCount) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ItemStack findMatchingStack(Ingredient ingredient) {
|
||||
for (ItemStack stack : ingredient.getMatchingStacks()) {
|
||||
if (this.storageScreen.blockEntity.chests.canRemove(stack)) {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removeItems(ItemStack stack, int count) {
|
||||
// Logic to remove items from the storage
|
||||
ItemStack stackRemove = stack.copy();
|
||||
stackRemove.setCount(count);
|
||||
ItemStack fromPlayer = this.storageScreen.blockEntity.chests.removeItemStack(stackRemove);
|
||||
if (fromPlayer != null && fromPlayer.getCount() > 0) {
|
||||
Inventory playerInventory = player.getInventory();
|
||||
for (int i = 0; i < playerInventory.size(); i++) {
|
||||
if (playerInventory.getStack(i).equals(fromPlayer)) {
|
||||
playerInventory.removeStack(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
super.onClose();
|
||||
storageScreen.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPageAmount() {
|
||||
return Math.ceilDivExact(recipesList.size(), 9 * 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement getElement(int id) {
|
||||
if (id >=0 && id < recipesList.size()) {
|
||||
return recipesList.get(id);
|
||||
}
|
||||
else {
|
||||
return DisplayElement.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package systems.brn.server_storage.screens;
|
||||
|
||||
import eu.pb4.sgui.api.elements.GuiElementBuilder;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import systems.brn.server_storage.lib.PagedGui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SettingsScreen extends PagedGui {
|
||||
|
||||
private final StorageScreen storageScreen;
|
||||
|
||||
private ArrayList<DisplayElement> settingsList;
|
||||
|
||||
public SettingsScreen(StorageScreen storageScreen) {
|
||||
super(storageScreen.getPlayer(), null);
|
||||
this.storageScreen = storageScreen;
|
||||
this.setTitle(Text.translatable("mco.configure.world.buttons.settings"));
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
super.onClose();
|
||||
storageScreen.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDisplay() {
|
||||
this.settingsList = new ArrayList<>();
|
||||
this.settingsList.add(containers());
|
||||
this.settingsList.add(autoSuck());
|
||||
super.updateDisplay();
|
||||
}
|
||||
|
||||
protected PagedGui.DisplayElement containers() {
|
||||
return PagedGui.DisplayElement.of(
|
||||
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||
.setName(Text.translatable(storageScreen.blockEntity.allInventories ? "gui.all" : "options.fov.min").formatted(Formatting.WHITE))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setSkullOwner(GUI_CONTAINERS)
|
||||
.setCallback((x, y, z) -> {
|
||||
storageScreen.blockEntity.allInventories ^= true;
|
||||
storageScreen.blockEntity.markDirty();
|
||||
storageScreen.blockEntity.rescanChests();
|
||||
playClickSound(getPlayer());
|
||||
updateDisplay();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPageAmount() {
|
||||
return Math.ceilDivExact(settingsList.size(), 9*6);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement getElement(int id) {
|
||||
if (id >= 0 && id < settingsList.size()) {
|
||||
return settingsList.get(id);
|
||||
}
|
||||
else {
|
||||
return DisplayElement.empty();
|
||||
}
|
||||
}
|
||||
|
||||
protected PagedGui.DisplayElement autoSuck() {
|
||||
return PagedGui.DisplayElement.of(
|
||||
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||
.setName(Text.translatable(storageScreen.blockEntity.autoSuck ? "gui.yes" : "gui.no").formatted(Formatting.WHITE))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setSkullOwner(storageScreen.blockEntity.autoSuck ? GUI_AUTOSUCK_ON : GUI_AUTOSUCK_OFF)
|
||||
.setCallback((x, y, z) -> {
|
||||
storageScreen.blockEntity.autoSuck ^= true;
|
||||
storageScreen.blockEntity.rescanChests();
|
||||
playClickSound(getPlayer());
|
||||
updateDisplay();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ import static systems.brn.server_storage.lib.Util.removeCountFromLore;
|
||||
|
||||
public class StorageScreen extends PagedGui {
|
||||
private final ServerPlayerEntity player;
|
||||
private final StorageBlockEntity blockEntity;
|
||||
public final StorageBlockEntity blockEntity;
|
||||
|
||||
public StorageScreen(ServerPlayerEntity player, BlockPos pos, @Nullable Runnable closeCallback) {
|
||||
super(player, closeCallback);
|
||||
@ -118,22 +118,6 @@ public class StorageScreen extends PagedGui {
|
||||
return super.insertItem(stack, startIndex, endIndex, fromLast);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement settings() {
|
||||
return DisplayElement.of(
|
||||
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||
.setName(Text.translatable(this.blockEntity.allInventories ? "gui.all" : "options.fov.min").formatted(Formatting.WHITE))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setSkullOwner(GUI_SETTINGS)
|
||||
.setCallback((x, y, z) -> {
|
||||
this.blockEntity.allInventories ^= true;
|
||||
this.blockEntity.markDirty();
|
||||
this.blockEntity.rescanChests();
|
||||
playClickSound(getPlayer());
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement search() {
|
||||
return DisplayElement.of(
|
||||
@ -149,6 +133,21 @@ public class StorageScreen extends PagedGui {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement settings() {
|
||||
return DisplayElement.of(
|
||||
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||
.setName(Text.translatable("mco.configure.world.settings.title").formatted(Formatting.WHITE))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setSkullOwner(GUI_SETTINGS)
|
||||
.setCallback((x, y, z) -> {
|
||||
SettingsScreen settingsScreen = new SettingsScreen(this);
|
||||
playClickSound(getPlayer());
|
||||
settingsScreen.open();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement sorting() {
|
||||
return DisplayElement.of(
|
||||
@ -164,6 +163,7 @@ public class StorageScreen extends PagedGui {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DisplayElement storeAll() {
|
||||
return DisplayElement.of(
|
||||
@ -181,6 +181,22 @@ public class StorageScreen extends PagedGui {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DisplayElement crafting() {
|
||||
return DisplayElement.of(
|
||||
new GuiElementBuilder(Items.PLAYER_HEAD)
|
||||
.setName(Text.translatable("container.crafting").formatted(Formatting.WHITE))
|
||||
.hideDefaultTooltip().noDefaults()
|
||||
.setSkullOwner(GUI_CRAFTING)
|
||||
.setCallback((x, y, z) -> {
|
||||
playClickSound(player);
|
||||
CraftingScreen craftingScreen = new CraftingScreen(this);
|
||||
playClickSound(getPlayer());
|
||||
craftingScreen.open();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public void doSearch(String query) {
|
||||
this.blockEntity.searchString = query;
|
||||
this.blockEntity.rescanChests();
|
||||
|
Loading…
Reference in New Issue
Block a user