Example #1
0
  private static double emit_do_do(
      TileEntityElectricBlock from,
      TileEntity tileEntity,
      ForgeDirection side,
      double currentSending,
      boolean tryAgain) {
    double sent = 0;

    if (tileEntity instanceof IStrictEnergyAcceptor) {
      IStrictEnergyAcceptor acceptor = (IStrictEnergyAcceptor) tileEntity;

      if (acceptor.canReceiveEnergy(side.getOpposite())) {
        sent += acceptor.transferEnergyToAcceptor(side.getOpposite(), currentSending);
      }
    } else if (MekanismUtils.useRF() && tileEntity instanceof IEnergyHandler) {
      IEnergyHandler handler = (IEnergyHandler) tileEntity;

      if (handler.canConnectEnergy(side.getOpposite())) {
        int used =
            handler.receiveEnergy(
                side.getOpposite(), (int) Math.round(currentSending * Mekanism.TO_TE), false);
        sent += used * Mekanism.FROM_TE;
      }
    } else if (MekanismUtils.useIC2() && tileEntity instanceof IEnergySink) {
      if (((IEnergySink) tileEntity).acceptsEnergyFrom(from, side.getOpposite())) {
        double toSend =
            Math.min(
                currentSending,
                EnergyNet.instance.getPowerFromTier(((IEnergySink) tileEntity).getSinkTier())
                    * Mekanism.FROM_IC2);
        toSend =
            Math.min(toSend, ((IEnergySink) tileEntity).getDemandedEnergy() * Mekanism.FROM_IC2);
        sent +=
            (toSend
                - (((IEnergySink) tileEntity)
                        .injectEnergy(side.getOpposite(), toSend * Mekanism.TO_IC2, 0)
                    * Mekanism.FROM_IC2));
      }
    } else if (MekanismUtils.useBuildCraft()
        && MjAPI.getMjBattery(tileEntity, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite()) != null
        && !tryAgain) {
      IBatteryObject battery =
          MjAPI.getMjBattery(tileEntity, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite());
      double toSend =
          battery.addEnergy(
              Math.min(battery.getEnergyRequested(), currentSending * Mekanism.TO_BC));
      sent += toSend * Mekanism.FROM_BC;
    }

    return sent;
  }
Example #2
0
  public static boolean isConnectable(TileEntity orig, TileEntity tileEntity, ForgeDirection side) {
    if (tileEntity instanceof IGridTransmitter) {
      return false;
    }

    if (tileEntity instanceof IStrictEnergyAcceptor) {
      if (((IStrictEnergyAcceptor) tileEntity).canReceiveEnergy(side.getOpposite())) {
        return true;
      }
    } else if (MekanismUtils.useIC2() && tileEntity instanceof IEnergyAcceptor) {
      if (((IEnergyAcceptor) tileEntity).acceptsEnergyFrom(orig, side.getOpposite())) {
        return true;
      }
    } else if (tileEntity instanceof ICableOutputter) {
      if (((ICableOutputter) tileEntity).canOutputTo(side.getOpposite())) {
        return true;
      }
    } else if (MekanismUtils.useRF() && tileEntity instanceof IEnergyHandler) {
      if (((IEnergyHandler) tileEntity).canConnectEnergy(side.getOpposite())) {
        return true;
      }
    } else if (MekanismUtils.useBuildCraft()) {
      if (MjAPI.getMjBattery(tileEntity, MjAPI.DEFAULT_POWER_FRAMEWORK, side.getOpposite())
          != null) {
        return true;
      }
    }

    return false;
  }
