1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-15 12:37:13 +00:00
Files
CC-Tweaked/remappedSrc/dan200/computercraft/shared/util/ItemStorage.java
2021-07-11 01:33:21 +00:00

304 lines
8.6 KiB
Java

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.util;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Direction;
import javax.annotation.Nonnull;
/**
* The most cutesy alternative of {@code IItemHandler} the world has ever seen.
*/
public interface ItemStorage
{
static ItemStorage wrap( Inventory inventory )
{
return new InventoryWrapper( inventory );
}
static ItemStorage wrap( @Nonnull SidedInventory inventory, @Nonnull Direction facing )
{
return new SidedInventoryWrapper( inventory, facing );
}
static ItemStorage wrap( @Nonnull Inventory inventory, @Nonnull Direction facing )
{
return inventory instanceof SidedInventory ? new SidedInventoryWrapper( (SidedInventory) inventory, facing ) : new InventoryWrapper( inventory );
}
static boolean areStackable( @Nonnull ItemStack a, @Nonnull ItemStack b )
{
return a == b || (a.getItem() == b.getItem() && ItemStack.areNbtEqual( a, b ));
}
int size();
@Nonnull
ItemStack getStack( int slot );
@Nonnull
ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate );
@Nonnull
ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate );
default ItemStorage view( int start, int size )
{
return new View( this, start, size );
}
class InventoryWrapper implements ItemStorage
{
private final Inventory inventory;
InventoryWrapper( Inventory inventory )
{
this.inventory = inventory;
}
@Override
public int size()
{
return inventory.size();
}
@Override
@Nonnull
public ItemStack getStack( int slot )
{
return inventory.getStack( slot );
}
@Override
@Nonnull
public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate )
{
ItemStack existing = inventory.getStack( slot );
if( existing.isEmpty() || !canExtract( slot, existing ) || (!filter.isEmpty() && !areStackable( existing, filter )) )
{
return ItemStack.EMPTY;
}
if( simulate )
{
existing = existing.copy();
if( existing.getCount() > limit )
{
existing.setCount( limit );
}
return existing;
}
else if( existing.getCount() < limit )
{
setAndDirty( slot, ItemStack.EMPTY );
return existing;
}
else
{
ItemStack result = existing.split( limit );
setAndDirty( slot, existing );
return result;
}
}
protected boolean canExtract( int slot, ItemStack stack )
{
return true;
}
private void setAndDirty( int slot, @Nonnull ItemStack stack )
{
inventory.setStack( slot, stack );
inventory.markDirty();
}
@Override
@Nonnull
public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate )
{
if( stack.isEmpty() || !inventory.isValid( slot, stack ) )
{
return stack;
}
ItemStack existing = inventory.getStack( slot );
if( existing.isEmpty() )
{
int limit = Math.min( stack.getMaxCount(), inventory.getMaxCountPerStack() );
if( limit <= 0 )
{
return stack;
}
if( stack.getCount() < limit )
{
if( !simulate )
{
setAndDirty( slot, stack );
}
return ItemStack.EMPTY;
}
else
{
stack = stack.copy();
ItemStack insert = stack.split( limit );
if( !simulate )
{
setAndDirty( slot, insert );
}
return stack;
}
}
else if( areStackable( stack, existing ) )
{
int limit = Math.min( existing.getMaxCount(), inventory.getMaxCountPerStack() ) - existing.getCount();
if( limit <= 0 )
{
return stack;
}
if( stack.getCount() < limit )
{
if( !simulate )
{
existing.increment( stack.getCount() );
setAndDirty( slot, existing );
}
return ItemStack.EMPTY;
}
else
{
stack = stack.copy();
stack.decrement( limit );
if( !simulate )
{
existing.increment( limit );
setAndDirty( slot, existing );
}
return stack;
}
}
else
{
return stack;
}
}
}
class SidedInventoryWrapper extends InventoryWrapper
{
private final SidedInventory inventory;
private final Direction facing;
SidedInventoryWrapper( SidedInventory inventory, Direction facing )
{
super( inventory );
this.inventory = inventory;
this.facing = facing;
}
@Override
protected boolean canExtract( int slot, ItemStack stack )
{
return super.canExtract( slot, stack ) && inventory.canExtract( slot, stack, facing );
}
@Override
public int size()
{
return inventory.getAvailableSlots( facing ).length;
}
@Nonnull
@Override
public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate )
{
int[] slots = inventory.getAvailableSlots( facing );
return slot >= 0 && slot < slots.length ? super.take( slots[slot], limit, filter, simulate ) : ItemStack.EMPTY;
}
@Nonnull
@Override
public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate )
{
int[] slots = inventory.getAvailableSlots( facing );
if( slot < 0 || slot >= slots.length )
{
return stack;
}
int mappedSlot = slots[slot];
if( !inventory.canInsert( slot, stack, facing ) )
{
return stack;
}
return super.store( mappedSlot, stack, simulate );
}
}
class View implements ItemStorage
{
private final ItemStorage parent;
private final int start;
private final int size;
View( ItemStorage parent, int start, int size )
{
this.parent = parent;
this.start = start;
this.size = size;
}
@Override
public int size()
{
return size;
}
@Override
@Nonnull
public ItemStack getStack( int slot )
{
if( slot < start || slot >= start + size )
{
return ItemStack.EMPTY;
}
return parent.getStack( slot - start );
}
@Nonnull
@Override
public ItemStack take( int slot, int limit, @Nonnull ItemStack filter, boolean simulate )
{
if( slot < start || slot >= start + size )
{
return ItemStack.EMPTY;
}
return parent.take( slot - start, limit, filter, simulate );
}
@Nonnull
@Override
public ItemStack store( int slot, @Nonnull ItemStack stack, boolean simulate )
{
if( slot < start || slot >= start + size )
{
return stack;
}
return parent.store( slot - start, stack, simulate );
}
@Override
public ItemStorage view( int start, int size )
{
return new View( parent, this.start + start, size );
}
}
}