All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minecraft.server.TileEntityHopper Maven / Gradle / Ivy

package net.minecraft.server;

import org.bukkit.craftbukkit.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.Inventory;
import walkmc.WalkConfig;

import java.util.Arrays;
import java.util.List;
// CraftBukkit end

public class TileEntityHopper extends TileEntityContainer implements IHopper, IUpdatePlayerListBox {
	
	public final static boolean HOPPERS_DISABLED = WalkConfig.INSTANCE.getData().getPerformance().getHoppersDisabled(); // walkmc
	
	// CraftBukkit start - add fields and methods
	public List transaction = new java.util.ArrayList<>();
	private ItemStack[] items = new ItemStack[5];
	private String f;
	private int g = -1;
	private int maxStack = MAX_STACK;
	
	public TileEntityHopper() {
	}
	
	private static boolean b(IInventory iinventory, EnumDirection enumdirection) {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		if (iinventory instanceof IWorldInventory) {
			IWorldInventory iworldinventory = (IWorldInventory) iinventory;
			final int[] aint = iworldinventory.getSlotsForFace(enumdirection);
			
			for (int j : aint) {
				if (iworldinventory.getItem(j) != null) {
					return false;
				}
			}
		} else {
			final int j = iinventory.getSize();
			
			for (int k = 0; k < j; ++k) {
				if (iinventory.getItem(k) != null) {
					return false;
				}
			}
		}
		
		return true;
	}
	
	public static boolean a(IHopper ihopper) {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		final IInventory iinventory = b(ihopper);
		
		if (iinventory != null) {
			final EnumDirection enumdirection = EnumDirection.DOWN;
			
			if (b(iinventory, enumdirection)) {
				return false;
			}
			
			if (iinventory instanceof IWorldInventory) {
				final IWorldInventory iworldinventory = (IWorldInventory) iinventory;
				final int[] aint = iworldinventory.getSlotsForFace(enumdirection);
				
				for (final int j : aint) {
					if (a(ihopper, iinventory, j, enumdirection)) {
						return true;
					}
				}
			} else {
				final int j = iinventory.getSize();
				
				for (int k = 0; k < j; ++k) {
					if (a(ihopper, iinventory, k, enumdirection)) {
						return true;
					}
				}
			}
		} else {
			
			for (final EntityItem entityitem : a(ihopper.getWorld(), ihopper.A(), ihopper.B() + 1.0D, ihopper.C())) {
				if (a(ihopper, entityitem)) {
					return true;
				}
			}
		}
		
		return false;
	}
	
	private static boolean a(IHopper hopper, IInventory inv, int i, EnumDirection direction) {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		final ItemStack itemstack = inv.getItem(i);
		
		if (itemstack != null && b(inv, itemstack, i, direction)) {
			final ItemStack itemstack1 = itemstack.cloneItemStack();
			// ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null);
			// CraftBukkit start - Call event on collection of items from inventories into the hopper
			final CraftItemStack oitemstack = CraftItemStack.asCraftMirror(inv.splitStack(i, hopper.getWorld().spigotConfig.hopperAmount)); // Spigot
			
			final Inventory sourceInventory;
			// Have to special case large chests as they work oddly
			if (inv instanceof InventoryLargeChest) {
				sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) inv);
			} else {
				sourceInventory = inv.getOwner().getInventory();
			}
			
