package openperipheral.integration.vanilla; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.List; import java.util.Map; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.ForgeDirection; import openmods.inventory.legacy.ItemDistribution; import openmods.utils.InventoryUtils; import openperipheral.api.Constants; import openperipheral.api.adapter.Asynchronous; import openperipheral.api.adapter.IPeripheralAdapter; import openperipheral.api.adapter.method.Arg; import openperipheral.api.adapter.method.Env; import openperipheral.api.adapter.method.Optionals; import openperipheral.api.adapter.method.ReturnType; import openperipheral.api.adapter.method.ScriptCallable; import openperipheral.api.architecture.FeatureGroup; import openperipheral.api.architecture.IArchitecture; import openperipheral.api.helpers.Index; import openperipheral.integration.OpcAccess; @Asynchronous @FeatureGroup("vanilla-inventory") public class AdapterInventory implements IPeripheralAdapter { private static final int ANY_SLOT = -1; @Override public Class<?> getTargetClass() { return IInventory.class; } @Override public String getSourceId() { return "inventory"; } @ScriptCallable(returnTypes = ReturnType.STRING, description = "Get the name of this inventory") public String getInventoryName(IInventory target) { IInventory inventory = InventoryUtils.getInventory(target); return inventory != null? inventory.getInventoryName() : null; } @ScriptCallable(returnTypes = ReturnType.NUMBER, description = "Get the size of this inventory") public int getInventorySize(IInventory target) { IInventory inventory = InventoryUtils.getInventory(target); return inventory != null? inventory.getSizeInventory() : 0; } @Asynchronous(false) @ScriptCallable(description = "Condense and tidy the stacks in an inventory") public void condenseItems(IInventory target) { IInventory inventory = InventoryUtils.getInventory(target); List<ItemStack> stacks = Lists.newArrayList(); for (int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack sta = inventory.getStackInSlot(i); if (sta != null) stacks.add(sta.copy()); inventory.setInventorySlotContents(i, null); } for (ItemStack stack : stacks) ItemDistribution.insertItemIntoInventory(inventory, stack, ForgeDirection.UNKNOWN, ANY_SLOT); target.markDirty(); } @Asynchronous(false) @ScriptCallable(description = "Swap two slots in the inventory") public void swapStacks(IInventory target, @Arg(name = "from", description = "The first slot") Index fromSlot, @Arg(name = "to", description = "The other slot") Index intoSlot, @Optionals @Arg(name = "fromDirection") ForgeDirection fromDirection, @Arg(name = "fromDirection") ForgeDirection toDirection) { IInventory inventory = InventoryUtils.getInventory(target); Preconditions.checkNotNull(inventory, "Invalid target!"); final int size = inventory.getSizeInventory(); fromSlot.checkElementIndex("first slot id", size); intoSlot.checkElementIndex("second slot id", size); if (inventory instanceof ISidedInventory) { InventoryUtils.swapStacks((ISidedInventory)inventory, fromSlot.value, Objects.firstNonNull(fromDirection, ForgeDirection.UNKNOWN), intoSlot.value, Objects.firstNonNull(toDirection, ForgeDirection.UNKNOWN)); } else InventoryUtils.swapStacks(inventory, fromSlot.value, intoSlot.value); inventory.markDirty(); } @ScriptCallable(returnTypes = ReturnType.OBJECT, description = "Get details of an item in a particular slot") public Object getStackInSlot(IInventory target, @Arg(name = "slotNumber", description = "Slot number") Index slot, @Optionals @Arg(name = "proxy", description = "If true, method will return proxy instead of computing whole table") Boolean proxy) { IInventory inventory = InventoryUtils.getInventory(target); slot.checkElementIndex("slot id", inventory.getSizeInventory()); ItemStack stack = inventory.getStackInSlot(slot.value); return proxy == Boolean.TRUE? OpcAccess.itemStackMetaBuilder.createProxy(stack) : stack; } @ScriptCallable(returnTypes = ReturnType.TABLE, description = "Get a table with all the items of the chest") public Map<Index, Object> getAllStacks(IInventory target, @Env(Constants.ARG_ARCHITECTURE) IArchitecture access, @Optionals @Arg(name = "proxy", description = "If false, method will compute whole table, instead of returning proxy") Boolean proxy) { final IInventory inventory = InventoryUtils.getInventory(target); Map<Index, Object> result = Maps.newHashMap(); for (int i = 0; i < inventory.getSizeInventory(); i++) { ItemStack stack = inventory.getStackInSlot(i); if (stack != null) result.put(access.createIndex(i), (proxy != Boolean.FALSE)? OpcAccess.itemStackMetaBuilder.createProxy(stack) : stack); } return result; } @Asynchronous(false) @ScriptCallable(description = "Destroy a stack") public void destroyStack(IInventory target, @Arg(name = "slotNumber", description = "The slot number") Index slot) { IInventory inventory = InventoryUtils.getInventory(target); slot.checkElementIndex("slot id", inventory.getSizeInventory()); inventory.setInventorySlotContents(slot.value, null); inventory.markDirty(); } @ScriptCallable(returnTypes = ReturnType.TABLE, description = "Get full stack information from id and/or damage") public ItemStack expandStack(IInventory target, @Arg(name = "stack") ItemStack itemStack) { return itemStack; } }