2016-06-23 03:49:47 +00:00
|
|
|
/*
|
|
|
|
* Minecraft Forge
|
|
|
|
* Copyright (c) 2016.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation version 2.1
|
|
|
|
* of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2016-01-17 16:41:34 +00:00
|
|
|
package net.minecraftforge.items;
|
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
import net.minecraft.block.Block;
|
2016-01-17 16:41:34 +00:00
|
|
|
import net.minecraft.block.BlockDropper;
|
|
|
|
import net.minecraft.block.BlockHopper;
|
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
|
import net.minecraft.tileentity.IHopper;
|
|
|
|
import net.minecraft.tileentity.TileEntity;
|
|
|
|
import net.minecraft.tileentity.TileEntityDispenser;
|
|
|
|
import net.minecraft.tileentity.TileEntityHopper;
|
|
|
|
import net.minecraft.util.EnumFacing;
|
2016-11-23 20:45:07 +00:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
|
|
|
import net.minecraft.util.math.MathHelper;
|
2016-01-17 16:41:34 +00:00
|
|
|
import net.minecraft.world.World;
|
2016-11-25 04:15:32 +00:00
|
|
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-13 22:09:54 +00:00
|
|
|
import javax.annotation.Nonnull;
|
2016-11-23 20:45:07 +00:00
|
|
|
import javax.annotation.Nullable;
|
2016-11-13 22:09:54 +00:00
|
|
|
|
2016-01-17 16:41:34 +00:00
|
|
|
public class VanillaInventoryCodeHooks
|
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
/**
|
|
|
|
* Copied from TileEntityHopper#captureDroppedItems and added capability support
|
|
|
|
* @return Null if we did nothing {no IItemHandler}, True if we moved an item, False if we moved no items
|
|
|
|
*/
|
2016-07-03 20:45:26 +00:00
|
|
|
public static Boolean extractHook(IHopper dest)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
Pair<IItemHandler, Object> itemHandlerResult = getItemHandler(dest, EnumFacing.UP);
|
|
|
|
if (itemHandlerResult == null)
|
2016-07-03 20:45:26 +00:00
|
|
|
return null;
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
IItemHandler handler = itemHandlerResult.getKey();
|
2016-01-17 16:41:34 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < handler.getSlots(); i++)
|
|
|
|
{
|
|
|
|
ItemStack extractItem = handler.extractItem(i, 1, true);
|
2016-11-18 21:24:03 +00:00
|
|
|
if (!extractItem.func_190926_b())
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
|
|
|
for (int j = 0; j < dest.getSizeInventory(); j++)
|
|
|
|
{
|
|
|
|
ItemStack destStack = dest.getStackInSlot(j);
|
2016-12-05 20:06:16 +00:00
|
|
|
if (dest.isItemValidForSlot(j, extractItem) && (destStack.func_190926_b() || destStack.func_190916_E() < destStack.getMaxStackSize() && destStack.func_190916_E() < dest.getInventoryStackLimit() && ItemHandlerHelper.canItemStacksStack(extractItem, destStack)))
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
|
|
|
extractItem = handler.extractItem(i, 1, false);
|
2016-11-18 21:24:03 +00:00
|
|
|
if (destStack.func_190926_b())
|
2016-01-17 16:41:34 +00:00
|
|
|
dest.setInventorySlotContents(j, extractItem);
|
|
|
|
else
|
|
|
|
{
|
2016-11-13 22:09:54 +00:00
|
|
|
destStack.func_190917_f(1);
|
2016-01-17 16:41:34 +00:00
|
|
|
dest.setInventorySlotContents(j, destStack);
|
|
|
|
}
|
|
|
|
dest.markDirty();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-03 20:45:26 +00:00
|
|
|
return false;
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
/**
|
|
|
|
* Copied from BlockDropper#dispense and added capability support
|
|
|
|
*/
|
2016-11-13 22:09:54 +00:00
|
|
|
public static boolean dropperInsertHook(World world, BlockPos pos, TileEntityDispenser dropper, int slot, @Nonnull ItemStack stack)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
|
|
|
EnumFacing enumfacing = world.getBlockState(pos).getValue(BlockDropper.FACING);
|
2016-11-23 20:45:07 +00:00
|
|
|
BlockPos blockpos = pos.offset(enumfacing);
|
|
|
|
Pair<IItemHandler, Object> destinationResult = getItemHandler(world, (double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ(), enumfacing.getOpposite());
|
|
|
|
if (destinationResult == null)
|
|
|
|
{
|
2016-01-17 16:41:34 +00:00
|
|
|
return true;
|
2016-11-23 20:45:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IItemHandler itemHandler = destinationResult.getKey();
|
|
|
|
Object destination = destinationResult.getValue();
|
|
|
|
ItemStack dispensedStack = stack.copy().splitStack(1);
|
|
|
|
ItemStack remainder = putStackInInventoryAllSlots(dropper, destination, itemHandler, dispensedStack);
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
if (remainder.func_190926_b())
|
|
|
|
{
|
|
|
|
remainder = stack.copy();
|
|
|
|
remainder.func_190918_g(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
remainder = stack.copy();
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
dropper.setInventorySlotContents(slot, remainder);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
/**
|
|
|
|
* Copied from TileEntityHopper#transferItemsOut and added capability support
|
|
|
|
*/
|
|
|
|
public static boolean insertHook(TileEntityHopper hopper)
|
|
|
|
{
|
|
|
|
EnumFacing hopperFacing = BlockHopper.getFacing(hopper.getBlockMetadata());
|
|
|
|
Pair<IItemHandler, Object> destinationResult = getItemHandler(hopper, hopperFacing);
|
|
|
|
if (destinationResult == null)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
return false;
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
IItemHandler itemHandler = destinationResult.getKey();
|
|
|
|
Object destination = destinationResult.getValue();
|
|
|
|
if (isFull(itemHandler))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < hopper.getSizeInventory(); ++i)
|
|
|
|
{
|
|
|
|
if (!hopper.getStackInSlot(i).func_190926_b())
|
|
|
|
{
|
|
|
|
ItemStack originalSlotContents = hopper.getStackInSlot(i).copy();
|
|
|
|
ItemStack insertStack = hopper.decrStackSize(i, 1);
|
|
|
|
ItemStack remainder = putStackInInventoryAllSlots(hopper, destination, itemHandler, insertStack);
|
|
|
|
|
|
|
|
if (remainder.func_190926_b())
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
hopper.setInventorySlotContents(i, originalSlotContents);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
private static ItemStack putStackInInventoryAllSlots(TileEntity source, Object destination, IItemHandler destInventory, ItemStack stack)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
for (int slot = 0; slot < destInventory.getSlots() && !stack.func_190926_b(); slot++)
|
|
|
|
{
|
|
|
|
stack = insertStack(source, destination, destInventory, stack, slot);
|
|
|
|
}
|
|
|
|
return stack;
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
/**
|
|
|
|
* Copied from TileEntityHopper#insertStack and added capability support
|
|
|
|
*/
|
|
|
|
private static ItemStack insertStack(TileEntity source, Object destination, IItemHandler destInventory, ItemStack stack, int slot)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
ItemStack itemstack = destInventory.getStackInSlot(slot);
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
if (destInventory.insertItem(slot, stack, true).func_190926_b())
|
|
|
|
{
|
|
|
|
boolean insertedItem = false;
|
|
|
|
boolean inventoryWasEmpty = isEmpty(destInventory);
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
if (itemstack.func_190926_b())
|
|
|
|
{
|
|
|
|
destInventory.insertItem(slot, stack, false);
|
|
|
|
stack = ItemStack.field_190927_a;
|
|
|
|
insertedItem = true;
|
|
|
|
}
|
|
|
|
else if (ItemHandlerHelper.canItemStacksStack(itemstack, stack))
|
|
|
|
{
|
|
|
|
int originalSize = stack.func_190916_E();
|
|
|
|
stack = destInventory.insertItem(slot, stack, false);
|
|
|
|
insertedItem = originalSize < stack.func_190916_E();
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
if (insertedItem)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
if (inventoryWasEmpty && destination instanceof TileEntityHopper)
|
2016-01-17 16:41:34 +00:00
|
|
|
{
|
2016-11-23 20:45:07 +00:00
|
|
|
TileEntityHopper destinationHopper = (TileEntityHopper)destination;
|
|
|
|
|
|
|
|
if (!destinationHopper.mayTransfer())
|
|
|
|
{
|
|
|
|
int k = 0;
|
|
|
|
|
|
|
|
if (source instanceof TileEntityHopper)
|
|
|
|
{
|
|
|
|
if (destinationHopper.getLastUpdateTime() >= ((TileEntityHopper) source).getLastUpdateTime())
|
|
|
|
{
|
|
|
|
k = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
destinationHopper.setTransferCooldown(8 - k);
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-23 20:45:07 +00:00
|
|
|
return stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
private static Pair<IItemHandler, Object> getItemHandler(IHopper hopper, EnumFacing hopperFacing)
|
|
|
|
{
|
|
|
|
double x = hopper.getXPos() + (double) hopperFacing.getFrontOffsetX();
|
|
|
|
double y = hopper.getYPos() + (double) hopperFacing.getFrontOffsetY();
|
|
|
|
double z = hopper.getZPos() + (double) hopperFacing.getFrontOffsetZ();
|
|
|
|
return getItemHandler(hopper.getWorld(), x, y, z, hopperFacing.getOpposite());
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean isFull(IItemHandler itemHandler)
|
|
|
|
{
|
|
|
|
for (int slot = 0; slot < itemHandler.getSlots(); slot++)
|
|
|
|
{
|
|
|
|
ItemStack stackInSlot = itemHandler.getStackInSlot(slot);
|
|
|
|
if (stackInSlot.func_190926_b() || stackInSlot.func_190916_E() != stackInSlot.getMaxStackSize())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
return true;
|
|
|
|
}
|
2016-11-23 20:45:07 +00:00
|
|
|
|
|
|
|
private static boolean isEmpty(IItemHandler itemHandler)
|
|
|
|
{
|
|
|
|
for (int slot = 0; slot < itemHandler.getSlots(); slot++)
|
|
|
|
{
|
|
|
|
ItemStack stackInSlot = itemHandler.getStackInSlot(slot);
|
|
|
|
if (stackInSlot.func_190916_E() > 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public static Pair<IItemHandler, Object> getItemHandler(World worldIn, double x, double y, double z, final EnumFacing side)
|
|
|
|
{
|
|
|
|
Pair<IItemHandler, Object> destination = null;
|
|
|
|
int i = MathHelper.floor_double(x);
|
|
|
|
int j = MathHelper.floor_double(y);
|
|
|
|
int k = MathHelper.floor_double(z);
|
|
|
|
BlockPos blockpos = new BlockPos(i, j, k);
|
|
|
|
net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos);
|
|
|
|
Block block = state.getBlock();
|
|
|
|
|
|
|
|
if (block.hasTileEntity(state))
|
|
|
|
{
|
|
|
|
TileEntity tileentity = worldIn.getTileEntity(blockpos);
|
|
|
|
if (tileentity != null)
|
|
|
|
{
|
|
|
|
if (tileentity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side))
|
|
|
|
{
|
|
|
|
IItemHandler capability = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
|
2016-11-25 04:15:32 +00:00
|
|
|
destination = ImmutablePair.<IItemHandler, Object>of(capability, tileentity);
|
2016-11-23 20:45:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return destination;
|
|
|
|
}
|
2016-01-17 16:41:34 +00:00
|
|
|
}
|