Package crazypants.enderio.conduit.liquid

Source Code of crazypants.enderio.conduit.liquid.AdvancedLiquidConduitNetwork$InnerTickHandler

package crazypants.enderio.conduit.liquid;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.IPipeTile.PipeType;
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent;
import crazypants.enderio.conduit.ConduitNetworkTickHandler;
import crazypants.enderio.conduit.ConduitNetworkTickHandler.TickListener;
import crazypants.enderio.conduit.IConduit;
import crazypants.util.BlockCoord;

public class AdvancedLiquidConduitNetwork extends AbstractTankConduitNetwork<AdvancedLiquidConduit> {

  private final ConduitTank tank = new ConduitTank(0);

  private final Set<LiquidOutput> outputs = new HashSet<LiquidOutput>();

  private Iterator<LiquidOutput> outputIterator;

  private int ticksActiveUnsynced;

  private boolean lastSyncedActive = false;

  private int lastSyncedVolume = -1;

  private long timeAtLastApply;

  private final InnerTickHandler tickHandler = new InnerTickHandler();

  private int ticksEmpty;

  public AdvancedLiquidConduitNetwork() {
    super(AdvancedLiquidConduit.class);
  }

  @Override
  public Class<ILiquidConduit> getBaseConduitType() {
    return ILiquidConduit.class;
  }

  @Override
  public void addConduit(AdvancedLiquidConduit con) {
    tank.setCapacity(tank.getCapacity() + AdvancedLiquidConduit.CONDUIT_VOLUME);
    if(con.getTank().containsValidLiquid()) {
      tank.addAmount(con.getTank().getFluidAmount());
    }
    for (ForgeDirection dir : con.getExternalConnections()) {
      if(con.getConnectionMode(dir).acceptsOutput()) {
        outputs.add(new LiquidOutput(con.getLocation().getLocation(dir), dir.getOpposite()));
      }
    }
    outputIterator = null;
    super.addConduit(con);
  }

  @Override
  public boolean setFluidType(FluidStack newType) {
    if(super.setFluidType(newType)) {

      FluidStack ft = getFluidType();
      tank.setLiquid(ft == null ? null : ft.copy());
      return true;
    }
    return false;
  }

  @Override
  public void setFluidTypeLocked(boolean fluidTypeLocked) {
    super.setFluidTypeLocked(fluidTypeLocked);
    if(!fluidTypeLocked && tank.isEmpty()) {
      setFluidType(null);
    }
  }

  @Override
  public void destroyNetwork() {
    setConduitVolumes();
    outputs.clear();
    super.destroyNetwork();
  }

  private void setConduitVolumes() {
    if(tank.containsValidLiquid() && !conduits.isEmpty()) {
      FluidStack fluidPerConduit = tank.getFluid().copy();
      int numCons = conduits.size();
      int leftOvers = fluidPerConduit.amount % numCons;
      fluidPerConduit.amount = fluidPerConduit.amount / numCons;

      for (AdvancedLiquidConduit con : conduits) {
        FluidStack f = fluidPerConduit.copy();
        if(leftOvers > 0) {
          f.amount += 1;
          leftOvers--;
        }
        con.getTank().setLiquid(f);
        BlockCoord bc = con.getLocation();
        con.getBundle().getEntity().getWorldObj().markTileEntityChunkModified(bc.x, bc.y, bc.z, con.getBundle().getEntity());
      }

    }
  }

  @Override
  public void onUpdateEntity(IConduit conduit) {
    World world = conduit.getBundle().getEntity().getWorldObj();
    if(world == null) {
      return;
    }
    if(world.isRemote) {
      return;
    }

    long curTime = world.getTotalWorldTime();
    if(curTime > 0 && curTime != timeAtLastApply) {
      timeAtLastApply = curTime;
      ConduitNetworkTickHandler.instance.addListener(tickHandler);
    }

  }

  private void doTick() {
    if(liquidType == null || outputs.isEmpty() || !tank.containsValidLiquid() || tank.isEmpty()) {
      updateActiveState();
      return;
    }

    if(outputIterator == null || !outputIterator.hasNext()) {
      outputIterator = outputs.iterator();
    }

    updateActiveState();

    int numVisited = 0;
    while (!tank.isEmpty() && numVisited < outputs.size()) {
      if(!outputIterator.hasNext()) {
        outputIterator = outputs.iterator();
      }
      LiquidOutput output = outputIterator.next();
      if(output != null) {
        IFluidHandler cont = getTankContainer(output.location);
        if(cont != null) {
          FluidStack offer = tank.getFluid().copy();
          int filled = cont.fill(output.dir, offer, true);
          if(filled > 0) {
            tank.addAmount(-filled);

          }
        }
      }
      numVisited++;
    }

  }

  private void updateActiveState() {

    boolean isActive = tank.containsValidLiquid() && !tank.isEmpty();
    if(!isActive) {
      if(!fluidTypeLocked && liquidType != null) {
        ticksEmpty++;
        if(ticksEmpty > 40) {
          setFluidType(null);
          ticksEmpty = 0;
          for (IConduit con : conduits) {
            con.setActive(false);
          }
          lastSyncedActive = false;
          ticksActiveUnsynced = 0;
        }
      }
      return;
    }

    ticksEmpty = 0;
   
    if(!lastSyncedActive) {
      for (IConduit con : conduits) {
        con.setActive(true);
      }
      lastSyncedActive = true;
    }

  }

