mirror of https://github.com/YatopiaMC/Yatopia.git
514 lines
20 KiB
Diff
514 lines
20 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Paul Sauve <paul@technove.co>
|
|
Date: Wed, 19 May 2021 13:08:26 -0500
|
|
Subject: [PATCH] Improve container checking with a bitset
|
|
|
|
|
|
diff --git a/src/main/java/gg/airplane/structs/ItemListWithBitset.java b/src/main/java/gg/airplane/structs/ItemListWithBitset.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..7103aa120d3a27d5579d54bd6f4018dc20cca95c
|
|
--- /dev/null
|
|
+++ b/src/main/java/gg/airplane/structs/ItemListWithBitset.java
|
|
@@ -0,0 +1,105 @@
|
|
+package gg.airplane.structs;
|
|
+
|
|
+import net.minecraft.core.NonNullList;
|
|
+import net.minecraft.world.item.ItemStack;
|
|
+import org.apache.commons.lang.Validate;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+
|
|
+import java.util.Arrays;
|
|
+
|
|
+public class ItemListWithBitset extends NonNullList<ItemStack> {
|
|
+ public static ItemListWithBitset fromNonNullList(NonNullList<ItemStack> list) {
|
|
+ if (list instanceof ItemListWithBitset) {
|
|
+ return (ItemListWithBitset) list;
|
|
+ }
|
|
+ return new ItemListWithBitset(list);
|
|
+ }
|
|
+
|
|
+ private static ItemStack[] createArray(int size) {
|
|
+ ItemStack[] array = new ItemStack[size];
|
|
+ Arrays.fill(array, ItemStack.NULL_ITEM);
|
|
+ return array;
|
|
+ }
|
|
+
|
|
+ private final ItemStack[] items;
|
|
+
|
|
+ private long bitSet = 0;
|
|
+ private final long allBits;
|
|
+
|
|
+ private ItemListWithBitset(NonNullList<ItemStack> list) {
|
|
+ this(list.size());
|
|
+
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
+ this.set(i, list.get(i));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public ItemListWithBitset(int size) {
|
|
+ super(null, ItemStack.NULL_ITEM);
|
|
+
|
|
+ Validate.isTrue(size < Long.BYTES * 8, "size is too large");
|
|
+
|
|
+ this.items = createArray(size);
|
|
+ this.allBits = ((1L << size) - 1);
|
|
+ }
|
|
+
|
|
+ public boolean isCompletelyEmpty() {
|
|
+ return this.bitSet == 0;
|
|
+ }
|
|
+
|
|
+ public boolean hasFullStacks() {
|
|
+ return (this.bitSet & this.allBits) == allBits;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public ItemStack set(int index, ItemStack itemStack) {
|
|
+ ItemStack existing = this.items[index];
|
|
+
|
|
+ this.items[index] = itemStack;
|
|
+
|
|
+ if (itemStack == ItemStack.NULL_ITEM) {
|
|
+ this.bitSet &= ~(1L << index);
|
|
+ } else {
|
|
+ this.bitSet |= 1L << index;
|
|
+ }
|
|
+
|
|
+ return existing;
|
|
+ }
|
|
+
|
|
+ @NotNull
|
|
+ @Override
|
|
+ public ItemStack get(int var0) {
|
|
+ return this.items[var0];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int size() {
|
|
+ return this.items.length;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void clear() {
|
|
+ Arrays.fill(this.items, ItemStack.NULL_ITEM);
|
|
+ }
|
|
+
|
|
+ // these are unsupported for block inventories which have a static size
|
|
+ @Override
|
|
+ public void add(int var0, ItemStack var1) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public ItemStack remove(int var0) {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public String toString() {
|
|
+ return "ItemListWithBitset{" +
|
|
+ "items=" + Arrays.toString(items) +
|
|
+ ", bitSet=" + Long.toString(bitSet, 2) +
|
|
+ ", allBits=" + Long.toString(allBits, 2) +
|
|
+ ", size=" + this.items.length +
|
|
+ '}';
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
|
|
index b4d8fbbc421b3288ae66db2932825b3e2f9b8d98..1553be4263f08ae21447ccf2e19e8a30a2932208 100644
|
|
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
|
|
@@ -846,6 +846,22 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
return result;
|
|
}
|
|
|
|
+ // Airplane start - skip type lookup if already completed, but still run check
|
|
+ public TileEntity getAndCheckTileEntity(IBlockData data, BlockPosition pos) {
|
|
+ TileEntity result = super.getTileEntity(pos, false);
|
|
+ Block type = data.getBlock();
|
|
+
|
|
+ // copied from above
|
|
+ if (result != null && type != Blocks.AIR) {
|
|
+ if (!result.getTileType().isValidBlock(type)) {
|
|
+ result = fixTileEntity(pos, type, result);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return result;
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
private TileEntity fixTileEntity(BlockPosition pos, Block type, TileEntity found) {
|
|
this.getServer().getLogger().log(Level.SEVERE, "Block at {0}, {1}, {2} is {3} but has {4}" + ". "
|
|
+ "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), type, found});
|
|
diff --git a/src/main/java/net/minecraft/world/IInventory.java b/src/main/java/net/minecraft/world/IInventory.java
|
|
index 774ba6a923f7e329f6af5efc17e1c46e87ed2d77..8faf3850f4c965feec42f6998563b7265a8f599e 100644
|
|
--- a/src/main/java/net/minecraft/world/IInventory.java
|
|
+++ b/src/main/java/net/minecraft/world/IInventory.java
|
|
@@ -1,6 +1,8 @@
|
|
package net.minecraft.world;
|
|
|
|
import java.util.Set;
|
|
+
|
|
+import net.minecraft.core.EnumDirection; // Airplane
|
|
import net.minecraft.world.entity.player.EntityHuman;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
@@ -18,6 +20,70 @@ public interface IInventory extends Clearable {
|
|
|
|
ItemStack getItem(int i);
|
|
|
|
+ // Airplane start - allow the inventory to override and optimize these frequent calls
|
|
+ default boolean hasEmptySlot(EnumDirection enumdirection) { // there is a slot with 0 items in it
|
|
+ if (this instanceof IWorldInventory) {
|
|
+ for (int i : ((IWorldInventory) this).getSlotsForFace(enumdirection)) {
|
|
+ if (this.getHopperItem(i).isEmpty()) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ int size = this.getSize();
|
|
+ for (int i = 0; i < size; i++) {
|
|
+ if (this.getHopperItem(i).isEmpty()) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ default boolean isCompletelyFull(EnumDirection enumdirection) { // every stack is maxed
|
|
+ if (this instanceof IWorldInventory) {
|
|
+ for (int i : ((IWorldInventory) this).getSlotsForFace(enumdirection)) {
|
|
+ ItemStack itemStack = this.getHopperItem(i);
|
|
+ if (itemStack.getCount() < itemStack.getMaxStackSize()) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ int size = this.getSize();
|
|
+ for (int i = 0; i < size; i++) {
|
|
+ ItemStack itemStack = this.getHopperItem(i);
|
|
+ if (itemStack.getCount() < itemStack.getMaxStackSize()) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ default boolean isCompletelyEmpty(EnumDirection enumdirection) {
|
|
+ if (this instanceof IWorldInventory) {
|
|
+ for (int i : ((IWorldInventory) this).getSlotsForFace(enumdirection)) {
|
|
+ if (!this.getHopperItem(i).isEmpty()) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ int size = this.getSize();
|
|
+ for (int i = 0; i < size; i++) {
|
|
+ if (!this.getHopperItem(i).isEmpty()) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
+ // Airplane start - way for inventories to know it's a hopper, skipping certain steps
|
|
+ default ItemStack getHopperItem(int index) {
|
|
+ return this.getItem(index);
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
ItemStack splitStack(int i, int j);
|
|
|
|
ItemStack splitWithoutUpdate(int i);
|
|
diff --git a/src/main/java/net/minecraft/world/InventoryLargeChest.java b/src/main/java/net/minecraft/world/InventoryLargeChest.java
|
|
index 92818df3689e35b921eb04678c84d2dd4b21ddbe..f6b723062a9cd0667efcc0171df71e9df93def06 100644
|
|
--- a/src/main/java/net/minecraft/world/InventoryLargeChest.java
|
|
+++ b/src/main/java/net/minecraft/world/InventoryLargeChest.java
|
|
@@ -1,5 +1,6 @@
|
|
package net.minecraft.world;
|
|
|
|
+import net.minecraft.core.EnumDirection; // Airplane
|
|
import net.minecraft.world.entity.player.EntityHuman;
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
@@ -91,6 +92,30 @@ public class InventoryLargeChest implements IInventory {
|
|
return i >= this.left.getSize() ? this.right.getItem(i - this.left.getSize()) : this.left.getItem(i);
|
|
}
|
|
|
|
+ // Airplane start
|
|
+ @Override
|
|
+ public boolean hasEmptySlot(EnumDirection enumdirection) {
|
|
+ return this.left.hasEmptySlot(null) || this.right.hasEmptySlot(null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyFull(EnumDirection enumdirection) {
|
|
+ return this.left.isCompletelyFull(null) && this.right.isCompletelyFull(null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyEmpty(EnumDirection enumdirection) {
|
|
+ return this.left.isCompletelyEmpty(null) && this.right.isCompletelyEmpty(null);
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
+ // Airplane start
|
|
+ @Override
|
|
+ public ItemStack getHopperItem(int i) {
|
|
+ return i >= this.left.getSize() ? this.right.getHopperItem(i - this.left.getSize()) : this.left.getHopperItem(i);
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
@Override
|
|
public ItemStack splitStack(int i, int j) {
|
|
return i >= this.left.getSize() ? this.right.splitStack(i - this.left.getSize(), j) : this.left.splitStack(i, j);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
index 111f62d0e5b40e945793b8f504f2c035c0884a6a..324b752c70e0bd7ea06caa98ec15cdd4e6ea40ae 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityChest.java
|
|
@@ -36,7 +36,7 @@ import org.bukkit.entity.HumanEntity;
|
|
|
|
public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITickable
|
|
|
|
- private NonNullList<ItemStack> items;
|
|
+ private gg.airplane.structs.ItemListWithBitset items; // Airplane
|
|
protected float a;
|
|
protected float b;
|
|
public int viewingCount;
|
|
@@ -73,10 +73,34 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ private final boolean isNative = getClass().equals(TileEntityChest.class); // Airplane
|
|
+
|
|
protected TileEntityChest(TileEntityTypes<?> tileentitytypes) {
|
|
super(tileentitytypes);
|
|
+ // Airplane start
|
|
+ /*
|
|
this.items = NonNullList.a(27, ItemStack.b);
|
|
+ */
|
|
+ this.items = new gg.airplane.structs.ItemListWithBitset(27);
|
|
+ // Airplane end
|
|
+ }
|
|
+
|
|
+ // Airplane start
|
|
+ @Override
|
|
+ public boolean hasEmptySlot(EnumDirection enumdirection) {
|
|
+ return isNative ? !this.items.hasFullStacks() : super.hasEmptySlot(enumdirection);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyFull(EnumDirection enumdirection) {
|
|
+ return isNative ? this.items.hasFullStacks() && super.isCompletelyFull(enumdirection) : super.isCompletelyFull(enumdirection);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyEmpty(EnumDirection enumdirection) {
|
|
+ return isNative && this.items.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection);
|
|
}
|
|
+ // Airplane end
|
|
|
|
public TileEntityChest() {
|
|
this(TileEntityTypes.CHEST);
|
|
@@ -95,7 +119,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
- this.items = NonNullList.a(this.getSize(), ItemStack.b);
|
|
+ this.items = new gg.airplane.structs.ItemListWithBitset(this.getSize()); // Airplane
|
|
if (!this.b(nbttagcompound)) {
|
|
ContainerUtil.b(nbttagcompound, this.items);
|
|
}
|
|
@@ -295,7 +319,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic
|
|
|
|
@Override
|
|
protected void a(NonNullList<ItemStack> nonnulllist) {
|
|
- this.items = nonnulllist;
|
|
+ this.items = gg.airplane.structs.ItemListWithBitset.fromNonNullList(nonnulllist); // Airplane
|
|
}
|
|
|
|
public static int a(IBlockAccess iblockaccess, BlockPosition blockposition) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityHopper.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityHopper.java
|
|
index 537dc52e5ff3325555ee6049bc7f277952983b76..056d280c7db6fc532d83b2a547d6a01402a49bd0 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityHopper.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityHopper.java
|
|
@@ -46,7 +46,7 @@ import org.bukkit.inventory.Inventory;
|
|
|
|
public class TileEntityHopper extends TileEntityLootable implements IHopper, ITickable {
|
|
|
|
- private NonNullList<ItemStack> items;
|
|
+ private gg.airplane.structs.ItemListWithBitset items; // Airplane
|
|
private int j;
|
|
private long k;
|
|
|
|
@@ -82,14 +82,31 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
|
|
public TileEntityHopper() {
|
|
super(TileEntityTypes.HOPPER);
|
|
- this.items = NonNullList.a(5, ItemStack.b);
|
|
+ this.items = new gg.airplane.structs.ItemListWithBitset(5); // Airplane
|
|
this.j = -1;
|
|
}
|
|
|
|
+ // Airplane start
|
|
+ @Override
|
|
+ public boolean hasEmptySlot(EnumDirection enumdirection) {
|
|
+ return !this.items.hasFullStacks();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyFull(EnumDirection enumdirection) {
|
|
+ return this.items.hasFullStacks() && super.isCompletelyFull(enumdirection);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCompletelyEmpty(EnumDirection enumdirection) {
|
|
+ return this.items.isCompletelyEmpty() || super.isCompletelyEmpty(enumdirection);
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
@Override
|
|
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
|
|
super.load(iblockdata, nbttagcompound);
|
|
- this.items = NonNullList.a(this.getSize(), ItemStack.b);
|
|
+ this.items = new gg.airplane.structs.ItemListWithBitset(this.getSize()); // Airplane
|
|
if (!this.b(nbttagcompound)) {
|
|
ContainerUtil.b(nbttagcompound, this.items);
|
|
}
|
|
@@ -181,16 +198,19 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
|
|
private boolean j() {
|
|
- Iterator iterator = this.items.iterator();
|
|
+ // Airplane start - no iterator
|
|
+ //Iterator iterator = this.items.iterator();
|
|
+ int i = 0;
|
|
|
|
ItemStack itemstack;
|
|
|
|
do {
|
|
- if (!iterator.hasNext()) {
|
|
+ if (i >= this.items.size()) {
|
|
return true;
|
|
}
|
|
|
|
- itemstack = (ItemStack) iterator.next();
|
|
+ itemstack = (ItemStack) this.items.get(i++);
|
|
+ // Airplane end
|
|
} while (!itemstack.isEmpty() && itemstack.getCount() == itemstack.getMaxStackSize());
|
|
|
|
return false;
|
|
@@ -205,7 +225,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
skipPushModeEventFire = skipHopperEvents;
|
|
boolean foundItem = false;
|
|
for (int i = 0; i < this.getSize(); ++i) {
|
|
- ItemStack item = this.getItem(i);
|
|
+ ItemStack item = this.getHopperItem(i); // Airplane
|
|
if (!item.isEmpty()) {
|
|
foundItem = true;
|
|
ItemStack origItemStack = item;
|
|
@@ -429,14 +449,14 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
private static boolean anyMatch(IInventory iinventory, EnumDirection enumdirection, java.util.function.BiPredicate<ItemStack, Integer> test) {
|
|
if (iinventory instanceof IWorldInventory) {
|
|
for (int i : ((IWorldInventory) iinventory).getSlotsForFace(enumdirection)) {
|
|
- if (test.test(iinventory.getItem(i), i)) {
|
|
+ if (test.test(iinventory.getHopperItem(i), i)) { // Airplane
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
int size = iinventory.getSize();
|
|
for (int i = 0; i < size; i++) {
|
|
- if (test.test(iinventory.getItem(i), i)) {
|
|
+ if (test.test(iinventory.getHopperItem(i), i)) { // Airplane
|
|
return true;
|
|
}
|
|
}
|
|
@@ -450,12 +470,22 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
|
|
private boolean b(IInventory iinventory, EnumDirection enumdirection) {
|
|
// Paper start - no streams
|
|
+ // Airplane start - use direct method
|
|
+ /*
|
|
return allMatch(iinventory, enumdirection, STACK_SIZE_TEST);
|
|
+ */
|
|
+ return iinventory.isCompletelyFull(enumdirection);
|
|
+ // Airplane end
|
|
// Paper end
|
|
}
|
|
|
|
private static boolean c(IInventory iinventory, EnumDirection enumdirection) {
|
|
+ // Airplane start - use direct method
|
|
+ /*
|
|
return allMatch(iinventory, enumdirection, IS_EMPTY_TEST);
|
|
+ */
|
|
+ return iinventory.isCompletelyEmpty(enumdirection);
|
|
+ // Airplane end
|
|
}
|
|
|
|
public static boolean a(IHopper ihopper) {
|
|
@@ -594,7 +624,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
|
|
if (a(iinventory1, itemstack, i, enumdirection)) {
|
|
boolean flag = false;
|
|
- boolean flag1 = iinventory1.isEmpty();
|
|
+ boolean flag1 = iinventory1.isCompletelyEmpty(enumdirection); // Airplane
|
|
|
|
if (itemstack1.isEmpty()) {
|
|
IGNORE_TILE_UPDATES = true; // Paper
|
|
@@ -677,7 +707,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
if (block instanceof IInventoryHolder) {
|
|
object = ((IInventoryHolder) block).a(iblockdata, world, blockposition);
|
|
} else if (block.isTileEntity()) {
|
|
- TileEntity tileentity = world.getTileEntity(blockposition);
|
|
+ TileEntity tileentity = ((net.minecraft.server.level.WorldServer) world).getAndCheckTileEntity(iblockdata, blockposition); // Airplane - skip validation check, since we already looked it up
|
|
|
|
if (tileentity instanceof IInventory) {
|
|
object = (IInventory) tileentity;
|
|
@@ -736,7 +766,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
|
|
@Override
|
|
protected void a(NonNullList<ItemStack> nonnulllist) {
|
|
- this.items = nonnulllist;
|
|
+ this.items = gg.airplane.structs.ItemListWithBitset.fromNonNullList(nonnulllist); // Airplane
|
|
}
|
|
|
|
public void a(Entity entity) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TileEntityLootable.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntityLootable.java
|
|
index f0da819627035bed83561128a11059424d2b7e30..36ef5b11f12da1a7e3c8031ec84d28ba22d59a5c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntityLootable.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntityLootable.java
|
|
@@ -98,7 +98,11 @@ public abstract class TileEntityLootable extends TileEntityContainer {
|
|
public boolean isEmpty() {
|
|
this.d((EntityHuman) null);
|
|
// Paper start
|
|
- for (ItemStack itemStack : this.f()) {
|
|
+ // Airplane start - don't use abstract iterator
|
|
+ java.util.List<ItemStack> list = this.f();
|
|
+ for (int i = 0, size = list.size(); i < size; i++) {
|
|
+ ItemStack itemStack = list.get(i);
|
|
+ // Airplane end
|
|
if (!itemStack.isEmpty()) {
|
|
return false;
|
|
}
|
|
@@ -107,6 +111,13 @@ public abstract class TileEntityLootable extends TileEntityContainer {
|
|
return true;
|
|
}
|
|
|
|
+ // Airplane start - skip loot check for hoppers
|
|
+ @Override
|
|
+ public final ItemStack getHopperItem(int index) {
|
|
+ return this.f().get(index);
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
@Override
|
|
public ItemStack getItem(int i) {
|
|
if (i == 0) this.d((EntityHuman) null); // Paper
|