/**
* Copyright (c) 2011-2015, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
* <p/>
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.lib.inventory;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.api.core.IInvSlot;
import buildcraft.core.lib.inventory.filters.IStackFilter;
public class TransactorSimple extends Transactor {
protected IInventory inventory;
public TransactorSimple(IInventory inventory) {
this.inventory = inventory;
}
@Override
public int inject(ItemStack stack, ForgeDirection orientation, boolean doAdd) {
List<IInvSlot> filledSlots = new ArrayList<IInvSlot>(inventory.getSizeInventory());
List<IInvSlot> emptySlots = new ArrayList<IInvSlot>(inventory.getSizeInventory());
for (IInvSlot slot : InventoryIterator.getIterable(inventory, orientation)) {
if (slot.canPutStackInSlot(stack)) {
if (slot.getStackInSlot() == null) {
emptySlots.add(slot);
} else {
filledSlots.add(slot);
}
}
}
int injected = 0;
injected = tryPut(stack, filledSlots, injected, doAdd);
injected = tryPut(stack, emptySlots, injected, doAdd);
if (injected > 0 && doAdd) {
inventory.markDirty();
}
return injected;
}
private int tryPut(ItemStack stack, List<IInvSlot> slots, int injected, boolean doAdd) {
int realInjected = injected;
if (realInjected >= stack.stackSize) {
return realInjected;
}
for (IInvSlot slot : slots) {
ItemStack stackInSlot = slot.getStackInSlot();
if (stackInSlot == null || StackHelper.canStacksMerge(stackInSlot, stack)) {
int used = addToSlot(slot, stack, realInjected, doAdd);
if (used > 0) {
realInjected += used;
if (realInjected >= stack.stackSize) {
return realInjected;
}
}
}
}
return realInjected;
}
/**
*
* @param slot
* @param stack
* @param injected Amount not to move?
* @param doAdd
* @return Return the number of items moved.
*/
protected int addToSlot(IInvSlot slot, ItemStack stack, int injected, boolean doAdd) {
int available = stack.stackSize - injected;
int max = Math.min(stack.getMaxStackSize(), inventory.getInventoryStackLimit());
ItemStack stackInSlot = slot.getStackInSlot();
if (stackInSlot == null) {
int wanted = Math.min(available, max);
if (doAdd) {
stackInSlot = stack.copy();
stackInSlot.stackSize = wanted;
slot.setStackInSlot(stackInSlot);
}
return wanted;
}
if (!StackHelper.canStacksMerge(stack, stackInSlot)) {
return 0;
}
int wanted = max - stackInSlot.stackSize;
if (wanted <= 0) {
return 0;
}
if (wanted > available) {
wanted = available;
}
if (doAdd) {
stackInSlot.stackSize += wanted;
slot.setStackInSlot(stackInSlot);
}
return wanted;
}
@Override
public ItemStack remove(IStackFilter filter, ForgeDirection orientation, boolean doRemove) {
for (IInvSlot slot : InventoryIterator.getIterable(inventory, orientation)) {
ItemStack stack = slot.getStackInSlot();
if (stack != null && slot.canTakeStackFromSlot(stack) && filter.matches(stack)) {
if (doRemove) {
return slot.decreaseStackInSlot(1);
} else {
ItemStack output = stack.copy();
output.stackSize = 1;
return output;
}
}
}
return null;
}
}