Added error handling in crafting tasks: recursive pattern check and max time.
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
- Removed Storage Drawers integration (you can still attach an External Storage to drawers, though) (raoulvdberge)
|
||||
- Removed blocking mode in autocrafting (raoulvdberge)
|
||||
- Removed the Wrench (raoulvdberge)
|
||||
- Rewrote autocrafting (raoulvdberge)
|
||||
- Autocrafting tasks that take longer than 5 seconds to calculate are automatically stopped to avoid server strain (raoulvdberge)
|
||||
- Added new storage disk system where the storage disk data (items, fluids) are stored off the disk itself, in another file (refinedstorage_disks.dat). The disk itself only stores its ID (raoulvdberge)
|
||||
- Changed fluid storage progression to be 64k - 256k - 1024k - 4096k (raoulvdberge)
|
||||
- You can no longer put a Filter in filter slots to gain additional filter slots (raoulvdberge)
|
||||
|
@@ -0,0 +1,15 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
|
||||
|
||||
/**
|
||||
* The error type.
|
||||
*/
|
||||
public enum CraftingTaskErrorType {
|
||||
/**
|
||||
* When the crafting task would cause too much server strain or is too complex.
|
||||
*/
|
||||
TOO_COMPLEX,
|
||||
/**
|
||||
* When one of the used patterns during the calculation reuses itself again and would cause an infinite loop.
|
||||
*/
|
||||
RECURSIVE
|
||||
}
|
@@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -15,8 +16,11 @@ import java.util.List;
|
||||
public interface ICraftingTask {
|
||||
/**
|
||||
* Calculates what this task will do, but doesn't run the task yet.
|
||||
*
|
||||
* @return the error, or null if there was no error
|
||||
*/
|
||||
void calculate();
|
||||
@Nullable
|
||||
ICraftingTaskError calculate();
|
||||
|
||||
/**
|
||||
* Updates this task.
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package com.raoulvdberge.refinedstorage.api.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Returned from {@link ICraftingTask#calculate()} when an error occurs during the calculation.
|
||||
*/
|
||||
public interface ICraftingTaskError {
|
||||
/**
|
||||
* @return the type
|
||||
*/
|
||||
CraftingTaskErrorType getType();
|
||||
|
||||
/**
|
||||
* If this error type is a {@link CraftingTaskErrorType#RECURSIVE}, the recursed pattern will be returned here.
|
||||
*
|
||||
* @return the recursed pattern, or null if this error is not {@link CraftingTaskErrorType#RECURSIVE}
|
||||
*/
|
||||
@Nullable
|
||||
ICraftingPattern getRecursedPattern();
|
||||
}
|
@@ -6,6 +6,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContaine
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorListener;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
@@ -138,12 +139,13 @@ public class CraftingManager implements ICraftingManager {
|
||||
ICraftingTask task = create(stack, toSchedule);
|
||||
|
||||
if (task != null) {
|
||||
task.calculate();
|
||||
ICraftingTaskError error = task.calculate();
|
||||
|
||||
this.add(task);
|
||||
this.onTaskChanged();
|
||||
if (error == null) {
|
||||
this.add(task);
|
||||
|
||||
return task;
|
||||
return task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType;
|
||||
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -11,9 +12,11 @@ import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
public class CraftingPreviewElementError implements ICraftingPreviewElement<ItemStack> {
|
||||
public static final String ID = "error";
|
||||
|
||||
private CraftingTaskErrorType type;
|
||||
private ItemStack stack;
|
||||
|
||||
public CraftingPreviewElementError(ItemStack stack) {
|
||||
public CraftingPreviewElementError(CraftingTaskErrorType type, ItemStack stack) {
|
||||
this.type = type;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@@ -39,17 +42,25 @@ public class CraftingPreviewElementError implements ICraftingPreviewElement<Item
|
||||
|
||||
@Override
|
||||
public boolean hasMissing() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToByteBuf(ByteBuf buf) {
|
||||
buf.writeInt(type.ordinal());
|
||||
buf.writeInt(Item.getIdFromItem(stack.getItem()));
|
||||
buf.writeInt(stack.getMetadata());
|
||||
ByteBufUtils.writeTag(buf, stack.getTagCompound());
|
||||
}
|
||||
|
||||
public CraftingTaskErrorType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static CraftingPreviewElementError fromByteBuf(ByteBuf buf) {
|
||||
int errorIdx = buf.readInt();
|
||||
CraftingTaskErrorType error = errorIdx >= 0 && errorIdx < CraftingTaskErrorType.values().length ? CraftingTaskErrorType.values()[errorIdx] : CraftingTaskErrorType.TOO_COMPLEX;
|
||||
|
||||
Item item = Item.getItemById(buf.readInt());
|
||||
int meta = buf.readInt();
|
||||
NBTTagCompound tag = ByteBufUtils.readTag(buf);
|
||||
@@ -57,7 +68,7 @@ public class CraftingPreviewElementError implements ICraftingPreviewElement<Item
|
||||
ItemStack stack = new ItemStack(item, 1, meta);
|
||||
stack.setTagCompound(tag);
|
||||
|
||||
return new CraftingPreviewElementError(stack);
|
||||
return new CraftingPreviewElementError(error, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -4,7 +4,9 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
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.CraftingTaskErrorType;
|
||||
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.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
@@ -24,17 +26,23 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingSt
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.NonNullList;
|
||||
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 INetwork network;
|
||||
private ItemStack 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;
|
||||
|
||||
private IStackList<ItemStack> toTake = API.instance().createItemStackList();
|
||||
private IStackList<ItemStack> missing = API.instance().createItemStackList();
|
||||
@@ -49,7 +57,10 @@ public class CraftingTask implements ICraftingTask {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate() {
|
||||
@Nullable
|
||||
public ICraftingTaskError calculate() {
|
||||
this.calculationStarted = System.currentTimeMillis();
|
||||
|
||||
int qty = this.quantity;
|
||||
int qtyPerCraft = getQuantityPerCraft(pattern, requested);
|
||||
int crafted = 0;
|
||||
@@ -58,7 +69,13 @@ public class CraftingTask implements ICraftingTask {
|
||||
IStackList<ItemStack> storage = network.getItemStorageCache().getList().copy();
|
||||
|
||||
while (qty > 0) {
|
||||
this.steps.add(calculateInternal(storage, results, pattern));
|
||||
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(storage, results, pattern);
|
||||
|
||||
if (result.getRight() != null) {
|
||||
return result.getRight();
|
||||
}
|
||||
|
||||
this.steps.add(result.getLeft());
|
||||
|
||||
qty -= qtyPerCraft;
|
||||
|
||||
@@ -66,9 +83,19 @@ public class CraftingTask implements ICraftingTask {
|
||||
}
|
||||
|
||||
this.toCraft.add(requested, crafted);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private CraftingStep calculateInternal(IStackList<ItemStack> mutatedStorage, IStackList<ItemStack> results, ICraftingPattern pattern) {
|
||||
private Pair<CraftingStep, ICraftingTaskError> calculateInternal(IStackList<ItemStack> mutatedStorage, IStackList<ItemStack> results, 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();
|
||||
|
||||
NonNullList<ItemStack> took = NonNullList.create();
|
||||
@@ -140,7 +167,13 @@ public class CraftingTask implements ICraftingTask {
|
||||
|
||||
if (subPattern != null) {
|
||||
while ((fromSelf == null ? 0 : fromSelf.getCount()) < remaining) {
|
||||
this.steps.add(calculateInternal(mutatedStorage, results, subPattern));
|
||||
Pair<CraftingStep, ICraftingTaskError> result = calculateInternal(mutatedStorage, results, subPattern);
|
||||
|
||||
if (result.getRight() != null) {
|
||||
return Pair.of(null, result.getRight());
|
||||
}
|
||||
|
||||
this.steps.add(result.getLeft());
|
||||
|
||||
fromSelf = results.get(possibleInput);
|
||||
if (fromSelf == null) {
|
||||
@@ -161,12 +194,14 @@ public class CraftingTask implements ICraftingTask {
|
||||
}
|
||||
}
|
||||
|
||||
patternsUsed.remove(pattern);
|
||||
|
||||
if (pattern.isProcessing()) {
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
results.add(output);
|
||||
}
|
||||
|
||||
return new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks()));
|
||||
return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks())), null);
|
||||
} else {
|
||||
results.add(pattern.getOutput(took));
|
||||
|
||||
@@ -174,7 +209,7 @@ public class CraftingTask implements ICraftingTask {
|
||||
results.add(byproduct);
|
||||
}
|
||||
|
||||
return new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took);
|
||||
return Pair.of(new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,32 @@
|
||||
package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CraftingTaskError implements ICraftingTaskError {
|
||||
private CraftingTaskErrorType type;
|
||||
private ICraftingPattern recursedPattern;
|
||||
|
||||
public CraftingTaskError(CraftingTaskErrorType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public CraftingTaskError(CraftingTaskErrorType type, ICraftingPattern recursedPattern) {
|
||||
this.type = type;
|
||||
this.recursedPattern = recursedPattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CraftingTaskErrorType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ICraftingPattern getRecursedPattern() {
|
||||
return recursedPattern;
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
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.grid.handler.IItemGridHandler;
|
||||
import com.raoulvdberge.refinedstorage.api.network.item.INetworkItem;
|
||||
@@ -11,6 +12,7 @@ import com.raoulvdberge.refinedstorage.api.network.item.NetworkItemAction;
|
||||
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IStackList;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse;
|
||||
import com.raoulvdberge.refinedstorage.network.MessageGridCraftingStartResponse;
|
||||
import com.raoulvdberge.refinedstorage.util.StackUtils;
|
||||
@@ -21,6 +23,8 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class ItemGridHandler implements IItemGridHandler {
|
||||
private INetwork network;
|
||||
|
||||
@@ -187,9 +191,11 @@ public class ItemGridHandler implements IItemGridHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
task.calculate();
|
||||
ICraftingTaskError error = task.calculate();
|
||||
|
||||
if (noPreview && task.getMissing().isEmpty()) {
|
||||
if (error != null) {
|
||||
RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(Collections.singletonList(new CraftingPreviewElementError(error.getType(), error.getRecursedPattern() == null ? ItemStack.EMPTY : error.getRecursedPattern().getStack())), hash, quantity), player);
|
||||
} else if (noPreview && task.getMissing().isEmpty()) {
|
||||
network.getCraftingManager().add(task);
|
||||
|
||||
RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player);
|
||||
@@ -230,9 +236,10 @@ public class ItemGridHandler implements IItemGridHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
task.calculate();
|
||||
|
||||
network.getCraftingManager().add(task);
|
||||
ICraftingTaskError error = task.calculate();
|
||||
if (error == null) {
|
||||
network.getCraftingManager().add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.gui;
|
||||
import com.raoulvdberge.refinedstorage.RS;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType;
|
||||
import com.raoulvdberge.refinedstorage.api.render.IElementDrawer;
|
||||
import com.raoulvdberge.refinedstorage.api.render.IElementDrawers;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError;
|
||||
@@ -25,6 +26,7 @@ import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -77,7 +79,7 @@ public class GuiCraftingPreview extends GuiBase {
|
||||
public void init(int x, int y) {
|
||||
cancelButton = addButton(x + 16, y + 144, 50, 20, t("gui.cancel"));
|
||||
startButton = addButton(x + 85, y + 144, 50, 20, t("misc.refinedstorage:start"));
|
||||
startButton.enabled = stacks.stream().noneMatch(ICraftingPreviewElement::hasMissing);
|
||||
startButton.enabled = stacks.stream().noneMatch(ICraftingPreviewElement::hasMissing) && getErrorType() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,13 +89,18 @@ public class GuiCraftingPreview extends GuiBase {
|
||||
scrollbar.setMaxOffset(getRows() - VISIBLE_ROWS);
|
||||
}
|
||||
|
||||
if (startButton != null && !startButton.enabled && isCtrlKeyDown() && isShiftKeyDown()) {
|
||||
if (startButton != null && !startButton.enabled && isCtrlKeyDown() && isShiftKeyDown() && getErrorType() == null) {
|
||||
startButton.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasErrored() {
|
||||
return stacks.size() == 1 && stacks.get(0) instanceof CraftingPreviewElementError;
|
||||
@Nullable
|
||||
private CraftingTaskErrorType getErrorType() {
|
||||
if (stacks.size() == 1 && stacks.get(0) instanceof CraftingPreviewElementError) {
|
||||
return ((CraftingPreviewElementError) stacks.get(0)).getType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,7 +109,7 @@ public class GuiCraftingPreview extends GuiBase {
|
||||
|
||||
drawTexture(x, y, 0, 0, screenWidth, screenHeight);
|
||||
|
||||
if (hasErrored()) {
|
||||
if (getErrorType() != null) {
|
||||
drawRect(x + 7, y + 20, x + 142, y + 139, 0xFFDBDBDB);
|
||||
}
|
||||
}
|
||||
@@ -116,36 +123,51 @@ public class GuiCraftingPreview extends GuiBase {
|
||||
|
||||
float scale = fontRenderer.getUnicodeFlag() ? 1F : 0.5F;
|
||||
|
||||
if (hasErrored()) {
|
||||
if (getErrorType() != null) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(scale, scale, 1);
|
||||
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 10, scale), t("gui.refinedstorage:crafting_preview.error.0"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 20, scale), t("gui.refinedstorage:crafting_preview.error.1"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 30, scale), t("gui.refinedstorage:crafting_preview.error.2"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 40, scale), t("gui.refinedstorage:crafting_preview.error.3"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 50, scale), t("gui.refinedstorage:crafting_preview.error.4"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 11, scale), t("gui.refinedstorage:crafting_preview.error"));
|
||||
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 60, scale), t("gui.refinedstorage:crafting_preview.error.5"));
|
||||
switch (getErrorType()) {
|
||||
case RECURSIVE: {
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 21, scale), t("gui.refinedstorage:crafting_preview.error.recursive.0"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 31, scale), t("gui.refinedstorage:crafting_preview.error.recursive.1"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 41, scale), t("gui.refinedstorage:crafting_preview.error.recursive.2"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 51, scale), t("gui.refinedstorage:crafting_preview.error.recursive.3"));
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 61, scale), t("gui.refinedstorage:crafting_preview.error.recursive.4"));
|
||||
|
||||
ICraftingPattern pattern = ItemPattern.getPatternFromCache(parent.mc.world, (ItemStack) stacks.get(0).getElement());
|
||||
|
||||
int yy = 80;
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
if (output != null) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(scale, scale, 1);
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 25, scale), RenderUtils.getOffsetOnScale(yy + 7, scale), output.getDisplayName());
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.enableDepth();
|
||||
drawItem(x + 5, yy, output);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
ICraftingPattern pattern = ItemPattern.getPatternFromCache(parent.mc.world, (ItemStack) stacks.get(0).getElement());
|
||||
|
||||
yy += 17;
|
||||
int yy = 83;
|
||||
for (ItemStack output : pattern.getOutputs()) {
|
||||
if (output != null) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.scale(scale, scale, 1);
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 25, scale), RenderUtils.getOffsetOnScale(yy + 6, scale), output.getDisplayName());
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.enableDepth();
|
||||
drawItem(x + 5, yy, output);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
|
||||
yy += 17;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TOO_COMPLEX: {
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 21, scale), t("gui.refinedstorage:crafting_preview.error.too_complex.0"));
|
||||
drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 31, scale), t("gui.refinedstorage:crafting_preview.error.too_complex.1"));
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.integration.oc;
|
||||
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError;
|
||||
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||
import com.raoulvdberge.refinedstorage.api.util.IComparer;
|
||||
import com.raoulvdberge.refinedstorage.apiimpl.API;
|
||||
@@ -129,9 +130,11 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment {
|
||||
throw new IllegalArgumentException("Could not create crafting task");
|
||||
}
|
||||
|
||||
task.calculate();
|
||||
ICraftingTaskError error = task.calculate();
|
||||
|
||||
node.getNetwork().getCraftingManager().add(task);
|
||||
if (error == null) {
|
||||
node.getNetwork().getCraftingManager().add(task);
|
||||
}
|
||||
|
||||
return new Object[]{};
|
||||
}
|
||||
|
@@ -55,12 +55,14 @@ gui.refinedstorage:crafting_preview=Crafting Preview
|
||||
gui.refinedstorage:crafting_preview.to_craft=To craft: %d
|
||||
gui.refinedstorage:crafting_preview.available=Available: %d
|
||||
gui.refinedstorage:crafting_preview.missing=Missing: %d
|
||||
gui.refinedstorage:crafting_preview.error.0=Cannot craft
|
||||
gui.refinedstorage:crafting_preview.error.1=One of the crafting ingredients ended up needing
|
||||
gui.refinedstorage:crafting_preview.error.2=itself.
|
||||
gui.refinedstorage:crafting_preview.error.3=You need to remove the pattern or make sure
|
||||
gui.refinedstorage:crafting_preview.error.4=the pattern is not used during crafting.
|
||||
gui.refinedstorage:crafting_preview.error.5=Offending pattern:
|
||||
gui.refinedstorage:crafting_preview.error=Request failed
|
||||
gui.refinedstorage:crafting_preview.error.recursive.0=One of the crafting ingredients ended up needing
|
||||
gui.refinedstorage:crafting_preview.error.recursive.1=itself.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.2=You need to remove the pattern or make sure
|
||||
gui.refinedstorage:crafting_preview.error.recursive.3=the pattern is not used during crafting.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.4=Offending pattern:
|
||||
gui.refinedstorage:crafting_preview.error.too_complex.0=The crafting task calculation was too complex
|
||||
gui.refinedstorage:crafting_preview.error.too_complex.1=and was stopped to avoid server strain.
|
||||
gui.refinedstorage:crafting_preview.force_start=Press CTRL + SHIFT to ignore
|
||||
gui.refinedstorage:reader=Reader
|
||||
gui.refinedstorage:writer=Writer
|
||||
|
@@ -52,12 +52,12 @@ gui.refinedstorage:crafting_preview=Avance de Fabricación
|
||||
gui.refinedstorage:crafting_preview.to_craft=Para fabricar: %d
|
||||
gui.refinedstorage:crafting_preview.available=Disponible: %d
|
||||
gui.refinedstorage:crafting_preview.missing=Falta: %d
|
||||
gui.refinedstorage:crafting_preview.error.0=No puede fabricar
|
||||
gui.refinedstorage:crafting_preview.error.1=Uno de los objetos de creación termino faltando
|
||||
gui.refinedstorage:crafting_preview.error.2=sí mismo.
|
||||
gui.refinedstorage:crafting_preview.error.3=Necesita remover el patrón o revisarlo
|
||||
gui.refinedstorage:crafting_preview.error.4=el patrón no se usa para la fabricación.
|
||||
gui.refinedstorage:crafting_preview.error.5=Patrón ofensivo:
|
||||
gui.refinedstorage:crafting_preview.error=No puede fabricar
|
||||
gui.refinedstorage:crafting_preview.error.recursive.0=Uno de los objetos de creación termino faltando
|
||||
gui.refinedstorage:crafting_preview.error.recursive.1=sí mismo.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.2=Necesita remover el patrón o revisarlo
|
||||
gui.refinedstorage:crafting_preview.error.recursive.3=el patrón no se usa para la fabricación.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.4=Patrón ofensivo:
|
||||
gui.refinedstorage:crafting_preview.force_start=Presiona CTRL + SHIFT para forzar el inicio
|
||||
gui.refinedstorage:reader=Lector
|
||||
gui.refinedstorage:writer=Escritor
|
||||
|
@@ -52,12 +52,12 @@ gui.refinedstorage:crafting_preview=Предварительный просмо
|
||||
gui.refinedstorage:crafting_preview.to_craft=Создать: %d
|
||||
gui.refinedstorage:crafting_preview.available=Доступно: %d
|
||||
gui.refinedstorage:crafting_preview.missing=Отсутствует: %d
|
||||
gui.refinedstorage:crafting_preview.error.0=Не удается создать
|
||||
gui.refinedstorage:crafting_preview.error.1=Один из ингредиентов для крафта оказался нуждающимся
|
||||
gui.refinedstorage:crafting_preview.error.2=в себе.
|
||||
gui.refinedstorage:crafting_preview.error.3=Вам нужно удалить шаблон или убедиться, что
|
||||
gui.refinedstorage:crafting_preview.error.4=шаблон не используется во время обработки.
|
||||
gui.refinedstorage:crafting_preview.error.5=Нарушение шаблона:
|
||||
gui.refinedstorage:crafting_preview.error=Не удается создать
|
||||
gui.refinedstorage:crafting_preview.error.recursive.0=Один из ингредиентов для крафта оказался нуждающимся
|
||||
gui.refinedstorage:crafting_preview.error.recursive.1=в себе.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.2=Вам нужно удалить шаблон или убедиться, что
|
||||
gui.refinedstorage:crafting_preview.error.recursive.3=шаблон не используется во время обработки.
|
||||
gui.refinedstorage:crafting_preview.error.recursive.4=Нарушение шаблона:
|
||||
gui.refinedstorage:crafting_preview.force_start=Нажмите CTRL + SHIFT, чтобы все равно начать
|
||||
gui.refinedstorage:reader=Устройство чтения
|
||||
gui.refinedstorage:writer=Устройство записи
|
||||
|
Reference in New Issue
Block a user