package erogenousbeef.bigreactors.common.multiblock.tileentity;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import erogenousbeef.bigreactors.common.multiblock.MultiblockTurbine;
import erogenousbeef.bigreactors.common.multiblock.interfaces.INeighborUpdatableEntity;
import erogenousbeef.bigreactors.common.multiblock.interfaces.ITickableMultiblockPart;
import erogenousbeef.core.multiblock.MultiblockControllerBase;
public class TileEntityTurbineFluidPort extends TileEntityTurbinePartStandard implements IFluidHandler, INeighborUpdatableEntity, ITickableMultiblockPart {
public enum FluidFlow {
In,
Out
}
FluidFlow flowSetting;
IFluidHandler pumpDestination;
public TileEntityTurbineFluidPort() {
super();
flowSetting = FluidFlow.In;
pumpDestination = null;
}
public void setFluidFlowDirection(FluidFlow newDirection, boolean markDirty) {
flowSetting = newDirection;
if(!worldObj.isRemote) {
if(markDirty) {
this.markDirty();
}
else {
notifyNeighborsOfTileChange();
}
}
else {
notifyNeighborsOfTileChange();
}
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public void onMachineAssembled(MultiblockControllerBase multiblockControllerBase)
{
super.onMachineAssembled(multiblockControllerBase);
checkForAdjacentTank();
this.notifyNeighborsOfTileChange();
}
@Override
public void onMachineBroken()
{
super.onMachineBroken();
pumpDestination = null;
}
@Override
public void writeToNBT(NBTTagCompound data) {
super.writeToNBT(data);
data.setInteger("flowSetting", flowSetting.ordinal());
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
if(data.hasKey("flowSetting")) {
flowSetting = FluidFlow.values()[data.getInteger("flowSetting")];
}
}
@Override
public void encodeDescriptionPacket(NBTTagCompound data) {
super.encodeDescriptionPacket(data);
data.setInteger("flowSetting", flowSetting.ordinal());
}
@Override
public void decodeDescriptionPacket(NBTTagCompound data) {
super.decodeDescriptionPacket(data);
if(data.hasKey("flowSetting")) {
flowSetting = FluidFlow.values()[data.getInteger("flowSetting")];
}
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
if(!isConnected() || from != getOutwardsDir()) { return 0; }
if(flowSetting != FluidFlow.In) {
return 0;
}
return getTurbine().fill(getTankIndex(), resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource,
boolean doDrain) {
if(resource == null || !isConnected() || from != getOutwardsDir()) { return resource; }
return getTurbine().drain(getTankIndex(), resource, doDrain);
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
if(!isConnected() || from != getOutwardsDir()) { return null; }
return getTurbine().drain(getTankIndex(), maxDrain, doDrain);
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
if(!isConnected() || from != getOutwardsDir()) { return false; }
if(flowSetting != FluidFlow.In) {
return false;
}
return getTurbine().canFill(getTankIndex(), fluid);
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
if(!isConnected() || from != getOutwardsDir()) { return false; }
return getTurbine().canDrain(getTankIndex(), fluid);
}
protected static final FluidTankInfo[] emptyTankInfoArray = new FluidTankInfo[0];
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
if(!isConnected() || from != getOutwardsDir()) { return emptyTankInfoArray; }
return new FluidTankInfo[] { getTurbine().getTankInfo(getTankIndex()) };
}
private int getTankIndex() {
if(flowSetting == FluidFlow.In) { return MultiblockTurbine.TANK_INPUT; }
else { return MultiblockTurbine.TANK_OUTPUT; }
}
public FluidFlow getFlowDirection() { return flowSetting; }
// ITickableMultiblockPart
@Override
public void onMultiblockServerTick() {
// Try to pump steam out, if an outlet
if(pumpDestination == null || flowSetting != FluidFlow.Out)
return;
MultiblockTurbine turbine = getTurbine();
FluidStack fluidToDrain = turbine.drain(MultiblockTurbine.TANK_OUTPUT, turbine.TANK_SIZE, false);
if(fluidToDrain != null && fluidToDrain.amount > 0)
{
fluidToDrain.amount = pumpDestination.fill(getOutwardsDir().getOpposite(), fluidToDrain, true);
turbine.drain(MultiblockTurbine.TANK_OUTPUT, fluidToDrain, true);
}
}
// INeighborUpdatableEntity
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block neighborBlock) {
if(!world.isRemote) {
checkForAdjacentTank();
}
}
@Override
public void onNeighborTileChange(IBlockAccess world, int x, int y, int z, int neighborX, int neighborY, int neighborZ) {
if(!worldObj.isRemote) {
checkForAdjacentTank();
}
}
// Private Helpers
protected void checkForAdjacentTank()
{
pumpDestination = null;
if(worldObj.isRemote || flowSetting == FluidFlow.In) {
return;
}
ForgeDirection outDir = getOutwardsDir();
if(outDir == ForgeDirection.UNKNOWN) {
return;
}
TileEntity neighbor = worldObj.getTileEntity(xCoord + outDir.offsetX, yCoord + outDir.offsetY, zCoord + outDir.offsetZ);
if(neighbor instanceof IFluidHandler) {
pumpDestination = (IFluidHandler)neighbor;
}
}
}