2013-06-24 18:24:04 +02:00
|
|
|
package mekanism.common;
|
|
|
|
|
2015-04-02 04:22:53 +02:00
|
|
|
import java.util.ArrayList;
|
2013-08-19 03:32:47 +02:00
|
|
|
import java.util.Collection;
|
2013-06-24 18:24:04 +02:00
|
|
|
import java.util.Collections;
|
2014-08-15 22:21:58 +02:00
|
|
|
import java.util.EnumSet;
|
2013-06-24 18:24:04 +02:00
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2014-06-19 14:34:57 +02:00
|
|
|
import mekanism.api.Coord4D;
|
2015-04-06 19:53:16 +02:00
|
|
|
import mekanism.common.base.EnergyAcceptorWrapper;
|
2015-04-01 03:42:36 +02:00
|
|
|
import mekanism.api.energy.EnergyStack;
|
2013-08-27 00:49:32 +02:00
|
|
|
import mekanism.api.transmitters.DynamicNetwork;
|
2013-12-21 01:12:33 +01:00
|
|
|
import mekanism.api.transmitters.IGridTransmitter;
|
2013-11-03 11:26:43 +01:00
|
|
|
import mekanism.common.util.MekanismUtils;
|
2013-06-24 18:24:04 +02:00
|
|
|
import net.minecraft.tileentity.TileEntity;
|
2013-08-04 02:48:13 +02:00
|
|
|
import net.minecraftforge.common.MinecraftForge;
|
2014-06-02 23:57:40 +02:00
|
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
2014-09-03 20:00:03 +02:00
|
|
|
import cpw.mods.fml.common.FMLCommonHandler;
|
|
|
|
import cpw.mods.fml.common.eventhandler.Event;
|
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public class EnergyNetwork extends DynamicNetwork<EnergyAcceptorWrapper, EnergyNetwork>
|
2013-11-11 20:37:56 +01:00
|
|
|
{
|
|
|
|
private double lastPowerScale = 0;
|
2013-07-05 18:54:22 +02:00
|
|
|
private double joulesTransmitted = 0;
|
2014-01-07 04:17:59 +01:00
|
|
|
private double jouleBufferLastTick = 0;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-11-25 06:00:26 +01:00
|
|
|
public double clientEnergyScale = 0;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public EnergyStack buffer = new EnergyStack(0);
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public EnergyNetwork() {}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public EnergyNetwork(Collection<EnergyNetwork> networks)
|
2013-07-28 04:32:41 +02:00
|
|
|
{
|
2013-07-31 22:44:53 +02:00
|
|
|
for(EnergyNetwork net : networks)
|
2013-07-28 04:32:41 +02:00
|
|
|
{
|
|
|
|
if(net != null)
|
|
|
|
{
|
2014-01-07 04:17:59 +01:00
|
|
|
if(net.jouleBufferLastTick > jouleBufferLastTick || net.clientEnergyScale > clientEnergyScale)
|
2013-11-29 19:04:39 +01:00
|
|
|
{
|
|
|
|
clientEnergyScale = net.clientEnergyScale;
|
2014-01-07 04:17:59 +01:00
|
|
|
jouleBufferLastTick = net.jouleBufferLastTick;
|
2013-11-29 19:04:39 +01:00
|
|
|
joulesTransmitted = net.joulesTransmitted;
|
|
|
|
lastPowerScale = net.lastPowerScale;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
buffer.amount += net.buffer.amount;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
adoptTransmittersAndAcceptorsFrom(net);
|
2013-07-28 04:32:41 +02:00
|
|
|
net.deregister();
|
|
|
|
}
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-04 02:41:16 +02:00
|
|
|
register();
|
2013-07-28 04:32:41 +02:00
|
|
|
}
|
2014-08-07 00:25:33 +02:00
|
|
|
|
|
|
|
public static double round(double d)
|
|
|
|
{
|
|
|
|
return Math.round(d * 10000)/10000;
|
|
|
|
}
|
2013-12-14 21:32:32 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
@Override
|
|
|
|
public void absorbBuffer(IGridTransmitter<EnergyAcceptorWrapper, EnergyNetwork> transmitter)
|
|
|
|
{
|
|
|
|
EnergyStack energy = (EnergyStack)transmitter.getBuffer();
|
|
|
|
buffer.amount += energy.amount;
|
|
|
|
energy.amount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void clampBuffer()
|
|
|
|
{
|
|
|
|
if(buffer.amount > getCapacity())
|
|
|
|
{
|
|
|
|
buffer.amount = getCapacity();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void updateMeanCapacity()
|
2013-12-14 05:42:27 +01:00
|
|
|
{
|
2013-12-14 21:32:32 +01:00
|
|
|
int numCables = transmitters.size();
|
|
|
|
double reciprocalSum = 0;
|
2013-12-16 23:54:27 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
for(IGridTransmitter<EnergyAcceptorWrapper, EnergyNetwork> cable : transmitters)
|
2013-12-14 21:32:32 +01:00
|
|
|
{
|
|
|
|
reciprocalSum += 1.0/(double)cable.getCapacity();
|
|
|
|
}
|
2014-03-24 06:56:31 +01:00
|
|
|
|
|
|
|
meanCapacity = (double)numCables / reciprocalSum;
|
2013-12-14 05:42:27 +01:00
|
|
|
}
|
2013-12-16 23:54:27 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public double getEnergyNeeded()
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2013-11-25 06:00:26 +01:00
|
|
|
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
return getCapacity()-buffer.amount;
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public double tickEmit(double energyToSend)
|
2013-11-17 16:55:20 +01:00
|
|
|
{
|
2013-11-25 06:00:26 +01:00
|
|
|
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
|
|
|
|
{
|
2013-12-21 20:27:35 +01:00
|
|
|
return 0;
|
2013-11-25 06:00:26 +01:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-12-21 20:27:35 +01:00
|
|
|
double sent = 0;
|
|
|
|
boolean tryAgain = false;
|
2014-08-19 17:42:16 +02:00
|
|
|
int i = 0;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-12-21 20:27:35 +01:00
|
|
|
do {
|
2014-08-08 05:48:22 +02:00
|
|
|
double prev = sent;
|
2014-08-09 19:29:04 +02:00
|
|
|
sent += doEmit(energyToSend-sent, tryAgain);
|
2014-08-08 05:48:22 +02:00
|
|
|
|
2014-08-19 17:42:16 +02:00
|
|
|
tryAgain = energyToSend-sent > 0 && sent-prev > 0 && i < 100;
|
|
|
|
|
|
|
|
i++;
|
2013-12-21 20:27:35 +01:00
|
|
|
} while(tryAgain);
|
2014-01-07 04:17:59 +01:00
|
|
|
|
|
|
|
joulesTransmitted = sent;
|
2013-12-21 20:27:35 +01:00
|
|
|
return sent;
|
2013-11-17 16:55:20 +01:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
public double emit(double energyToSend, boolean doEmit)
|
2013-12-14 05:42:27 +01:00
|
|
|
{
|
|
|
|
double toUse = Math.min(getEnergyNeeded(), energyToSend);
|
2014-11-10 22:51:37 +01:00
|
|
|
if(doEmit)
|
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
buffer.amount += toUse;
|
2014-11-10 22:51:37 +01:00
|
|
|
}
|
2013-12-14 05:42:27 +01:00
|
|
|
return energyToSend-toUse;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-11-28 00:17:44 +01:00
|
|
|
/**
|
2013-12-21 20:27:35 +01:00
|
|
|
* @return sent
|
2013-11-28 00:17:44 +01:00
|
|
|
*/
|
2015-04-01 03:42:36 +02:00
|
|
|
public double doEmit(double energyToSend, boolean tryAgain)
|
2014-03-08 02:00:25 +01:00
|
|
|
{
|
2013-12-21 20:27:35 +01:00
|
|
|
double sent = 0;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-02 04:22:53 +02:00
|
|
|
List<EnergyAcceptorWrapper> availableAcceptors = new ArrayList<>();
|
|
|
|
availableAcceptors.addAll(getAcceptors(null));
|
2013-07-05 18:54:22 +02:00
|
|
|
|
2013-06-24 18:24:04 +02:00
|
|
|
Collections.shuffle(availableAcceptors);
|
2013-07-05 18:54:22 +02:00
|
|
|
|
2013-06-24 18:24:04 +02:00
|
|
|
if(!availableAcceptors.isEmpty())
|
|
|
|
{
|
|
|
|
int divider = availableAcceptors.size();
|
|
|
|
double remaining = energyToSend % divider;
|
|
|
|
double sending = (energyToSend-remaining)/divider;
|
2013-07-05 18:54:22 +02:00
|
|
|
|
2015-04-02 04:22:53 +02:00
|
|
|
for(EnergyAcceptorWrapper acceptor : availableAcceptors)
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-02 04:22:53 +02:00
|
|
|
double currentSending = sending+remaining;
|
|
|
|
EnumSet<ForgeDirection> sides = acceptorDirections.get(acceptor.coord);
|
|
|
|
|
|
|
|
if(sides == null || sides.isEmpty())
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-02 04:22:53 +02:00
|
|
|
continue;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-02 04:22:53 +02:00
|
|
|
for(ForgeDirection side : sides)
|
|
|
|
{
|
|
|
|
double prev = sent;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-02 04:22:53 +02:00
|
|
|
sent += acceptor.transferEnergyToAcceptor(side, currentSending);
|
|
|
|
|
|
|
|
if(sent > prev)
|
2013-12-03 12:57:53 +01:00
|
|
|
{
|
2015-04-02 04:22:53 +02:00
|
|
|
break;
|
2013-12-03 12:57:53 +01:00
|
|
|
}
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-12-21 20:27:35 +01:00
|
|
|
return sent;
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-18 22:51:47 +02:00
|
|
|
@Override
|
2015-04-01 03:42:36 +02:00
|
|
|
public Set<EnergyAcceptorWrapper> getAcceptors(Object data)
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
Set<EnergyAcceptorWrapper> toReturn = new HashSet<>();
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-11-25 06:00:26 +01:00
|
|
|
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
|
|
|
|
{
|
|
|
|
return toReturn;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-02-16 20:40:10 +01:00
|
|
|
for(Coord4D coord : possibleAcceptors.keySet())
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2014-08-15 22:21:58 +02:00
|
|
|
EnumSet<ForgeDirection> sides = acceptorDirections.get(coord);
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2014-08-15 22:21:58 +02:00
|
|
|
if(sides == null || sides.isEmpty())
|
2013-12-04 05:36:06 +01:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
TileEntity tile = coord.getTileEntity(getWorld());
|
|
|
|
EnergyAcceptorWrapper acceptor = EnergyAcceptorWrapper.get(tile);
|
|
|
|
|
|
|
|
if(acceptor != null)
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
for(ForgeDirection side : sides)
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-02 04:22:53 +02:00
|
|
|
if(acceptor.canReceiveEnergy(side) && acceptor.getNeeded() > 0)
|
2013-06-24 18:24:04 +02:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
toReturn.add(acceptor);
|
|
|
|
break;
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
|
|
|
}
|
2013-12-03 12:57:53 +01:00
|
|
|
}
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-06-24 18:24:04 +02:00
|
|
|
return toReturn;
|
|
|
|
}
|
|
|
|
|
2013-08-04 02:48:13 +02:00
|
|
|
public static class EnergyTransferEvent extends Event
|
|
|
|
{
|
|
|
|
public final EnergyNetwork energyNetwork;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-04 02:48:13 +02:00
|
|
|
public final double power;
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-04 02:48:13 +02:00
|
|
|
public EnergyTransferEvent(EnergyNetwork network, double currentPower)
|
|
|
|
{
|
|
|
|
energyNetwork = network;
|
|
|
|
power = currentPower;
|
|
|
|
}
|
|
|
|
}
|
2013-07-05 18:54:22 +02:00
|
|
|
|
2013-06-24 18:24:04 +02:00
|
|
|
@Override
|
|
|
|
public String toString()
|
|
|
|
{
|
2013-08-17 19:32:05 +02:00
|
|
|
return "[EnergyNetwork] " + transmitters.size() + " transmitters, " + possibleAcceptors.size() + " acceptors.";
|
2013-06-24 18:24:04 +02:00
|
|
|
}
|
2013-07-05 18:54:22 +02:00
|
|
|
|
2013-08-18 22:51:47 +02:00
|
|
|
@Override
|
2013-12-21 20:54:12 +01:00
|
|
|
public void onUpdate()
|
2014-03-08 02:00:25 +01:00
|
|
|
{
|
2013-12-21 20:54:12 +01:00
|
|
|
super.onUpdate();
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-11-25 06:00:26 +01:00
|
|
|
clearJoulesTransmitted();
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-04 02:48:13 +02:00
|
|
|
double currentPowerScale = getPowerScale();
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-11-03 22:54:33 +01:00
|
|
|
if(FMLCommonHandler.instance().getEffectiveSide().isServer())
|
2013-08-04 02:48:13 +02:00
|
|
|
{
|
2013-12-14 05:42:27 +01:00
|
|
|
if(Math.abs(currentPowerScale-lastPowerScale) > 0.01 || (currentPowerScale != lastPowerScale && (currentPowerScale == 0 || currentPowerScale == 1)))
|
2013-11-03 22:54:33 +01:00
|
|
|
{
|
|
|
|
needsUpdate = true;
|
|
|
|
}
|
2013-08-04 02:48:13 +02:00
|
|
|
|
2013-11-03 22:54:33 +01:00
|
|
|
if(needsUpdate)
|
|
|
|
{
|
|
|
|
MinecraftForge.EVENT_BUS.post(new EnergyTransferEvent(this, currentPowerScale));
|
2013-12-28 03:50:24 +01:00
|
|
|
lastPowerScale = currentPowerScale;
|
2013-11-03 22:54:33 +01:00
|
|
|
needsUpdate = false;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2015-04-01 03:42:36 +02:00
|
|
|
if(buffer.amount > 0)
|
2013-12-14 05:42:27 +01:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
buffer.amount -= tickEmit(buffer.amount);
|
2013-12-14 05:42:27 +01:00
|
|
|
}
|
2013-08-04 02:48:13 +02:00
|
|
|
}
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-04 02:48:13 +02:00
|
|
|
public double getPowerScale()
|
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
return Math.max(jouleBufferLastTick == 0 ? 0 : Math.min(Math.ceil(Math.log10(getPower())*2)/10, 1), getCapacity() == 0 ? 0 : buffer.amount/getCapacity());
|
2013-07-28 04:32:41 +02:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-07-06 03:43:59 +02:00
|
|
|
public void clearJoulesTransmitted()
|
2013-07-05 18:54:22 +02:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
jouleBufferLastTick = buffer.amount;
|
2013-07-05 18:54:22 +02:00
|
|
|
joulesTransmitted = 0;
|
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-07-06 03:43:59 +02:00
|
|
|
public double getPower()
|
2013-07-05 18:54:22 +02:00
|
|
|
{
|
2014-01-07 04:17:59 +01:00
|
|
|
return jouleBufferLastTick * 20;
|
2013-07-05 18:54:22 +02:00
|
|
|
}
|
2014-03-08 02:00:25 +01:00
|
|
|
|
2013-08-23 20:23:08 +02:00
|
|
|
@Override
|
2014-07-09 21:31:57 +02:00
|
|
|
public String getNeededInfo()
|
2013-08-23 20:23:08 +02:00
|
|
|
{
|
2013-12-14 05:42:27 +01:00
|
|
|
return MekanismUtils.getEnergyDisplay(getEnergyNeeded());
|
2013-08-23 20:23:08 +02:00
|
|
|
}
|
|
|
|
|
2014-01-07 04:17:59 +01:00
|
|
|
@Override
|
2014-07-09 21:31:57 +02:00
|
|
|
public String getStoredInfo()
|
2014-01-07 04:17:59 +01:00
|
|
|
{
|
2015-04-01 03:42:36 +02:00
|
|
|
return MekanismUtils.getEnergyDisplay(buffer.amount);
|
2014-01-07 04:17:59 +01:00
|
|
|
}
|
|
|
|
|
2013-08-23 20:23:08 +02:00
|
|
|
@Override
|
2014-07-09 21:31:57 +02:00
|
|
|
public String getFlowInfo()
|
2013-08-23 20:23:08 +02:00
|
|
|
{
|
2014-07-09 21:31:57 +02:00
|
|
|
return MekanismUtils.getEnergyDisplay(joulesTransmitted) + "/t";
|
2013-08-23 20:23:08 +02:00
|
|
|
}
|
2013-07-28 04:32:41 +02:00
|
|
|
}
|