mirror of
https://github.com/PaperMC/Paper.git
synced 2025-03-29 17:50:24 +01:00
Tick a hopper only if certain conditions have changed i.e. inventory changes, redstone updates, etc.
323 lines
No EOL
15 KiB
Diff
323 lines
No EOL
15 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: "Evan A. Haskell" <eah2119@gmail.com>
|
|
Date: Sat, 19 Apr 2014 16:58:26 -0400
|
|
Subject: [PATCH] Schedule Hopper Ticks
|
|
|
|
Tick a hopper only if certain conditions have changed i.e. inventory changes, redstone updates, etc.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/BlockHopper.java b/src/main/java/net/minecraft/server/BlockHopper.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockHopper.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockHopper.java
|
|
@@ -0,0 +0,0 @@ public class BlockHopper extends BlockContainer {
|
|
this.j(this.blockStateList.getBlockData().set(BlockHopper.FACING, EnumDirection.DOWN).set(BlockHopper.ENABLED, Boolean.valueOf(true)));
|
|
this.a(CreativeModeTab.d);
|
|
this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
|
+ this.a(true); // Spigot - Enable random block updates on hoppers // PAIL: Rename
|
|
}
|
|
|
|
public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
|
|
@@ -0,0 +0,0 @@ public class BlockHopper extends BlockContainer {
|
|
|
|
if (flag != ((Boolean) iblockdata.get(BlockHopper.ENABLED)).booleanValue()) {
|
|
world.setTypeAndData(blockposition, iblockdata.set(BlockHopper.ENABLED, Boolean.valueOf(flag)), 4);
|
|
+ // Spigot start - When this hopper becomes unpowered, make it active.
|
|
+ // Called when this block's power level changes. flag1 is the current
|
|
+ // isNotPowered from metadata. flag is the recalculated isNotPowered.
|
|
+ TileEntityHopper hopper = (TileEntityHopper) world.getTileEntity(blockposition);
|
|
+ if (flag && hopper != null) {
|
|
+ hopper.ensureUpdates();
|
|
+ }
|
|
+ // Spigot end
|
|
}
|
|
|
|
}
|
|
@@ -0,0 +0,0 @@ public class BlockHopper extends BlockContainer {
|
|
protected BlockStateList getStateList() {
|
|
return new BlockStateList(this, new IBlockState[] { BlockHopper.FACING, BlockHopper.ENABLED});
|
|
}
|
|
+
|
|
+ // Spigot start - Use random block updates to make hoppers active.
|
|
+ // PAIL: Rename
|
|
+ @Override
|
|
+ public void a(World world, BlockPosition blockposition, IBlockData iblockdata, java.util.Random random) {
|
|
+ TileEntityHopper hopper = (TileEntityHopper) world.getTileEntity(blockposition);
|
|
+ if (hopper != null) {
|
|
+ hopper.ensureUpdates();
|
|
+ }
|
|
+ }
|
|
+ // Spigot end
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -0,0 +0,0 @@ public class Chunk {
|
|
|
|
tileentity.D();
|
|
this.tileEntities.put(blockposition, tileentity);
|
|
+ // Spigot start
|
|
+ // When a tile entity is added, update hoppers around the tile
|
|
+ tileentity.scheduleTicks();
|
|
+
|
|
+ // if it is a large chest, hoppers should update around its
|
|
+ // other half
|
|
+ TileEntity.updateChestAndHoppers(this.world, blockposition);
|
|
+ // Spigot end
|
|
// CraftBukkit start
|
|
} else {
|
|
System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ()
|
|
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityItem.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityItem.java
|
|
@@ -0,0 +0,0 @@ public class EntityItem extends Entity {
|
|
if (this.onGround) {
|
|
this.motY *= -0.5D;
|
|
}
|
|
+ // Spigot start - Make the hopper(s) below this item active.
|
|
+ // Called each tick on each item entity.
|
|
+ int xi = MathHelper.floor(this.getBoundingBox().a);
|
|
+ int yi = MathHelper.floor(this.getBoundingBox().b) - 1;
|
|
+ int zi = MathHelper.floor(this.getBoundingBox().c);
|
|
+ int xf = MathHelper.floor(this.getBoundingBox().d);
|
|
+ int yf = MathHelper.floor(this.getBoundingBox().e) - 1;
|
|
+ int zf = MathHelper.floor(this.getBoundingBox().f);
|
|
+ for (int a = xi; a <= xf; a++) {
|
|
+ for (int c = zi; c <= zf; c++) {
|
|
+ for (int b = yi; b <= yf; b++) {
|
|
+ TileEntity tileEntity = this.world.getTileEntity(new BlockPosition(a, b, c));
|
|
+ if (tileEntity instanceof TileEntityHopper) {
|
|
+ ((TileEntityHopper) tileEntity).ensureUpdates();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Spigot end
|
|
|
|
/* Craftbukkit start - moved up
|
|
if (this.age != -32768) {
|
|
diff --git a/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
|
|
@@ -0,0 +0,0 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp
|
|
super(world, d0, d1, d2);
|
|
}
|
|
|
|
+ // Spigot start - Make hoppers around this container minecart active.
|
|
+ // Called each tick on each minecart.
|
|
+ // PAIL: Rename
|
|
+ @Override
|
|
+ public void t_() {
|
|
+ int xi = MathHelper.floor(this.getBoundingBox().a) - 1;
|
|
+ int yi = MathHelper.floor(this.getBoundingBox().b) - 1;
|
|
+ int zi = MathHelper.floor(this.getBoundingBox().c) - 1;
|
|
+ int xf = MathHelper.floor(this.getBoundingBox().d) + 1;
|
|
+ int yf = MathHelper.floor(this.getBoundingBox().e) + 1;
|
|
+ int zf = MathHelper.floor(this.getBoundingBox().f) + 1;
|
|
+ for (int a = xi; a <= xf; a++) {
|
|
+ for (int b = yi; b <= yf; b++) {
|
|
+ for (int c = zi; c <= zf; c++) {
|
|
+ TileEntity tileEntity = this.world.getTileEntity(new BlockPosition(a, b, c));
|
|
+ if (tileEntity instanceof TileEntityHopper) {
|
|
+ ((TileEntityHopper) tileEntity).ensureUpdates();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ super.t_();
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
public void a(DamageSource damagesource) {
|
|
super.a(damagesource);
|
|
if (this.world.getGameRules().getBoolean("doEntityDrops")) {
|
|
diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityOcelot.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityOcelot.java
|
|
@@ -0,0 +0,0 @@ public class EntityOcelot extends EntityTameableAnimal {
|
|
this.datawatcher.a(18, Byte.valueOf((byte) 0));
|
|
}
|
|
|
|
+ // Spigot start - We use K, the method called in World.class on each entity each tick
|
|
+ // PAIL: Rename
|
|
+ @Override
|
|
+ public void K() {
|
|
+ int xi = MathHelper.floor(this.getBoundingBox().a);
|
|
+ int yi = MathHelper.floor(this.getBoundingBox().b) - 1;
|
|
+ int zi = MathHelper.floor(this.getBoundingBox().c);
|
|
+ int xf = MathHelper.floor(this.getBoundingBox().d);
|
|
+ int yf = MathHelper.floor(this.getBoundingBox().e) - 1;
|
|
+ int zf = MathHelper.floor(this.getBoundingBox().f);
|
|
+ for (int a = xi; a <= xf; a++) {
|
|
+ for (int c = zi; c <= zf; c++) {
|
|
+ for (int b = yi; b <= yf; b++) {
|
|
+ TileEntity.updateChestAndHoppers(this.world, new BlockPosition(a, b, c));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ super.K();
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
public void E() {
|
|
if (this.getControllerMove().a()) {
|
|
double d0 = this.getControllerMove().b();
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntity.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntity.java
|
|
@@ -0,0 +0,0 @@ public abstract class TileEntity {
|
|
private int h;
|
|
protected Block e;
|
|
|
|
+ // Spigot start
|
|
+ // Helper method for scheduleTicks. If the hopper at blockposition is pointed
|
|
+ // toward this tile, then make the hopper active
|
|
+ private void scheduleTick(BlockPosition blockposition) {
|
|
+ TileEntity tileEntity = this.world.getTileEntity(blockposition);
|
|
+ if (tileEntity instanceof TileEntityHopper) {
|
|
+ // i is the metadeta assoiated with the direction the hopper faces.
|
|
+ EnumDirection dir = BlockHopper.b(tileEntity.u());
|
|
+
|
|
+ // Facing class provides arrays for direction offset.
|
|
+ if (tileEntity.position.shift(dir).equals(position)) {
|
|
+ ((TileEntityHopper) tileEntity).ensureUpdates();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Called from update when the contents have changed, so hoppers need updates.
|
|
+ // Check all 6 faces.
|
|
+ public void scheduleTicks() {
|
|
+ if (this.world != null) {
|
|
+ // Check the top
|
|
+ this.scheduleTick(position.up());
|
|
+ // Check the sides
|
|
+ for (int i = 2; i < 6; i++) {
|
|
+ this.scheduleTick(position.shift(EnumDirection.fromType1(i)));
|
|
+ }
|
|
+ // Check the bottom.
|
|
+ TileEntity tileEntity = this.world.getTileEntity(position.down());
|
|
+ if (tileEntity instanceof TileEntityHopper && tileEntity.world != null) {
|
|
+ ((TileEntityHopper) tileEntity).ensureUpdates();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // If there is a chest at blockposition, then update hoppers around it
|
|
+ // as well as around its other half (if it exists)
|
|
+ public static void updateChestAndHoppers(World world, BlockPosition blockposition) {
|
|
+ Block block = world.getType(blockposition).getBlock();
|
|
+ if (block instanceof BlockChest) {
|
|
+ TileEntity tile = world.getTileEntity(blockposition);
|
|
+ if (tile instanceof TileEntityChest) {
|
|
+ tile.scheduleTicks();
|
|
+ }
|
|
+ for (int i = 2; i < 6; i++) {
|
|
+ // Look for a matching chest at each face
|
|
+ BlockPosition pos = blockposition.shift(EnumDirection.fromType1(i));
|
|
+ if (world.getType(pos).getBlock() == block) {
|
|
+ tile = world.getTileEntity(pos);
|
|
+ if (tile instanceof TileEntityChest) {
|
|
+ tile.scheduleTicks();
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
public TileEntity() {
|
|
this.position = BlockPosition.ZERO;
|
|
this.h = -1;
|
|
@@ -0,0 +0,0 @@ public abstract class TileEntity {
|
|
if (this.w() != Blocks.AIR) {
|
|
this.world.updateAdjacentComparators(this.position, this.w());
|
|
}
|
|
+ // Spigot start - Called when the contents have changed, so hoppers around this
|
|
+ // tile need updating.
|
|
+ this.scheduleTicks();
|
|
+ // Spigot end
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
|
|
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
|
|
private String f;
|
|
private int g = -1;
|
|
|
|
+ // Spigot start
|
|
+
|
|
+ // Whether it has been determined that this hopper should update
|
|
+ private boolean active = true;
|
|
+
|
|
+ // Called by redstone updates, inventory changes, etc. to ensure this
|
|
+ // hopper updates
|
|
+ public void ensureUpdates() {
|
|
+ active = true;
|
|
+ }
|
|
+ // Spigot end
|
|
+
|
|
// CraftBukkit start - add fields and methods
|
|
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
|
private int maxStack = MAX_STACK;
|
|
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
|
|
|
|
public void update() {
|
|
super.update();
|
|
+ ensureUpdates(); // Spigot - Contents have changed, so make this hopper active
|
|
}
|
|
|
|
public int getSize() {
|
|
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
|
|
|
|
public boolean m() {
|
|
if (this.world != null && !this.world.isClientSide) {
|
|
+ // Spigot start
|
|
+
|
|
+ // if it has not been determined that this hopper should update,
|
|
+ // then don't waste time doing it
|
|
+ if (!active)
|
|
+ return false;
|
|
+
|
|
+ // set it up for the next time this method is called
|
|
+ active = false;
|
|
+ // Spigot end
|
|
if (!this.n() && BlockHopper.f(this.u())) {
|
|
boolean flag = false;
|
|
|
|
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityContainer implements IHopper, IU
|
|
|
|
public void d(int i) {
|
|
this.g = i;
|
|
+ this.ensureUpdates(); // Spigot
|
|
}
|
|
|
|
public boolean n() {
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess {
|
|
// Modularize client and physic updates
|
|
notifyAndUpdatePhysics(blockposition, chunk, block1, block, i);
|
|
}
|
|
+ // Spigot start - If this block is changing to that which a chest beneath it
|
|
+ // becomes able to be opened, then the chest must be updated.
|
|
+ // block1 is the old block. block is the new block. r returns true if the block type
|
|
+ // prevents access to a chest.
|
|
+ if (block1 != null && block1.isOccluding() && !block.isOccluding()) {
|
|
+ TileEntity.updateChestAndHoppers(this, blockposition.down());
|
|
+ }
|
|
+ // Spigot end
|
|
// CraftBukkit end
|
|
|
|
return true;
|
|
--
|