diff --git a/CHANGELOG.md b/CHANGELOG.md index 182cdecf2..3a53dd0a5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Refined Storage Changelog +### 1.6.12 +- Increased the speed of autocrafting (raoulvdberge) +- Added a completion percentage to the Crafting Monitor (raoulvdberge) +- Updated Russian translation (kellixon) + ### 1.6.11 - Fixed blocks neighboring a controller breaking when returning from a dimension in a unchunkloaded area (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java index ca58dec09..c63051e0f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -16,9 +16,37 @@ import java.util.UUID; */ public interface ICraftingPatternContainer { /** + * @deprecated Use {@link #getUpdateInterval()} and/or {@link #getMaximumSuccessfulCraftingUpdates()} * @return the amount of speed upgrades in the container */ - int getSpeedUpgradeCount(); + @Deprecated + default int getSpeedUpgradeCount() { + return 0; + } + + /** + * Returns the interval of when a crafting step with a pattern in this container can update. + * Minimum value is 0 (each tick). + *

+ * Note: rather than maxing out the update interval, implementors might want to balance around {@link #getMaximumSuccessfulCraftingUpdates()}. + * This method merely speeds up the update rate, it might be more interesting to increase the output rate in {@link #getMaximumSuccessfulCraftingUpdates()}. + * + * @return the update interval + */ + default int getUpdateInterval() { + return 10; + } + + /** + * Returns the amount of successful crafting updates that this container can have per crafting step update. + * If this limit is reached, crafting patterns from this container won't be able to update until the next + * eligible crafting step update interval from {@link #getUpdateInterval()}. + * + * @return the maximum amount of successful crafting updates + */ + default int getMaximumSuccessfulCraftingUpdates() { + return 1; + } /** * @return the inventory that this container is connected to, or null if no inventory is present diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java index 683e39e69..875a98749 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java @@ -47,6 +47,13 @@ public interface ICraftingTask { */ int getQuantityPerCraft(); + /** + * @return the completion percentage + */ + default int getCompletionPercentage() { + return 0; + } + /** * @return the stack requested */ 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 978d832a4..eafc6a252 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 @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; +import com.google.common.collect.Maps; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.*; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; @@ -56,6 +57,7 @@ public class CraftingTask implements ICraftingTask { private static final String NBT_PROCESSING = "Processing"; private static final String NBT_MISSING = "Missing"; private static final String NBT_MISSING_FLUIDS = "MissingFluids"; + private static final String NBT_TOTAL_STEPS = "TotalSteps"; private static final String NBT_PATTERN_STACK = "Stack"; private static final String NBT_PATTERN_CONTAINER_POS = "ContainerPos"; @@ -72,6 +74,7 @@ public class CraftingTask implements ICraftingTask { private int ticks; private long calculationStarted = -1; private long executionStarted = -1; + private int totalSteps; private Set patternsUsed = new HashSet<>(); private IStorageDisk internalStorage; @@ -118,6 +121,10 @@ public class CraftingTask implements ICraftingTask { this.id = tag.getUniqueId(NBT_ID); this.executionStarted = tag.getLong(NBT_EXECUTION_STARTED); + if (tag.hasKey(NBT_TOTAL_STEPS)) { + totalSteps = tag.getInteger(NBT_TOTAL_STEPS); + } + StorageDiskFactoryItem factoryItem = new StorageDiskFactoryItem(); StorageDiskFactoryFluid factoryFluid = new StorageDiskFactoryFluid(); @@ -153,6 +160,7 @@ public class CraftingTask implements ICraftingTask { tag.setTag(NBT_INTERNAL_FLUID_STORAGE, internalFluidStorage.writeToNbt()); tag.setTag(NBT_TO_EXTRACT_INITIAL, writeItemStackList(toExtractInitial)); tag.setTag(NBT_TO_EXTRACT_INITIAL_FLUIDS, writeFluidStackList(toExtractInitialFluids)); + tag.setInteger(NBT_TOTAL_STEPS, totalSteps); NBTTagList craftingList = new NBTTagList(); for (Crafting crafting : this.crafting) { @@ -535,23 +543,6 @@ public class CraftingTask implements ICraftingTask { 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 toRemove = new ArrayList<>(); @@ -601,10 +592,24 @@ public class CraftingTask implements ICraftingTask { private void updateCrafting() { Iterator it = crafting.iterator(); + Map counter = Maps.newHashMap(); + while (it.hasNext()) { Crafting c = it.next(); - if (ticks % getTickInterval(c.getPattern().getContainer().getSpeedUpgradeCount()) == 0) { + ICraftingPatternContainer container = c.getPattern().getContainer(); + + int interval = container.getUpdateInterval(); + + if (interval < 0) { + throw new IllegalStateException(c.getPattern().getContainer() + " has an update interval of < 0"); + } + + if (interval == 0 || ticks % interval == 0) { + if (counter.getOrDefault(container, 0) == container.getMaximumSuccessfulCraftingUpdates()) { + continue; + } + boolean hasAll = true; for (ItemStack need : c.getToExtract().getStacks()) { @@ -648,7 +653,7 @@ public class CraftingTask implements ICraftingTask { network.getCraftingManager().onTaskChanged(); - return; + counter.merge(container, 1, (a, b) -> a + b); } } } @@ -657,9 +662,13 @@ public class CraftingTask implements ICraftingTask { private void updateProcessing() { Iterator it = processing.iterator(); + Map counter = Maps.newHashMap(); + while (it.hasNext()) { Processing p = it.next(); + ICraftingPatternContainer container = p.getPattern().getContainer(); + if (p.getState() == ProcessingState.PROCESSED) { it.remove(); @@ -672,7 +681,17 @@ public class CraftingTask implements ICraftingTask { continue; } - if (ticks % getTickInterval(p.getPattern().getContainer().getSpeedUpgradeCount()) == 0) { + int interval = p.getPattern().getContainer().getUpdateInterval(); + + if (interval < 0) { + throw new IllegalStateException(p.getPattern().getContainer() + " has an update interval of < 0"); + } + + if (interval == 0 || ticks % interval == 0) { + if (counter.getOrDefault(container, 0) == container.getMaximumSuccessfulCraftingUpdates()) { + continue; + } + ProcessingState originalState = p.getState(); if (p.getPattern().getContainer().isLocked()) { @@ -751,6 +770,8 @@ public class CraftingTask implements ICraftingTask { p.setState(ProcessingState.EXTRACTED_ALL); p.getPattern().getContainer().onUsedForProcessing(); + + counter.merge(container, 1, (a, b) -> a + b); } } @@ -798,6 +819,15 @@ public class CraftingTask implements ICraftingTask { return current == null && stacks.isEmpty(); } + @Override + public int getCompletionPercentage() { + if (totalSteps == 0) { + return 0; + } + + return 100 - (int) (((float) (crafting.size() + processing.size()) / (float) totalSteps) * 100F); + } + @Override public boolean update() { if (hasMissing()) { @@ -808,6 +838,8 @@ public class CraftingTask implements ICraftingTask { if (executionStarted == -1) { executionStarted = System.currentTimeMillis(); + + totalSteps = crafting.size() + processing.size(); } ++ticks; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java index ac6724287..63185ae60 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeCrafter.java @@ -228,8 +228,39 @@ public class NetworkNodeCrafter extends NetworkNode implements ICraftingPatternC } @Override - public int getSpeedUpgradeCount() { - return upgrades.getUpgradeCount(ItemUpgrade.TYPE_SPEED); + public int getUpdateInterval() { + switch (upgrades.getUpgradeCount(ItemUpgrade.TYPE_SPEED)) { + case 0: + return 10; + case 1: + return 8; + case 2: + return 6; + case 3: + return 4; + case 4: + return 2; + default: + return 0; + } + } + + @Override + public int getMaximumSuccessfulCraftingUpdates() { + switch (upgrades.getUpgradeCount(ItemUpgrade.TYPE_SPEED)) { + case 0: + return 1; + case 1: + return 2; + case 2: + return 3; + case 3: + return 4; + case 4: + return 5; + default: + return 1; + } } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java index 2302d24dd..2e0231b0e 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingMonitor.java @@ -64,13 +64,15 @@ public class GuiCraftingMonitor extends GuiBase { private ICraftingRequestInfo requested; private int qty; private long executionStarted; + private int completionPercentage; private List elements; - public CraftingMonitorTask(UUID id, ICraftingRequestInfo requested, int qty, long executionStarted, List elements) { + public CraftingMonitorTask(UUID id, ICraftingRequestInfo requested, int qty, long executionStarted, int completionPercentage, List elements) { this.id = id; this.requested = requested; this.qty = qty; this.executionStarted = executionStarted; + this.completionPercentage = completionPercentage; this.elements = elements; } @@ -90,6 +92,7 @@ public class GuiCraftingMonitor extends GuiBase { smallTextLines.add(I18n.format("gui.refinedstorage:crafting_monitor.tooltip.requested", requested.getFluid() != null ? API.instance().getQuantityFormatter().formatInBucketForm(qty) : API.instance().getQuantityFormatter().format(qty))); smallTextLines.add(String.format("%02d:%02d", minutes, seconds)); + smallTextLines.add(String.format("%d%%", completionPercentage)); RenderUtils.drawTooltipWithSmallText(textLines, smallTextLines, true, ItemStack.EMPTY, x, y, screenWidth, screenHeight, fontRenderer); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java index 6061bef73..5e68dec24 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageCraftingMonitorElements.java @@ -48,6 +48,7 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler int qty = buf.readInt(); long executionStarted = buf.readLong(); + int percentage = buf.readInt(); List elements = new ArrayList<>(); @@ -61,7 +62,7 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler } } - tasks.add(new GuiCraftingMonitor.CraftingMonitorTask(id, requested, qty, executionStarted, elements)); + tasks.add(new GuiCraftingMonitor.CraftingMonitorTask(id, requested, qty, executionStarted, percentage, elements)); } } @@ -74,6 +75,7 @@ public class MessageCraftingMonitorElements implements IMessage, IMessageHandler ByteBufUtils.writeTag(buf, task.getRequested().writeToNbt()); buf.writeInt(task.getQuantity()); buf.writeLong(task.getExecutionStarted()); + buf.writeInt(task.getCompletionPercentage()); List elements = task.getCraftingMonitorElements();