Example #3
0
 public static boolean isEnergyAcceptor(TileEntity tileEntity) {
   return (tileEntity instanceof IStrictEnergyAcceptor
       || (MekanismUtils.useIC2() && tileEntity instanceof IEnergySink)
       || (MekanismUtils.useBuildCraft()
           && MjAPI.getMjBattery(tileEntity) != null
           && !(tileEntity instanceof IGridTransmitter))
       || (MekanismUtils.useRF() && tileEntity instanceof IEnergyHandler));
 }
  /** Refresh all energy acceptors in the network */
  private void refreshAcceptors() {
    this.connectedAcceptors.clear();
    this.connectedDirections.clear();

    this.refreshWithChecks();

    try {
      LinkedList<IConductor> conductorsCopy = new LinkedList();
      conductorsCopy.addAll(this.conductors);
      // This prevents concurrent modifications if something in the loop causes chunk loading
      // (Chunk loading can change the network if new conductors are found)
      for (IConductor conductor : conductorsCopy) {
        final TileEntity[] adjacentConnections =
            EnergyUtil.getAdjacentPowerConnections((TileEntity) conductor);
        for (int i = 0; i < 6; i++) {
          TileEntity acceptor = adjacentConnections[i];

          if (!(acceptor instanceof IConductor) && acceptor != null && !acceptor.isInvalid()) {
            // The direction 'sideFrom' is from the perspective of the acceptor, that's more useful
            // than the conductor's perspective
            ForgeDirection sideFrom = ForgeDirection.getOrientation(i ^ 1);

            if (acceptor instanceof IElectrical) {
              if (((IElectrical) acceptor).canConnect(sideFrom, NetworkType.POWER)) {
                this.connectedAcceptors.add(acceptor);
                this.connectedDirections.add(sideFrom);
              }
            } else if ((isRF2Loaded && acceptor instanceof IEnergyReceiver)
                || (isRF1Loaded && acceptor instanceof IEnergyHandler)) {
              if (((IEnergyConnection) acceptor).canConnectEnergy(sideFrom)) {
                this.connectedAcceptors.add(acceptor);
                this.connectedDirections.add(sideFrom);
              }
            } else if (isMekLoaded && acceptor instanceof IStrictEnergyAcceptor) {
              if (((IStrictEnergyAcceptor) acceptor).canReceiveEnergy(sideFrom)) {
                this.connectedAcceptors.add(acceptor);
                this.connectedDirections.add(sideFrom);
              }
            } else if (isIC2Loaded && acceptor instanceof IEnergyAcceptor) {
              if (((IEnergyAcceptor) acceptor)
                  .acceptsEnergyFrom((TileEntity) conductor, sideFrom)) {
                this.connectedAcceptors.add(acceptor);
                this.connectedDirections.add(sideFrom);
              }
            } else if (isBCLoaded
                && EnergyConfigHandler.getBuildcraftVersion() == 6
                && MjAPI.getMjBattery(acceptor, MjAPI.DEFAULT_POWER_FRAMEWORK, sideFrom) != null) {
              this.connectedAcceptors.add(acceptor);
              this.connectedDirections.add(sideFrom);
            } else if (isBCLoaded && acceptor instanceof IPowerReceptor) {
              if (((IPowerReceptor) acceptor).getPowerReceiver(sideFrom) != null
                  && (!(acceptor instanceof IPowerEmitter)
                      || !((IPowerEmitter) acceptor).canEmitPowerFrom(sideFrom))) {
                this.connectedAcceptors.add(acceptor);
                this.connectedDirections.add(sideFrom);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      FMLLog.severe("Energy Network: Error when trying to refresh list of power acceptors.");
      e.printStackTrace();
    }
  }
  /**
   * Complete the energy transfer. Called internally on server tick end.
   *
   * @return Amount of energy SENT to all acceptors
   */
  private float doProduce() {
    float sent = 0.0F;

    if (!this.availableAcceptors.isEmpty()) {
      float energyNeeded = this.totalRequested;
      float energyAvailable = this.totalEnergy;
      float reducor = 1.0F;
      float energyStorageReducor = 1.0F;

      if (energyNeeded > energyAvailable) {
        // If not enough energy, try reducing what goes into energy storage (if any)
        energyNeeded -= this.totalStorageExcess;
        // If there's still not enough, put the minimum into energy storage (if any) and, anyhow,
        // reduce everything proportionately
        if (energyNeeded > energyAvailable) {
          energyStorageReducor = 0F;
          reducor = energyAvailable / energyNeeded;
        } else {
          // Energyavailable exceeds the total needed but only if storage does not fill all in one
          // go - this is a common situation
          energyStorageReducor = (energyAvailable - energyNeeded) / this.totalStorageExcess;
        }
      }

      float currentSending;
      float sentToAcceptor;
      int tierProduced = Math.min(this.producersTierGC, this.networkTierGC);

      TileEntity debugTE = null;
      try {
        for (TileEntity tileEntity : this.availableAcceptors) {
          debugTE = tileEntity;
          // Exit the loop if there is no energy left at all (should normally not happen, should be
          // some even for the last acceptor)
          if (sent >= energyAvailable) {
            break;
          }

          // The base case is to give each acceptor what it is requesting
          currentSending = this.energyRequests.get(tileEntity);

          // If it's an energy store, we may need to damp it down if energyStorageReducor is less
          // than 1
          if (currentSending > EnergyNetwork.ENERGY_STORAGE_LEVEL) {
            currentSending =
                EnergyNetwork.ENERGY_STORAGE_LEVEL
                    + (currentSending - EnergyNetwork.ENERGY_STORAGE_LEVEL) * energyStorageReducor;
          }

          // Reduce everything proportionately if there is not enough energy for all needs
          currentSending *= reducor;

          if (currentSending > energyAvailable - sent) {
            currentSending = energyAvailable - sent;
          }

          ForgeDirection sideFrom = this.availableconnectedDirections.get(tileEntity);

          if (tileEntity instanceof IElectrical) {
            sentToAcceptor =
                ((IElectrical) tileEntity)
                    .receiveElectricity(sideFrom, currentSending, tierProduced, true);
          } else if (isRF2Loaded && tileEntity instanceof IEnergyReceiver) {
            final int currentSendinginRF =
                (currentSending >= Integer.MAX_VALUE / EnergyConfigHandler.TO_RF_RATIO)
                    ? Integer.MAX_VALUE
                    : (int) (currentSending * EnergyConfigHandler.TO_RF_RATIO);
            sentToAcceptor =
                ((IEnergyReceiver) tileEntity).receiveEnergy(sideFrom, currentSendinginRF, false)
                    / EnergyConfigHandler.TO_RF_RATIO;
          } else if (isMekLoaded && tileEntity instanceof IStrictEnergyAcceptor) {
            sentToAcceptor =
                (float)
                        ((IStrictEnergyAcceptor) tileEntity)
                            .transferEnergyToAcceptor(
                                sideFrom, currentSending * EnergyConfigHandler.TO_MEKANISM_RATIO)
                    / EnergyConfigHandler.TO_MEKANISM_RATIO;
          } else if (isRF1Loaded && tileEntity instanceof IEnergyHandler) {
            final int currentSendinginRF =
                (currentSending >= Integer.MAX_VALUE / EnergyConfigHandler.TO_RF_RATIO)
                    ? Integer.MAX_VALUE
                    : (int) (currentSending * EnergyConfigHandler.TO_RF_RATIO);
            sentToAcceptor =
                ((IEnergyHandler) tileEntity).receiveEnergy(sideFrom, currentSendinginRF, false)
                    / EnergyConfigHandler.TO_RF_RATIO;
          } else if (isIC2Loaded && tileEntity instanceof IEnergySink) {
            double energySendingIC2 = currentSending * EnergyConfigHandler.TO_IC2_RATIO;
            if (energySendingIC2 >= 1D) {
              double result = 0;
              try {
                if (EnergyUtil.voltageParameterIC2) {
                  result =
                      (Double)
                          EnergyUtil.injectEnergyIC2.invoke(
                              tileEntity, sideFrom, energySendingIC2, 120D);
                } else {
                  result =
                      (Double)
                          EnergyUtil.injectEnergyIC2.invoke(tileEntity, sideFrom, energySendingIC2);
                }
              } catch (Exception ex) {
                if (ConfigManagerCore.enableDebug) {
                  ex.printStackTrace();
                }
              }
              sentToAcceptor = currentSending - (float) result / EnergyConfigHandler.TO_IC2_RATIO;
              if (sentToAcceptor < 0F) {
                sentToAcceptor = 0F;
              }
            } else {
              sentToAcceptor = 0F;
            }
          } else if (isBCLoaded
              && EnergyConfigHandler.getBuildcraftVersion() == 6
              && MjAPI.getMjBattery(tileEntity, MjAPI.DEFAULT_POWER_FRAMEWORK, sideFrom) != null)
          // New BC API
          {
            sentToAcceptor =
                (float)
                        MjAPI.getMjBattery(tileEntity, MjAPI.DEFAULT_POWER_FRAMEWORK, sideFrom)
                            .addEnergy(currentSending * EnergyConfigHandler.TO_BC_RATIO)
                    / EnergyConfigHandler.TO_BC_RATIO;
          } else if (isBCLoaded && tileEntity instanceof IPowerReceptor)
          // Legacy BC API
          {
            PowerReceiver receiver = ((IPowerReceptor) tileEntity).getPowerReceiver(sideFrom);

            if (receiver != null) {
              double toSendBC =
                  Math.min(
                      currentSending * EnergyConfigHandler.TO_BC_RATIO, receiver.powerRequest());
              sentToAcceptor =
                  (float)
                          receiver.receiveEnergy(
                              buildcraft.api.power.PowerHandler.Type.PIPE, toSendBC, sideFrom)
                      / EnergyConfigHandler.TO_BC_RATIO;
            } else {
              sentToAcceptor = 0F;
            }
          } else {
            sentToAcceptor = 0F;
          }

          if (sentToAcceptor / currentSending > 1.002F && sentToAcceptor > 0.01F) {
            if (!this.spamstop) {
              FMLLog.info(
                  "Energy network: acceptor took too much energy, offered "
                      + currentSending
                      + ", took "
                      + sentToAcceptor
                      + ". "
                      + tileEntity.toString());
              this.spamstop = true;
            }
            sentToAcceptor = currentSending;
          }

          sent += sentToAcceptor;
        }
      } catch (Exception e) {
        GCLog.severe("DEBUG Energy network loop issue, please report this");
        if (debugTE != null)
          GCLog.severe(
              "Problem was likely caused by tile in dim "
                  + debugTE.getWorldObj().provider.dimensionId
                  + " at "
                  + debugTE.xCoord
                  + ","
                  + debugTE.yCoord
                  + ","
                  + debugTE.zCoord
                  + " Type:"
                  + debugTE.getClass().getSimpleName());
      }
    }

    if (EnergyNetwork.tickCount % 200 == 0) {
      this.spamstop = false;
    }

    float returnvalue = sent;
    if (returnvalue > this.totalEnergy) {
      returnvalue = this.totalEnergy;
    }
    if (returnvalue < 0F) {
      returnvalue = 0F;
    }
    return returnvalue;
  }
  /**
   * Refreshes all tiles in network, and updates requested energy
   *
   * @param ignoreTiles TileEntities to ignore for energy calculations.
   */
  private void doTickStartCalc() {
    this.tickDone = EnergyNetwork.tickCount;
    this.totalSent = 0F;
    this.refreshAcceptors();

    if (!EnergyUtil.initialisedIC2Methods) {
      EnergyUtil.initialiseIC2Methods();
    }

    if (this.conductors.size() == 0) {
      return;
    }

    this.loopPrevention = true;

    this.availableAcceptors.clear();
    this.availableconnectedDirections.clear();
    this.energyRequests.clear();
    this.totalRequested = 0.0F;
    this.totalStorageExcess = 0F;

    if (!this.connectedAcceptors.isEmpty()) {
      float e;
      final Iterator<ForgeDirection> acceptorDirection = this.connectedDirections.iterator();
      for (TileEntity acceptor : this.connectedAcceptors) {
        // This tries all sides of the acceptor which are connected (see refreshAcceptors())
        ForgeDirection sideFrom = acceptorDirection.next();

        // But the grid will only put energy into the acceptor from one side - once it's in
        // availableAcceptors
        if (!this.ignoreAcceptors.contains(acceptor)
            && !this.availableAcceptors.contains(acceptor)) {
          e = 0.0F;

          if (acceptor instanceof IElectrical) {
            e = ((IElectrical) acceptor).getRequest(sideFrom);
          } else if (isRF2Loaded && acceptor instanceof IEnergyReceiver) {
            e =
                ((IEnergyReceiver) acceptor).receiveEnergy(sideFrom, Integer.MAX_VALUE, true)
                    / EnergyConfigHandler.TO_RF_RATIO;
          } else if (isMekLoaded && acceptor instanceof IStrictEnergyAcceptor) {
            e =
                (float)
                    ((((IStrictEnergyAcceptor) acceptor).getMaxEnergy()
                            - ((IStrictEnergyAcceptor) acceptor).getEnergy())
                        / EnergyConfigHandler.TO_MEKANISM_RATIO);
          } else if (isRF1Loaded && acceptor instanceof IEnergyHandler) {
            e =
                ((IEnergyHandler) acceptor).receiveEnergy(sideFrom, Integer.MAX_VALUE, true)
                    / EnergyConfigHandler.TO_RF_RATIO;
          } else if (isIC2Loaded && acceptor instanceof IEnergySink) {
            double result = 0;
            try {
              result = (Double) EnergyUtil.demandedEnergyIC2.invoke(acceptor);
            } catch (Exception ex) {
              if (ConfigManagerCore.enableDebug) {
                ex.printStackTrace();
              }
            }
            // Cap IC2 power transfer at 128EU/t for standard Alu wire, 256EU/t for heavy Alu wire
            result = Math.max(result, (this.networkTierGC == 2) ? 256D : 128D);
            e = (float) result / EnergyConfigHandler.TO_IC2_RATIO;
          } else if (isBCLoaded
              && EnergyConfigHandler.getBuildcraftVersion() == 6
              && MjAPI.getMjBattery(acceptor, MjAPI.DEFAULT_POWER_FRAMEWORK, sideFrom) != null)
          // New BC API
          {
            e =
                (float)
                        MjAPI.getMjBattery(acceptor, MjAPI.DEFAULT_POWER_FRAMEWORK, sideFrom)
                            .getEnergyRequested()
                    / EnergyConfigHandler.TO_BC_RATIO;
          } else if (isBCLoaded && acceptor instanceof IPowerReceptor)
          // Legacy BC API
          {
            PowerReceiver BCreceiver = ((IPowerReceptor) acceptor).getPowerReceiver(sideFrom);
            if (BCreceiver != null) {
              e = (float) BCreceiver.powerRequest() / EnergyConfigHandler.TO_BC_RATIO;
            }
          }

          if (e > 0.0F) {
            this.availableAcceptors.add(acceptor);
            this.availableconnectedDirections.put(acceptor, sideFrom);
            this.energyRequests.put(acceptor, Float.valueOf(e));
            this.totalRequested += e;
            if (e > EnergyNetwork.ENERGY_STORAGE_LEVEL) {
              this.totalStorageExcess += e - EnergyNetwork.ENERGY_STORAGE_LEVEL;
            }
          }
        }
      }
    }

    this.loopPrevention = false;
  }