@@ -0,0 +1,1908 @@
+package openmods.liquids;%0A%0Aimport javax.annotation.Nullable;%0Aimport net.minecraft.item.ItemStack;%0Aimport net.minecraftforge.fluids.Fluid;%0Aimport net.minecraftforge.fluids.FluidRegistry;%0Aimport net.minecraftforge.fluids.FluidStack;%0Aimport net.minecraftforge.fluids.capability.FluidTankProperties;%0Aimport net.minecraftforge.fluids.capability.IFluidHandler;%0Aimport net.minecraftforge.fluids.capability.IFluidTankProperties;%0A%0Apublic class SingleFluidBucketHandler implements IFluidHandler %7B%0A%0A%09private final ItemStack container;%0A%0A%09private final int volume;%0A%0A%09private final Fluid fluid;%0A%0A%09private final ItemStack emptyContainer;%0A%0A%09private final FluidStack contents;%0A%0A%09private final IFluidTankProperties properties;%0A%0A%09public SingleFluidBucketHandler(ItemStack container, String fluidId, int volume, ItemStack emptyContainer) %7B%0A%09%09this.container = container;%0A%09%09this.fluid = FluidRegistry.getFluid(fluidId);%0A%09%09this.volume = volume;%0A%09%09this.emptyContainer = emptyContainer.copy();%0A%0A%09%09this.contents = new FluidStack(fluid, volume);%0A%09%09this.properties = new FluidTankProperties(contents, volume);%0A%09%7D%0A%0A%09@Override%0A%09public IFluidTankProperties%5B%5D getTankProperties() %7B%0A%09%09return new IFluidTankProperties%5B%5D %7B properties %7D;%0A%09%7D%0A%0A%09@Override%0A%09public int fill(FluidStack resource, boolean doFill) %7B%0A%09%09return 0;%0A%09%7D%0A%0A%09protected void switchToEmptyBucket() %7B%0A%09%09container.deserializeNBT(emptyContainer.serializeNBT());%0A%09%7D%0A%0A%09@Override%0A%09@Nullable%0A%09public FluidStack drain(FluidStack resource, boolean doDrain) %7B%0A%09%09if (container.stackSize != 1 %7C%7C resource == null %7C%7C resource.amount %3C volume)%0A%09%09%09return null;%0A%0A%09%09if (resource.getFluid() == fluid)%0A%09%09%09if (doDrain)%0A%09%09%09%09switchToEmptyBucket();%0A%0A%09%09return contents;%0A%09%7D%0A%0A%09@Override%0A%09@Nullable%0A%09public FluidStack drain(int maxDrain, boolean doDrain) %7B%0A%09%09if (container.stackSize != 1 %7C%7C maxDrain %3C Fluid.BUCKET_VOLUME)%0A%09%09%09return null;%0A%0A%09%09if (doDrain)%0A%09%09%09switchToEmptyBucket();%0A%0A%09%09return contents;%0A%09%7D%0A%0A%7D

Add IFluidHandler for simple bucket items