ForgePatch/src/main/java/net/minecraftforge/fluids/DispenseFluidContainer.java

138 lines
4.6 KiB
Java

/*
* Minecraft Forge
* Copyright (c) 2016-2018.
*
* 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.block.BlockDispenser;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.item.ItemStack;
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.IFluidHandlerItem;
/**
* Fills or drains a fluid container item using a Dispenser.
*/
public class DispenseFluidContainer extends BehaviorDefaultDispenseItem
{
private static final DispenseFluidContainer INSTANCE = new DispenseFluidContainer();
public static DispenseFluidContainer getInstance()
{
return INSTANCE;
}
private DispenseFluidContainer() {}
private final BehaviorDefaultDispenseItem dispenseBehavior = new BehaviorDefaultDispenseItem();
@Override
@Nonnull
public ItemStack dispenseStack(@Nonnull IBlockSource source, @Nonnull ItemStack stack)
{
if (FluidUtil.getFluidContained(stack) != null)
{
return dumpContainer(source, stack);
}
else
{
return fillContainer(source, stack);
}
}
/**
* Picks up fluid in front of a Dispenser and fills a container with it.
*/
@Nonnull
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);
FluidActionResult actionResult = FluidUtil.tryPickUpFluid(stack, null, world, blockpos, dispenserFacing.getOpposite());
ItemStack resultStack = actionResult.getResult();
if (!actionResult.isSuccess() || resultStack.isEmpty())
{
return super.dispenseStack(source, stack);
}
if (stack.getCount() == 1)
{
return resultStack;
}
else if (((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(resultStack) < 0)
{
this.dispenseBehavior.dispense(source, resultStack);
}
ItemStack stackCopy = stack.copy();
stackCopy.shrink(1);
return stackCopy;
}
/**
* Drains a filled container and places the fluid in front of the Dispenser.
*/
@Nonnull
private ItemStack dumpContainer(IBlockSource source, @Nonnull ItemStack stack)
{
ItemStack singleStack = stack.copy();
singleStack.setCount(1);
IFluidHandlerItem fluidHandler = FluidUtil.getFluidHandler(singleStack);
if (fluidHandler == null)
{
return super.dispenseStack(source, stack);
}
FluidStack fluidStack = fluidHandler.drain(Fluid.BUCKET_VOLUME, false);
EnumFacing dispenserFacing = source.getBlockState().getValue(BlockDispenser.FACING);
BlockPos blockpos = source.getBlockPos().offset(dispenserFacing);
FluidActionResult result = fluidStack != null ? FluidUtil.tryPlaceFluid(null, source.getWorld(), blockpos, stack, fluidStack) : FluidActionResult.FAILURE;
if (result.isSuccess())
{
ItemStack drainedStack = result.getResult();
if (drainedStack.getCount() == 1)
{
return drainedStack;
}
else if (!drainedStack.isEmpty() && ((TileEntityDispenser)source.getBlockTileEntity()).addItemStack(drainedStack) < 0)
{
this.dispenseBehavior.dispense(source, drainedStack);
}
ItemStack stackCopy = drainedStack.copy();
stackCopy.shrink(1);
return stackCopy;
}
else
{
return this.dispenseBehavior.dispense(source, stack);
}
}
}