  public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
    if(resource == null) {
      return 0;
    }
    resource.amount = Math.min(resource.amount, AdvancedLiquidConduit.MAX_IO_PER_TICK);
    boolean liquidWasValid = !tank.containsValidLiquid();
    int res = tank.fill(resource, doFill);
    if(doFill && res > 0 && !liquidWasValid) {
      int vol = tank.getFluidAmount();
      setFluidType(resource);
      tank.setAmount(vol);
    }
    return res;
  }

  public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
    if(resource == null || tank.isEmpty() || !tank.containsValidLiquid() || !LiquidConduitNetwork.areFluidsCompatable(getFluidType(), resource)) {
      return null;
    }
    int amount = Math.min(resource.amount, tank.getFluidAmount());
    amount = Math.min(amount, AdvancedLiquidConduit.MAX_IO_PER_TICK);
    FluidStack result = resource.copy();
    result.amount = amount;
    if(doDrain) {
      tank.addAmount(-amount);
    }
    return result;
  }

  public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
    if(tank.isEmpty() || !tank.containsValidLiquid()) {
      return null;
    }
    int amount = Math.min(maxDrain, tank.getFluidAmount());
    FluidStack result = tank.getFluid().copy();
    result.amount = amount;
    if(doDrain) {
      tank.addAmount(-amount);
    }
    return result;
  }

  public boolean extractFrom(AdvancedLiquidConduit advancedLiquidConduit, ForgeDirection dir, int maxExtractPerTick) {

    if(tank.isFull()) {
      return false;
    }

    IFluidHandler extTank = getTankContainer(advancedLiquidConduit, dir);
    if(extTank != null) {
      int maxExtract = Math.min(maxExtractPerTick, tank.getAvailableSpace());

      if(liquidType == null || !tank.containsValidLiquid()) {
        FluidStack drained = extTank.drain(dir.getOpposite(), maxExtract, true);
        if(drained == null || drained.amount <= 0) {
          return false;
        }
        setFluidType(drained);
        tank.setLiquid(drained.copy());
        return true;
      }

      FluidStack couldDrain = liquidType.copy();
      couldDrain.amount = maxExtract;

      boolean foundFluid = false;
      FluidTankInfo[] info = extTank.getTankInfo(dir.getOpposite());
      if(info != null) {
        for (FluidTankInfo inf : info) {
          if(inf != null && inf.fluid != null && inf.fluid.amount > 0) {
            foundFluid = true;
          }
        }
      }
      if(!foundFluid) {
        return false;
      }

      //      FluidStack drained = extTank.drain(dir.getOpposite(), couldDrain, true);
      //      if(drained == null || drained.amount <= 0) {
      //        return false;
      //      }
      //      tank.addAmount(drained.amount);    

      //Have to use this 'double handle' approach to work around an issue with TiC
      FluidStack drained = extTank.drain(dir.getOpposite(), maxExtract, false);
      if(drained == null || drained.amount == 0) {
        return false;
      } else {
        if(drained.isFluidEqual(getFluidType())) {
          drained = extTank.drain(dir.getOpposite(), maxExtract, true);
          tank.addAmount(drained.amount);
        }
      }
      return true;
    }
    return false;
  }

  public IFluidHandler getTankContainer(BlockCoord bc) {
    World w = getWorld();
    if(w == null) {
      return null;
    }
    TileEntity te = w.getTileEntity(bc.x, bc.y, bc.z);
    if(te instanceof IFluidHandler) {
      if(te instanceof IPipeTile) {
        if(((IPipeTile) te).getPipeType() != PipeType.FLUID) {
          return null;
        }
      }
      return (IFluidHandler) te;
    }
    return null;
  }

  public IFluidHandler getTankContainer(AdvancedLiquidConduit con, ForgeDirection dir) {
    BlockCoord bc = con.getLocation().getLocation(dir);
    return getTankContainer(bc);
  }

  World getWorld() {
    if(conduits.isEmpty()) {
      return null;
    }
    return conduits.get(0).getBundle().getWorld();
  }

  public void removeInput(LiquidOutput lo) {
    outputs.remove(lo);
    outputIterator = null;
  }

  public void addInput(LiquidOutput lo) {
    outputs.add(lo);
    outputIterator = null;
  }

  public void updateConduitVolumes() {
    if(tank.getFluidAmount() == lastSyncedVolume) {
      return;
    }
    setConduitVolumes();
    lastSyncedVolume = tank.getFluidAmount();
  }

  private class InnerTickHandler implements TickListener {

    @Override
    public void tickStart(ServerTickEvent evt) {
    }

    @Override
    public void tickEnd(ServerTickEvent evt) {
      doTick();
    }
  }

}
TOP

Related Classes of crazypants.enderio.conduit.liquid.AdvancedLiquidConduitNetwork$InnerTickHandler

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.