implementation of #704, crafting tasks now balace over patterns
This commit is contained in:
@@ -39,6 +39,16 @@ public interface ICraftingManager {
|
|||||||
*/
|
*/
|
||||||
ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity);
|
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.
|
* 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
|
* @return the pattern, or null if the pattern is not found
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@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.
|
* Returns a crafting pattern for an item stack.
|
||||||
@@ -98,10 +111,38 @@ public interface ICraftingManager {
|
|||||||
* @param pattern the stack to get a pattern for
|
* @param pattern the stack to get a pattern for
|
||||||
* @return the pattern, or null if the pattern is not found
|
* @return the pattern, or null if the pattern is not found
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
default ICraftingPattern getPattern(ItemStack pattern) {
|
default ICraftingPattern getPattern(ItemStack pattern) {
|
||||||
return getPattern(pattern, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT);
|
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.
|
* 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
|
* @return true if there is a pattern, false otherwise
|
||||||
*/
|
*/
|
||||||
default boolean hasPattern(ItemStack stack) {
|
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 update();
|
||||||
|
|
||||||
void readFromNBT(NBTTagCompound tag);
|
void readFromNBT(NBTTagCompound tag);
|
||||||
|
|||||||
@@ -105,4 +105,13 @@ public interface ICraftingPattern {
|
|||||||
* @return the actual {@link ItemStack} with quantity
|
* @return the actual {@link ItemStack} with quantity
|
||||||
*/
|
*/
|
||||||
ItemStack getActualOutput(ItemStack requested, int compare);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<ICraftingPattern> {
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.raoulvdberge.refinedstorage.api.autocrafting.registry;
|
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.ICraftingPattern;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
|
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -18,7 +18,6 @@ public interface ICraftingTaskFactory {
|
|||||||
/**
|
/**
|
||||||
* Returns a crafting task for a given NBT tag and pattern.
|
* Returns a crafting task for a given NBT tag and pattern.
|
||||||
*
|
*
|
||||||
* @param world the world
|
|
||||||
* @param network the network
|
* @param network the network
|
||||||
* @param stack the stack to create task for
|
* @param stack the stack to create task for
|
||||||
* @param pattern the pattern
|
* @param pattern the pattern
|
||||||
@@ -27,5 +26,17 @@ public interface ICraftingTaskFactory {
|
|||||||
* @return the crafting task
|
* @return the crafting task
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting;
|
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.ICraftingManager;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
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.autocrafting.task.ICraftingTask;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
|
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
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.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
@@ -18,7 +20,6 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
private TileController network;
|
private TileController network;
|
||||||
|
|
||||||
private List<ICraftingPattern> patterns = new ArrayList<>();
|
private CraftingPatternChainList patterns = new CraftingPatternChainList();
|
||||||
|
|
||||||
private List<ICraftingTask> craftingTasks = new ArrayList<>();
|
private List<ICraftingTask> craftingTasks = new ArrayList<>();
|
||||||
private List<ICraftingTask> craftingTasksToAdd = new ArrayList<>();
|
private List<ICraftingTask> craftingTasksToAdd = new ArrayList<>();
|
||||||
@@ -66,37 +67,58 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICraftingTask create(@Nullable ItemStack stack, ICraftingPattern pattern, int quantity) {
|
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
|
@Override
|
||||||
public List<ICraftingPattern> getPatterns() {
|
public List<ICraftingPattern> getPatterns() {
|
||||||
return patterns;
|
return patterns.asList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ICraftingPattern> getPatterns(ItemStack pattern, int flags) {
|
public List<ICraftingPattern> getPatterns(ItemStack pattern, int flags) {
|
||||||
List<ICraftingPattern> patterns = new ArrayList<>();
|
return getPatternChains(pattern, flags).stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
for (ICraftingPattern craftingPattern : getPatterns()) {
|
private List<ICraftingPatternChain> getPatternChains(ItemStack pattern, int flags) {
|
||||||
for (ItemStack output : craftingPattern.getOutputs()) {
|
List<ICraftingPatternChain> patternChains = new LinkedList<>();
|
||||||
|
|
||||||
|
for (CraftingPatternChainList.CraftingPatternChain chain : this.patterns) {
|
||||||
|
for (ItemStack output : chain.getPrototype().getOutputs()) {
|
||||||
if (API.instance().getComparer().isEqual(output, pattern, flags)) {
|
if (API.instance().getComparer().isEqual(output, pattern, flags)) {
|
||||||
patterns.add(craftingPattern);
|
patternChains.add(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return patterns;
|
return patternChains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICraftingPattern getPattern(ItemStack pattern, int flags) {
|
public boolean hasPattern(ItemStack stack, int flags) {
|
||||||
List<ICraftingPattern> patterns = getPatterns(pattern, 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<ICraftingPatternChain> patternChains = getPatternChains(pattern, flags);
|
||||||
|
|
||||||
|
if (patternChains.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else if (patterns.size() == 1) {
|
} else if (patternChains.size() == 1) {
|
||||||
return patterns.get(0);
|
return patternChains.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int highestScore = 0;
|
int highestScore = 0;
|
||||||
@@ -104,12 +126,12 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
IStackList<ItemStack> itemList = network.getItemStorageCache().getList().getOredicted();
|
IStackList<ItemStack> itemList = network.getItemStorageCache().getList().getOredicted();
|
||||||
|
|
||||||
for (int i = 0; i < patterns.size(); ++i) {
|
for (int i = 0; i < patternChains.size(); ++i) {
|
||||||
int score = 0;
|
int score = 0;
|
||||||
|
|
||||||
for (ItemStack input : patterns.get(i).getInputs()) {
|
for (ItemStack input : patternChains.get(i).getPrototype().getInputs()) {
|
||||||
if (input != null) {
|
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;
|
score += stored != null ? stored.getCount() : 0;
|
||||||
}
|
}
|
||||||
@@ -121,14 +143,14 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return patterns.get(highestPattern);
|
return patternChains.get(highestPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
if (!craftingTasksToRead.isEmpty()) {
|
if (!craftingTasksToRead.isEmpty()) {
|
||||||
for (NBTTagCompound tag : craftingTasksToRead) {
|
for (NBTTagCompound tag : craftingTasksToRead) {
|
||||||
ICraftingTask task = readCraftingTask(network.getNetworkWorld(), network, tag);
|
ICraftingTask task = readCraftingTask(network, tag);
|
||||||
|
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
add(task);
|
add(task);
|
||||||
@@ -207,10 +229,10 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (toSchedule > 0) {
|
if (toSchedule > 0) {
|
||||||
ICraftingPattern pattern = getPattern(stack, compare);
|
ICraftingPatternChain patternChain = getPatternChain(stack, compare);
|
||||||
|
|
||||||
if (pattern != null) {
|
if (patternChain != null) {
|
||||||
ICraftingTask task = create(stack, pattern, toSchedule);
|
ICraftingTask task = create(stack, patternChain, toSchedule);
|
||||||
|
|
||||||
task.calculate();
|
task.calculate();
|
||||||
task.getMissing().clear();
|
task.getMissing().clear();
|
||||||
@@ -245,24 +267,26 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
for (INetworkNode node : network.getNodeGraph().all()) {
|
for (INetworkNode node : network.getNodeGraph().all()) {
|
||||||
if (node instanceof ICraftingPatternContainer && node.canUpdate()) {
|
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));
|
ItemStack stack = new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_PATTERN_STACK));
|
||||||
|
|
||||||
if (!stack.isEmpty() && stack.getItem() instanceof ICraftingPatternProvider) {
|
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) {
|
if (container instanceof INetworkNodeProxy) {
|
||||||
ICraftingPattern pattern = ((ICraftingPatternProvider) stack.getItem()).create(world, stack, (ICraftingPatternContainer) container);
|
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));
|
ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().get(tag.getString(ICraftingTask.NBT_PATTERN_ID));
|
||||||
|
|
||||||
if (factory != null) {
|
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);
|
return factory.create(network, tag.hasKey(ICraftingTask.NBT_REQUESTED) ? new ItemStack(tag.getCompoundTag(ICraftingTask.NBT_REQUESTED)) : null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,4 +278,41 @@ public class CraftingPattern implements ICraftingPattern {
|
|||||||
", byproducts=" + byproducts +
|
", 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<ItemStack> otherList = other.getOreInputs().get(i);
|
||||||
|
List<ItemStack> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<CraftingPatternChainList.CraftingPatternChain> {
|
||||||
|
LinkedList<CraftingPatternChain> 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<ICraftingPattern> patterns) {
|
||||||
|
patterns.forEach(this::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ICraftingPattern> asList() {
|
||||||
|
return innerChain.stream().flatMap(Collection::stream).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<CraftingPatternChain> iterator() {
|
||||||
|
return innerChain.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
innerChain.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CraftingPatternChain implements ICraftingPatternChain {
|
||||||
|
private LinkedList<ICraftingPattern> 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<ICraftingPattern> iterator() {
|
||||||
|
return innerList.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
return innerList.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> 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<? extends ICraftingPattern> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
|
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RSUtils;
|
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.ICraftingPattern;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep;
|
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.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ public class CraftingTaskFactory implements ICraftingTaskFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@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) {
|
if (tag != null) {
|
||||||
NBTTagList stepsList = tag.getTagList(CraftingTask.NBT_STEPS, Constants.NBT.TAG_COMPOUND);
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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.ICraftingStep;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||||
import com.raoulvdberge.refinedstorage.api.network.INetworkMaster;
|
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.IComparer;
|
||||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||||
@@ -53,8 +54,10 @@ public abstract class CraftingStep implements ICraftingStep {
|
|||||||
if (!patternStack.isEmpty()) {
|
if (!patternStack.isEmpty()) {
|
||||||
TileEntity container = network.getNetworkWorld().getTileEntity(BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER)));
|
TileEntity container = network.getNetworkWorld().getTileEntity(BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER)));
|
||||||
|
|
||||||
if (container instanceof ICraftingPatternContainer) {
|
if (container instanceof INetworkNodeProxy) {
|
||||||
this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.getNetworkWorld(), patternStack, (ICraftingPatternContainer) container);
|
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());
|
this.satisfied = new HashMap<>(pattern.getOutputs().size());
|
||||||
|
|
||||||
for (ItemStack stack : pattern.getOutputs()) {
|
for (ItemStack stack : pattern.getOutputs()) {
|
||||||
@@ -83,6 +86,7 @@ public abstract class CraftingStep implements ICraftingStep {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.RSUtils;
|
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.ICraftingPattern;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
|
||||||
@@ -42,6 +43,7 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private ItemStack requested;
|
private ItemStack requested;
|
||||||
private ICraftingPattern pattern;
|
private ICraftingPattern pattern;
|
||||||
|
private ICraftingPatternChain chain;
|
||||||
private int quantity;
|
private int quantity;
|
||||||
private List<ICraftingStep> mainSteps = new LinkedList<>();
|
private List<ICraftingStep> mainSteps = new LinkedList<>();
|
||||||
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
|
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
|
||||||
@@ -60,6 +62,11 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
this.quantity = quantity;
|
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<ICraftingStep> mainSteps, Deque<ItemStack> toInsertItems, IStackList<FluidStack> toTakeFluids, Deque<FluidStack> toInsertFluids) {
|
public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, List<ICraftingStep> mainSteps, Deque<ItemStack> toInsertItems, IStackList<FluidStack> toTakeFluids, Deque<FluidStack> toInsertFluids) {
|
||||||
this(network, requested, pattern, quantity);
|
this(network, requested, pattern, quantity);
|
||||||
this.mainSteps = mainSteps;
|
this.mainSteps = mainSteps;
|
||||||
@@ -82,9 +89,11 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
|
|
||||||
int quantity = this.quantity;
|
int quantity = this.quantity;
|
||||||
|
|
||||||
|
ICraftingPattern currentPattern;
|
||||||
while (quantity > 0 && !recurseFound) {
|
while (quantity > 0 && !recurseFound) {
|
||||||
mainSteps.add(calculate(networkList, networkFluidList, pattern, toInsert));
|
currentPattern = this.chain == null ? this.pattern : this.chain.cycle();
|
||||||
quantity -= pattern.getQuantityPerRequest(requested);
|
mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert));
|
||||||
|
quantity -= currentPattern.getQuantityPerRequest(requested);
|
||||||
}
|
}
|
||||||
|
|
||||||
usedPatterns.clear();
|
usedPatterns.clear();
|
||||||
@@ -124,7 +133,7 @@ public class CraftingTask implements ICraftingTask {
|
|||||||
|
|
||||||
extraStack = toInsert.get(input, compare);
|
extraStack = toInsert.get(input, compare);
|
||||||
networkStack = networkList.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()) {
|
if (i == inputs.size()) {
|
||||||
input = inputs.get(0).copy();
|
input = inputs.get(0).copy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ public class ItemGridHandler implements IItemGridHandler {
|
|||||||
|
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
Thread calculationThread = new Thread(() -> {
|
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();
|
task.calculate();
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ public class ItemGridHandler implements IItemGridHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack != null) {
|
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();
|
task.calculate();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user