Formatting changes and minor renaming in autocrafting

This commit is contained in:
raoulvdberge
2017-11-29 22:21:20 +01:00
parent 74ae66d247
commit ad51a75847
10 changed files with 270 additions and 130 deletions

View File

@@ -19,9 +19,9 @@ public interface ICraftingStep {
ICraftingPattern getPattern(); ICraftingPattern getPattern();
/** /**
* @return the stacks to insert * @return the input stacks
*/ */
List<ItemStack> getToInsert(); List<ItemStack> getInputs();
/** /**
* @return a list of steps the have to be done before this one can be started * @return a list of steps the have to be done before this one can be started

View File

@@ -55,6 +55,7 @@ public class CraftingPattern implements ICraftingPattern {
for (IRecipe r : CraftingManager.REGISTRY) { for (IRecipe r : CraftingManager.REGISTRY) {
if (r.matches(inv, world)) { if (r.matches(inv, world)) {
recipe = r; recipe = r;
break; break;
} }
} }
@@ -86,7 +87,7 @@ public class CraftingPattern implements ICraftingPattern {
} }
for (ItemStack remaining : recipe.getRemainingItems(inv)) { for (ItemStack remaining : recipe.getRemainingItems(inv)) {
if (remaining != null) { if (!remaining.isEmpty()) {
ItemStack cleaned = Comparer.stripTags(remaining.copy()); ItemStack cleaned = Comparer.stripTags(remaining.copy());
byproducts.add(cleaned); byproducts.add(cleaned);
} }
@@ -94,34 +95,34 @@ public class CraftingPattern implements ICraftingPattern {
} }
} }
} else { } else {
outputs = ItemPattern.getOutputs(stack).stream().collect(Collectors.toList()); outputs = ItemPattern.getOutputs(stack);
}
if (oreInputs.isEmpty()) { if (oreInputs.isEmpty()) {
for (ItemStack input : inputs) { for (ItemStack input : inputs) {
if (input == null) { if (input == null) {
oreInputs.add(Collections.emptyList()); oreInputs.add(Collections.emptyList());
} else if (!input.isEmpty()) { } else if (!input.isEmpty()) {
int[] ids = OreDictionary.getOreIDs(input); int[] ids = OreDictionary.getOreIDs(input);
if (ids == null || ids.length == 0) {
oreInputs.add(Collections.singletonList(Comparer.stripTags(input))); if (ids.length == 0) {
} else if (isOredict()) { oreInputs.add(Collections.singletonList(Comparer.stripTags(input)));
List<ItemStack> oredict = Arrays.stream(ids) } else if (isOredict()) {
.mapToObj(OreDictionary::getOreName) List<ItemStack> oredict = Arrays.stream(ids)
.map(OreDictionary::getOres) .mapToObj(OreDictionary::getOreName)
.flatMap(List::stream) .map(OreDictionary::getOres)
.map(ItemStack::copy) .flatMap(List::stream)
.map(Comparer::stripTags) .map(ItemStack::copy)
.map(s -> { .map(Comparer::stripTags)
s.setCount(input.getCount()); .peek(s -> s.setCount(input.getCount()))
return s; .collect(Collectors.toList());
})
.collect(Collectors.toList()); // Add original stack as first, should prevent some issues
// Add original stack as first, should prevent some issues oredict.add(0, Comparer.stripTags(input.copy()));
oredict.add(0, Comparer.stripTags(input.copy()));
oreInputs.add(oredict); oreInputs.add(oredict);
} else { } else {
oreInputs.add(Collections.singletonList(Comparer.stripTags(input))); oreInputs.add(Collections.singletonList(Comparer.stripTags(input)));
}
} }
} }
} }
@@ -218,7 +219,7 @@ public class CraftingPattern implements ICraftingPattern {
} }
for (ItemStack remaining : recipe.getRemainingItems(inv)) { for (ItemStack remaining : recipe.getRemainingItems(inv)) {
if (remaining != null) { if (!remaining.isEmpty()) {
byproducts.add(remaining.copy()); byproducts.add(remaining.copy());
} }
} }

View File

@@ -20,8 +20,8 @@ public class CraftingPreviewElementFluidStack implements ICraftingPreviewElement
private FluidStack stack; private FluidStack stack;
private int available; private int available;
private boolean missing; private boolean missing;
// If missing is true then toCraft is the missing amount
private int toCraft; private int toCraft;
// if missing is true then toCraft is the missing amount
public CraftingPreviewElementFluidStack(FluidStack stack) { public CraftingPreviewElementFluidStack(FluidStack stack) {
this.stack = stack.copy(); this.stack = stack.copy();
@@ -65,8 +65,10 @@ public class CraftingPreviewElementFluidStack implements ICraftingPreviewElement
if (missing) { if (missing) {
drawers.getOverlayDrawer().draw(x, y, 0xFFF2DEDE); drawers.getOverlayDrawer().draw(x, y, 0xFFF2DEDE);
} }
x += 5; x += 5;
y += 7; y += 7;
drawers.getFluidDrawer().draw(x, y, getElement()); drawers.getFluidDrawer().draw(x, y, getElement());
float scale = drawers.getFontRenderer().getUnicodeFlag() ? 1F : 0.5F; float scale = drawers.getFontRenderer().getUnicodeFlag() ? 1F : 0.5F;

View File

@@ -20,8 +20,8 @@ public class CraftingPreviewElementItemStack implements ICraftingPreviewElement<
private ItemStack stack; private ItemStack stack;
private int available; private int available;
private boolean missing; private boolean missing;
// If missing is true then toCraft is the missing amount
private int toCraft; private int toCraft;
// if missing is true then toCraft is the missing amount
public CraftingPreviewElementItemStack(ItemStack stack) { public CraftingPreviewElementItemStack(ItemStack stack) {
this.stack = ItemHandlerHelper.copyStackWithSize(stack, 1); this.stack = ItemHandlerHelper.copyStackWithSize(stack, 1);
@@ -54,6 +54,7 @@ public class CraftingPreviewElementItemStack implements ICraftingPreviewElement<
ItemStack stack = new ItemStack(item, 1, meta); ItemStack stack = new ItemStack(item, 1, meta);
stack.setTagCompound(tag); stack.setTagCompound(tag);
return new CraftingPreviewElementItemStack(stack, available, missing, toCraft); return new CraftingPreviewElementItemStack(stack, available, missing, toCraft);
} }

View File

@@ -21,6 +21,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -34,7 +35,9 @@ public abstract class CraftingStep implements ICraftingStep {
protected INetwork network; protected INetwork network;
protected ICraftingPattern pattern; protected ICraftingPattern pattern;
protected Map<Integer, Integer> satisfied; protected Map<Integer, Integer> satisfied;
protected boolean startedProcessing; protected boolean startedProcessing;
protected List<ICraftingStep> preliminarySteps; protected List<ICraftingStep> preliminarySteps;
@@ -57,12 +60,14 @@ public abstract class CraftingStep implements ICraftingStep {
if (container instanceof INetworkNodeProxy) { if (container instanceof INetworkNodeProxy) {
INetworkNodeProxy proxy = (INetworkNodeProxy) container; INetworkNodeProxy proxy = (INetworkNodeProxy) container;
if (proxy.getNode() instanceof ICraftingPatternContainer) { if (proxy.getNode() instanceof ICraftingPatternContainer) {
this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.world(), patternStack, (ICraftingPatternContainer) proxy.getNode()); this.pattern = ((ICraftingPatternProvider) patternStack.getItem()).create(network.world(), 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()) {
int hashcode = API.instance().getItemStackHashCode(stack); int hashcode = API.instance().getItemStackHashCode(stack);
String id = String.format(NBT_SATISFIED, hashcode); String id = String.format(NBT_SATISFIED, hashcode);
if (tag.hasKey(id)) { if (tag.hasKey(id)) {
@@ -73,7 +78,9 @@ public abstract class CraftingStep implements ICraftingStep {
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); NBTTagList preliminaryTagList = tag.getTagList(NBT_PRELIMINARY_STEPS, Constants.NBT.TAG_COMPOUND);
this.preliminarySteps = new LinkedList<>(); this.preliminarySteps = new LinkedList<>();
for (int i = 0; i < preliminaryTagList.tagCount(); i++) { for (int i = 0; i < preliminaryTagList.tagCount(); i++) {
NBTTagCompound stepTag = preliminaryTagList.getCompoundTagAt(i); NBTTagCompound stepTag = preliminaryTagList.getCompoundTagAt(i);
@@ -98,7 +105,7 @@ public abstract class CraftingStep implements ICraftingStep {
} }
@Override @Override
public List<ItemStack> getToInsert() { public List<ItemStack> getInputs() {
return pattern.getInputs().stream().filter(Objects::nonNull).collect(Collectors.toList()); return pattern.getInputs().stream().filter(Objects::nonNull).collect(Collectors.toList());
} }
@@ -112,7 +119,6 @@ public abstract class CraftingStep implements ICraftingStep {
return getPreliminarySteps().size() == 0; return getPreliminarySteps().size() == 0;
} }
@Override @Override
public void setStartedProcessing() { public void setStartedProcessing() {
if (getPattern().isBlocking()) { if (getPattern().isBlocking()) {
@@ -131,6 +137,7 @@ public abstract class CraftingStep implements ICraftingStep {
public boolean hasReceivedOutputs() { public boolean hasReceivedOutputs() {
for (ItemStack stack : pattern.getOutputs()) { for (ItemStack stack : pattern.getOutputs()) {
Integer received = satisfied.get(API.instance().getItemStackHashCode(stack)); Integer received = satisfied.get(API.instance().getItemStackHashCode(stack));
if (received == null || stack.getCount() > received) { if (received == null || stack.getCount() > received) {
return false; return false;
} }
@@ -145,34 +152,40 @@ public abstract class CraftingStep implements ICraftingStep {
@Override @Override
public boolean hasReceivedOutput(ItemStack stack) { public boolean hasReceivedOutput(ItemStack stack) {
Integer received = satisfied.get(API.instance().getItemStackHashCode(stack)); return getReceivedOutput(stack) >= stack.getCount();
return received != null && received >= stack.getCount();
} }
@Override @Override
public int getReceivedOutput(ItemStack stack) { public int getReceivedOutput(ItemStack stack) {
Integer received = satisfied.get(API.instance().getItemStackHashCode(stack)); Integer received = satisfied.get(API.instance().getItemStackHashCode(stack));
return received == null ? 0 : received; return received == null ? 0 : received;
} }
@Override @Override
public boolean onReceiveOutput(ItemStack stack) { public boolean onReceiveOutput(ItemStack stack) {
ItemStack compareStack = Comparer.stripTags(stack.copy()); ItemStack compareStack = Comparer.stripTags(stack.copy());
for (ItemStack output : pattern.getOutputs()) { for (ItemStack output : pattern.getOutputs()) {
int hashcode = API.instance().getItemStackHashCode(output); int hash = API.instance().getItemStackHashCode(output);
Integer received = satisfied.get(hashcode);
Integer received = satisfied.get(hash);
if (received == null) { if (received == null) {
received = 0; received = 0;
} }
if (API.instance().getComparer().isEqual(compareStack, output, CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0))) { if (API.instance().getComparer().isEqual(compareStack, output, CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0))) {
if (received < output.getCount()) { if (received < output.getCount()) {
int toReceive = Math.min(output.getCount() - received, stack.getCount()); int toReceive = Math.min(output.getCount() - received, stack.getCount());
satisfied.put(hashcode, received + toReceive);
satisfied.put(hash, received + toReceive);
stack.shrink(toReceive); stack.shrink(toReceive);
network.markCraftingMonitorForUpdate(); network.markCraftingMonitorForUpdate();
if (stack.getCount() == 0) { if (stack.isEmpty()) {
return true; return true;
} }
} }
@@ -207,6 +220,7 @@ public abstract class CraftingStep implements ICraftingStep {
ITEM, FLUID ITEM, FLUID
} }
@Nullable
protected AvailableType isItemAvailable(IStackList<ItemStack> items, IStackList<FluidStack> fluids, ItemStack stack, ItemStack actualStack, int compare) { protected AvailableType isItemAvailable(IStackList<ItemStack> items, IStackList<FluidStack> fluids, ItemStack stack, ItemStack actualStack, int compare) {
if (actualStack == null || actualStack.isEmpty() || !items.trackedRemove(actualStack, stack.getCount())) { if (actualStack == null || actualStack.isEmpty() || !items.trackedRemove(actualStack, stack.getCount())) {
FluidStack fluidInItem; FluidStack fluidInItem;
@@ -214,56 +228,69 @@ public abstract class CraftingStep implements ICraftingStep {
if (API.instance().getComparer().isEqual(stack, StackUtils.WATER_BOTTLE)) { if (API.instance().getComparer().isEqual(stack, StackUtils.WATER_BOTTLE)) {
FluidStack fluidStack = fluids.get(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), compare); FluidStack fluidStack = fluids.get(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), compare);
ItemStack emptyBottle = items.get(StackUtils.EMPTY_BOTTLE, compare); ItemStack emptyBottle = items.get(StackUtils.EMPTY_BOTTLE, compare);
if (emptyBottle != null && fluidStack != null && !emptyBottle.isEmpty() && items.trackedRemove(StackUtils.EMPTY_BOTTLE, 1)) { if (emptyBottle != null && fluidStack != null && !emptyBottle.isEmpty() && items.trackedRemove(StackUtils.EMPTY_BOTTLE, 1)) {
return AvailableType.FLUID; return AvailableType.FLUID;
} }
} else if ((fluidInItem = StackUtils.getFluid(stack, true).getValue()) != null && StackUtils.hasFluidBucket(fluidInItem)) { } else if ((fluidInItem = StackUtils.getFluid(stack, true).getValue()) != null && StackUtils.hasFluidBucket(fluidInItem)) {
FluidStack fluidStack = fluids.get(fluidInItem, compare); FluidStack fluidStack = fluids.get(fluidInItem, compare);
ItemStack bucket = items.get(StackUtils.EMPTY_BUCKET, compare); ItemStack bucket = items.get(StackUtils.EMPTY_BUCKET, compare);
if (bucket != null && fluidStack != null && !bucket.isEmpty() && fluids.trackedRemove(fluidStack, fluidInItem.amount) && items.trackedRemove(bucket, 1)) { if (bucket != null && fluidStack != null && !bucket.isEmpty() && fluids.trackedRemove(fluidStack, fluidInItem.amount) && items.trackedRemove(bucket, 1)) {
return AvailableType.FLUID; return AvailableType.FLUID;
} }
} }
return null; return null;
} }
return AvailableType.ITEM; return AvailableType.ITEM;
} }
protected boolean extractItems(List<ItemStack> actualInputs, int compare, Deque<ItemStack> toInsertItems) { protected boolean extractItems(List<ItemStack> extractedItems, int compare, Deque<ItemStack> toInsertItems) {
for (ItemStack insertStack : getToInsert()) { for (ItemStack input : getInputs()) {
// This will be a tool, like a hammer // This will be a tool, like a hammer
if (insertStack.isItemStackDamageable()) { if (input.isItemStackDamageable()) {
compare &= ~IComparer.COMPARE_DAMAGE; compare &= ~IComparer.COMPARE_DAMAGE;
} else { } else {
compare |= IComparer.COMPARE_DAMAGE; compare |= IComparer.COMPARE_DAMAGE;
} }
ItemStack input = network.extractItem(insertStack, insertStack.getCount(), compare, false); ItemStack extracted = network.extractItem(input, input.getCount(), compare, false);
if (input != null) {
actualInputs.add(input); if (extracted != null) {
extractedItems.add(extracted);
} else { } else {
boolean abort = true; boolean abort = true;
FluidStack fluidInItem; FluidStack fluidInItem;
if (API.instance().getComparer().isEqual(insertStack, StackUtils.WATER_BOTTLE)) {
if (API.instance().getComparer().isEqual(input, StackUtils.WATER_BOTTLE)) {
FluidStack fluidStack = network.extractFluid(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), Fluid.BUCKET_VOLUME, compare, true); // Simulate is true because we won't actually get the fluid out of the storage for bottles! FluidStack fluidStack = network.extractFluid(new FluidStack(FluidRegistry.WATER, Fluid.BUCKET_VOLUME), Fluid.BUCKET_VOLUME, compare, true); // Simulate is true because we won't actually get the fluid out of the storage for bottles!
ItemStack emptyBottleStack = network.extractItem(StackUtils.EMPTY_BOTTLE, 1, compare, false); ItemStack emptyBottleStack = network.extractItem(StackUtils.EMPTY_BOTTLE, 1, compare, false);
if (fluidStack != null && fluidStack.amount == Fluid.BUCKET_VOLUME && emptyBottleStack != null) { if (fluidStack != null && fluidStack.amount == Fluid.BUCKET_VOLUME && emptyBottleStack != null) {
abort = false; abort = false;
actualInputs.add(insertStack.copy());
extractedItems.add(input.copy());
} }
} else if ((fluidInItem = StackUtils.getFluid(insertStack, true).getValue()) != null) { } else if ((fluidInItem = StackUtils.getFluid(input, true).getValue()) != null) {
FluidStack fluidStack = network.extractFluid(fluidInItem, fluidInItem.amount, compare, false); FluidStack fluidStack = network.extractFluid(fluidInItem, fluidInItem.amount, compare, false);
ItemStack bucketStack = network.extractItem(StackUtils.EMPTY_BUCKET, 1, compare, false); ItemStack bucketStack = network.extractItem(StackUtils.EMPTY_BUCKET, 1, compare, false);
if (fluidStack != null && fluidStack.amount == fluidInItem.amount && bucketStack != null) { if (fluidStack != null && fluidStack.amount == fluidInItem.amount && bucketStack != null) {
abort = false; abort = false;
actualInputs.add(insertStack.copy());
extractedItems.add(input.copy());
} }
} }
if (abort) { if (abort) {
// Abort task re-insert taken stacks and reset state // Abort task re-insert taken stacks and reset state
toInsertItems.addAll(actualInputs); toInsertItems.addAll(extractedItems);
startedProcessing = false; startedProcessing = false;
return false; return false;
} }
} }
@@ -272,10 +299,11 @@ public abstract class CraftingStep implements ICraftingStep {
return true; return true;
} }
public static ICraftingStep toCraftingStep(NBTTagCompound compound, INetwork network) { @Nullable
public static ICraftingStep toCraftingStep(NBTTagCompound tag, INetwork network) {
CraftingStep step = null; CraftingStep step = null;
switch (compound.getString(CraftingStep.NBT_CRAFTING_STEP_TYPE)) { switch (tag.getString(CraftingStep.NBT_CRAFTING_STEP_TYPE)) {
case CraftingStepCraft.ID: case CraftingStepCraft.ID:
step = new CraftingStepCraft(network); step = new CraftingStepCraft(network);
break; break;
@@ -284,7 +312,7 @@ public abstract class CraftingStep implements ICraftingStep {
break; break;
} }
if (step != null && step.readFromNBT(compound)) { if (step != null && step.readFromNBT(tag)) {
return step; return step;
} }

View File

@@ -20,12 +20,16 @@ public class CraftingStepCraft extends CraftingStep {
public static final String ID = "craft"; public static final String ID = "craft";
private static final String NBT_TO_INSERT = "ToInsert"; private static final String NBT_TO_INSERT = "ToInsert";
private List<ItemStack> toInsert; private List<ItemStack> inputs;
public CraftingStepCraft(INetwork network, ICraftingPattern pattern, List<ItemStack> toInsert, List<ICraftingStep> preliminarySteps) { public CraftingStepCraft(INetwork network, ICraftingPattern pattern, List<ItemStack> inputs, List<ICraftingStep> preliminarySteps) {
super(network, pattern, preliminarySteps); super(network, pattern, preliminarySteps);
this.toInsert = new LinkedList<>();
toInsert.forEach(stack -> this.toInsert.add(stack == null ? null : stack.copy())); this.inputs = new LinkedList<>();
for (ItemStack input : inputs) {
this.inputs.add(input == null ? null : input.copy());
}
} }
public CraftingStepCraft(INetwork network) { public CraftingStepCraft(INetwork network) {
@@ -33,8 +37,8 @@ public class CraftingStepCraft extends CraftingStep {
} }
@Override @Override
public List<ItemStack> getToInsert() { public List<ItemStack> getInputs() {
return toInsert == null ? super.getToInsert() : toInsert.stream().filter(Objects::nonNull).collect(Collectors.toList()); return inputs == null ? super.getInputs() : inputs.stream().filter(Objects::nonNull).collect(Collectors.toList());
} }
@Override @Override
@@ -42,8 +46,10 @@ public class CraftingStepCraft extends CraftingStep {
if (!super.canStartProcessing()) { if (!super.canStartProcessing()) {
return false; return false;
} }
int compare = CraftingTask.DEFAULT_COMPARE; int compare = CraftingTask.DEFAULT_COMPARE;
for (ItemStack stack : getToInsert()) {
for (ItemStack stack : getInputs()) {
// This will be a tool, like a hammer // This will be a tool, like a hammer
if (stack.isItemStackDamageable()) { if (stack.isItemStackDamageable()) {
compare &= ~IComparer.COMPARE_DAMAGE; compare &= ~IComparer.COMPARE_DAMAGE;
@@ -52,30 +58,38 @@ public class CraftingStepCraft extends CraftingStep {
} }
ItemStack actualStack = items.get(stack, compare); ItemStack actualStack = items.get(stack, compare);
if (isItemAvailable(items, fluids, stack, actualStack, compare) == null) { if (isItemAvailable(items, fluids, stack, actualStack, compare) == null) {
items.undo(); items.undo();
fluids.undo(); fluids.undo();
return false; return false;
} }
} }
items.undo(); items.undo();
fluids.undo(); fluids.undo();
return true; return true;
} }
@Override @Override
public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) { public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) {
List<ItemStack> actualInputs = new LinkedList<>(); List<ItemStack> extracted = new LinkedList<>();
if (extractItems(actualInputs, CraftingTask.DEFAULT_COMPARE, toInsertItems)) {
IStackList<ItemStack> stackList = API.instance().createItemStackList();
actualInputs.forEach(stackList::add);
ItemStack[] took = StackListItem.toCraftingGrid(stackList, toInsert, CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0)); if (extractItems(extracted, CraftingTask.DEFAULT_COMPARE, toInsertItems)) {
IStackList<ItemStack> extractedStacks = API.instance().createItemStackList();
extracted.forEach(extractedStacks::add);
ItemStack[] took = StackListItem.toCraftingGrid(extractedStacks, inputs, CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
List<ItemStack> outputs = pattern.isOredict() ? pattern.getOutputs(took) : pattern.getOutputs(); List<ItemStack> outputs = pattern.isOredict() ? pattern.getOutputs(took) : pattern.getOutputs();
if (outputs == null) { if (outputs == null) {
toInsertItems.addAll(actualInputs); toInsertItems.addAll(extracted);
startedProcessing = false; startedProcessing = false;
return; return;
} }
@@ -103,7 +117,7 @@ public class CraftingStepCraft extends CraftingStep {
NBTTagList toInsertList = new NBTTagList(); NBTTagList toInsertList = new NBTTagList();
for (ItemStack insert : toInsert) { for (ItemStack insert : inputs) {
toInsertList.appendTag(insert == null ? new NBTTagCompound() : insert.serializeNBT()); toInsertList.appendTag(insert == null ? new NBTTagCompound() : insert.serializeNBT());
} }
@@ -117,13 +131,16 @@ public class CraftingStepCraft extends CraftingStep {
if (super.readFromNBT(tag)) { if (super.readFromNBT(tag)) {
if (tag.hasKey(NBT_TO_INSERT)) { if (tag.hasKey(NBT_TO_INSERT)) {
NBTTagList toInsertList = tag.getTagList(NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND); NBTTagList toInsertList = tag.getTagList(NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND);
toInsert = new ArrayList<>(toInsertList.tagCount());
inputs = new ArrayList<>(toInsertList.tagCount());
for (int i = 0; i < toInsertList.tagCount(); ++i) { for (int i = 0; i < toInsertList.tagCount(); ++i) {
ItemStack stack = new ItemStack(toInsertList.getCompoundTagAt(i)); ItemStack stack = new ItemStack(toInsertList.getCompoundTagAt(i));
if (stack.isEmpty()) { if (stack.isEmpty()) {
toInsert.add(null); inputs.add(null);
} else { } else {
toInsert.add(stack); inputs.add(stack);
} }
} }
} }

View File

@@ -34,11 +34,15 @@ public class CraftingStepProcess extends CraftingStep {
if (!super.canStartProcessing()) { if (!super.canStartProcessing()) {
return false; return false;
} }
IItemHandler inventory = getPattern().getContainer().getFacingInventory(); IItemHandler inventory = getPattern().getContainer().getFacingInventory();
int compare = CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0); int compare = CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0);
if (inventory != null) { if (inventory != null) {
Deque<ItemStack> toInsert = new LinkedList<>(); Deque<ItemStack> toInsert = new LinkedList<>();
for (ItemStack stack : getToInsert()) {
for (ItemStack stack : getInputs()) {
// This will be a tool, like a hammer // This will be a tool, like a hammer
if (stack.isItemStackDamageable()) { if (stack.isItemStackDamageable()) {
compare &= ~IComparer.COMPARE_DAMAGE; compare &= ~IComparer.COMPARE_DAMAGE;
@@ -56,14 +60,17 @@ public class CraftingStepProcess extends CraftingStep {
} else { } else {
items.undo(); items.undo();
fluids.undo(); fluids.undo();
return false; return false;
} }
} }
items.undo(); items.undo();
fluids.undo(); fluids.undo();
return insert(inventory, toInsert, true);
return insertItems(inventory, toInsert, true);
} }
return false; return false;
} }
@@ -72,21 +79,26 @@ public class CraftingStepProcess extends CraftingStep {
if (!super.canStartProcessing()) { if (!super.canStartProcessing()) {
return false; return false;
} }
IItemHandler inventory = getPattern().getContainer().getFacingInventory(); IItemHandler inventory = getPattern().getContainer().getFacingInventory();
return inventory != null && insert(inventory, new LinkedList<>(getToInsert()), true);
return inventory != null && insertItems(inventory, new LinkedList<>(getInputs()), true);
} }
@Override @Override
public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) { public void execute(Deque<ItemStack> toInsertItems, Deque<FluidStack> toInsertFluids) {
LinkedList<ItemStack> actualInputs = new LinkedList<>(); LinkedList<ItemStack> extracted = new LinkedList<>();
int compare = CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0); int compare = CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0);
if (extractItems(actualInputs, compare, toInsertItems)) {
if (extractItems(extracted, compare, toInsertItems)) {
IItemHandler inventory = getPattern().getContainer().getFacingInventory(); IItemHandler inventory = getPattern().getContainer().getFacingInventory();
if (insert(inventory, new ArrayDeque<>(actualInputs), true)) {
insert(inventory, actualInputs, false); if (insertItems(inventory, new ArrayDeque<>(extracted), true)) {
insertItems(inventory, extracted, false);
} else { } else {
// Something went wrong here, redo! // Something went wrong here, redo!
toInsertItems.addAll(actualInputs); toInsertItems.addAll(extracted);
startedProcessing = false; startedProcessing = false;
} }
} }
@@ -99,26 +111,23 @@ public class CraftingStepProcess extends CraftingStep {
return super.writeToNBT(tag); return super.writeToNBT(tag);
} }
/** private static boolean insertItems(IItemHandler inventory, Deque<ItemStack> stacks, boolean simulate) {
* Insert or simulate insertion of {@link ItemStack}s into an {@link IItemHandler}
*
* @param dest target {@link IItemHandler}
* @param stacks a {@link Deque} of {@link ItemStack}s
* @param simulate simulate or actually insert the {@link ItemStack}s
* @return true when all can be inserted, false otherwise
*/
private static boolean insert(IItemHandler dest, Deque<ItemStack> stacks, boolean simulate) {
ItemStack current = stacks.poll(); ItemStack current = stacks.poll();
List<Integer> availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList());
List<Integer> availableSlots = IntStream.range(0, inventory.getSlots()).boxed().collect(Collectors.toList());
while (current != null && !availableSlots.isEmpty()) { while (current != null && !availableSlots.isEmpty()) {
ItemStack remainder = null; ItemStack remainder = null;
for (Integer slot : availableSlots) { for (Integer slot : availableSlots) {
remainder = dest.insertItem(slot, current, simulate); remainder = inventory.insertItem(slot, current, simulate);
if (remainder.isEmpty() || current.getCount() != remainder.getCount()) { if (remainder.isEmpty() || current.getCount() != remainder.getCount()) {
availableSlots.remove(slot); availableSlots.remove(slot);
break; break;
} }
} }
if (remainder == null || remainder.isEmpty()) { if (remainder == null || remainder.isEmpty()) {
current = stacks.poll(); current = stacks.poll();
} else if (current.getCount() == remainder.getCount()) { } else if (current.getCount() == remainder.getCount()) {
@@ -127,6 +136,7 @@ public class CraftingStepProcess extends CraftingStep {
current = remainder; current = remainder;
} }
} }
return current == null && stacks.isEmpty(); return current == null && stacks.isEmpty();
} }
} }

