From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Fri, 26 Jun 2020 01:11:47 +0200 Subject: [PATCH] Optimize Hopper logic diff --git a/src/main/java/net/minecraft/server/BlockHopper.java b/src/main/java/net/minecraft/server/BlockHopper.java index a29294fbc7cd6fcfff0df9eadd11de3bd7f1405e..2f66740de68667e5c0054a0bc7990256163087cd 100644 --- a/src/main/java/net/minecraft/server/BlockHopper.java +++ b/src/main/java/net/minecraft/server/BlockHopper.java @@ -110,6 +110,12 @@ public class BlockHopper extends BlockTileEntity { @Override public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { this.a(world, blockposition, iblockdata); + // Yatopia start + TileEntity tileEntity = world.getTileEntity(blockposition); + if (tileEntity instanceof TileEntityHopper) { + ((TileEntityHopper) tileEntity).flushCaches(); + } + // Yatopia end } private void a(World world, BlockPosition blockposition, IBlockData iblockdata) { diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java index 95bede605c6401af10f18b641cd12c9d8ec2f207..0a975642ce0cce4cbce02e9be976427ed42cce65 100644 --- a/src/main/java/net/minecraft/server/TileEntityHopper.java +++ b/src/main/java/net/minecraft/server/TileEntityHopper.java @@ -661,14 +661,93 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi @Nullable private IInventory l() { + // Yatopia start + if (!shouldNotCachePush && cachedPush != null) { + return cachedPush; + } + // Yatopia end EnumDirection enumdirection = (EnumDirection) this.getBlock().get(BlockHopper.FACING); - return b(this.getWorld(), this.position.shift(enumdirection)); + // Yatopia start - replace logic + //return b(this.getWorld(), this.position.shift(enumdirection)); + // basically reimplement TileEntityHopper#b but in a better way in order to + // not make them composters bork + if (shouldNotCachePush || !cachedPushAir) { + BlockPosition shifted = this.position.shift(enumdirection); + BlockPosition checkedPosition = new BlockPosition(shifted.getX() + 0.5D, shifted.getY() + 0.5D, shifted.getZ() + 0.5D); + if (!world.isLoaded(checkedPosition)) return null; + IBlockData blockData = world.getType(checkedPosition); + Block block = blockData.getBlock(); + if (block instanceof IInventoryHolder) { + this.cachedPush = ((IInventoryHolder) block).a(blockData, world, checkedPosition); + shouldNotCachePush = true; + } else if (block.isTileEntity()) { + TileEntity tileEntity = world.getTileEntity(checkedPosition); + if (tileEntity instanceof IInventory) { + IInventory inv = (IInventory) tileEntity; + if (inv instanceof TileEntityChest && block instanceof BlockChest) { + inv = BlockChest.getInventory((BlockChest) block, blockData, world, checkedPosition, true); + } + if (inv instanceof EntityMinecartContainer) { + shouldNotCachePush = true; + } + this.cachedPush = inv; + } + } + } + if (this.cachedPush == null) { + this.cachedPushAir = true; + } + return this.cachedPush; + // Yatopia end } @Nullable public static IInventory b(IHopper ihopper) { + // Yatopia start - replaced logic + if (ihopper instanceof TileEntityHopper) { + TileEntityHopper hopper = (TileEntityHopper) ihopper; + if (!hopper.shouldNotCachePull && hopper.cachedAbove != null) { + return hopper.cachedAbove; + } + // reimplement here too cuz minecarts + BlockPosition pos = new BlockPosition(ihopper.getX(), ihopper.getY() + 1.0D, ihopper.getZ()); + if (hopper.shouldNotCachePull || hopper.cachedPullAir) { + if (hopper.world.isLoaded(pos)) return null; + IBlockData blockData = hopper.world.getType(pos); + Block block = blockData.getBlock(); + if (block instanceof IInventoryHolder) { + hopper.cachedAbove = ((IInventoryHolder) block).a(blockData, hopper.world, pos); + hopper.shouldNotCachePull = true; + } else if (block.isTileEntity()) { + TileEntity tileEntity = hopper.world.getTileEntity(pos); + if (tileEntity instanceof IInventory) { + IInventory inv = (IInventory) tileEntity; + if (inv instanceof TileEntityChest && block instanceof BlockChest) { + inv = BlockChest.getInventory((BlockChest) block, blockData, hopper.world, pos, true); + } + if (inv instanceof EntityMinecartContainer) { + hopper.shouldNotCachePull = true; + } + hopper.cachedAbove = inv; + } + } + } + if (hopper.cachedAbove == null) { + List list = hopper.world.getEntities((Entity) null, new AxisAlignedBB(pos.getX() - 0.5D, pos.getY() - 0.5D, pos.getZ() - 0.5D, pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D), IEntitySelector.d); + + if (!list.isEmpty()) { + hopper.cachedAbove = (IInventory) list.get(java.util.concurrent.ThreadLocalRandom.current().nextInt(list.size())); + } + } + if (hopper.cachedAbove == null) { + hopper.cachedPullAir = true; + } + return hopper.cachedAbove; + } else { return a(ihopper.getWorld(), ihopper.x(), ihopper.z() + 1.0D, ihopper.A()); + } + // Yatopia end } public static List c(IHopper ihopper) { @@ -779,4 +858,21 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi protected Container createContainer(int i, PlayerInventory playerinventory) { return new ContainerHopper(i, playerinventory, this); } + + // Yatopia start + private IInventory cachedAbove = null; + private IInventory cachedPush = null; + private boolean cachedPushAir = false; + private boolean cachedPullAir = false; + private boolean shouldNotCachePush = false; + private boolean shouldNotCachePull = false; + public void flushCaches() { + cachedAbove = null; + cachedPush = null; + cachedPushAir = false; + cachedPullAir = false; + shouldNotCachePush = false; + shouldNotCachePull = false; + } + // Yatopia end }