use of cofh.api.energy.IEnergyReceiver in project Galacticraft by micdoodle8.
the class EnergyNetwork method doProduce.
/**
* 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);
Object debugTE = null;
try {
for (Object 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;
}
EnumFacing sideFrom = this.availableconnectedDirections.get(tileEntity);
if (tileEntity instanceof IElectrical) {
sentToAcceptor = ((IElectrical) tileEntity).receiveElectricity(sideFrom, currentSending, tierProduced, true);
} else if (isMekLoaded && tileEntity instanceof IStrictEnergyAcceptor) {
sentToAcceptor = (float) ((IStrictEnergyAcceptor) tileEntity).transferEnergyToAcceptor(sideFrom, currentSending * EnergyConfigHandler.TO_MEKANISM_RATIO) / EnergyConfigHandler.TO_MEKANISM_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.getOpposite(), energySendingIC2, 120D);
} else {
result = (Double) EnergyUtil.injectEnergyIC2.invoke(tileEntity, sideFrom.getOpposite(), 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 (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 {
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 instanceof TileEntity) {
GCLog.severe("Problem was likely caused by tile in dim " + GCCoreUtil.getDimensionID(((TileEntity) debugTE).getWorld()) + " at " + ((TileEntity) debugTE).getPos() + " 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;
}
use of cofh.api.energy.IEnergyReceiver in project Galacticraft by micdoodle8.
the class EnergyUtil method setAdjacentPowerConnections.
/**
* Similar to getAdjacentPowerConnections but specific to energy receivers only
* Adds the adjacent power connections found to the passed acceptors, directions parameter Lists
* (Note: an acceptor can therefore sometimes be entered in the Lists more than once, with a different direction each time:
* this would represent GC wires connected to the acceptor on more than one side.)
*
* @param conductor
* @param connectedAcceptors
* @param directions
* @throws Exception
*/
public static void setAdjacentPowerConnections(TileEntity conductor, List<Object> connectedAcceptors, List<EnumFacing> directions) throws Exception {
final BlockVec3 thisVec = new BlockVec3(conductor);
final World world = conductor.getWorld();
for (EnumFacing direction : EnumFacing.VALUES) {
TileEntity tileEntity = thisVec.getTileEntityOnSide(world, direction);
if (// world.getTileEntity will not have returned an invalid tile, invalid tiles are null
tileEntity == null || tileEntity instanceof IConductor) {
continue;
}
EnumFacing sideFrom = direction.getOpposite();
if (tileEntity instanceof IElectrical) {
if (((IElectrical) tileEntity).canConnect(sideFrom, NetworkType.POWER)) {
connectedAcceptors.add(tileEntity);
directions.add(sideFrom);
}
continue;
}
if (isMekLoaded && tileEntity instanceof IStrictEnergyAcceptor) {
if (clazzMekCable != null && clazzMekCable.isInstance(tileEntity)) {
continue;
}
if (((IStrictEnergyAcceptor) tileEntity).canReceiveEnergy(sideFrom)) {
connectedAcceptors.add(tileEntity);
directions.add(sideFrom);
}
continue;
}
if (isBCReallyLoaded && clazzPipeTile.isInstance(tileEntity)) {
continue;
}
if (isIC2Loaded && !world.isRemote) {
IEnergyTile IC2tile = null;
BlockPos checkingIC2 = thisVec.toBlockPos().offset(direction);
try {
IC2tile = EnergyNet.instance.getSubTile(world, checkingIC2);
} catch (Exception e) {
e.printStackTrace();
}
if (IC2tile instanceof IEnergyConductor) {
continue;
}
if (IC2tile instanceof IEnergyAcceptor && ((IEnergyAcceptor) IC2tile).acceptsEnergyFrom((IEnergyEmitter) conductor, sideFrom)) {
connectedAcceptors.add(IC2tile);
directions.add(sideFrom);
}
continue;
}
if ((isRF2Loaded && tileEntity instanceof IEnergyReceiver) || (isRF1Loaded && tileEntity instanceof IEnergyHandler)) {
if (clazzEnderIOCable != null && clazzEnderIOCable.isInstance(tileEntity)) {
continue;
}
if (clazzMFRRednetEnergyCable != null && clazzMFRRednetEnergyCable.isInstance(tileEntity)) {
continue;
}
if (((IEnergyConnection) tileEntity).canConnectEnergy(sideFrom)) {
connectedAcceptors.add(tileEntity);
directions.add(sideFrom);
}
continue;
}
}
return;
}
use of cofh.api.energy.IEnergyReceiver in project BuildCraft by BuildCraft.
the class PipeTransportPower method updateEntity.
@Override
public void updateEntity() {
if (container.getWorld().isRemote) {
for (int i = 0; i < 6; i++) {
displayPowerAverage[i].tick(displayPower[i]);
}
return;
}
if (PipeTransportPower.canExplode) {
if (overload >= 3) {
destroyPipe();
return;
}
}
step();
init();
for (EnumFacing side : EnumFacing.VALUES) {
if (tiles[side.ordinal()] != null && tiles[side.ordinal()].isInvalid()) {
updateTile(side);
}
}
// FIXME: LEFT OVER FROM MERGE! LOOK AT THIS!
Arrays.fill(displayFlow, (short) 0);
// Send the power to nearby pipes who requested it
for (int i = 0; i < 6; ++i) {
if (internalPower[i] > 0) {
int totalPowerQuery = 0;
for (int j = 0; j < 6; ++j) {
if (j != i && powerQuery[j] > 0) {
Object ep = providers[j];
if (ep instanceof IPipeTile || ep instanceof IEnergyReceiver || ep instanceof IEnergyHandler) {
totalPowerQuery += powerQuery[j];
}
}
}
if (totalPowerQuery > 0) {
int unusedPowerQuery = totalPowerQuery;
for (int j = 0; j < 6; ++j) {
if (j != i && powerQuery[j] > 0) {
Object ep = providers[j];
double watts = Math.min(internalPower[i] * powerQuery[j] / unusedPowerQuery, internalPower[i]);
unusedPowerQuery -= powerQuery[j];
if (ep instanceof IPipeTile && ((IPipeTile) ep).getPipeType() == IPipeTile.PipeType.POWER) {
Pipe<?> nearbyPipe = (Pipe<?>) ((IPipeTile) ep).getPipe();
PipeTransportPower nearbyTransport = (PipeTransportPower) nearbyPipe.transport;
watts = nearbyTransport.receiveEnergy(EnumFacing.VALUES[j].getOpposite(), watts);
internalPower[i] -= watts;
dbgEnergyOutput[j] += watts;
powerAverage[j].push((int) Math.ceil(watts));
powerAverage[i].push((int) Math.ceil(watts));
displayFlow[i] = 1;
displayFlow[j] = -1;
} else {
int iWatts = (int) watts;
if (ep instanceof IEnergyReceiver) {
IEnergyReceiver handler = (IEnergyReceiver) ep;
if (handler.canConnectEnergy(EnumFacing.values()[j].getOpposite())) {
iWatts = handler.receiveEnergy(EnumFacing.values()[j].getOpposite(), iWatts, false);
}
}
internalPower[i] -= iWatts;
dbgEnergyOutput[j] += iWatts;
powerAverage[j].push(iWatts);
powerAverage[i].push(iWatts);
displayFlow[i] = 1;
displayFlow[j] = -1;
}
}
}
}
}
}
short highestPower = 0;
for (int i = 0; i < 6; i++) {
powerAverage[i].tick();
displayPower[i] = (short) Math.round(powerAverage[i].getAverage());
if (displayPower[i] > highestPower) {
highestPower = displayPower[i];
}
}
if (PipeTransportPower.canExplode) {
if (energyInputTick > powerLimit || overload > 0) {
overload++;
} else {
overload = 0;
}
} else {
overload += highestPower > (maxPower * 0.95F) ? 1 : -1;
if (overload < 0) {
overload = 0;
}
if (overload > OVERLOAD_TICKS) {
overload = OVERLOAD_TICKS;
}
}
energyInputTick = 0;
// Compute the tiles requesting energy that are not power pipes
for (EnumFacing dir : EnumFacing.VALUES) {
if (!outputOpen(dir)) {
continue;
}
Object tile = providers[dir.ordinal()];
if (tile instanceof IPipeTile && ((IPipeTile) tile).getPipe() != null && ((Pipe<?>) ((IPipeTile) tile).getPipe()).transport instanceof PipeTransportPower) {
continue;
}
if (tile instanceof IEnergyReceiver) {
IEnergyReceiver handler = (IEnergyReceiver) tile;
if (handler.canConnectEnergy(dir.getOpposite())) {
int request = handler.receiveEnergy(dir.getOpposite(), this.maxPower, true);
if (request > 0) {
requestEnergy(dir, request);
}
}
} else if (tile instanceof IEnergyReceiver) {
IEnergyReceiver handler = (IEnergyReceiver) tile;
if (handler.canConnectEnergy(dir.getOpposite())) {
int request = handler.receiveEnergy(dir.getOpposite(), this.maxPower, true);
if (request > 0) {
requestEnergy(dir, 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;
if (!inputOpen(EnumFacing.getFront(i))) {
continue;
}
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 && tiles[i] != null) {
TileEntity entity = tiles[i];
if (entity instanceof IPipeTile && ((IPipeTile) entity).getPipeType() == IPipeTile.PipeType.POWER) {
IPipeTile nearbyTile = (IPipeTile) entity;
if (nearbyTile.getPipe() == null || nearbyTile.getPipeType() != IPipeTile.PipeType.POWER) {
continue;
}
PipeTransportPower nearbyTransport = (PipeTransportPower) ((Pipe<?>) nearbyTile.getPipe()).transport;
nearbyTransport.requestEnergy(EnumFacing.VALUES[i].getOpposite(), transferQuery[i]);
}
}
}
if (tracker.markTimeIfDelay(container.getWorld())) {
PacketPowerUpdate packet = new PacketPowerUpdate(container);
packet.displayPower = new short[6];
for (int i = 0; i < 6; i++) {
double val = displayPower[i];
val /= MAX_POWER;
val = Math.sqrt(val);
val *= POWER_STAGES;
packet.displayPower[i] = (short) val;
}
packet.displayFlow = displayFlow;
packet.overload = isOverloaded();
BuildCraftTransport.instance.sendToPlayersNear(packet, container);
}
}
use of cofh.api.energy.IEnergyReceiver in project BuildCraft by BuildCraft.
the class TileEngineBase method sendPower.
protected void sendPower() {
Object tile = getEnergyProvider(orientation);
if (isPoweredTile(tile, orientation)) {
int extracted = getPowerToExtract();
if (extracted <= 0) {
setPumping(false);
return;
}
setPumping(true);
if (tile instanceof IEngine) {
IEngine engine = (IEngine) tile;
int neededRF = engine.receiveEnergyFromEngine(orientation.getOpposite(), extracted, false);
extractEnergy(neededRF, true);
} else if (tile instanceof IEnergyReceiver) {
IEnergyReceiver handler = (IEnergyReceiver) tile;
int neededRF = handler.receiveEnergy(orientation.getOpposite(), extracted, false);
extractEnergy(neededRF, true);
}
}
}
use of cofh.api.energy.IEnergyReceiver in project Railcraft by Railcraft.
the class RedstoneFluxPlugin method pushToTiles.
public static int pushToTiles(IEnergyProvider provider, AdjacentTileCache tileCache, int pushPerSide) {
int pushed = 0;
for (EnumFacing side : EnumFacing.VALUES) {
TileEntity tile = tileCache.getTileOnSide(side);
if (canTileReceivePower(tile, side.getOpposite())) {
IEnergyReceiver handler = (IEnergyReceiver) tile;
int amountToPush = provider.extractEnergy(side, pushPerSide, true);
if (amountToPush > 0) {
int amountPushed = handler.receiveEnergy(side.getOpposite(), amountToPush, false);
pushed += amountPushed;
provider.extractEnergy(side, amountPushed, false);
}
}
}
return pushed;
}
Aggregations