Merge pull request #2385 from rwtema/master
Add IItemHandler capability
This commit is contained in:
commit
e9a86f27fb
20 changed files with 1299 additions and 1 deletions
|
@ -0,0 +1,11 @@
|
|||
--- ../src-base/minecraft/net/minecraft/block/BlockDropper.java
|
||||
+++ ../src-work/minecraft/net/minecraft/block/BlockDropper.java
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
ItemStack itemstack = tileentitydispenser.func_70301_a(i);
|
||||
|
||||
- if (itemstack != null)
|
||||
+ if (itemstack != null && net.minecraftforge.items.VanillaInventoryCodeHooks.dropperInsertHook(p_176439_1_, p_176439_2_, tileentitydispenser, i, itemstack))
|
||||
{
|
||||
EnumFacing enumfacing = (EnumFacing)p_176439_1_.func_180495_p(p_176439_2_).func_177229_b(field_176441_a);
|
||||
BlockPos blockpos = p_176439_2_.func_177972_a(enumfacing);
|
|
@ -8,3 +8,26 @@
|
|||
if (!this.field_70170_p.field_72995_K)
|
||||
{
|
||||
p_130002_1_.func_71007_a(this);
|
||||
@@ -232,4 +233,22 @@
|
||||
this.field_94113_a[i] = null;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public net.minecraftforge.items.IItemHandler itemHandler = new net.minecraftforge.items.wrapper.InvWrapper(this);
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
+ {
|
||||
+ return (T) itemHandler;
|
||||
+ }
|
||||
+ return super.getCapability(capability, facing);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
|
||||
+ }
|
||||
}
|
||||
|
|
|
@ -76,3 +76,22 @@
|
|||
}
|
||||
|
||||
public boolean[] func_174902_m()
|
||||
@@ -386,4 +393,18 @@
|
||||
this.field_145945_j[i] = null;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ net.minecraftforge.items.IItemHandler handlerInput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP);
|
||||
+ net.minecraftforge.items.IItemHandler handlerOutput = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN);
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
+ if (facing == EnumFacing.UP)
|
||||
+ return (T) handlerInput;
|
||||
+ else
|
||||
+ return (T) handlerOutput;
|
||||
+ return super.getCapability(capability, facing);
|
||||
+ }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityChest.java
|
||||
+++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityChest.java
|
||||
@@ -186,6 +186,7 @@
|
||||
{
|
||||
super.func_145836_u();
|
||||
this.field_145984_a = false;
|
||||
+ doubleChestHandler = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
@@ -468,4 +469,24 @@
|
||||
this.field_145985_p[i] = null;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ public net.minecraftforge.items.VanillaDoubleChestItemHandler doubleChestHandler;
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
+ {
|
||||
+ if(doubleChestHandler == null || doubleChestHandler.needsRefresh())
|
||||
+ doubleChestHandler = net.minecraftforge.items.VanillaDoubleChestItemHandler.get(this);
|
||||
+ if (doubleChestHandler != null && doubleChestHandler != net.minecraftforge.items.VanillaDoubleChestItemHandler.NO_ADJACENT_CHESTS_INSTANCE)
|
||||
+ return (T) doubleChestHandler;
|
||||
+ }
|
||||
+ return super.getCapability(capability, facing);
|
||||
+ }
|
||||
+
|
||||
+ public net.minecraftforge.items.IItemHandler getSingleChestHandler()
|
||||
+ {
|
||||
+ return super.getCapability(net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
|
||||
+ }
|
||||
}
|
|
@ -49,3 +49,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -451,4 +462,21 @@
|
||||
this.field_145957_n[i] = null;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ net.minecraftforge.items.IItemHandler handlerTop = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.UP);
|
||||
+ net.minecraftforge.items.IItemHandler handlerBottom = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.DOWN);
|
||||
+ net.minecraftforge.items.IItemHandler handlerSide = new net.minecraftforge.items.wrapper.SidedInvWrapper(this, net.minecraft.util.EnumFacing.WEST);
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
+ if (facing == EnumFacing.DOWN)
|
||||
+ return (T) handlerBottom;
|
||||
+ else if (facing == EnumFacing.UP)
|
||||
+ return (T) handlerTop;
|
||||
+ else
|
||||
+ return (T) handlerSide;
|
||||
+ return super.getCapability(capability, facing);
|
||||
+ }
|
||||
}
|
||||
|
|
|
@ -1,6 +1,22 @@
|
|||
--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityHopper.java
|
||||
+++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityHopper.java
|
||||
@@ -515,17 +515,31 @@
|
||||
@@ -260,6 +260,7 @@
|
||||
|
||||
private boolean func_145883_k()
|
||||
{
|
||||
+ if (net.minecraftforge.items.VanillaInventoryCodeHooks.insertHook(this)) { return true; }
|
||||
IInventory iinventory = this.func_145895_l();
|
||||
|
||||
if (iinventory == null)
|
||||
@@ -366,6 +367,7 @@
|
||||
|
||||
public static boolean func_145891_a(IHopper p_145891_0_)
|
||||
{
|
||||
+ if (net.minecraftforge.items.VanillaInventoryCodeHooks.extractHook(p_145891_0_)) { return true; }
|
||||
IInventory iinventory = func_145884_b(p_145891_0_);
|
||||
|
||||
if (iinventory != null)
|
||||
@@ -515,17 +517,31 @@
|
||||
|
||||
if (itemstack == null)
|
||||
{
|
||||
|
@ -33,3 +49,14 @@
|
|||
}
|
||||
|
||||
if (flag)
|
||||
@@ -668,4 +684,10 @@
|
||||
this.field_145900_a[i] = null;
|
||||
}
|
||||
}
|
||||
+
|
||||
+
|
||||
+ protected net.minecraftforge.items.IItemHandler createUnSidedHandler()
|
||||
+ {
|
||||
+ return new net.minecraftforge.items.VanillaHopperItemHandler(this);
|
||||
+ }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityLockable.java
|
||||
+++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityLockable.java
|
||||
@@ -47,4 +47,25 @@
|
||||
{
|
||||
return (IChatComponent)(this.func_145818_k_() ? new ChatComponentText(this.func_70005_c_()) : new ChatComponentTranslation(this.func_70005_c_(), new Object[0]));
|
||||
}
|
||||
+
|
||||
+ private net.minecraftforge.items.IItemHandler itemHandler;
|
||||
+
|
||||
+ protected net.minecraftforge.items.IItemHandler createUnSidedHandler()
|
||||
+ {
|
||||
+ return new net.minecraftforge.items.wrapper.InvWrapper(this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ if (capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
+ return (T) (itemHandler == null ? (itemHandler = createUnSidedHandler()) : itemHandler);
|
||||
+ return super.getCapability(capability, facing);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasCapability(net.minecraftforge.common.capabilities.Capability<?> capability, net.minecraft.util.EnumFacing facing)
|
||||
+ {
|
||||
+ return capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
|
||||
+ }
|
||||
}
|
|
@ -26,6 +26,7 @@ import net.minecraftforge.common.config.Configuration;
|
|||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.common.network.ForgeNetworkHandler;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.RecipeSorter;
|
||||
import net.minecraftforge.server.command.ForgeCommand;
|
||||
|
@ -310,6 +311,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
|
|||
@Subscribe
|
||||
public void preInit(FMLPreInitializationEvent evt)
|
||||
{
|
||||
CapabilityItemHandler.register();
|
||||
MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER);
|
||||
ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory());
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||
import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class CapabilityItemHandler
|
||||
{
|
||||
@CapabilityInject(IItemHandler.class)
|
||||
public static Capability<IItemHandler> ITEM_HANDLER_CAPABILITY = null;
|
||||
|
||||
public static void register()
|
||||
{
|
||||
CapabilityManager.INSTANCE.register(IItemHandler.class, new Capability.IStorage<IItemHandler>()
|
||||
{
|
||||
@Override
|
||||
public NBTBase writeNBT(Capability<IItemHandler> capability, IItemHandler instance, EnumFacing side)
|
||||
{
|
||||
NBTTagList nbtTagList = new NBTTagList();
|
||||
int size = instance.getSlots();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ItemStack stack = instance.getStackInSlot(i);
|
||||
if (stack != null)
|
||||
{
|
||||
NBTTagCompound itemTag = new NBTTagCompound();
|
||||
itemTag.setInteger("Slot", i);
|
||||
stack.writeToNBT(itemTag);
|
||||
nbtTagList.appendTag(itemTag);
|
||||
}
|
||||
}
|
||||
return nbtTagList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(Capability<IItemHandler> capability, IItemHandler instance, EnumFacing side, NBTBase base)
|
||||
{
|
||||
if (!(instance instanceof IItemHandlerModifiable))
|
||||
throw new RuntimeException("IItemHandler instance does not implement IItemHandlerModifiable");
|
||||
IItemHandlerModifiable itemHandlerModifiable = (IItemHandlerModifiable) instance;
|
||||
NBTTagList tagList = (NBTTagList) base;
|
||||
for (int i = 0; i < tagList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound itemTags = tagList.getCompoundTagAt(i);
|
||||
int j = itemTags.getInteger("Slot");
|
||||
|
||||
if (j > 0 && j < instance.getSlots())
|
||||
{
|
||||
itemHandlerModifiable.setStackInSlot(j, ItemStack.loadItemStackFromNBT(itemTags));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, new Callable<ItemStackHandler>()
|
||||
{
|
||||
@Override
|
||||
public ItemStackHandler call() throws Exception
|
||||
{
|
||||
return new ItemStackHandler();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
57
src/main/java/net/minecraftforge/items/IItemHandler.java
Normal file
57
src/main/java/net/minecraftforge/items/IItemHandler.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IItemHandler
|
||||
{
|
||||
/**
|
||||
* Returns the number of slots available
|
||||
*
|
||||
* @return The number of slots available
|
||||
**/
|
||||
int getSlots();
|
||||
|
||||
/**
|
||||
* Returns the ItemStack in a given slot.
|
||||
*
|
||||
* The result's stack size may be greater than the itemstacks max size.
|
||||
*
|
||||
* If the result is null, then the slot is empty.
|
||||
* If the result is not null but the stack size is zero, then it represents
|
||||
* an empty slot that will only accept* a specific itemstack.
|
||||
*
|
||||
* <p/>
|
||||
* IMPORTANT: This ItemStack MUST NOT be modified. This method is not for
|
||||
* altering an inventories contents. Any implementers who are able to detect
|
||||
* modification through this method should throw an exception.
|
||||
* <p/>
|
||||
* SERIOUSLY: DO NOT MODIFY THE RETURNED ITEMSTACK
|
||||
*
|
||||
* @param slot Slot to query
|
||||
* @return ItemStack in given slot. May be null.
|
||||
**/
|
||||
ItemStack getStackInSlot(int slot);
|
||||
|
||||
/**
|
||||
* Inserts an ItemStack into the given slot and return the remainder.
|
||||
* Note: This behaviour is subtly different from IFluidHandlers.fill()
|
||||
*
|
||||
* @param slot Slot to insert into.
|
||||
* @param stack ItemStack to insert
|
||||
* @param simulate If true, the insertion is only simulated
|
||||
* @return The remaining ItemStack that was not inserted (if the entire stack is accepted, then return null)
|
||||
**/
|
||||
ItemStack insertItem(int slot, ItemStack stack, boolean simulate);
|
||||
|
||||
/**
|
||||
* Extracts an ItemStack from the given slot. The returned value must be null
|
||||
* if nothing is extracted, otherwise it's stack size must not be greater than amount or the
|
||||
* itemstacks getMaxStackSize().
|
||||
*
|
||||
* @param slot Slot to extract from.
|
||||
* @param amount Amount to extract (may be greater than the current stacks max limit)
|
||||
* @param simulate If true, the extraction is only simulated
|
||||
* @return ItemStack extracted from the slot, must be null, if nothing can be extracted
|
||||
**/
|
||||
ItemStack extractItem(int slot, int amount, boolean simulate);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IItemHandlerModifiable extends IItemHandler
|
||||
{
|
||||
/**
|
||||
* Overrides the stack in the given slot. This method is used by the
|
||||
* standard Forge helper methods and classes. It is not intended for
|
||||
* general use by other mods, and the handler may throw an error if it
|
||||
* is called unexpectedly.
|
||||
*
|
||||
* @param slot Slot to modify
|
||||
* @param stack ItemStack to set slot to (may be null)
|
||||
* @throws RuntimeException if the handler is called in a way that the handler
|
||||
* was not expecting.
|
||||
**/
|
||||
void setStackInSlot(int slot, ItemStack stack);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ItemHandlerHelper
|
||||
{
|
||||
public static ItemStack insertItem(IItemHandler dest, ItemStack stack, boolean simulate)
|
||||
{
|
||||
if (dest == null || stack == null)
|
||||
return stack;
|
||||
|
||||
for (int i = 0; i < dest.getSlots(); i++)
|
||||
{
|
||||
stack = dest.insertItem(i, stack, simulate);
|
||||
if (stack == null || stack.stackSize <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static boolean canItemStacksStack(ItemStack a, ItemStack b)
|
||||
{
|
||||
if (a == null || !a.isItemEqual(b))
|
||||
return false;
|
||||
|
||||
final NBTTagCompound aTag = a.getTagCompound();
|
||||
final NBTTagCompound bTag = b.getTagCompound();
|
||||
return (aTag != null || bTag == null) && (aTag == null || aTag.equals(bTag));
|
||||
}
|
||||
|
||||
public static ItemStack copyStackWithSize(ItemStack itemStack, int size)
|
||||
{
|
||||
if (size == 0)
|
||||
return null;
|
||||
ItemStack copy = ItemStack.copyItemStack(itemStack);
|
||||
copy.stackSize = size;
|
||||
return copy;
|
||||
}
|
||||
}
|
185
src/main/java/net/minecraftforge/items/ItemStackHandler.java
Normal file
185
src/main/java/net/minecraftforge/items/ItemStackHandler.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
|
||||
public class ItemStackHandler implements IItemHandler, IItemHandlerModifiable, INBTSerializable<NBTTagCompound>
|
||||
{
|
||||
protected ItemStack[] stacks;
|
||||
|
||||
public ItemStackHandler()
|
||||
{
|
||||
this(1);
|
||||
}
|
||||
|
||||
public ItemStackHandler(int size)
|
||||
{
|
||||
stacks = new ItemStack[size];
|
||||
}
|
||||
|
||||
public void setSize(int size)
|
||||
{
|
||||
stacks = new ItemStack[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackInSlot(int slot, ItemStack stack)
|
||||
{
|
||||
validateSlotIndex(slot);
|
||||
if (ItemStack.areItemStacksEqual(this.stacks[slot], stack))
|
||||
return;
|
||||
this.stacks[slot] = stack;
|
||||
onContentsChanged(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots()
|
||||
{
|
||||
return stacks.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
validateSlotIndex(slot);
|
||||
return this.stacks[slot];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
if (stack == null || stack.stackSize == 0)
|
||||
return null;
|
||||
|
||||
validateSlotIndex(slot);
|
||||
|
||||
ItemStack existing = this.stacks[slot];
|
||||
|
||||
int limit = getStackLimit(slot, stack);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
if (!ItemHandlerHelper.canItemStacksStack(stack, existing))
|
||||
return stack;
|
||||
|
||||
limit -= existing.stackSize;
|
||||
}
|
||||
|
||||
if (limit <= 0)
|
||||
return stack;
|
||||
|
||||
boolean reachedLimit = stack.stackSize > limit;
|
||||
|
||||
if (!simulate)
|
||||
{
|
||||
if (existing == null)
|
||||
{
|
||||
this.stacks[slot] = reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, limit) : stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.stackSize += reachedLimit ? limit : stack.stackSize;
|
||||
}
|
||||
onContentsChanged(slot);
|
||||
}
|
||||
|
||||
return reachedLimit ? ItemHandlerHelper.copyStackWithSize(stack, stack.stackSize - limit) : null;
|
||||
}
|
||||
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate)
|
||||
{
|
||||
if (amount == 0)
|
||||
return null;
|
||||
|
||||
validateSlotIndex(slot);
|
||||
|
||||
ItemStack existing = this.stacks[slot];
|
||||
|
||||
if (existing == null)
|
||||
return null;
|
||||
|
||||
int toExtract = Math.min(amount, existing.getMaxStackSize());
|
||||
|
||||
if (existing.stackSize <= toExtract)
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
this.stacks[slot] = null;
|
||||
onContentsChanged(slot);
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
this.stacks[slot] = ItemHandlerHelper.copyStackWithSize(existing, existing.stackSize - toExtract);
|
||||
onContentsChanged(slot);
|
||||
}
|
||||
|
||||
return ItemHandlerHelper.copyStackWithSize(existing, toExtract);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getStackLimit(int slot, ItemStack stack)
|
||||
{
|
||||
return stack.getMaxStackSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound serializeNBT()
|
||||
{
|
||||
NBTTagList nbtTagList = new NBTTagList();
|
||||
for (int i = 0; i < stacks.length; i++)
|
||||
{
|
||||
if (stacks[i] != null)
|
||||
{
|
||||
NBTTagCompound itemTag = new NBTTagCompound();
|
||||
itemTag.setInteger("Slot", i);
|
||||
stacks[i].writeToNBT(itemTag);
|
||||
nbtTagList.appendTag(itemTag);
|
||||
}
|
||||
}
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setTag("Items", nbtTagList);
|
||||
nbt.setInteger("Size", stacks.length);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(NBTTagCompound nbt)
|
||||
{
|
||||
setSize(nbt.hasKey("Size", Constants.NBT.TAG_INT) ? nbt.getInteger("Size") : stacks.length);
|
||||
NBTTagList tagList = nbt.getTagList("Items", Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < tagList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound itemTags = tagList.getCompoundTagAt(i);
|
||||
int slot = itemTags.getInteger("Slot");
|
||||
|
||||
if (slot >= 0 && slot < stacks.length)
|
||||
{
|
||||
stacks[slot] = ItemStack.loadItemStackFromNBT(itemTags);
|
||||
}
|
||||
}
|
||||
onLoad();
|
||||
}
|
||||
|
||||
protected void validateSlotIndex(int slot)
|
||||
{
|
||||
if (slot < 0 || slot >= stacks.length)
|
||||
throw new RuntimeException("Slot " + slot + " not in valid range - [0," + stacks.length + ")");
|
||||
}
|
||||
|
||||
protected void onLoad()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void onContentsChanged(int slot)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
75
src/main/java/net/minecraftforge/items/SlotItemHandler.java
Normal file
75
src/main/java/net/minecraftforge/items/SlotItemHandler.java
Normal file
|
@ -0,0 +1,75 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.InventoryBasic;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class SlotItemHandler extends Slot
|
||||
{
|
||||
private static IInventory emptyInventory = new InventoryBasic("[Null]", true, 0);
|
||||
public final IItemHandler itemHandler;
|
||||
private final int index;
|
||||
|
||||
public SlotItemHandler(IItemHandler itemHandler, int index, int xPosition, int yPosition)
|
||||
{
|
||||
super(emptyInventory, index, xPosition, yPosition);
|
||||
this.itemHandler = itemHandler;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(ItemStack stack)
|
||||
{
|
||||
if (stack == null)
|
||||
return false;
|
||||
ItemStack remainder = this.itemHandler.insertItem(index, stack, true);
|
||||
return remainder == null || remainder.stackSize < stack.stackSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack()
|
||||
{
|
||||
return this.itemHandler.getStackInSlot(index);
|
||||
}
|
||||
|
||||
// Override if your IItemHandler does not implement IItemHandlerModifiable
|
||||
@Override
|
||||
public void putStack(ItemStack stack)
|
||||
{
|
||||
((IItemHandlerModifiable) this.itemHandler).setStackInSlot(index, stack);
|
||||
this.onSlotChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlotChange(ItemStack p_75220_1_, ItemStack p_75220_2_)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemStackLimit(ItemStack stack)
|
||||
{
|
||||
ItemStack maxAdd = stack.copy();
|
||||
maxAdd.stackSize = maxAdd.getMaxStackSize();
|
||||
ItemStack currentStack = this.itemHandler.getStackInSlot(index);
|
||||
ItemStack remainder = this.itemHandler.insertItem(index, maxAdd, true);
|
||||
|
||||
int current = currentStack == null ? 0 : currentStack.stackSize;
|
||||
int added = maxAdd.stackSize - (remainder != null ? remainder.stackSize : 0);
|
||||
return current + added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeStack(EntityPlayer playerIn)
|
||||
{
|
||||
return this.itemHandler.extractItem(index, 1, true) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int amount)
|
||||
{
|
||||
return this.itemHandler.extractItem(index, amount, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityChest;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
public class VanillaDoubleChestItemHandler extends WeakReference<TileEntityChest> implements IItemHandler
|
||||
{
|
||||
// Dummy cache value to signify that we have checked and definitely found no adjacent chests
|
||||
public static final VanillaDoubleChestItemHandler NO_ADJACENT_CHESTS_INSTANCE = new VanillaDoubleChestItemHandler(null, null, false);
|
||||
private final boolean mainChestIsUpper;
|
||||
private final TileEntityChest mainChest;
|
||||
private final int hashCode;
|
||||
|
||||
public VanillaDoubleChestItemHandler(TileEntityChest mainChest, TileEntityChest other, boolean mainChestIsUpper)
|
||||
{
|
||||
super(other);
|
||||
this.mainChest = mainChest;
|
||||
this.mainChestIsUpper = mainChestIsUpper;
|
||||
hashCode = Objects.hashCode(mainChestIsUpper ? mainChest : other) * 31 + Objects.hashCode(!mainChestIsUpper ? mainChest : other);
|
||||
}
|
||||
|
||||
public static VanillaDoubleChestItemHandler get(TileEntityChest chest)
|
||||
{
|
||||
World world = chest.getWorld();
|
||||
BlockPos pos = chest.getPos();
|
||||
if (world == null || pos == null || !world.isBlockLoaded(pos))
|
||||
return null; // Still loading
|
||||
|
||||
Block blockType = chest.getBlockType();
|
||||
|
||||
EnumFacing[] horizontals = EnumFacing.HORIZONTALS;
|
||||
for (int i = horizontals.length - 1; i >= 0; i--) // Use reverse order so we can return early
|
||||
{
|
||||
EnumFacing enumfacing = horizontals[i];
|
||||
BlockPos blockpos = pos.offset(enumfacing);
|
||||
Block block = world.getBlockState(blockpos).getBlock();
|
||||
|
||||
if (block == blockType)
|
||||
{
|
||||
TileEntity otherTE = world.getTileEntity(blockpos);
|
||||
|
||||
if (otherTE instanceof TileEntityChest)
|
||||
{
|
||||
TileEntityChest otherChest = (TileEntityChest) otherTE;
|
||||
return new VanillaDoubleChestItemHandler(chest, otherChest,
|
||||
enumfacing != net.minecraft.util.EnumFacing.WEST && enumfacing != net.minecraft.util.EnumFacing.NORTH);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO_ADJACENT_CHESTS_INSTANCE; //All alone
|
||||
}
|
||||
|
||||
public TileEntityChest getChest(boolean accessingUpper)
|
||||
{
|
||||
if (accessingUpper == mainChestIsUpper)
|
||||
return mainChest;
|
||||
else
|
||||
{
|
||||
return getOtherChest();
|
||||
}
|
||||
}
|
||||
|
||||
private TileEntityChest getOtherChest()
|
||||
{
|
||||
TileEntityChest tileEntityChest = get();
|
||||
return tileEntityChest != null && !tileEntityChest.isInvalid() ? tileEntityChest : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots()
|
||||
{
|
||||
return 27 * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
boolean accessingUpperChest = slot < 27;
|
||||
int targetSlot = accessingUpperChest ? slot : slot - 27;
|
||||
TileEntityChest chest = getChest(accessingUpperChest);
|
||||
return chest != null ? chest.getStackInSlot(targetSlot) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
boolean accessingUpperChest = slot < 27;
|
||||
int targetSlot = accessingUpperChest ? slot : slot - 27;
|
||||
TileEntityChest chest = getChest(accessingUpperChest);
|
||||
return chest != null ? chest.getSingleChestHandler().insertItem(targetSlot, stack, simulate) : stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate)
|
||||
{
|
||||
boolean accessingUpperChest = slot < 27;
|
||||
int targetSlot = accessingUpperChest ? slot : slot - 27;
|
||||
TileEntityChest chest = getChest(accessingUpperChest);
|
||||
return chest != null ? chest.getSingleChestHandler().extractItem(targetSlot, amount, simulate) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
VanillaDoubleChestItemHandler that = (VanillaDoubleChestItemHandler) o;
|
||||
|
||||
if (hashCode != that.hashCode)
|
||||
return false;
|
||||
|
||||
final TileEntityChest otherChest = getOtherChest();
|
||||
if (mainChestIsUpper == that.mainChestIsUpper)
|
||||
return Objects.equals(mainChest, that.mainChest) && Objects.equals(otherChest, that.getOtherChest());
|
||||
else
|
||||
return Objects.equals(mainChest, that.getOtherChest()) && Objects.equals(otherChest, that.mainChest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public boolean needsRefresh()
|
||||
{
|
||||
if (this == NO_ADJACENT_CHESTS_INSTANCE)
|
||||
return false;
|
||||
TileEntityChest tileEntityChest = get();
|
||||
return tileEntityChest == null || tileEntityChest.isInvalid();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntityHopper;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
public class VanillaHopperItemHandler extends InvWrapper
|
||||
{
|
||||
private final TileEntityHopper hopper;
|
||||
|
||||
public VanillaHopperItemHandler(TileEntityHopper hopper)
|
||||
{
|
||||
super(hopper);
|
||||
this.hopper = hopper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
if (stack == null)
|
||||
return null;
|
||||
if (simulate || !hopper.mayTransfer())
|
||||
return super.insertItem(slot, stack, simulate);
|
||||
|
||||
int curStackSize = stack.stackSize;
|
||||
ItemStack itemStack = super.insertItem(slot, stack, false);
|
||||
if (itemStack == null || curStackSize != itemStack.stackSize)
|
||||
{
|
||||
hopper.setTransferCooldown(8);
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package net.minecraftforge.items;
|
||||
|
||||
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.BlockPos;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class VanillaInventoryCodeHooks
|
||||
{
|
||||
|
||||
public static boolean extractHook(IHopper dest)
|
||||
{
|
||||
TileEntity tileEntity = dest.getWorld().getTileEntity(new BlockPos(dest.getXPos(), dest.getYPos() + 1, dest.getZPos()));
|
||||
|
||||
if (tileEntity == null || !tileEntity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN))
|
||||
return false;
|
||||
|
||||
IItemHandler handler = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
|
||||
|
||||
for (int i = 0; i < handler.getSlots(); i++)
|
||||
{
|
||||
ItemStack extractItem = handler.extractItem(i, 1, true);
|
||||
if (extractItem != null)
|
||||
{
|
||||
for (int j = 0; j < dest.getSizeInventory(); j++)
|
||||
{
|
||||
ItemStack destStack = dest.getStackInSlot(j);
|
||||
if (destStack == null || destStack.stackSize < destStack.getMaxStackSize() || ItemHandlerHelper.canItemStacksStack(extractItem, destStack))
|
||||
{
|
||||
extractItem = handler.extractItem(i, 1, false);
|
||||
if (destStack == null)
|
||||
dest.setInventorySlotContents(j, extractItem);
|
||||
else
|
||||
{
|
||||
destStack.stackSize++;
|
||||
dest.setInventorySlotContents(j, destStack);
|
||||
}
|
||||
dest.markDirty();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean dropperInsertHook(World world, BlockPos pos, TileEntityDispenser dropper, int slot, ItemStack stack)
|
||||
{
|
||||
EnumFacing enumfacing = world.getBlockState(pos).getValue(BlockDropper.FACING);
|
||||
BlockPos offsetPos = pos.offset(enumfacing);
|
||||
TileEntity tileEntity = world.getTileEntity(offsetPos);
|
||||
if (tileEntity == null)
|
||||
return false;
|
||||
if (!tileEntity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, enumfacing.getOpposite()))
|
||||
return true;
|
||||
|
||||
IItemHandler capability = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, enumfacing.getOpposite());
|
||||
|
||||
ItemStack result = ItemHandlerHelper.insertItem(capability, ItemHandlerHelper.copyStackWithSize(stack, 1), false);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
result = stack.copy();
|
||||
|
||||
if (--result.stackSize == 0)
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = stack.copy();
|
||||
}
|
||||
dropper.setInventorySlotContents(slot, result);
|
||||
dropper.markDirty();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean insertHook(TileEntityHopper hopper)
|
||||
{
|
||||
return insertHook(hopper, BlockHopper.getFacing(hopper.getBlockMetadata()));
|
||||
}
|
||||
|
||||
public static boolean insertHook(IHopper hopper, EnumFacing facing)
|
||||
{
|
||||
TileEntity tileEntity = hopper.getWorld().getTileEntity(
|
||||
new BlockPos(hopper.getXPos(), hopper.getYPos(), hopper.getZPos()).offset(facing));
|
||||
|
||||
if (tileEntity == null)
|
||||
return false;
|
||||
if (!tileEntity.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()))
|
||||
return false;
|
||||
|
||||
IItemHandler handler = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite());
|
||||
|
||||
for (int i = 0; i < hopper.getSizeInventory(); i++)
|
||||
{
|
||||
ItemStack stackInSlot = hopper.getStackInSlot(i);
|
||||
if (stackInSlot != null)
|
||||
{
|
||||
ItemStack insert = stackInSlot.copy();
|
||||
insert.stackSize = 1;
|
||||
ItemStack newStack = ItemHandlerHelper.insertItem(handler, insert, true);
|
||||
if (newStack == null || newStack.stackSize == 0)
|
||||
{
|
||||
ItemHandlerHelper.insertItem(handler, hopper.decrStackSize(i, 1), false);
|
||||
hopper.markDirty();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package net.minecraftforge.items.wrapper;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class EmptyHandler implements IItemHandler
|
||||
{
|
||||
public static IItemHandler INSTANCE = new EmptyHandler();
|
||||
|
||||
@Override
|
||||
public int getSlots()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
166
src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java
Normal file
166
src/main/java/net/minecraftforge/items/wrapper/InvWrapper.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
package net.minecraftforge.items.wrapper;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class InvWrapper implements IItemHandlerModifiable
|
||||
{
|
||||
public final IInventory inv;
|
||||
|
||||
public InvWrapper(IInventory inv)
|
||||
{
|
||||
this.inv = inv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
InvWrapper that = (InvWrapper) o;
|
||||
|
||||
return inv.equals(that.inv);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return inv.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots()
|
||||
{
|
||||
return inv.getSizeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
return inv.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
if (stack == null)
|
||||
return null;
|
||||
|
||||
if (!inv.isItemValidForSlot(slot, stack))
|
||||
return stack;
|
||||
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
|
||||
int m;
|
||||
if (stackInSlot != null)
|
||||
{
|
||||
if (!ItemHandlerHelper.canItemStacksStack(stack, stackInSlot))
|
||||
return stack;
|
||||
|
||||
m = Math.min(stack.getMaxStackSize(), inv.getInventoryStackLimit()) - stackInSlot.stackSize;
|
||||
|
||||
if (stack.stackSize <= m)
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
ItemStack copy = stack.copy();
|
||||
copy.stackSize += stackInSlot.stackSize;
|
||||
inv.setInventorySlotContents(slot, copy);
|
||||
inv.markDirty();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
ItemStack copy = stack.splitStack(m);
|
||||
copy.stackSize += stackInSlot.stackSize;
|
||||
inv.setInventorySlotContents(slot, copy);
|
||||
inv.markDirty();
|
||||
return stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.stackSize -= m;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m = Math.min(stack.getMaxStackSize(), inv.getInventoryStackLimit());
|
||||
if (m < stack.stackSize)
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
inv.setInventorySlotContents(slot, stack.splitStack(m));
|
||||
inv.markDirty();
|
||||
return stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.stackSize -= m;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
inv.setInventorySlotContents(slot, stack);
|
||||
inv.markDirty();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate)
|
||||
{
|
||||
if (amount == 0)
|
||||
return null;
|
||||
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
|
||||
if (stackInSlot == null)
|
||||
return null;
|
||||
|
||||
if (simulate)
|
||||
{
|
||||
if (stackInSlot.stackSize < amount)
|
||||
{
|
||||
return stackInSlot.copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack copy = stackInSlot.copy();
|
||||
copy.stackSize = amount;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int m = Math.min(stackInSlot.stackSize, amount);
|
||||
|
||||
ItemStack decrStackSize = inv.decrStackSize(slot, m);
|
||||
inv.markDirty();
|
||||
return decrStackSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackInSlot(int slot, ItemStack stack)
|
||||
{
|
||||
inv.setInventorySlotContents(slot, stack);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package net.minecraftforge.items.wrapper;
|
||||
|
||||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class SidedInvWrapper implements IItemHandlerModifiable
|
||||
{
|
||||
protected final ISidedInventory inv;
|
||||
protected final EnumFacing side;
|
||||
|
||||
public SidedInvWrapper(ISidedInventory inv, EnumFacing side)
|
||||
{
|
||||
this.inv = inv;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public static int getSlot(ISidedInventory inv, int slot, EnumFacing side)
|
||||
{
|
||||
int[] slots = inv.getSlotsForFace(side);
|
||||
if (slot < slots.length)
|
||||
return slots[slot];
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
SidedInvWrapper that = (SidedInvWrapper) o;
|
||||
|
||||
return inv.equals(that.inv) && side == that.side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int result = inv.hashCode();
|
||||
result = 31 * result + side.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots()
|
||||
{
|
||||
return inv.getSlotsForFace(side).length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
int i = getSlot(inv, slot, side);
|
||||
return i == -1 ? null : inv.getStackInSlot(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate)
|
||||
{
|
||||
|
||||
if (stack == null)
|
||||
return null;
|
||||
|
||||
int slot1 = getSlot(inv, slot, side);
|
||||
|
||||
if (slot1 == -1)
|
||||
return stack;
|
||||
|
||||
if (!inv.isItemValidForSlot(slot1, stack) || !inv.canInsertItem(slot1, stack, side))
|
||||
return stack;
|
||||
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot1);
|
||||
|
||||
int m;
|
||||
if (stackInSlot != null)
|
||||
{
|
||||
if (!ItemHandlerHelper.canItemStacksStack(stack, stackInSlot))
|
||||
return stack;
|
||||
|
||||
m = Math.min(stack.getMaxStackSize(), inv.getInventoryStackLimit()) - stackInSlot.stackSize;
|
||||
|
||||
if (stack.stackSize <= m)
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
ItemStack copy = stack.copy();
|
||||
copy.stackSize += stackInSlot.stackSize;
|
||||
inv.setInventorySlotContents(slot1, copy);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
ItemStack copy = stack.splitStack(m);
|
||||
copy.stackSize += stackInSlot.stackSize;
|
||||
inv.setInventorySlotContents(slot1, copy);
|
||||
return stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.stackSize -= m;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m = Math.min(stack.getMaxStackSize(), inv.getInventoryStackLimit());
|
||||
if (m < stack.stackSize)
|
||||
{
|
||||
if (!simulate)
|
||||
{
|
||||
inv.setInventorySlotContents(slot1, stack.splitStack(m));
|
||||
return stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
stack.stackSize -= m;
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!simulate)
|
||||
inv.setInventorySlotContents(slot1, stack);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStackInSlot(int slot, ItemStack stack)
|
||||
{
|
||||
inv.setInventorySlotContents(slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate)
|
||||
{
|
||||
if (amount == 0)
|
||||
return null;
|
||||
|
||||
int slot1 = getSlot(inv, slot, side);
|
||||
|
||||
if (slot1 == -1)
|
||||
return null;
|
||||
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot1);
|
||||
|
||||
if (stackInSlot == null)
|
||||
return null;
|
||||
|
||||
if (!inv.canExtractItem(slot1, stackInSlot, side))
|
||||
return null;
|
||||
|
||||
if (simulate)
|
||||
{
|
||||
if (stackInSlot.stackSize < amount)
|
||||
{
|
||||
return stackInSlot.copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack copy = stackInSlot.copy();
|
||||
copy.stackSize = amount;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int m = Math.min(stackInSlot.stackSize, amount);
|
||||
return inv.decrStackSize(slot1, m);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue