diff --git a/src/main/java/refinedstorage/api/autocrafting/task/ICraftingTask.java b/src/main/java/refinedstorage/api/autocrafting/task/ICraftingTask.java index c370ca615..81b43b882 100755 --- a/src/main/java/refinedstorage/api/autocrafting/task/ICraftingTask.java +++ b/src/main/java/refinedstorage/api/autocrafting/task/ICraftingTask.java @@ -1,10 +1,12 @@ package refinedstorage.api.autocrafting.task; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; import refinedstorage.api.autocrafting.preview.ICraftingPreviewElement; +import javax.annotation.Nullable; import java.util.List; /** @@ -15,6 +17,7 @@ public interface ICraftingTask { String NBT_PATTERN_ID = "PatternID"; String NBT_PATTERN_STACK = "PatternStack"; String NBT_PATTERN_CONTAINER = "PatternContainer"; + String NBT_REQUESTED = "Requested"; /** * Calculates what this task will do, but doesn't run the task just yet. @@ -39,6 +42,12 @@ public interface ICraftingTask { */ int getQuantity(); + /** + * @return the stack requested + */ + @Nullable + ItemStack getRequested(); + /** * Writes this task to NBT. * @@ -47,6 +56,25 @@ public interface ICraftingTask { */ NBTTagCompound writeToNBT(NBTTagCompound tag); + /** + * Helper method to write default neccesary elements to NBT. + * + * @param tag the tag + * @return the written tag + */ + default NBTTagCompound writeDefaultsToNBT(NBTTagCompound tag) { + tag.setInteger(NBT_QUANTITY, getQuantity()); + tag.setString(NBT_PATTERN_ID, getPattern().getId()); + tag.setTag(NBT_PATTERN_STACK, getPattern().getStack().serializeNBT()); + tag.setLong(NBT_PATTERN_CONTAINER, getPattern().getContainer().getPosition().toLong()); + + if (getRequested() != null) { + tag.setTag(NBT_REQUESTED, getRequested().serializeNBT()); + } + + return tag; + } + /** * {@link ICraftingTask#calculate()} must be run before this * diff --git a/src/main/java/refinedstorage/api/autocrafting/task/IProcessable.java b/src/main/java/refinedstorage/api/autocrafting/task/IProcessable.java index 36b2bee75..11e631100 100755 --- a/src/main/java/refinedstorage/api/autocrafting/task/IProcessable.java +++ b/src/main/java/refinedstorage/api/autocrafting/task/IProcessable.java @@ -1,6 +1,7 @@ package refinedstorage.api.autocrafting.task; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import refinedstorage.api.autocrafting.ICraftingPattern; import java.util.Deque; @@ -35,4 +36,12 @@ public interface IProcessable { * @return true if this item belonged to the processable item, false otherwise */ boolean onReceiveOutput(ItemStack stack); + + /** + * Writes the processable to NBT. + * + * @param tag the tag + * @return the written tag + */ + NBTTagCompound writeToNBT(NBTTagCompound tag); } diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java b/src/main/java/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java index 2ee668008..d88bdd255 100755 --- a/src/main/java/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java @@ -2,15 +2,26 @@ package refinedstorage.apiimpl.autocrafting.registry; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.FluidStack; +import refinedstorage.RSUtils; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.registry.ICraftingTaskFactory; import refinedstorage.api.autocrafting.task.ICraftingTask; +import refinedstorage.api.autocrafting.task.IProcessable; import refinedstorage.api.network.INetworkMaster; +import refinedstorage.api.util.IFluidStackList; +import refinedstorage.api.util.IItemStackList; import refinedstorage.apiimpl.autocrafting.task.CraftingTask; +import refinedstorage.apiimpl.autocrafting.task.Processable; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; public class CraftingTaskFactory implements ICraftingTaskFactory { public static final String ID = "normal"; @@ -18,6 +29,57 @@ public class CraftingTaskFactory implements ICraftingTaskFactory { @Override @Nonnull public ICraftingTask create(World world, INetworkMaster network, @Nullable ItemStack stack, ICraftingPattern pattern, int quantity, @Nullable NBTTagCompound tag) { + if (tag != null) { + NBTTagList toProcessList = tag.getTagList(CraftingTask.NBT_TO_PROCESS, Constants.NBT.TAG_COMPOUND); + + List toProcess = new ArrayList<>(); + + for (int i = 0; i < toProcessList.tagCount(); ++i) { + toProcess.add(new Processable(pattern, toProcessList.getCompoundTagAt(i))); + } + + IItemStackList toTake = RSUtils.readItemStackList(tag.getTagList(CraftingTask.NBT_TO_TAKE, Constants.NBT.TAG_COMPOUND)); + IFluidStackList toTakeFluids = RSUtils.readFluidStackList(tag.getTagList(CraftingTask.NBT_TO_TAKE_FLUIDS, Constants.NBT.TAG_COMPOUND)); + + NBTTagList toInsertList = tag.getTagList(CraftingTask.NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND); + + List toInsert = new ArrayList<>(); + + for (int i = 0; i < toInsertList.tagCount(); ++i) { + ItemStack insertStack = ItemStack.loadItemStackFromNBT(toInsertList.getCompoundTagAt(i)); + + if (insertStack != null) { + toInsert.add(insertStack); + } + } + + NBTTagList tookList = tag.getTagList(CraftingTask.NBT_TOOK, Constants.NBT.TAG_COMPOUND); + + List took = new ArrayList<>(); + + for (int i = 0; i < tookList.tagCount(); ++i) { + ItemStack tookStack = ItemStack.loadItemStackFromNBT(tookList.getCompoundTagAt(i)); + + if (tookStack != null) { + took.add(tookStack); + } + } + + NBTTagList tookFluidsList = tag.getTagList(CraftingTask.NBT_TOOK_FLUIDS, Constants.NBT.TAG_COMPOUND); + + List tookFluids = new ArrayList<>(); + + for (int i = 0; i < tookFluidsList.tagCount(); ++i) { + FluidStack tookStack = FluidStack.loadFluidStackFromNBT(tookList.getCompoundTagAt(i)); + + if (tookStack != null) { + tookFluids.add(tookStack); + } + } + + return new CraftingTask(network, stack, pattern, quantity, toProcess, toTake, toTakeFluids, new ArrayDeque(toInsert), took, tookFluids); + } + return new CraftingTask(network, stack, pattern, quantity); } } \ No newline at end of file diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index a85657fb1..5991f2179 100755 --- a/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -2,6 +2,7 @@ package refinedstorage.apiimpl.autocrafting.task; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; @@ -22,13 +23,22 @@ import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElemen import refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; +import javax.annotation.Nullable; import java.util.*; import java.util.stream.Collectors; public class CraftingTask implements ICraftingTask { private static final int DEFAULT_COMPARE = IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT; + public static final String NBT_TO_PROCESS = "ToProcess"; + public static final String NBT_TO_TAKE = "ToTake"; + public static final String NBT_TO_TAKE_FLUIDS = "ToTakeFluids"; + public static final String NBT_TO_INSERT = "ToInsert"; + public static final String NBT_TOOK = "Took"; + public static final String NBT_TOOK_FLUIDS = "TookFluids"; + private INetworkMaster network; + @Nullable private ItemStack requested; private ICraftingPattern pattern; private int quantity; @@ -43,13 +53,24 @@ public class CraftingTask implements ICraftingTask { private List took = new ArrayList<>(); private List tookFluids = new ArrayList<>(); - public CraftingTask(INetworkMaster network, ItemStack requested, ICraftingPattern pattern, int quantity) { + public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity) { this.network = network; this.requested = requested; this.pattern = pattern; this.quantity = quantity; } + public CraftingTask(INetworkMaster network, @Nullable ItemStack requested, ICraftingPattern pattern, int quantity, List toProcess, IItemStackList toTake, IFluidStackList toTakeFluids, Deque toInsert, List took, List tookFluids) { + this(network, requested, pattern, quantity); + + this.toProcess = toProcess; + this.toTake = toTake; + this.toTakeFluids = toTakeFluids; + this.toInsert = toInsert; + this.took = took; + this.tookFluids = tookFluids; + } + @Override public void calculate() { IItemStackList networkList = network.getItemStorageCache().getList().copy(); @@ -269,8 +290,51 @@ public class CraftingTask implements ICraftingTask { return quantity; } + @Nullable + @Override + public ItemStack getRequested() { + return requested; + } + @Override public NBTTagCompound writeToNBT(NBTTagCompound tag) { + writeDefaultsToNBT(tag); + + NBTTagList processablesList = new NBTTagList(); + + for (IProcessable processable : toProcess) { + processablesList.appendTag(processable.writeToNBT(new NBTTagCompound())); + } + + tag.setTag(NBT_TO_PROCESS, processablesList); + + tag.setTag(NBT_TO_TAKE, RSUtils.serializeItemStackList(toTake)); + tag.setTag(NBT_TO_TAKE_FLUIDS, RSUtils.serializeFluidStackList(toTakeFluids)); + + NBTTagList toInsertList = new NBTTagList(); + + for (ItemStack insert : new ArrayList<>(toInsert)) { + toInsertList.appendTag(insert.serializeNBT()); + } + + tag.setTag(NBT_TO_INSERT, toInsertList); + + NBTTagList tookList = new NBTTagList(); + + for (ItemStack took : this.took) { + tookList.appendTag(took.serializeNBT()); + } + + tag.setTag(NBT_TOOK, tookList); + + NBTTagList fluidsTookList = new NBTTagList(); + + for (FluidStack took : this.tookFluids) { + fluidsTookList.appendTag(took.writeToNBT(new NBTTagCompound())); + } + + tag.setTag(NBT_TOOK_FLUIDS, fluidsTookList); + return tag; } @@ -280,7 +344,7 @@ public class CraftingTask implements ICraftingTask { elements.add(new CraftingMonitorElementItemRender( network.getCraftingTasks().indexOf(this), - pattern.getOutputs().get(0), + requested != null ? requested : pattern.getOutputs().get(0), quantity, 0 )); diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/task/Processable.java b/src/main/java/refinedstorage/apiimpl/autocrafting/task/Processable.java index 57bc3bc90..246eb5687 100755 --- a/src/main/java/refinedstorage/apiimpl/autocrafting/task/Processable.java +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/task/Processable.java @@ -1,14 +1,22 @@ package refinedstorage.apiimpl.autocrafting.task; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.task.IProcessable; import refinedstorage.apiimpl.API; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Deque; +import java.util.List; public class Processable implements IProcessable { + private static final String NBT_SATISFIED = "Satisfied_%d"; + private static final String NBT_TO_INSERT = "ToInsert"; + private ICraftingPattern pattern; private Deque toInsert = new ArrayDeque<>(); private boolean satisfied[]; @@ -24,6 +32,33 @@ public class Processable implements IProcessable { } } + public Processable(ICraftingPattern pattern, NBTTagCompound tag) { + this.pattern = pattern; + this.satisfied = new boolean[pattern.getOutputs().size()]; + + for (int i = 0; i < satisfied.length; ++i) { + String id = String.format(NBT_SATISFIED, i); + + if (tag.hasKey(id)) { + this.satisfied[i] = tag.getBoolean(id); + } + } + + NBTTagList toInsertList = tag.getTagList(NBT_TO_INSERT, Constants.NBT.TAG_COMPOUND); + + List toInsert = new ArrayList<>(); + + for (int i = 0; i < toInsertList.tagCount(); ++i) { + ItemStack stack = ItemStack.loadItemStackFromNBT(toInsertList.getCompoundTagAt(i)); + + if (stack != null) { + toInsert.add(stack); + } + } + + this.toInsert = new ArrayDeque<>(toInsert); + } + @Override public ICraftingPattern getPattern() { return pattern; @@ -66,4 +101,21 @@ public class Processable implements IProcessable { return false; } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound tag) { + for (int i = 0; i < satisfied.length; ++i) { + tag.setBoolean(String.format(NBT_SATISFIED, i), satisfied[i]); + } + + NBTTagList toInsertList = new NBTTagList(); + + for (ItemStack stack : new ArrayList<>(toInsert)) { + toInsertList.appendTag(stack.serializeNBT()); + } + + tag.setTag(NBT_TO_INSERT, toInsertList); + + return tag; + } } diff --git a/src/main/java/refinedstorage/tile/TileController.java b/src/main/java/refinedstorage/tile/TileController.java index e19196b46..052e85bfd 100755 --- a/src/main/java/refinedstorage/tile/TileController.java +++ b/src/main/java/refinedstorage/tile/TileController.java @@ -736,7 +736,7 @@ public class TileController extends TileBase implements INetworkMaster, IEnergyR ICraftingTaskFactory factory = API.instance().getCraftingTaskRegistry().getFactory(tag.getString(ICraftingTask.NBT_PATTERN_ID)); if (factory != null) { - return factory.create(world, network, null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), tag); + return factory.create(world, network, tag.hasKey(ICraftingTask.NBT_REQUESTED) ? ItemStack.loadItemStackFromNBT(tag.getCompoundTag(ICraftingTask.NBT_REQUESTED)) : null, pattern, tag.getInteger(ICraftingTask.NBT_QUANTITY), tag); } } }