Package logisticspipes.modules

Source Code of logisticspipes.modules.ModuleActiveSupplier

package logisticspipes.modules;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import logisticspipes.interfaces.IClientInformationProvider;
import logisticspipes.interfaces.IHUDModuleHandler;
import logisticspipes.interfaces.IHUDModuleRenderer;
import logisticspipes.interfaces.IInventoryUtil;
import logisticspipes.interfaces.IModuleInventoryReceive;
import logisticspipes.interfaces.IModuleWatchReciver;
import logisticspipes.interfaces.routing.IAdditionalTargetInformation;
import logisticspipes.interfaces.routing.IRequestItems;
import logisticspipes.interfaces.routing.IRequireReliableTransport;
import logisticspipes.interfaces.routing.ITargetSlotInformation;
import logisticspipes.modules.abstractmodules.LogisticsGuiModule;
import logisticspipes.modules.abstractmodules.LogisticsModule;
import logisticspipes.network.NewGuiHandler;
import logisticspipes.network.PacketHandler;
import logisticspipes.network.abstractguis.ModuleCoordinatesGuiProvider;
import logisticspipes.network.abstractguis.ModuleInHandGuiProvider;
import logisticspipes.network.guis.module.inhand.ActiveSupplierInHand;
import logisticspipes.network.guis.module.inpipe.ActiveSupplierSlot;
import logisticspipes.network.packets.hud.HUDStartModuleWatchingPacket;
import logisticspipes.network.packets.hud.HUDStopModuleWatchingPacket;
import logisticspipes.network.packets.module.ModuleInventory;
import logisticspipes.pipefxhandlers.Particles;
import logisticspipes.pipes.PipeLogisticsChassi.ChasseTargetInformation;
import logisticspipes.pipes.basic.debug.StatusEntry;
import logisticspipes.proxy.MainProxy;
import logisticspipes.proxy.SimpleServiceLocator;
import logisticspipes.request.RequestTree;
import logisticspipes.routing.IRouter;
import logisticspipes.utils.AdjacentTile;
import logisticspipes.utils.ISimpleInventoryEventHandler;
import logisticspipes.utils.PlayerCollectionList;
import logisticspipes.utils.SinkReply;
import logisticspipes.utils.WorldUtil;
import logisticspipes.utils.item.ItemIdentifier;
import logisticspipes.utils.item.ItemIdentifierInventory;
import logisticspipes.utils.item.ItemIdentifierStack;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IIcon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ModuleActiveSupplier extends LogisticsGuiModule implements IRequestItems, IRequireReliableTransport, IClientInformationProvider, IHUDModuleHandler, IModuleWatchReciver, IModuleInventoryReceive, ISimpleInventoryEventHandler {

  private final PlayerCollectionList localModeWatchers = new PlayerCollectionList();

  private boolean _lastRequestFailed = false;
 
  public ModuleActiveSupplier() {
    dummyInventory.addListener(this);
  }

  @Override
  public SinkReply sinksItem(ItemIdentifier item, int bestPriority, int bestCustomPriority, boolean allowDefault, boolean includeInTransit) {
    return null;
  }

  @Override
  public LogisticsModule getSubModule(int slot) {return null;}

  @Override
  public List<String> getClientInformation() {
    List<String> list = new ArrayList<String>();
    list.add("Supplied: ");
    list.add("<inventory>");
    list.add("<that>");
    return list;
  }
 
  @Override
  public void startHUDWatching() {
    MainProxy.sendPacketToServer(PacketHandler.getPacket(HUDStartModuleWatchingPacket.class).setModulePos(this));
  }

  @Override
  public void stopHUDWatching() {
    MainProxy.sendPacketToServer(PacketHandler.getPacket(HUDStopModuleWatchingPacket.class).setModulePos(this));
  }

  @Override
  public void startWatching(EntityPlayer player) {
    localModeWatchers.add(player);
    MainProxy.sendPacketToPlayer(PacketHandler.getPacket(ModuleInventory.class).setIdentList(ItemIdentifierStack.getListFromInventory(dummyInventory)).setModulePos(this), player);
  }

  @Override
  public void stopWatching(EntityPlayer player) {
    localModeWatchers.remove(player);
  }

  @Override
  public IHUDModuleRenderer getHUDRenderer() {
    return null;
    //return HUD;
  }

  @Override
  public void handleInvContent(Collection<ItemIdentifierStack> list) {
    dummyInventory.handleItemIdentifierList(list);
  }

  @Override
  public void InventoryChanged(IInventory inventory) {
    MainProxy.sendToPlayerList(PacketHandler.getPacket(ModuleInventory.class).setIdentList(ItemIdentifierStack.getListFromInventory(dummyInventory)).setModulePos(this), localModeWatchers);
  }

  @Override
  public boolean hasGenericInterests() {
    return false;
  }

  @Override
  public List<ItemIdentifier> getSpecificInterests() {
    return new ArrayList<ItemIdentifier>(0);
  }

  @Override
  public boolean interestedInAttachedInventory() {   
    return false;
  }

  @Override
  public boolean interestedInUndamagedID() {
    return false;
  }

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

  @Override
  @SideOnly(Side.CLIENT)
  public IIcon getIconTexture(IIconRegister register) {
    return register.registerIcon("logisticspipes:itemModule/ModuleActiveSupplier");
  }

  /* TRIGGER INTERFACE */
  public boolean isRequestFailed(){
    return _lastRequestFailed;
  }
  
  public void setRequestFailed(boolean value){
    _lastRequestFailed = value;
  }

  private ItemIdentifierInventory dummyInventory = new ItemIdentifierInventory(9, "", 127);
 
  private final HashMap<ItemIdentifier, Integer> _requestedItems = new HashMap<ItemIdentifier, Integer>();
 
  public enum SupplyMode {
    Partial,
    Full,
    Bulk50,
    Bulk100,
    Infinite
  }
 
  public enum PatternMode {
    Partial,
    Full,
    Bulk50,
    Bulk100;
  }
 
  private SupplyMode _requestMode = SupplyMode.Bulk50;
  private PatternMode _patternMode = PatternMode.Bulk50;
  @Getter
  @Setter
  private boolean isLimited = true;

  public int[] slotArray = new int[9];
 
  /*** GUI ***/
  public ItemIdentifierInventory getDummyInventory() {
    return dummyInventory;
  }

  @Override
  public void tick() {
    if(!_service.isNthTick(100)) return;
   
    for(int amount : _requestedItems.values()) {
      if(amount > 0) {
        _service.spawnParticle(Particles.VioletParticle, 2);
      }
    }

    WorldUtil worldUtil = new WorldUtil(_world.getWorld(), getX(), getY(), getZ());
    for (AdjacentTile tile :  worldUtil.getAdjacentTileEntities(true)){
      if (!(tile.tile instanceof IInventory)) continue;
     
      IInventory inv = (IInventory) tile.tile;
      if (inv.getSizeInventory() < 1) continue;
      IInventoryUtil invUtil = SimpleServiceLocator.inventoryUtilFactory.getInventoryUtil(inv);
     
      if(_service.getUpgradeManager().hasPatternUpgrade()) {
        createPatternRequest(invUtil);
      } else {
        createSupplyRequest(invUtil);
      }

    }
  }

  private void createPatternRequest(IInventoryUtil invUtil) {
    _service.getDebug().log("Supplier: Start calculating pattern request");
    setRequestFailed(false);
    for(int i=0;i < 9;i++) {
      ItemIdentifierStack needed = dummyInventory.getIDStackInSlot(i);
      if(needed == null) continue;
      if(invUtil.getSizeInventory() <= slotArray[i]) continue;
      ItemStack stack = invUtil.getStackInSlot(slotArray[i]);
      ItemIdentifierStack have = null;
      if(stack != null) {
        have = ItemIdentifierStack.getFromStack(stack);
      }
      int haveCount = 0;
      if(have != null) {
        if(!have.getItem().equals(needed.getItem())) {
          _service.getDebug().log("Supplier: Slot for " + i + ", " + needed + " already taken by " + have);
          setRequestFailed(true);
          continue;
        }
        haveCount = have.getStackSize();
      }
      if( ( _patternMode==PatternMode.Bulk50 && haveCount > needed.getStackSize()/2) ||
          ( _patternMode==PatternMode.Bulk100 && haveCount >= needed.getStackSize())) {
        continue;
      }
     

      Integer requestedCount =  _requestedItems.get(needed.getItem());
      if (requestedCount != null) {
        haveCount += requestedCount;
      }
     
      int neededCount = needed.getStackSize() - haveCount;
      if(neededCount < 1) continue;
     
      ItemIdentifierStack toRequest = new ItemIdentifierStack(needed.getItem(), neededCount);
     
      _service.getDebug().log("Supplier: Missing for slot " + i + ": " + toRequest);

      if(!_service.useEnergy(10)) {
        break;
      }
     
      boolean success = false;
     
      IAdditionalTargetInformation targetInformation = new PatternSupplierTargetInformation(slotArray[i], needed.getStackSize());
     
      if(_patternMode != PatternMode.Full) {
        _service.getDebug().log("Supplier: Requesting partial: " + toRequest);
        neededCount = RequestTree.requestPartial(toRequest, this, targetInformation);
        _service.getDebug().log("Supplier: Requested: " + toRequest.getItem().makeStack(neededCount));
        if(neededCount > 0) {
          success = true;
        }
      } else {
        _service.getDebug().log("Supplier: Requesting: " + toRequest);
        success = RequestTree.request(toRequest, this, null, targetInformation);
        if(success) {
          _service.getDebug().log("Supplier: Request success");
        } else {
          _service.getDebug().log("Supplier: Request failed");
        }
      }
     
      if (success){
        Integer currentRequest = _requestedItems.get(toRequest.getItem());
        if(currentRequest == null) {
          _requestedItems.put(toRequest.getItem(), neededCount);
        } else {
          _requestedItems.put(toRequest.getItem(), currentRequest + neededCount);
        }
      } else {
        setRequestFailed(true);
      }
    }
  }

  private void createSupplyRequest(IInventoryUtil invUtil) {
    _service.getDebug().log("Supplier: Start calculating supply request");
    //How many do I want?
    HashMap<ItemIdentifier, Integer> needed = new HashMap<ItemIdentifier, Integer>(dummyInventory.getItemsAndCount());
    _service.getDebug().log("Supplier: Needed: " + needed);
   
    //How many do I have?
    Map<ItemIdentifier, Integer> have = invUtil.getItemsAndCount();
    _service.getDebug().log("Supplier: Have:   " + have);
   
    //How many do I have?
    HashMap<ItemIdentifier, Integer> haveUndamaged = new HashMap<ItemIdentifier, Integer>();
    for (Entry<ItemIdentifier, Integer> item : have.entrySet()){
      Integer n=haveUndamaged.get(item.getKey().getUndamaged());
      if(n==null)
        haveUndamaged.put(item.getKey().getUndamaged(), item.getValue());
      else
        haveUndamaged.put(item.getKey().getUndamaged(), item.getValue()+n);
    }
   
    //Reduce what I have and what have been requested already
    for (Entry<ItemIdentifier, Integer> item : needed.entrySet()){
      Integer haveCount = haveUndamaged.get(item.getKey().getUndamaged());
      if(haveCount==null)
        haveCount=0;
      int spaceAvailable = invUtil.roomForItem(item.getKey());
      if(_requestMode==SupplyMode.Infinite) {
        Integer requestedCount =  _requestedItems.get(item.getKey());
        if (requestedCount!=null){
          spaceAvailable -= requestedCount;
        }
        item.setValue(Math.min(item.getKey().getMaxStackSize(), spaceAvailable));
        continue;

      }
      if(spaceAvailable == 0 ||
          ( _requestMode==SupplyMode.Bulk50 && haveCount>item.getValue()/2) ||
          ( _requestMode==SupplyMode.Bulk100 && haveCount>=item.getValue()))
      {
        item.setValue(0);
        continue;
      }
      if (haveCount >0){
        item.setValue(item.getValue() - haveCount);
        // so that 1 damaged item can't satisfy a request for 2 other damage values.
        haveUndamaged.put(item.getKey().getUndamaged(),haveCount - item.getValue());
      }
      Integer requestedCount =  _requestedItems.get(item.getKey());
      if (requestedCount!=null){
        item.setValue(item.getValue() - requestedCount);
      }
    }
   
    _service.getDebug().log("Supplier: Missing:   " + needed);
   
    setRequestFailed(false);

    //Make request
    for (Entry<ItemIdentifier, Integer> need : needed.entrySet()){
      Integer amountRequested = need.getValue();
      if (amountRequested==null || amountRequested < 1) continue;
      int neededCount = amountRequested;
      if(!_service.useEnergy(10)) {
        break;
      }
     
      boolean success = false;

      IAdditionalTargetInformation targetInformation = new SupplierTargetInformation();
     
      if(_requestMode!=SupplyMode.Full) {
        _service.getDebug().log("Supplier: Requesting partial: " + need.getKey().makeStack(neededCount));
        neededCount = RequestTree.requestPartial(need.getKey().makeStack(neededCount), this, targetInformation);
        _service.getDebug().log("Supplier: Requested: " + need.getKey().makeStack(neededCount));
        if(neededCount > 0) {
          success = true;
        }
      } else {
        _service.getDebug().log("Supplier: Requesting: " + need.getKey().makeStack(neededCount));
        success = RequestTree.request(need.getKey().makeStack(neededCount), this, null, targetInformation);
        if(success) {
          _service.getDebug().log("Supplier: Request success");
        } else {
          _service.getDebug().log("Supplier: Request failed");
        }
      }
     
      if (success){
        Integer currentRequest = _requestedItems.get(need.getKey());
        if(currentRequest == null) {
          _requestedItems.put(need.getKey(), neededCount);
          _service.getDebug().log("Supplier: Inserting Requested Items: " + neededCount);
        } else {
          _requestedItems.put(need.getKey(), currentRequest + neededCount);
          _service.getDebug().log("Supplier: Raising Requested Items from: " + currentRequest + " to: " + currentRequest + neededCount);
        }
      } else {
        setRequestFailed(true);
      }
     
    }
  }

  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    dummyInventory.readFromNBT(nbttagcompound, "");
    if(nbttagcompound.hasKey("requestmode")){
      _requestMode=SupplyMode.values()[nbttagcompound.getShort("requestmode")];
    }
    if(nbttagcompound.hasKey("patternmode")){
      _patternMode=PatternMode.values()[nbttagcompound.getShort("patternmode")];
    }
    if(nbttagcompound.hasKey("limited")){
      setLimited(nbttagcompound.getBoolean("limited"));
    }
    if(nbttagcompound.hasKey("requestpartials")){
      boolean oldPartials = nbttagcompound.getBoolean("requestpartials");
      if(oldPartials)
        _requestMode=SupplyMode.Partial;
      else
        _requestMode=SupplyMode.Full;
    }
    for(int i=0;i<9;i++) {
      slotArray[i] = nbttagcompound.getInteger("slotArray_" + i);
    }
    }

  @Override
    public void writeToNBT(NBTTagCompound nbttagcompound) {
      dummyInventory.writeToNBT(nbttagcompound, "");
      nbttagcompound.setShort("requestmode", (short) _requestMode.ordinal());
      nbttagcompound.setShort("patternmode", (short) _patternMode.ordinal());
      nbttagcompound.setBoolean("limited", isLimited());
      for(int i=0;i<9;i++) {
      nbttagcompound.setInteger("slotArray_" + i, slotArray[i]);
    }
  }
 
  private void decreaseRequested(ItemIdentifierStack item) {
    int remaining = item.getStackSize();
    //see if we can get an exact match
    Integer count = _requestedItems.get(item.getItem());
    if (count != null) {
      _service.getDebug().log("Supplier: Exact match. Still missing: " + Math.max(0, count - remaining));
      if(count - remaining > 0) {
        _requestedItems.put(item.getItem(), count - remaining);
      } else {
        _requestedItems.remove(item.getItem());
      }
      remaining -= count;
    }
    if(remaining <= 0) {
      return;
    }
    //still remaining... was from fuzzyMatch on a crafter
    Iterator<Entry<ItemIdentifier, Integer>> it = _requestedItems.entrySet().iterator();
    while(it.hasNext()) {
      Entry<ItemIdentifier, Integer> e = it.next();
      if(e.getKey().equalsWithoutNBT(item.getItem())) {
        int expected = e.getValue();
        _service.getDebug().log("Supplier: Fuzzy match with" + e + ". Still missing: " + Math.max(0, expected - remaining));
        if(expected - remaining > 0) {
          e.setValue(expected - remaining);
        } else {
          it.remove();
        }
        remaining -= expected;
      }
      if(remaining <= 0) {
        return;
      }
    }
    //we have no idea what this is, log it.
    _service.getDebug().log("Supplier: supplier got unexpected item " + item.toString());
  }

  @Override
  public void itemLost(ItemIdentifierStack item, IAdditionalTargetInformation info) {
    _service.getDebug().log("Supplier: Registered Item Lost: " + item);
    decreaseRequested(item);
  }

  @Override
  public void itemArrived(ItemIdentifierStack item, IAdditionalTargetInformation info) {
    _service.getDebug().log("Supplier: Registered Item Arrived: " + item);
    decreaseRequested(item);
  }
 
  public SupplyMode getSupplyMode() {
    return _requestMode;
  }
 
  public void setSupplyMode(SupplyMode mode) {
    _requestMode = mode;
  }
 
  public PatternMode getPatternMode() {
    return _patternMode;
  }
 
  public void setPatternMode(PatternMode mode) {
    _patternMode = mode;
  }

  public int[] getSlotsForItemIdentifier(ItemIdentifier item) {
    int size = 0;
    for(int i=0;i<9;i++) {
      if(dummyInventory.getIDStackInSlot(i) != null && dummyInventory.getIDStackInSlot(i).getItem().equals(item)) size++;
    }
    int[] array = new int[size];
    int pos = 0;
    for(int i=0;i<9;i++) {
      if(dummyInventory.getIDStackInSlot(i) != null && dummyInventory.getIDStackInSlot(i).getItem().equals(item)) {
        array[pos++] = i;
      }
    }
    return array;
  }
 
  public int getInvSlotForSlot(int i) {
    return slotArray[i];
  }
 
  public int getAmountForSlot(int i) {
    return dummyInventory.getIDStackInSlot(i).getStackSize();
  }

  public void addStatusInformation(List<StatusEntry> status) {
    StatusEntry entry = new StatusEntry();
    entry.name = "Requested Items";
    entry.subEntry = new ArrayList<StatusEntry>();
    for(Entry<ItemIdentifier, Integer> part:_requestedItems.entrySet()) {
      StatusEntry subEntry = new StatusEntry();
      subEntry.name = part.toString();
      entry.subEntry.add(subEntry);
    }
    status.add(entry);
  }

  @Override
  protected ModuleCoordinatesGuiProvider getPipeGuiProvider() {
    return NewGuiHandler.getGui(ActiveSupplierSlot.class).setPatternUpgarde(this.hasPatternUpgrade()).setSlotArray(slotArray).setMode((_service.getUpgradeManager().hasPatternUpgrade() ? getPatternMode() : getSupplyMode()).ordinal()).setLimit(isLimited);
  }

  @Override
  protected ModuleInHandGuiProvider getInHandGuiProvider() {
    return NewGuiHandler.getGui(ActiveSupplierInHand.class);
  }

  @Override
  public IRouter getRouter() {
    return _service.getRouter();
  }

  @Override
  public void itemCouldNotBeSend(ItemIdentifierStack item, IAdditionalTargetInformation info) {
    this.itemLost(item, info);
  }

  @Override
  public int getID() {
    return this._service.getRouter().getSimpleID();
  }

  @Override
  public int compareTo(IRequestItems value2) {
    return 0;
  }

  public boolean hasPatternUpgrade() {
    if(_service != null && _service.getUpgradeManager() != null) {
      return _service.getUpgradeManager().hasPatternUpgrade();
    }
    return false;
  }
 
  public class PatternSupplierTargetInformation extends SupplierTargetInformation implements ITargetSlotInformation {
   
    private final int amount;
    private final int targetSlot;
   
    public PatternSupplierTargetInformation(int targetSlot, int amount) {
      super();
      this.targetSlot = targetSlot;
      this.amount = amount;
     
    }

    @Override
    public int getTargetSlot() {
      return targetSlot;
    }

    @Override
    public int getAmount() {
      return amount;
    }

    @Override
    public boolean isLimited() {
      return ModuleActiveSupplier.this.isLimited();
    }
   
  }
 
  public class SupplierTargetInformation extends ChasseTargetInformation {

    public SupplierTargetInformation() {
      super(ModuleActiveSupplier.this.getPositionInt());
    }
   
  }
}
TOP

Related Classes of logisticspipes.modules.ModuleActiveSupplier

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.