Package erogenousbeef.bigreactors.common.tileentity.base

Source Code of erogenousbeef.bigreactors.common.tileentity.base.TileEntityPoweredInventoryFluid

package erogenousbeef.bigreactors.common.tileentity.base;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import net.minecraftforge.fluids.IFluidTank;
import erogenousbeef.bigreactors.common.interfaces.IMultipleFluidHandler;

public abstract class TileEntityPoweredInventoryFluid extends
    TileEntityPoweredInventory implements IFluidHandler, IMultipleFluidHandler {

  private FluidTank[] tanks;
  private FluidTank[][] tankExposureCache;

  protected static final FluidTank[] kEmptyFluidTankList = new FluidTank[0];
  protected static final int FLUIDTANK_NONE = -1;
 
  public TileEntityPoweredInventoryFluid() {
    super();
   
    tanks = new FluidTank[getNumTanks()];
    tankExposureCache = new FluidTank[getNumTanks()][1];

    for(int i = 0; i < getNumTanks(); i++) {
      tanks[i] = new FluidTank(getTankSize(i));
      tankExposureCache[i][0] = tanks[i];
    }
  }

  // Internal Helpers
 
  private void readFluidsFromNBT(NBTTagCompound tag) {
    // Initialize tanks to empty, as we send sparse updates.
    for(int i = 0; i < tanks.length; i++) {
      tanks[i].setFluid(null);
    }

    if(tag.hasKey("fluids")) {
      NBTTagList tagList = tag.getTagList("fluids", 10);
      for(int i = 0; i < tagList.tagCount(); i++) {
        NBTTagCompound fluidTag = tagList.getCompoundTagAt(i);
        int fluidIdx = fluidTag.getInteger("tagIdx");
        FluidStack newFluid = FluidStack.loadFluidStackFromNBT(fluidTag);
        tanks[fluidIdx].setFluid(newFluid);
      }
    }
  }
 
  private void writeFluidsToNBT(NBTTagCompound tag) {
    NBTTagList fluidTagList = new NBTTagList();
    for(int i = 0; i < getNumTanks(); i++) {
      if(tanks[i] != null && tanks[i].getFluid() != null) {
        NBTTagCompound fluidTag = new NBTTagCompound();
        fluidTag.setInteger("tagIdx", i);
        tanks[i].getFluid().writeToNBT(fluidTag);
        fluidTagList.appendTag(fluidTag);
      }
    }
   
    if(fluidTagList.tagCount() > 0) {
      tag.setTag("fluids", fluidTagList);
    }
  }
 
  // TileEntity overrides
  @Override
  public void readFromNBT(NBTTagCompound tag) {
    super.readFromNBT(tag);
    readFluidsFromNBT(tag);
  }
 
  @Override
  public void writeToNBT(NBTTagCompound tag) {
    super.writeToNBT(tag);
    writeFluidsToNBT(tag);
  }
 
  // TileEntityBeefBase
  @Override
  protected void onSendUpdate(NBTTagCompound updateTag) {
    super.onSendUpdate(updateTag);
    writeFluidsToNBT(updateTag);
  }
 
  @Override
  public void onReceiveUpdate(NBTTagCompound updateTag) {
    super.onReceiveUpdate(updateTag);
    readFluidsFromNBT(updateTag);
  }

  // IFluidHandler
 
  /**
   * The number of fluid tanks in this machine.
   * @return The number of fluid tanks in this machine.
   */
   public abstract int getNumTanks();
  
   /**
    * Returns the size of the tank at a given position
    * @param tankIndex The index of the given tank in the tanks array.
    * @return The volume of the tank, in fluid units. 1000 = 1 Bucket.
    */
   public abstract int getTankSize(int tankIndex);

   /**
    * Returns the index of the tank which is exposed on a given world side.
    * Remember to translate this into a reference side!
    * @param side The world side on which the device is being queried for fluid tank exposures.
    * @return The index of the exposed tank, or -1 for none.
    */
   public abstract int getExposedTankFromSide(int side);
  
  /**
     * Fills fluid into internal tanks, distribution is left to the ITankContainer.
     * @param from Orientation the fluid is pumped in from.
     * @param resource FluidStack representing the maximum amount of fluid filled into the ITankContainer
     * @param doFill If false filling will only be simulated.
     * @return Amount of resource that was filled into internal tanks.
     */
    public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
      int tankToFill = FLUIDTANK_NONE;
      if(from != ForgeDirection.UNKNOWN) {
        tankToFill = getExposedTankFromSide(from.ordinal());
      }
      else {
        tankToFill = getDefaultTankForFluid(resource.getFluid());
      }

      if(tankToFill <= FLUIDTANK_NONE) {
        return 0;
      } else {
        return fill(tankToFill, resource, doFill);
      }
    }
    /**
     * Fills fluid into the specified internal tank.
     * @param tankIndex the index of the tank to fill
     * @param resource FluidStack representing the maximum amount of fluid filled into the ITankContainer
     * @param doFill If false filling will only be simulated.
     * @return Amount of resource that was filled into internal tanks.
     */
    public int fill(int tankIndex, FluidStack resource, boolean doFill) {
      if(!isFluidValidForTank(tankIndex, resource)) {
        return 0;
      }
     
      int res = tanks[tankIndex].fill(resource, doFill);
      return res;
    }

    /** Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
   *
   * This method is not Fluid-sensitive.
     * @param from Orientation the fluid is drained to.
     * @param maxDrain Maximum amount of fluid to drain.
     * @param doDrain If false draining will only be simulated.
     * @return FluidStack representing the fluid and amount actually drained from the ITankContainer
     */
    public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
      int tankToDrain = 0;
      if(from != ForgeDirection.UNKNOWN) {
        tankToDrain = getExposedTankFromSide(from.ordinal());
      }

      if(tankToDrain <= FLUIDTANK_NONE) {
        return null;
      } else {
        return drain(tankToDrain, maxDrain, doDrain);
      }
    }
  
    /**
     * Drains fluid out of the specified internal tank.
     * @param tankIndex the index of the tank to drain
     * @param maxDrain Maximum amount of fluid to drain.
     * @param doDrain If false draining will only be simulated.
     * @return FluidStack representing the fluid and amount actually drained from the ITankContainer
     */
    public FluidStack drain(int tankIndex, int maxDrain, boolean doDrain) {
      return tanks[tankIndex].drain(maxDrain, doDrain);
    }

    /**
     * Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
     *
     * @param from
     *            Orientation the Fluid is drained to.
     * @param resource
     *            FluidStack representing the Fluid and maximum amount of fluid to be drained.
     * @param doDrain
     *            If false, drain will only be simulated.
     * @return FluidStack representing the Fluid and amount that was (or would have been, if
     *         simulated) drained.
     */
    public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
      int tankToDrain = 0;
      if(from != ForgeDirection.UNKNOWN) {
        tankToDrain = getExposedTankFromSide(from.ordinal());
      }
     
      if(tankToDrain == FLUIDTANK_NONE) {
        return null;
      }
      else {
        // Can't drain that fluid from that side.
        if(!resource.isFluidEqual( tanks[tankToDrain].getFluid() )) {
          return null;
        }
       
        return drain(tankToDrain, resource.amount, doDrain);
      }
    }
   
    /**
     * @param direction tank side: UNKNOWN for default tank set
     * @return Array of {@link FluidTank}s contained in this ITankContainer for this direction
     */
    public IFluidTank[] getTanks(ForgeDirection direction) {
      if(direction == ForgeDirection.UNKNOWN) {
        return tanks;
      }
      else {
        int exposure = getExposedTankFromSide(direction.ordinal());
        if(exposure == FLUIDTANK_NONE) {
          return kEmptyFluidTankList;
        }
       
        return tankExposureCache[exposure];
      }
    }

    /**
     * Return the tank that this tank container desired to be used for the specified fluid type from the specified direction
     *
     * @param direction the direction
     * @param type the fluid type, null is always an acceptable value
     * @return a tank or null for no such tank
     */
    public IFluidTank getTank(ForgeDirection direction, FluidStack type) {
      if(direction == ForgeDirection.UNKNOWN) {
        return null;
      }
      else {
        int tankIdx = getExposedTankFromSide(direction.ordinal());
        if(tankIdx == FLUIDTANK_NONE) {
          return null;
        }
       
        IFluidTank t = tanks[tankIdx];
        if(type == null || isFluidValidForTank(tankIdx, type)) {
          return t;
        }
       
        return null;
      }
    }

    /**
     * Returns true if the given fluid can be inserted into the given direction.
     *
     * More formally, this should return true if fluid is able to enter from the given direction.
     */
    public boolean canFill(ForgeDirection from, Fluid fluid) {
      int tankIdx = 0;
      if(from != ForgeDirection.UNKNOWN) {
        tankIdx = getExposedTankFromSide(from.ordinal());
      }

      if(tankIdx == FLUIDTANK_NONE) { return false; }

      IFluidTank tank = tanks[tankIdx];
      if(tank.getFluidAmount() <= 0) {
        return true;
      }
      else {
        return tank.getFluid().fluidID == fluid.getID();
      }
    }

    /**
     * Returns true if the given fluid can be extracted from the given direction.
     *
     * More formally, this should return true if fluid is able to leave from the given direction.
     */
    public boolean canDrain(ForgeDirection from, Fluid fluid) {
      int tankIdx = 0;
      if(from != ForgeDirection.UNKNOWN) {
        tankIdx = getExposedTankFromSide(from.ordinal());
      }

      if(tankIdx == FLUIDTANK_NONE) { return false; }

      IFluidTank tank = tanks[tankIdx];
      if(tank.getFluidAmount() <= 0) {
        return false;
      }
      else {
        return tank.getFluid().fluidID == fluid.getID();
      }
    }

    /**
     * Returns an array of objects which represent the internal tanks. These objects cannot be used
     * to manipulate the internal tanks. See {@link FluidTankInfo}.
     *
     * @param from
     *            Orientation determining which tanks should be queried.
     * @return Info for the relevant internal tanks.
     */
    public FluidTankInfo[] getTankInfo(ForgeDirection from) {
      return getTankInfo();
    }

    /**
     * Returns an array of objects which represent the internal tanks. These objects cannot be used
     * to manipulate the internal tanks. See {@link FluidTankInfo}.
     *
     * @return Info for the relevant internal tanks.
     */
    public FluidTankInfo[] getTankInfo() {
      FluidTankInfo[] infos = new FluidTankInfo[tanks.length];
      for(int i = 0; i < tanks.length; i++) {
        infos[i] = tanks[i].getInfo();
      }
     
      return infos;
    }
   
    /**
     * Check if the given fluid is valid for the given tank.
     * Note that the fluid may be null.
     *
     * @param tankIdx The index of the tank to check validity for.
     * @param type The fluid to check validity for, or null.
     * @return True if the fluid can go in the identified tank, false otherwise.
     */
  protected abstract boolean isFluidValidForTank(int tankIdx, FluidStack type);
 
  // Helpers
  /**
   * @param fluid The fluid whose default tank is being queried.
   * @return The index of the tank into which a given fluid should be deposited by default.
   */
  protected abstract int getDefaultTankForFluid(Fluid fluid);
}
TOP

Related Classes of erogenousbeef.bigreactors.common.tileentity.base.TileEntityPoweredInventoryFluid

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.