From aedaa0740765ef09eab10aab9a6b1a390fd77596 Mon Sep 17 00:00:00 2001 From: way2muchnoise Date: Wed, 4 Jan 2017 16:29:54 +0100 Subject: [PATCH] implementation of #704, crafting tasks now balace over patterns --- .../api/autocrafting/ICraftingManager.java | 54 +++++++- .../api/autocrafting/ICraftingPattern.java | 9 ++ .../autocrafting/ICraftingPatternChain.java | 32 +++++ .../registry/ICraftingTaskFactory.java | 17 ++- .../apiimpl/autocrafting/CraftingManager.java | 86 +++++++----- .../apiimpl/autocrafting/CraftingPattern.java | 37 +++++ .../CraftingPatternChainList.java | 128 ++++++++++++++++++ .../registry/CraftingTaskFactory.java | 10 +- .../autocrafting/task/CraftingStep.java | 42 +++--- .../autocrafting/task/CraftingTask.java | 15 +- .../apiimpl/network/grid/ItemGridHandler.java | 4 +- 11 files changed, 372 insertions(+), 62 deletions(-) create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternChain.java create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java index 82b8825a4..e06970e8a 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java @@ -39,6 +39,16 @@ public interface ICraftingManager { */ ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity); + /** + * Creates a crafting task. + * + * @param stack the stack to create a task for + * @param patternChain the pattern + * @param quantity the quantity + * @return the crafting task + */ + ICraftingTask create(@Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity); + /** * Schedules a crafting task if the task isn't scheduled yet. * @@ -87,7 +97,10 @@ public interface ICraftingManager { * @return the pattern, or null if the pattern is not found */ @Nullable - ICraftingPattern getPattern(ItemStack pattern, int flags); + default ICraftingPattern getPattern(ItemStack pattern, int flags) { + ICraftingPatternChain chain = getPatternChain(pattern, flags); + return chain == null ? null : chain.cycle(); + } /** * Returns a crafting pattern for an item stack. @@ -98,10 +111,38 @@ public interface ICraftingManager { * @param pattern the stack to get a pattern for * @return the pattern, or null if the pattern is not found */ + @Nullable default ICraftingPattern getPattern(ItemStack pattern) { return getPattern(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT); } + /** + * Returns a crafting pattern chain for an item stack. + * This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}. + * Internally, this makes a selection out of the available patterns. + * It makes this selection based on the item count of the pattern outputs in the system. + * + * @param pattern the stack to get a pattern for + * @param flags the flags to compare on, see {@link IComparer} + * @return the pattern chain, or null if the pattern chain is not found + */ + @Nullable + ICraftingPatternChain getPatternChain(ItemStack pattern, int flags); + + /** + * Returns a crafting pattern for an item stack. + * This returns a single crafting pattern, as opposed to {@link ICraftingManager#getPatterns(ItemStack, int)}. + * Internally, this makes a selection out of the available patterns. + * It makes this selection based on the item count of the pattern outputs in the system. + * + * @param pattern the stack to get a pattern for + * @return the pattern chain, or null if the pattern chain is not found + */ + @Nullable + default ICraftingPatternChain getPatternChain(ItemStack pattern) { + return getPatternChain(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT); + } + /** * Returns if there is a pattern with a given stack as output. * @@ -109,9 +150,18 @@ public interface ICraftingManager { * @return true if there is a pattern, false otherwise */ default boolean hasPattern(ItemStack stack) { - return getPattern(stack) != null; + return hasPattern(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT); } + /** + * Returns if there is a pattern with a given stack as output. + * + * @param stack the stack + * @param flags the flags to compare on, see {@link IComparer} + * @return true if there is a pattern, false otherwise + */ + boolean hasPattern(ItemStack stack, int flags); + void update(); void readFromNBT(NBTTagCompound tag); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java index bf028f39b..085d26bfe 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java @@ -105,4 +105,13 @@ public interface ICraftingPattern { * @return the actual {@link ItemStack} with quantity */ ItemStack getActualOutput(ItemStack requested, int compare); + + /** + * Compares with an other pattern if it is alike + * Used to balance out {@link com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep}s over alike {@link ICraftingPattern}s + * + * @param pattern the {@link ICraftingPattern} to compare against + * @return true if the patterns are alike + */ + boolean alike(ICraftingPattern pattern); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternChain.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternChain.java new file mode 100644 index 000000000..4e267029c --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternChain.java @@ -0,0 +1,32 @@ +package com.raoulvdberge.refinedstorage.api.autocrafting; + +import java.util.Collection; + +/** + * Represents a chain of {@link ICraftingPattern}s, used to balance crafts over those patterns + */ +public interface ICraftingPatternChain extends Collection { + /** + * Check whether a pattern belongs in the chain + * + * @param compare the {@link ICraftingPattern} to check + * @return true if the chains {@link #getPrototype()} is {@link ICraftingPattern#alike(ICraftingPattern)} + */ + default boolean isValidForChain(ICraftingPattern compare) { + return getPrototype() == compare || getPrototype().alike(compare); + } + + /** + * Cycles the list and returns use you the pattern that was used the longest time ago + * + * @return an {@link ICraftingPattern} + */ + ICraftingPattern cycle(); + + /** + * The prototype used for this {@link ICraftingPatternChain} + * + * @return an {@link ICraftingPattern} that represents all patterns in the chain + */ + ICraftingPattern getPrototype(); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/registry/ICraftingTaskFactory.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/registry/ICraftingTaskFactory.java index 84dc58320..7a5585f0f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/registry/ICraftingTaskFactory.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/registry/ICraftingTaskFactory.java @@ -1,11 +1,11 @@ package com.raoulvdberge.refinedstorage.api.autocrafting.registry; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -18,7 +18,6 @@ public interface ICraftingTaskFactory { /** * Returns a crafting task for a given NBT tag and pattern. * - * @param world the world * @param network the network * @param stack the stack to create task for * @param pattern the pattern @@ -27,5 +26,17 @@ public interface ICraftingTaskFactory { * @return the crafting task */ @Nonnull - ICraftingTask create(World world, INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag); + ICraftingTask create(INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag); + + /** + * Returns a crafting task for a given NBT tag and pattern. + * + * @param network the network + * @param stack the stack to create task for + * @param patternChain the patternChain + * @param quantity the quantity + * @return the crafting task + */ + @Nonnull + ICraftingTask create(INetworkMaster network, @Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java index 03af990d3..2c666097d 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer; @@ -9,6 +10,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -18,7 +20,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import net.minecraftforge.items.ItemHandlerHelper; @@ -32,7 +33,7 @@ public class CraftingManager implements ICraftingManager { private TileController network; - private List patterns = new ArrayList<>(); + private CraftingPatternChainList patterns = new CraftingPatternChainList(); private List craftingTasks = new ArrayList<>(); private List craftingTasksToAdd = new ArrayList<>(); @@ -66,37 +67,58 @@ public class CraftingManager implements ICraftingManager { @Override public ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity) { - return API.instance().getCraftingTaskRegistry().get(pattern.getId()).create(network.getNetworkWorld(), network, stack, pattern, quantity, null); + return API.instance().getCraftingTaskRegistry().get(pattern.getId()).create(network, stack, pattern, quantity, null); + } + + @Override + public ICraftingTask create(@Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity) { + return API.instance().getCraftingTaskRegistry().get(patternChain.getPrototype().getId()).create( network, stack, patternChain, quantity); } @Override public List getPatterns() { - return patterns; + return patterns.asList(); } @Override public List getPatterns(ItemStack pattern, int flags) { - List patterns = new ArrayList<>(); + return getPatternChains(pattern, flags).stream().flatMap(Collection::stream).collect(Collectors.toList()); + } - for (ICraftingPattern craftingPattern : getPatterns()) { - for (ItemStack output : craftingPattern.getOutputs()) { + private List getPatternChains(ItemStack pattern, int flags) { + List patternChains = new LinkedList<>(); + + for (CraftingPatternChainList.CraftingPatternChain chain : this.patterns) { + for (ItemStack output : chain.getPrototype().getOutputs()) { if (API.instance().getComparer().isEqual(output, pattern, flags)) { - patterns.add(craftingPattern); + patternChains.add(chain); } } } - return patterns; + return patternChains; } @Override - public ICraftingPattern getPattern(ItemStack pattern, int flags) { - List patterns = getPatterns(pattern, flags); + public boolean hasPattern(ItemStack stack, int flags) { + for (CraftingPatternChainList.CraftingPatternChain chain : this.patterns) { + for (ItemStack output : chain.getPrototype().getOutputs()) { + if (API.instance().getComparer().isEqual(output, stack, flags)) { + return true; + } + } + } + return false; + } - if (patterns.isEmpty()) { + @Override + public ICraftingPatternChain getPatternChain(ItemStack pattern, int flags) { + List patternChains = getPatternChains(pattern, flags); + + if (patternChains.isEmpty()) { return null; - } else if (patterns.size() == 1) { - return patterns.get(0); + } else if (patternChains.size() == 1) { + return patternChains.get(0); } int highestScore = 0; @@ -104,12 +126,12 @@ public class CraftingManager implements ICraftingManager { IStackList itemList = network.getItemStorageCache().getList().getOredicted(); - for (int i = 0; i < patterns.size(); ++i) { + for (int i = 0; i < patternChains.size(); ++i) { int score = 0; - for (ItemStack input : patterns.get(i).getInputs()) { + for (ItemStack input : patternChains.get(i).getPrototype().getInputs()) { if (input != null) { - ItemStack stored = itemList.get(input, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | (patterns.get(i).isOredict() ? IComparer.COMPARE_OREDICT : 0)); + ItemStack stored = itemList.get(input, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | (patternChains.get(i).getPrototype().isOredict() ? IComparer.COMPARE_OREDICT : 0)); score += stored != null ? stored.getCount() : 0; } @@ -121,14 +143,14 @@ public class CraftingManager implements ICraftingManager { } } - return patterns.get(highestPattern); + return patternChains.get(highestPattern); } @Override public void update() { if (!craftingTasksToRead.isEmpty()) { for (NBTTagCompound tag : craftingTasksToRead) { - ICraftingTask task = readCraftingTask(network.getNetworkWorld(), network, tag); + ICraftingTask task = readCraftingTask(network, tag); if (task != null) { add(task); @@ -207,10 +229,10 @@ public class CraftingManager implements ICraftingManager { } if (toSchedule > 0) { - ICraftingPattern pattern = getPattern(stack, compare); + ICraftingPatternChain patternChain = getPatternChain(stack, compare); - if (pattern != null) { - ICraftingTask task = create(stack, pattern, toSchedule); + if (patternChain != null) { + ICraftingTask task = create(stack, patternChain, toSchedule); task.calculate(); task.getMissing().clear(); @@ -245,24 +267,26 @@ public class CraftingManager implements ICraftingManager { for (INetworkNode node : network.getNodeGraph().all()) { if (node instanceof ICraftingPatternContainer && node.canUpdate()) { - patterns.addAll(((ICraftingPatternContainer) node).getPatterns()); + patterns.addAll((((ICraftingPatternContainer) node).getPatterns())); } } } - private static ICraftingTask readCraftingTask(World world, INetworkMaster network, NBTTagCompound tag) { + private static ICraftingTask readCraftingTask(INetworkMaster network, NBTTagCompound tag) { ItemStack stack = new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_PATTERN_STACK)); if (!stack.isEmpty() && stack.getItem() instanceof ICraftingPatternProvider) { - TileEntity container = world.getTileEntity(BlockPos.fromLong(tag.getLong(ICraftingTask.NBT_PATTERN_CONTAINER))); + TileEntity container = network.getNetworkWorld().getTileEntity(BlockPos.fromLong(tag.getLong(ICraftingTask.NBT_PATTERN_CONTAINER))); - if (container instanceof ICraftingPatternContainer) { - ICraftingPattern pattern = ((ICraftingPatternProvider) stack.getItem()).create(world, stack, (ICraftingPatternContainer) container); + if (container instanceof INetworkNodeProxy) { + INetworkNodeProxy proxy = (INetworkNodeProxy) container; + if (proxy.getNode() instanceof ICraftingPatternContainer) { + ICraftingPattern pattern = ((ICraftingPatternProvider) stack.getItem()).create(network.getNetworkWorld(), stack, (ICraftingPatternContainer) proxy.getNode()); - ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(tag.getString(ICraftingTask.NBT_PATTERN_ID)); - - if (factory != null) { - return factory.create(world, network, tag.hasKey(ICraftingTask.NBT_REQUESTED) ? new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_REQUESTED)) : null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), tag); + ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(tag.getString(ICraftingTask.NBT_PATTERN_ID)); + if (factory != null) { + return factory.create(network, tag.hasKey(ICraftingTask.NBT_REQUESTED) ? new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_REQUESTED)) : null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), tag); + } } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java index 9a7e3e14e..ab092b5b5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java @@ -278,4 +278,41 @@ public class CraftingPattern implements ICraftingPattern { ", byproducts=" + byproducts + '}'; } + + @Override + public boolean alike(ICraftingPattern other) { + if (other == this) { + return true; + } + + if (other.getId().equals(this.getId()) + && other.isOredict() == this.isOredict() + && other.isBlocking() == this.isBlocking() + && other.isProcessing() == this.isProcessing() + && other.getOreInputs().size() == this.getOreInputs().size() + && other.getOutputs().size() == this.getOutputs().size()) { + boolean same = true; + for (int i = 0; i < other.getOreInputs().size(); i++) { + same &= other.getOreInputs().get(i).size() == this.getOreInputs().get(i).size(); + } + int j = 0; + while (same && j < other.getOutputs().size()) { + same = ItemStack.areItemStacksEqual(other.getOutputs().get(j), this.getOutputs().get(j)); + j++; + } + int i = 0; + while (same && i < other.getOreInputs().size()) { + List otherList = other.getOreInputs().get(i); + List thisList = this.getOreInputs().get(i); + j = 0; + while (same && j < otherList.size()) { + same = ItemStack.areItemStacksEqual(otherList.get(j), thisList.get(j)); + j++; + } + i++; + } + return same; + } + return false; + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java new file mode 100644 index 000000000..5a3216c59 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPatternChainList.java @@ -0,0 +1,128 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting; + +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +public class CraftingPatternChainList implements Iterable { + LinkedList innerChain = new LinkedList<>(); + + public void add(ICraftingPattern pattern) { + int i = 0; + while (i < innerChain.size() && !innerChain.get(i).add(pattern)) { + i++; + } + if (i == innerChain.size()) { + innerChain.add(new CraftingPatternChain(pattern)); + } + } + + public void addAll(Collection patterns) { + patterns.forEach(this::add); + } + + public List asList() { + return innerChain.stream().flatMap(Collection::stream).collect(Collectors.toList()); + } + + @Override + public Iterator iterator() { + return innerChain.iterator(); + } + + public void clear() { + innerChain.clear(); + } + + public static class CraftingPatternChain implements ICraftingPatternChain { + private LinkedList innerList; + private ICraftingPattern prototype; + + public CraftingPatternChain(ICraftingPattern prototype) { + this.prototype = prototype; + this.innerList = new LinkedList<>(); + this.innerList.add(prototype); + } + + public ICraftingPattern cycle() { + ICraftingPattern front = innerList.poll(); + innerList.addLast(front); + return front; + } + + public ICraftingPattern getPrototype() { + return prototype; + } + + @Override + public int size() { + return innerList.size(); + } + + @Override + public boolean isEmpty() { + return innerList.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return innerList.contains(o); + } + + @Override + public Iterator iterator() { + return innerList.iterator(); + } + + @Override + public Object[] toArray() { + return innerList.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return innerList.toArray(a); + } + + @Override + public boolean add(ICraftingPattern iCraftingPattern) { + return isValidForChain(iCraftingPattern) && innerList.add(iCraftingPattern); + } + + @Override + public boolean remove(Object o) { + return innerList.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return innerList.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + c.removeIf(p -> !isValidForChain(p)); + return innerList.addAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return innerList.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return innerList.retainAll(c); + } + + @Override + public void clear() { + innerList.clear(); + } + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java index 71891ccd8..da146d4c5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java @@ -1,6 +1,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry; import com.raoulvdberge.refinedstorage.RSUtils; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep; @@ -12,7 +13,6 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; @@ -28,7 +28,7 @@ public class CraftingTaskFactory implements ICraftingTaskFactory { @Override @Nonnull - public ICraftingTask create(World world, INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag) { + public ICraftingTask create(INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag) { if (tag != null) { NBTTagList stepsList = tag.getTagList(CraftingTask.NBT_STEPS, Constants.NBT.TAG_COMPOUND); @@ -75,4 +75,10 @@ public class CraftingTaskFactory implements ICraftingTaskFactory { return new CraftingTask(network, stack, pattern, quantity); } + + @Nonnull + @Override + public ICraftingTask create(INetworkMaster network, @Nullable ItemStack stack, ICraftingPatternChain patternChain, int quantity) { + return new CraftingTask(network, stack, patternChain, quantity); + } } \ No newline at end of file diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java index b34721322..604ceb02e 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java @@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternProvider import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; +import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -53,34 +54,37 @@ public abstract class CraftingStep implements ICraftingStep { if (!patternStack.isEmpty()) { TileEntity container = network.getNetworkWorld().getTileEntity(BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER))); - if (container instanceof ICraftingPatternContainer) { - this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.getNetworkWorld(), patternStack, (ICraftingPatternContainer) container); - this.satisfied = new HashMap<>(pattern.getOutputs().size()); + if (container instanceof INetworkNodeProxy) { + INetworkNodeProxy proxy = (INetworkNodeProxy) container; + if (proxy.getNode() instanceof ICraftingPatternContainer) { + this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.getNetworkWorld(), patternStack, (ICraftingPatternContainer) proxy.getNode()); + this.satisfied = new HashMap<>(pattern.getOutputs().size()); - for (ItemStack stack : pattern.getOutputs()) { - int hashcode = API.instance().getItemStackHashCode(stack); - String id = String.format(NBT_SATISFIED, hashcode); + for (ItemStack stack : pattern.getOutputs()) { + int hashcode = API.instance().getItemStackHashCode(stack); + String id = String.format(NBT_SATISFIED, hashcode); - if (tag.hasKey(id)) { - this.satisfied.put(hashcode, tag.getInteger(id)); + if (tag.hasKey(id)) { + this.satisfied.put(hashcode, tag.getInteger(id)); + } } - } - this.startedProcessing = tag.getBoolean(NBT_STARTED_PROCESSING); + this.startedProcessing = tag.getBoolean(NBT_STARTED_PROCESSING); - NBTTagList preliminaryTagList = tag.getTagList(NBT_PRELIMINARY_STEPS, Constants.NBT.TAG_COMPOUND); - this.preliminarySteps = new LinkedList<>(); - for (int i = 0; i < preliminaryTagList.tagCount(); i++) { - NBTTagCompound stepTag = preliminaryTagList.getCompoundTagAt(i); + NBTTagList preliminaryTagList = tag.getTagList(NBT_PRELIMINARY_STEPS, Constants.NBT.TAG_COMPOUND); + this.preliminarySteps = new LinkedList<>(); + for (int i = 0; i < preliminaryTagList.tagCount(); i++) { + NBTTagCompound stepTag = preliminaryTagList.getCompoundTagAt(i); - ICraftingStep step = CraftingStep.toCraftingStep(stepTag, network); + ICraftingStep step = CraftingStep.toCraftingStep(stepTag, network); - if (step != null) { - this.preliminarySteps.add(step); + if (step != null) { + this.preliminarySteps.add(step); + } } - } - return true; + return true; + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index a027106d7..926beb2c0 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -1,6 +1,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; import com.raoulvdberge.refinedstorage.RSUtils; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; @@ -42,6 +43,7 @@ public class CraftingTask implements ICraftingTask { @Nullable private ItemStack requested; private ICraftingPattern pattern; + private ICraftingPatternChain chain; private int quantity; private List mainSteps = new LinkedList<>(); private IStackList toTake = API.instance().createItemStackList(); @@ -60,6 +62,11 @@ public class CraftingTask implements ICraftingTask { this.quantity = quantity; } + public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPatternChain chain, int quantity) { + this(network, requested, chain.getPrototype(), quantity); + this.chain = chain; + } + public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, List mainSteps, Deque toInsertItems, IStackList toTakeFluids, Deque toInsertFluids) { this(network, requested, pattern, quantity); this.mainSteps = mainSteps; @@ -82,9 +89,11 @@ public class CraftingTask implements ICraftingTask { int quantity = this.quantity; + ICraftingPattern currentPattern; while (quantity > 0 && !recurseFound) { - mainSteps.add(calculate(networkList, networkFluidList, pattern, toInsert)); - quantity -= pattern.getQuantityPerRequest(requested); + currentPattern = this.chain == null ? this.pattern : this.chain.cycle(); + mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert)); + quantity -= currentPattern.getQuantityPerRequest(requested); } usedPatterns.clear(); @@ -124,7 +133,7 @@ public class CraftingTask implements ICraftingTask { extraStack = toInsert.get(input, compare); networkStack = networkList.get(input, compare); - } while (extraStack == null && networkStack == null && ++i < inputs.size() && network.getCraftingManager().getPatterns(input, compare).isEmpty()); + } while (extraStack == null && networkStack == null && ++i < inputs.size() && network.getCraftingManager().hasPattern(input, compare)); if (i == inputs.size()) { input = inputs.get(0).copy(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/ItemGridHandler.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/ItemGridHandler.java index e3f426a37..dee3ed19b 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/ItemGridHandler.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/ItemGridHandler.java @@ -168,7 +168,7 @@ public class ItemGridHandler implements IItemGridHandler { if (stack != null) { Thread calculationThread = new Thread(() -> { - ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPattern(stack), quantity); + ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPatternChain(stack), quantity); task.calculate(); @@ -186,7 +186,7 @@ public class ItemGridHandler implements IItemGridHandler { } if (stack != null) { - ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPattern(stack), quantity); + ICraftingTask task = new CraftingTask(network, stack, network.getCraftingManager().getPatternChain(stack), quantity); task.calculate();