Implement fluid item capabilities without item swapping
This commit is contained in:
parent
6f1a44a405
commit
eb6b3ea228
|
@ -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
|
||||
+ {
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue