diff --git a/src/main/java/io/github/sefiraat/networks/network/stackcaches/QuantumCache.java b/src/main/java/io/github/sefiraat/networks/network/stackcaches/QuantumCache.java index e4603b6cc..c47495812 100644 --- a/src/main/java/io/github/sefiraat/networks/network/stackcaches/QuantumCache.java +++ b/src/main/java/io/github/sefiraat/networks/network/stackcaches/QuantumCache.java @@ -12,16 +12,18 @@ public class QuantumCache extends ItemStackCache { @Nullable private final ItemMeta storedItemMeta; - private final int limit; + private int limit; private int amount; private boolean voidExcess; + private boolean supportsCustomMaxAmount; - public QuantumCache(@Nullable ItemStack storedItem, int amount, int limit, boolean voidExcess) { + public QuantumCache(@Nullable ItemStack storedItem, int amount, int limit, boolean voidExcess, boolean supportsCustomMaxAmount) { super(storedItem); this.storedItemMeta = storedItem == null ? null : storedItem.getItemMeta(); this.amount = amount; this.limit = limit; this.voidExcess = voidExcess; + this.supportsCustomMaxAmount = supportsCustomMaxAmount; } @Nullable @@ -33,10 +35,18 @@ public int getAmount() { return amount; } + public boolean supportsCustomMaxAmount() { + return this.supportsCustomMaxAmount; + } + public void setAmount(int amount) { this.amount = amount; } + public void setLimit(int limit) { + this.limit = limit; + } + public int increaseAmount(int amount) { long total = (long) this.amount + (long) amount; if (total > this.limit) { @@ -92,15 +102,23 @@ public void addMetaLore(ItemMeta itemMeta) { (this.getItemMeta() != null && this.getItemMeta().hasDisplayName() ? this.getItemMeta().getDisplayName() : this.getItemStack().getType().name()) ); lore.add(Theme.CLICK_INFO + "Amount: " + this.getAmount()); + if (this.supportsCustomMaxAmount) { + lore.add(Theme.CLICK_INFO + "Max Amount: " + this.getLimit()); + } + itemMeta.setLore(lore); } public void updateMetaLore(ItemMeta itemMeta) { final List lore = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); - lore.set(lore.size() - 2,Theme.CLICK_INFO + "Holding: " + + final int loreIndexModifier = this.supportsCustomMaxAmount ? 1 : 0; + lore.set(lore.size() - 2 - loreIndexModifier,Theme.CLICK_INFO + "Holding: " + (this.getItemMeta() != null && this.getItemMeta().hasDisplayName() ? this.getItemMeta().getDisplayName() : this.getItemStack().getType().name()) ); - lore.set(lore.size() - 1, Theme.CLICK_INFO + "Amount: " + this.getAmount()); + lore.set(lore.size() - 1 - loreIndexModifier, Theme.CLICK_INFO + "Amount: " + this.getAmount()); + if (this.supportsCustomMaxAmount) { + lore.set(lore.size() - loreIndexModifier, Theme.CLICK_INFO + "Max Amount: " + this.getLimit()); + } itemMeta.setLore(lore); } } diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/NetworkSlimefunItems.java b/src/main/java/io/github/sefiraat/networks/slimefun/NetworkSlimefunItems.java index 9de83a079..59bc784ae 100644 --- a/src/main/java/io/github/sefiraat/networks/slimefun/NetworkSlimefunItems.java +++ b/src/main/java/io/github/sefiraat/networks/slimefun/NetworkSlimefunItems.java @@ -565,6 +565,7 @@ public class NetworkSlimefunItems { }, NetworkQuantumStorage.getSizes()[7] ); + NETWORK_QUANTUM_STORAGE_8.setSupportsCustomMaxAmount(true); NETWORK_CAPACITOR_1 = new NetworkPowerNode( NetworksItemGroups.NETWORK_ITEMS, diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/NetworksSlimefunItemStacks.java b/src/main/java/io/github/sefiraat/networks/slimefun/NetworksSlimefunItemStacks.java index 1f5d3e1a7..50b07a9f7 100644 --- a/src/main/java/io/github/sefiraat/networks/slimefun/NetworksSlimefunItemStacks.java +++ b/src/main/java/io/github/sefiraat/networks/slimefun/NetworksSlimefunItemStacks.java @@ -520,6 +520,7 @@ public class NetworksSlimefunItemStacks { Theme.MACHINE, "Network Quantum Storage (∞)", "Stores ∞ items... almost", + "Has configurable maximum storage capacity", "", "Stores items in mass quantities within", "a quantum singularity." diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumStorage.java b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumStorage.java index bd33de91d..32bccd2e3 100644 --- a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumStorage.java +++ b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumStorage.java @@ -18,6 +18,7 @@ import io.github.thebusybiscuit.slimefun4.libraries.dough.data.persistent.PersistentDataAPI; import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack; import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; +import io.github.thebusybiscuit.slimefun4.utils.ChatUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; @@ -58,6 +59,7 @@ public class NetworkQuantumStorage extends SlimefunItem implements DistinctiveIt public static final String BS_AMOUNT = "stored_amount"; public static final String BS_VOID = "void_excess"; + public static final String BS_CUSTOM_MAX_AMOUNT = "custom_max_amount"; public static final int INPUT_SLOT = 1; public static final int ITEM_SLOT = 4; @@ -84,8 +86,16 @@ public class NetworkQuantumStorage extends SlimefunItem implements DistinctiveIt private static final ItemStack SET_ITEM = new CustomItemStack( Material.LIME_STAINED_GLASS_PANE, Theme.SUCCESS + "Set Item", - Theme.PASSIVE + "Drag an item on top of this pane to register it.", - Theme.PASSIVE + "Shift Click to change voiding" + Theme.PASSIVE + "Click with an item to set the Quantum's Stored Item.", + Theme.PASSIVE + "Shift Click to toggle voiding items over the maximum storage size." + ); + + private static final ItemStack SET_ITEM_SUPPORTING_CUSTOM_MAX = new CustomItemStack( + Material.LIME_STAINED_GLASS_PANE, + Theme.SUCCESS + "Set Item", + Theme.PASSIVE + "Click with an item to set the Quantum's Stored Item.", + Theme.PASSIVE + "Click without an item to set the Quantum's maximum storage size.", + Theme.PASSIVE + "Shift Click to toggle voiding items over the maximum storage size." ); private static final ItemStack BACK_OUTPUT = new CustomItemStack( @@ -108,6 +118,7 @@ public class NetworkQuantumStorage extends SlimefunItem implements DistinctiveIt private final List slotsToDrop = new ArrayList<>(); private final int maxAmount; + private boolean supportsCustomMaxAmount = false; public NetworkQuantumStorage(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, int maxAmount) { super(itemGroup, item, recipeType, recipe); @@ -217,6 +228,23 @@ private void setItem(@Nonnull BlockMenu blockMenu, @Nonnull Player player) { CACHES.put(blockMenu.getLocation(), cache); } + private void setCustomMaxAmount(@Nonnull BlockMenu blockMenu, @Nonnull Player player, @Nonnull int newMaxAmount) { + final QuantumCache cache = CACHES.get(blockMenu.getLocation()); + if (cache == null || !cache.supportsCustomMaxAmount()) { + player.sendMessage(Theme.ERROR + "This Quantum Storage does not support custom maximum storage amounts."); + return; + } + cache.setLimit(newMaxAmount); + updateDisplayItem(blockMenu, cache); + syncBlock(blockMenu.getLocation(), cache); + CACHES.put(blockMenu.getLocation(), cache); + player.sendMessage(Theme.SUCCESS + "Maximum Storage Size applied"); + } + + public void setSupportsCustomMaxAmount(boolean supportsCustomMaxAmount) { + this.supportsCustomMaxAmount = supportsCustomMaxAmount; + } + @Override public void postRegister() { new BlockMenuPreset(this.getId(), this.getItemName()) { @@ -232,7 +260,8 @@ public void init() { for (int i : OUTPUT_SLOTS) { addItem(i, BACK_OUTPUT, (p, slot, item, action) -> false); } - addItem(ITEM_SET_SLOT, SET_ITEM, (p, slot, item, action) -> false); + ItemStack setItemItemstack = supportsCustomMaxAmount ? SET_ITEM_SUPPORTING_CUSTOM_MAX : SET_ITEM; + addItem(ITEM_SET_SLOT, setItemItemstack, (p, slot, item, action) -> false); addMenuClickHandler(ITEM_SLOT, ChestMenuUtils.getEmptyClickHandler()); drawBackground(BACKGROUND_SLOTS); } @@ -255,8 +284,28 @@ public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) { @Override public void newInstance(@Nonnull BlockMenu menu, @Nonnull Block block) { menu.addMenuClickHandler(ITEM_SET_SLOT, (p, slot, item, action) -> { + final QuantumCache cache = CACHES.get(menu.getLocation()); if (action.isShiftClicked()) { toggleVoid(menu); + } else if ( + cache != null && + cache.supportsCustomMaxAmount() && + p.getItemOnCursor().getType() == Material.AIR + ) { + p.closeInventory(); + p.sendMessage(Theme.WARNING + "Type the new maximum storage size for this Quantum Storage - it must be between 1 and " + Integer.MAX_VALUE + "!"); + ChatUtils.awaitInput(p, s -> { + // Catching the error is cleaner than directly validating the string + try { + if (s.isBlank()) { + return; + } + int newMax = Math.max(1, Math.min(Integer.parseInt(s), maxAmount)); + setCustomMaxAmount(menu, p, newMax); + } catch (NumberFormatException e) { + p.sendMessage(Theme.ERROR + "That's not a number."); + } + }); } else { setItem(menu, p); } @@ -279,18 +328,26 @@ private QuantumCache addCache(@Nonnull BlockMenu blockMenu) { final String voidString = BlockStorage.getLocationInfo(location, BS_VOID); final int amount = amountString == null ? 0 : Integer.parseInt(amountString); final boolean voidExcess = voidString == null || Boolean.parseBoolean(voidString); + // We use either the maximum amount if custom is not set, or the custom amount if it is set and is supported for this quantum + int maxAmount = this.maxAmount; + if (this.supportsCustomMaxAmount) { + final String customMaxAmountString = BlockStorage.getLocationInfo(blockMenu.getLocation(), BS_CUSTOM_MAX_AMOUNT); + if (customMaxAmountString != null) { + maxAmount = Integer.parseInt(customMaxAmountString); + } + } final ItemStack itemStack = blockMenu.getItemInSlot(ITEM_SLOT); - QuantumCache cache = createCache(itemStack, blockMenu, amount, voidExcess); + QuantumCache cache = createCache(itemStack, blockMenu, amount, maxAmount, voidExcess); CACHES.put(location, cache); return cache; } - private QuantumCache createCache(@Nullable ItemStack itemStack, @Nonnull BlockMenu menu, int amount, boolean voidExcess) { + private QuantumCache createCache(@Nullable ItemStack itemStack, @Nonnull BlockMenu menu, int amount, int maxAmount, boolean voidExcess) { if (itemStack == null || itemStack.getType() == Material.AIR || isDisplayItem(itemStack)) { menu.addItem(ITEM_SLOT, NO_ITEM); - return new QuantumCache(null, 0, this.maxAmount, true); + return new QuantumCache(null, 0, maxAmount, true, this.supportsCustomMaxAmount); } else { final ItemStack clone = itemStack.clone(); final ItemMeta itemMeta = clone.getItemMeta(); @@ -301,7 +358,7 @@ private QuantumCache createCache(@Nullable ItemStack itemStack, @Nonnull BlockMe itemMeta.setLore(lore.isEmpty() ? null : lore); clone.setItemMeta(itemMeta); - final QuantumCache cache = new QuantumCache(clone, amount, this.maxAmount, voidExcess); + final QuantumCache cache = new QuantumCache(clone, amount, maxAmount, voidExcess, this.supportsCustomMaxAmount); updateDisplayItem(menu, cache); return cache; @@ -353,6 +410,10 @@ public int getMaxAmount() { return maxAmount; } + public boolean supportsCustomMaxAmount() { + return this.supportsCustomMaxAmount; + } + @ParametersAreNonnullByDefault public static void tryInputItem(Location location, ItemStack[] input, QuantumCache cache) { if (cache.getItemStack() == null) { @@ -431,6 +492,12 @@ private static void updateDisplayItem(@Nonnull BlockMenu menu, @Nonnull QuantumC lore.add(""); lore.add(Theme.CLICK_INFO + "Voiding: " + Theme.PASSIVE + StringUtils.toTitleCase(String.valueOf(cache.isVoidExcess()))); lore.add(Theme.CLICK_INFO + "Amount: " + Theme.PASSIVE + cache.getAmount()); + if (cache.supportsCustomMaxAmount()) { + // Cache limit is set at the potentially custom max amount set + // The player could set the custom maximum amount to be the actual maximum amount + lore.add(Theme.CLICK_INFO + "Max Amount: " + Theme.PASSIVE + cache.getLimit()); + } + itemMeta.setLore(lore); itemStack.setItemMeta(itemMeta); itemStack.setAmount(1); @@ -441,6 +508,9 @@ private static void updateDisplayItem(@Nonnull BlockMenu menu, @Nonnull QuantumC private static void syncBlock(@Nonnull Location location, @Nonnull QuantumCache cache) { BlockStorage.addBlockInfo(location, BS_AMOUNT, String.valueOf(cache.getAmount())); BlockStorage.addBlockInfo(location, BS_VOID, String.valueOf(cache.isVoidExcess())); + if (cache.supportsCustomMaxAmount()) { + BlockStorage.addBlockInfo(location, BS_CUSTOM_MAX_AMOUNT, String.valueOf(cache.getLimit())); + } } public static Map getCaches() { diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumWorkbench.java b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumWorkbench.java index 56d05f7ff..1e60092b5 100644 --- a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumWorkbench.java +++ b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkQuantumWorkbench.java @@ -146,7 +146,8 @@ public void craft(@Nonnull BlockMenu menu) { oldCache.getItemStack().clone(), oldCache.getAmount(), newQuantum.getMaxAmount(), - oldCache.isVoidExcess() + oldCache.isVoidExcess(), + newQuantum.supportsCustomMaxAmount() ); DataTypeMethods.setCustom(newMeta, Keys.QUANTUM_STORAGE_INSTANCE, PersistentQuantumStorageType.TYPE, newCache); newCache.addMetaLore(newMeta); diff --git a/src/main/java/io/github/sefiraat/networks/utils/datatypes/PersistentQuantumStorageType.java b/src/main/java/io/github/sefiraat/networks/utils/datatypes/PersistentQuantumStorageType.java index 7c981ebb0..e9abfff25 100644 --- a/src/main/java/io/github/sefiraat/networks/utils/datatypes/PersistentQuantumStorageType.java +++ b/src/main/java/io/github/sefiraat/networks/utils/datatypes/PersistentQuantumStorageType.java @@ -28,6 +28,7 @@ public class PersistentQuantumStorageType implements PersistentDataType