Package buildcraft.factory

Source Code of buildcraft.factory.TileTank

/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.factory;

import java.io.IOException;

import io.netty.buffer.ByteBuf;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.EnumSkyBlock;

import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;

import buildcraft.BuildCraftCore;
import buildcraft.api.core.SafeTimeTracker;
import buildcraft.core.TileBuildCraft;
import buildcraft.core.fluids.Tank;
import buildcraft.core.fluids.TankManager;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;

public class TileTank extends TileBuildCraft implements IFluidHandler {

  public final Tank tank = new Tank("tank", FluidContainerRegistry.BUCKET_VOLUME * 16, this);
  public final TankManager<Tank> tankManager = new TankManager<Tank>(tank);
  public boolean hasUpdate = false;
  public SafeTimeTracker tracker = new SafeTimeTracker(2 * BuildCraftCore.updateFactor);
  private int prevLightValue = 0;

  /* UPDATING */
  @Override
  public void updateEntity() {
    if (worldObj.isRemote) {
      int lightValue = getFluidLightLevel();
      if (prevLightValue != lightValue) {
        prevLightValue = lightValue;
        worldObj.updateLightByType(EnumSkyBlock.Block, xCoord, yCoord, zCoord);
      }
      return;
    }

    // Have liquid flow down into tanks below if any.
    if (tank.getFluid() != null) {
      moveFluidBelow();
    }

    if (hasUpdate && tracker.markTimeIfDelay(worldObj)) {
      sendNetworkUpdate();
      hasUpdate = false;
    }
  }

  /* NETWORK */
  @Override
  public PacketPayload getPacketPayload() {
    PacketPayload payload = new PacketPayload(new PacketPayload.StreamWriter() {
      @Override
      public void writeData(ByteBuf data) {
        tankManager.writeData(data);
      }
    });
    return payload;
  }

  @Override
  public void handleUpdatePacket(PacketUpdate packet) throws IOException {
    ByteBuf stream = packet.payload.stream;
    tankManager.readData(stream);
  }

  /* SAVING & LOADING */
  @Override
  public void readFromNBT(NBTTagCompound data) {
    super.readFromNBT(data);
    tankManager.readFromNBT(data);
  }

  @Override
  public void writeToNBT(NBTTagCompound data) {
    super.writeToNBT(data);
    tankManager.writeToNBT(data);
  }

  /* HELPER FUNCTIONS */
  /**
   * @return Last tank block below this one or this one if it is the last.
   */
  public TileTank getBottomTank() {

    TileTank lastTank = this;

    while (true) {
      TileTank below = getTankBelow(lastTank);
      if (below != null) {
        lastTank = below;
      } else {
        break;
      }
    }

    return lastTank;
  }

  public TileTank getTopTank() {

    TileTank lastTank = this;

    while (true) {
      TileTank above = getTankAbove(lastTank);
      if (above != null) {
        lastTank = above;
      } else {
        break;
      }
    }

    return lastTank;
  }

  public static TileTank getTankBelow(TileTank tile) {
    TileEntity below = tile.getWorldObj().getTileEntity(tile.xCoord, tile.yCoord - 1, tile.zCoord);
    if (below instanceof TileTank) {
      return (TileTank) below;
    } else {
      return null;
    }
  }

  public static TileTank getTankAbove(TileTank tile) {
    TileEntity above = tile.getWorldObj().getTileEntity(tile.xCoord, tile.yCoord + 1, tile.zCoord);
    if (above instanceof TileTank) {
      return (TileTank) above;
    } else {
      return null;
    }
  }

  public void moveFluidBelow() {
    TileTank below = getTankBelow(this);
    if (below == null) {
      return;
    }

    int used = below.tank.fill(tank.getFluid(), true);
    if (used > 0) {
      hasUpdate = true; // not redundant because tank.drain operates on an IFluidTank, not a tile
      below.hasUpdate = true; // redundant because below.fill sets hasUpdate

      tank.drain(used, true);
    }
  }

  /* ITANKCONTAINER */
  @Override
  public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
    if (resource == null) {
      return 0;
    }

    FluidStack resourceCopy = resource.copy();
    int totalUsed = 0;
    TileTank tankToFill = getBottomTank();

    FluidStack liquid = tankToFill.tank.getFluid();
    if (liquid != null && liquid.amount > 0 && !liquid.isFluidEqual(resourceCopy)) {
      return 0;
    }

    while (tankToFill != null && resourceCopy.amount > 0) {
      int used = tankToFill.tank.fill(resourceCopy, doFill);
      resourceCopy.amount -= used;
      if (used > 0) {
        tankToFill.hasUpdate = true;
      }

      totalUsed += used;
      tankToFill = getTankAbove(tankToFill);
    }
    return totalUsed;
  }

  @Override
  public FluidStack drain(ForgeDirection from, int maxEmpty, boolean doDrain) {
    TileTank bottom = getBottomTank();
    bottom.hasUpdate = true;
    return bottom.tank.drain(maxEmpty, doDrain);
  }

  @Override
  public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
    if (resource == null) {
      return null;
    }
    TileTank bottom = getBottomTank();
    if (!resource.isFluidEqual(bottom.tank.getFluid())) {
      return null;
    }
    return drain(from, resource.amount, doDrain);
  }

  @Override
  public FluidTankInfo[] getTankInfo(ForgeDirection direction) {
    FluidTank compositeTank = new FluidTank(tank.getCapacity());

    TileTank tile = getBottomTank();

    int capacity = tank.getCapacity();

    if (tile != null && tile.tank.getFluid() != null) {
      compositeTank.setFluid(tile.tank.getFluid().copy());
    } else {
      return new FluidTankInfo[]{compositeTank.getInfo()};
    }

    tile = getTankAbove(tile);

    while (tile != null) {

      FluidStack liquid = tile.tank.getFluid();
      if (liquid == null || liquid.amount == 0) {
        // NOOP
      } else if (!compositeTank.getFluid().isFluidEqual(liquid)) {
        break;
      } else {
        compositeTank.getFluid().amount += liquid.amount;
      }

      capacity += tile.tank.getCapacity();
      tile = getTankAbove(tile);
    }

    compositeTank.setCapacity(capacity);
    return new FluidTankInfo[]{compositeTank.getInfo()};
  }

  @Override
  public boolean canFill(ForgeDirection from, Fluid fluid) {
    Fluid tankFluid = getBottomTank().tank.getFluidType();
    return tankFluid == null || tankFluid == fluid;
  }

  @Override
  public boolean canDrain(ForgeDirection from, Fluid fluid) {
    Fluid tankFluid = getBottomTank().tank.getFluidType();
    return tankFluid != null && tankFluid == fluid;
  }

  public int getFluidLightLevel() {
    FluidStack tankFluid = tank.getFluid();
    return tankFluid == null ? 0 : tankFluid.getFluid().getLuminosity(tankFluid);
  }
}
TOP

Related Classes of buildcraft.factory.TileTank

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.