Implement fluid item capabilities without item swapping

This commit is contained in:
mezz 2016-10-10 00:44:50 -07:00 committed by LexManos
parent 6f1a44a405
commit eb6b3ea228
15 changed files with 437 additions and 227 deletions

View File

@ -9,23 +9,16 @@
if (raytraceresult == null)
{
@@ -181,4 +183,23 @@
@@ -181,4 +183,16 @@
}
}
}
+
+ @Override
+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, net.minecraft.nbt.NBTTagCompound nbt) {
+ public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities(ItemStack stack, @Nullable net.minecraft.nbt.NBTTagCompound nbt) {
+ if (this.getClass() == ItemBucket.class)
+ {
+ if (net.minecraftforge.fluids.FluidRegistry.isUniversalBucketEnabled())
+ {
+ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack);
+ }
+ else
+ {
+ return new net.minecraftforge.fluids.capability.wrappers.FluidContainerRegistryWrapper(stack); // when fluid container registry is gone, just use FluidBucketWrapper
+ }
+ return new net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper(stack);
+ }
+ else
+ {

View File

@ -19,6 +19,8 @@
package net.minecraftforge.fluids;
import javax.annotation.Nonnull;
import net.minecraft.block.BlockDispenser;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
@ -27,9 +29,7 @@ import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.capability.IFluidHandler;
import javax.annotation.Nonnull;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
/**
* Fills or drains a fluid container item using a Dispenser.
@ -47,7 +47,8 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
private final BehaviorDefaultDispenseItem dispenseBehavior = new BehaviorDefaultDispenseItem();
public ItemStack dispenseStack(IBlockSource source, ItemStack stack)
@Nonnull
public ItemStack dispenseStack(@Nonnull IBlockSource source, @Nonnull ItemStack stack)
{
if (FluidUtil.getFluidContained(stack) != null)
{
@ -63,29 +64,32 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
* Picks up fluid in front of a Dispenser and fills a container with it.
*/
@Nonnull
private ItemStack fillContainer(IBlockSource source, @Nonnull ItemStack stack)
private ItemStack fillContainer(@Nonnull IBlockSource source, @Nonnull ItemStack stack)
{
World world = source.getWorld();
EnumFacing dispenserFacing = source.getBlockState().getValue(BlockDispenser.FACING);
BlockPos blockpos = source.getBlockPos().offset(dispenserFacing);
ItemStack result = FluidUtil.tryPickUpFluid(stack, null, world, blockpos, dispenserFacing.getOpposite());
if (result == null)
FluidActionResult actionResult = FluidUtil.tryPickUpFluid(stack, null, world, blockpos, dispenserFacing.getOpposite());
ItemStack resultStack = actionResult.getResult();
if (!actionResult.isSuccess() || resultStack.func_190926_b())
{
return super.dispenseStack(source, stack);
}
if (stack.func_190916_E() == 1)
{
stack.deserializeNBT(result.serializeNBT());
return resultStack;
}
else if (((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(result) < 0)
else if (((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(resultStack) < 0)
{
this.dispenseBehavior.dispense(source, result);
this.dispenseBehavior.dispense(source, resultStack);
}
stack.func_190918_g(1);
return stack;
ItemStack stackCopy = stack.copy();
stackCopy.func_190918_g(1);
return stackCopy;
}
/**
@ -93,9 +97,9 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
*/
private ItemStack dumpContainer(IBlockSource source, ItemStack stack)
{
ItemStack dispensedStack = stack.copy();
dispensedStack.func_190920_e(1);
IFluidHandler fluidHandler = FluidUtil.getFluidHandler(dispensedStack);
ItemStack singleStack = stack.copy();
singleStack.func_190920_e(1);
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(singleStack);
if (fluidHandler == null)
{
return super.dispenseStack(source, stack);
@ -108,17 +112,20 @@ public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
if (fluidStack != null && fluidStack.amount == Fluid.BUCKET_VOLUME && FluidUtil.tryPlaceFluid(null, source.getWorld(), fluidStack, blockpos))
{
fluidHandler.drain(Fluid.BUCKET_VOLUME, true);
ItemStack drainedStack = fluidHandler.getContainer();
if (stack.func_190916_E() == 1)
{
stack.deserializeNBT(dispensedStack.serializeNBT());
return drainedStack;
}
else if (((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(dispensedStack) < 0)
else if (!drainedStack.func_190926_b() && ((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(drainedStack) < 0)
{
this.dispenseBehavior.dispense(source, dispensedStack);
this.dispenseBehavior.dispense(source, drainedStack);
}
return stack;
ItemStack stackCopy = stack.copy();
stackCopy.func_190918_g(1);
return stackCopy;
}
else
{

View File

@ -0,0 +1,64 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fluids;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
/**
* Holds the result of a fluid action from {@link FluidUtil}.
*
* Failed actions will always have {@link #isSuccess()} == false and an empty ItemStack result. See {@link #FAILURE}.
*
* Successful actions will always have {@link #isSuccess()} == true.
* Successful actions may have an empty ItemStack result in some cases,
* for example the action succeeded and the resulting item was consumed.
*/
public class FluidActionResult
{
public static final FluidActionResult FAILURE = new FluidActionResult(false, ItemStack.field_190927_a);
public final boolean success;
@Nonnull
public final ItemStack result;
public FluidActionResult(@Nonnull ItemStack result)
{
this(true, result);
}
private FluidActionResult(boolean success, @Nonnull ItemStack result)
{
this.success = success;
this.result = result;
}
public boolean isSuccess()
{
return success;
}
@Nonnull
public ItemStack getResult()
{
return result;
}
}

View File

@ -36,6 +36,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.wrappers.BlockLiquidWrapper;
import net.minecraftforge.fluids.capability.wrappers.FluidBlockWrapper;
import net.minecraftforge.items.IItemHandler;
@ -53,37 +54,51 @@ public class FluidUtil
* First it tries to fill the container item from the fluid handler,
* if that action fails then it tries to drain the container item into the fluid handler.
*
* Returns true if interaction was successful.
* Returns false if interaction failed.
* @param stack The filled or empty fluid container.
* Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
* @param fluidHandler The fluid handler to interact with.
* @param player The player doing the interaction between the item and fluid handler.
* @return a {@link FluidActionResult} holding the result and resulting container.
*/
public static boolean interactWithFluidHandler(ItemStack stack, IFluidHandler fluidHandler, EntityPlayer player)
@Nonnull
public static FluidActionResult interactWithFluidHandler(@Nonnull ItemStack stack, IFluidHandler fluidHandler, EntityPlayer player)
{
if (stack == null || fluidHandler == null || player == null)
if (stack.func_190926_b() || fluidHandler == null || player == null)
{
return false;
return FluidActionResult.FAILURE;
}
IItemHandler playerInventory = new InvWrapper(player.inventory);
return tryFillContainerAndStow(stack, fluidHandler, playerInventory, Integer.MAX_VALUE, player) ||
tryEmptyContainerAndStow(stack, fluidHandler, playerInventory, Integer.MAX_VALUE, player);
FluidActionResult fillResult = tryFillContainerAndStow(stack, fluidHandler, playerInventory, Integer.MAX_VALUE, player);
if (fillResult.isSuccess())
{
return fillResult;
}
else
{
return tryEmptyContainerAndStow(stack, fluidHandler, playerInventory, Integer.MAX_VALUE, player);
}
}
/**
* Fill a container from the given fluidSource.
*
* @param container The container to be filled. Will not be modified.
* Separate handling must be done to reduce the stack size, stow containers, etc, on success.
* See {@link #tryFillContainerAndStow(ItemStack, IFluidHandler, IItemHandler, int, EntityPlayer)}.
* @param fluidSource The fluid handler to be drained.
* @param maxAmount The largest amount of fluid that should be transferred.
* @param player The player to make the filling noise. Pass null for no noise.
* @param doFill true if the container should actually be filled, false if it should be simulated.
* @return The filled container or null if the liquid couldn't be taken from the tank.
* @return a {@link FluidActionResult} holding the filled container if successful.
*/
@Nonnull
public static ItemStack tryFillContainer(@Nonnull ItemStack container, IFluidHandler fluidSource, int maxAmount, @Nullable EntityPlayer player, boolean doFill)
public static FluidActionResult tryFillContainer(@Nonnull ItemStack container, IFluidHandler fluidSource, int maxAmount, @Nullable EntityPlayer player, boolean doFill)
{
container = container.copy(); // do not modify the input
container.func_190920_e(1);
IFluidHandler containerFluidHandler = getFluidHandler(container);
ItemStack containerCopy = container.copy(); // do not modify the input
containerCopy.func_190920_e(1);
IFluidHandlerItem containerFluidHandler = getFluidHandler(containerCopy);
if (containerFluidHandler != null)
{
FluidStack simulatedTransfer = tryFluidTransfer(containerFluidHandler, fluidSource, maxAmount, false);
@ -102,30 +117,33 @@ public class FluidUtil
{
containerFluidHandler.fill(simulatedTransfer, true);
}
return container;
ItemStack resultContainer = containerFluidHandler.getContainer();
return new FluidActionResult(resultContainer);
}
}
return null;
return FluidActionResult.FAILURE;
}
/**
* Takes a filled container and tries to empty it into the given tank.
*
* @param container The filled container. Will not be modified.
* Separate handling must be done to reduce the stack size, stow containers, etc, on success.
* See {@link #tryEmptyContainerAndStow(ItemStack, IFluidHandler, IItemHandler, int, EntityPlayer)}.
* @param fluidDestination The fluid handler to be filled by the container.
* @param maxAmount The largest amount of fluid that should be transferred.
* @param player Player for making the bucket drained sound. Pass null for no noise.
* @param doDrain true if the container should actually be drained, false if it should be simulated.
* @return The empty container if successful, null if the fluid handler couldn't be filled.
* NOTE The empty container will have a stackSize of 0 when a filled container is consumable,
* i.e. it has a "null" empty container but has successfully been emptied.
* @return a {@link FluidActionResult} holding the empty container if the fluid handler was filled.
* NOTE If the container is consumable, the empty container will be null on success.
*/
@Nonnull
public static ItemStack tryEmptyContainer(@Nonnull ItemStack container, IFluidHandler fluidDestination, int maxAmount, @Nullable EntityPlayer player, boolean doDrain)
public static FluidActionResult tryEmptyContainer(@Nonnull ItemStack container, IFluidHandler fluidDestination, int maxAmount, @Nullable EntityPlayer player, boolean doDrain)
{
container = container.copy(); // do not modify the input
container.func_190920_e(1);
IFluidHandler containerFluidHandler = getFluidHandler(container);
ItemStack containerCopy = container.copy(); // do not modify the input
containerCopy.func_190920_e(1);
IFluidHandlerItem containerFluidHandler = getFluidHandler(containerCopy);
if (containerFluidHandler != null)
{
FluidStack simulatedTransfer = tryFluidTransfer(fluidDestination, containerFluidHandler, maxAmount, false);
@ -144,10 +162,12 @@ public class FluidUtil
{
containerFluidHandler.drain(simulatedTransfer, true);
}
return container;
ItemStack resultContainer = containerFluidHandler.getContainer();
return new FluidActionResult(resultContainer);
}
}
return null;
return FluidActionResult.FAILURE;
}
/**
@ -157,62 +177,65 @@ public class FluidUtil
* If the inventory does not accept it, it will be given to the player or dropped at the players feet.
* If player is null in this case, the action will be aborted.
*
* @param container The Fluid Container Itemstack to fill. This stack WILL be modified on success.
* @param container The Fluid Container ItemStack to fill.
* Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
* @param fluidSource The fluid source to fill from
* @param inventory An inventory where any additionally created item (filled container if multiple empty are present) are put
* @param maxAmount Maximum amount of fluid to take from the tank.
* @param player The player that gets the items the inventory can't take. Can be null, only used if the inventory cannot take the filled stack.
* @return True if the container was filled successfully and stowed, false otherwise.
* @param player The player that gets the items the inventory can't take.
* Can be null, only used if the inventory cannot take the filled stack.
* @return a {@link FluidActionResult} holding the result and the resulting container. The resulting container is empty on failure.
*/
public static boolean tryFillContainerAndStow(@Nonnull ItemStack container, IFluidHandler fluidSource, IItemHandler inventory, int maxAmount, @Nullable EntityPlayer player)
@Nonnull
public static FluidActionResult tryFillContainerAndStow(@Nonnull ItemStack container, IFluidHandler fluidSource, IItemHandler inventory, int maxAmount, @Nullable EntityPlayer player)
{
if (container.func_190926_b())
{
return false;
return FluidActionResult.FAILURE;
}
if (player != null && player.capabilities.isCreativeMode)
{
ItemStack filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
if (filledReal != null)
FluidActionResult filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
if (filledReal.isSuccess())
{
return true;
return new FluidActionResult(container); // creative mode: item does not change
}
}
else if (container.func_190916_E() == 1) // don't need to stow anything, just fill and edit the container stack
else if (container.func_190916_E() == 1) // don't need to stow anything, just fill the container stack
{
ItemStack filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
if (filledReal != null)
FluidActionResult filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
if (filledReal.isSuccess())
{
container.deserializeNBT(filledReal.serializeNBT());
return true;
return filledReal;
}
}
else
{
ItemStack filledSimulated = tryFillContainer(container, fluidSource, maxAmount, player, false);
if (filledSimulated != null)
FluidActionResult filledSimulated = tryFillContainer(container, fluidSource, maxAmount, player, false);
if (filledSimulated.isSuccess())
{
// check if we can give the itemStack to the inventory
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inventory, filledSimulated, true);
if (remainder == null || player != null)
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inventory, filledSimulated.getResult(), true);
if (remainder.func_190926_b() || player != null)
{
ItemStack filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
remainder = ItemHandlerHelper.insertItemStacked(inventory, filledReal, false);
FluidActionResult filledReal = tryFillContainer(container, fluidSource, maxAmount, player, true);
remainder = ItemHandlerHelper.insertItemStacked(inventory, filledReal.getResult(), false);
// give it to the player or drop it at their feet
if (remainder != null && player != null)
if (!remainder.func_190926_b() && player != null)
{
ItemHandlerHelper.giveItemToPlayer(player, remainder);
}
container.func_190918_g(1);
return true;
ItemStack containerCopy = container.copy();
containerCopy.func_190918_g(1);
return new FluidActionResult(containerCopy);
}
}
}
return false;
return FluidActionResult.FAILURE;
}
/**
@ -222,72 +245,64 @@ public class FluidUtil
* If the inventory does not accept the emptied container, it will be given to the player or dropped at the players feet.
* If player is null in this case, the action will be aborted.
*
* @param container The filled Fluid Container Itemstack to empty. This stack WILL be modified on success.
* @param container The filled Fluid Container Itemstack to empty.
* Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
* @param fluidDestination The fluid destination to fill from the fluid container.
* @param inventory An inventory where any additionally created item (filled container if multiple empty are present) are put
* @param maxAmount Maximum amount of fluid to take from the tank.
* @param player The player that gets the items the inventory can't take. Can be null, only used if the inventory cannot take the filled stack.
* @return True if the container was filled successfully and stowed, false otherwise.
* @return a {@link FluidActionResult} holding the result and the resulting container. The resulting container is empty on failure.
*/
public static boolean tryEmptyContainerAndStow(@Nonnull ItemStack container, IFluidHandler fluidDestination, IItemHandler inventory, int maxAmount, @Nullable EntityPlayer player)
@Nonnull
public static FluidActionResult tryEmptyContainerAndStow(@Nonnull ItemStack container, IFluidHandler fluidDestination, IItemHandler inventory, int maxAmount, @Nullable EntityPlayer player)
{
if (container.func_190926_b())
{
return false;
return FluidActionResult.FAILURE;
}
if (player != null && player.capabilities.isCreativeMode)
{
ItemStack emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
if (emptiedReal != null)
FluidActionResult emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
if (emptiedReal.isSuccess())
{
return true;
return new FluidActionResult(container); // creative mode: item does not change
}
}
else if (container.func_190916_E() == 1) // don't need to stow anything, just fill and edit the container stack
{
ItemStack emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
if (emptiedReal.func_190926_b())
FluidActionResult emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
if (emptiedReal.isSuccess())
{
container.func_190918_g(1);
return emptiedReal;
}
else
{
container.deserializeNBT(emptiedReal.serializeNBT());
}
return true;
}
else
{
ItemStack emptiedSimulated = tryEmptyContainer(container, fluidDestination, maxAmount, player, false);
if (emptiedSimulated.func_190926_b())
{
tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
container.func_190918_g(1);
return true;
}
else
FluidActionResult emptiedSimulated = tryEmptyContainer(container, fluidDestination, maxAmount, player, false);
if (emptiedSimulated.isSuccess())
{
// check if we can give the itemStack to the inventory
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inventory, emptiedSimulated, true);
if (remainder == null || player != null)
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inventory, emptiedSimulated.getResult(), true);
if (remainder.func_190926_b() || player != null)
{
ItemStack emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
remainder = ItemHandlerHelper.insertItemStacked(inventory, emptiedReal, false);
FluidActionResult emptiedReal = tryEmptyContainer(container, fluidDestination, maxAmount, player, true);
remainder = ItemHandlerHelper.insertItemStacked(inventory, emptiedReal.getResult(), false);
// give it to the player or drop it at their feet
if (remainder != null && player != null)
if (!remainder.func_190926_b() && player != null)
{
ItemHandlerHelper.giveItemToPlayer(player, remainder);
}
container.func_190918_g(1);
return true;
ItemStack containerCopy = container.copy();
containerCopy.func_190918_g(1);
return new FluidActionResult(containerCopy);
}
}
}
return false;
return FluidActionResult.FAILURE;
}
/**
@ -308,11 +323,19 @@ public class FluidUtil
int fillableAmount = fluidDestination.fill(drainable, false);
if (fillableAmount > 0)
{
FluidStack drained = fluidSource.drain(fillableAmount, doTransfer);
if (drained != null)
if (doTransfer)
{
drained.amount = fluidDestination.fill(drained, doTransfer);
return drained;
FluidStack drained = fluidSource.drain(fillableAmount, true);
if (drained != null)
{
drained.amount = fluidDestination.fill(drained, true);
return drained;
}
}
else
{
drainable.amount = fillableAmount;
return drainable;
}
}
}
@ -320,23 +343,25 @@ public class FluidUtil
}
/**
* Helper method to get an IFluidHandler for an itemStack.
* Helper method to get an {@link IFluidHandlerItem} for an itemStack.
*
* The itemStack passed in here WILL be modified, the IFluidHandler acts on it directly.
* The itemStack passed in here WILL be modified, the {@link IFluidHandlerItem} acts on it directly.
* Some {@link IFluidHandlerItem} will change the item entirely, always use {@link IFluidHandlerItem#getContainer()}
* after using the fluid handler to get the resulting item back.
*
* Note that the itemStack MUST have a stackSize of 1 if you want to fill or drain it.
* You can't fill or drain a whole stack at once, if you do then liquid is multiplied or destroyed.
* You can't fill or drain multiple items at once, if you do then liquid is multiplied or destroyed.
*
* Vanilla buckets will be converted to universal buckets if they are enabled.
*
* Returns null if the itemStack passed in does not have a fluid handler.
*/
@Nullable
public static IFluidHandler getFluidHandler(ItemStack itemStack)
public static IFluidHandlerItem getFluidHandler(@Nonnull ItemStack itemStack)
{
if (itemStack != null && itemStack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null))
if (itemStack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null))
{
return itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null);
return itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null);
}
else
{
@ -348,13 +373,13 @@ public class FluidUtil
* Helper method to get the fluid contained in an itemStack
*/
@Nullable
public static FluidStack getFluidContained(ItemStack container)
public static FluidStack getFluidContained(@Nonnull ItemStack container)
{
if (container != null)
if (!container.func_190926_b())
{
container = container.copy();
container.func_190920_e(1);
IFluidHandler fluidHandler = FluidUtil.getFluidHandler(container);
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(container);
if (fluidHandler != null)
{
return fluidHandler.drain(Integer.MAX_VALUE, false);
@ -453,18 +478,20 @@ public class FluidUtil
/**
* Attempts to pick up a fluid in the world and put it in an empty container item.
*
* @param emptyContainer The empty container to fill. Will not be modified.
* @param emptyContainer The empty container to fill.
* Will not be modified directly, if modifications are necessary a modified copy is returned in the result.
* @param playerIn The player filling the container. Optional.
* @param worldIn The world the fluid is in.
* @param pos The position of the fluid in the world.
* @param side The side of the fluid that is being drained.
* @return a filled container if it was successful. returns null on failure.
* @return a {@link FluidActionResult} holding the result and the resulting container.
*/
@Nonnull
public static ItemStack tryPickUpFluid(@Nonnull ItemStack emptyContainer, @Nullable EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side)
public static FluidActionResult tryPickUpFluid(@Nonnull ItemStack emptyContainer, @Nullable EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side)
{
if (emptyContainer.func_190926_b() || worldIn == null || pos == null) {
return ItemStack.field_190927_a;
if (emptyContainer.func_190926_b() || worldIn == null || pos == null)
{
return FluidActionResult.FAILURE;
}
IBlockState state = worldIn.getBlockState(pos);
@ -475,9 +502,13 @@ public class FluidUtil
IFluidHandler targetFluidHandler = FluidUtil.getFluidHandler(worldIn, pos, side);
if (targetFluidHandler != null)
{
return FluidUtil.tryFillContainer(emptyContainer, targetFluidHandler, Integer.MAX_VALUE, playerIn, true);
FluidActionResult fluidActionResult = FluidUtil.tryFillContainer(emptyContainer, targetFluidHandler, Integer.MAX_VALUE, playerIn, true);
if (fluidActionResult.isSuccess())
{
return fluidActionResult;
}
}
}
return null;
return FluidActionResult.FAILURE;
}
}

View File

@ -38,6 +38,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.entity.player.FillBucketEvent;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
@ -46,6 +47,8 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nonnull;
/**
* A universal bucket that can hold any liquid
*/
@ -53,6 +56,7 @@ public class UniversalBucket extends Item
{
private final int capacity; // how much the bucket holds
@Nonnull
private final ItemStack empty; // empty item to return and recognize when filling
private final boolean nbtSensitive;
@ -66,7 +70,7 @@ public class UniversalBucket extends Item
* @param empty Item used for filling with the bucket event and returned when emptied
* @param nbtSensitive Whether the empty item is NBT sensitive (usually true if empty and full are the same items)
*/
public UniversalBucket(int capacity, ItemStack empty, boolean nbtSensitive)
public UniversalBucket(int capacity, @Nonnull ItemStack empty, boolean nbtSensitive)
{
this.capacity = capacity;
this.empty = empty;
@ -82,13 +86,13 @@ public class UniversalBucket extends Item
@Override
public boolean hasContainerItem(ItemStack stack)
{
return getEmpty() != null;
return !getEmpty().func_190926_b();
}
@Override
public ItemStack getContainerItem(ItemStack itemStack)
{
if (getEmpty() != null)
if (!getEmpty().func_190926_b())
{
// Create a copy such that the game can't mess with it
return getEmpty().copy();
@ -107,10 +111,11 @@ public class UniversalBucket extends Item
// add all fluids that the bucket can be filled with
FluidStack fs = new FluidStack(fluid, getCapacity());
ItemStack stack = new ItemStack(this);
IFluidHandler fluidHandler = new FluidBucketWrapper(stack);
IFluidHandlerItem fluidHandler = new FluidBucketWrapper(stack);
if (fluidHandler.fill(fs, true) == fs.amount)
{
subItems.add(stack);
ItemStack filled = fluidHandler.getContainer();
subItems.add(filled);
}
}
}
@ -122,7 +127,7 @@ public class UniversalBucket extends Item
FluidStack fluidStack = getFluid(stack);
if (fluidStack == null)
{
if(getEmpty() != null)
if(!getEmpty().func_190926_b())
{
return getEmpty().getDisplayName();
}
@ -176,7 +181,7 @@ public class UniversalBucket extends Item
player.addStat(StatList.getObjectUseStats(this));
itemstack.func_190918_g(1);
ItemStack emptyStack = getEmpty() != null ? getEmpty().copy() : new ItemStack(this);
ItemStack emptyStack = !getEmpty().func_190926_b() ? getEmpty().copy() : new ItemStack(this);
// check whether we replace the item or add the empty one to the inventory
if (itemstack.func_190926_b())
@ -228,11 +233,11 @@ public class UniversalBucket extends Item
ItemStack singleBucket = emptyBucket.copy();
singleBucket.func_190920_e(1);
ItemStack filledBucket = FluidUtil.tryPickUpFluid(singleBucket, event.getEntityPlayer(), world, pos, target.sideHit);
if (filledBucket != null)
FluidActionResult filledResult = FluidUtil.tryPickUpFluid(singleBucket, event.getEntityPlayer(), world, pos, target.sideHit);
if (filledResult.isSuccess())
{
event.setResult(Event.Result.ALLOW);
event.setFilledBucket(filledBucket);
event.setFilledBucket(filledResult.getResult());
}
else
{
@ -242,7 +247,8 @@ public class UniversalBucket extends Item
}
}
public static ItemStack getFilledBucket(UniversalBucket item, Fluid fluid)
@Nonnull
public static ItemStack getFilledBucket(@Nonnull UniversalBucket item, Fluid fluid)
{
ItemStack bucket = new ItemStack(item);
@ -256,11 +262,11 @@ public class UniversalBucket extends Item
}
else if (fluid == FluidRegistry.WATER)
{
bucket.deserializeNBT(new ItemStack(Items.WATER_BUCKET).serializeNBT());
return new ItemStack(Items.WATER_BUCKET);
}
else if (fluid == FluidRegistry.LAVA)
{
bucket.deserializeNBT(new ItemStack(Items.LAVA_BUCKET).serializeNBT());
return new ItemStack(Items.LAVA_BUCKET);
}
return bucket;
@ -276,6 +282,7 @@ public class UniversalBucket extends Item
return capacity;
}
@Nonnull
public ItemStack getEmpty()
{
return empty;
@ -287,7 +294,7 @@ public class UniversalBucket extends Item
}
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt)
public ICapabilityProvider initCapabilities(@Nonnull ItemStack stack, NBTTagCompound nbt)
{
return new FluidBucketWrapper(stack);
}

View File

@ -19,6 +19,10 @@
package net.minecraftforge.fluids.capability;
import java.util.concurrent.Callable;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
@ -29,49 +33,18 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.IFluidTank;
import java.util.concurrent.Callable;
import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack;
public class CapabilityFluidHandler
{
@CapabilityInject(IFluidHandler.class)
public static Capability<IFluidHandler> FLUID_HANDLER_CAPABILITY = null;
@CapabilityInject(IFluidHandlerItem.class)
public static Capability<IFluidHandlerItem> FLUID_HANDLER_ITEM_CAPABILITY = null;
public static void register()
{
CapabilityManager.INSTANCE.register(IFluidHandler.class, new Capability.IStorage<IFluidHandler>()
{
@Override
public NBTBase writeNBT(Capability<IFluidHandler> capability, IFluidHandler instance, EnumFacing side)
{
if (!(instance instanceof IFluidTank))
throw new RuntimeException("IFluidHandler instance does not implement IFluidTank");
NBTTagCompound nbt = new NBTTagCompound();
IFluidTank tank = (IFluidTank) instance;
FluidStack fluid = tank.getFluid();
if (fluid != null)
{
fluid.writeToNBT(nbt);
}
else
{
nbt.setString("Empty", "");
}
nbt.setInteger("Capacity", tank.getCapacity());
return nbt;
}
@Override
public void readNBT(Capability<IFluidHandler> capability, IFluidHandler instance, EnumFacing side, NBTBase nbt)
{
if (!(instance instanceof IFluidTank))
throw new RuntimeException("IFluidHandler instance is not instance of FluidTank");
NBTTagCompound tags = (NBTTagCompound) nbt;
FluidTank tank = (FluidTank) instance;
tank.setCapacity(tags.getInteger("Capacity"));
tank.readFromNBT(tags);
}
}, new Callable<IFluidHandler>()
CapabilityManager.INSTANCE.register(IFluidHandler.class, new DefaultFluidHandlerStorage<IFluidHandler>(), new Callable<IFluidHandler>()
{
@Override
public IFluidHandler call() throws Exception
@ -79,6 +52,46 @@ public class CapabilityFluidHandler
return new FluidTank(Fluid.BUCKET_VOLUME);
}
});
CapabilityManager.INSTANCE.register(IFluidHandlerItem.class, new DefaultFluidHandlerStorage<IFluidHandlerItem>(), new Callable<IFluidHandlerItem>() {
@Override
public IFluidHandlerItem call() throws Exception
{
return new FluidHandlerItemStack(new ItemStack(Items.BUCKET), Fluid.BUCKET_VOLUME);
}
});
}
private static class DefaultFluidHandlerStorage<T extends IFluidHandler> implements Capability.IStorage<T> {
@Override
public NBTBase writeNBT(Capability<T> capability, T instance, EnumFacing side)
{
if (!(instance instanceof IFluidTank))
throw new RuntimeException("IFluidHandler instance does not implement IFluidTank");
NBTTagCompound nbt = new NBTTagCompound();
IFluidTank tank = (IFluidTank) instance;
FluidStack fluid = tank.getFluid();
if (fluid != null)
{
fluid.writeToNBT(nbt);
}
else
{
nbt.setString("Empty", "");
}
nbt.setInteger("Capacity", tank.getCapacity());
return nbt;
}
@Override
public void readNBT(Capability<T> capability, T instance, EnumFacing side, NBTBase nbt)
{
if (!(instance instanceof IFluidTank))
throw new RuntimeException("IFluidHandler instance is not instance of FluidTank");
NBTTagCompound tags = (NBTTagCompound) nbt;
FluidTank tank = (FluidTank) instance;
tank.setCapacity(tags.getInteger("Capacity"));
tank.readFromNBT(tags);
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fluids.capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
/**
* ItemStacks handled by an {@link IFluidHandler} may change, so this class allows
* users of the fluid handler to get the container after it has been used.
*/
public interface IFluidHandlerItem extends IFluidHandler
{
/**
* Get the container currently acted on by this fluid handler.
* The ItemStack may be different from its initial state, in the case of fluid containers that have different items
* for their filled and empty states.
* May be an empty item if the container was drained and is consumable.
*/
@Nonnull
ItemStack getContainer();
}

View File

@ -25,6 +25,9 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A simple fluid container, to replace the functionality of the old FluidContainerRegistry and IFluidContainerItem.
* This fluid container may be set so that is can only completely filled or empty. (binary)
@ -43,7 +46,7 @@ public class ItemFluidContainer extends Item
}
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt)
public ICapabilityProvider initCapabilities(@Nonnull ItemStack stack, @Nullable NBTTagCompound nbt)
{
return new FluidHandlerItemStack(stack, capacity);
}

View File

@ -19,6 +19,7 @@
package net.minecraftforge.fluids.capability.templates;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
@ -29,7 +30,7 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fluids.*;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.FluidTankProperties;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
/**
@ -41,23 +42,31 @@ import net.minecraftforge.fluids.capability.IFluidTankProperties;
* Additional examples are provided to enable consumable fluid containers (see {@link Consumable}),
* fluid containers with different empty and full items (see {@link SwapEmpty},
*/
public class FluidHandlerItemStack implements IFluidHandler, ICapabilityProvider
public class FluidHandlerItemStack implements IFluidHandlerItem, ICapabilityProvider
{
public static final String FLUID_NBT_KEY = "Fluid";
protected final ItemStack container;
protected final int capacity;
@Nonnull
protected ItemStack container;
protected int capacity;
/**
* @param container The container itemStack, data is stored on it directly as NBT.
* @param capacity The maximum capacity of this fluid tank.
*/
public FluidHandlerItemStack(ItemStack container, int capacity)
public FluidHandlerItemStack(@Nonnull ItemStack container, int capacity)
{
this.container = container;
this.capacity = capacity;
}
@Nonnull
@Override
public ItemStack getContainer()
{
return container;
}
@Nullable
public FluidStack getFluid()
{
@ -184,8 +193,7 @@ public class FluidHandlerItemStack implements IFluidHandler, ICapabilityProvider
/**
* Override this method for special handling.
* Can be used to swap out the container's item for a different one with "container.setItem".
* Can be used to destroy the container with "container.stackSize--"
* Can be used to swap out or destroy the container.
*/
protected void setContainerToEmpty()
{
@ -195,14 +203,14 @@ public class FluidHandlerItemStack implements IFluidHandler, ICapabilityProvider
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY ? (T) this : null;
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY ? (T) this : null;
}
/**
@ -240,7 +248,7 @@ public class FluidHandlerItemStack implements IFluidHandler, ICapabilityProvider
protected void setContainerToEmpty()
{
super.setContainerToEmpty();
container.deserializeNBT(emptyContainer.serializeNBT());
container = emptyContainer;
}
}
}

View File

@ -19,6 +19,7 @@
package net.minecraftforge.fluids.capability.templates;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
@ -28,33 +29,41 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.FluidTankProperties;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
/**
* FluidHandlerItemStackSimple is a template capability provider for ItemStacks.
* Data is stored directly in the vanilla NBT, in the same way as the old deprecated {@link ItemFluidContainer}.
* Data is stored directly in the vanilla NBT, in the same way as the old ItemFluidContainer.
*
* This implementation only allows item containers to be fully filled or emptied, similar to vanilla buckets.
*/
public class FluidHandlerItemStackSimple implements IFluidHandler, ICapabilityProvider
public class FluidHandlerItemStackSimple implements IFluidHandlerItem, ICapabilityProvider
{
public static final String FLUID_NBT_KEY = "Fluid";
protected final ItemStack container;
protected final int capacity;
@Nonnull
protected ItemStack container;
protected int capacity;
/**
* @param container The container itemStack, data is stored on it directly as NBT.
* @param capacity The maximum capacity of this fluid tank.
*/
public FluidHandlerItemStackSimple(ItemStack container, int capacity)
public FluidHandlerItemStackSimple(@Nonnull ItemStack container, int capacity)
{
this.container = container;
this.capacity = capacity;
}
@Nonnull
@Override
public ItemStack getContainer()
{
return container;
}
@Nullable
public FluidStack getFluid()
{
@ -171,14 +180,14 @@ public class FluidHandlerItemStackSimple implements IFluidHandler, ICapabilityPr
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY ? (T) this : null;
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY ? (T) this : null;
}
/**
@ -216,7 +225,7 @@ public class FluidHandlerItemStackSimple implements IFluidHandler, ICapabilityPr
protected void setContainerToEmpty()
{
super.setContainerToEmpty();
container.deserializeNBT(emptyContainer.serializeNBT());
container = emptyContainer;
}
}
}

View File

@ -19,6 +19,7 @@
package net.minecraftforge.fluids.capability.wrappers;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.init.Items;
@ -33,6 +34,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.FluidTankProperties;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fluids.UniversalBucket;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
@ -42,15 +44,23 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
* Wrapper for vanilla and forge buckets.
* Swaps between empty bucket and filled bucket of the correct type.
*/
public class FluidBucketWrapper implements IFluidHandler, ICapabilityProvider
public class FluidBucketWrapper implements IFluidHandlerItem, ICapabilityProvider
{
protected final ItemStack container;
@Nonnull
protected ItemStack container;
public FluidBucketWrapper(ItemStack container)
public FluidBucketWrapper(@Nonnull ItemStack container)
{
this.container = container;
}
@Nonnull
@Override
public ItemStack getContainer()
{
return container;
}
public boolean canFillFluidType(FluidStack fluid)
{
if (fluid.getFluid() == FluidRegistry.WATER || fluid.getFluid() == FluidRegistry.LAVA || fluid.getFluid().getName().equals("milk"))
@ -89,24 +99,23 @@ public class FluidBucketWrapper implements IFluidHandler, ICapabilityProvider
protected void setFluid(Fluid fluid) {
if (fluid == null)
{
container.deserializeNBT(new ItemStack(Items.BUCKET).serializeNBT());
container = new ItemStack(Items.BUCKET);
}
else if (fluid == FluidRegistry.WATER)
{
container.deserializeNBT(new ItemStack(Items.WATER_BUCKET).serializeNBT());
container = new ItemStack(Items.WATER_BUCKET);
}
else if (fluid == FluidRegistry.LAVA)
{
container.deserializeNBT(new ItemStack(Items.LAVA_BUCKET).serializeNBT());
container = new ItemStack(Items.LAVA_BUCKET);
}
else if (fluid.getName().equals("milk"))
{
container.deserializeNBT(new ItemStack(Items.MILK_BUCKET).serializeNBT());
container = new ItemStack(Items.MILK_BUCKET);
}
else if (FluidRegistry.isUniversalBucketEnabled() && FluidRegistry.getBucketFluids().contains(fluid))
{
ItemStack filledBucket = UniversalBucket.getFilledBucket(ForgeModContainer.getInstance().universalBucket, fluid);
container.deserializeNBT(filledBucket.serializeNBT());
container = UniversalBucket.getFilledBucket(ForgeModContainer.getInstance().universalBucket, fluid);
}
}
@ -179,15 +188,15 @@ public class FluidBucketWrapper implements IFluidHandler, ICapabilityProvider
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
{
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
return capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing)
{
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
if (capability == CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)
{
return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY.cast(this);
return CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY.cast(this);
}
return null;
}

View File

@ -98,9 +98,10 @@ public class ItemHandlerHelper
* This is equivalent to the behaviour of a player picking up an item.
* Note: This function stacks items without subtypes with different metadata together.
*/
public static ItemStack insertItemStacked(IItemHandler inventory, ItemStack stack, boolean simulate)
@Nonnull
public static ItemStack insertItemStacked(IItemHandler inventory, @Nonnull ItemStack stack, boolean simulate)
{
if (inventory == null || stack == null)
if (inventory == null || stack.func_190926_b())
return stack;
// not stackable -> just insert into a new slot
@ -119,7 +120,7 @@ public class ItemHandlerHelper
{
stack = inventory.insertItem(i, stack, simulate);
if (stack == null)
if (stack.func_190926_b())
{
break;
}
@ -127,15 +128,15 @@ public class ItemHandlerHelper
}
// insert remainder into empty slots
if (stack != null)
if (!stack.func_190926_b())
{
// find empty slot
for (int i = 0; i < sizeInventory; i++)
{
if (inventory.getStackInSlot(i) == null)
if (inventory.getStackInSlot(i).func_190926_b())
{
stack = inventory.insertItem(i, stack, simulate);
if (stack == null)
if (stack.func_190926_b())
{
break;
}

View File

@ -47,6 +47,7 @@ import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fluids.UniversalBucket;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
@ -68,7 +69,7 @@ public class DynBucketTest
private static final ResourceLocation simpleTankName = new ResourceLocation(MODID, "simpletank");
private static final ResourceLocation testItemName = new ResourceLocation(MODID, "testitem");
private static final boolean ENABLE = false;
private static final boolean ENABLE = true;
static
{
@ -152,13 +153,14 @@ public class DynBucketTest
FluidStack fs = new FluidStack(fluid, Fluid.BUCKET_VOLUME);
ItemStack bucket = event.getEmptyBucket();
IFluidHandler fluidHandler = FluidUtil.getFluidHandler(bucket);
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(bucket);
if (fluidHandler != null)
{
int fillAmount = fluidHandler.fill(fs, true);
if (fillAmount > 0)
{
event.setFilledBucket(bucket);
ItemStack filledBucket = fluidHandler.getContainer();
event.setFilledBucket(filledBucket);
event.setResult(Result.ALLOW);
}
}
@ -269,7 +271,7 @@ public class DynBucketTest
}
// do the thing with the tank and the buckets
if (FluidUtil.interactWithFluidHandler(heldItem, tank, playerIn))
if (FluidUtil.interactWithFluidHandler(heldItem, tank, playerIn).isSuccess())
{
return true;
}

View File

@ -27,7 +27,7 @@ public class ModelFluidDebug
public static final String MODID = "forgedebugmodelfluid";
public static final String VERSION = "1.0";
public static final boolean ENABLE = false;
public static final boolean ENABLE = true;
@SidedProxy
public static CommonProxy proxy;

View File

@ -1,6 +1,5 @@
package net.minecraftforge.test;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.creativetab.CreativeTabs;
@ -11,7 +10,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Mod;
@ -19,10 +18,12 @@ import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
@Mod(modid="fluidhandlertest", name="FluidHandlerTest", version="0.0.0")
public class FluidHandlerTest
{
public static final boolean ENABLE = false;
public static final boolean ENABLE = true;
@Mod.EventHandler
public void loadComplete(FMLLoadCompleteEvent event)
@ -38,24 +39,45 @@ public class FluidHandlerTest
private static void testFluidContainer(ItemStack stack)
{
ItemStack drainedStack = stack.copy();
IFluidHandler fluidHandler = FluidUtil.getFluidHandler(drainedStack);
ItemStack originalStack = stack.copy();
ItemStack preDrainStack = stack.copy();
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(preDrainStack);
if (fluidHandler != null)
{
FluidStack drain = fluidHandler.drain(Integer.MAX_VALUE, true);
ItemStack drainedStack = fluidHandler.getContainer();
FMLLog.info("Draining " + stackString(stack) + " gives " + fluidString(drain) + " and " + stackString(drainedStack));
if (drain == null && !ItemStack.areItemStacksEqual(originalStack, preDrainStack))
{
throw new RuntimeException("ItemStack was altered by its fluid handler when drain did nothing.");
}
for (Fluid fluid : FluidRegistry.getRegisteredFluids().values())
{
ItemStack filledStack = stack.copy();
fluidHandler = FluidUtil.getFluidHandler(filledStack);
ItemStack preFillStack = stack.copy();
fluidHandler = FluidUtil.getFluidHandler(preFillStack);
if (fluidHandler != null)
{
int filled = fluidHandler.fill(new FluidStack(fluid, Integer.MAX_VALUE), true);
ItemStack filledStack = fluidHandler.getContainer();
if (filled > 0)
{
FMLLog.info("Filling " + stackString(stack) + " with " + fluidString(new FluidStack(fluid, filled)) + " gives " + stackString(filledStack));
}
else
{
if (!ItemStack.areItemStacksEqual(originalStack, preFillStack))
{
throw new RuntimeException("ItemStack was altered by its fluid handler when fill did nothing.");
}
if (!ItemStack.areItemStacksEqual(preFillStack, filledStack))
{
throw new RuntimeException("ItemStack was altered by its fluid handler when fill did nothing.");
}
}
}
}
}
@ -73,7 +95,7 @@ public class FluidHandlerTest
}
}
private static String stackString(ItemStack stack)
private static String stackString(@Nonnull ItemStack stack)
{
if (stack.func_190926_b())
{
@ -82,7 +104,7 @@ public class FluidHandlerTest
else
{
String resourceDomain;
if (stack.getItem() == null || stack.getItem().getRegistryName() == null)
if (stack.getItem().getRegistryName() == null)
{
resourceDomain = "unknown";
}