c62efac3eb
Disable push based hoppers by default Set chunk unload delay to 15s by default Neither of these changes are retroactive for old users
374 lines
16 KiB
Diff
374 lines
16 KiB
Diff
From 610d21cb97d0f91919916b135a646f3ece9b78a6 Mon Sep 17 00:00:00 2001
|
|
From: Techcable <Techcable@outlook.com>
|
|
Date: Sat, 18 Jun 2016 01:01:37 -0500
|
|
Subject: [PATCH] Make entities look for hoppers
|
|
|
|
Every tick hoppers try and find an block-inventory to extract from.
|
|
If no tile entity is above the hopper (which there often isn't) it will do a bounding box search for minecart chests and minecart hoppers.
|
|
If it can't find an inventory, it will then look for a dropped item, which is another bounding box search.
|
|
This patch eliminates that expensive check by having dropped items and minecart hoppers/chests look for hoppers instead.
|
|
Hoppers are tile entities meaning you can do a simple tile entity lookup to find the nearest hopper in range.
|
|
Pushing out of hoppers causes a bouding box lookup, which this patch replaces with a tile entity lookup.
|
|
|
|
This patch may causes a decrease in the performance of dropped items, which is why it can be disabled in the configuration.
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/HopperPusher.java b/src/main/java/com/destroystokyo/paper/HopperPusher.java
|
|
new file mode 100644
|
|
index 0000000..aef7c2b
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/HopperPusher.java
|
|
@@ -0,0 +1,59 @@
|
|
+package com.destroystokyo.paper;
|
|
+
|
|
+import net.minecraft.server.AxisAlignedBB;
|
|
+import net.minecraft.server.BlockPosition;
|
|
+import net.minecraft.server.MCUtil;
|
|
+import net.minecraft.server.TileEntityHopper;
|
|
+import net.minecraft.server.World;
|
|
+
|
|
+public interface HopperPusher {
|
|
+
|
|
+ default TileEntityHopper findHopper() {
|
|
+ BlockPosition pos = new BlockPosition(getX(), getY(), getZ());
|
|
+ int startX = pos.getX() - 1;
|
|
+ int endX = pos.getX() + 1;
|
|
+ int startY = Math.max(0, pos.getY() - 1);
|
|
+ int endY = Math.min(255, pos.getY() + 1);
|
|
+ int startZ = pos.getZ() - 1;
|
|
+ int endZ = pos.getZ() + 1;
|
|
+ BlockPosition.PooledBlockPosition adjacentPos = BlockPosition.PooledBlockPosition.aquire();
|
|
+ for (int x = startX; x <= endX; x++) {
|
|
+ for (int y = startY; y <= endY; y++) {
|
|
+ for (int z = startZ; z <= endZ; z++) {
|
|
+ adjacentPos.setValues(x, y, z);
|
|
+ TileEntityHopper hopper = MCUtil.getHopper(getWorld(), adjacentPos);
|
|
+ if (hopper == null) continue; // Avoid playing with the bounding boxes, if at all possible
|
|
+ AxisAlignedBB hopperBoundingBox = hopper.getHopperLookupBoundingBox();
|
|
+ /*
|
|
+ * Check if the entity's bounding box intersects with the hopper's lookup box.
|
|
+ * This operation doesn't work both ways!
|
|
+ * Make sure you check if the entity's box intersects the hopper's box, not vice versa!
|
|
+ */
|
|
+ if (this.getBoundingBox().intersects(hopperBoundingBox)) {
|
|
+ return hopper;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ adjacentPos.free();
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ boolean acceptItem(TileEntityHopper hopper);
|
|
+
|
|
+ default boolean tryPutInHopper() {
|
|
+ if (!getWorld().paperConfig.isHopperPushBased) return false;
|
|
+ TileEntityHopper hopper = findHopper();
|
|
+ return hopper != null && hopper.canAcceptItems() && acceptItem(hopper);
|
|
+ }
|
|
+
|
|
+ AxisAlignedBB getBoundingBox();
|
|
+
|
|
+ World getWorld();
|
|
+
|
|
+ double getX();
|
|
+
|
|
+ double getY();
|
|
+
|
|
+ double getZ();
|
|
+}
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 3500b6c..21c0a3f 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -363,4 +363,9 @@ public class PaperWorldConfig {
|
|
private void altFallingBlockOnGround() {
|
|
altFallingBlockOnGround = getBoolean("use-alternate-fallingblock-onGround-detection", false);
|
|
}
|
|
+
|
|
+ public boolean isHopperPushBased;
|
|
+ private void isHopperPushBased() {
|
|
+ isHopperPushBased = getBoolean("hopper.push-based", false);
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java
|
|
index 8c64279..4445ae7 100644
|
|
--- a/src/main/java/net/minecraft/server/AxisAlignedBB.java
|
|
+++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java
|
|
@@ -191,6 +191,7 @@ public class AxisAlignedBB {
|
|
}
|
|
}
|
|
|
|
+ public final boolean intersects(AxisAlignedBB intersecting) { return this.b(intersecting); } // Paper - OBFHELPER
|
|
public boolean b(AxisAlignedBB axisalignedbb) {
|
|
return this.a(axisalignedbb.a, axisalignedbb.b, axisalignedbb.c, axisalignedbb.d, axisalignedbb.e, axisalignedbb.f);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
|
index d6cc51b..5bbaa87 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
|
@@ -265,6 +265,7 @@ public class BlockPosition extends BaseBlockPosition {
|
|
super(i, j, k);
|
|
}
|
|
|
|
+ public static BlockPosition.PooledBlockPosition aquire() { return s(); } // Paper - OBFHELPER
|
|
public static BlockPosition.PooledBlockPosition s() {
|
|
return e(0, 0, 0);
|
|
}
|
|
@@ -291,6 +292,7 @@ public class BlockPosition extends BaseBlockPosition {
|
|
return new BlockPosition.PooledBlockPosition(i, j, k);
|
|
}
|
|
|
|
+ public void free() { t(); } // Paper - OBFHELPER
|
|
public void t() {
|
|
List list = BlockPosition.PooledBlockPosition.g;
|
|
|
|
@@ -392,6 +394,7 @@ public class BlockPosition extends BaseBlockPosition {
|
|
return this.d;
|
|
}
|
|
|
|
+ public void setValues(int x, int y, int z) { c(x, y, z); } // Paper - OBFHELPER
|
|
public BlockPosition.MutableBlockPosition c(int i, int j, int k) {
|
|
this.b = i;
|
|
this.c = j;
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index fbf114f..d26ffa7 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -77,6 +77,19 @@ public abstract class Entity implements ICommandListener {
|
|
public double locX;
|
|
public double locY;
|
|
public double locZ;
|
|
+ // Paper start - getters to implement HopperPusher
|
|
+ public double getX() {
|
|
+ return locX;
|
|
+ }
|
|
+
|
|
+ public double getY() {
|
|
+ return locY;
|
|
+ }
|
|
+
|
|
+ public double getZ() {
|
|
+ return locZ;
|
|
+ }
|
|
+ // Paper end
|
|
public double motX;
|
|
public double motY;
|
|
public double motZ;
|
|
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
|
|
index 234c547..86be072 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityItem.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityItem.java
|
|
@@ -6,8 +6,15 @@ import javax.annotation.Nullable;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit
|
|
+import com.destroystokyo.paper.HopperPusher; // Paper
|
|
|
|
-public class EntityItem extends Entity {
|
|
+// Paper start - implement HopperPusher
|
|
+public class EntityItem extends Entity implements HopperPusher {
|
|
+ @Override
|
|
+ public boolean acceptItem(TileEntityHopper hopper) {
|
|
+ return TileEntityHopper.a(hopper, this);
|
|
+ }
|
|
+// Paper end
|
|
|
|
private static final Logger b = LogManager.getLogger();
|
|
private static final DataWatcherObject<Optional<ItemStack>> c = DataWatcher.a(EntityItem.class, DataWatcherRegistry.f);
|
|
@@ -62,6 +69,7 @@ public class EntityItem extends Entity {
|
|
this.die();
|
|
} else {
|
|
super.m();
|
|
+ if (tryPutInHopper()) return; // Paper
|
|
// CraftBukkit start - Use wall time for pickup and despawn timers
|
|
int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
|
|
if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks;
|
|
@@ -129,6 +137,7 @@ public class EntityItem extends Entity {
|
|
// Spigot start - copied from above
|
|
@Override
|
|
public void inactiveTick() {
|
|
+ if (tryPutInHopper()) return; // Paper
|
|
// CraftBukkit start - Use wall time for pickup and despawn timers
|
|
int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
|
|
if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks;
|
|
diff --git a/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
index a9b8cfd..6abf6b1 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
@@ -6,6 +6,7 @@ import javax.annotation.Nullable;
|
|
import java.util.List;
|
|
import org.bukkit.Location;
|
|
|
|
+import com.destroystokyo.paper.HopperPusher; // Paper
|
|
import com.destroystokyo.paper.loottable.CraftLootableInventoryData; // Paper
|
|
import com.destroystokyo.paper.loottable.CraftLootableInventory; // Paper
|
|
import com.destroystokyo.paper.loottable.LootableInventory; // Paper
|
|
@@ -14,7 +15,25 @@ import org.bukkit.entity.HumanEntity;
|
|
import org.bukkit.inventory.InventoryHolder;
|
|
// CraftBukkit end
|
|
|
|
-public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ITileInventory, ILootable, CraftLootableInventory { // Paper
|
|
+// Paper start - push into hoppers
|
|
+public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ITileInventory, ILootable, CraftLootableInventory, HopperPusher { // Paper - CraftLootableInventory
|
|
+ @Override
|
|
+ public boolean acceptItem(TileEntityHopper hopper) {
|
|
+ return TileEntityHopper.acceptItem(hopper, this);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void m() {
|
|
+ super.m();
|
|
+ tryPutInHopper();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void inactiveTick() {
|
|
+ super.inactiveTick();
|
|
+ tryPutInHopper();
|
|
+ }
|
|
+ // Paper end
|
|
|
|
private ItemStack[] items = new ItemStack[27]; // CraftBukkit - 36 -> 27
|
|
private boolean b = true;
|
|
diff --git a/src/main/java/net/minecraft/server/IHopper.java b/src/main/java/net/minecraft/server/IHopper.java
|
|
index 804215a..e830d83 100644
|
|
--- a/src/main/java/net/minecraft/server/IHopper.java
|
|
+++ b/src/main/java/net/minecraft/server/IHopper.java
|
|
@@ -4,9 +4,9 @@ public interface IHopper extends IInventory {
|
|
|
|
World getWorld();
|
|
|
|
- double E();
|
|
+ double E(); default double getX() { return E(); } // Paper - OBFHELPER
|
|
|
|
- double F();
|
|
+ double F(); default double getY() { return F(); } // Paper - OBFHELPER
|
|
|
|
- double G();
|
|
+ double G(); default double getZ() { return G(); } // Paper - OBFHELPER
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
index a651961..1f5de89 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
@@ -170,6 +170,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
|
|
public boolean m() {
|
|
+ mayAcceptItems = false; // Paper - at the beginning of a tick, assume we can't accept items
|
|
if (this.world != null && !this.world.isClientSide) {
|
|
if (!this.o() && BlockHopper.f(this.u())) {
|
|
boolean flag = false;
|
|
@@ -179,6 +180,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
|
|
if (!this.r()) {
|
|
+ mayAcceptItems = true; // Paper - flag this hopper to be able to accept items
|
|
flag = a((IHopper) this) || flag;
|
|
}
|
|
|
|
@@ -195,6 +197,14 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
}
|
|
|
|
+ // Paper start
|
|
+ private boolean mayAcceptItems = false;
|
|
+
|
|
+ public boolean canAcceptItems() {
|
|
+ return mayAcceptItems;
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
private boolean q() {
|
|
ItemStack[] aitemstack = this.items;
|
|
int i = aitemstack.length;
|
|
@@ -338,8 +348,15 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
return true;
|
|
}
|
|
|
|
+ // Paper start - split methods, and only do entity lookup if in pull mode
|
|
public static boolean a(IHopper ihopper) {
|
|
- IInventory iinventory = b(ihopper);
|
|
+ IInventory iinventory = getInventory(ihopper, !(ihopper instanceof TileEntityHopper) || !ihopper.getWorld().paperConfig.isHopperPushBased);
|
|
+
|
|
+ return acceptItem(ihopper, iinventory);
|
|
+ }
|
|
+
|
|
+ public static boolean acceptItem(IHopper ihopper, IInventory iinventory) {
|
|
+ // Paper end
|
|
|
|
if (iinventory != null) {
|
|
EnumDirection enumdirection = EnumDirection.DOWN;
|
|
@@ -370,8 +387,8 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
}
|
|
}
|
|
- } else {
|
|
- Iterator iterator = a(ihopper.getWorld(), ihopper.E(), ihopper.F(), ihopper.G()).iterator();
|
|
+ } else if (!ihopper.getWorld().paperConfig.isHopperPushBased || !(ihopper instanceof TileEntityHopper)) { // Paper - only search for entities in 'pull mode'
|
|
+ Iterator iterator = a(ihopper.getWorld(), ihopper.E(), ihopper.F(), ihopper.G()).iterator(); // Change getHopperLookupBoundingBox() if this ever changes
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityItem entityitem = (EntityItem) iterator.next();
|
|
@@ -535,18 +552,44 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
private IInventory I() {
|
|
EnumDirection enumdirection = BlockHopper.e(this.u());
|
|
|
|
- return b(this.getWorld(), this.E() + (double) enumdirection.getAdjacentX(), this.F() + (double) enumdirection.getAdjacentY(), this.G() + (double) enumdirection.getAdjacentZ());
|
|
+ // Paper start - don't search for entities in push mode
|
|
+ World world = getWorld();
|
|
+ return getInventory(world, this.E() + (double) enumdirection.getAdjacentX(), this.F() + (double) enumdirection.getAdjacentY(), this.G() + (double) enumdirection.getAdjacentZ(), !world.paperConfig.isHopperPushBased);
|
|
+ // Paper end
|
|
}
|
|
|
|
- public static IInventory b(IHopper ihopper) {
|
|
- return b(ihopper.getWorld(), ihopper.E(), ihopper.F() + 1.0D, ihopper.G());
|
|
+ // Paper start - add option to search for entities
|
|
+ public static IInventory b(IHopper hopper) {
|
|
+ return getInventory(hopper, true);
|
|
+ }
|
|
+
|
|
+ public static IInventory getInventory(IHopper ihopper, boolean searchForEntities) {
|
|
+ return getInventory(ihopper.getWorld(), ihopper.E(), ihopper.F() + 1.0D, ihopper.G(), searchForEntities);
|
|
+ // Paper end
|
|
}
|
|
|
|
public static List<EntityItem> a(World world, double d0, double d1, double d2) {
|
|
- return world.a(EntityItem.class, new AxisAlignedBB(d0 - 0.5D, d1, d2 - 0.5D, d0 + 0.5D, d1 + 1.5D, d2 + 0.5D), IEntitySelector.a);
|
|
+ return world.a(EntityItem.class, new AxisAlignedBB(d0 - 0.5D, d1, d2 - 0.5D, d0 + 0.5D, d1 + 1.5D, d2 + 0.5D), IEntitySelector.a); // Change getHopperLookupBoundingBox(double, double, double) if the bounding box calculation is ever changed
|
|
+ }
|
|
+
|
|
+ // Paper start
|
|
+ public AxisAlignedBB getHopperLookupBoundingBox() {
|
|
+ return getHopperLookupBoundingBox(this.getX(), this.getY(), this.getZ());
|
|
}
|
|
|
|
+ private static AxisAlignedBB getHopperLookupBoundingBox(double d0, double d1, double d2) {
|
|
+ // Change this if a(World, double, double, double) above ever changes
|
|
+ return new AxisAlignedBB(d0 - 0.5D, d1, d2 - 0.5D, d0 + 0.5D, d1 + 1.5D, d2 + 0.5D);
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
+ // Paper start - add option to searchForEntities
|
|
public static IInventory b(World world, double d0, double d1, double d2) {
|
|
+ return getInventory(world, d0, d1, d2, true);
|
|
+ }
|
|
+
|
|
+ public static IInventory getInventory(World world, double d0, double d1, double d2, boolean searchForEntities) {
|
|
+ // Paper end
|
|
Object object = null;
|
|
int i = MathHelper.floor(d0);
|
|
int j = MathHelper.floor(d1);
|
|
@@ -566,7 +609,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
|
}
|
|
}
|
|
|
|
- if (object == null) {
|
|
+ if (object == null && searchForEntities) { // Paper - only if searchForEntities
|
|
List list = world.getEntities((Entity) null, new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), IEntitySelector.c);
|
|
|
|
if (!list.isEmpty()) {
|
|
--
|
|
2.9.0
|
|
|