diff --git a/src/main/java/refinedstorage/api/storage/item/IGroupedItemStorage.java b/src/main/java/refinedstorage/api/storage/item/IGroupedItemStorage.java index 6e6bd8bc5..b1c2292d7 100755 --- a/src/main/java/refinedstorage/api/storage/item/IGroupedItemStorage.java +++ b/src/main/java/refinedstorage/api/storage/item/IGroupedItemStorage.java @@ -64,6 +64,13 @@ public interface IGroupedItemStorage { @Nullable ItemStack get(int hash); + /** + * Copies a grouped item storage. + * + * @return the storage + */ + IGroupedItemStorage copy(); + /** * @return all items in this storage network */ diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/v2/CraftingTask.java b/src/main/java/refinedstorage/apiimpl/autocrafting/v2/CraftingTask.java index 1c57409b7..55307e736 100755 --- a/src/main/java/refinedstorage/apiimpl/autocrafting/v2/CraftingTask.java +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/v2/CraftingTask.java @@ -4,10 +4,12 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.NetworkUtils; import refinedstorage.api.storage.CompareUtils; +import refinedstorage.api.storage.item.IGroupedItemStorage; import java.util.ArrayDeque; import java.util.Deque; @@ -19,6 +21,7 @@ public class CraftingTask { private Deque toTake = new ArrayDeque<>(); private Multimap toCraft = ArrayListMultimap.create(); private Multimap missing = ArrayListMultimap.create(); + private Multimap extras = ArrayListMultimap.create(); public CraftingTask(INetworkMaster network, ICraftingPattern pattern, int quantity) { this.network = network; @@ -31,30 +34,44 @@ public class CraftingTask { } private void calculate(ICraftingPattern pattern, boolean basePattern) { + IGroupedItemStorage itemStorage = network.getItemStorage().copy(); + for (int i = 0; i < quantity; ++i) { for (ItemStack input : pattern.getInputs()) { - ItemStack inputInNetwork = network.getItemStorage().get(input, CompareUtils.COMPARE_DAMAGE | CompareUtils.COMPARE_NBT); + ItemStack inputInNetwork = itemStorage.get(input, CompareUtils.COMPARE_DAMAGE | CompareUtils.COMPARE_NBT); if (inputInNetwork == null || inputInNetwork.stackSize == 0) { - ICraftingPattern inputPattern = NetworkUtils.getPattern(network, input); - - if (inputPattern != null) { - addToCraft(input); - - calculate(inputPattern, false); + if (getExtrasFor(input) != null) { + decrOrRemoveExtras(input); } else { - addMissing(input); + ICraftingPattern inputPattern = NetworkUtils.getPattern(network, input); + + if (inputPattern != null) { + for (ItemStack output : inputPattern.getOutputs()) { + addToCraft(output); + } + + calculate(inputPattern, false); + } else { + addMissing(input); + } } } else { toTake.push(input); + + itemStorage.remove(input); } } + + if (!basePattern) { + pattern.getOutputs().stream().filter(o -> o.stackSize > 1).forEach(o -> addExtras(ItemHandlerHelper.copyStackWithSize(o, o.stackSize - 1))); + } } } @Override public String toString() { - return "quantity=" + quantity + ",toTake=" + toTake.toString() + ",toCraft=" + toCraft.toString() + ",missing=" + missing.toString(); + return "{quantity=" + quantity + ",toTake=" + toTake.toString() + ",toCraft=" + toCraft.toString() + ",missing=" + missing.toString() + "}"; } public boolean update() { @@ -95,6 +112,36 @@ public class CraftingTask { missing.put(stack.getItem(), stack.copy()); } + private void addExtras(ItemStack stack) { + ItemStack extras = getExtrasFor(stack); + + if (extras != null) { + extras.stackSize += stack.stackSize; + } else { + this.extras.put(stack.getItem(), stack.copy()); + } + } + + private ItemStack getExtrasFor(ItemStack stack) { + for (ItemStack m : extras.get(stack.getItem())) { + if (CompareUtils.compareStackNoQuantity(m, stack)) { + return m; + } + } + + return null; + } + + private void decrOrRemoveExtras(ItemStack stack) { + ItemStack extras = getExtrasFor(stack); + + extras.stackSize--; + + if (extras.stackSize == 0) { + this.extras.remove(extras.getItem(), extras); + } + } + private void addToCraft(ItemStack stack) { for (ItemStack m : toCraft.get(stack.getItem())) { if (CompareUtils.compareStackNoQuantity(m, stack)) { diff --git a/src/main/java/refinedstorage/apiimpl/storage/item/GroupedItemStorage.java b/src/main/java/refinedstorage/apiimpl/storage/item/GroupedItemStorage.java index 8fc055d89..8d9778ed6 100755 --- a/src/main/java/refinedstorage/apiimpl/storage/item/GroupedItemStorage.java +++ b/src/main/java/refinedstorage/apiimpl/storage/item/GroupedItemStorage.java @@ -118,6 +118,19 @@ public class GroupedItemStorage implements IGroupedItemStorage { return null; } + @Override + public IGroupedItemStorage copy() { + GroupedItemStorage copy = new GroupedItemStorage(network); + + copy.storages = storages; + + for (ItemStack stack : stacks.values()) { + copy.stacks.put(stack.getItem(), stack.copy()); + } + + return copy; + } + @Override public Collection getStacks() { return stacks.values();