private void sendPower() { for (ForgeDirection s : ForgeDirection.VALID_DIRECTIONS) { TileEntity tile = getTileBuffer(s).getTile(); if (tile instanceof IPowerReceptor) { PowerReceiver receptor = ((IPowerReceptor) tile).getPowerReceiver(s.getOpposite()); if (receptor != null) { receptor.receiveEnergy(PowerHandler.Type.ENGINE, energyStored / 10.0, s.getOpposite()); energyStored = 0; } } else if (tile instanceof IEnergyHandler) { int energyUsed = ((IEnergyHandler) tile).receiveEnergy(s.getOpposite(), energyStored, false); energyStored -= energyUsed; } } }
public boolean produceBuildCraft(ForgeDirection outputDirection) { if (!this.worldObj.isRemote && outputDirection != null && outputDirection != ForgeDirection.UNKNOWN) { float provide = this.getProvide(outputDirection); if (this.getEnergyStored() >= provide && provide > 0) { if (Compatibility.isBuildcraftLoaded()) { TileEntity tileEntity = new Vector3(this) .modifyPositionFromSide(outputDirection) .getTileEntity(this.worldObj); if (tileEntity instanceof IPowerReceptor) { PowerReceiver receiver = ((IPowerReceptor) tileEntity).getPowerReceiver(outputDirection.getOpposite()); if (receiver != null) { if (receiver.powerRequest() > 0) { float bc3Provide = provide * Compatibility.TO_BC_RATIO; float energyUsed = Math.min( receiver.receiveEnergy( Type.MACHINE, bc3Provide, outputDirection.getOpposite()), bc3Provide); this.provideElectricity(energyUsed * Compatibility.TO_BC_RATIO, true); } } return true; } } } } return false; }
@Override public void updateEntity() { if (CoreProxy.proxy.isRenderWorld(container.worldObj)) return; step(); init(); // Send the power to nearby pipes who requested it System.arraycopy(displayPower, 0, prevDisplayPower, 0, 6); Arrays.fill(displayPower, 0.0F); for (int i = 0; i < 6; ++i) { if (internalPower[i] > 0) { float totalPowerQuery = 0; for (int j = 0; j < 6; ++j) { if (j != i && powerQuery[j] > 0) if (tiles[j] instanceof TileGenericPipe || tiles[j] instanceof IPowerReceptor) { totalPowerQuery += powerQuery[j]; } } for (int j = 0; j < 6; ++j) { if (j != i && powerQuery[j] > 0) { float watts = 0.0F; PowerReceiver prov = getReceiverOnSide(ForgeDirection.VALID_DIRECTIONS[j]); if (prov != null && prov.powerRequest() > 0) { watts = (internalPower[i] / totalPowerQuery) * powerQuery[j]; watts = prov.receiveEnergy( Type.PIPE, watts, ForgeDirection.VALID_DIRECTIONS[j].getOpposite()); internalPower[i] -= watts; } else if (tiles[j] instanceof TileGenericPipe) { watts = (internalPower[i] / totalPowerQuery) * powerQuery[j]; TileGenericPipe nearbyTile = (TileGenericPipe) tiles[j]; PipeTransportPower nearbyTransport = (PipeTransportPower) nearbyTile.pipe.transport; watts = nearbyTransport.receiveEnergy( ForgeDirection.VALID_DIRECTIONS[j].getOpposite(), watts); internalPower[i] -= watts; } displayPower[j] += watts; displayPower[i] += watts; } } } } double highestPower = 0; for (int i = 0; i < 6; i++) { displayPower[i] = (prevDisplayPower[i] * (DISPLAY_SMOOTHING - 1.0F) + displayPower[i]) / DISPLAY_SMOOTHING; if (displayPower[i] > highestPower) { highestPower = displayPower[i]; } } overload += highestPower > maxPower * 0.95 ? 1 : -1; if (overload < 0) { overload = 0; } if (overload > OVERLOAD_TICKS) { overload = OVERLOAD_TICKS; } // Compute the tiles requesting energy that are not power pipes for (int i = 0; i < 6; ++i) { PowerReceiver prov = getReceiverOnSide(ForgeDirection.VALID_DIRECTIONS[i]); if (prov != null) { float request = prov.powerRequest(); if (request > 0) { requestEnergy(ForgeDirection.VALID_DIRECTIONS[i], request); } } } // Sum the amount of energy requested on each side int[] transferQuery = new int[6]; for (int i = 0; i < 6; ++i) { transferQuery[i] = 0; for (int j = 0; j < 6; ++j) { if (j != i) { transferQuery[i] += powerQuery[j]; } } transferQuery[i] = Math.min(transferQuery[i], maxPower); } // Transfer the requested energy to nearby pipes for (int i = 0; i < 6; ++i) { if (transferQuery[i] != 0) { if (tiles[i] != null) { TileEntity entity = tiles[i]; if (entity instanceof TileGenericPipe) { TileGenericPipe nearbyTile = (TileGenericPipe) entity; if (nearbyTile.pipe == null) { continue; } PipeTransportPower nearbyTransport = (PipeTransportPower) nearbyTile.pipe.transport; nearbyTransport.requestEnergy( ForgeDirection.VALID_DIRECTIONS[i].getOpposite(), transferQuery[i]); } } } } if (tracker.markTimeIfDelay(container.worldObj, 2 * BuildCraftCore.updateFactor)) { PacketPowerUpdate packet = new PacketPowerUpdate(container.xCoord, container.yCoord, container.zCoord); double displayFactor = MAX_DISPLAY / 1024.0; for (int i = 0; i < clientDisplayPower.length; i++) { clientDisplayPower[i] = (short) (displayPower[i] * displayFactor + .9999); } packet.displayPower = clientDisplayPower; packet.overload = isOverloaded(); CoreProxy.proxy.sendToPlayers( packet.getPacket(), container.worldObj, container.xCoord, container.yCoord, container.zCoord, DefaultProps.PIPE_CONTENTS_RENDER_DIST); } }
/** * 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; }