New autocrafting system, again.
This commit is contained in:
@@ -101,14 +101,14 @@ public interface ICraftingManager {
|
||||
*
|
||||
* @param stack the stack
|
||||
*/
|
||||
void track(ItemStack stack, int size);
|
||||
int track(ItemStack stack, int size);
|
||||
|
||||
/**
|
||||
* Tracks an incoming stack.
|
||||
*
|
||||
* @param stack the stack
|
||||
*/
|
||||
void track(FluidStack stack, int size);
|
||||
int track(FluidStack stack, int size);
|
||||
|
||||
/**
|
||||
* @return a list of crafting patterns in this network, do NOT modify this list
|
||||
|
||||
@@ -56,7 +56,6 @@ public interface ICraftingTask {
|
||||
* Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertItemTracked(ItemStack, int)}.
|
||||
*
|
||||
* @param stack the stack
|
||||
* @return the size remaining, decremented by the crafting task when it was relevant to it
|
||||
*/
|
||||
int onTrackedInsert(ItemStack stack, int size);
|
||||
|
||||
@@ -64,7 +63,6 @@ public interface ICraftingTask {
|
||||
* Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertFluidTracked(FluidStack, int)}.
|
||||
*
|
||||
* @param stack the stack
|
||||
* @return the size remaining, decremented by the crafting task when it was relevant to it
|
||||
*/
|
||||
int onTrackedInsert(FluidStack stack, int size);
|
||||
|
||||
@@ -95,14 +93,6 @@ public interface ICraftingTask {
|
||||
*/
|
||||
ICraftingPattern getPattern();
|
||||
|
||||
/**
|
||||
* Used to check if the crafting task has recursive elements (eg. block needs 9 ingots, ingots are crafted by a block).
|
||||
* {@link ICraftingTask#calculate()} must be run before this!
|
||||
*
|
||||
* @return true if no recursion was found, false otherwise
|
||||
*/
|
||||
boolean isValid();
|
||||
|
||||
/**
|
||||
* @return the time in ms when this task has started
|
||||
*/
|
||||
|
||||
@@ -108,14 +108,15 @@ public interface INetwork {
|
||||
* @param size the amount of that prototype that has to be inserted
|
||||
* @return null if the insert was successful, or a stack with the remainder
|
||||
*/
|
||||
@Nullable
|
||||
default ItemStack insertItemTracked(@Nonnull ItemStack stack, int size) {
|
||||
ItemStack remainder = insertItem(stack, size, Action.PERFORM);
|
||||
int remainder = getCraftingManager().track(stack, size);
|
||||
|
||||
int inserted = remainder == null ? size : (size - remainder.getCount());
|
||||
if (remainder == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
getCraftingManager().track(stack, inserted);
|
||||
|
||||
return remainder;
|
||||
return insertItem(stack, remainder, Action.PERFORM);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,13 +179,13 @@ public interface INetwork {
|
||||
*/
|
||||
@Nullable
|
||||
default FluidStack insertFluidTracked(@Nonnull FluidStack stack, int size) {
|
||||
FluidStack remainder = insertFluid(stack, size, Action.PERFORM);
|
||||
int remainder = getCraftingManager().track(stack, size);
|
||||
|
||||
int inserted = remainder == null ? size : (size - remainder.amount);
|
||||
if (remainder == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
getCraftingManager().track(stack, inserted);
|
||||
|
||||
return remainder;
|
||||
return insertFluid(stack, remainder, Action.PERFORM);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -152,7 +152,9 @@ public class CraftingManager implements ICraftingManager {
|
||||
}
|
||||
this.tasksToCancel.clear();
|
||||
|
||||
this.tasksToAdd.stream().filter(ICraftingTask::isValid).forEach(t -> tasks.put(t.getId(), t));
|
||||
for (ICraftingTask task : this.tasksToAdd) {
|
||||
this.tasks.put(task.getId(), task);
|
||||
}
|
||||
this.tasksToAdd.clear();
|
||||
|
||||
boolean anyFinished = false;
|
||||
@@ -275,37 +277,29 @@ public class CraftingManager implements ICraftingManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void track(ItemStack stack, int size) {
|
||||
int initialSize = size;
|
||||
|
||||
public int track(ItemStack stack, int size) {
|
||||
for (ICraftingTask task : tasks.values()) {
|
||||
size = task.onTrackedInsert(stack, size);
|
||||
|
||||
if (size == 0) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (size != initialSize) {
|
||||
this.onTaskChanged();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void track(FluidStack stack, int size) {
|
||||
int initialSize = size;
|
||||
|
||||
public int track(FluidStack stack, int size) {
|
||||
for (ICraftingTask task : tasks.values()) {
|
||||
size = task.onTrackedInsert(stack, size);
|
||||
|
||||
if (size == 0) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (size != initialSize) {
|
||||
this.onTaskChanged();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,6 @@ public class CraftingTaskFactory implements ICraftingTaskFactory {
|
||||
|
||||
@Override
|
||||
public ICraftingTask createFromNbt(INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
return new CraftingTask(network, tag);
|
||||
throw new CraftingTaskReadException("Persistence isn't implemented yet, ignoring..."); // TODO: Persistence
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
class Crafting {
|
||||
private ICraftingPattern pattern;
|
||||
private NonNullList<ItemStack> took;
|
||||
private IStackList<ItemStack> toExtract;
|
||||
|
||||
public Crafting(ICraftingPattern pattern, NonNullList<ItemStack> took, IStackList<ItemStack> toExtract) {
|
||||
this.pattern = pattern;
|
||||
this.took = took;
|
||||
this.toExtract = toExtract;
|
||||
}
|
||||
|
||||
public ICraftingPattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public NonNullList<ItemStack> getTook() {
|
||||
return took;
|
||||
}
|
||||
|
||||
public IStackList<ItemStack> getToExtract() {
|
||||
return toExtract;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.*;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChainList;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementList;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.*;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
@@ -16,57 +21,34 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.Craf
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStatus;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItem;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItemStatus;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStep;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStepCraft;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStepProcess;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFluid;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public class CraftingTask implements ICraftingTask {
|
||||
private static final long CALCULATION_TIMEOUT_MS = 5000;
|
||||
|
||||
private static final String NBT_REQUESTED = "Requested";
|
||||
private static final String NBT_QUANTITY = "Quantity";
|
||||
private static final String NBT_PATTERN = "Pattern";
|
||||
private static final String NBT_STEPS = "Steps";
|
||||
private static final String NBT_INSERTER = "Inserter";
|
||||
private static final String NBT_TICKS = "Ticks";
|
||||
private static final String NBT_ID = "Id";
|
||||
private static final String NBT_MISSING = "Missing";
|
||||
private static final String NBT_EXECUTION_STARTED = "ExecutionStarted";
|
||||
|
||||
private static final String NBT_PATTERN_STACK = "Stack";
|
||||
private static final String NBT_PATTERN_CONTAINER_POS = "ContainerPos";
|
||||
|
||||
private INetwork network;
|
||||
private ICraftingRequestInfo requested;
|
||||
private int quantity;
|
||||
private ICraftingPattern pattern;
|
||||
private List<CraftingStep> steps = new LinkedList<>();
|
||||
private CraftingInserter inserter;
|
||||
private Set<ICraftingPattern> patternsUsed = new HashSet<>();
|
||||
private int ticks = 0;
|
||||
private long calculationStarted = -1;
|
||||
private long executionStarted = -1;
|
||||
private UUID id = UUID.randomUUID();
|
||||
private int ticks;
|
||||
private long executionStarted = -1;
|
||||
|
||||
private IStorage<ItemStack> internalStorage;
|
||||
private IStorage<FluidStack> internalFluidStorage;
|
||||
|
||||
private IStackList<ItemStack> toExtractInitial = API.instance().createItemStackList();
|
||||
private IStackList<FluidStack> toExtractInitialFluids = API.instance().createFluidStackList();
|
||||
|
||||
private List<Crafting> crafting = new ArrayList<>();
|
||||
private List<Processing> processing = new ArrayList<>();
|
||||
|
||||
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
|
||||
private IStackList<FluidStack> toTakeFluids = API.instance().createFluidStackList();
|
||||
@@ -79,58 +61,17 @@ public class CraftingTask implements ICraftingTask {
|
||||
|
||||
public CraftingTask(INetwork network, ICraftingRequestInfo requested, int quantity, ICraftingPattern pattern) {
|
||||
this.network = network;
|
||||
this.inserter = new CraftingInserter(network);
|
||||
this.requested = requested;
|
||||
this.quantity = quantity;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public CraftingTask(INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
this.network = network;
|
||||
|
||||
this.requested = API.instance().createCraftingRequestInfo(tag.getCompoundTag(NBT_REQUESTED));
|
||||
this.quantity = tag.getInteger(NBT_QUANTITY);
|
||||
this.pattern = readPatternFromNbt(tag.getCompoundTag(NBT_PATTERN), network.world());
|
||||
this.inserter = new CraftingInserter(network, tag.getTagList(NBT_INSERTER, Constants.NBT.TAG_COMPOUND));
|
||||
this.ticks = tag.getInteger(NBT_TICKS);
|
||||
this.id = tag.getUniqueId(NBT_ID);
|
||||
|
||||
NBTTagList steps = tag.getTagList(NBT_STEPS, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < steps.tagCount(); ++i) {
|
||||
NBTTagCompound stepTag = steps.getCompoundTagAt(i);
|
||||
|
||||
this.steps.add(CraftingStep.readFromNbt(network, inserter, stepTag));
|
||||
}
|
||||
|
||||
NBTTagList missing = tag.getTagList(NBT_MISSING, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < missing.tagCount(); ++i) {
|
||||
ItemStack missingItem = StackUtils.deserializeStackFromNbt(missing.getCompoundTagAt(i));
|
||||
|
||||
if (missingItem.isEmpty()) {
|
||||
throw new CraftingTaskReadException("Missing item is empty");
|
||||
}
|
||||
|
||||
this.missing.add(missingItem);
|
||||
}
|
||||
|
||||
if (tag.hasKey(NBT_EXECUTION_STARTED)) {
|
||||
this.executionStarted = tag.getLong(NBT_EXECUTION_STARTED);
|
||||
}
|
||||
this.internalStorage = new StorageDiskItem(network.world(), -1);
|
||||
this.internalFluidStorage = new StorageDiskFluid(network.world(), -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ICraftingTaskError calculate() {
|
||||
if (calculationStarted != -1) {
|
||||
throw new IllegalStateException("Task already calculated!");
|
||||
}
|
||||
|
||||
if (executionStarted != -1) {
|
||||
throw new IllegalStateException("Task already started!");
|
||||
}
|
||||
|
||||
this.calculationStarted = System.currentTimeMillis();
|
||||
|
||||
int qty = this.quantity;
|
||||
int qtyPerCraft = getQuantityPerCraft();
|
||||
int crafted = 0;
|
||||
@@ -141,52 +82,17 @@ public class CraftingTask implements ICraftingTask {
|
||||
IStackList<ItemStack> storage = network.getItemStorageCache().getList().copy();
|
||||
IStackList<FluidStack> fluidStorage = network.getFluidStorageCache().getList().copy();
|
||||
|
||||
// Items that are being handled in other tasks aren't available to us.
|
||||
for (ICraftingTask task : network.getCraftingManager().getTasks()) {
|
||||
if (task instanceof CraftingTask) {
|
||||
for (CraftingStep step : ((CraftingTask) task).steps) {
|
||||
CraftingExtractor extractor = null;
|
||||
|
||||
if (step instanceof CraftingStepCraft) {
|
||||
extractor = ((CraftingStepCraft) step).getExtractor();
|
||||
} else if (step instanceof CraftingStepProcess) {
|
||||
extractor = ((CraftingStepProcess) step).getExtractor();
|
||||
}
|
||||
|
||||
if (extractor != null) {
|
||||
for (CraftingExtractorStack inUse : extractor.getStacks()) {
|
||||
ItemStack inUseItem = inUse.getItem();
|
||||
|
||||
if (inUseItem != null) {
|
||||
storage.remove(inUseItem);
|
||||
} else {
|
||||
FluidStack inUseFluid = inUse.getFluid();
|
||||
|
||||
if (inUseFluid != null) {
|
||||
fluidStorage.remove(inUseFluid);
|
||||
} else {
|
||||
throw new IllegalStateException("Extractor stack is neither a fluid or an item!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ICraftingPatternChainList patternChainList = network.getCraftingManager().createPatternChainList();
|
||||
|
||||
ICraftingPatternChain patternChain = patternChainList.getChain(pattern);
|
||||
|
||||
while (qty > 0) {
|
||||
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(storage, fluidStorage, results, fluidResults, patternChainList, patternChain.current());
|
||||
ICraftingTaskError result = calculateInternal(storage, fluidStorage, results, fluidResults, patternChainList, patternChain.current());
|
||||
|
||||
if (result.getRight() != null) {
|
||||
return result.getRight();
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
this.steps.add(result.getLeft());
|
||||
|
||||
qty -= qtyPerCraft;
|
||||
|
||||
crafted += qtyPerCraft;
|
||||
@@ -203,7 +109,8 @@ public class CraftingTask implements ICraftingTask {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Pair<CraftingStep, ICraftingTaskError> calculateInternal(
|
||||
@Nullable
|
||||
private ICraftingTaskError calculateInternal(
|
||||
IStackList<ItemStack> mutatedStorage,
|
||||
IStackList<FluidStack> mutatedFluidStorage,
|
||||
IStackList<ItemStack> results,
|
||||
@@ -211,14 +118,6 @@ public class CraftingTask implements ICraftingTask {
|
||||
ICraftingPatternChainList patternChainList,
|
||||
ICraftingPattern pattern) {
|
||||
|
||||
if (System.currentTimeMillis() - calculationStarted > CALCULATION_TIMEOUT_MS) {
|
||||
return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.TOO_COMPLEX));
|
||||
}
|
||||
|
||||
if (!patternsUsed.add(pattern)) {
|
||||
return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.RECURSIVE, pattern));
|
||||
}
|
||||
|
||||
IStackList<ItemStack> itemsToExtract = API.instance().createItemStackList();
|
||||
IStackList<FluidStack> fluidsToExtract = API.instance().createFluidStackList();
|
||||
|
||||
@@ -292,6 +191,8 @@ public class CraftingTask implements ICraftingTask {
|
||||
took.set(took.size() - 1, ItemHandlerHelper.copyStackWithSize(fromNetwork, possibleInput.getCount()));
|
||||
|
||||
fromNetwork = mutatedStorage.get(possibleInput, flags);
|
||||
|
||||
toExtractInitial.add(took.get(took.size() - 1));
|
||||
} else {
|
||||
ICraftingPattern subPattern = network.getCraftingManager().getPattern(possibleInput);
|
||||
|
||||
@@ -299,14 +200,12 @@ public class CraftingTask implements ICraftingTask {
|
||||
ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern);
|
||||
|
||||
while ((fromSelf == null ? 0 : fromSelf.getCount()) < remaining) {
|
||||
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
|
||||
ICraftingTaskError result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
|
||||
|
||||
if (result.getRight() != null) {
|
||||
return Pair.of(null, result.getRight());
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
this.steps.add(result.getLeft());
|
||||
|
||||
fromSelf = results.get(possibleInput, flags);
|
||||
if (fromSelf == null) {
|
||||
throw new IllegalStateException("Recursive calculation didn't yield anything");
|
||||
@@ -359,6 +258,8 @@ public class CraftingTask implements ICraftingTask {
|
||||
remaining -= toTake;
|
||||
|
||||
fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT);
|
||||
|
||||
toExtractInitialFluids.add(input);
|
||||
} else {
|
||||
ICraftingPattern subPattern = network.getCraftingManager().getPattern(input);
|
||||
|
||||
@@ -366,14 +267,12 @@ public class CraftingTask implements ICraftingTask {
|
||||
ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern);
|
||||
|
||||
while ((fromSelf == null ? 0 : fromSelf.amount) < remaining) {
|
||||
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
|
||||
ICraftingTaskError result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current());
|
||||
|
||||
if (result.getRight() != null) {
|
||||
return Pair.of(null, result.getRight());
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
this.steps.add(result.getLeft());
|
||||
|
||||
fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT);
|
||||
if (fromSelf == null) {
|
||||
throw new IllegalStateException("Recursive fluid calculation didn't yield anything");
|
||||
@@ -397,31 +296,307 @@ public class CraftingTask implements ICraftingTask {
|
||||
}
|
||||
}
|
||||
|
||||
patternsUsed.remove(pattern);
|
||||
|
||||
if (pattern.isProcessing()) {
|
||||
IStackList<ItemStack> itemsToReceive = API.instance().createItemStackList();
|
||||
IStackList<FluidStack> fluidsToReceive = API.instance().createFluidStackList();
|
||||
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
results.add(output);
|
||||
|
||||
itemsToReceive.add(output);
|
||||
}
|
||||
|
||||
for (FluidStack output : pattern.getFluidOutputs()) {
|
||||
fluidResults.add(output);
|
||||
|
||||
fluidsToReceive.add(output);
|
||||
}
|
||||
|
||||
return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks())), null);
|
||||
processing.add(new Processing(pattern, itemsToReceive, fluidsToReceive, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks())));
|
||||
} else {
|
||||
if (!fluidsToExtract.isEmpty()) {
|
||||
throw new IllegalStateException("Cannot extract fluids in normal pattern!");
|
||||
}
|
||||
|
||||
crafting.add(new Crafting(pattern, took, itemsToExtract));
|
||||
|
||||
results.add(pattern.getOutput(took));
|
||||
|
||||
for (ItemStack byproduct : pattern.getByproducts(took)) {
|
||||
results.add(byproduct);
|
||||
}
|
||||
|
||||
return Pair.of(new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took), null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getTickInterval(int speedUpgrades) {
|
||||
switch (speedUpgrades) {
|
||||
case 0:
|
||||
return 10;
|
||||
case 1:
|
||||
return 8;
|
||||
case 2:
|
||||
return 6;
|
||||
case 3:
|
||||
return 4;
|
||||
case 4:
|
||||
return 2;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void extractInitial() {
|
||||
if (!toExtractInitial.isEmpty()) {
|
||||
List<ItemStack> toRemove = new ArrayList<>();
|
||||
|
||||
for (ItemStack toExtract : toExtractInitial.getStacks()) {
|
||||
ItemStack result = network.extractItem(toExtract, toExtract.getCount(), getFlags(toExtract), Action.PERFORM);
|
||||
|
||||
if (result != null) {
|
||||
internalStorage.insert(toExtract, toExtract.getCount(), Action.PERFORM);
|
||||
|
||||
toRemove.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack stack : toRemove) {
|
||||
toExtractInitial.remove(stack);
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
|
||||
if (!toExtractInitialFluids.isEmpty()) {
|
||||
List<FluidStack> toRemove = new ArrayList<>();
|
||||
|
||||
for (FluidStack toExtract : toExtractInitialFluids.getStacks()) {
|
||||
FluidStack result = network.extractFluid(toExtract, toExtract.amount, Action.PERFORM);
|
||||
|
||||
if (result != null) {
|
||||
internalFluidStorage.insert(toExtract, toExtract.amount, Action.PERFORM);
|
||||
|
||||
toRemove.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
for (FluidStack stack : toRemove) {
|
||||
toExtractInitialFluids.remove(stack);
|
||||
}
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCrafting() {
|
||||
Iterator<Crafting> it = crafting.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
Crafting c = it.next();
|
||||
|
||||
if (ticks % getTickInterval(c.getPattern().getContainer().getSpeedUpgradeCount()) == 0) {
|
||||
boolean hasAll = true;
|
||||
|
||||
for (ItemStack need : c.getToExtract().getStacks()) {
|
||||
ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE);
|
||||
|
||||
if (result == null || result.getCount() != need.getCount()) {
|
||||
hasAll = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAll) {
|
||||
for (ItemStack need : c.getToExtract().getStacks()) {
|
||||
ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM);
|
||||
|
||||
if (result == null || result.getCount() != need.getCount()) {
|
||||
throw new IllegalStateException("Extractor check lied");
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack output = c.getPattern().getOutput(c.getTook());
|
||||
this.internalStorage.insert(output, output.getCount(), Action.PERFORM);
|
||||
|
||||
for (ItemStack byp : c.getPattern().getByproducts(c.getTook())) {
|
||||
this.internalStorage.insert(byp, byp.getCount(), Action.PERFORM);
|
||||
}
|
||||
|
||||
it.remove();
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProcessing() {
|
||||
Iterator<Processing> it = processing.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
Processing p = it.next();
|
||||
|
||||
if (p.getState() == ProcessingState.PROCESSED) {
|
||||
it.remove();
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.getState() == ProcessingState.EXTRACTED_ALL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ticks % getTickInterval(p.getPattern().getContainer().getSpeedUpgradeCount()) == 0) {
|
||||
ProcessingState originalState = p.getState();
|
||||
|
||||
boolean hasAll = true;
|
||||
|
||||
for (ItemStack need : p.getItemsToPut()) {
|
||||
if (p.getPattern().getContainer().getConnectedInventory() == null) {
|
||||
p.setState(ProcessingState.MACHINE_NONE);
|
||||
} else {
|
||||
ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE);
|
||||
|
||||
if (result == null || result.getCount() != need.getCount()) {
|
||||
hasAll = false;
|
||||
|
||||
break;
|
||||
} else if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, true).isEmpty()) {
|
||||
p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT);
|
||||
|
||||
break;
|
||||
} else {
|
||||
p.setState(ProcessingState.READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FluidStack need : p.getFluidsToPut()) {
|
||||
if (p.getPattern().getContainer().getConnectedFluidInventory() == null) {
|
||||
p.setState(ProcessingState.MACHINE_NONE);
|
||||
} else {
|
||||
FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.SIMULATE);
|
||||
|
||||
if (result == null || result.amount != need.amount) {
|
||||
hasAll = false;
|
||||
|
||||
break;
|
||||
} else if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, false) != result.amount) {
|
||||
p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT);
|
||||
|
||||
break;
|
||||
} else if (p.getState() == ProcessingState.READY) { // If the items were ok.
|
||||
p.setState(ProcessingState.READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p.getState() == ProcessingState.READY && hasAll) {
|
||||
for (ItemStack need : p.getItemsToPut()) {
|
||||
ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM);
|
||||
if (result == null || result.getCount() != need.getCount()) {
|
||||
throw new IllegalStateException("Could not extract from the internal inventory even though we could");
|
||||
}
|
||||
|
||||
if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, false).isEmpty()) {
|
||||
throw new IllegalStateException("Can't fill up inventory even though we could");
|
||||
}
|
||||
}
|
||||
|
||||
for (FluidStack need : p.getFluidsToPut()) {
|
||||
FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
if (result == null || result.amount != need.amount) {
|
||||
throw new IllegalStateException("Could not extract from the internal inventory even though we could");
|
||||
}
|
||||
|
||||
if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, true) != result.amount) {
|
||||
throw new IllegalStateException("Can't fill up inventory even though we could");
|
||||
}
|
||||
}
|
||||
|
||||
p.setState(ProcessingState.EXTRACTED_ALL);
|
||||
}
|
||||
|
||||
if (originalState != p.getState()) {
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
if (executionStarted == -1) {
|
||||
executionStarted = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
++ticks;
|
||||
|
||||
extractInitial();
|
||||
|
||||
if (this.crafting.isEmpty() && this.processing.isEmpty()) {
|
||||
List<Runnable> toPerform = new ArrayList<>();
|
||||
|
||||
for (ItemStack stack : internalStorage.getStacks()) {
|
||||
ItemStack remainder = network.insertItem(stack, stack.getCount(), Action.PERFORM);
|
||||
|
||||
toPerform.add(() -> {
|
||||
if (remainder == null) {
|
||||
internalStorage.extract(stack, stack.getCount(), IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
} else {
|
||||
internalStorage.extract(stack, stack.getCount() - remainder.getCount(), IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (FluidStack stack : internalFluidStorage.getStacks()) {
|
||||
FluidStack remainder = network.insertFluid(stack, stack.amount, Action.PERFORM);
|
||||
|
||||
toPerform.add(() -> {
|
||||
if (remainder == null) {
|
||||
internalFluidStorage.extract(stack, stack.amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
} else {
|
||||
internalFluidStorage.extract(stack, stack.amount - remainder.amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Prevent CME.
|
||||
toPerform.forEach(Runnable::run);
|
||||
|
||||
return internalStorage.getStacks().isEmpty() && internalFluidStorage.getStacks().isEmpty();
|
||||
} else {
|
||||
updateCrafting();
|
||||
updateProcessing();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled() {
|
||||
for (ItemStack remainder : internalStorage.getStacks()) {
|
||||
network.insertItem(remainder, remainder.getCount(), Action.PERFORM);
|
||||
}
|
||||
|
||||
for (FluidStack remainder : internalFluidStorage.getStacks()) {
|
||||
network.insertFluid(remainder, remainder.amount, Action.PERFORM);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -449,43 +624,12 @@ public class CraftingTask implements ICraftingTask {
|
||||
return qty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
if (executionStarted == -1) {
|
||||
executionStarted = System.currentTimeMillis();
|
||||
private static int getFlags(ItemStack stack) {
|
||||
if (stack.getItem().isDamageable()) {
|
||||
return IComparer.COMPARE_NBT;
|
||||
}
|
||||
|
||||
boolean allCompleted = true;
|
||||
|
||||
if (ticks % getTickInterval(pattern.getContainer().getSpeedUpgradeCount()) == 0) {
|
||||
inserter.insertOne();
|
||||
}
|
||||
|
||||
for (CraftingStep step : steps) {
|
||||
if (!step.isCompleted()) {
|
||||
allCompleted = false;
|
||||
|
||||
if (ticks % getTickInterval(step.getPattern().getContainer().getSpeedUpgradeCount()) == 0 && step.canExecute() && step.execute()) {
|
||||
step.setCompleted();
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ticks++;
|
||||
|
||||
return allCompleted && inserter.getItems().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled() {
|
||||
inserter.insertAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
return IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -495,12 +639,32 @@ public class CraftingTask implements ICraftingTask {
|
||||
|
||||
@Override
|
||||
public int onTrackedInsert(ItemStack stack, int size) {
|
||||
for (CraftingStep step : steps) {
|
||||
if (step instanceof CraftingStepProcess) {
|
||||
size = ((CraftingStepProcess) step).onTrackedItemInserted(stack, size);
|
||||
for (Processing p : this.processing) {
|
||||
if (p.getState() != ProcessingState.EXTRACTED_ALL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack content = p.getItemsToReceive().get(stack);
|
||||
|
||||
if (content != null) {
|
||||
int needed = content.getCount();
|
||||
|
||||
if (needed > size) {
|
||||
needed = size;
|
||||
}
|
||||
|
||||
p.getItemsToReceive().remove(stack, needed);
|
||||
|
||||
size -= needed;
|
||||
|
||||
if (p.getItemsToReceive().isEmpty() && p.getFluidsToReceive().isEmpty()) {
|
||||
p.setState(ProcessingState.PROCESSED);
|
||||
}
|
||||
|
||||
internalStorage.insert(stack, needed, Action.PERFORM);
|
||||
|
||||
if (size == 0) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,12 +674,32 @@ public class CraftingTask implements ICraftingTask {
|
||||
|
||||
@Override
|
||||
public int onTrackedInsert(FluidStack stack, int size) {
|
||||
for (CraftingStep step : steps) {
|
||||
if (step instanceof CraftingStepProcess) {
|
||||
size = ((CraftingStepProcess) step).onTrackedFluidInserted(stack, size);
|
||||
for (Processing p : this.processing) {
|
||||
if (p.getState() != ProcessingState.EXTRACTED_ALL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FluidStack content = p.getFluidsToReceive().get(stack);
|
||||
|
||||
if (content != null) {
|
||||
int needed = content.amount;
|
||||
|
||||
if (needed > size) {
|
||||
needed = size;
|
||||
}
|
||||
|
||||
p.getFluidsToReceive().remove(stack, needed);
|
||||
|
||||
size -= needed;
|
||||
|
||||
if (p.getItemsToReceive().isEmpty() && p.getFluidsToReceive().isEmpty()) {
|
||||
p.setState(ProcessingState.PROCESSED);
|
||||
}
|
||||
|
||||
internalFluidStorage.insert(stack, needed, Action.PERFORM);
|
||||
|
||||
if (size == 0) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,11 +707,16 @@ public class CraftingTask implements ICraftingTask {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNbt(NBTTagCompound tag) {
|
||||
return new NBTTagCompound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICraftingMonitorElement> getCraftingMonitorElements() {
|
||||
ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList();
|
||||
|
||||
if (!missing.isEmpty() || !missingFluids.isEmpty()) {
|
||||
if (!missing.isEmpty() && !missingFluids.isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.missing", 5));
|
||||
}
|
||||
|
||||
@@ -547,81 +736,32 @@ public class CraftingTask implements ICraftingTask {
|
||||
elements.commit();
|
||||
}
|
||||
|
||||
if (!inserter.getItems().isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 5));
|
||||
|
||||
for (CraftingInserterItem item : inserter.getItems()) {
|
||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(item.getStack(), item.getStack().getCount(), 0);
|
||||
|
||||
if (item.getStatus() == CraftingInserterItemStatus.FULL) {
|
||||
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.network_full", CraftingMonitorElementColor.COLOR_ERROR);
|
||||
}
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
elements.commit();
|
||||
}
|
||||
|
||||
if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted() && !((CraftingStepCraft) s).getExtractor().getStacks().isEmpty())) {
|
||||
if (!this.crafting.isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 5));
|
||||
|
||||
for (CraftingStep step : steps) {
|
||||
if (step instanceof CraftingStepCraft && !step.isCompleted()) {
|
||||
CraftingExtractor extractor = ((CraftingStepCraft) step).getExtractor();
|
||||
|
||||
for (int i = 0; i < extractor.getStacks().size(); ++i) {
|
||||
// Assume we have an item here.
|
||||
CraftingExtractorStack stack = extractor.getStacks().get(i);
|
||||
|
||||
ICraftingMonitorElement element = new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0);
|
||||
|
||||
if (stack.getStatus() == CraftingExtractorStatus.MISSING) {
|
||||
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO);
|
||||
}
|
||||
|
||||
elements.add(element);
|
||||
}
|
||||
for (Crafting c : this.crafting) {
|
||||
for (ItemStack s : c.getToExtract().getStacks()) {
|
||||
elements.add(new CraftingMonitorElementItemRender(s, s.getCount(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
elements.commit();
|
||||
}
|
||||
|
||||
if (steps.stream().anyMatch(s -> s instanceof CraftingStepProcess && !s.isCompleted())) {
|
||||
if (!this.processing.isEmpty()) {
|
||||
elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.processing", 5));
|
||||
|
||||
for (CraftingStep step : steps) {
|
||||
if (step instanceof CraftingStepProcess && !step.isCompleted()) {
|
||||
CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor();
|
||||
|
||||
for (int i = 0; i < extractor.getStacks().size(); ++i) {
|
||||
CraftingExtractorStack stack = extractor.getStacks().get(i);
|
||||
|
||||
if (stack.getItem() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elements.add(wrapAccordingToStatus(new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0), stack));
|
||||
}
|
||||
for (Processing p : this.processing) {
|
||||
for (ItemStack s : p.getItemsToReceive().getStacks()) {
|
||||
elements.add(wrapAccordingToState(new CraftingMonitorElementItemRender(s, s.getCount(), 0), p.getState(), false));
|
||||
}
|
||||
}
|
||||
|
||||
elements.commit();
|
||||
|
||||
for (CraftingStep step : steps) {
|
||||
if (step instanceof CraftingStepProcess && !step.isCompleted()) {
|
||||
CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor();
|
||||
|
||||
for (int i = 0; i < extractor.getStacks().size(); ++i) {
|
||||
CraftingExtractorStack stack = extractor.getStacks().get(i);
|
||||
|
||||
if (stack.getItem() != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
elements.add(wrapAccordingToStatus(new CraftingMonitorElementFluidRender(stack.getFluid(), stack.getFluid().amount, 0), stack));
|
||||
}
|
||||
for (Processing p : this.processing) {
|
||||
for (FluidStack s : p.getFluidsToReceive().getStacks()) {
|
||||
elements.add(wrapAccordingToState(new CraftingMonitorElementFluidRender(s, s.amount, 0), p.getState(), true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,15 +771,14 @@ public class CraftingTask implements ICraftingTask {
|
||||
return elements.getElements();
|
||||
}
|
||||
|
||||
private ICraftingMonitorElement wrapAccordingToStatus(ICraftingMonitorElement element, CraftingExtractorStack stack) {
|
||||
if (stack.getStatus() == CraftingExtractorStatus.MISSING) {
|
||||
element = new CraftingMonitorElementColor(element, stack.getFluid() != null ? "gui.refinedstorage:crafting_monitor.waiting_for_fluids" : "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO);
|
||||
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT) {
|
||||
element = new CraftingMonitorElementColor(element, stack.getFluid() != null ? "gui.refinedstorage:crafting_monitor.machine_does_not_accept_fluid" : "gui.refinedstorage:crafting_monitor.machine_does_not_accept_item", CraftingMonitorElementColor.COLOR_ERROR);
|
||||
} else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_NONE) {
|
||||
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR);
|
||||
} else if (stack.getStatus() == CraftingExtractorStatus.EXTRACTED) {
|
||||
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.inserted_into_machine", CraftingMonitorElementColor.COLOR_SUCCESS);
|
||||
private ICraftingMonitorElement wrapAccordingToState(ICraftingMonitorElement element, ProcessingState state, boolean fluid) {
|
||||
switch (state) {
|
||||
case MACHINE_NONE:
|
||||
element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR);
|
||||
break;
|
||||
case MACHINE_DOES_NOT_ACCEPT:
|
||||
element = new CraftingMonitorElementColor(element, fluid ? "gui.refinedstorage:crafting_monitor.machine_does_not_accept_fluid" : "gui.refinedstorage:crafting_monitor.machine_does_not_accept_item", CraftingMonitorElementColor.COLOR_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
return element;
|
||||
@@ -749,11 +888,6 @@ public class CraftingTask implements ICraftingTask {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExecutionStarted() {
|
||||
return executionStarted;
|
||||
@@ -768,83 +902,4 @@ public class CraftingTask implements ICraftingTask {
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNbt(NBTTagCompound tag) {
|
||||
tag.setTag(NBT_REQUESTED, requested.writeToNbt());
|
||||
tag.setInteger(NBT_QUANTITY, quantity);
|
||||
tag.setTag(NBT_PATTERN, writePatternToNbt(pattern));
|
||||
tag.setTag(NBT_INSERTER, inserter.writeToNbt());
|
||||
tag.setInteger(NBT_TICKS, ticks);
|
||||
tag.setUniqueId(NBT_ID, id);
|
||||
tag.setLong(NBT_EXECUTION_STARTED, executionStarted);
|
||||
|
||||
NBTTagList steps = new NBTTagList();
|
||||
for (CraftingStep step : this.steps) {
|
||||
steps.appendTag(step.writeToNbt());
|
||||
}
|
||||
|
||||
tag.setTag(NBT_STEPS, steps);
|
||||
|
||||
NBTTagList missing = new NBTTagList();
|
||||
for (ItemStack missingItem : this.missing.getStacks()) {
|
||||
missing.appendTag(StackUtils.serializeStackToNbt(missingItem));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_MISSING, missing);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
private int getTickInterval(int speedUpgrades) {
|
||||
switch (speedUpgrades) {
|
||||
case 0:
|
||||
return 10;
|
||||
case 1:
|
||||
return 8;
|
||||
case 2:
|
||||
return 6;
|
||||
case 3:
|
||||
return 4;
|
||||
case 4:
|
||||
return 2;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static NBTTagCompound writePatternToNbt(ICraftingPattern pattern) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
|
||||
tag.setTag(NBT_PATTERN_STACK, pattern.getStack().serializeNBT());
|
||||
tag.setLong(NBT_PATTERN_CONTAINER_POS, pattern.getContainer().getPosition().toLong());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static ICraftingPattern readPatternFromNbt(NBTTagCompound tag, World world) throws CraftingTaskReadException {
|
||||
BlockPos containerPos = BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER_POS));
|
||||
|
||||
INetworkNode node = API.instance().getNetworkNodeManager(world).getNode(containerPos);
|
||||
|
||||
if (node instanceof ICraftingPatternContainer) {
|
||||
ItemStack stack = new ItemStack(tag.getCompoundTag(NBT_PATTERN_STACK));
|
||||
|
||||
if (stack.getItem() instanceof ICraftingPatternProvider) {
|
||||
return ((ICraftingPatternProvider) stack.getItem()).create(world, stack, (ICraftingPatternContainer) node);
|
||||
} else {
|
||||
throw new CraftingTaskReadException("Pattern stack is not a crafting pattern provider");
|
||||
}
|
||||
} else {
|
||||
throw new CraftingTaskReadException("Crafting pattern container doesn't exist anymore");
|
||||
}
|
||||
}
|
||||
|
||||
public static int getFlags(ItemStack stack) {
|
||||
if (stack.getItem().isDamageable()) {
|
||||
return IComparer.COMPARE_NBT;
|
||||
}
|
||||
|
||||
return IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class Processing {
|
||||
private ICraftingPattern pattern;
|
||||
private IStackList<ItemStack> itemsToReceive;
|
||||
private IStackList<FluidStack> fluidsToReceive;
|
||||
private List<ItemStack> itemsToPut;
|
||||
private List<FluidStack> fluidsToPut;
|
||||
private ProcessingState state = ProcessingState.READY;
|
||||
|
||||
public Processing(ICraftingPattern pattern, IStackList<ItemStack> itemsToReceive, IStackList<FluidStack> fluidsToReceive, List<ItemStack> itemsToPut, List<FluidStack> fluidsToPut) {
|
||||
this.pattern = pattern;
|
||||
this.itemsToReceive = itemsToReceive;
|
||||
this.fluidsToReceive = fluidsToReceive;
|
||||
this.itemsToPut = itemsToPut;
|
||||
this.fluidsToPut = fluidsToPut;
|
||||
}
|
||||
|
||||
public ICraftingPattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public IStackList<ItemStack> getItemsToReceive() {
|
||||
return itemsToReceive;
|
||||
}
|
||||
|
||||
public IStackList<FluidStack> getFluidsToReceive() {
|
||||
return fluidsToReceive;
|
||||
}
|
||||
|
||||
public List<ItemStack> getItemsToPut() {
|
||||
return itemsToPut;
|
||||
}
|
||||
|
||||
public List<FluidStack> getFluidsToPut() {
|
||||
return fluidsToPut;
|
||||
}
|
||||
|
||||
public void setState(ProcessingState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public ProcessingState getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
enum ProcessingState {
|
||||
READY,
|
||||
EXTRACTED_ALL,
|
||||
MACHINE_NONE,
|
||||
MACHINE_DOES_NOT_ACCEPT,
|
||||
PROCESSED
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CraftingExtractor {
|
||||
private INetwork network;
|
||||
private List<CraftingExtractorStack> stacks;
|
||||
private boolean processing;
|
||||
|
||||
public CraftingExtractor(INetwork network, List<CraftingExtractorStack> stacks, boolean processing) {
|
||||
this.network = network;
|
||||
this.stacks = stacks;
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
public CraftingExtractor(INetwork network, NBTTagList tag, boolean processing) throws CraftingTaskReadException {
|
||||
this.network = network;
|
||||
this.processing = processing;
|
||||
|
||||
this.stacks = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < tag.tagCount(); ++i) {
|
||||
this.stacks.add(new CraftingExtractorStack(tag.getCompoundTagAt(i)));
|
||||
}
|
||||
}
|
||||
|
||||
public List<CraftingExtractorStack> getStacks() {
|
||||
return stacks;
|
||||
}
|
||||
|
||||
public void updateStatus(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) {
|
||||
boolean updated = false;
|
||||
|
||||
for (CraftingExtractorStack stack : stacks) {
|
||||
if (stack.getStatus() != CraftingExtractorStatus.EXTRACTED) {
|
||||
CraftingExtractorStatus previousStatus = stack.getStatus();
|
||||
|
||||
if (stack.getItem() != null) {
|
||||
ItemStack item = stack.getItem();
|
||||
|
||||
ItemStack inNetwork = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.SIMULATE);
|
||||
|
||||
if (inNetwork == null || inNetwork.getCount() < item.getCount()) {
|
||||
stack.setStatus(CraftingExtractorStatus.MISSING);
|
||||
} else {
|
||||
stack.setStatus(CraftingExtractorStatus.AVAILABLE);
|
||||
|
||||
if (processing) {
|
||||
if (processingInventory == null) {
|
||||
stack.setStatus(CraftingExtractorStatus.MACHINE_NONE);
|
||||
} else if (!ItemHandlerHelper.insertItem(processingInventory, item, true).isEmpty()) {
|
||||
stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FluidStack fluid = stack.getFluid();
|
||||
|
||||
FluidStack inNetwork = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.SIMULATE);
|
||||
|
||||
if (inNetwork == null || inNetwork.amount < fluid.amount) {
|
||||
stack.setStatus(CraftingExtractorStatus.MISSING);
|
||||
} else {
|
||||
stack.setStatus(CraftingExtractorStatus.AVAILABLE);
|
||||
|
||||
if (processingFluidInventory == null) {
|
||||
stack.setStatus(CraftingExtractorStatus.MACHINE_NONE);
|
||||
} else if (processingFluidInventory.fill(fluid, false) != fluid.amount) {
|
||||
stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (previousStatus != stack.getStatus()) {
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAllAvailable() {
|
||||
return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.AVAILABLE || s.getStatus() == CraftingExtractorStatus.EXTRACTED);
|
||||
}
|
||||
|
||||
public boolean isAllExtracted() {
|
||||
return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.EXTRACTED);
|
||||
}
|
||||
|
||||
public void extractOne(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) {
|
||||
boolean changed = false;
|
||||
|
||||
for (CraftingExtractorStack stack : stacks) {
|
||||
if (stack.getStatus() == CraftingExtractorStatus.AVAILABLE) {
|
||||
if (stack.getItem() != null) {
|
||||
ItemStack item = stack.getItem();
|
||||
|
||||
ItemStack extracted = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.PERFORM);
|
||||
if (extracted == null) {
|
||||
throw new IllegalStateException("Did not extract anything while available");
|
||||
}
|
||||
|
||||
if (processing) {
|
||||
if (processingInventory == null) {
|
||||
throw new IllegalStateException("Processing inventory is null");
|
||||
}
|
||||
|
||||
ItemStack remainder = ItemHandlerHelper.insertItem(processingInventory, extracted, false);
|
||||
if (!remainder.isEmpty()) {
|
||||
throw new IllegalStateException("The processing inventory gave back a remainder while it previously stated it could handle all");
|
||||
}
|
||||
}
|
||||
|
||||
stack.setStatus(CraftingExtractorStatus.EXTRACTED);
|
||||
|
||||
changed = true;
|
||||
} else {
|
||||
FluidStack fluid = stack.getFluid();
|
||||
|
||||
FluidStack extracted = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.PERFORM);
|
||||
if (extracted == null) {
|
||||
throw new IllegalStateException("Did not extract any fluids while available");
|
||||
}
|
||||
|
||||
if (processingFluidInventory == null) {
|
||||
throw new IllegalStateException("Processing fluid inventory is null");
|
||||
}
|
||||
|
||||
int filled = processingFluidInventory.fill(fluid, true);
|
||||
if (filled != fluid.amount) {
|
||||
throw new IllegalStateException("The processing fluid inventory gave back a remainder while it previously stated it could handle all");
|
||||
}
|
||||
|
||||
stack.setStatus(CraftingExtractorStatus.EXTRACTED);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// For processing patterns we want to insert all items at once to avoid conflicts with other crafting steps.
|
||||
if (!processing) {
|
||||
return;
|
||||
} else {
|
||||
updateStatus(processingInventory, processingFluidInventory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public NBTTagList writeToNbt() {
|
||||
NBTTagList list = new NBTTagList();
|
||||
|
||||
for (CraftingExtractorStack stack : stacks) {
|
||||
list.appendTag(stack.writeToNbt());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CraftingExtractorStack {
|
||||
private static final String NBT_FLUID = "Fluid";
|
||||
private static final String NBT_STACK = "Stack";
|
||||
private static final String NBT_STATUS = "Status";
|
||||
|
||||
private ItemStack item;
|
||||
private FluidStack fluid;
|
||||
private CraftingExtractorStatus status = CraftingExtractorStatus.MISSING;
|
||||
|
||||
public CraftingExtractorStack(ItemStack item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public CraftingExtractorStack(FluidStack fluid) {
|
||||
this.fluid = fluid;
|
||||
}
|
||||
|
||||
public CraftingExtractorStack(NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
if (!tag.getBoolean(NBT_FLUID)) {
|
||||
item = StackUtils.deserializeStackFromNbt(tag.getCompoundTag(NBT_STACK));
|
||||
|
||||
if (item.isEmpty()) {
|
||||
throw new CraftingTaskReadException("Extractor stack is empty");
|
||||
}
|
||||
} else {
|
||||
fluid = FluidStack.loadFluidStackFromNBT(tag.getCompoundTag(NBT_STACK));
|
||||
|
||||
if (fluid == null) {
|
||||
throw new CraftingTaskReadException("Extractor fluid stack is empty");
|
||||
}
|
||||
}
|
||||
|
||||
status = CraftingExtractorStatus.values()[tag.getInteger(NBT_STATUS)];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FluidStack getFluid() {
|
||||
return fluid;
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNbt() {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
|
||||
tag.setBoolean(NBT_FLUID, fluid != null);
|
||||
|
||||
if (fluid != null) {
|
||||
tag.setTag(NBT_STACK, fluid.writeToNBT(new NBTTagCompound()));
|
||||
} else {
|
||||
tag.setTag(NBT_STACK, StackUtils.serializeStackToNbt(item));
|
||||
}
|
||||
|
||||
tag.setInteger(NBT_STATUS, status.ordinal());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public CraftingExtractorStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(CraftingExtractorStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor;
|
||||
|
||||
public enum CraftingExtractorStatus {
|
||||
AVAILABLE,
|
||||
MISSING,
|
||||
EXTRACTED,
|
||||
MACHINE_NONE,
|
||||
MACHINE_DOES_NOT_ACCEPT
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.Action;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
|
||||
public class CraftingInserter {
|
||||
private static final String NBT_ITEM = "Item";
|
||||
private static final String NBT_STATUS = "Status";
|
||||
|
||||
private INetwork network;
|
||||
private Deque<CraftingInserterItem> items = new ArrayDeque<>();
|
||||
|
||||
public CraftingInserter(INetwork network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public CraftingInserter(INetwork network, NBTTagList list) throws CraftingTaskReadException {
|
||||
this(network);
|
||||
|
||||
for (int i = 0; i < list.tagCount(); ++i) {
|
||||
NBTTagCompound itemTag = list.getCompoundTagAt(i);
|
||||
|
||||
ItemStack stack = StackUtils.deserializeStackFromNbt(itemTag.getCompoundTag(NBT_ITEM));
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
throw new CraftingTaskReadException("Inserter has empty stack");
|
||||
}
|
||||
|
||||
CraftingInserterItemStatus status = CraftingInserterItemStatus.values()[itemTag.getInteger(NBT_STATUS)];
|
||||
|
||||
items.push(new CraftingInserterItem(stack, status));
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(ItemStack stack) {
|
||||
items.addLast(new CraftingInserterItem(stack, CraftingInserterItemStatus.WAITING));
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
|
||||
public void insertOne() {
|
||||
CraftingInserterItem item = items.peekFirst();
|
||||
|
||||
if (item != null) {
|
||||
CraftingInserterItemStatus currentStatus = item.getStatus();
|
||||
|
||||
if (network.insertItem(item.getStack(), item.getStack().getCount(), Action.SIMULATE) == null) {
|
||||
ItemStack inserted = network.insertItem(item.getStack(), item.getStack().getCount(), Action.PERFORM);
|
||||
if (inserted != null) {
|
||||
throw new IllegalStateException("Could not insert item");
|
||||
}
|
||||
|
||||
items.pop();
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
} else if (currentStatus != CraftingInserterItemStatus.FULL) {
|
||||
item.setStatus(CraftingInserterItemStatus.FULL);
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void insertAll() {
|
||||
while (!items.isEmpty()) {
|
||||
CraftingInserterItem item = items.pop();
|
||||
|
||||
network.insertItem(item.getStack(), item.getStack().getCount(), Action.PERFORM);
|
||||
}
|
||||
|
||||
network.getCraftingManager().onTaskChanged();
|
||||
}
|
||||
|
||||
public Collection<CraftingInserterItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public NBTTagList writeToNbt() {
|
||||
NBTTagList list = new NBTTagList();
|
||||
|
||||
for (CraftingInserterItem item : items) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
|
||||
tag.setTag(NBT_ITEM, StackUtils.serializeStackToNbt(item.getStack()));
|
||||
tag.setInteger(NBT_STATUS, item.getStatus().ordinal());
|
||||
|
||||
list.appendTag(tag);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class CraftingInserterItem {
|
||||
private ItemStack stack;
|
||||
private CraftingInserterItemStatus status;
|
||||
|
||||
public CraftingInserterItem(ItemStack stack, CraftingInserterItemStatus status) {
|
||||
this.stack = stack;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public ItemStack getStack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public CraftingInserterItemStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(CraftingInserterItemStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter;
|
||||
|
||||
public enum CraftingInserterItemStatus {
|
||||
WAITING,
|
||||
FULL
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public abstract class CraftingStep {
|
||||
private static final String NBT_PATTERN = "Pattern";
|
||||
private static final String NBT_COMPLETED = "Completed";
|
||||
private static final String NBT_TYPE = "Type";
|
||||
|
||||
protected ICraftingPattern pattern;
|
||||
private boolean completed;
|
||||
|
||||
public CraftingStep(ICraftingPattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public abstract boolean canExecute();
|
||||
|
||||
public abstract boolean execute();
|
||||
|
||||
public ICraftingPattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted() {
|
||||
this.completed = true;
|
||||
}
|
||||
|
||||
public abstract String getType();
|
||||
|
||||
public NBTTagCompound writeToNbt() {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
|
||||
tag.setTag(NBT_PATTERN, CraftingTask.writePatternToNbt(pattern));
|
||||
tag.setBoolean(NBT_COMPLETED, completed);
|
||||
tag.setString(NBT_TYPE, getType());
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static CraftingStep readFromNbt(INetwork network, CraftingInserter inserter, NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
ICraftingPattern pattern = CraftingTask.readPatternFromNbt(tag.getCompoundTag(NBT_PATTERN), network.world());
|
||||
boolean completed = tag.getBoolean(NBT_COMPLETED);
|
||||
String type = tag.getString(NBT_TYPE);
|
||||
|
||||
CraftingStep step;
|
||||
|
||||
switch (type) {
|
||||
case CraftingStepCraft.TYPE:
|
||||
step = new CraftingStepCraft(pattern, inserter, network, tag);
|
||||
break;
|
||||
case CraftingStepProcess.TYPE:
|
||||
step = new CraftingStepProcess(pattern, network, tag);
|
||||
break;
|
||||
default:
|
||||
throw new CraftingTaskReadException("Unknown crafting step type");
|
||||
}
|
||||
|
||||
if (completed) {
|
||||
step.setCompleted();
|
||||
}
|
||||
|
||||
return step;
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CraftingStepCraft extends CraftingStep {
|
||||
public static final String TYPE = "craft";
|
||||
|
||||
private static final String NBT_EXTRACTOR = "Extractor";
|
||||
private static final String NBT_TOOK = "Took";
|
||||
|
||||
private CraftingInserter inserter;
|
||||
private CraftingExtractor extractor;
|
||||
|
||||
private NonNullList<ItemStack> took;
|
||||
|
||||
public CraftingStepCraft(ICraftingPattern pattern, CraftingInserter inserter, INetwork network, List<ItemStack> toExtract, NonNullList<ItemStack> took) {
|
||||
super(pattern);
|
||||
|
||||
if (pattern.isProcessing()) {
|
||||
throw new IllegalArgumentException("Cannot pass processing pattern to craft handler");
|
||||
}
|
||||
|
||||
this.inserter = inserter;
|
||||
this.extractor = new CraftingExtractor(network, toExtract.stream().map(CraftingExtractorStack::new).collect(Collectors.toList()), false);
|
||||
this.took = took;
|
||||
}
|
||||
|
||||
public CraftingStepCraft(ICraftingPattern pattern, CraftingInserter inserter, INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
super(pattern);
|
||||
|
||||
if (pattern.isProcessing()) {
|
||||
throw new IllegalArgumentException("Cannot pass processing pattern to craft handler");
|
||||
}
|
||||
|
||||
this.inserter = inserter;
|
||||
this.extractor = new CraftingExtractor(network, tag.getTagList(NBT_EXTRACTOR, Constants.NBT.TAG_COMPOUND), false);
|
||||
|
||||
this.took = NonNullList.create();
|
||||
|
||||
NBTTagList tookList = tag.getTagList(NBT_TOOK, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < tookList.tagCount(); ++i) {
|
||||
took.add(StackUtils.deserializeStackFromNbt(tookList.getCompoundTagAt(i))); // Took stack can be empty
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
extractor.updateStatus(null, null);
|
||||
|
||||
return extractor.isAllAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
extractor.extractOne(null, null);
|
||||
|
||||
boolean allExtracted = extractor.isAllExtracted();
|
||||
|
||||
if (allExtracted) {
|
||||
inserter.insert(pattern.getOutput(took));
|
||||
|
||||
for (ItemStack byproduct : pattern.getByproducts(took)) {
|
||||
inserter.insert(byproduct);
|
||||
}
|
||||
}
|
||||
|
||||
return allExtracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNbt() {
|
||||
NBTTagCompound tag = super.writeToNbt();
|
||||
|
||||
tag.setTag(NBT_EXTRACTOR, extractor.writeToNbt());
|
||||
|
||||
NBTTagList took = new NBTTagList();
|
||||
|
||||
for (ItemStack stack : this.took) {
|
||||
took.appendTag(StackUtils.serializeStackToNbt(stack));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TOOK, took);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public CraftingExtractor getExtractor() {
|
||||
return extractor;
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
|
||||
import com.raoulvdberge.refinedstorage.api.network.INetwork;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CraftingStepProcess extends CraftingStep {
|
||||
public static final String TYPE = "process";
|
||||
|
||||
private static final String NBT_EXTRACTOR = "Extractor";
|
||||
private static final String NBT_TO_RECEIVE = "ToReceive";
|
||||
private static final String NBT_TO_RECEIVE_FLUIDS = "ToReceiveFluids";
|
||||
|
||||
private CraftingExtractor extractor;
|
||||
|
||||
private IStackList<ItemStack> itemsToReceive = API.instance().createItemStackList();
|
||||
private IStackList<FluidStack> fluidsToReceive = API.instance().createFluidStackList();
|
||||
|
||||
public CraftingStepProcess(ICraftingPattern pattern, INetwork network, List<ItemStack> toExtract, List<FluidStack> fluidsToExtract) {
|
||||
super(pattern);
|
||||
|
||||
if (!pattern.isProcessing()) {
|
||||
throw new IllegalArgumentException("Cannot pass non-processing pattern to processing handler");
|
||||
}
|
||||
|
||||
List<CraftingExtractorStack> stacks = new ArrayList<>();
|
||||
|
||||
for (ItemStack item : toExtract) {
|
||||
stacks.add(new CraftingExtractorStack(item));
|
||||
}
|
||||
|
||||
for (FluidStack fluid : fluidsToExtract) {
|
||||
stacks.add(new CraftingExtractorStack(fluid));
|
||||
}
|
||||
|
||||
this.extractor = new CraftingExtractor(network, stacks, true);
|
||||
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
this.itemsToReceive.add(output);
|
||||
}
|
||||
|
||||
for (FluidStack output : pattern.getFluidOutputs()) {
|
||||
this.fluidsToReceive.add(output);
|
||||
}
|
||||
}
|
||||
|
||||
public CraftingStepProcess(ICraftingPattern pattern, INetwork network, NBTTagCompound tag) throws CraftingTaskReadException {
|
||||
super(pattern);
|
||||
|
||||
if (!pattern.isProcessing()) {
|
||||
throw new IllegalArgumentException("Cannot pass non-processing pattern to processing handler");
|
||||
}
|
||||
|
||||
this.extractor = new CraftingExtractor(network, tag.getTagList(NBT_EXTRACTOR, Constants.NBT.TAG_COMPOUND), true);
|
||||
|
||||
NBTTagList toReceiveList = tag.getTagList(NBT_TO_RECEIVE, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < toReceiveList.tagCount(); ++i) {
|
||||
ItemStack toReceive = StackUtils.deserializeStackFromNbt(toReceiveList.getCompoundTagAt(i));
|
||||
|
||||
if (toReceive.isEmpty()) {
|
||||
throw new CraftingTaskReadException("Item to receive is empty");
|
||||
}
|
||||
|
||||
this.itemsToReceive.add(toReceive);
|
||||
}
|
||||
|
||||
NBTTagList toReceiveFluidsList = tag.getTagList(NBT_TO_RECEIVE_FLUIDS, Constants.NBT.TAG_COMPOUND);
|
||||
for (int i = 0; i < toReceiveFluidsList.tagCount(); ++i) {
|
||||
FluidStack toReceive = FluidStack.loadFluidStackFromNBT(toReceiveFluidsList.getCompoundTagAt(i));
|
||||
|
||||
if (toReceive == null) {
|
||||
throw new CraftingTaskReadException("Fluid to receive is null");
|
||||
}
|
||||
|
||||
this.fluidsToReceive.add(toReceive);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
extractor.updateStatus(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory());
|
||||
|
||||
return extractor.isAllAvailable();
|
||||
}
|
||||
|
||||
public int onTrackedItemInserted(ItemStack stack, int size) {
|
||||
if (!extractor.isAllExtracted()) {
|
||||
return size;
|
||||
}
|
||||
|
||||
ItemStack inList = itemsToReceive.get(stack);
|
||||
if (inList == null) {
|
||||
return size;
|
||||
}
|
||||
|
||||
int toExtract = Math.min(size, inList.getCount());
|
||||
|
||||
itemsToReceive.remove(stack, toExtract);
|
||||
|
||||
return size - toExtract;
|
||||
}
|
||||
|
||||
public int onTrackedFluidInserted(FluidStack stack, int size) {
|
||||
if (!extractor.isAllExtracted()) {
|
||||
return size;
|
||||
}
|
||||
|
||||
FluidStack inList = fluidsToReceive.get(stack);
|
||||
if (inList == null) {
|
||||
return size;
|
||||
}
|
||||
|
||||
int toExtract = Math.min(size, inList.amount);
|
||||
|
||||
fluidsToReceive.remove(stack, toExtract);
|
||||
|
||||
return size - toExtract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
if (!extractor.isAllExtracted()) {
|
||||
extractor.extractOne(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory());
|
||||
}
|
||||
|
||||
return extractor.isAllExtracted() && itemsToReceive.isEmpty() && fluidsToReceive.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNbt() {
|
||||
NBTTagCompound tag = super.writeToNbt();
|
||||
|
||||
tag.setTag(NBT_EXTRACTOR, extractor.writeToNbt());
|
||||
|
||||
NBTTagList toReceive = new NBTTagList();
|
||||
|
||||
for (ItemStack toReceiveStack : itemsToReceive.getStacks()) {
|
||||
toReceive.appendTag(StackUtils.serializeStackToNbt(toReceiveStack));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TO_RECEIVE, toReceive);
|
||||
|
||||
NBTTagList toReceiveFluids = new NBTTagList();
|
||||
|
||||
for (FluidStack toReceiveStack : fluidsToReceive.getStacks()) {
|
||||
toReceiveFluids.appendTag(toReceiveStack.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
|
||||
tag.setTag(NBT_TO_RECEIVE_FLUIDS, toReceiveFluids);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public CraftingExtractor getExtractor() {
|
||||
return extractor;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user