/// <summary> /// The thing that actually equalises the tiles /// </summary> private void Equalize() { // If there is just one isolated tile, it's not nescessary to calculate the mean. Speeds up things a bit. if (nodes.Count > 1) { //Calculate the average gas from adding up all the adjacent tiles and dividing by the number of tiles GasMix MeanGasMix = CalcMeanGasMix(); for (var i = 0; i < nodes.Count; i++) { MetaDataNode node = nodes[i]; if (!node.IsOccupied) { node.GasMix = CalcAtmos(node.GasMix, MeanGasMix); if (node.IsSpace) { //Set to 0 if space node.GasMix *= 0; } } } } }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min(gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen)); var energyUsed = reactionEfficiency * AtmosDefines.NITROUS_FORMATION_ENERGY; if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0) { //No reaction return(0f); } if (gasMix.Temperature > 250f) { //No reaction return(0f); } gasMix.RemoveGas(Gas.Oxygen, reactionEfficiency); gasMix.RemoveGas(Gas.Nitrogen, 2 * reactionEfficiency); gasMix.AddGas(Gas.NitrousOxide, reactionEfficiency); if (energyUsed > 0) { gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f)); } return(0f); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min(gasMix.Temperature / 3731.5f, gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.CarbonDioxide), gasMix.GetMoles(Gas.BZ)); var energyUsed = reactionEfficiency * 100; if (gasMix.GetMoles(Gas.Plasma) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.CarbonDioxide) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0) { //No reaction return(0f); } gasMix.RemoveGas(Gas.Plasma, 5 * reactionEfficiency); gasMix.RemoveGas(Gas.CarbonDioxide, reactionEfficiency); gasMix.RemoveGas(Gas.BZ, 0.25f * reactionEfficiency); gasMix.AddGas(Gas.Freon, reactionEfficiency * 2); if (energyUsed > 0) { gasMix.Temperature = Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f); } return(0f); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var ballShotAngle = 180 * Mathf.Cos(gasMix.GetMoles(Gas.WaterVapor) * gasMix.GetMoles(Gas.Nitryl)) + 180; var stimUsed = Mathf.Min(AtmosDefines.STIM_BALL_GAS_AMOUNT * gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Stimulum)); var pluoxUsed = Mathf.Min(AtmosDefines.STIM_BALL_GAS_AMOUNT * gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Pluoxium)); var energyReleased = stimUsed * AtmosDefines.STIMULUM_HEAT_SCALE; //TODO shoot stim projectile using the angle gasMix.AddGas(Gas.CarbonDioxide, 4 * pluoxUsed); gasMix.AddGas(Gas.Nitrogen, 8 * stimUsed); gasMix.SetGas(Gas.Plasma, gasMix.GetMoles(Gas.Plasma) * 0.5f); gasMix.RemoveGas(Gas.Pluoxium, 10 * pluoxUsed); gasMix.RemoveGas(Gas.Stimulum, 20 * stimUsed); gasMix.SetTemperature(Mathf.Clamp((gasMix.Temperature * oldHeatCap + energyReleased) / gasMix.WholeHeatCapacity, 2.7f, Single.PositiveInfinity)); return(0f); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min( //More efficient at less than 10 Kpa (float)(1 / ((gasMix.Pressure / (0.1 * 101.325)))) * (Mathf.Max(gasMix.GetMoles(Gas.Plasma) * gasMix.GetMoles(Gas.NitrousOxide), 1f)), gasMix.GetMoles(Gas.NitrousOxide), gasMix.GetMoles(Gas.Plasma) / 2); var energyReleased = 2 * reactionEfficiency * AtmosDefines.FIRE_CARBON_ENERGY_RELEASED; if (gasMix.GetMoles(Gas.NitrousOxide) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Plasma) - 2 * reactionEfficiency < 0 || energyReleased <= 0) { //No reaction return(0f); } gasMix.AddGas(Gas.BZ, reactionEfficiency); gasMix.RemoveGas(Gas.NitrousOxide, reactionEfficiency); gasMix.RemoveGas(Gas.Plasma, 2 * reactionEfficiency); gasMix.Temperature = Mathf.Max((gasMix.Temperature * oldHeatCap + energyReleased) / gasMix.WholeHeatCapacity, 2.7f); return(0f); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var burnedFuel = 0f; burnedFuel = Mathf.Max(0f, 0.00002f * (gasMix.Temperature - (0.00001f * Mathf.Pow(gasMix.Temperature, 2)))) * gasMix.GetMoles(Gas.NitrousOxide); gasMix.RemoveGas(Gas.NitrousOxide, burnedFuel); if (burnedFuel != 0) { var energyReleased = AtmosDefines.N2O_DECOMPOSITION_ENERGY_RELEASED * burnedFuel; gasMix.AddGas(Gas.Oxygen, burnedFuel / 2f); gasMix.AddGas(Gas.Nitrogen, burnedFuel); var newHeatCap = gasMix.WholeHeatCapacity; if (newHeatCap > 0.0003f) { gasMix.SetTemperature((gasMix.Temperature + energyReleased) / newHeatCap); } } return(0f); }
public float React(ref GasMix gasMix) { float consumed = 0; float temperature = gasMix.Temperature; float BurnRate = GetOxygenContact(gasMix); //Logger.Log(BurnRate.ToString() + "BurnRate"); if (BurnRate > 0) { float MolesPlasmaBurnt = gasMix.GetMoles(Gas.Plasma) * Reactions.BurningDelta * BurnRate; if (MolesPlasmaBurnt * 2 > gasMix.GetMoles(Gas.Oxygen)) { MolesPlasmaBurnt = (gasMix.GetMoles(Gas.Oxygen) * Reactions.BurningDelta * BurnRate) / 2; } gasMix.RemoveGas(Gas.Plasma, MolesPlasmaBurnt); gasMix.RemoveGas(Gas.Oxygen, MolesPlasmaBurnt * 2); var TotalmolestoCO2 = MolesPlasmaBurnt + (MolesPlasmaBurnt * 2); gasMix.AddGas(Gas.CarbonDioxide, TotalmolestoCO2 / 3); float heatCapacity = gasMix.WholeHeatCapacity; gasMix.Temperature = (temperature * heatCapacity + (Reactions.EnergyPerMole * TotalmolestoCO2)) / gasMix.WholeHeatCapacity; consumed = TotalmolestoCO2; } return(consumed); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var heatScale = Mathf.Min(gasMix.Temperature / AtmosDefines.STIMULUM_HEAT_SCALE, gasMix.GetMoles(Gas.Tritium), gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Nitryl)); var stimEnergyChange = heatScale + AtmosDefines.STIMULUM_FIRST_RISE * Mathf.Pow(heatScale, 2) - AtmosDefines.STIMULUM_FIRST_DROP * Mathf.Pow(heatScale, 3) + AtmosDefines.STIMULUM_SECOND_RISE * Mathf.Pow(heatScale, 4) - AtmosDefines.STIMULUM_ABSOLUTE_DROP * Mathf.Pow(heatScale, 5); if (gasMix.GetMoles(Gas.Tritium) - heatScale < 0 || gasMix.GetMoles(Gas.Plasma) - heatScale < 0 || gasMix.GetMoles(Gas.Nitryl) - heatScale < 0) { //No reaction return(0f); } gasMix.AddGas(Gas.Stimulum, heatScale / 10f); gasMix.RemoveGas(Gas.Tritium, heatScale); gasMix.RemoveGas(Gas.Plasma, heatScale); gasMix.RemoveGas(Gas.Nitryl, heatScale); gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap + stimEnergyChange) / gasMix.WholeHeatCapacity, 2.7f)); return(0f); }
public GasMix RemoveRatio(float ratio) { GasMix removed = this * ratio; this -= removed; return(removed); }
public float React(ref GasMix gasMix, Vector3 tilePos) { float consumed = 0; float temperature = gasMix.Temperature; float BurnRate = GetOxygenContact(gasMix); //Logger.Log(BurnRate.ToString() + "BurnRate"); if (BurnRate > 0) { var superSaturated = false; float MolesPlasmaBurnt = gasMix.GetMoles(Gas.Plasma) * Reactions.BurningDelta * BurnRate; if (MolesPlasmaBurnt * 2 > gasMix.GetMoles(Gas.Oxygen)) { MolesPlasmaBurnt = (gasMix.GetMoles(Gas.Oxygen) * Reactions.BurningDelta * BurnRate) / 2; } if (MolesPlasmaBurnt < 0) { return(0); } if (gasMix.GetMoles(Gas.Oxygen) / gasMix.GetMoles(Gas.Plasma) > AtmosDefines.SUPER_SATURATION_THRESHOLD) { superSaturated = true; } gasMix.RemoveGas(Gas.Plasma, MolesPlasmaBurnt); if (gasMix.Gases[Gas.Plasma] < 0) { gasMix.Gases[Gas.Plasma] = 0; } gasMix.RemoveGas(Gas.Oxygen, MolesPlasmaBurnt * 2); if (gasMix.Gases[Gas.Oxygen] < 0) { gasMix.Gases[Gas.Oxygen] = 0; } var TotalmolestoCO2 = MolesPlasmaBurnt + (MolesPlasmaBurnt * 2); if (superSaturated) { gasMix.AddGas(Gas.Tritium, TotalmolestoCO2 / 3); } else { gasMix.AddGas(Gas.CarbonDioxide, TotalmolestoCO2 / 3); } float heatCapacity = gasMix.WholeHeatCapacity; gasMix.Temperature = (temperature * heatCapacity + (Reactions.EnergyPerMole * TotalmolestoCO2)) / gasMix.WholeHeatCapacity; consumed = TotalmolestoCO2; } return(consumed); }
public void Copy(GasMix other) { for (int i = 0; i < Gas.Count; i++) { Gases[i] = other.Gases[i]; } SetPressure(other.Pressure); Volume = other.Volume; }
private GasMix CalcAtmos(GasMix atmos, GasMix gasMix) { for (int i = 0; i < Gas.Count; i++) { atmos.Gases[i] += (gasMix.Gases[i] - atmos.Gases[i]) * factor; } atmos.Pressure += (gasMix.Pressure - atmos.Pressure) * factor; return(atmos); }
private GasMix CalcAtmos(GasMix atmos, GasMix gasMix) { //Used for updating tiles with the averagee Calculated gas for (int i = 0; i < Gas.Count; i++) { atmos.Gases[i] = gasMix.Gases[i]; } atmos.Pressure = gasMix.Pressure; return(atmos); }
public GasMix RemoveVolume(float volume, bool setVolume = false) { GasMix removed = RemoveRatio(volume / Volume); if (setVolume) { removed.Volume = volume; removed = FromTemperature(removed.Gases, Temperature, volume); } return(removed); }
private GasMix CalcAtmos(GasMix atmos, GasMix gasMix) { float[] gases = new float[Gas.Count]; for (int i = 0; i < Gas.Count; i++) { gases[i] = atmos.Gases[i] + (gasMix.Gases[i] - atmos.Gases[i]) * factor; } float pressure = atmos.Pressure + (gasMix.Pressure - atmos.Pressure) * factor; return(GasMix.FromPressure(gases, pressure, atmos.Volume)); }
public GasMix RemoveRatio(float ratio) { GasMix removed = this * ratio; for (int i = 0; i < Gas.Count; i++) { Gases[i] -= removed.Gases[i]; } SetPressure(Pressure -= removed.Pressure * removed.Volume / Volume); return(removed); }
public static float React(ref GasMix gasMix) { float consumed = 0; foreach (Reaction reaction in reactions) { if (reaction.Satisfies(gasMix)) { consumed += reaction.React(ref gasMix); } } return(consumed); }
private void Equalize() { GasMix gasMix = CalcMeanGasMix(); for (var i = 0; i < nodes.Count; i++) { MetaDataNode node = nodes[i]; if (!node.IsOccupied) { node.Atmos = CalcAtmos(node.Atmos, gasMix); } } }
/// <summary> /// The thing that actually equalises the tiles /// </summary> private void Equalize() { //Calculate the average gas from adding up all the adjacent tiles and dividing by the number of tiles GasMix MeanGasMix = CalcMeanGasMix(); for (var i = 0; i < nodes.Count; i++) { MetaDataNode node = nodes[i]; if (!node.IsOccupied) { node.GasMix = CalcAtmos(node.GasMix, MeanGasMix); } } }
private GasMix CalcMeanGasMix() { int targetCount = 0; float[] gases = new float[Gas.Count]; float pressure = 0f; for (var i = 0; i < nodes.Count; i++) { MetaDataNode node = nodes[i]; if (node.IsSpace) { node.Atmos *= 1 - factor; } for (int j = 0; j < Gas.Count; j++) { gases[j] += node.Atmos.Gases[j]; } pressure += node.Atmos.Pressure; if (!node.IsOccupied) { targetCount++; } else { node.Atmos *= 1 - factor; if (node.Atmos.Pressure > AtmosUtils.MinimumPressure) { updateList.Enqueue(node); } } } for (int j = 0; j < Gas.Count; j++) { gases[j] /= targetCount; } GasMix gasMix = GasMix.FromPressure(gases, pressure / targetCount); return(gasMix); }
private static bool ReactionMoleCheck(GasReactions gasReaction, GasMix gasMix) { foreach (var data in gasReaction.GasReactionData) { if (gasMix.GetMoles(data.Key) == 0) { return(true); } if (gasMix.GetMoles(data.Key) < data.Value.minimumMolesToReact) { return(true); } } return(false); }
public float React(ref GasMix gasMix) { float consumed = 0; float temperature = gasMix.Temperature; float temperatureScale = 1; if (temperature <= Reactions.PLASMA_UPPER_TEMPERATURE) { temperatureScale = (temperature - Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE) / (Reactions.PLASMA_UPPER_TEMPERATURE - Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE); } if (temperatureScale > 0) { float oxygenBurnRate = Reactions.OXYGEN_BURN_RATE_BASE - temperatureScale; // orientate plasma burn rate on the one with less moles float moles = Mathf.Min(gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Oxygen) / Reactions.PLASMA_OXYGEN_FULLBURN); float plasmaBurnRate = (temperatureScale * moles) / Reactions.PLASMA_BURN_RATE_DELTA; // MINIMUM_HEAT_CAPACITY 0.0003 if (plasmaBurnRate > 0.0003) { float heatCapacity = gasMix.HeatCapacity; plasmaBurnRate = Mathf.Min(plasmaBurnRate, gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Oxygen) / oxygenBurnRate); float consumedOxygen = plasmaBurnRate * oxygenBurnRate; gasMix.RemoveGas(Gas.Plasma, plasmaBurnRate); gasMix.RemoveGas(Gas.Oxygen, consumedOxygen); gasMix.AddGas(Gas.CarbonDioxide, plasmaBurnRate); float energyReleased = Reactions.FIRE_PLASMA_ENERGY_RELEASED * plasmaBurnRate; gasMix.Temperature = (temperature * heatCapacity + energyReleased) / gasMix.HeatCapacity; consumed = plasmaBurnRate + consumedOxygen; } } return(consumed); }
public float React(ref GasMix gasMix, Vector3 tilePos) { if (gasMix.GetMoles(Gas.WaterVapor) != 0 && gasMix.GetMoles(Gas.WaterVapor) / gasMix.Moles > 0.1) { //No reaction return(0f); } var cleanedAir = Mathf.Min(gasMix.GetMoles(Gas.Miasma), 20 + (gasMix.Temperature - 373.15f - 70) / 20); gasMix.RemoveGas(Gas.Miasma, cleanedAir); gasMix.AddGas(Gas.Oxygen, cleanedAir); gasMix.Temperature += cleanedAir * 0.002f; return(0f); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var energyReleased = 0f; var oldHeatCap = gasMix.WholeHeatCapacity; var temperatureScale = 1f; var burnedFuel = 0f; if (gasMix.GetMoles(Gas.Oxygen) < gasMix.GetMoles(Gas.Tritium) || AtmosDefines.MINIMUM_TRIT_OXYBURN_ENERGY > gasMix.InternalEnergy) { burnedFuel = gasMix.GetMoles(Gas.Oxygen) / AtmosDefines.TRITIUM_BURN_OXY_FACTOR; gasMix.RemoveGas(Gas.Tritium, burnedFuel); } else { burnedFuel = gasMix.GetMoles(Gas.Tritium) * AtmosDefines.TRITIUM_BURN_TRIT_FACTOR; gasMix.RemoveGas(Gas.Tritium, gasMix.GetMoles(Gas.Tritium) / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR); gasMix.RemoveGas(Gas.Oxygen, gasMix.GetMoles(Gas.Tritium)); } if (burnedFuel != 0) { energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_RELEASED * burnedFuel; if (Random.Range(0, 10) == 0 && burnedFuel > AtmosDefines.TRITIUM_MINIMUM_RADIATION_ENERGY) { RadiationManager.Instance.RequestPulse(MatrixManager.AtPoint(tilePos.RoundToInt(), true).Matrix, tilePos.RoundToInt(), energyReleased / AtmosDefines.TRITIUM_BURN_RADIOACTIVITY_FACTOR, Random.Range(Int32.MinValue, Int32.MaxValue)); } gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_OXY_FACTOR); } if (energyReleased > 0) { var newHeatCap = gasMix.WholeHeatCapacity; if (newHeatCap > 0.0003f) { gasMix.Temperature = (gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap; } } return(0f); }
public bool Satisfies(GasMix gasMix) { if (gasMix.Temperature > Reactions.PlasmaMaintainFire && gasMix.GetMoles(Gas.Plasma) > 0.1f && gasMix.GetMoles(Gas.Oxygen) > 0.1f) { if (GetOxygenContact(gasMix) > Reactions.MinimumOxygenContact) { return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// Exposes the hotspot, igniting gases on the tile /// </summary> private void Expose() { if ((Volume / node.GasMix.Volume) > 0.95f) { GasMix gasMix = node.GasMix; float consumed = Reactions.React(ref gasMix); node.GasMix = gasMix; Volume = consumed * 40; Temperature = node.GasMix.Temperature; } else { GasMix removed = node.GasMix.RemoveVolume(Volume); removed.SetTemperature(Temperature); float consumed = Reactions.React(ref removed); Volume = consumed * 40; Temperature = removed.Temperature; node.GasMix -= removed; } }
private void Expose() { if ((Volume / node.Atmos.Volume) > 0.95f) { float consumed = Reactions.React(ref node.Atmos); Volume = consumed * 40; Temperature = node.Atmos.Temperature; } else { GasMix removed = node.Atmos.RemoveVolume(Volume); removed.Temperature = Temperature; float consumed = Reactions.React(ref removed); Volume = consumed * 40; Temperature = removed.Temperature; node.Atmos += removed; } }
public float React(ref GasMix gasMix, Vector3 tilePos) { if (gasMix.Temperature <= AtmosDefines.WATER_VAPOR_FREEZE) { if (gasMix.GetMoles(Gas.WaterVapor) < 2f) { //Not enough moles to freeze return(0f); } var numberOfIceToSpawn = Mathf.Floor(gasMix.GetMoles(Gas.WaterVapor) / 2f); for (var i = 0; i < numberOfIceToSpawn; i++) { Spawn.ServerPrefab(AtmosManager.Instance.iceShard, tilePos, MatrixManager.GetDefaultParent(tilePos, true)); } gasMix.RemoveGas(Gas.WaterVapor, numberOfIceToSpawn * 2f); } return(0f); }
/// <summary> /// Ensures that both containers have the same pressure /// </summary> /// <param name="otherGas"></param> public GasMix MergeGasMix(GasMix otherGas) { float totalInternalEnergy = InternalEnergy + otherGas.InternalEnergy; float totalWholeHeatCapacity = WholeHeatCapacity + otherGas.WholeHeatCapacity; float Newtemperature = totalInternalEnergy / totalWholeHeatCapacity; float totalVolume = Volume + otherGas.Volume; for (int i = 0; i < Gas.Count; i++) { if (Gases[i] < 0) { Debug.Log("OH GOFD!!"); } float gas = (Gases[i] + otherGas.Gases[i]) / totalVolume; Gases[i] = gas * Volume; otherGas.Gases[i] = gas * otherGas.Volume; } SetTemperature(Newtemperature); otherGas.SetTemperature(Newtemperature); return(otherGas); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min(gasMix.GetMoles(Gas.Nitrogen) + gasMix.GetMoles(Gas.Tritium) / 100, gasMix.GetMoles(Gas.Tritium) / 10, gasMix.GetMoles(Gas.Nitrogen) / 20); var energyUsed = reactionEfficiency * (AtmosDefines.NOBLIUM_FORMATION_ENERGY / Mathf.Max(gasMix.GetMoles(Gas.BZ), 1f)); if (gasMix.GetMoles(Gas.Tritium) - 10 * reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - 20 * reactionEfficiency < 0) { //No reaction return(0f); } gasMix.RemoveGas(Gas.Tritium, 10 * reactionEfficiency); gasMix.RemoveGas(Gas.Nitrogen, 20 * reactionEfficiency); gasMix.AddGas(Gas.HyperNoblium, reactionEfficiency); gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f)); return(0f); }