diff --git a/CHANGELOG.md b/CHANGELOG.md index 390be6e84..39f83fc9a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Refined Storage Changelog +### 1.5.31 +- Improved the "cannot craft! loop in processing..." error message (raoulvdberge) + ### 1.5.30 - Fixed crashing bug when MCMultiPart is not installed (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java new file mode 100644 index 000000000..f9266e70e --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java @@ -0,0 +1,67 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview; + +import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement; +import com.raoulvdberge.refinedstorage.api.render.IElementDrawers; +import io.netty.buffer.ByteBuf; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.common.network.ByteBufUtils; + +public class CraftingPreviewElementError implements ICraftingPreviewElement { + public static final String ID = "error"; + + private ItemStack stack; + + public CraftingPreviewElementError(ItemStack stack) { + this.stack = stack; + } + + @Override + public ItemStack getElement() { + return stack; + } + + @Override + public void draw(int x, int y, IElementDrawers drawers) { + // NO OP + } + + @Override + public int getAvailable() { + return 0; + } + + @Override + public int getToCraft() { + return 0; + } + + @Override + public boolean hasMissing() { + return true; + } + + @Override + public void writeToByteBuf(ByteBuf buf) { + buf.writeInt(Item.getIdFromItem(stack.getItem())); + buf.writeInt(stack.getMetadata()); + ByteBufUtils.writeTag(buf, stack.getTagCompound()); + } + + public static CraftingPreviewElementError fromByteBuf(ByteBuf buf) { + Item item = Item.getItemById(buf.readInt()); + int meta = buf.readInt(); + NBTTagCompound tag = ByteBufUtils.readTag(buf); + + ItemStack stack = new ItemStack(item, 1, meta); + stack.setTagCompound(tag); + + return new CraftingPreviewElementError(stack); + } + + @Override + public String getId() { + return ID; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index b95337f8f..41921653f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -16,6 +16,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.Craf import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementInfo; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText; +import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; import com.raoulvdberge.refinedstorage.apiimpl.util.StackListItem; @@ -57,7 +58,7 @@ public class CraftingTask implements ICraftingTask { private IStackList missing = API.instance().createItemStackList(); private Set usedPatterns = new HashSet<>(); - private boolean recurseFound = false; + private ICraftingPattern recursedPattern = null; private Deque toInsertItems = new ArrayDeque<>(); private Deque toInsertFluids = new ArrayDeque<>(); @@ -102,7 +103,7 @@ public class CraftingTask implements ICraftingTask { int quantity = this.quantity; ICraftingPattern currentPattern; - while (quantity > 0 && !recurseFound) { + while (quantity > 0 && recursedPattern == null) { currentPattern = this.chain == null ? this.pattern : this.chain.cycle(); mainSteps.add(calculate(networkList, networkFluidList, currentPattern, toInsert)); @@ -115,8 +116,8 @@ public class CraftingTask implements ICraftingTask { @Nullable private ICraftingStep calculate(IStackList networkItems, IStackList networkFluids, ICraftingPattern pattern, IStackList toInsert) { - recurseFound |= !usedPatterns.add(pattern); - if (recurseFound) { + if (!usedPatterns.add(pattern)) { + recursedPattern = pattern; return null; } @@ -252,7 +253,7 @@ public class CraftingTask implements ICraftingTask { input.shrink(craftQuantity); - if (!recurseFound) { + if (recursedPattern == null) { // Calculate added all the crafted outputs toInsert // So we remove the ones we use from toInsert ItemStack inserted = toInsert.get(inputCrafted, compare); @@ -708,7 +709,7 @@ public class CraftingTask implements ICraftingTask { @Override public boolean isValid() { - return !recurseFound; + return recursedPattern == null; } @Override @@ -719,7 +720,7 @@ public class CraftingTask implements ICraftingTask { @Override public List getPreviewStacks() { if (!isValid()) { - return Collections.emptyList(); + return Collections.singletonList(new CraftingPreviewElementError(recursedPattern.getStack())); } Map map = new LinkedHashMap<>(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java index 227934c73..c60da218f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java @@ -1,11 +1,14 @@ 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.render.IElementDrawer; import com.raoulvdberge.refinedstorage.api.render.IElementDrawers; +import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; +import com.raoulvdberge.refinedstorage.item.ItemPattern; import com.raoulvdberge.refinedstorage.network.MessageGridCraftingStart; import com.raoulvdberge.refinedstorage.util.RenderUtils; import net.minecraft.client.Minecraft; @@ -88,13 +91,17 @@ public class GuiCraftingPreview extends GuiBase { } } + private boolean hasErrored() { + return stacks.size() == 1 && stacks.get(0) instanceof CraftingPreviewElementError; + } + @Override public void drawBackground(int x, int y, int mouseX, int mouseY) { bindTexture("gui/crafting_preview.png"); drawTexture(x, y, 0, 0, screenWidth, screenHeight); - if (stacks.isEmpty()) { + if (hasErrored()) { drawRect(x + 7, y + 20, x + 142, y + 139, 0xFFDBDBDB); } } @@ -108,14 +115,38 @@ public class GuiCraftingPreview extends GuiBase { float scale = fontRenderer.getUnicodeFlag() ? 1F : 0.5F; - if (stacks.isEmpty()) { + if (hasErrored()) { GlStateManager.pushMatrix(); GlStateManager.scale(scale, scale, 1); - drawString(RenderUtils.getOffsetOnScale(x + 39, scale), RenderUtils.getOffsetOnScale(y + 57, scale), t("gui.refinedstorage:crafting_preview.circular")); - drawString(RenderUtils.getOffsetOnScale(x + 40, scale), RenderUtils.getOffsetOnScale(y + 64, scale), t("gui.refinedstorage:crafting_preview.loop")); + 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 + 60, scale), t("gui.refinedstorage:crafting_preview.error.5")); GlStateManager.popMatrix(); + + ICraftingPattern pattern = ItemPattern.getPatternFromCache(parent.mc.world, (ItemStack) stacks.get(0).getElement()); + + int yy = 80; + for (ItemStack input : pattern.getOutputs()) { + if (input != null) { + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, 1); + drawString(RenderUtils.getOffsetOnScale(x + 25, scale), RenderUtils.getOffsetOnScale(yy + 7, scale), input.getDisplayName()); + GlStateManager.popMatrix(); + + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.enableDepth(); + drawItem(x + 5, yy, input); + RenderHelper.disableStandardItemLighting(); + + yy += 17; + } + } } else { int slot = scrollbar != null ? (scrollbar.getOffset() * 2) : 0; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java index fbfd10770..8daec61c8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java @@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.RSItems; import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.*; +import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory; @@ -100,6 +101,7 @@ public class ProxyCommon { API.instance().getCraftingPreviewElementRegistry().add(CraftingPreviewElementItemStack.ID, CraftingPreviewElementItemStack::fromByteBuf); API.instance().getCraftingPreviewElementRegistry().add(CraftingPreviewElementFluidStack.ID, CraftingPreviewElementFluidStack::fromByteBuf); + API.instance().getCraftingPreviewElementRegistry().add(CraftingPreviewElementError.ID, CraftingPreviewElementError::fromByteBuf); API.instance().getReaderWriterHandlerRegistry().add(ReaderWriterHandlerItems.ID, ReaderWriterHandlerItems::new); API.instance().getReaderWriterHandlerRegistry().add(ReaderWriterHandlerFluids.ID, ReaderWriterHandlerFluids::new); diff --git a/src/main/resources/assets/refinedstorage/lang/en_us.lang b/src/main/resources/assets/refinedstorage/lang/en_us.lang index daed7e9cb..474ceaa46 100644 --- a/src/main/resources/assets/refinedstorage/lang/en_us.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_us.lang @@ -54,8 +54,12 @@ 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.circular=Circular dependency! -gui.refinedstorage:crafting_preview.loop=Loop in processing... +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.force_start=Press CTRL + SHIFT to start anyway gui.refinedstorage:reader=Reader gui.refinedstorage:writer=Writer