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:
parent
25128dfb66
commit
b07f28c30c
@ -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.
|
||||
*
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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() );
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user