Package logisticspipes.pipes

Source Code of logisticspipes.pipes.PipeFluidProvider

package logisticspipes.pipes;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import logisticspipes.interfaces.ISpecialTankAccessHandler;
import logisticspipes.interfaces.ISpecialTankHandler;
import logisticspipes.interfaces.routing.IFluidProvider;
import logisticspipes.interfaces.routing.IRequestFluid;
import logisticspipes.logisticspipes.IRoutedItem;
import logisticspipes.logisticspipes.IRoutedItem.TransportMode;
import logisticspipes.pipes.basic.fluid.FluidRoutedPipe;
import logisticspipes.proxy.SimpleServiceLocator;
import logisticspipes.request.FluidRequestTreeNode;
import logisticspipes.routing.FluidLogisticsPromise;
import logisticspipes.routing.order.LogisticsFluidOrderManager;
import logisticspipes.textures.Textures;
import logisticspipes.textures.Textures.TextureType;
import logisticspipes.utils.FluidIdentifier;
import logisticspipes.utils.item.ItemIdentifier;
import logisticspipes.utils.item.ItemIdentifierStack;
import logisticspipes.utils.tuples.Pair;
import logisticspipes.utils.tuples.Triplet;
import net.minecraft.item.Item;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;

public class PipeFluidProvider extends FluidRoutedPipe implements IFluidProvider {
 
  LogisticsFluidOrderManager manager = new LogisticsFluidOrderManager();
 
  public PipeFluidProvider(Item item) {
    super(item);
  }

  @Override
  public void enabledUpdateEntity() {
    super.enabledUpdateEntity();
    if (!manager.hasOrders() || !isNthTick(6)) return;
   
    Triplet<FluidIdentifier, Integer, IRequestFluid> order = manager.getFirst();
    int amountToSend, attemptedAmount;
    amountToSend = attemptedAmount = Math.min(order.getValue2(), 5000);
    for(Pair<TileEntity, ForgeDirection> pair:getAdjacentTanks(false)) {
      if(amountToSend <= 0) break;
      boolean fallback = true;
      if(SimpleServiceLocator.specialTankHandler.hasHandlerFor(pair.getValue1())) {
        ISpecialTankHandler handler = SimpleServiceLocator.specialTankHandler.getTankHandlerFor(pair.getValue1());
        if(handler instanceof ISpecialTankAccessHandler) {
          fallback = false;
          FluidStack drained = ((ISpecialTankAccessHandler)handler).drainFrom(pair.getValue1(), order.getValue1(), amountToSend, false);
          if(drained != null && order.getValue1().equals(FluidIdentifier.get(drained))) {
            drained = ((ISpecialTankAccessHandler)handler).drainFrom(pair.getValue1(), order.getValue1(), amountToSend, true);
            int amount = drained.amount;
            amountToSend -= amount;
            ItemIdentifierStack stack = SimpleServiceLocator.logisticsFluidManager.getFluidContainer(drained);
            IRoutedItem item = SimpleServiceLocator.routedItemHelper.createNewTravelItem(stack);
            item.setDestination(order.getValue3().getRouter().getSimpleID());
            item.setTransportMode(TransportMode.Active);
            this.queueRoutedItem(item, pair.getValue2());
            manager.sendAmount(amount);
            if(amountToSend <= 0) break;
          }
        }
      }
      if(fallback) {
        FluidTankInfo[] tanks = ((IFluidHandler)pair.getValue1()).getTankInfo(pair.getValue2().getOpposite());
        if(tanks != null) {
          for(FluidTankInfo tank:tanks) {
            if(tank == null) continue;
            FluidStack liquid;
            if((liquid = tank.fluid) != null && liquid.fluidID != 0) {
              if(order.getValue1().equals(FluidIdentifier.get(liquid))) {
                int amount = Math.min(liquid.amount, amountToSend);
                FluidStack drained = ((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), amount, false);
                if(drained != null && order.getValue1().equals(FluidIdentifier.get(drained))) {
                  drained = ((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), amount, true);
                  while(drained.amount < amountToSend) {
                    FluidStack addition = ((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), amountToSend - drained.amount, false);
                    if(addition != null && order.getValue1().equals(FluidIdentifier.get(addition))) {
                      addition = ((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), amountToSend - drained.amount, true);
                      drained.amount += addition.amount;
                    } else {
                      break;
                    }
                  }
                  amount = drained.amount;
                  amountToSend -= amount;
                  ItemIdentifierStack stack = SimpleServiceLocator.logisticsFluidManager.getFluidContainer(drained);
                  IRoutedItem item = SimpleServiceLocator.routedItemHelper.createNewTravelItem(stack);
                  item.setDestination(order.getValue3().getRouter().getSimpleID());
                  item.setTransportMode(TransportMode.Active);
                  this.queueRoutedItem(item, pair.getValue2());
                  manager.sendAmount(amount);
                  if(amountToSend <= 0) break;
                }
              }
            }
          }
        }
      }
    }
    if(amountToSend >= attemptedAmount) {
      manager.sendFailed();
    }
  }

