|
|
|
@@ -8,114 +8,181 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/d93e9766d3797d130
|
|
|
|
|
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
|
|
|
|
index 5995c499298454a060433746c64be5fcc8d202e2..3452399de0fa464ce04a7cf1a05b440346bef662 100644
|
|
|
|
|
index 102de78be0eb82d6898b4104fad1bf5e8366f993..11891a66fe3232287238ea87289444586fbc9717 100644
|
|
|
|
|
--- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
|
|
|
|
+++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
|
|
|
|
@@ -17,29 +17,30 @@
|
|
|
|
|
@@ -17,12 +17,173 @@
|
|
|
|
|
|
|
|
|
|
package org.leavesmc.leaves.util;
|
|
|
|
|
|
|
|
|
|
+import fun.bm.lophine.config.modules.misc.ContainerExpansionConfig;
|
|
|
|
|
//import io.papermc.paper.datacomponent.DataComponentTypes;
|
|
|
|
|
//import io.papermc.paper.datacomponent.item.ItemEnchantments;
|
|
|
|
|
import net.minecraft.core.component.DataComponents;
|
|
|
|
|
import net.minecraft.nbt.CompoundTag;
|
|
|
|
|
import net.minecraft.world.entity.item.ItemEntity;
|
|
|
|
|
-//import net.minecraft.world.item.BlockItem;
|
|
|
|
|
+import net.minecraft.core.component.DataComponents;
|
|
|
|
|
+import net.minecraft.nbt.CompoundTag;
|
|
|
|
|
+import net.minecraft.world.entity.item.ItemEntity;
|
|
|
|
|
+import net.minecraft.world.item.BlockItem;
|
|
|
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
|
import net.minecraft.world.item.component.CustomData;
|
|
|
|
|
-//import net.minecraft.world.item.component.ItemContainerContents;
|
|
|
|
|
-//import net.minecraft.world.level.block.ShulkerBoxBlock;
|
|
|
|
|
+import net.minecraft.world.item.component.CustomData;
|
|
|
|
|
+import net.minecraft.world.item.component.ItemContainerContents;
|
|
|
|
|
+import net.minecraft.world.level.block.ShulkerBoxBlock;
|
|
|
|
|
//import org.bukkit.enchantments.Enchantment;
|
|
|
|
|
-//import org.jetbrains.annotations.NotNull;
|
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
|
|
//import org.leavesmc.leaves.LeavesConfig;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
-//import java.util.Objects;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Objects;
|
|
|
|
|
import java.util.Optional;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
|
|
|
|
|
// Only the used part is retained
|
|
|
|
|
public class ItemOverstackUtils {
|
|
|
|
|
|
|
|
|
|
private static final List<ItemUtil> overstackUtils = List.of(
|
|
|
|
|
-/* new ShulkerBox(),
|
|
|
|
|
- new CurseEnchantedBook()*/
|
|
|
|
|
+ private static final List<ItemUtil> overstackUtils = List.of(
|
|
|
|
|
+ new ShulkerBox()
|
|
|
|
|
+ // new CurseEnchantedBook() // only use shulker box part
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
public static int getItemStackMaxCount(ItemStack stack) {
|
|
|
|
|
@@ -109,6 +110,7 @@ public class ItemOverstackUtils {
|
|
|
|
|
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ public static int getItemStackMaxCount(ItemStack stack) {
|
|
|
|
|
+ int size;
|
|
|
|
|
+ for (ItemUtil util : overstackUtils) {
|
|
|
|
|
+ if ((size = util.getMaxServerStackCount(stack)) != -1) {
|
|
|
|
|
+ return size;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return stack.getMaxStackSize();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static int getNetworkMaxCount(ItemStack stack) {
|
|
|
|
|
+ int size;
|
|
|
|
|
+ for (ItemUtil util : overstackUtils) {
|
|
|
|
|
+ if ((size = util.getMaxClientStackCount(stack)) != -1) {
|
|
|
|
|
+ return size;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return stack.getMaxStackSize();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
|
|
|
+ for (ItemUtil util : overstackUtils) {
|
|
|
|
|
+ if (util.tryStackItems(self, other)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean hasOverstackingItem() {
|
|
|
|
|
+ return overstackUtils.stream().anyMatch(ItemUtil::isEnabled);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static int getItemStackMaxCountReal(ItemStack stack) {
|
|
|
|
|
+ CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag();
|
|
|
|
|
+ return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ItemStack encodeMaxStackSize(ItemStack itemStack) {
|
|
|
|
|
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
|
|
|
|
+ int modifiedMaxStackSize = getNetworkMaxCount(itemStack);
|
|
|
|
|
+ if (itemStack.getMaxStackSize() != modifiedMaxStackSize) {
|
|
|
|
|
+ itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize);
|
|
|
|
|
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
|
|
|
|
+ nbt.putInt("Leaves.RealStackSize", realMaxStackSize);
|
|
|
|
|
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
|
|
|
|
+ }
|
|
|
|
|
+ return itemStack;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ItemStack decodeMaxStackSize(ItemStack itemStack) {
|
|
|
|
|
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
|
|
|
|
|
+ if (itemStack.getMaxStackSize() != realMaxStackSize) {
|
|
|
|
|
+ itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize);
|
|
|
|
|
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
|
|
|
|
+ nbt.remove("Leaves.RealStackSize");
|
|
|
|
|
+ if (nbt.isEmpty()) {
|
|
|
|
|
+ itemStack.remove(DataComponents.CUSTOM_DATA);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return itemStack;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
public static float getItemStackSignalStrength(int maxStackSize, ItemStack itemStack) {
|
|
|
|
|
float result = (float) itemStack.getCount() / Math.min(maxStackSize, itemStack.getMaxStackSize());
|
|
|
|
|
+ // only use shulker box part
|
|
|
|
|
/* if (LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && CurseEnchantedBook.isCursedEnchantedBook(itemStack)) {
|
|
|
|
|
return result;
|
|
|
|
|
}*/
|
|
|
|
|
@@ -134,9 +136,9 @@ public class ItemOverstackUtils {
|
|
|
|
|
}
|
|
|
|
|
return Math.clamp(result, 0f, 1f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-/* private static class ShulkerBox implements ItemUtil {
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean isStackable(ItemStack itemStack) {
|
|
|
|
|
+ return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private interface ItemUtil {
|
|
|
|
|
+ boolean isEnabled();
|
|
|
|
|
+
|
|
|
|
|
+ boolean tryStackItems(ItemEntity self, ItemEntity other);
|
|
|
|
|
+
|
|
|
|
|
+ // number -> modified count, -1 -> I don't care
|
|
|
|
|
+ int getMaxServerStackCount(ItemStack stack);
|
|
|
|
|
+
|
|
|
|
|
+ // number -> modified count, -1 -> I don't care
|
|
|
|
|
+ default int getMaxClientStackCount(ItemStack stack) {
|
|
|
|
|
+ return getMaxServerStackCount(stack);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class ShulkerBox implements ItemUtil {
|
|
|
|
|
public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
|
|
|
|
|
- if (LeavesConfig.modify.shulkerBox.sameNbtStackable) {
|
|
|
|
|
+ public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
|
|
|
|
|
+ if (ContainerExpansionConfig.nbtShulkerStackable) {
|
|
|
|
|
return Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
|
|
|
}
|
|
|
|
|
return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
|
|
|
@@ -148,24 +150,24 @@ public class ItemOverstackUtils {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isEnabled() {
|
|
|
|
|
- return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize > 1;
|
|
|
|
|
+ return Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
|
|
|
+ }
|
|
|
|
|
+ return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) {
|
|
|
|
|
+ return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean isEnabled() {
|
|
|
|
|
+ return ContainerExpansionConfig.shulkerCount > 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
|
|
|
ItemStack selfStack = self.getItem();
|
|
|
|
|
if (!isEnabled() ||
|
|
|
|
|
- !(selfStack.getItem() instanceof BlockItem blockItem) ||
|
|
|
|
|
- !(blockItem.getBlock() instanceof ShulkerBoxBlock)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public boolean tryStackItems(ItemEntity self, ItemEntity other) {
|
|
|
|
|
+ ItemStack selfStack = self.getItem();
|
|
|
|
|
+ if (!isEnabled() ||
|
|
|
|
|
+ !(selfStack.getItem() instanceof BlockItem blockItem) ||
|
|
|
|
|
+ !(blockItem.getBlock() instanceof ShulkerBoxBlock)
|
|
|
|
|
) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ItemStack otherStack = other.getItem();
|
|
|
|
|
if (selfStack.getItem() == otherStack.getItem()
|
|
|
|
|
- && shulkerBoxCheck(selfStack, otherStack)
|
|
|
|
|
- && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize) {
|
|
|
|
|
- int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize - selfStack.getCount());
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ItemStack otherStack = other.getItem();
|
|
|
|
|
+ if (selfStack.getItem() == otherStack.getItem()
|
|
|
|
|
+ && shulkerBoxCheck(selfStack, otherStack)
|
|
|
|
|
+ && selfStack.getCount() != ContainerExpansionConfig.shulkerCount) {
|
|
|
|
|
+ int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount());
|
|
|
|
|
|
|
|
|
|
selfStack.grow(amount);
|
|
|
|
|
self.setItem(selfStack);
|
|
|
|
|
@@ -187,14 +189,15 @@ public class ItemOverstackUtils {
|
|
|
|
|
@Override
|
|
|
|
|
public int getMaxServerStackCount(ItemStack stack) {
|
|
|
|
|
if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
|
|
|
|
|
- bi.getBlock() instanceof ShulkerBoxBlock && (LeavesConfig.modify.shulkerBox.sameNbtStackable || shulkerBoxNoItem(stack))) {
|
|
|
|
|
- return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize;
|
|
|
|
|
+
|
|
|
|
|
+ selfStack.grow(amount);
|
|
|
|
|
+ self.setItem(selfStack);
|
|
|
|
|
+
|
|
|
|
|
+ self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay);
|
|
|
|
|
+ self.age = Math.min(other.getAge(), self.age);
|
|
|
|
|
+
|
|
|
|
|
+ otherStack.shrink(amount);
|
|
|
|
|
+ if (otherStack.isEmpty()) {
|
|
|
|
|
+ other.discard();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ other.setItem(otherStack);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public int getMaxServerStackCount(ItemStack stack) {
|
|
|
|
|
+ if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
|
|
|
|
|
+ bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) {
|
|
|
|
|
+ return ContainerExpansionConfig.shulkerCount;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- public static class CurseEnchantedBook implements ItemUtil {
|
|
|
|
|
+// only use shulker box part
|
|
|
|
|
+/* public static class CurseEnchantedBook implements ItemUtil {
|
|
|
|
|
public static boolean isCursedEnchantedBook(ItemStack stack) {
|
|
|
|
|
ItemEnchantments enchantments = stack.getBukkitStack().getData(DataComponentTypes.STORED_ENCHANTMENTS);
|
|
|
|
|
if (enchantments == null || enchantments.enchantments().size() != 1) {
|
|
|
|
|
+ }
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
\ No newline at end of file
|
|
|
|
|