Fluid autocrafting

This commit is contained in:
Raoul Van den Berge
2016-10-09 18:34:23 +02:00
parent 5168508acc
commit db5c6a664a
21 changed files with 385 additions and 151 deletions

View File

@@ -10,8 +10,10 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.wrappers.FluidHandlerWrapper; 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.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper; import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper; import net.minecraftforge.items.wrapper.SidedInvWrapper;
import org.apache.commons.lang3.tuple.Pair;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.API;
import refinedstorage.apiimpl.storage.fluid.FluidStorageNBT; import refinedstorage.apiimpl.storage.fluid.FluidStorageNBT;
import refinedstorage.apiimpl.storage.item.ItemStorageNBT; import refinedstorage.apiimpl.storage.item.ItemStorageNBT;
import java.util.Locale;
import java.util.function.Function; import java.util.function.Function;
public final class RSUtils { public final class RSUtils {
@@ -47,6 +51,10 @@ public final class RSUtils {
ByteBufUtils.writeTag(buf, stack.tag); ByteBufUtils.writeTag(buf, stack.tag);
} }
public static Pair<Integer, FluidStack> 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<ItemStack, ItemStorageNBT> itemStorageSupplier, Function<ItemStack, FluidStorageNBT> fluidStorageNBTSupplier) { public static void constructFromDrive(ItemStack disk, int slot, ItemStorageNBT[] itemStorages, FluidStorageNBT[] fluidStorages, Function<ItemStack, ItemStorageNBT> itemStorageSupplier, Function<ItemStack, FluidStorageNBT> fluidStorageNBTSupplier) {
if (disk == null) { if (disk == null) {
itemStorages[slot] = null; itemStorages[slot] = null;
@@ -148,6 +156,7 @@ public final class RSUtils {
return handler; return handler;
} }
@SuppressWarnings("deprecation")
public static IFluidHandler getFluidHandler(TileEntity tile, EnumFacing side) { public static IFluidHandler getFluidHandler(TileEntity tile, EnumFacing side) {
if (tile == null) { if (tile == null) {
return null; return null;
@@ -163,4 +172,23 @@ public final class RSUtils {
return handler; 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", "");
}
} }

View File

@@ -6,6 +6,7 @@ import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRe
import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry; import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import refinedstorage.api.solderer.ISoldererRegistry; import refinedstorage.api.solderer.ISoldererRegistry;
import refinedstorage.api.util.IComparer; import refinedstorage.api.util.IComparer;
import refinedstorage.api.util.IFluidStackList;
import refinedstorage.api.util.IItemStackList; import refinedstorage.api.util.IItemStackList;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -45,6 +46,12 @@ public interface IRSAPI {
@Nonnull @Nonnull
IItemStackList createItemStackList(); IItemStackList createItemStackList();
/**
* @return an empty fluid stack list
*/
@Nonnull
IFluidStackList createFluidStackList();
/** /**
* @param stack the stack * @param stack the stack
* @return a hashcode for the given stack * @return a hashcode for the given stack

View File

@@ -2,14 +2,12 @@ package refinedstorage.api.storage.fluid;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.util.IFluidStackList;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
* e
* This holds all fluids from all the connected storages from a {@link INetworkMaster}. * This holds all fluids from all the connected storages from a {@link INetworkMaster}.
* <p> * <p>
* Refined Storage uses this class mainly for use in Grids and Detectors to avoid querying * 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); void remove(@Nonnull FluidStack stack);
/** /**
* Gets a fluid from the network. * @return the list behind this grouped storage
*
* @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
*/ */
@Nullable IFluidStackList getList();
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<FluidStack> getStacks();
/** /**
* @return the fluid storages connected to this network * @return the fluid storages connected to this network

View File

@@ -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<FluidStack> getStacks();
/**
* @return a new copy of this list, with the stacks in it copied as well
*/
@Nonnull
IFluidStackList copy();
}

View File

@@ -9,11 +9,13 @@ import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementRe
import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry; import refinedstorage.api.autocrafting.registry.ICraftingTaskRegistry;
import refinedstorage.api.solderer.ISoldererRegistry; import refinedstorage.api.solderer.ISoldererRegistry;
import refinedstorage.api.util.IComparer; import refinedstorage.api.util.IComparer;
import refinedstorage.api.util.IFluidStackList;
import refinedstorage.api.util.IItemStackList; import refinedstorage.api.util.IItemStackList;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementRegistry;
import refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry; import refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry;
import refinedstorage.apiimpl.solderer.SoldererRegistry; import refinedstorage.apiimpl.solderer.SoldererRegistry;
import refinedstorage.apiimpl.util.Comparer; import refinedstorage.apiimpl.util.Comparer;
import refinedstorage.apiimpl.util.FluidStackList;
import refinedstorage.apiimpl.util.ItemStackList; import refinedstorage.apiimpl.util.ItemStackList;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -58,6 +60,12 @@ public class API implements IRSAPI {
return new ItemStackList(); return new ItemStackList();
} }
@Nonnull
@Override
public IFluidStackList createFluidStackList() {
return new FluidStackList();
}
@Override @Override
public int getItemStackHashCode(ItemStack stack) { public int getItemStackHashCode(ItemStack stack) {
return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1); return stack.getItem().hashCode() * (stack.getItemDamage() + 1) * (stack.hasTagCompound() ? stack.getTagCompound().hashCode() : 1);

View File

@@ -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<GuiBase> {
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);
}
}

View File

@@ -1,15 +1,20 @@
package refinedstorage.apiimpl.autocrafting.task; package refinedstorage.apiimpl.autocrafting.task;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import refinedstorage.RSUtils;
import refinedstorage.api.autocrafting.ICraftingPattern; import refinedstorage.api.autocrafting.ICraftingPattern;
import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; import refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement;
import refinedstorage.api.autocrafting.task.ICraftingTask; import refinedstorage.api.autocrafting.task.ICraftingTask;
import refinedstorage.api.autocrafting.task.IProcessable; import refinedstorage.api.autocrafting.task.IProcessable;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.util.IFluidStackList;
import refinedstorage.api.util.IItemStackList; import refinedstorage.api.util.IItemStackList;
import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.API;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
@@ -18,12 +23,15 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class CraftingTaskNormal implements ICraftingTask { public class CraftingTaskNormal implements ICraftingTask {
private static final ItemStack EMPTY_BUCKET = new ItemStack(Items.BUCKET);
private INetworkMaster network; private INetworkMaster network;
private ItemStack requested; private ItemStack requested;
private ICraftingPattern pattern; private ICraftingPattern pattern;
private int quantity; private int quantity;
private List<IProcessable> toProcess = new ArrayList<>(); private List<IProcessable> toProcess = new ArrayList<>();
private IItemStackList toTake = API.instance().createItemStackList(); private IItemStackList toTake = API.instance().createItemStackList();
private IFluidStackList toTakeFluids = API.instance().createFluidStackList();
private IItemStackList toCraft = API.instance().createItemStackList(); private IItemStackList toCraft = API.instance().createItemStackList();
private IItemStackList missing = API.instance().createItemStackList(); private IItemStackList missing = API.instance().createItemStackList();
private IItemStackList extras = API.instance().createItemStackList(); private IItemStackList extras = API.instance().createItemStackList();
@@ -68,7 +76,22 @@ public class CraftingTaskNormal implements ICraftingTask {
calculate(list, inputPattern, false); calculate(list, inputPattern, false);
} else { } else {
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); 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 { } else {
@@ -122,7 +145,20 @@ public class CraftingTaskNormal implements ICraftingTask {
break; 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()) { for (ItemStack output : pattern.getOutputs()) {
// @TODO: Handle remainder // @TODO: Handle remainder
network.insertItem(output, output.stackSize, false); 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()) { if (!hasProcessedItems()) {
elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16)); elements.add(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_processing", 16));

View File

@@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import refinedstorage.RSUtils;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.network.grid.IFluidGridHandler; import refinedstorage.api.network.grid.IFluidGridHandler;
import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.API;
@@ -22,9 +23,9 @@ public class FluidGridHandler implements IFluidGridHandler {
@Override @Override
public void onExtract(int hash, boolean shift, EntityPlayerMP player) { 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); ItemStack bucket = FluidUtils.extractBucket(network);
if (bucket == null) { if (bucket == null) {
@@ -59,10 +60,10 @@ public class FluidGridHandler implements IFluidGridHandler {
@Nullable @Nullable
@Override @Override
public ItemStack onInsert(ItemStack container) { 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) { 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); network.insertFluid(drained, drained.amount, false);
} }

View File

@@ -2,13 +2,8 @@ package refinedstorage.apiimpl.storage.fluid;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.util.IComparer;
// @TODO: Move to RSUtils // @TODO: Move to RSUtils
public final class FluidUtils { public final class FluidUtils {
@@ -24,41 +19,6 @@ public final class FluidUtils {
return stack == null ? null : stack.copy(); 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) { public static ItemStack extractBucket(INetworkMaster network) {
return network.extractItem(EMPTY_BUCKET, 1); return network.extractItem(EMPTY_BUCKET, 1);
} }

View File

@@ -1,25 +1,21 @@
package refinedstorage.apiimpl.storage.fluid; 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 net.minecraftforge.fluids.FluidStack;
import refinedstorage.api.network.INetworkMaster; import refinedstorage.api.network.INetworkMaster;
import refinedstorage.api.storage.fluid.IFluidStorage; import refinedstorage.api.storage.fluid.IFluidStorage;
import refinedstorage.api.storage.fluid.IFluidStorageProvider; import refinedstorage.api.storage.fluid.IFluidStorageProvider;
import refinedstorage.api.storage.fluid.IGroupedFluidStorage; import refinedstorage.api.storage.fluid.IGroupedFluidStorage;
import refinedstorage.api.util.IFluidStackList;
import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.API;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
public class GroupedFluidStorage implements IGroupedFluidStorage { public class GroupedFluidStorage implements IGroupedFluidStorage {
private INetworkMaster network; private INetworkMaster network;
private List<IFluidStorage> storages = new ArrayList<>(); private List<IFluidStorage> storages = new ArrayList<>();
private Multimap<Fluid, FluidStack> stacks = ArrayListMultimap.create(); private IFluidStackList list = API.instance().createFluidStackList();
public GroupedFluidStorage(INetworkMaster network) { public GroupedFluidStorage(INetworkMaster network) {
this.network = network; this.network = network;
@@ -33,7 +29,7 @@ public class GroupedFluidStorage implements IGroupedFluidStorage {
.filter(node -> node.canUpdate() && node instanceof IFluidStorageProvider) .filter(node -> node.canUpdate() && node instanceof IFluidStorageProvider)
.forEach(node -> ((IFluidStorageProvider) node).addFluidStorages(storages)); .forEach(node -> ((IFluidStorageProvider) node).addFluidStorages(storages));
stacks.clear(); list.clear();
for (IFluidStorage storage : storages) { for (IFluidStorage storage : storages) {
for (FluidStack stack : storage.getStacks()) { for (FluidStack stack : storage.getStacks()) {
@@ -46,19 +42,7 @@ public class GroupedFluidStorage implements IGroupedFluidStorage {
@Override @Override
public void add(@Nonnull FluidStack stack, boolean rebuilding) { public void add(@Nonnull FluidStack stack, boolean rebuilding) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) { list.add(stack);
if (otherStack.isFluidEqual(stack)) {
otherStack.amount += stack.amount;
if (!rebuilding) {
network.sendFluidStorageDeltaToClient(stack, stack.amount);
}
return;
}
}
stacks.put(stack.getFluid(), stack.copy());
if (!rebuilding) { if (!rebuilding) {
network.sendFluidStorageDeltaToClient(stack, stack.amount); network.sendFluidStorageDeltaToClient(stack, stack.amount);
@@ -67,48 +51,14 @@ public class GroupedFluidStorage implements IGroupedFluidStorage {
@Override @Override
public void remove(@Nonnull FluidStack stack) { public void remove(@Nonnull FluidStack stack) {
for (FluidStack otherStack : stacks.get(stack.getFluid())) { if (list.remove(stack, true)) {
if (otherStack.isFluidEqual(stack)) {
otherStack.amount -= stack.amount;
if (otherStack.amount == 0) {
stacks.remove(otherStack.getFluid(), otherStack);
}
network.sendFluidStorageDeltaToClient(stack, -stack.amount); network.sendFluidStorageDeltaToClient(stack, -stack.amount);
return;
}
} }
} }
@Override @Override
@Nullable public IFluidStackList getList() {
public FluidStack get(@Nonnull FluidStack stack, int flags) { return list;
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<FluidStack> getStacks() {
return stacks.values();
} }
@Override @Override

View File

@@ -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<Fluid, FluidStack> 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<FluidStack> getStacks() {
return stacks.values();
}
@Override
@Nonnull
public IFluidStackList copy() {
FluidStackList list = new FluidStackList();
for (FluidStack stack : stacks.values()) {
list.add(stack.copy());
}
return list;
}
}

View File

@@ -1,20 +1,17 @@
package refinedstorage.gui.grid.stack; package refinedstorage.gui.grid.stack;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack; 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 refinedstorage.gui.GuiBase;
import java.util.Locale;
public class ClientStackFluid implements IClientStack { public class ClientStackFluid implements IClientStack {
private int hash; private int hash;
private FluidStack stack; private FluidStack stack;
public ClientStackFluid(ByteBuf buf) { public ClientStackFluid(Pair<Integer, FluidStack> data) {
this.hash = buf.readInt(); this.hash = data.getLeft();
this.stack = new FluidStack(FluidRegistry.getFluid(ByteBufUtils.readUTF8String(buf)), buf.readInt(), ByteBufUtils.readTag(buf)); this.stack = data.getRight();
} }
public FluidStack getStack() { public FluidStack getStack() {
@@ -50,7 +47,7 @@ public class ClientStackFluid implements IClientStack {
public void draw(GuiBase gui, int x, int y, boolean isOverWithShift) { public void draw(GuiBase gui, int x, int y, boolean isOverWithShift) {
GuiBase.FLUID_RENDERER.draw(gui.mc, x, y, stack); 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 @Override

View File

@@ -4,13 +4,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import refinedstorage.apiimpl.storage.fluid.FluidUtils; import refinedstorage.RSUtils;
public class ItemHandlerFluid extends ItemHandlerBasic { public class ItemHandlerFluid extends ItemHandlerBasic {
private FluidStack[] fluids; private FluidStack[] fluids;
public ItemHandlerFluid(int size, TileEntity tile) { 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]; this.fluids = new FluidStack[size];
} }
@@ -24,7 +24,7 @@ public class ItemHandlerFluid extends ItemHandlerBasic {
if (stack == null) { if (stack == null) {
fluids[slot] = null; fluids[slot] = null;
} else { } else {
fluids[slot] = FluidUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(stack, 1), true); fluids[slot] = RSUtils.getFluidFromStack(ItemHandlerHelper.copyStackWithSize(stack, 1), true);
} }
} }

View File

@@ -26,7 +26,7 @@ public class MessageGridFluidDelta implements IMessage, IMessageHandler<MessageG
@Override @Override
public void fromBytes(ByteBuf buf) { public void fromBytes(ByteBuf buf) {
clientStack = new ClientStackFluid(buf); clientStack = new ClientStackFluid(RSUtils.readFluidStack(buf));
delta = buf.readInt(); delta = buf.readInt();
} }

View File

@@ -29,15 +29,15 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler<Message
int items = buf.readInt(); int items = buf.readInt();
for (int i = 0; i < items; ++i) { for (int i = 0; i < items; ++i) {
this.stacks.add(new ClientStackFluid(buf)); this.stacks.add(new ClientStackFluid(RSUtils.readFluidStack(buf)));
} }
} }
@Override @Override
public void toBytes(ByteBuf buf) { public void toBytes(ByteBuf buf) {
buf.writeInt(network.getFluidStorage().getStacks().size()); buf.writeInt(network.getFluidStorage().getList().getStacks().size());
for (FluidStack stack : network.getFluidStorage().getStacks()) { for (FluidStack stack : network.getFluidStorage().getList().getStacks()) {
RSUtils.writeFluidStack(buf, stack); RSUtils.writeFluidStack(buf, stack);
} }
} }

View File

@@ -18,7 +18,9 @@ import net.minecraftforge.oredict.ShapedOreRecipe;
import refinedstorage.RS; import refinedstorage.RS;
import refinedstorage.RSBlocks; import refinedstorage.RSBlocks;
import refinedstorage.RSItems; import refinedstorage.RSItems;
import refinedstorage.RSUtils;
import refinedstorage.apiimpl.API; import refinedstorage.apiimpl.API;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementFluidRender;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementItemRender;
import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText; import refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText;
import refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactoryNormal; import refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactoryNormal;
@@ -52,6 +54,7 @@ public class CommonProxy {
API.instance().getCraftingTaskRegistry().addFactory(CraftingTaskFactoryNormal.ID, new CraftingTaskFactoryNormal()); API.instance().getCraftingTaskRegistry().addFactory(CraftingTaskFactoryNormal.ID, new CraftingTaskFactoryNormal());
API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementItemRender.ID, buf -> new CraftingMonitorElementItemRender(buf.readInt(), ByteBufUtils.readItemStack(buf), buf.readInt(), buf.readInt())); API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementItemRender.ID, buf -> 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())); API.instance().getCraftingMonitorElementRegistry().add(CraftingMonitorElementText.ID, buf -> new CraftingMonitorElementText(ByteBufUtils.readUTF8String(buf), buf.readInt()));
int id = 0; 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_IMPROVED));
API.instance().getSoldererRegistry().addRecipe(new SoldererRecipeProcessor(ItemProcessor.TYPE_ADVANCED)); 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 // Silicon
GameRegistry.addSmelting(Items.QUARTZ, new ItemStack(RSItems.SILICON), 0.5f); GameRegistry.addSmelting(Items.QUARTZ, new ItemStack(RSItems.SILICON), 0.5f);

View File

@@ -141,11 +141,11 @@ public class TileDetector extends TileNode implements IComparable, IType {
FluidStack slot = fluidFilters.getFluidStackInSlot(0); FluidStack slot = fluidFilters.getFluidStackInSlot(0);
if (slot != null) { 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); powered = isPowered(stack == null ? null : stack.amount);
} else { } 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());
} }
} }
} }

View File

@@ -338,7 +338,7 @@ public class TileDiskManipulator extends TileNode implements IComparable, IFilte
if (IFilterable.isEmpty(itemFilters)) { if (IFilterable.isEmpty(itemFilters)) {
FluidStack toExtract = null; FluidStack toExtract = null;
ArrayList<FluidStack> networkFluids = new ArrayList<>(network.getFluidStorage().getStacks()); ArrayList<FluidStack> networkFluids = new ArrayList<>(network.getFluidStorage().getList().getStacks());
int j = 0; int j = 0;

View File

@@ -83,7 +83,7 @@ public class TileExporter extends TileMultipartNode implements IComparable, ITyp
if (handler != null) { if (handler != null) {
for (FluidStack stack : fluidFilters.getFluids()) { for (FluidStack stack : fluidFilters.getFluids()) {
if (stack != null) { if (stack != null) {
FluidStack stackInStorage = network.getFluidStorage().get(stack, compare); FluidStack stackInStorage = network.getFluidStorage().getList().get(stack, compare);
if (stackInStorage != null) { if (stackInStorage != null) {
int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount); int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount);

View File

@@ -11,7 +11,6 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import refinedstorage.RS; import refinedstorage.RS;
import refinedstorage.RSUtils; import refinedstorage.RSUtils;
import refinedstorage.api.util.IComparer; import refinedstorage.api.util.IComparer;
import refinedstorage.apiimpl.storage.fluid.FluidUtils;
import refinedstorage.inventory.ItemHandlerBasic; import refinedstorage.inventory.ItemHandlerBasic;
import refinedstorage.inventory.ItemHandlerFluid; import refinedstorage.inventory.ItemHandlerFluid;
import refinedstorage.inventory.ItemHandlerUpgrade; import refinedstorage.inventory.ItemHandlerUpgrade;
@@ -94,10 +93,10 @@ public class TileFluidInterface extends TileNode implements IComparable {
ItemStack container = in.getStackInSlot(0); ItemStack container = in.getStackInSlot(0);
if (container != null) { if (container != null) {
FluidStack fluid = FluidUtils.getFluidFromStack(container, true); FluidStack fluid = RSUtils.getFluidFromStack(container, true);
if (fluid != null && tankIn.fillInternal(fluid, false) == fluid.amount) { 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) { } else if (stack != null) {
// Fill the out fluid // Fill the out fluid
FluidStack stackInStorage = network.getFluidStorage().get(stack, compare); FluidStack stackInStorage = network.getFluidStorage().getList().get(stack, compare);
if (stackInStorage != null) { if (stackInStorage != null) {
int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount); int toExtract = Math.min(Fluid.BUCKET_VOLUME * upgrades.getInteractStackSize(), stackInStorage.amount);

View File

@@ -20,6 +20,7 @@ gui.refinedstorage:interface.import=Interface Import
gui.refinedstorage:interface.export=Interface Export gui.refinedstorage:interface.export=Interface Export
gui.refinedstorage:crafting_monitor=Crafting Monitor gui.refinedstorage:crafting_monitor=Crafting Monitor
gui.refinedstorage:crafting_monitor.items_taking=Items taking 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.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_in_use=Waiting on machine that is in use by another task
gui.refinedstorage:crafting_monitor.machine_none=No machine found gui.refinedstorage:crafting_monitor.machine_none=No machine found