diff --git a/src/main/java/refinedstorage/RSUtils.java b/src/main/java/refinedstorage/RSUtils.java index f630e8329..b8533c95c 100755 --- a/src/main/java/refinedstorage/RSUtils.java +++ b/src/main/java/refinedstorage/RSUtils.java @@ -10,8 +10,10 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidContainerItem; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.wrappers.FluidHandlerWrapper; @@ -20,11 +22,13 @@ import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.wrapper.InvWrapper; import net.minecraftforge.items.wrapper.SidedInvWrapper; +import org.apache.commons.lang3.tuple.Pair; import refinedstorage.api.network.INetworkMaster; import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.storage.fluid.FluidStorageNBT; import refinedstorage.apiimpl.storage.item.ItemStorageNBT; +import java.util.Locale; import java.util.function.Function; public final class RSUtils { @@ -47,6 +51,10 @@ public final class RSUtils { ByteBufUtils.writeTag(buf, stack.tag); } + public static Pair readFluidStack(ByteBuf buf) { + return Pair.of(buf.readInt(), new FluidStack(FluidRegistry.getFluid(ByteBufUtils.readUTF8String(buf)), buf.readInt(), ByteBufUtils.readTag(buf))); + } + public static void constructFromDrive(ItemStack disk, int slot, ItemStorageNBT[] itemStorages, FluidStorageNBT[] fluidStorages, Function itemStorageSupplier, Function fluidStorageNBTSupplier) { if (disk == null) { itemStorages[slot] = null; @@ -148,6 +156,7 @@ public final class RSUtils { return handler; } + @SuppressWarnings("deprecation") public static IFluidHandler getFluidHandler(TileEntity tile, EnumFacing side) { if (tile == null) { return null; @@ -163,4 +172,23 @@ public final class RSUtils { return handler; } + + @SuppressWarnings("deprecation") + public static FluidStack getFluidFromStack(ItemStack stack, boolean simulate) { + if (stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null)) { + return stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null).drain(Fluid.BUCKET_VOLUME, !simulate); + } else if (stack.getItem() instanceof IFluidContainerItem) { + return ((IFluidContainerItem) stack.getItem()).drain(stack, Fluid.BUCKET_VOLUME, !simulate); + } + + return null; + } + + public static boolean hasFluidBucket(FluidStack stack) { + return stack.getFluid() == FluidRegistry.WATER || stack.getFluid() == FluidRegistry.LAVA || FluidRegistry.getBucketFluids().contains(stack.getFluid()); + } + + public static String formatFluidStackQuantity(FluidStack stack) { + return String.format(Locale.US, "%.1f", (float) stack.amount / 1000).replace(".0", ""); + } } diff --git a/src/main/java/refinedstorage/api/IRSAPI.java b/src/main/java/refinedstorage/api/IRSAPI.java index 1cb4c328c..cdbc3f4ec 100755 --- a/src/main/java/refinedstorage/api/IRSAPI.java +++ b/src/main/java/refinedstorage/api/IRSAPI.java @@ -6,6 +6,7 @@ import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRe import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry; import refinedstorage.api.solderer.ISoldererRegistry; import refinedstorage.api.util.IComparer; +import refinedstorage.api.util.IFluidStackList; import refinedstorage.api.util.IItemStackList; import javax.annotation.Nonnull; @@ -45,6 +46,12 @@ public interface IRSAPI { @Nonnull IItemStackList createItemStackList(); + /** + * @return an empty fluid stack list + */ + @Nonnull + IFluidStackList createFluidStackList(); + /** * @param stack the stack * @return a hashcode for the given stack diff --git a/src/main/java/refinedstorage/api/storage/fluid/IGroupedFluidStorage.java b/src/main/java/refinedstorage/api/storage/fluid/IGroupedFluidStorage.java index 202e3e887..d5c4aac16 100755 --- a/src/main/java/refinedstorage/api/storage/fluid/IGroupedFluidStorage.java +++ b/src/main/java/refinedstorage/api/storage/fluid/IGroupedFluidStorage.java @@ -2,14 +2,12 @@ package refinedstorage.api.storage.fluid; import net.minecraftforge.fluids.FluidStack; import refinedstorage.api.network.INetworkMaster; +import refinedstorage.api.util.IFluidStackList; import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Collection; import java.util.List; /** - * e * This holds all fluids from all the connected storages from a {@link INetworkMaster}. *

* Refined Storage uses this class mainly for use in Grids and Detectors to avoid querying @@ -47,27 +45,9 @@ public interface IGroupedFluidStorage { void remove(@Nonnull FluidStack stack); /** - * Gets a fluid from the network. - * - * @param stack the stack to find - * @param flags the flags to compare on, see {@link CompareUtils} - * @return null if no fluid is found, or the stack, do NOT modify + * @return the list behind this grouped storage */ - @Nullable - FluidStack get(@Nonnull FluidStack stack, int flags); - - /** - * Gets a fluid from the network by hash, see {@link refinedstorage.api.network.NetworkUtils#getFluidStackHashCode(FluidStack)}. - * - * @return null if no fluid is found matching the hash, or the stack, do NOT modify - */ - @Nullable - FluidStack get(int hash); - - /** - * @return all fluids in this storage network - */ - Collection getStacks(); + IFluidStackList getList(); /** * @return the fluid storages connected to this network diff --git a/src/main/java/refinedstorage/api/util/IFluidStackList.java b/src/main/java/refinedstorage/api/util/IFluidStackList.java new file mode 100755 index 000000000..ea6f4e933 --- /dev/null +++ b/src/main/java/refinedstorage/api/util/IFluidStackList.java @@ -0,0 +1,93 @@ +package refinedstorage.api.util; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; + +/** + * A fluid stack list. + */ +public interface IFluidStackList { + /** + * Adds a stack to the list, will merge it with another stack if it already exists in the list. + * + * @param stack the stack + */ + void add(FluidStack stack); + + /** + * Decrements the count of that stack in the list. + * + * @param stack the stack + * @param size the size to remove + * @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise + * @return whether the remove was successful + */ + boolean remove(@Nonnull FluidStack stack, int size, boolean removeIfReachedZero); + + /** + * Decrements the count of that stack in the list. + * + * @param stack the stack + * @param removeIfReachedZero true to remove the stack if the count reaches 0, false otherwise + * @return whether the remove was successful + */ + default boolean remove(@Nonnull FluidStack stack, boolean removeIfReachedZero) { + return remove(stack, stack.amount, removeIfReachedZero); + } + + /** + * Returns a stack. + * + * @param stack the stack to search for + * @return the stack, or null if no stack was found + */ + @Nullable + default FluidStack get(@Nonnull FluidStack stack) { + return get(stack, IComparer.COMPARE_NBT); + } + + /** + * Returns a stack. + * + * @param stack the stack to search for + * @param flags the flags to compare on, see {@link refinedstorage.api.storage.CompareUtils} + * @return the stack, or null if no stack was found + */ + @Nullable + FluidStack get(@Nonnull FluidStack stack, int flags); + + /** + * Returns a stack. + * + * @param hash the hash of the stack to search for, see {@link refinedstorage.api.network.NetworkUtils#getItemStackHashCode(ItemStack)} + * @return the stack, or null if no stack was found + */ + @Nullable + FluidStack get(int hash); + + /** + * Clears the list. + */ + void clear(); + + /** + * @return true if the list is empty, false otherwise + */ + boolean isEmpty(); + + /** + * @return a collection of stacks in this list + */ + @Nonnull + Collection getStacks(); + + /** + * @return a new copy of this list, with the stacks in it copied as well + */ + @Nonnull + IFluidStackList copy(); +} diff --git a/src/main/java/refinedstorage/apiimpl/API.java b/src/main/java/refinedstorage/apiimpl/API.java index e29a2428e..c84893790 100755 --- a/src/main/java/refinedstorage/apiimpl/API.java +++ b/src/main/java/refinedstorage/apiimpl/API.java @@ -9,11 +9,13 @@ import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRe import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry; import refinedstorage.api.solderer.ISoldererRegistry; import refinedstorage.api.util.IComparer; +import refinedstorage.api.util.IFluidStackList; import refinedstorage.api.util.IItemStackList; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry; import refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry; import refinedstorage.apiimpl.solderer.SoldererRegistry; import refinedstorage.apiimpl.util.Comparer; +import refinedstorage.apiimpl.util.FluidStackList; import refinedstorage.apiimpl.util.ItemStackList; import javax.annotation.Nonnull; @@ -58,6 +60,12 @@ public class API implements IRSAPI { return new ItemStackList(); } + @Nonnull + @Override + public IFluidStackList createFluidStackList() { + return new FluidStackList(); + } + @Override public int getItemStackHashCode(ItemStack stack) { return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1); diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java b/src/main/java/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java new file mode 100755 index 000000000..40a14a8f5 --- /dev/null +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/craftingmonitor/CraftingMonitorElementFluidRender.java @@ -0,0 +1,53 @@ +package refinedstorage.apiimpl.autocrafting.craftingmonitor; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraftforge.fluids.FluidStack; +import refinedstorage.RSUtils; +import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; +import refinedstorage.gui.GuiBase; + +public class CraftingMonitorElementFluidRender implements ICraftingMonitorElement { + public static final String ID = "fluid_render"; + + private int taskId; + private FluidStack stack; + private int offset; + + public CraftingMonitorElementFluidRender(int taskId, FluidStack stack, int offset) { + this.taskId = taskId; + this.stack = stack; + this.offset = offset; + } + + @Override + public void draw(GuiBase gui, int x, int y) { + GuiBase.FLUID_RENDERER.draw(gui.mc, x + 2 + offset, y + 1, stack); + + float scale = 0.5f; + + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, 1); + + gui.drawString(gui.calculateOffsetOnScale(x + 21 + offset, scale), gui.calculateOffsetOnScale(y + 7, scale), RSUtils.formatFluidStackQuantity(stack) + " " + stack.getLocalizedName()); + + GlStateManager.popMatrix(); + } + + @Override + public int getTaskId() { + return taskId; + } + + @Override + public String getId() { + return ID; + } + + @Override + public void write(ByteBuf buf) { + buf.writeInt(taskId); + RSUtils.writeFluidStack(buf, stack); + buf.writeInt(offset); + } +} diff --git a/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTaskNormal.java b/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTaskNormal.java index e24711fb2..abea4aac8 100755 --- a/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTaskNormal.java +++ b/src/main/java/refinedstorage/apiimpl/autocrafting/task/CraftingTaskNormal.java @@ -1,15 +1,20 @@ package refinedstorage.apiimpl.autocrafting.task; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.ItemHandlerHelper; +import refinedstorage.RSUtils; import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; 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.API; +import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText; @@ -18,12 +23,15 @@ import java.util.List; import java.util.stream.Collectors; public class CraftingTaskNormal implements ICraftingTask { + private static final ItemStack EMPTY_BUCKET = new ItemStack(Items.BUCKET); + private INetworkMaster network; private ItemStack requested; private ICraftingPattern pattern; private int quantity; private List toProcess = new ArrayList<>(); private IItemStackList toTake = API.instance().createItemStackList(); + private IFluidStackList toTakeFluids = API.instance().createFluidStackList(); private IItemStackList toCraft = API.instance().createItemStackList(); private IItemStackList missing = API.instance().createItemStackList(); private IItemStackList extras = API.instance().createItemStackList(); @@ -68,7 +76,22 @@ public class CraftingTaskNormal implements ICraftingTask { calculate(list, inputPattern, false); } else { - missing.add(input); + FluidStack fluidInItem = RSUtils.getFluidFromStack(input, true); + + if (fluidInItem != null && RSUtils.hasFluidBucket(fluidInItem)) { + FluidStack fluidInStorage = network.getFluidStorage().getList().get(fluidInItem); + + if (fluidInStorage == null || fluidInStorage.amount < fluidInItem.amount) { + missing.add(input); + } else if (network.getItemStorage().getList().get(EMPTY_BUCKET) == null) { + missing.add(EMPTY_BUCKET.copy()); + } else { + toTake.add(EMPTY_BUCKET.copy()); + toTakeFluids.add(fluidInItem.copy()); + } + } else { + missing.add(input); + } } } } else { @@ -122,7 +145,20 @@ public class CraftingTaskNormal implements ICraftingTask { break; } - if (toTake.isEmpty() && missing.isEmpty() && hasProcessedItems()) { + // If we took all the items, we can start taking fluids + if (toTake.isEmpty()) { + for (FluidStack toTakeStack : toTakeFluids.getStacks()) { + FluidStack took = network.extractFluid(toTakeStack, toTakeStack.amount); + + if (took != null) { + toTakeFluids.remove(toTakeStack, toTakeStack.amount, true); + } + + break; + } + } + + if (toTake.isEmpty() && toTakeFluids.isEmpty() && missing.isEmpty() && hasProcessedItems()) { for (ItemStack output : pattern.getOutputs()) { // @TODO: Handle remainder network.insertItem(output, output.stackSize, false); @@ -174,6 +210,19 @@ public class CraftingTaskNormal implements ICraftingTask { ); } + if (!toTakeFluids.isEmpty()) { + elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.fluids_taking", 16)); + + elements.addAll(toTakeFluids.getStacks().stream() + .map(stack -> new CraftingMonitorElementFluidRender( + -1, + stack, + 32 + )) + .collect(Collectors.toList()) + ); + } + if (!hasProcessedItems()) { elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16)); diff --git a/src/main/java/refinedstorage/apiimpl/network/grid/FluidGridHandler.java b/src/main/java/refinedstorage/apiimpl/network/grid/FluidGridHandler.java index 8a08e7c91..d7fb26ab9 100755 --- a/src/main/java/refinedstorage/apiimpl/network/grid/FluidGridHandler.java +++ b/src/main/java/refinedstorage/apiimpl/network/grid/FluidGridHandler.java @@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import refinedstorage.RSUtils; import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.grid.IFluidGridHandler; import refinedstorage.apiimpl.API; @@ -22,9 +23,9 @@ public class FluidGridHandler implements IFluidGridHandler { @Override public void onExtract(int hash, boolean shift, EntityPlayerMP player) { - FluidStack stack = network.getFluidStorage().get(hash); + FluidStack stack = network.getFluidStorage().getList().get(hash); - if (stack != null && FluidUtils.hasFluidBucket(stack)) { + if (stack != null && RSUtils.hasFluidBucket(stack)) { ItemStack bucket = FluidUtils.extractBucket(network); if (bucket == null) { @@ -59,10 +60,10 @@ public class FluidGridHandler implements IFluidGridHandler { @Nullable @Override public ItemStack onInsert(ItemStack container) { - FluidStack stack = FluidUtils.getFluidFromStack(container, true); + FluidStack stack = RSUtils.getFluidFromStack(container, true); if (stack != null && network.insertFluid(stack, stack.amount, true) == null) { - FluidStack drained = FluidUtils.getFluidFromStack(container, false); + FluidStack drained = RSUtils.getFluidFromStack(container, false); network.insertFluid(drained, drained.amount, false); } diff --git a/src/main/java/refinedstorage/apiimpl/storage/fluid/FluidUtils.java b/src/main/java/refinedstorage/apiimpl/storage/fluid/FluidUtils.java index 61c0bb9b4..884af2ba1 100755 --- a/src/main/java/refinedstorage/apiimpl/storage/fluid/FluidUtils.java +++ b/src/main/java/refinedstorage/apiimpl/storage/fluid/FluidUtils.java @@ -2,13 +2,8 @@ package refinedstorage.apiimpl.storage.fluid; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidContainerItem; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import refinedstorage.api.network.INetworkMaster; -import refinedstorage.api.util.IComparer; // @TODO: Move to RSUtils public final class FluidUtils { @@ -24,41 +19,6 @@ public final class FluidUtils { return stack == null ? null : stack.copy(); } - @SuppressWarnings("deprecation") - public static FluidStack getFluidFromStack(ItemStack stack, boolean simulate) { - if (stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null)) { - return stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null).drain(Fluid.BUCKET_VOLUME, !simulate); - } else if (stack.getItem() instanceof IFluidContainerItem) { - return ((IFluidContainerItem) stack.getItem()).drain(stack, Fluid.BUCKET_VOLUME, !simulate); - } - - return null; - } - - public static boolean hasFluidBucket(FluidStack stack) { - return stack.getFluid() == FluidRegistry.WATER || stack.getFluid() == FluidRegistry.LAVA || FluidRegistry.getBucketFluids().contains(stack.getFluid()); - } - - public static ItemStack extractItemOrIfBucketLookInFluids(INetworkMaster network, ItemStack stack, int size) { - ItemStack result = network.extractItem(stack, size); - - if (result == null && stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null)) { - FluidStack fluidStack = getFluidFromStack(stack, true); - - if (fluidStack != null && hasFluidBucket(fluidStack)) { - result = extractBucket(network); - - if (result != null) { - result.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null).fill(network.extractFluid(fluidStack, Fluid.BUCKET_VOLUME), true); - } else { - network.scheduleCraftingTaskIfUnscheduled(EMPTY_BUCKET, 1, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT); - } - } - } - - return result; - } - public static ItemStack extractBucket(INetworkMaster network) { return network.extractItem(EMPTY_BUCKET, 1); } diff --git a/src/main/java/refinedstorage/apiimpl/storage/fluid/GroupedFluidStorage.java b/src/main/java/refinedstorage/apiimpl/storage/fluid/GroupedFluidStorage.java index 6a6bdab7f..980a237bf 100755 --- a/src/main/java/refinedstorage/apiimpl/storage/fluid/GroupedFluidStorage.java +++ b/src/main/java/refinedstorage/apiimpl/storage/fluid/GroupedFluidStorage.java @@ -1,25 +1,21 @@ package refinedstorage.apiimpl.storage.fluid; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.storage.fluid.IFluidStorage; import refinedstorage.api.storage.fluid.IFluidStorageProvider; import refinedstorage.api.storage.fluid.IGroupedFluidStorage; +import refinedstorage.api.util.IFluidStackList; import refinedstorage.apiimpl.API; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collection; import java.util.List; public class GroupedFluidStorage implements IGroupedFluidStorage { private INetworkMaster network; private List storages = new ArrayList<>(); - private Multimap stacks = ArrayListMultimap.create(); + private IFluidStackList list = API.instance().createFluidStackList(); public GroupedFluidStorage(INetworkMaster network) { this.network = network; @@ -33,7 +29,7 @@ public class GroupedFluidStorage implements IGroupedFluidStorage { .filter(node -> node.canUpdate() && node instanceof IFluidStorageProvider) .forEach(node -> ((IFluidStorageProvider) node).addFluidStorages(storages)); - stacks.clear(); + list.clear(); for (IFluidStorage storage : storages) { for (FluidStack stack : storage.getStacks()) { @@ -46,19 +42,7 @@ public class GroupedFluidStorage implements IGroupedFluidStorage { @Override public void add(@Nonnull FluidStack stack, boolean rebuilding) { - for (FluidStack otherStack : stacks.get(stack.getFluid())) { - if (otherStack.isFluidEqual(stack)) { - otherStack.amount += stack.amount; - - if (!rebuilding) { - network.sendFluidStorageDeltaToClient(stack, stack.amount); - } - - return; - } - } - - stacks.put(stack.getFluid(), stack.copy()); + list.add(stack); if (!rebuilding) { network.sendFluidStorageDeltaToClient(stack, stack.amount); @@ -67,48 +51,14 @@ public class GroupedFluidStorage implements IGroupedFluidStorage { @Override public void remove(@Nonnull FluidStack stack) { - for (FluidStack otherStack : stacks.get(stack.getFluid())) { - if (otherStack.isFluidEqual(stack)) { - otherStack.amount -= stack.amount; - - if (otherStack.amount == 0) { - stacks.remove(otherStack.getFluid(), otherStack); - } - - network.sendFluidStorageDeltaToClient(stack, -stack.amount); - - return; - } + if (list.remove(stack, true)) { + network.sendFluidStorageDeltaToClient(stack, -stack.amount); } } @Override - @Nullable - public FluidStack get(@Nonnull FluidStack stack, int flags) { - for (FluidStack otherStack : stacks.get(stack.getFluid())) { - if (API.instance().getComparer().isEqual(otherStack, stack, flags)) { - return otherStack; - } - } - - return null; - } - - @Override - @Nullable - public FluidStack get(int hash) { - for (FluidStack stack : this.stacks.values()) { - if (API.instance().getFluidStackHashCode(stack) == hash) { - return stack; - } - } - - return null; - } - - @Override - public Collection getStacks() { - return stacks.values(); + public IFluidStackList getList() { + return list; } @Override diff --git a/src/main/java/refinedstorage/apiimpl/util/FluidStackList.java b/src/main/java/refinedstorage/apiimpl/util/FluidStackList.java new file mode 100755 index 000000000..bfa5550bd --- /dev/null +++ b/src/main/java/refinedstorage/apiimpl/util/FluidStackList.java @@ -0,0 +1,97 @@ +package refinedstorage.apiimpl.util; + +import com.google.common.collect.ArrayListMultimap; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import refinedstorage.api.util.IFluidStackList; +import refinedstorage.apiimpl.API; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collection; + +public class FluidStackList implements IFluidStackList { + private ArrayListMultimap stacks = ArrayListMultimap.create(); + + @Override + public void add(FluidStack stack) { + for (FluidStack otherStack : stacks.get(stack.getFluid())) { + if (stack.isFluidEqual(otherStack)) { + otherStack.amount += stack.amount; + + return; + } + } + + stacks.put(stack.getFluid(), stack.copy()); + } + + @Override + public boolean remove(@Nonnull FluidStack stack, int size, boolean removeIfReachedZero) { + for (FluidStack otherStack : stacks.get(stack.getFluid())) { + if (stack.isFluidEqual(otherStack)) { + otherStack.amount -= size; + + if (otherStack.amount <= 0 && removeIfReachedZero) { + stacks.remove(otherStack.getFluid(), otherStack); + } + + return true; + } + } + + return false; + } + + @Override + @Nullable + public FluidStack get(@Nonnull FluidStack stack, int flags) { + for (FluidStack otherStack : stacks.get(stack.getFluid())) { + if (API.instance().getComparer().isEqual(otherStack, stack, flags)) { + return otherStack; + } + } + + return null; + } + + @Override + @Nullable + public FluidStack get(int hash) { + for (FluidStack stack : this.stacks.values()) { + if (API.instance().getFluidStackHashCode(stack) == hash) { + return stack; + } + } + + return null; + } + + @Override + public void clear() { + stacks.clear(); + } + + @Override + public boolean isEmpty() { + return stacks.isEmpty(); + } + + @Nonnull + @Override + public Collection getStacks() { + return stacks.values(); + } + + @Override + @Nonnull + public IFluidStackList copy() { + FluidStackList list = new FluidStackList(); + + for (FluidStack stack : stacks.values()) { + list.add(stack.copy()); + } + + return list; + } +} diff --git a/src/main/java/refinedstorage/gui/grid/stack/ClientStackFluid.java b/src/main/java/refinedstorage/gui/grid/stack/ClientStackFluid.java index 011834f75..4eab1860f 100755 --- a/src/main/java/refinedstorage/gui/grid/stack/ClientStackFluid.java +++ b/src/main/java/refinedstorage/gui/grid/stack/ClientStackFluid.java @@ -1,20 +1,17 @@ package refinedstorage.gui.grid.stack; -import io.netty.buffer.ByteBuf; -import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.network.ByteBufUtils; +import org.apache.commons.lang3.tuple.Pair; +import refinedstorage.RSUtils; import refinedstorage.gui.GuiBase; -import java.util.Locale; - public class ClientStackFluid implements IClientStack { private int hash; private FluidStack stack; - public ClientStackFluid(ByteBuf buf) { - this.hash = buf.readInt(); - this.stack = new FluidStack(FluidRegistry.getFluid(ByteBufUtils.readUTF8String(buf)), buf.readInt(), ByteBufUtils.readTag(buf)); + public ClientStackFluid(Pair data) { + this.hash = data.getLeft(); + this.stack = data.getRight(); } public FluidStack getStack() { @@ -50,7 +47,7 @@ public class ClientStackFluid implements IClientStack { public void draw(GuiBase gui, int x, int y, boolean isOverWithShift) { GuiBase.FLUID_RENDERER.draw(gui.mc, x, y, stack); - gui.drawQuantity(x, y, String.format(Locale.US, "%.1f", (float) stack.amount / 1000).replace(".0", "")); + gui.drawQuantity(x, y, RSUtils.formatFluidStackQuantity(stack)); } @Override diff --git a/src/main/java/refinedstorage/inventory/ItemHandlerFluid.java b/src/main/java/refinedstorage/inventory/ItemHandlerFluid.java index 860a60b15..c419fc6c7 100755 --- a/src/main/java/refinedstorage/inventory/ItemHandlerFluid.java +++ b/src/main/java/refinedstorage/inventory/ItemHandlerFluid.java @@ -4,13 +4,13 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.ItemHandlerHelper; -import refinedstorage.apiimpl.storage.fluid.FluidUtils; +import refinedstorage.RSUtils; public class ItemHandlerFluid extends ItemHandlerBasic { private FluidStack[] fluids; public ItemHandlerFluid(int size, TileEntity tile) { - super(size, tile, s -> FluidUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(s, 1), true) != null); + super(size, tile, s -> RSUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(s, 1), true) != null); this.fluids = new FluidStack[size]; } @@ -24,7 +24,7 @@ public class ItemHandlerFluid extends ItemHandlerBasic { if (stack == null) { fluids[slot] = null; } else { - fluids[slot] = FluidUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(stack, 1), true); + fluids[slot] = RSUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(stack, 1), true); } } diff --git a/src/main/java/refinedstorage/network/MessageGridFluidDelta.java b/src/main/java/refinedstorage/network/MessageGridFluidDelta.java index 746be09ad..78ff9fb2b 100755 --- a/src/main/java/refinedstorage/network/MessageGridFluidDelta.java +++ b/src/main/java/refinedstorage/network/MessageGridFluidDelta.java @@ -26,7 +26,7 @@ public class MessageGridFluidDelta implements IMessage, IMessageHandler new CraftingMonitorElementItemRender(buf.readInt(), ByteBufUtils.readItemStack(buf), buf.readInt(), buf.readInt())); + API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementFluidRender.ID, buf -> new CraftingMonitorElementFluidRender(buf.readInt(), RSUtils.readFluidStack(buf).getRight(), buf.readInt())); API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementText.ID, buf -> new CraftingMonitorElementText(ByteBufUtils.readUTF8String(buf), buf.readInt())); int id = 0; @@ -158,6 +161,14 @@ public class CommonProxy { API.instance().getSoldererRegistry().addRecipe(new SoldererRecipeProcessor(ItemProcessor.TYPE_IMPROVED)); API.instance().getSoldererRegistry().addRecipe(new SoldererRecipeProcessor(ItemProcessor.TYPE_ADVANCED)); + GameRegistry.addRecipe(new ItemStack(Blocks.SPONGE), + "WWW", + "WBW", + "WWW", + 'W', new ItemStack(Blocks.PLANKS), + 'B', new ItemStack(Items.WATER_BUCKET) + ); + // Silicon GameRegistry.addSmelting(Items.QUARTZ, new ItemStack(RSItems.SILICON), 0.5f); diff --git a/src/main/java/refinedstorage/tile/TileDetector.java b/src/main/java/refinedstorage/tile/TileDetector.java index e04e5bdab..67d277393 100755 --- a/src/main/java/refinedstorage/tile/TileDetector.java +++ b/src/main/java/refinedstorage/tile/TileDetector.java @@ -141,11 +141,11 @@ public class TileDetector extends TileNode implements IComparable, IType { FluidStack slot = fluidFilters.getFluidStackInSlot(0); if (slot != null) { - FluidStack stack = network.getFluidStorage().get(slot, compare); + FluidStack stack = network.getFluidStorage().getList().get(slot, compare); powered = isPowered(stack == null ? null : stack.amount); } else { - powered = isPowered(network.getFluidStorage().getStacks().stream().map(s -> s.amount).mapToInt(Number::intValue).sum()); + powered = isPowered(network.getFluidStorage().getList().getStacks().stream().map(s -> s.amount).mapToInt(Number::intValue).sum()); } } } diff --git a/src/main/java/refinedstorage/tile/TileDiskManipulator.java b/src/main/java/refinedstorage/tile/TileDiskManipulator.java index 08ee35127..b9ea1e93f 100755 --- a/src/main/java/refinedstorage/tile/TileDiskManipulator.java +++ b/src/main/java/refinedstorage/tile/TileDiskManipulator.java @@ -338,7 +338,7 @@ public class TileDiskManipulator extends TileNode implements IComparable, IFilte if (IFilterable.isEmpty(itemFilters)) { FluidStack toExtract = null; - ArrayList networkFluids = new ArrayList<>(network.getFluidStorage().getStacks()); + ArrayList networkFluids = new ArrayList<>(network.getFluidStorage().getList().getStacks()); int j = 0; diff --git a/src/main/java/refinedstorage/tile/TileExporter.java b/src/main/java/refinedstorage/tile/TileExporter.java index e626ae839..cb4612646 100755 --- a/src/main/java/refinedstorage/tile/TileExporter.java +++ b/src/main/java/refinedstorage/tile/TileExporter.java @@ -83,7 +83,7 @@ public class TileExporter extends TileMultipartNode implements IComparable, ITyp if (handler != null) { for (FluidStack stack : fluidFilters.getFluids()) { if (stack != null) { - FluidStack stackInStorage = network.getFluidStorage().get(stack, compare); + FluidStack stackInStorage = network.getFluidStorage().getList().get(stack, compare); if (stackInStorage != null) { int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount); diff --git a/src/main/java/refinedstorage/tile/TileFluidInterface.java b/src/main/java/refinedstorage/tile/TileFluidInterface.java index d1f4da04e..45680d346 100755 --- a/src/main/java/refinedstorage/tile/TileFluidInterface.java +++ b/src/main/java/refinedstorage/tile/TileFluidInterface.java @@ -11,7 +11,6 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import refinedstorage.RS; import refinedstorage.RSUtils; import refinedstorage.api.util.IComparer; -import refinedstorage.apiimpl.storage.fluid.FluidUtils; import refinedstorage.inventory.ItemHandlerBasic; import refinedstorage.inventory.ItemHandlerFluid; import refinedstorage.inventory.ItemHandlerUpgrade; @@ -94,10 +93,10 @@ public class TileFluidInterface extends TileNode implements IComparable { ItemStack container = in.getStackInSlot(0); if (container != null) { - FluidStack fluid = FluidUtils.getFluidFromStack(container, true); + FluidStack fluid = RSUtils.getFluidFromStack(container, true); if (fluid != null && tankIn.fillInternal(fluid, false) == fluid.amount) { - tankIn.fillInternal(FluidUtils.getFluidFromStack(container, false), true); + tankIn.fillInternal(RSUtils.getFluidFromStack(container, false), true); } } @@ -126,7 +125,7 @@ public class TileFluidInterface extends TileNode implements IComparable { } } else if (stack != null) { // Fill the out fluid - FluidStack stackInStorage = network.getFluidStorage().get(stack, compare); + FluidStack stackInStorage = network.getFluidStorage().getList().get(stack, compare); if (stackInStorage != null) { int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount); diff --git a/src/main/resources/assets/refinedstorage/lang/en_US.lang b/src/main/resources/assets/refinedstorage/lang/en_US.lang index 27a41db6c..94db65e86 100755 --- a/src/main/resources/assets/refinedstorage/lang/en_US.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_US.lang @@ -20,6 +20,7 @@ gui.refinedstorage:interface.import=Interface Import gui.refinedstorage:interface.export=Interface Export gui.refinedstorage:crafting_monitor=Crafting Monitor gui.refinedstorage:crafting_monitor.items_taking=Items taking +gui.refinedstorage:crafting_monitor.fluids_taking=Fluids taking gui.refinedstorage:crafting_monitor.items_processing=Items processing gui.refinedstorage:crafting_monitor.machine_in_use=Waiting on machine that is in use by another task gui.refinedstorage:crafting_monitor.machine_none=No machine found