  @Override
  public Map<FluidIdentifier, Integer> getAvailableFluids() {
    Map<FluidIdentifier, Integer> map = new HashMap<FluidIdentifier, Integer>();
    for(Pair<TileEntity, ForgeDirection> pair:getAdjacentTanks(false)) {
      boolean fallback = true;
      if(SimpleServiceLocator.specialTankHandler.hasHandlerFor(pair.getValue1())) {
        ISpecialTankHandler handler = SimpleServiceLocator.specialTankHandler.getTankHandlerFor(pair.getValue1());
        if(handler instanceof ISpecialTankAccessHandler) {
          fallback = false;
          Map<FluidIdentifier, Long> tmp = ((ISpecialTankAccessHandler)handler).getAvailableLiquid(pair.getValue1());
          for(Entry<FluidIdentifier, Long> entry: tmp.entrySet()) {
            if(map.containsKey(entry.getKey())) {
              long addition = ((long)map.get(entry.getKey())) + entry.getValue();
              map.put(entry.getKey(), addition > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) addition);
            } else {
              map.put(entry.getKey(), entry.getValue() > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)(long)entry.getValue());
            }
          }
        }
      }
      if(fallback) {
        FluidTankInfo[] tanks = ((IFluidHandler)pair.getValue1()).getTankInfo(pair.getValue2().getOpposite());
        if(tanks != null) {
          for(FluidTankInfo tank:tanks) {
            if(tank == null) continue;
            FluidStack liquid;
            if((liquid = tank.fluid) != null && liquid.fluidID != 0) {
              FluidIdentifier ident = FluidIdentifier.get(liquid);
              if(((IFluidHandler)pair.getValue1()).canDrain(pair.getValue2().getOpposite(), liquid.getFluid())) {
                if(((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), 1, false) != null) {
                  if(map.containsKey(ident)) {
                    long addition = ((long)map.get(ident)) + tank.fluid.amount;
                    map.put(ident, addition > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) addition);
                  } else {
                    map.put(ident, tank.fluid.amount);
                  }
                }
              }
            }
          }
        }
      }
    }
    //Reduce Ordered
    for(Triplet<FluidIdentifier, Integer, IRequestFluid> pair: manager.getAll()) {
      if(map.containsKey(pair.getValue1())) {
        int result = map.get(pair.getValue1()) - pair.getValue2();
        if(result > 0) {
          map.put(pair.getValue1(), result);
        } else {
          map.remove(pair.getValue1());
        }
      }
    }
    return map;
  }
 
  @Override
  public boolean disconnectPipe(TileEntity tile, ForgeDirection dir) {
    return SimpleServiceLocator.pipeInformaitonManager.isFluidPipe(tile);
  }
 
  @Override
  public TextureType getCenterTexture() {
    return Textures.LOGISTICSPIPE_LIQUID_PROVIDER;
  }

  @Override
  public void canProvide(FluidRequestTreeNode request, int donePromises) {
    if(request.isDone()) return;
    int containedAmount = 0;
    for(Pair<TileEntity, ForgeDirection> pair:getAdjacentTanks(false)) {
      boolean fallback = true;
      if(SimpleServiceLocator.specialTankHandler.hasHandlerFor(pair.getValue1())) {
        ISpecialTankHandler handler = SimpleServiceLocator.specialTankHandler.getTankHandlerFor(pair.getValue1());
        if(handler instanceof ISpecialTankAccessHandler) {
          fallback = false;
          Map<FluidIdentifier, Long> map = ((ISpecialTankAccessHandler)handler).getAvailableLiquid(pair.getValue1());
          if(map.containsKey(request.getFluid())) {
            long addition = ((long) containedAmount) + map.get(request.getFluid());
            containedAmount = addition > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) addition;
          }
        }
      }
      if(fallback) {
        FluidTankInfo[] tanks = ((IFluidHandler)pair.getValue1()).getTankInfo(pair.getValue2().getOpposite());
        if(tanks != null) {
          for(FluidTankInfo tank:tanks) {
            if(tank == null) continue;
            FluidStack liquid;
            if((liquid = tank.fluid) != null && liquid.fluidID != 0) {
              if(request.getFluid().equals(FluidIdentifier.get(liquid))) {
                if(((IFluidHandler)pair.getValue1()).canDrain(pair.getValue2().getOpposite(), liquid.getFluid())) {
                  if(((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), 1, false) != null) {
                    long addition = ((long) containedAmount) + liquid.amount;
                    containedAmount = addition > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) addition;
                  }
                }
              }
            }
          }
        }
      }
    }
    FluidLogisticsPromise promise = new FluidLogisticsPromise();
    promise.liquid = request.getFluid();
    promise.amount = Math.min(request.amountLeft(), containedAmount - donePromises);
    promise.sender = this;
    if(promise.amount > 0) {
      request.addPromise(promise);
    }
  }

  @Override
  public void fullFill(FluidLogisticsPromise promise, IRequestFluid destination) {
    manager.add(promise, destination);
  }

  @Override
  public boolean canInsertToTanks() {
    return true;
  }

  @Override
  public boolean canInsertFromSideToTanks() {
    return true;
  }


  @Override //work in progress, currently not active code.
  public Set<ItemIdentifier> getSpecificInterests() {
    Set<ItemIdentifier> l1 = new TreeSet<ItemIdentifier>();
    for(Pair<TileEntity, ForgeDirection> pair:getAdjacentTanks(false)) {
      boolean fallback = true;
      if(SimpleServiceLocator.specialTankHandler.hasHandlerFor(pair.getValue1())) {
        ISpecialTankHandler handler = SimpleServiceLocator.specialTankHandler.getTankHandlerFor(pair.getValue1());
        if(handler instanceof ISpecialTankAccessHandler) {
          fallback = false;
          Map<FluidIdentifier, Long> map = ((ISpecialTankAccessHandler)handler).getAvailableLiquid(pair.getValue1());
          for(FluidIdentifier ident:map.keySet()) {
            l1.add(ident.getItemIdentifier());
          }
        }
      }
      if(fallback) {
        FluidTankInfo[] tanks = ((IFluidHandler)pair.getValue1()).getTankInfo(pair.getValue2().getOpposite());
        if(tanks != null) {
          for(FluidTankInfo tank:tanks) {
            if(tank == null) continue;
            FluidStack liquid;
            if((liquid = tank.fluid) != null && liquid.fluidID != 0) {
              if(((IFluidHandler)pair.getValue1()).canDrain(pair.getValue2().getOpposite(), liquid.getFluid())) {
                if(((IFluidHandler)pair.getValue1()).drain(pair.getValue2().getOpposite(), 1, false) != null) {
                  FluidIdentifier ident = FluidIdentifier.get(liquid);
                  l1.add(ident.getItemIdentifier());
                }
              }
            }
          }
        }
      }
    }
    return l1;
  }

  @Override
  public boolean canReceiveFluid() {
    return false;
  }
}
TOP

Related Classes of logisticspipes.pipes.PipeFluidProvider

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.