1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-13 11:40:29 +00:00

Replace most inventory handling code with IItemHandlers

- Make InventoryUtil deal with item handlers instead. This
   significantly simplifies the implementation, the interface now
   does most of the hard work.
 - Add InvWrapper item handlers to printers, disk drives and turtles
 - Add IItemHandlerModifiable accessor to ITurtleAccess
 - Migrate all other inventory code (mostly turtle commands) to use
   item handlers instead.
This commit is contained in:
SquidDev 2017-05-09 00:41:20 +01:00
parent 25128dfb66
commit b07f28c30c
16 changed files with 230 additions and 243 deletions

View File

@ -15,6 +15,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -138,10 +139,22 @@ public interface ITurtleAccess
* Get the inventory of this turtle
*
* @return This turtle's inventory
* @see #getItemHandler()
*/
@Nonnull
IInventory getInventory();
/**
* Get the inventory of this turtle as an {@link IItemHandlerModifiable}.
*
* @return This turtle's inventory
* @see #getInventory()
* @see IItemHandlerModifiable
* @see net.minecraftforge.items.CapabilityItemHandler#ITEM_HANDLER_CAPABILITY
*/
@Nonnull
IItemHandlerModifiable getItemHandler();
/**
* Determine whether this turtle will require fuel when performing actions.
*

View File

@ -22,16 +22,27 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.text.*;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
public class TileDiskDrive extends TilePeripheralBase
implements IInventory, ITickable
{
@ -50,6 +61,7 @@ public class TileDiskDrive extends TilePeripheralBase
private final Map<IComputerAccess, MountInfo> m_computers;
private ItemStack m_diskStack;
private final IItemHandlerModifiable m_itemHandler = new InvWrapper( this );
private IMount m_diskMount;
private boolean m_recordQueued;
@ -681,4 +693,21 @@ public class TileDiskDrive extends TilePeripheralBase
{
ComputerCraft.playRecord( null, null, worldObj, getPos() );
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == ITEM_HANDLER_CAPABILITY || super.hasCapability( capability, facing );
}
@Nonnull
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == ITEM_HANDLER_CAPABILITY )
{
return ITEM_HANDLER_CAPABILITY.cast( m_itemHandler );
}
return super.getCapability( capability, facing );
}
}

View File

@ -23,13 +23,22 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.text.*;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
public class TilePrinter extends TilePeripheralBase
implements IInventory, ISidedInventory
@ -43,6 +52,9 @@ public class TilePrinter extends TilePeripheralBase
// Members
private final ItemStack[] m_inventory;
private final IItemHandlerModifiable m_itemHandlerAll = new InvWrapper( this );
private IItemHandlerModifiable[] m_itemHandlerSides;
private final Terminal m_page;
private String m_pageTitle;
private boolean m_printing;
@ -532,7 +544,7 @@ public class TilePrinter extends TilePeripheralBase
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
synchronized( m_inventory )
{
ItemStack remainder = InventoryUtil.storeItems( stack, this, 7, 6, 7 );
ItemStack remainder = InventoryUtil.storeItems( stack, m_itemHandlerAll, 7, 6, 7 );
if( remainder == null )
{
m_printing = false;
@ -596,4 +608,35 @@ public class TilePrinter extends TilePeripheralBase
setAnim( anim );
}
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == ITEM_HANDLER_CAPABILITY || super.hasCapability( capability, facing );
}
@Nonnull
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == ITEM_HANDLER_CAPABILITY )
{
if( facing == null )
{
return ITEM_HANDLER_CAPABILITY.cast( m_itemHandlerAll );
}
else
{
IItemHandlerModifiable[] handlers = m_itemHandlerSides;
if( handlers == null ) handlers = m_itemHandlerSides = new IItemHandlerModifiable[ 6 ];
int i = facing.ordinal();
IItemHandlerModifiable handler = handlers[ i ];
if( handler == null ) handler = handlers[ i ] = new SidedInvWrapper( this, facing );
return ITEM_HANDLER_CAPABILITY.cast( handler );
}
}
return super.getCapability( capability, facing );
}
}

View File

@ -18,6 +18,7 @@ import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import javax.annotation.Nonnull;
@ -100,7 +101,7 @@ public class PocketAPI implements ILuaAPI
ItemStack stack = previousUpgrade.getCraftingItem();
if( stack != null )
{
stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem );
stack = InventoryUtil.storeItems( stack, new PlayerMainInvWrapper( inventory ), inventory.currentItem );
if( stack != null )
{
WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ );
@ -139,7 +140,7 @@ public class PocketAPI implements ILuaAPI
ItemStack stack = previousUpgrade.getCraftingItem();
if( stack != null )
{
stack = InventoryUtil.storeItems( stack, inventory, 0, 36, inventory.currentItem );
stack = InventoryUtil.storeItems( stack, new PlayerMainInvWrapper( inventory ), inventory.currentItem );
if( stack != null )
{
WorldUtil.dropItemStack( stack, player.worldObj, player.posX, player.posY, player.posZ );

View File

@ -40,11 +40,17 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
public class TileTurtle extends TileComputerBase
implements ITurtleTile, IInventory, ITickable
{
@ -65,6 +71,7 @@ public class TileTurtle extends TileComputerBase
private ItemStack[] m_inventory;
private ItemStack[] m_previousInventory;
private final IItemHandlerModifiable m_itemHandler = new InvWrapper( this );
private boolean m_inventoryChanged;
private TurtleBrain m_brain;
private MoveState m_moveState;
@ -714,4 +721,26 @@ public class TileTurtle extends TileComputerBase
m_brain.setOwner( this );
copy.m_moveState = MoveState.MOVED;
}
public IItemHandlerModifiable getItemHandler()
{
return m_itemHandler;
}
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return capability == ITEM_HANDLER_CAPABILITY || super.hasCapability( capability, facing );
}
@Nonnull
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == ITEM_HANDLER_CAPABILITY )
{
return ITEM_HANDLER_CAPABILITY.cast( m_itemHandler );
}
return super.getCapability( capability, facing );
}
}

View File

@ -34,6 +34,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.IItemHandlerModifiable;
import javax.annotation.Nonnull;
import java.lang.ref.WeakReference;
@ -649,6 +650,13 @@ public class TurtleBrain implements ITurtleAccess
return m_owner;
}
@Nonnull
@Override
public IItemHandlerModifiable getItemHandler()
{
return m_owner.getItemHandler();
}
@Override
public boolean isFuelNeeded()
{

View File

@ -40,7 +40,7 @@ public class TurtleCraftCommand implements ITurtleCommand
// Store the results
for( ItemStack stack : results )
{
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
// Drop the remainder

View File

@ -17,6 +17,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
@ -46,7 +47,7 @@ public class TurtleDropCommand implements ITurtleCommand
EnumFacing direction = m_direction.toWorldDir( turtle );
// Get things to drop
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getInventory(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
if( stack == null )
{
return TurtleCommandResult.failure( "No items to drop" );
@ -58,15 +59,15 @@ public class TurtleDropCommand implements ITurtleCommand
BlockPos newPosition = oldPosition.offset( direction );
EnumFacing side = direction.getOpposite();
IInventory inventory = InventoryUtil.getInventory( world, newPosition, side );
IItemHandler inventory = InventoryUtil.getInventory( world, newPosition, side );
if( inventory != null )
{
// Drop the item into the inventory
ItemStack remainder = InventoryUtil.storeItems( stack, inventory, side );
ItemStack remainder = InventoryUtil.storeItems( stack, inventory );
if( remainder != null )
{
// Put the remainder back in the turtle
InventoryUtil.storeItems( remainder, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
InventoryUtil.storeItems( remainder, turtle.getItemHandler(), turtle.getSelectedSlot() );
}
// Return true if we stored anything

View File

@ -14,6 +14,7 @@ import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
@ -33,7 +34,7 @@ public class TurtleEquipCommand implements ITurtleCommand
// Determine the upgrade to equipLeft
ITurtleUpgrade newUpgrade;
ItemStack newUpgradeStack;
IInventory inventory = turtle.getInventory();
IItemHandler inventory = turtle.getItemHandler();
ItemStack selectedStack = inventory.getStackInSlot( turtle.getSelectedSlot() );
if( selectedStack != null )
{
@ -68,19 +69,17 @@ public class TurtleEquipCommand implements ITurtleCommand
{
// Consume new upgrades item
InventoryUtil.takeItems( 1, inventory, turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
inventory.markDirty();
}
if( oldUpgradeStack != null )
{
// Store old upgrades item
ItemStack remainder = InventoryUtil.storeItems( oldUpgradeStack, inventory, 0, inventory.getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( oldUpgradeStack, inventory, turtle.getSelectedSlot() );
if( remainder != null )
{
// If there's no room for the items, drop them
BlockPos position = turtle.getPosition();
WorldUtil.dropItemStack( remainder, turtle.getWorld(), position, turtle.getDirection() );
}
inventory.markDirty();
}
turtle.setUpgrade( m_side, newUpgrade );

View File

@ -227,7 +227,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
@Override
public void consumeDrop( Entity entity, ItemStack drop )
{
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
WorldUtil.dropItemStack( remainder, world, position, turtle.getDirection().getOpposite() );

View File

@ -54,7 +54,7 @@ public class TurtlePlayer extends FakePlayer
ItemStack stack = inventory.getStackInSlot( i );
if( stack != null )
{
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
WorldUtil.dropItemStack( remainder, turtle.getWorld(), dropPosition, dropDirection );

View File

@ -42,14 +42,14 @@ public class TurtleRefuelCommand implements ITurtleCommand
{
// Otherwise, refuel for real
// Remove items from inventory
ItemStack stack = InventoryUtil.takeItems( m_limit, turtle.getInventory(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
ItemStack stack = InventoryUtil.takeItems( m_limit, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
if( stack != null )
{
TurtleCommandResult result = refuel( turtle, stack, false );
if( !result.isSuccess() )
{
// If the items weren't burnt, put them back
InventoryUtil.storeItems( stack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
}
return result;
}
@ -83,7 +83,7 @@ public class TurtleRefuelCommand implements ITurtleCommand
// Store the replacement item in the inventory
if( replacementStack != null )
{
InventoryUtil.storeItems( replacementStack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
}
// Animate

View File

@ -20,6 +20,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import java.util.List;
@ -55,19 +56,19 @@ public class TurtleSuckCommand implements ITurtleCommand
BlockPos newPosition = WorldUtil.moveCoords( oldPosition, direction );
EnumFacing side = direction.getOpposite();
IInventory inventory = InventoryUtil.getInventory( world, newPosition, side );
IItemHandler inventory = InventoryUtil.getInventory( world, newPosition, side );
if( inventory != null )
{
// Take from inventory of thing in front
ItemStack stack = InventoryUtil.takeItems( m_quantity, inventory, side );
ItemStack stack = InventoryUtil.takeItems( m_quantity, inventory );
if( stack != null )
{
// Try to place into the turtle
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
// Put the remainder back in the inventory
InventoryUtil.storeItems( remainder, inventory, side );
InventoryUtil.storeItems( remainder, inventory );
}
// Return true if we consumed anything
@ -115,7 +116,7 @@ public class TurtleSuckCommand implements ITurtleCommand
storeStack = stack;
leaveStack = null;
}
ItemStack remainder = InventoryUtil.storeItems( storeStack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( storeStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != storeStack )
{
storedItems = true;

View File

@ -31,7 +31,7 @@ public class TurtleTransferToCommand implements ITurtleCommand
public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
{
// Take stack
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getInventory(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
ItemStack stack = InventoryUtil.takeItems( m_quantity, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
if( stack == null )
{
turtle.playAnimation( TurtleAnimation.Wait );
@ -39,11 +39,11 @@ public class TurtleTransferToCommand implements ITurtleCommand
}
// Store stack
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getInventory(), m_slot, 1, m_slot );
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), m_slot, 1, m_slot );
if( remainder != null )
{
// Put the remainder back
InventoryUtil.storeItems( remainder, turtle.getInventory(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
InventoryUtil.storeItems( remainder, turtle.getItemHandler(), turtle.getSelectedSlot(), 1, turtle.getSelectedSlot() );
}
// Return true if we moved anything

View File

@ -36,6 +36,7 @@ import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import javax.vecmath.Matrix4f;
import java.util.List;
public class TurtleTool implements ITurtleUpgrade
{
@ -180,7 +181,7 @@ public class TurtleTool implements ITurtleUpgrade
@Override
public void consumeDrop( Entity entity, ItemStack drop )
{
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( drop, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
WorldUtil.dropItemStack( remainder, world, position, turtle.getDirection().getOpposite() );
@ -261,12 +262,12 @@ public class TurtleTool implements ITurtleUpgrade
// Consume the items the block drops
if( canHarvestBlock( world, newPosition ) )
{
java.util.List<ItemStack> items = getBlockDropped( world, newPosition );
List<ItemStack> items = getBlockDropped( world, newPosition );
if( items != null && items.size() > 0 )
{
for( ItemStack stack : items )
{
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getInventory(), 0, turtle.getInventory().getSizeInventory(), turtle.getSelectedSlot() );
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != null )
{
// If there's no room for the items, drop them

View File

@ -6,19 +6,20 @@
package dan200.computercraft.shared.util;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryLargeChest;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.ILockableContainer;
import net.minecraft.world.World;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import org.apache.commons.lang3.tuple.Pair;
public class InventoryUtil
@ -27,35 +28,12 @@ public class InventoryUtil
public static boolean areItemsEqual( ItemStack a, ItemStack b )
{
if( areItemsStackable( a, b ) )
{
if( a == null || a.stackSize == b.stackSize )
{
return true;
}
}
return false;
return a == b || ItemStack.areItemStacksEqual( a, b );
}
public static boolean areItemsStackable( ItemStack a, ItemStack b )
{
if( a == b )
{
return true;
}
if( a != null && b != null && a.getItem() == b.getItem() )
{
if( a.getItemDamage() == b.getItemDamage() )
{
if( (a.getTagCompound() == null && b.getTagCompound() == null) ||
(a.getTagCompound() != null && b.getTagCompound() != null && a.getTagCompound().equals( b.getTagCompound() ) ) )
{
return true;
}
}
}
return false;
return a == b || ItemHandlerHelper.canItemStacksStack( a, b );
}
public static ItemStack copyItem( ItemStack a )
@ -69,40 +47,28 @@ public class InventoryUtil
// Methods for finding inventories:
public static IInventory getInventory( World world, BlockPos pos, EnumFacing side )
public static IItemHandler getInventory( World world, BlockPos pos, EnumFacing side )
{
// Look for tile with inventory
int y = pos.getY();
if( y >= 0 && y < world.getHeight() )
{
TileEntity tileEntity = world.getTileEntity( pos );
if( tileEntity != null && tileEntity instanceof IInventory )
if( tileEntity != null )
{
// Special case code for double chests
Block block = world.getBlockState( pos ).getBlock();
if( block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST )
IItemHandler itemHandler = tileEntity.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side );
if( itemHandler != null )
{
// Check if it's a double chest, and return a combined inventory if so
if( world.getBlockState( pos.west() ).getBlock() == block )
{
return new InventoryLargeChest( "Large chest", (ILockableContainer)world.getTileEntity( pos.west() ), (ILockableContainer)tileEntity );
}
if( world.getBlockState( pos.east() ).getBlock() == block )
{
return new InventoryLargeChest( "Large chest", (ILockableContainer)tileEntity, (ILockableContainer)world.getTileEntity( pos.east() ) );
}
if( world.getBlockState( pos.north() ).getBlock() == block )
{
return new InventoryLargeChest( "Large chest", (ILockableContainer)world.getTileEntity( pos.north() ), (ILockableContainer)tileEntity );
}
if( world.getBlockState( pos.south() ).getBlock() == block )
{
return new InventoryLargeChest( "Large chest", (ILockableContainer)tileEntity, (ILockableContainer)world.getTileEntity( pos.south() ) );
}
return itemHandler;
}
else if( side != null && tileEntity instanceof ISidedInventory )
{
return new SidedInvWrapper( (ISidedInventory) tileEntity, side );
}
else if( tileEntity instanceof IInventory )
{
return new InvWrapper( (IInventory) tileEntity );
}
// Otherwise, get tile inventory
return (IInventory)tileEntity;
}
}
@ -122,60 +88,52 @@ public class InventoryUtil
Entity entity = hit.getKey();
if( entity instanceof IInventory )
{
return (IInventory) entity;
return new InvWrapper( (IInventory) entity );
}
}
return null;
}
// Methods for placing into inventories:
public static ItemStack storeItems( ItemStack itemstack, IInventory inventory, int start, int range, int begin )
public static ItemStack storeItems( ItemStack itemstack, IItemHandler inventory, int start, int range, int begin )
{
int[] slots = makeSlotList( start, range, begin );
return storeItems( itemstack, inventory, slots, null );
return storeItems( itemstack, inventory, slots );
}
public static ItemStack storeItems( ItemStack itemstack, IInventory inventory, EnumFacing side )
public static ItemStack storeItems( ItemStack itemstack, IItemHandler inventory, int begin )
{
// Try ISidedInventory
if( inventory instanceof ISidedInventory )
{
// Place into ISidedInventory
ISidedInventory sidedInventory = (ISidedInventory)inventory;
int[] slots = sidedInventory.getSlotsForFace( side );
return storeItems( itemstack, inventory, slots, side );
}
// No ISidedInventory, store into any slot
int[] slots = makeSlotList( 0, inventory.getSizeInventory(), 0 ); // TODO: optimise this out?
return storeItems( itemstack, inventory, slots, side );
int[] slots = makeSlotList( 0, inventory.getSlots(), begin );
return storeItems( itemstack, inventory, slots );
}
public static ItemStack storeItems( ItemStack itemstack, IItemHandler inventory )
{
int[] slots = makeSlotList( 0, inventory.getSlots(), 0 ); // TODO: optimise this out?
return storeItems( itemstack, inventory, slots );
}
// Methods for taking out of inventories
public static ItemStack takeItems( int count, IInventory inventory, int start, int range, int begin )
public static ItemStack takeItems( int count, IItemHandler inventory, int start, int range, int begin )
{
int[] slots = makeSlotList( start, range, begin );
return takeItems( count, inventory, slots, null );
return takeItems( count, inventory, slots );
}
public static ItemStack takeItems( int count, IInventory inventory, EnumFacing side )
{
// Try ISidedInventory
if( inventory instanceof ISidedInventory )
{
// Place into ISidedInventory
ISidedInventory sidedInventory = (ISidedInventory)inventory;
int[] slots = sidedInventory.getSlotsForFace( side );
return takeItems( count, inventory, slots, side );
}
// No ISidedInventory, store into any slot
int[] slots = makeSlotList( 0, inventory.getSizeInventory(), 0 );
return takeItems( count, inventory, slots, side );
public static ItemStack takeItems( int count, IItemHandler inventory, int begin )
{
int[] slots = makeSlotList( 0, inventory.getSlots(), begin );
return takeItems( count, inventory, slots );
}
public static ItemStack takeItems( int count, IItemHandler inventory )
{
int[] slots = makeSlotList( 0, inventory.getSlots(), 0 );
return takeItems( count, inventory, slots );
}
// Private methods
private static int[] makeSlotList( int start, int range, int begin )
@ -184,16 +142,16 @@ public class InventoryUtil
{
return null;
}
int[] slots = new int[range];
for( int n=0; n<slots.length; ++n )
int[] slots = new int[ range ];
for( int n = 0; n < slots.length; ++n )
{
slots[n] = start + ( (n + (begin - start)) % range );
slots[ n ] = start + ((n + (begin - start)) % range);
}
return slots;
}
private static ItemStack storeItems( ItemStack stack, IInventory inventory, int[] slots, EnumFacing face )
private static ItemStack storeItems( ItemStack stack, IItemHandler inventory, int[] slots )
{
if( slots == null || slots.length == 0 )
{
@ -208,74 +166,13 @@ public class InventoryUtil
ItemStack remainder = stack;
for( int slot : slots )
{
if( canPlaceItemThroughFace( inventory, slot, remainder, face ) )
{
ItemStack slotContents = inventory.getStackInSlot( slot );
if( slotContents == null )
{
// Slot is empty
int space = inventory.getInventoryStackLimit();
if( space >= remainder.stackSize )
{
// Items fit completely in slot
inventory.setInventorySlotContents( slot, remainder );
inventory.markDirty();
return null;
}
else
{
// Items fit partially in slot
remainder = remainder.copy();
inventory.setInventorySlotContents( slot, remainder.splitStack( space ) );
}
}
else if( areItemsStackable( slotContents, remainder ) )
{
// Slot is occupied, but matching
int space = Math.min( slotContents.getMaxStackSize(), inventory.getInventoryStackLimit() ) - slotContents.stackSize;
if( space >= remainder.stackSize )
{
// Items fit completely in slot
slotContents.stackSize += remainder.stackSize;
inventory.setInventorySlotContents( slot, slotContents );
inventory.markDirty();
return null;
}
else if( space > 0 )
{
// Items fit partially in slot
remainder = remainder.copy();
remainder.stackSize -= space;
slotContents.stackSize += space;
inventory.setInventorySlotContents( slot, slotContents );
}
}
}
}
// If the output isn't the input, inform the change
if( remainder != stack )
{
inventory.markDirty();
if( remainder == null ) break;
remainder = inventory.insertItem( slot, remainder, false );
}
return remainder;
}
private static boolean canPlaceItemThroughFace( IInventory inventory, int slot, ItemStack itemstack, EnumFacing face )
{
if( inventory.isItemValidForSlot( slot, itemstack ) )
{
if( face != null && inventory instanceof ISidedInventory )
{
ISidedInventory sided = (ISidedInventory)inventory;
return sided.canInsertItem( slot, itemstack, face );
}
return true;
}
return false;
}
private static ItemStack takeItems( int count, IInventory inventory, int[] slots, EnumFacing face )
private static ItemStack takeItems( int count, IItemHandler inventory, int[] slots )
{
if( slots == null )
{
@ -287,65 +184,30 @@ public class InventoryUtil
int countRemaining = count;
for( int slot : slots )
{
if( countRemaining > 0 )
if( countRemaining <= 0 ) break;
ItemStack stack = inventory.getStackInSlot( slot );
if( stack != null )
{
ItemStack stack = inventory.getStackInSlot( slot );
if( stack != null && canTakeItemThroughFace( inventory, slot, stack, face ) )
if( partialStack == null || areItemsStackable( stack, partialStack ) )
{
if( partialStack == null || areItemsStackable( stack, partialStack ) )
ItemStack extracted = inventory.extractItem( slot, countRemaining, false );
if( extracted != null )
{
// Found a matching thing
if( countRemaining >= stack.stackSize )
countRemaining -= extracted.stackSize;
if( partialStack == null )
{
// Eat the thing whole
inventory.setInventorySlotContents( slot, null );
if( partialStack == null )
{
partialStack = stack;
countRemaining = Math.min( countRemaining, partialStack.getItem().getItemStackLimit( partialStack ) ) - stack.stackSize;
}
else
{
partialStack.stackSize += stack.stackSize;
countRemaining -= stack.stackSize;
}
partialStack = extracted;
}
else
{
// Eat part of the thing
ItemStack splitStack = stack.splitStack( countRemaining );
if( partialStack == null )
{
partialStack = splitStack;
countRemaining = Math.min( countRemaining, partialStack.getItem().getItemStackLimit( partialStack ) ) - splitStack.stackSize;
}
else
{
partialStack.stackSize += splitStack.stackSize;
countRemaining -= splitStack.stackSize;
}
partialStack.stackSize += extracted.stackSize;
}
}
}
}
}
// Return the final stack
if( partialStack != null )
{
inventory.markDirty();
return partialStack;
}
return null;
}
private static boolean canTakeItemThroughFace( IInventory inventory, int slot, ItemStack itemstack, EnumFacing face )
{
if( face != null && inventory instanceof ISidedInventory )
{
ISidedInventory sided = (ISidedInventory)inventory;
return sided.canExtractItem( slot, itemstack, face );
}
return true;
return partialStack;
}
}