Starting to create my own fluid network

will be similar to Calclavia's UE network for power except it uses
LiquidStack instead of watts.
This commit is contained in:
Rseifert 2013-02-08 02:04:18 -05:00
parent 17698f7fda
commit 9d312ea04d
6 changed files with 718 additions and 5 deletions

View file

@ -64,7 +64,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
public class LiquidMechanics extends DummyModContainer
{
// TODO Change in Version Release
public static final String VERSION = "0.2.6";
public static final String VERSION = "0.2.7";
// Constants
public static final String NAME = "LiquidMechanics";
@ -111,7 +111,7 @@ public class LiquidMechanics extends DummyModContainer
public void preInit(FMLPreInitializationEvent event)
{
FMLog.setParent(FMLLog.getLogger());
FMLog.info(this.NAME+": Initializing...");
FMLog.info("Initializing...");
MinecraftForge.EVENT_BUS.register(new LiquidHandler());
instance = this;
@ -154,7 +154,7 @@ public class LiquidMechanics extends DummyModContainer
@Init
public void Init(FMLInitializationEvent event)
{
FMLog.info(this.NAME+": Loading...");
FMLog.info("Loading...");
proxy.Init();
// TileEntities
GameRegistry.registerTileEntity(TileEntityPipe.class, "lmPipeTile");
@ -172,7 +172,7 @@ public class LiquidMechanics extends DummyModContainer
@PostInit
public void PostInit(FMLPostInitializationEvent event)
{
FMLog.info(this.NAME+": Finalizing...");
FMLog.info("Finalizing...");
proxy.postInit();
TabLiquidMechanics.setItemStack(new ItemStack(blockPipe, 1, 4));
// generator
@ -322,6 +322,6 @@ public class LiquidMechanics extends DummyModContainer
// there liquid data first if used
LiquidStack waste = LiquidDictionary.getOrCreateLiquid("Waste", new LiquidStack(LiquidMechanics.blockWasteLiquid, 1));
LiquidHandler.addDefaultLiquids();
FMLog.info(this.NAME+": Done Loading");
FMLog.info("Done Loading");
}
}

View file

@ -0,0 +1,70 @@
package liquidmechanics.core.implement;
import liquidmechanics.core.pressure.FluidPressureNetwork;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.LiquidStack;
import universalelectricity.core.electricity.ElectricityNetwork;
/**
* Must be applied to all tile entities that are conductors.
*
* @author Calclavia
*
*/
public interface IPipe
{
/**
* The Fluid network that this pipe is part of
*/
public FluidPressureNetwork getNetwork();
public void setNetwork(FluidPressureNetwork network);
/**
* The UE tile entities that this conductor is connected to.
*
* @return
*/
public TileEntity[] getConnectedBlocks();
/**
* Gets the resistance the pipes too the liquid going threw it
*
* @return The amount of Ohm's of resistance.
*/
public double getResistance(LiquidStack stack);
/**
* The maximum amount of amps this pipe can handle before bursting. This is calculating
* PER TICK!
*
* @return The amount of amps in volts
*/
public double getMaxPressure();
/**
* Called when the pressure on the pipe passes max
*/
public void onOverPressure();
/**
* Resets the pipe and recalculate connection IDs again
*/
public void reset();
/**
* Instantly refreshes all connected blocks
*/
public void refreshConnectedBlocks();
/**
* Adds a connection between this conductor and a UE unit
*
* @param tileEntity - Must be either a producer, consumer or a conductor
* @param side - side in which the connection is coming from
*/
public void updateConnection(TileEntity tileEntity, ForgeDirection side);
public void updateConnectionWithoutSplit(TileEntity connectorFromSide, ForgeDirection orientation);
}

View file

@ -0,0 +1,139 @@
package liquidmechanics.core.pressure;
/**
* An easy way to display information on electricity.
*
* @author Calclavia
*/
public class FluidInfo
{
public static enum FluidUnits
{
FLOW_Rate("FLOW", "I"), PRESSURE("NPB", "P"), FORCE("Force", "N"), WATT_HOUR("Watt Hour", "Wh"), RESISTANCE("Ohm", "R");
public String name;
public String symbol;
private FluidUnits(String name, String symbol)
{
this.name = name;
this.symbol = symbol;
}
public String getPlural()
{
return this.name + "s";
}
}
public static enum MeasurementUnit
{
MICRO("Micro", "u", 0.000001), MILLI("Milli", "m", 0.001), KILO("Kilo", "k", 1000), MEGA("Mega", "M", 1000000);
public String name;
public String symbol;
public double value;
private MeasurementUnit(String name, String symbol, double value)
{
this.name = name;
this.symbol = symbol;
this.value = value;
}
public String getName(boolean isSymbol)
{
if (isSymbol)
{
return symbol;
}
else
{
return name;
}
}
public double process(double value)
{
return value / this.value;
}
}
/**
* Displays the unit as text. Works only for positive numbers.
*/
public static String getDisplay(double value, FluidUnits unit, int decimalPlaces, boolean isShort)
{
String unitName = unit.name;
if (isShort)
{
unitName = unit.symbol;
}
else if (value > 1)
{
unitName = unit.getPlural();
}
if (value == 0) { return value + " " + unitName; }
if (value <= MeasurementUnit.MILLI.value) { return roundDecimals(MeasurementUnit.MICRO.process(value), decimalPlaces) + " " + MeasurementUnit.MICRO.getName(isShort) + unitName; }
if (value < 1) { return roundDecimals(MeasurementUnit.MILLI.process(value), decimalPlaces) + " " + MeasurementUnit.MILLI.getName(isShort) + unitName; }
if (value > MeasurementUnit.MEGA.value) { return roundDecimals(MeasurementUnit.MEGA.process(value), decimalPlaces) + " " + MeasurementUnit.MEGA.getName(isShort) + unitName; }
if (value > MeasurementUnit.KILO.value) { return roundDecimals(MeasurementUnit.KILO.process(value), decimalPlaces) + " " + MeasurementUnit.KILO.getName(isShort) + unitName; }
return roundDecimals(value, decimalPlaces) + " " + unitName;
}
public static String getDisplay(double value, FluidUnits unit)
{
return getDisplay(value, unit, 2, false);
}
public static String getDisplayShort(double value, FluidUnits unit)
{
return getDisplay(value, unit, 2, true);
}
public static String getDisplayShort(double value, FluidUnits unit, int decimalPlaces)
{
return getDisplay(value, unit, decimalPlaces, true);
}
public static String getDisplaySimple(double value, FluidUnits unit, int decimalPlaces)
{
if (value > 1)
{
if (decimalPlaces < 1) { return (int) value + " " + unit.getPlural(); }
return roundDecimals(value, decimalPlaces) + " " + unit.getPlural();
}
if (decimalPlaces < 1) { return (int) value + " " + unit.name; }
return roundDecimals(value, decimalPlaces) + " " + unit.name;
}
/**
* Rounds a number to a specific number place places
*
* @param The number
* @return The rounded number
*/
public static double roundDecimals(double d, int decimalPlaces)
{
int j = (int) (d * Math.pow(10, decimalPlaces));
return j / (double) Math.pow(10, decimalPlaces);
}
public static double roundDecimals(double d)
{
return roundDecimals(d, 2);
}
}

View file

@ -0,0 +1,42 @@
package liquidmechanics.core.pressure;
import net.minecraftforge.liquids.LiquidStack;
/**
* A simple way to store electrical data.
*
* @author Calclavia
*
*/
public class FluidPacket implements Cloneable
{
public LiquidStack liquidStack;
public double pressure;
public FluidPacket(double pressure, LiquidStack stack)
{
this.liquidStack = stack;
this.pressure = pressure;
}
public FluidPacket()
{
this(0, new LiquidStack(0,0,0));
}
@Override
public String toString()
{
return "ElectricityPack [Amps:" + this.liquidStack + " Volts:" + this.pressure + "]";
}
@Override
public FluidPacket clone()
{
return new FluidPacket( this.pressure,this.liquidStack);
}
public boolean isEquals(FluidPacket electricityPack)
{
return this.liquidStack == electricityPack.liquidStack && this.pressure == electricityPack.pressure;
}
}

View file

@ -0,0 +1,153 @@
package liquidmechanics.core.pressure;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import liquidmechanics.core.implement.IPipe;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import universalelectricity.core.vector.Vector3;
import cpw.mods.fml.common.FMLLog;
/**
* based on Calclavia's UE Electric Network stuff
*
*/
public class FluidPressure
{
public static FluidPressure instance = new FluidPressure();
private List<FluidPressureNetwork> electricityNetworks = new ArrayList<FluidPressureNetwork>();
/**
* Registers a conductor into the UE electricity net.
*/
public void registerConductor(IPipe newConductor)
{
this.cleanUpNetworks();
FluidPressureNetwork newNetwork = new FluidPressureNetwork(newConductor);
this.electricityNetworks.add(newNetwork);
}
public void unregister(TileEntity tileEntity)
{
for (FluidPressureNetwork network : this.electricityNetworks)
{
network.stopProducing(tileEntity);
network.stopRequesting(tileEntity);
}
}
/**
* Merges two connection lines together into one.
*
* @param networkA
* - The network to be merged into. This network will be kept.
* @param networkB
* - The network to be merged. This network will be deleted.
*/
public void mergeConnection(FluidPressureNetwork networkA, FluidPressureNetwork networkB)
{
if (networkA != networkB)
{
if (networkA != null && networkB != null)
{
networkA.conductors.addAll(networkB.conductors);
networkA.setNetwork();
this.electricityNetworks.remove(networkB);
networkB = null;
networkA.cleanConductors();
}
else
{
System.err.println("Failed to merge Universal Electricity wire connections!");
}
}
}
/**
* Separate one connection line into two different ones between two
* conductors. This function does this by resetting all wires in the
* connection line and making them each reconnect.
*
* @param conductorA
* - existing conductor
* @param conductorB
* - broken/invalid conductor
*/
public void splitConnection(IPipe conductorA, IPipe conductorB)
{
try
{
FluidPressureNetwork network = conductorA.getNetwork();
if (network != null)
{
network.cleanConductors();
network.resetConductors();
Iterator it = network.conductors.iterator();
while (it.hasNext())
{
IPipe conductor = (IPipe) it.next();
for (byte i = 0; i < 6; i++)
{
conductor.updateConnectionWithoutSplit(Vector3.getConnectorFromSide(((TileEntity) conductor).worldObj, new Vector3((TileEntity) conductor), ForgeDirection.getOrientation(i)), ForgeDirection.getOrientation(i));
}
}
}
else
{
FMLLog.severe("Conductor invalid network while splitting connection!");
}
}
catch (Exception e)
{
FMLLog.severe("Failed to split wire connection!");
e.printStackTrace();
}
}
/**
* Clean up and remove all useless and invalid connections.
*/
public void cleanUpNetworks()
{
try
{
Iterator it = electricityNetworks.iterator();
while (it.hasNext())
{
FluidPressureNetwork network = (FluidPressureNetwork) it.next();
network.cleanConductors();
if (network.conductors.size() == 0)
{
it.remove();
}
}
}
catch (Exception e)
{
FMLLog.severe("Failed to clean up wire connections!");
e.printStackTrace();
}
}
public void resetConductors()
{
Iterator it = electricityNetworks.iterator();
while (it.hasNext())
{
FluidPressureNetwork network = ((FluidPressureNetwork) it.next());
network.resetConductors();
}
}
}

View file

@ -0,0 +1,309 @@
package liquidmechanics.core.pressure;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import liquidmechanics.api.liquids.LiquidHandler;
import liquidmechanics.core.implement.IPipe;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.LiquidStack;
import universalelectricity.core.vector.Vector3;
import cpw.mods.fml.common.FMLLog;
public class FluidPressureNetwork
{
private final HashMap<TileEntity, FluidPacket> producers = new HashMap<TileEntity, FluidPacket>();
private final HashMap<TileEntity, FluidPacket> consumers = new HashMap<TileEntity, FluidPacket>();
public final List<IPipe> conductors = new ArrayList<IPipe>();
public LiquidStack stack = new LiquidStack(0,0,0);
public FluidPressureNetwork(IPipe conductor)
{
this.addConductor(conductor);
}
/**
* Sets this tile entity to start producing energy in this network.
*/
public void startProducing(TileEntity tileEntity, FluidPacket pack)
{
if (tileEntity != null && pack.liquidStack != null && LiquidHandler.isEqual(stack, pack.liquidStack))
{
this.producers.put(tileEntity, pack);
}
}
public void startProducing(TileEntity tileEntity, double pressure, LiquidStack stack)
{
this.startProducing(tileEntity, new FluidPacket(pressure, stack));
}
public boolean isProducing(TileEntity tileEntity)
{
return this.producers.containsKey(tileEntity);
}
/**
* Sets this tile entity to stop producing energy in this network.
*/
public void stopProducing(TileEntity tileEntity)
{
this.producers.remove(tileEntity);
}
/**
* Sets this tile entity to start producing energy in this network.
*/
public void startRequesting(TileEntity tileEntity, FluidPacket pack)
{
if (tileEntity != null && pack.liquidStack != null && LiquidHandler.isEqual(stack, pack.liquidStack))
{
this.consumers.put(tileEntity, pack);
}
}
public void startRequesting(TileEntity tileEntity, double pressure, LiquidStack stack)
{
this.startRequesting(tileEntity, new FluidPacket(pressure, stack));
}
public boolean isRequesting(TileEntity tileEntity)
{
return this.consumers.containsKey(tileEntity);
}
/**
* Sets this tile entity to stop producing energy in this network.
*/
public void stopRequesting(TileEntity tileEntity)
{
this.consumers.remove(tileEntity);
}
/**
* @return The electricity produced in this electricity network
*/
public FluidPacket getProduced(LiquidStack stack)
{
FluidPacket totalElectricity = new FluidPacket(0, new LiquidStack(stack.itemID,0,stack.itemMeta));
Iterator it = this.producers.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
if (pairs != null)
{
TileEntity tileEntity = (TileEntity) pairs.getKey();
if (tileEntity == null)
{
it.remove();
continue;
}
if (tileEntity.isInvalid())
{
it.remove();
continue;
}
if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) != tileEntity)
{
it.remove();
continue;
}
FluidPacket pack = (FluidPacket) pairs.getValue();
if (pairs.getKey() != null && pairs.getValue() != null && pack != null && totalElectricity.liquidStack != null && pack.liquidStack != null)
{
int volume = totalElectricity.liquidStack.amount + pack.liquidStack.amount;
double pressure = Math.max(totalElectricity.pressure, pack.pressure);
totalElectricity.liquidStack = new LiquidStack(stack.itemID,volume,stack.itemMeta);
totalElectricity.pressure = pressure;
}
}
}
return totalElectricity;
}
/**
* @return How much electricity this network needs.
*/
public FluidPacket getRequest(LiquidStack stack)
{
FluidPacket totalElectricity = this.getRequestWithoutReduction(stack);
LiquidStack a = totalElectricity.liquidStack;
LiquidStack b = this.getProduced(stack).liquidStack;
if(a != null && b != null)
{
int amount = Math.max(a.amount - b.amount, 0);
totalElectricity.liquidStack.amount = amount;
}
return totalElectricity;
}
public FluidPacket getRequestWithoutReduction(LiquidStack stack)
{
FluidPacket totalElectricity = new FluidPacket(0, new LiquidStack(stack.itemID,0,stack.itemMeta));
Iterator it = this.consumers.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
if (pairs != null)
{
TileEntity tileEntity = (TileEntity) pairs.getKey();
if (tileEntity == null)
{
it.remove();
continue;
}
if (tileEntity.isInvalid())
{
it.remove();
continue;
}
if (tileEntity.worldObj.getBlockTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord) != tileEntity)
{
it.remove();
continue;
}
FluidPacket pack = (FluidPacket) pairs.getValue();
if (pack != null && pack.liquidStack != null)
{
totalElectricity.liquidStack.amount += pack.liquidStack.amount;
totalElectricity.pressure = Math.max(totalElectricity.pressure, pack.pressure);
}
}
}
return totalElectricity;
}
/**
* @return Returns all producers in this electricity network.
*/
public HashMap<TileEntity, FluidPacket> getProducers()
{
return this.producers;
}
/**
* @return Returns all consumers in this electricity network.
*/
public HashMap<TileEntity, FluidPacket> getConsumers()
{
return this.consumers;
}
public void addConductor(IPipe newConductor)
{
this.cleanConductors();
if (!conductors.contains(newConductor))
{
conductors.add(newConductor);
newConductor.setNetwork(this);
}
}
/**
* Get only the electric units that can receive electricity from the given side.
*/
public List<TileEntity> getReceivers()
{
List<TileEntity> receivers = new ArrayList<TileEntity>();
Iterator it = this.consumers.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
if (pairs != null)
{
receivers.add((TileEntity) pairs.getKey());
}
}
return receivers;
}
public void cleanConductors()
{
for (int i = 0; i < conductors.size(); i++)
{
if (conductors.get(i) == null)
{
conductors.remove(i);
}
else if (((TileEntity) conductors.get(i)).isInvalid())
{
conductors.remove(i);
}
}
}
public void resetConductors()
{
for (int i = 0; i < conductors.size(); i++)
{
conductors.get(i).reset();
}
}
public void setNetwork()
{
this.cleanConductors();
for (IPipe conductor : this.conductors)
{
conductor.setNetwork(this);
}
}
public void onOverCharge()
{
this.cleanConductors();
for (int i = 0; i < conductors.size(); i++)
{
conductors.get(i).onOverPressure();
}
}
/**
* This function is called to refresh all conductors in this network
*/
public void refreshConductors()
{
for (int j = 0; j < this.conductors.size(); j++)
{
IPipe conductor = this.conductors.get(j);
conductor.refreshConnectedBlocks();
}
}
}