package advancedsystemsmanager.tileentities;
import advancedsystemsmanager.api.tileentities.IBUDListener;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDynamicLiquid;
import net.minecraft.block.BlockStaticLiquid;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.*;
public class TileEntityFluidGate extends TileEntityElementRotation implements IFluidHandler, IBUDListener
{
protected FluidStack tank;
protected FluidStack cachedStack;
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
if (!isBlocked() && resource != null && resource.getFluid().canBePlacedInWorld() && (tank == null || resource.isFluidEqual(tank)))
{
int amount = FluidContainerRegistry.BUCKET_VOLUME - (tank == null ? 0 : tank.amount);
amount = Math.min(amount, resource.amount);
if (amount > 0 && doFill)
{
if (tank == null)
{
tank = resource.copy();
tank.amount = 0;
}
tank.amount += amount;
}
tryPlaceFluid();
return amount;
}
return 0;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
FluidStack tank = getTank(doDrain);
if (resource != null && tank != null && resource.isFluidEqual(tank))
{
FluidStack drain = tank.copy();
drain.amount = Math.min(tank.amount, resource.amount);
if (doDrain)
{
this.tank.amount -= drain.amount;
if (this.tank.amount == 0) this.tank = null;
}
return drain;
}
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
FluidStack tank = getTank(doDrain);
if (tank != null)
{
FluidStack drain = tank.copy();
drain.amount = Math.min(tank.amount, maxDrain);
if (doDrain)
{
this.tank.amount -= drain.amount;
if (this.tank.amount == 0) this.tank = null;
}
return drain;
}
return null;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
ForgeDirection direction = getFacing();
boolean validFluid = fluid != null && fluid.canBePlacedInWorld() && fluid.getBlock() != null && fluid.getBlock().canPlaceBlockAt(worldObj, xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ);
return !isBlocked() && validFluid && (tank == null || tank.getFluid() == fluid);
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
FluidStack stack = getTank(false);
return stack != null && stack.getFluid() == fluid;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
return new FluidTankInfo[]{new FluidTankInfo(getTank(false), FluidContainerRegistry.BUCKET_VOLUME)};
}
private FluidStack getTank(boolean doDrain)
{
if (tank != null && tank.amount > 0) return tank;
if (doDrain)
return tank = drainBlock(true);
return drainBlock(false);
}
private FluidStack drainBlock(boolean doDrain)
{
ForgeDirection direction = getFacing();
Block block = worldObj.getBlock(xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ);
return drainBlock(block, worldObj, xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ, doDrain);
}
public FluidStack drainBlock(Block block, World world, int x, int y, int z, boolean doDrain)
{
Fluid fluid = FluidRegistry.lookupFluidForBlock(block);
FluidStack result;
if (fluid != null && FluidRegistry.isFluidRegistered(fluid))
{
if (block instanceof IFluidBlock)
{
IFluidBlock fluidBlock = (IFluidBlock)block;
if (!fluidBlock.canDrain(world, x, y, z))
{
return cachedStack = null;
}
result = fluidBlock.drain(world, x, y, z, doDrain);
if (doDrain)
{
cachedStack = null;
} else
{
cachedStack = result;
}
return result;
} else
{
if (world.getBlockMetadata(x, y, z) != 0)
{
return null;
}
result = new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME);
if (doDrain)
{
cachedStack = null;
world.setBlockToAir(x, y, z);
} else
{
cachedStack = result;
}
return result;
}
}
return cachedStack = null;
}
public boolean isBlocked()
{
return cachedStack != null;
}
public void tryPlaceFluid()
{
if (tank != null && tank.amount == FluidContainerRegistry.BUCKET_VOLUME)
{
Fluid fluid = tank.getFluid();
ForgeDirection direction = getFacing();
if (fillBlock(fluid, worldObj, xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ, false) == FluidContainerRegistry.BUCKET_VOLUME)
fillBlock(fluid, worldObj, xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ, true);
}
}
public int fillBlock(Fluid fluid, World world, int x, int y, int z, boolean doFill)
{
Block block = fluid.getBlock();
if (block.canPlaceBlockAt(world, x, y, z))
{
Block worldBlock = world.getBlock(x, y, z);
boolean sourceBlock = (worldBlock instanceof IFluidBlock || worldBlock instanceof BlockDynamicLiquid) && world.getBlockMetadata(x, y, z) == 0 || worldBlock instanceof BlockStaticLiquid;
if (!sourceBlock)
{
if (doFill)
{
world.setBlock(x, y, z, block);
world.notifyBlockOfNeighborChange(x, y, z, getBlockType());
tank = null;
}
return FluidContainerRegistry.BUCKET_VOLUME;
}
}
return 0;
}
@Override
public void writeToTileNBT(NBTTagCompound tag)
{
super.writeToTileNBT(tag);
if (tank != null) tank.writeToNBT(tag);
}
@Override
public void readFromTileNBT(NBTTagCompound tag)
{
super.readFromTileNBT(tag);
tank = FluidStack.loadFluidStackFromNBT(tag);
}
@Override
public void onNeighborBlockChange()
{
drainBlock(false);
if (!isBlocked()) tryPlaceFluid();
}
}