package erogenousbeef.bigreactors.utils; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.transport.IPipeTile; import cofh.api.transport.IItemDuct; import erogenousbeef.bigreactors.utils.intermod.ModHelperBase; /** * Wraps a given direction's inventory exposure. Listen for block/tile changes and set * whatever tile entity you find in that direction as this object's * tracked tile entity. * * You can then use distribute() to safely try to distribute items. * @author Erogenous Beef */ public class AdjacentInventoryHelper { private ForgeDirection dir; private TileEntity entity; private IItemDuct duct; private IPipeTile pipe; private InventoryHelper inv; /** * @param dir The direction away from the current tile entity which this wrapper represents. */ public AdjacentInventoryHelper(ForgeDirection dir) { this.dir = dir; entity = null; duct = null; pipe = null; inv = null; } /** * Attempt to distribute an item to a cached inventory connection * which is wrapped by this object. * @param itemToDistribute An itemstack to distribute. * @return An itemstack containing the remaining items, or null if all items were distributed. */ public ItemStack distribute(ItemStack itemToDistribute) { if(entity == null || itemToDistribute == null) { return itemToDistribute; } if(!hasConnection()) { return itemToDistribute; } if(ModHelperBase.useCofh && duct != null) { itemToDistribute = duct.insertItem(dir.getOpposite(), itemToDistribute); } else if(ModHelperBase.useBuildcraftTransport && pipe != null) { if(pipe.isPipeConnected(dir.getOpposite())) { itemToDistribute.stackSize -= pipe.injectItem(itemToDistribute.copy(), true, dir.getOpposite()); if(itemToDistribute.stackSize <= 0) { itemToDistribute = null; } } } else if(inv != null) { itemToDistribute = inv.addItem(itemToDistribute); } return itemToDistribute; } public boolean hasConnection() { return inv != null || pipe != null || duct != null; } /** * @param te The new tile entity for this helper to cache. * @return True if this helper's wrapped inventory changed, false otherwise. */ public boolean set(TileEntity te) { if(entity == te) { return false; } if(te == null) { duct = null; pipe = null; inv = null; } else if(ModHelperBase.useCofh && te instanceof IItemDuct) { setDuct((IItemDuct)te); } else if(ModHelperBase.useBuildcraftTransport && te instanceof IPipeTile) { setPipe((IPipeTile)te); } else if(te instanceof IInventory) { setInv(te); } entity = te; return true; } private void setDuct(IItemDuct duct) { this.duct = duct; this.pipe = null; this.inv = null; } private void setPipe(IPipeTile pipe) { this.pipe = pipe; this.duct = null; this.inv = null; } private void setInv(TileEntity te) { this.pipe = null; this.duct = null; this.inv = null; if(te instanceof ISidedInventory) { this.inv = new SidedInventoryHelper((ISidedInventory)te, dir.getOpposite()); } else { IInventory inv = (IInventory)te; World world = te.getWorldObj(); if(world.getBlock(te.xCoord, te.yCoord, te.zCoord) == Blocks.chest) { inv = StaticUtils.Inventory.checkForDoubleChest(world, inv, te.xCoord, te.yCoord, te.zCoord); } this.inv = new InventoryHelper(inv); } } }