View File

@@ -46,14 +46,19 @@ public class CraftingTask implements ICraftingTask {
private ItemStack requested; private ItemStack requested;
private ICraftingPattern pattern; private ICraftingPattern pattern;
private ICraftingPatternChain chain; private ICraftingPatternChain chain;
private int quantity; private int quantity;
private boolean automated; private boolean automated;
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();
private IStackList<ItemStack> toCraft = API.instance().createItemStackList(); private IStackList<ItemStack> toCraft = API.instance().createItemStackList();
private IStackList<ItemStack> missing = API.instance().createItemStackList(); private IStackList<ItemStack> missing = API.instance().createItemStackList();
private Set<ICraftingPattern> usedPatterns = new HashSet<>(); private Set<ICraftingPattern> usedPatterns = new HashSet<>();
private boolean recurseFound = false; private boolean recurseFound = false;
private Deque<ItemStack> toInsertItems = new ArrayDeque<>(); private Deque<ItemStack> toInsertItems = new ArrayDeque<>();
private Deque<FluidStack> toInsertFluids = new ArrayDeque<>(); private Deque<FluidStack> toInsertFluids = new ArrayDeque<>();
private IStackList<FluidStack> toTakeFluids = API.instance().createFluidStackList(); private IStackList<FluidStack> toTakeFluids = API.instance().createFluidStackList();
@@ -87,10 +92,13 @@ public class CraftingTask implements ICraftingTask {
IStackList<ItemStack> networkList = network.getItemStorageCache().getList().copy(); IStackList<ItemStack> networkList = network.getItemStorageCache().getList().copy();
networkList.clean(); // Remove the zero stacks networkList.clean(); // Remove the zero stacks
networkList = networkList.getOredicted(); networkList = networkList.getOredicted();
IStackList<FluidStack> networkFluidList = network.getFluidStorageCache().getList().copy(); IStackList<FluidStack> networkFluidList = network.getFluidStorageCache().getList().copy();
IStackList<ItemStack> toInsert = API.instance().createItemStackList(); IStackList<ItemStack> toInsert = API.instance().createItemStackList();
ItemStack requested = this.requested != null ? this.requested : pattern.getOutputs().get(0); ItemStack requested = this.requested != null ? this.requested : pattern.getOutputs().get(0);
toCraft.add(ItemHandlerHelper.copyStackWithSize(requested, quantity)); toCraft.add(ItemHandlerHelper.copyStackWithSize(requested, quantity));
int quantity = this.quantity; int quantity = this.quantity;
@@ -98,14 +106,17 @@ public class CraftingTask implements ICraftingTask {
ICraftingPattern currentPattern; ICraftingPattern currentPattern;
while (quantity > 0 && !recurseFound) { while (quantity > 0 && !recurseFound) {
currentPattern = this.chain == null ? this.pattern : this.chain.cycle(); currentPattern = this.chain == null ? this.pattern : this.chain.cycle();
mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert)); mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert));
quantity -= currentPattern.getQuantityPerRequest(requested); quantity -= currentPattern.getQuantityPerRequest(requested);
} }
usedPatterns.clear(); usedPatterns.clear();
} }
private ICraftingStep calculate(IStackList<ItemStack> networkList, IStackList<FluidStack> networkFluidList, ICraftingPattern pattern, IStackList<ItemStack> toInsert) { @Nullable
private ICraftingStep calculate(IStackList<ItemStack> networkItems, IStackList<FluidStack> networkFluids, ICraftingPattern pattern, IStackList<ItemStack> toInsert) {
recurseFound |= !usedPatterns.add(pattern); recurseFound |= !usedPatterns.add(pattern);
if (recurseFound) { if (recurseFound) {
return null; return null;
@@ -118,7 +129,7 @@ public class CraftingTask implements ICraftingTask {
List<ICraftingStep> previousSteps = new LinkedList<>(); List<ICraftingStep> previousSteps = new LinkedList<>();
IStackList<ItemStack> byproductList = API.instance().createItemStackList(); IStackList<ItemStack> byproductList = API.instance().createItemStackList();
pattern.getByproducts().stream().filter(Objects::nonNull).forEach(byproductList::add); pattern.getByproducts().stream().filter(s -> !s.isEmpty()).forEach(byproductList::add);
for (List<ItemStack> inputs : pattern.getOreInputs()) { for (List<ItemStack> inputs : pattern.getOreInputs()) {
if (inputs == null || inputs.isEmpty()) { if (inputs == null || inputs.isEmpty()) {
@@ -130,6 +141,7 @@ public class CraftingTask implements ICraftingTask {
ItemStack input, extraStack, networkStack; ItemStack input, extraStack, networkStack;
do { do {
input = inputs.get(i).copy(); input = inputs.get(i).copy();
// This will be a tool, like a hammer // This will be a tool, like a hammer
if (input.isItemStackDamageable()) { if (input.isItemStackDamageable()) {
compare &= ~IComparer.COMPARE_DAMAGE; compare &= ~IComparer.COMPARE_DAMAGE;
@@ -138,12 +150,15 @@ public class CraftingTask implements ICraftingTask {
} }
extraStack = toInsert.get(input, compare); extraStack = toInsert.get(input, compare);
networkStack = networkList.get(input, compare); networkStack = networkItems.get(input, compare);
} }
while (extraStack == null && networkStack == null && ++i < inputs.size() && !network.getCraftingManager().hasPattern(input, compare)); while (extraStack == null && networkStack == null && ++i < inputs.size() && !network.getCraftingManager().hasPattern(input, compare));
// Stack not found, just take first
if (i == inputs.size()) { if (i == inputs.size()) {
input = inputs.get(0).copy(); input = inputs.get(0).copy();
} }
usedStacks.add(input.copy()); usedStacks.add(input.copy());
// This will be a tool, like a hammer // This will be a tool, like a hammer
@@ -157,16 +172,20 @@ public class CraftingTask implements ICraftingTask {
final int lambdaCompare = compare; final int lambdaCompare = compare;
final ItemStack lambdaInput = input; final ItemStack lambdaInput = input;
ICraftingPattern inputPattern = null; ICraftingPattern inputPattern = null;
int available = (extraStack == null ? 0 : extraStack.getCount()) + (networkStack == null ? 0 : networkStack.getCount()); int available = (extraStack == null ? 0 : extraStack.getCount()) + (networkStack == null ? 0 : networkStack.getCount());
if (available < input.getCount()) { if (available < input.getCount()) {
inputPattern = network.getCraftingManager().getPattern(input, compare, networkList); inputPattern = network.getCraftingManager().getPattern(input, compare, networkItems);
if (inputPattern != null) { if (inputPattern != null) {
if (inputPattern.getInputs().stream().anyMatch(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare))) { if (inputPattern.getInputs().stream().anyMatch(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare))) {
int craftQuantity = inputPattern.getQuantityPerRequest(input, compare); int craftQuantity = inputPattern.getQuantityPerRequest(input, compare);
// The needed amount is the actual needed amount of extraStacks + the needed input (twice so you can keep repeating it) // The needed amount is the actual needed amount of extraStacks + the needed input (twice so you can keep repeating it)
long needed = (networkStack == null ? 0 : -networkStack.getCount()) + input.getCount() + inputPattern.getInputs().stream().filter(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare)).count() * 2; long needed = (networkStack == null ? 0 : -networkStack.getCount()) + input.getCount() + inputPattern.getInputs().stream().filter(s -> API.instance().getComparer().isEqual(s, lambdaInput, lambdaCompare)).count() * 2;
do { do {
previousSteps.add(calculate(networkList, networkFluidList, inputPattern, toInsert)); previousSteps.add(calculate(networkItems, networkFluids, inputPattern, toInsert));
toCraft.add(ItemHandlerHelper.copyStackWithSize(input, craftQuantity)); toCraft.add(ItemHandlerHelper.copyStackWithSize(input, craftQuantity));
extraStack = toInsert.get(input, compare); extraStack = toInsert.get(input, compare);
} while (extraStack != null && extraStack.getCount() < needed); } while (extraStack != null && extraStack.getCount() < needed);
@@ -175,48 +194,66 @@ public class CraftingTask implements ICraftingTask {
} }
while (input.getCount() > 0) { while (input.getCount() > 0) {
if (extraStack != null && extraStack.getCount() > 0) { if (extraStack != null && !extraStack.isEmpty()) {
int takeQuantity = Math.min(extraStack.getCount(), input.getCount()); int takeQuantity = Math.min(extraStack.getCount(), input.getCount());
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(extraStack, takeQuantity); ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(extraStack, takeQuantity);
actualInputs.add(inputStack.copy());
actualInputs.add(inputStack);
input.shrink(takeQuantity); input.shrink(takeQuantity);
if (byproductList.get(inputStack, compare) == null) { if (byproductList.get(inputStack, compare) == null) {
toCraft.add(inputStack); toCraft.add(inputStack);
} }
toInsert.remove(inputStack); toInsert.remove(inputStack);
if (input.getCount() > 0) { if (input.getCount() > 0) {
i = 0; i = 0;
do { do {
extraStack = toInsert.get(inputs.get(i), compare); extraStack = toInsert.get(inputs.get(i), compare);
} while ((extraStack == null || extraStack.getCount() == 0) && ++i < inputs.size()); } while ((extraStack == null || extraStack.isEmpty()) && ++i < inputs.size());
} }
} else if (networkStack != null && networkStack.getCount() > 0) { } else if (networkStack != null && networkStack.getCount() > 0) {
int takeQuantity = Math.min(networkStack.getCount(), input.getCount()); int takeQuantity = Math.min(networkStack.getCount(), input.getCount());
ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(networkStack, takeQuantity); ItemStack inputStack = ItemHandlerHelper.copyStackWithSize(networkStack, takeQuantity);
toTake.add(inputStack.copy());
actualInputs.add(inputStack.copy()); toTake.add(inputStack);
actualInputs.add(inputStack);
input.shrink(takeQuantity); input.shrink(takeQuantity);
networkList.remove(inputStack);
networkItems.remove(inputStack);
if (input.getCount() > 0) { if (input.getCount() > 0) {
i = 0; i = 0;
do { do {
networkStack = networkList.get(inputs.get(i), compare); networkStack = networkItems.get(inputs.get(i), compare);
} while ((extraStack == null || extraStack.getCount() == 0) && ++i < inputs.size()); } while ((extraStack == null || extraStack.getCount() == 0) && ++i < inputs.size());
} }
} else { } else {
int oreDictedCompare = compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0); int oreDictedCompare = compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0);
if (inputPattern == null) { if (inputPattern == null) {
inputPattern = network.getCraftingManager().getPattern(input, oreDictedCompare, networkList); inputPattern = network.getCraftingManager().getPattern(input, oreDictedCompare, networkItems);
} }
if (inputPattern != null) { if (inputPattern != null) {
ItemStack actualCraft = inputPattern.getActualOutput(input, oreDictedCompare); ItemStack actualCraft = inputPattern.getActualOutput(input, oreDictedCompare);
int craftQuantity = Math.min(inputPattern.getQuantityPerRequest(input, oreDictedCompare), input.getCount()); int craftQuantity = Math.min(inputPattern.getQuantityPerRequest(input, oreDictedCompare), input.getCount());
ItemStack inputCrafted = ItemHandlerHelper.copyStackWithSize(actualCraft, craftQuantity); ItemStack inputCrafted = ItemHandlerHelper.copyStackWithSize(actualCraft, craftQuantity);
toCraft.add(inputCrafted.copy());
actualInputs.add(inputCrafted.copy()); toCraft.add(inputCrafted);
previousSteps.add(calculate(networkList, networkFluidList, inputPattern, toInsert)); actualInputs.add(inputCrafted);
previousSteps.add(calculate(networkItems, networkFluids, inputPattern, toInsert));
input.shrink(craftQuantity); input.shrink(craftQuantity);
if (!recurseFound) { if (!recurseFound) {
// Calculate added all the crafted outputs toInsert // Calculate added all the crafted outputs toInsert
// So we remove the ones we use from toInsert // So we remove the ones we use from toInsert
@@ -226,7 +263,8 @@ public class CraftingTask implements ICraftingTask {
} else { } else {
// Fluid checks are with a stack size of one // Fluid checks are with a stack size of one
ItemStack fluidCheck = ItemHandlerHelper.copyStackWithSize(input, 1); ItemStack fluidCheck = ItemHandlerHelper.copyStackWithSize(input, 1);
while (input.getCount() > 0 && doFluidCalculation(networkList, networkFluidList, fluidCheck, toInsert, previousSteps)) {
while (!input.isEmpty() && doFluidCalculation(networkItems, networkFluids, fluidCheck, toInsert, previousSteps)) {
actualInputs.add(fluidCheck); actualInputs.add(fluidCheck);
input.shrink(1); input.shrink(1);
} }
@@ -234,10 +272,13 @@ public class CraftingTask implements ICraftingTask {
// When it isn't a fluid or just doesn't have the needed fluids // When it isn't a fluid or just doesn't have the needed fluids
if (input.getCount() > 0) { if (input.getCount() > 0) {
ItemStack copy = input.copy(); ItemStack copy = input.copy();
if (copy.getItemDamage() == OreDictionary.WILDCARD_VALUE) { if (copy.getItemDamage() == OreDictionary.WILDCARD_VALUE) {
copy.setItemDamage(0); copy.setItemDamage(0);
} }
missing.add(copy); missing.add(copy);
input.setCount(0); input.setCount(0);
} }
} }
@@ -246,26 +287,24 @@ public class CraftingTask implements ICraftingTask {
} }
ItemStack[] took = null; ItemStack[] took = null;
if (missing.isEmpty()) { if (missing.isEmpty() && !pattern.isProcessing()) {
if (!pattern.isProcessing()) { took = StackListItem.toCraftingGrid(actualInputs, usedStacks, compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
took = StackListItem.toCraftingGrid(actualInputs, usedStacks, compare | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0));
}
} }
List<ItemStack> outputs = !pattern.isProcessing() && pattern.isOredict() && missing.isEmpty() ? pattern.getOutputs(took) : pattern.getOutputs(); List<ItemStack> outputs = (!pattern.isProcessing() && pattern.isOredict() && missing.isEmpty()) ? pattern.getOutputs(took) : pattern.getOutputs();
if (outputs == null) { // Bla Bla what evs if (outputs == null) {
outputs = pattern.getOutputs(); outputs = pattern.getOutputs();
} }
for (ItemStack output : outputs) { for (ItemStack output : outputs) {
if (output != null && !output.isEmpty()) { if (output != null && !output.isEmpty()) {
toInsert.add(output.copy()); toInsert.add(output);
} }
} }
for (ItemStack byproduct : (!pattern.isProcessing() && pattern.isOredict() && missing.isEmpty() ? pattern.getByproducts(took) : pattern.getByproducts())) { for (ItemStack byproduct : (!pattern.isProcessing() && pattern.isOredict() && missing.isEmpty()) ? pattern.getByproducts(took) : pattern.getByproducts()) {
if (byproduct != null && !byproduct.isEmpty()) { if (byproduct != null && !byproduct.isEmpty()) {
toInsert.add(byproduct.copy()); toInsert.add(byproduct);
} }
} }
@@ -299,16 +338,16 @@ public class CraftingTask implements ICraftingTask {
if (!hasBottle) { if (!hasBottle) {
if (emptyBottlePattern == null) { if (emptyBottlePattern == null) {
missing.add(StackUtils.EMPTY_BOTTLE.copy()); missing.add(StackUtils.EMPTY_BOTTLE);
} else { } else {
toCraft.add(StackUtils.EMPTY_BOTTLE.copy()); toCraft.add(StackUtils.EMPTY_BOTTLE);
previousSteps.add(calculate(networkList, networkFluidList, emptyBottlePattern, toInsert)); previousSteps.add(calculate(networkList, networkFluidList, emptyBottlePattern, toInsert));
toInsert.remove(StackUtils.EMPTY_BOTTLE, 1); toInsert.remove(StackUtils.EMPTY_BOTTLE, 1);
} }
} }
if (hasBottle || emptyBottlePattern != null) { if (hasBottle || emptyBottlePattern != null) {
toTake.add(StackUtils.EMPTY_BOTTLE.copy()); toTake.add(StackUtils.EMPTY_BOTTLE);
networkList.remove(StackUtils.EMPTY_BOTTLE); networkList.remove(StackUtils.EMPTY_BOTTLE);
} }
} }
@@ -336,16 +375,16 @@ public class CraftingTask implements ICraftingTask {
if (!hasBucket) { if (!hasBucket) {
if (bucketPattern == null) { if (bucketPattern == null) {
missing.add(StackUtils.EMPTY_BUCKET.copy()); missing.add(StackUtils.EMPTY_BUCKET);
} else { } else {
toCraft.add(StackUtils.EMPTY_BUCKET.copy()); toCraft.add(StackUtils.EMPTY_BUCKET);
previousSteps.add(calculate(networkList, networkFluidList, bucketPattern, toInsert)); previousSteps.add(calculate(networkList, networkFluidList, bucketPattern, toInsert));
toInsert.remove(StackUtils.EMPTY_BUCKET, 1); toInsert.remove(StackUtils.EMPTY_BUCKET, 1);
} }
} }
if (hasBucket || bucketPattern != null) { if (hasBucket || bucketPattern != null) {
toTakeFluids.add(fluidInItem.copy()); toTakeFluids.add(fluidInItem);
networkFluidList.remove(fluidInItem); networkFluidList.remove(fluidInItem);
} }
} }
@@ -386,18 +425,21 @@ public class CraftingTask implements ICraftingTask {
@Override @Override
public boolean update(Map<ICraftingPatternContainer, Integer> usedContainers) { public boolean update(Map<ICraftingPatternContainer, Integer> usedContainers) {
IStackList<ItemStack> oreDictPrepped = network.getItemStorageCache().getList().getOredicted(); IStackList<ItemStack> networkItems = network.getItemStorageCache().getList().getOredicted();
IStackList<FluidStack> networkFluids = network.getFluidStorageCache().getList(); IStackList<FluidStack> networkFluids = network.getFluidStorageCache().getList();
if (!missing.isEmpty()) { if (!missing.isEmpty()) {
for (ItemStack missing : this.missing.getStacks()) { for (ItemStack missing : this.missing.getStacks()) {
if (!oreDictPrepped.trackedRemove(missing)) { if (!networkItems.trackedRemove(missing)) {
oreDictPrepped.undo(); networkItems.undo();
return false; return false;
} }
} }
oreDictPrepped.undo();
networkItems.undo();
reschedule(); reschedule();
return false; return false;
} }
@@ -419,9 +461,12 @@ public class CraftingTask implements ICraftingTask {
// Collect all leaf steps // Collect all leaf steps
List<ICraftingStep> leafSteps = new LinkedList<>(); List<ICraftingStep> leafSteps = new LinkedList<>();
Queue<ICraftingStep> steps = new LinkedList<>(); Queue<ICraftingStep> steps = new LinkedList<>();
steps.addAll(mainSteps); steps.addAll(mainSteps);
while (steps.size() > 0) { while (steps.size() > 0) {
ICraftingStep step = steps.poll(); ICraftingStep step = steps.poll();
if (step.getPreliminarySteps().size() > 0) { if (step.getPreliminarySteps().size() > 0) {
steps.addAll(step.getPreliminarySteps()); steps.addAll(step.getPreliminarySteps());
} else { } else {
@@ -440,10 +485,13 @@ public class CraftingTask implements ICraftingTask {
if (timesUsed++ <= container.getSpeedUpdateCount()) { if (timesUsed++ <= container.getSpeedUpdateCount()) {
if (!step.getPattern().isProcessing() || !container.isBlocked()) { if (!step.getPattern().isProcessing() || !container.isBlocked()) {
if (step.canStartProcessing(oreDictPrepped, networkFluids)) { if (step.canStartProcessing(networkItems, networkFluids)) {
step.setStartedProcessing(); step.setStartedProcessing();
step.execute(toInsertItems, toInsertFluids); step.execute(toInsertItems, toInsertFluids);
usedContainers.put(container, timesUsed); usedContainers.put(container, timesUsed);
network.markCraftingMonitorForUpdate(); network.markCraftingMonitorForUpdate();
} }
} }
@@ -451,7 +499,6 @@ public class CraftingTask implements ICraftingTask {
} }
} }
if (getSteps().stream().filter(ICraftingStep::hasStartedProcessing).count() == 0) { if (getSteps().stream().filter(ICraftingStep::hasStartedProcessing).count() == 0) {
// When there is no started processes, restart the task. // When there is no started processes, restart the task.
reschedule(); reschedule();
@@ -459,8 +506,11 @@ public class CraftingTask implements ICraftingTask {
// Remove finished tasks // Remove finished tasks
steps.clear(); // Re use Queue from earlier steps.clear(); // Re use Queue from earlier
mainSteps.removeIf(ICraftingStep::hasReceivedOutputs); mainSteps.removeIf(ICraftingStep::hasReceivedOutputs);
steps.addAll(mainSteps); steps.addAll(mainSteps);
while (steps.size() > 0) { while (steps.size() > 0) {
ICraftingStep step = steps.poll(); ICraftingStep step = steps.poll();
step.getPreliminarySteps().removeIf(ICraftingStep::hasReceivedOutputs); step.getPreliminarySteps().removeIf(ICraftingStep::hasReceivedOutputs);
@@ -473,18 +523,24 @@ public class CraftingTask implements ICraftingTask {
@Override @Override
public void reschedule() { public void reschedule() {
List<ICraftingStep> mainSteps = this.mainSteps.stream().filter(s -> s.getPattern().alike(pattern)).collect(Collectors.toList()); List<ICraftingStep> mainSteps = this.mainSteps.stream().filter(s -> s.getPattern().alike(pattern)).collect(Collectors.toList());
missing.clear(); missing.clear();
this.mainSteps.clear(); this.mainSteps.clear();
// if the list of main mainSteps is empty there is no point in rescheduling // if the list of main mainSteps is empty there is no point in rescheduling
if (!mainSteps.isEmpty()) { if (!mainSteps.isEmpty()) {
quantity = 0; quantity = 0;
int quantityPerRequest = pattern.getQuantityPerRequest(requested); int quantityPerRequest = pattern.getQuantityPerRequest(requested);
for (ICraftingStep step : mainSteps) { for (ICraftingStep step : mainSteps) {
quantity += quantityPerRequest - step.getReceivedOutput(requested); quantity += quantityPerRequest - step.getReceivedOutput(requested);
} }
if (quantity > 0) { if (quantity > 0) {
calculate(); calculate();
} }
network.markCraftingMonitorForUpdate(); network.markCraftingMonitorForUpdate();
} }
} }
@@ -640,12 +696,17 @@ public class CraftingTask implements ICraftingTask {
public List<ICraftingStep> getSteps() { public List<ICraftingStep> getSteps() {
List<ICraftingStep> allSteps = new LinkedList<>(); List<ICraftingStep> allSteps = new LinkedList<>();
Queue<ICraftingStep> steps = new LinkedList<>(); Queue<ICraftingStep> steps = new LinkedList<>();
steps.addAll(mainSteps); steps.addAll(mainSteps);
while (steps.size() > 0) { while (steps.size() > 0) {
ICraftingStep step = steps.poll(); ICraftingStep step = steps.poll();
allSteps.add(step); allSteps.add(step);
steps.addAll(step.getPreliminarySteps()); steps.addAll(step.getPreliminarySteps());
} }
return allSteps; return allSteps;
} }
@@ -669,32 +730,44 @@ public class CraftingTask implements ICraftingTask {
for (ItemStack stack : toCraft.getStacks()) { for (ItemStack stack : toCraft.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack); int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash); CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) { if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack); previewStack = new CraftingPreviewElementItemStack(stack);
} }
previewStack.addToCraft(stack.getCount()); previewStack.addToCraft(stack.getCount());
map.put(hash, previewStack); map.put(hash, previewStack);
} }
for (ItemStack stack : missing.getStacks()) { for (ItemStack stack : missing.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack); int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash); CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) { if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack); previewStack = new CraftingPreviewElementItemStack(stack);
} }
previewStack.setMissing(true); previewStack.setMissing(true);
previewStack.addToCraft(stack.getCount()); previewStack.addToCraft(stack.getCount());
map.put(hash, previewStack); map.put(hash, previewStack);
} }
for (ItemStack stack : toTake.getStacks()) { for (ItemStack stack : toTake.getStacks()) {
int hash = API.instance().getItemStackHashCode(stack); int hash = API.instance().getItemStackHashCode(stack);
CraftingPreviewElementItemStack previewStack = map.get(hash); CraftingPreviewElementItemStack previewStack = map.get(hash);
if (previewStack == null) { if (previewStack == null) {
previewStack = new CraftingPreviewElementItemStack(stack); previewStack = new CraftingPreviewElementItemStack(stack);
} }
previewStack.addAvailable(stack.getCount()); previewStack.addAvailable(stack.getCount());
map.put(hash, previewStack); map.put(hash, previewStack);
} }

View File

@@ -140,7 +140,8 @@ public class Comparer implements IComparer {
return EnumActionResult.PASS; return EnumActionResult.PASS;
} }
public static ItemStack stripTags(ItemStack stack) { @Nullable
public static ItemStack stripTags(@Nullable ItemStack stack) {
if (stack != null && stack.hasTagCompound()) { if (stack != null && stack.hasTagCompound()) {
switch (stack.getItem().getRegistryName().getResourceDomain()) { switch (stack.getItem().getRegistryName().getResourceDomain()) {
case "mekanism": case "mekanism":

View File

@@ -187,8 +187,10 @@ public class StackListItem implements IStackList<ItemStack> {
public static ItemStack[] toCraftingGrid(IStackList<ItemStack> list, List<ItemStack> grid, int compare) { public static ItemStack[] toCraftingGrid(IStackList<ItemStack> list, List<ItemStack> grid, int compare) {
ItemStack[] took = new ItemStack[Math.max(9, grid.size())]; ItemStack[] took = new ItemStack[Math.max(9, grid.size())];
for (int i = 0; i < grid.size(); i++) { for (int i = 0; i < grid.size(); i++) {
ItemStack input = grid.get(i); ItemStack input = grid.get(i);
if (input != null) { if (input != null) {
// This will be a tool, like a hammer // This will be a tool, like a hammer
if (input.isItemStackDamageable()) { if (input.isItemStackDamageable()) {
@@ -196,14 +198,19 @@ public class StackListItem implements IStackList<ItemStack> {
} else { } else {
compare |= IComparer.COMPARE_DAMAGE; compare |= IComparer.COMPARE_DAMAGE;
} }
ItemStack actualInput = list.get(input, compare); ItemStack actualInput = list.get(input, compare);
if (actualInput != null) { if (actualInput != null) {
ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.getCount()); ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.getCount());
took[i] = taken; took[i] = taken;
list.remove(taken, taken.getCount()); list.remove(taken, taken.getCount());
} }
} }
} }
return took; return took;
} }
} }