From 2f0b01b262ce96cb98ebff9578756d975eea47cd Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Tue, 19 Jun 2018 23:38:14 +0200 Subject: [PATCH] Fixes issue #1575 "Using interfaces for minimum stock levels fails when requester is also an interface". --- .../api/autocrafting/ICraftingManager.java | 10 ++- .../apiimpl/autocrafting/CraftingManager.java | 5 ++ .../autocrafting/CraftingRequester.java | 84 +++++++++++++++++++ .../network/node/NetworkNodeInterface.java | 14 +++- 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingRequester.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java index a6e7f1ab7..aa4b48cd1 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java @@ -22,6 +22,14 @@ public interface ICraftingManager { */ Collection getTasks(); + /** + * Returns a crafting task by id. + * + * @param id the id + * @return the task, or null if no task was found for the given id + */ + ICraftingTask getTask(UUID id); + /** * @return named crafting pattern containers */ @@ -42,7 +50,7 @@ public interface ICraftingManager { void cancel(@Nullable UUID id); /** - * Creates a crafting task for a given stack. + * Creates a crafting task for a given stack, but doesn't add it to the list. * * @param stack the stack to craft * @param quantity the quantity to craft diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java index 3a36b6867..8d1cdfbf9 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -49,6 +49,11 @@ public class CraftingManager implements ICraftingManager { return tasks.values(); } + @Override + public ICraftingTask getTask(UUID id) { + return tasks.get(id); + } + @Override public Map> getNamedContainers() { return containerInventories; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingRequester.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingRequester.java new file mode 100644 index 000000000..f1f161e79 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingRequester.java @@ -0,0 +1,84 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting; + +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 net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import java.util.UUID; + +public class CraftingRequester { + private static final String NBT_TASK_ID = "TaskId"; + private static final String NBT_ALLOW_REQUEST = "AllowRequest"; + + private UUID taskId; + private INetworkNode node; + private boolean allowRequest = true; + + public CraftingRequester(INetworkNode node) { + this.node = node; + } + + public void request(ItemStack stack, int quantity) { + INetwork network = node.getNetwork(); + + if (network != null) { + if (taskId != null && network.getCraftingManager().getTask(taskId) == null) { + this.taskId = null; + + this.node.markDirty(); + } + + // Only allow a request if we have no current task running. + // Only allow a request if we received all items from a previous request. + // We can only check if we received all items with a flag, because there is a delay in finishing the task + // and actually receiving the items. + if (taskId == null && allowRequest) { + ICraftingTask task = network.getCraftingManager().create(stack, quantity); + + if (task != null) { + ICraftingTaskError error = task.calculate(); + + if (error == null) { + network.getCraftingManager().add(task); + + this.allowRequest = false; + this.taskId = task.getId(); + + this.node.markDirty(); + } + } + } + } + } + + public void setAllowRequest() { + if (!allowRequest) { + this.allowRequest = true; + + this.node.markDirty(); + } + } + + public void readFromNbt(NBTTagCompound tag) { + if (tag.hasUniqueId(NBT_TASK_ID)) { + taskId = tag.getUniqueId(NBT_TASK_ID); + } + + allowRequest = tag.getBoolean(NBT_ALLOW_REQUEST); + } + + public NBTTagCompound writeToNbt() { + NBTTagCompound tag = new NBTTagCompound(); + + if (taskId != null) { + tag.setUniqueId(NBT_TASK_ID, taskId); + } + + tag.setBoolean(NBT_ALLOW_REQUEST, allowRequest); + + return tag; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java index 487fa5d04..0eee80bcb 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java @@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.CraftingRequester; import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageItemItemHandler; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode; @@ -22,6 +23,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { public static final String ID = "interface"; private static final String NBT_COMPARE = "Compare"; + private static final String NBT_REQUESTER = "Requester"; private ItemHandlerBase importItems = new ItemHandlerBase(9, new ItemHandlerListenerNetworkNode(this)); @@ -36,6 +38,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { private int currentSlot = 0; + private CraftingRequester requester = new CraftingRequester(this); + public NetworkNodeInterface(World world, BlockPos pos) { super(world, pos); } @@ -104,7 +108,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { delta -= result == null ? 0 : result.getCount(); if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().schedule(wanted, delta); + requester.request(wanted, delta); } } else if (delta < 0) { ItemStack remainder = network.insertItemTracked(got, Math.abs(delta)); @@ -114,6 +118,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { } else { exportItems.extractItem(i, Math.abs(delta) - remainder.getCount(), false); } + } else { + requester.setAllowRequest(); } } } @@ -138,6 +144,10 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { StackUtils.readItems(importItems, 0, tag); StackUtils.readItems(exportItems, 2, tag); StackUtils.readItems(upgrades, 3, tag); + + if (tag.hasKey(NBT_REQUESTER)) { + requester.readFromNbt(tag.getCompoundTag(NBT_REQUESTER)); + } } @Override @@ -153,6 +163,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { StackUtils.writeItems(exportItems, 2, tag); StackUtils.writeItems(upgrades, 3, tag); + tag.setTag(NBT_REQUESTER, requester.writeToNbt()); + return tag; }