			final InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), hopper.getOwner().getInventory(), false);
			
			hopper.getWorld().getServer().getPluginManager().callEvent(event);
			if (event.isCancelled()) {
				inv.setItem(i, itemstack1);
				
				if (hopper instanceof TileEntityHopper) {
					((TileEntityHopper) hopper).d(hopper.getWorld().spigotConfig.hopperTransfer); // Spigot
				} else if (hopper instanceof EntityMinecartHopper) {
					((EntityMinecartHopper) hopper).m(hopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot
				}
				return false;
			}
			
			final int origCount = event.getItem().getAmount(); // Spigot
			final ItemStack itemstack2 = addItem(hopper, CraftItemStack.asNMSCopy(event.getItem()), null);
			
			if (itemstack2 == null || itemstack2.count == 0) {
				if (event.getItem().equals(oitemstack)) {
					inv.update();
				} else {
					inv.setItem(i, itemstack1);
				}
				// CraftBukkit end
				return true;
			}
			
			itemstack1.count -= origCount - itemstack2.count; // Spigot
			
			inv.setItem(i, itemstack1);
		}
		
		return false;
	}
	
	public static boolean a(IInventory iinventory, EntityItem entityitem) {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		boolean flag = false;
		
		if (entityitem == null) {
			return false;
		} else {
			
			// CraftBukkit start
			final InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
			entityitem.world.getServer().getPluginManager().callEvent(event);
			
			if (event.isCancelled())
				return false;
			// CraftBukkit end
			
			final ItemStack itemstack = entityitem.getItemStack().cloneItemStack();
			final ItemStack itemstack1 = addItem(iinventory, itemstack, null);
			
			if (itemstack1 != null && itemstack1.count != 0) {
				entityitem.setItemStack(itemstack1);
			} else {
				flag = true;
				entityitem.die();
			}
			
			return flag;
		}
	}
	// CraftBukkit end
	
	public static ItemStack addItem(IInventory iinventory, ItemStack itemstack, EnumDirection enumdirection) {
		if (iinventory instanceof IWorldInventory && enumdirection != null) {
			final IWorldInventory iworldinventory = (IWorldInventory) iinventory;
			final int[] aint = iworldinventory.getSlotsForFace(enumdirection);
			
			for (int i = 0; i < aint.length && itemstack != null && itemstack.count > 0; ++i) {
				itemstack = c(iinventory, itemstack, aint[i], enumdirection);
			}
		} else {
			final int j = iinventory.getSize();
			
			for (int k = 0; k < j && itemstack != null && itemstack.count > 0; ++k) {
				itemstack = c(iinventory, itemstack, k, enumdirection);
			}
		}
		
		if (itemstack != null && itemstack.count == 0) {
			itemstack = null;
		}
		
		return itemstack;
	}
	
	private static boolean a(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) {
		return iinventory.b(i, itemstack) && (!(iinventory instanceof IWorldInventory) || ((IWorldInventory) iinventory).canPlaceItemThroughFace(i, itemstack, enumdirection));
	}
	
	private static boolean b(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) {
		return !(iinventory instanceof IWorldInventory) || ((IWorldInventory) iinventory).canTakeItemThroughFace(i, itemstack, enumdirection);
	}
	
	private static ItemStack c(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) {
		if (HOPPERS_DISABLED) // walkmc
			return null;
		
		final ItemStack itemstack1 = iinventory.getItem(i);
		
		if (a(iinventory, itemstack, i, enumdirection)) {
			boolean flag = false;
			
			if (itemstack1 == null) {
				iinventory.setItem(i, itemstack);
				itemstack = null;
				flag = true;
			} else if (a(itemstack1, itemstack)) {
				int j = itemstack.getMaxStackSize() - itemstack1.count;
				int k = Math.min(itemstack.count, j);
				
				itemstack.count -= k;
				itemstack1.count += k;
				flag = k > 0;
			}
			
			if (flag) {
				if (iinventory instanceof TileEntityHopper) {
					final TileEntityHopper hopper = (TileEntityHopper) iinventory;
					
					if (hopper.o()) {
						hopper.d(hopper.world.spigotConfig.hopperTransfer); // Spigot
					}
					
					iinventory.update();
				}
				
				iinventory.update();
			}
		}
		
		return itemstack;
	}
	
	public static IInventory b(IHopper ihopper) {
		return b(ihopper.getWorld(), ihopper.A(), ihopper.B() + 1.0D, ihopper.C());
	}
	
	public static List a(World world, double d0, double d1, double d2) {
		return world.a(EntityItem.class, new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), IEntitySelector.a);
	}
	
	public static IInventory b(World world, double d0, double d1, double d2) {
		Object object = null;
		
		final BlockPosition blockposition = new BlockPosition(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
		
		if (!world.isLoaded(blockposition))
			return null; // Spigot
		
		final Block block = world.getType(blockposition).getBlock();
		
		if (block.isTileEntity()) {
			TileEntity tileentity = world.getTileEntity(blockposition);
			
			if (tileentity instanceof IInventory) {
				object = tileentity;
				if (object instanceof TileEntityChest && block instanceof BlockChest) {
					object = ((BlockChest) block).f(world, blockposition);
				}
			}
		}
		
		if (object == null) {
			List list = world.getEntities(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.size() > 0) {
				object = list.get(world.random.nextInt(list.size()));
			}
		}
		
		return (IInventory) object;
	}
	
	private static boolean a(ItemStack itemstack, ItemStack itemstack1) {
		return itemstack.getItem() == itemstack1.getItem() && (itemstack.getData() == itemstack1.getData() && (itemstack.count <= itemstack.getMaxStackSize() && ItemStack.equals(itemstack, itemstack1)));
	}
	
	public ItemStack[] getContents() {
		return this.items;
	}
	
	public void onOpen(CraftHumanEntity who) {
		transaction.add(who);
	}
	
	public void onClose(CraftHumanEntity who) {
		transaction.remove(who);
	}
	
	public List getViewers() {
		return transaction;
	}
	
	public void a(NBTTagCompound nbttagcompound) {
		super.a(nbttagcompound);
		NBTTagList nbttaglist = nbttagcompound.getList("Items", 10);
		
		this.items = new ItemStack[this.getSize()];
		if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
			this.f = nbttagcompound.getString("CustomName");
		}
		
		this.g = nbttagcompound.getInt("TransferCooldown");
		
		for (int i = 0; i < nbttaglist.size(); ++i) {
			NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
			byte b0 = nbttagcompound1.getByte("Slot");
			
			if (b0 >= 0 && b0 < this.items.length) {
				this.items[b0] = ItemStack.createStack(nbttagcompound1);
			}
		}
		
	}
	
	public void b(NBTTagCompound nbttagcompound) {
		super.b(nbttagcompound);
		NBTTagList nbttaglist = new NBTTagList();
		
		for (int i = 0; i < this.items.length; ++i) {
			if (this.items[i] != null) {
				NBTTagCompound nbttagcompound1 = new NBTTagCompound();
				
				nbttagcompound1.setByte("Slot", (byte) i);
				this.items[i].writeToNBT(nbttagcompound1);
				nbttaglist.add(nbttagcompound1);
			}
		}
		
		nbttagcompound.set("Items", nbttaglist);
		nbttagcompound.setInt("TransferCooldown", this.g);
		if (this.hasCustomName()) {
			nbttagcompound.setString("CustomName", this.f);
		}
		
	}
	
	public void update() {
		super.update();
	}
	
	public int getSize() {
		return this.items.length;
	}
	
	public ItemStack getItem(int i) {
		return this.items[i];
	}
	
	public ItemStack splitStack(int i, int j) {
		if (this.items[i] != null) {
			ItemStack itemstack;
			
			if (this.items[i].count <= j) {
				itemstack = this.items[i];
				this.items[i] = null;
			} else {
				itemstack = this.items[i].cloneAndSubtract(j);
				if (this.items[i].count == 0) {
					this.items[i] = null;
				}
				
			}
			return itemstack;
		} else {
			return null;
		}
	}
	
	public ItemStack splitWithoutUpdate(int i) {
		if (this.items[i] != null) {
			ItemStack itemstack = this.items[i];
			
			this.items[i] = null;
			return itemstack;
		} else {
			return null;
		}
	}
	
	public void setItem(int i, ItemStack itemstack) {
		this.items[i] = itemstack;
		if (itemstack != null && itemstack.count > this.getMaxStackSize()) {
			itemstack.count = this.getMaxStackSize();
		}
		
	}
	
	public String getName() {
		return this.hasCustomName() ? this.f : "container.hopper";
	}
	
	public boolean hasCustomName() {
		return this.f != null && this.f.length() > 0;
	}
	
	public void a(String s) {
		this.f = s;
	}
	
	public int getMaxStackSize() {
		return maxStack; // CraftBukkit
	}
	
	public void setMaxStackSize(int size) {
		maxStack = size;
	}
	
	public boolean a(EntityHuman entityhuman) {
		return this.world.getTileEntity(this.position) == this && entityhuman.getDistanceSquared((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D;
	}
	
	public void startOpen(EntityHuman entityhuman) {
	}
	
	public void closeContainer(EntityHuman entityhuman) {
	}
	
	public boolean b(int i, ItemStack itemstack) {
		return true;
	}
	
	public void c() {
		if (this.world != null && !this.world.isClientSide) {
			--this.g;
			if (!this.n()) {
				this.d(0);
				this.m();
			}
			
		}
	}
	
	public boolean m() {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		if (this.world != null && !this.world.isClientSide) {
			if (!this.n() && BlockHopper.f(this.u())) {
				boolean flag = false;
				
				if (!this.p()) {
					flag = this.r();
				}
				
				if (!this.q()) {
					flag = a(this) || flag;
				}
				
				if (flag) {
					this.d(world.spigotConfig.hopperTransfer); // Spigot
					this.update();
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean p() {
		ItemStack[] aitemstack = this.items;
		int i = aitemstack.length;
		
		for (ItemStack itemstack : aitemstack) {
			if (itemstack != null) {
				return false;
			}
		}
		
		return true;
	}
	
	private boolean q() {
		ItemStack[] aitemstack = this.items;
		int i = aitemstack.length;
		
		for (ItemStack itemstack : aitemstack) {
			if (itemstack == null || itemstack.count != itemstack.getMaxStackSize()) {
				return false;
			}
		}
		
		return true;
	}
	
	private boolean r() {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		final IInventory iinventory = this.H();
		
		if (iinventory != null) {
			final EnumDirection enumdirection = BlockHopper.b(this.u()).opposite();
			
			if (!this.a(iinventory, enumdirection)) {
				for (int i = 0; i < this.getSize(); ++i) {
					if (getItem(i) == null)
						continue;
					
					ItemStack item = this.getItem(i).cloneItemStack();
					
					// CraftBukkit start - Call event when pushing items into other inventories
					CraftItemStack craftItem = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot
					
					Inventory destinationInventory;
					// Have to special case large chests as they work oddly
					if (iinventory instanceof InventoryLargeChest) {
						destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory);
					} else {
						destinationInventory = iinventory.getOwner().getInventory();
					}
					
					// walkmc start
					
					
					InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), craftItem.clone(), destinationInventory, true);
					this.getWorld().getServer().getPluginManager().callEvent(event);
					
					if (event.isCancelled()) {
						this.setItem(i, item);
						this.d(world.spigotConfig.hopperTransfer); // Spigot
						return false;
					}
					
					
					int origCount = event.getItem().getAmount(); // Spigot
					ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
					
					if (itemstack1 == null || itemstack1.count == 0) {
						if (event.getItem().equals(craftItem)) {
							iinventory.update();
						} else {
							this.setItem(i, item);
						}
						// CraftBukkit end
						return true;
					}
					item.count -= origCount - itemstack1.count; // Spigot
					this.setItem(i, item);
				}
			}
		}
		return false;
	}
	
	private boolean a(IInventory iinventory, EnumDirection enumdirection) {
		if (HOPPERS_DISABLED) // walkmc
			return false;
		
		if (iinventory instanceof IWorldInventory) {
			IWorldInventory iworldinventory = (IWorldInventory) iinventory;
			int[] aint = iworldinventory.getSlotsForFace(enumdirection);
			
			for (int j : aint) {
				ItemStack itemstack = iworldinventory.getItem(j);
				
				if (itemstack == null || itemstack.count != itemstack.getMaxStackSize()) {
					return false;
				}
			}
		} else {
			int j = iinventory.getSize();
			
			for (int k = 0; k < j; ++k) {
				ItemStack itemstack1 = iinventory.getItem(k);
				
				if (itemstack1 == null || itemstack1.count != itemstack1.getMaxStackSize()) {
					return false;
				}
			}
		}
		
		return true;
	}
	
	private IInventory H() {
		EnumDirection enumdirection = BlockHopper.b(this.u());
		
		return b(this.getWorld(), this.position.getX() + enumdirection.getAdjacentX(), this.position.getY() + enumdirection.getAdjacentY(), this.position.getZ() + enumdirection.getAdjacentZ());
	}
	
	public double A() {
		return (double) this.position.getX() + 0.5D;
	}
	
	public double B() {
		return (double) this.position.getY() + 0.5D;
	}
	
	public double C() {
		return (double) this.position.getZ() + 0.5D;
	}
	
	public void d(int i) {
		this.g = i;
	}
	
	public boolean n() {
		return this.g > 0;
	}
	
	public boolean o() {
		return this.g <= 1;
	}
	
	public String getContainerName() {
		return "minecraft:hopper";
	}
	
	public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) {
		return new ContainerHopper(playerinventory, this, entityhuman);
	}
	
	public int getProperty(int i) {
		return 0;
	}
	
	public void b(int i, int j) {
	}
	
	public int g() {
		return 0;
	}
	
	public void l() {
		Arrays.fill(this.items, null);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy