|
1 | 1 | package ch.njol.skript.aliases; |
2 | 2 |
|
| 3 | +import ch.njol.skript.Skript; |
3 | 4 | import ch.njol.skript.aliases.ItemData.OldItemData; |
4 | 5 | import ch.njol.skript.bukkitutil.BukkitUnsafe; |
5 | 6 | import ch.njol.skript.bukkitutil.ItemUtils; |
|
21 | 22 | import ch.njol.yggdrasil.Fields; |
22 | 23 | import ch.njol.yggdrasil.Fields.FieldContext; |
23 | 24 | import ch.njol.yggdrasil.YggdrasilSerializable.YggdrasilExtendedSerializable; |
| 25 | +import com.google.common.collect.Iterators; |
24 | 26 | import org.bukkit.*; |
25 | 27 | import org.bukkit.block.Block; |
26 | 28 | import org.bukkit.block.BlockState; |
|
50 | 52 | public class ItemType implements Unit, Iterable<ItemData>, Container<ItemStack>, YggdrasilExtendedSerializable, |
51 | 53 | AnyNamed, AnyAmount { |
52 | 54 |
|
| 55 | + private static final boolean IS_RUNNING_1_21 = Skript.isRunningMinecraft(1, 21); |
| 56 | + |
53 | 57 | static { |
54 | 58 | // This handles updating ItemType and ItemData variable records |
55 | 59 | Variables.yggdrasil.registerFieldHandler(new FieldHandler() { |
@@ -710,20 +714,18 @@ public static ItemStack[] getCopiedContents(Inventory invi) { |
710 | 714 | } |
711 | 715 |
|
712 | 716 | /** |
713 | | - * Gets copy of storage contents, i.e. ignores armor and off hand. This is due to Spigot 1.9 |
714 | | - * added armor slots, and off hand to default inventory index. |
715 | | - * @param invi Inventory |
| 717 | + * Gets copy of storage contents, i.e. ignores armor and off hand. |
| 718 | + * This method simply calls {@link Inventory#getStorageContents()} and clones the items contained within the array. |
| 719 | + * @param inventory The inventory to obtain contents from. |
716 | 720 | * @return Copied storage contents |
717 | 721 | */ |
718 | | - public static ItemStack[] getStorageContents(final Inventory invi) { |
719 | | - if (invi instanceof PlayerInventory) { |
720 | | - ItemStack[] buf = invi.getContents(); |
721 | | - ItemStack[] tBuf = new ItemStack[36]; |
722 | | - for (int i = 0; i < 36; i++) |
723 | | - if (buf[i] != null) |
724 | | - tBuf[i] = buf[i].clone(); |
725 | | - return tBuf; |
726 | | - } else return getCopiedContents(invi); |
| 722 | + public static ItemStack[] getStorageContents(Inventory inventory) { |
| 723 | + ItemStack[] buf = inventory.getStorageContents(); |
| 724 | + for (int i = 0; i < buf.length; i++) { |
| 725 | + if (buf[i] != null) |
| 726 | + buf[i] = buf[i].clone(); |
| 727 | + } |
| 728 | + return buf; |
727 | 729 | } |
728 | 730 |
|
729 | 731 | /** |
@@ -969,33 +971,46 @@ public void addTo(final List<ItemStack> list) { |
969 | 971 | /** |
970 | 972 | * Tries to add this ItemType to the given inventory. Does not call updateInventory for players. |
971 | 973 | * |
972 | | - * @param invi |
| 974 | + * @param inventory The inventory to add this the {@link ItemStack}(s) represented by this ItemType to. |
973 | 975 | * @return Whether everything could be added to the inventory |
974 | 976 | */ |
975 | | - public boolean addTo(final Inventory invi) { |
976 | | - // important: don't use inventory.add() - it ignores max stack sizes |
977 | | - ItemStack[] buf = invi.getContents(); |
978 | | - |
979 | | - ItemStack[] tBuf = buf.clone(); |
980 | | - if (invi instanceof PlayerInventory) { |
981 | | - buf = new ItemStack[36]; |
982 | | - for(int i = 0; i < 36; ++i) { |
983 | | - buf[i] = tBuf[i]; |
| 977 | + public boolean addTo(Inventory inventory) { |
| 978 | + // TODO remove this when applicable |
| 979 | + // On newer versions, such as 1.21.6, this legacy method of manually rewriting inventory content arrays risks |
| 980 | + // accidental item deletion and fails to respect properties such as stack size. |
| 981 | + // Thus, we switch to use the API methods. However, these API methods do not work properly on older versions |
| 982 | + // such as 1.20.6. For those versions, we continue to use this legacy method. |
| 983 | + // See https://github.com/SkriptLang/Skript/pull/7986 |
| 984 | + if (!IS_RUNNING_1_21) { |
| 985 | + // important: don't use inventory.add() - it ignores max stack sizes |
| 986 | + ItemStack[] buf = inventory.getContents(); |
| 987 | + |
| 988 | + ItemStack[] tBuf = buf.clone(); |
| 989 | + if (inventory instanceof PlayerInventory) { |
| 990 | + buf = new ItemStack[36]; |
| 991 | + for(int i = 0; i < 36; ++i) { |
| 992 | + buf[i] = tBuf[i]; |
| 993 | + } |
984 | 994 | } |
985 | | - } |
986 | 995 |
|
987 | | - final boolean b = addTo(buf); |
| 996 | + final boolean b = addTo(buf); |
988 | 997 |
|
989 | | - if (invi instanceof PlayerInventory) { |
990 | | - buf = Arrays.copyOf(buf, tBuf.length); |
991 | | - for (int i = tBuf.length - 5; i < tBuf.length; ++i) { |
992 | | - buf[i] = tBuf[i]; |
| 998 | + if (inventory instanceof PlayerInventory) { |
| 999 | + buf = Arrays.copyOf(buf, tBuf.length); |
| 1000 | + for (int i = tBuf.length - 5; i < tBuf.length; ++i) { |
| 1001 | + buf[i] = tBuf[i]; |
| 1002 | + } |
993 | 1003 | } |
994 | | - } |
995 | 1004 |
|
996 | | - assert buf != null; |
997 | | - invi.setContents(buf); |
998 | | - return b; |
| 1005 | + assert buf != null; |
| 1006 | + inventory.setContents(buf); |
| 1007 | + return b; |
| 1008 | + } |
| 1009 | + if (!isAll()) { |
| 1010 | + ItemStack random = getItem().getRandom(); |
| 1011 | + return random == null || inventory.addItem(random).isEmpty(); |
| 1012 | + } |
| 1013 | + return inventory.addItem(Iterators.toArray(getItem().getAll().iterator(), ItemStack.class)).isEmpty(); |
999 | 1014 | } |
1000 | 1015 |
|
1001 | 1016 | private static boolean addTo(@Nullable ItemStack is, ItemStack[] buf) { |
|
0 commit comments