public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix) { 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; } if (gasMix.Temperature > 250f) { //No reaction return; } 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)); } }
public void React(GasMix gasMix, MetaDataNode node) { 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.Nitryl) - heatScale < 0) { //No reaction return; } gasMix.AddGas(Gas.Stimulum, heatScale / 10f); gasMix.RemoveGas(Gas.Tritium, heatScale); gasMix.RemoveGas(Gas.Nitryl, heatScale); gasMix.SetTemperature( Mathf.Max((gasMix.Temperature * oldHeatCap + stimEnergyChange) / gasMix.WholeHeatCapacity, AtmosDefines.SPACE_TEMPERATURE)); }
/// <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 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, 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 void React(GasMix gasMix, MetaDataNode node) { 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; } 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.SetTemperature( Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, AtmosDefines.SPACE_TEMPERATURE)); } }
public void React(GasMix gasMix, MetaDataNode node) { 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; } 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, AtmosDefines.SPACE_TEMPERATURE)); }
public override void Initialize() { if (!CustomNetworkManager.IsServer) { return; } //We have bool to stop null checks on every pos var hasCustomMix = defaultRoomGasMixOverride != null; foreach (var gasSetter in GetComponentsInChildren <RoomGasSetter>()) { gasSetter.SetUp(); } BoundsInt bounds = metaTileMap.GetBounds(); foreach (Vector3Int position in bounds.allPositionsWithin) { //Get top tile at pos to check if it should spawn with no air bool spawnWithNoAir = false; var topTile = metaTileMap.GetTile(position, LayerTypeSelection.Effects | LayerTypeSelection.Underfloor); if (topTile is BasicTile tile) { spawnWithNoAir = tile.SpawnWithNoAir; } MetaDataNode node = metaDataLayer.Get(position, false); if ((node.IsRoom || node.IsOccupied) && !spawnWithNoAir) { //Check to see if theres a special room mix if (toSet.Count > 0 && toSet.TryGetValue(node.RoomNumber, out var gasSetter)) { node.GasMix = GasMix.NewGasMix(gasSetter.GasMixToSpawn); } //See if the whole matrix has a custom mix else if (hasCustomMix) { node.GasMix = GasMix.NewGasMix(defaultRoomGasMixOverride.BaseGasMix); } //Default to air mix otherwise else { node.GasMix = GasMix.NewGasMix(GasMixes.BaseAirMix); } } else { node.GasMix = GasMix.NewGasMix(GasMixes.BaseSpaceMix); } } foreach (var gasSetter in toSet) { _ = Despawn.ServerSingle(gasSetter.Value.gameObject); } toSet.Clear(); }
public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix) { 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; } gasMix.AddGas(Gas.BZ, reactionEfficiency); gasMix.RemoveGas(Gas.NitrousOxide, reactionEfficiency); gasMix.RemoveGas(Gas.Plasma, 2 * reactionEfficiency); gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap + energyReleased) / gasMix.WholeHeatCapacity, 2.7f)); }
public float React(ref GasMix gasMix, Vector3 tilePos) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min(gasMix.Temperature / 37315, gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen)); var energyUsed = reactionEfficiency * AtmosDefines.NITRYL_FORMATION_ENERGY; if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0) { //No reaction return(0f); } gasMix.RemoveGas(Gas.Oxygen, 2 * reactionEfficiency); gasMix.RemoveGas(Gas.Nitrogen, reactionEfficiency); gasMix.RemoveGas(Gas.BZ, 0.05f * reactionEfficiency); gasMix.AddGas(Gas.Nitryl, reactionEfficiency); if (energyUsed > 0) { gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f)); } return(0f); }
public void ExposeHotspot(Vector3Int localPosition) { if (!hotspots.ContainsKey(localPosition) || hotspots[localPosition].Hotspot == null) { Profiler.BeginSample("MarkForAddition"); MetaDataNode node = metaDataLayer.Get(localPosition); GasMix gasMix = node.GasMix; if (PlasmaFireReaction.CanHoldHotspot(gasMix)) { // igniting //addition will be done later in Update hotspotsToAdd.Add(new Hotspot(node)); } Profiler.EndSample(); } if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null) { //expose everything on this tile Expose(localPosition, localPosition); //expose impassable things on the adjacent tile Expose(localPosition, localPosition + Vector3Int.right); Expose(localPosition, localPosition + Vector3Int.left); Expose(localPosition, localPosition + Vector3Int.up); Expose(localPosition, localPosition + Vector3Int.down); } }
public void React(GasMix gasMix, MetaDataNode node) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEfficiency = Mathf.Min(gasMix.Temperature / 37315, gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen)); var energyUsed = reactionEfficiency * AtmosDefines.NITRYL_FORMATION_ENERGY; if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0) { //No reaction return; } gasMix.RemoveGas(Gas.Oxygen, 2 * reactionEfficiency); gasMix.RemoveGas(Gas.Nitrogen, reactionEfficiency); gasMix.RemoveGas(Gas.BZ, 0.05f * reactionEfficiency); gasMix.AddGas(Gas.Nitryl, reactionEfficiency); if (energyUsed > 0) { gasMix.SetTemperature( Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, AtmosDefines.SPACE_TEMPERATURE)); } }
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 void React(GasMix gasMix, Vector3 tilePos, Matrix matrix) { if (gasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE) { return; } if (gasMix.GetMoles(Gas.WaterVapor) < 2f) { //Not enough moles to freeze return; } var numberOfIceToSpawn = (int)Mathf.Floor(gasMix.GetMoles(Gas.WaterVapor) / 2f); //Stack size of ice is 50 if (numberOfIceToSpawn > 50) { numberOfIceToSpawn = 50; } if (numberOfIceToSpawn < 1) { return; } SpawnSafeThread.SpawnPrefab(tilePos, AtmosManager.Instance.iceShard, amountIfStackable: numberOfIceToSpawn); gasMix.RemoveGas(Gas.WaterVapor, numberOfIceToSpawn * 2f); }
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.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f)); } return(0f); }
public override void Initialize() { if (!CustomNetworkManager.IsServer) { return; } BoundsInt bounds = metaTileMap.GetBounds(); foreach (Vector3Int position in bounds.allPositionsWithin) { //get toptile at pos to check if it should spawn with no air bool spawnWithNoAir = false; var topTile = metaTileMap.GetTile(position, LayerTypeSelection.Effects | LayerTypeSelection.Underfloor); if (topTile is BasicTile tile) { spawnWithNoAir = tile.SpawnWithNoAir; } MetaDataNode node = metaDataLayer.Get(position, false); if ((node.IsRoom || node.IsOccupied) && !spawnWithNoAir) { node.GasMix = GasMix.NewGasMix(GasMixes.BaseAirMix); } else { node.GasMix = GasMix.NewGasMix(GasMixes.BaseSpaceMix); } } }
public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix) { var energyReleased = 0f; var oldHeatCap = gasMix.WholeHeatCapacity; var temperatureScale = 1f; if (gasMix.Temperature < AtmosDefines.FREON_LOWER_TEMPERATURE) { temperatureScale = 0; } else { temperatureScale = (AtmosDefines.FREON_MAXIMUM_BURN_TEMPERATURE - gasMix.Temperature) / (AtmosDefines.FREON_MAXIMUM_BURN_TEMPERATURE - AtmosDefines.FREON_LOWER_TEMPERATURE); } if (temperatureScale >= 0) { var oxygenBurnRate = AtmosDefines.OXYGEN_BURN_RATE_BASE - temperatureScale; var freonBurnRate = 0f; if (gasMix.GetMoles(Gas.Oxygen) > gasMix.GetMoles(Gas.Freon) * AtmosDefines.FREON_OXYGEN_FULLBURN) { freonBurnRate = gasMix.GetMoles(Gas.Freon) * temperatureScale / AtmosDefines.FREON_BURN_RATE_DELTA; } else { freonBurnRate = (temperatureScale * (gasMix.GetMoles(Gas.Oxygen) / AtmosDefines.FREON_OXYGEN_FULLBURN) / AtmosDefines.FREON_BURN_RATE_DELTA); } if (freonBurnRate > 0.0001f) { freonBurnRate = Mathf.Min(freonBurnRate, gasMix.GetMoles(Gas.Freon), gasMix.GetMoles(Gas.Oxygen)); gasMix.RemoveGas(Gas.Freon, freonBurnRate); gasMix.RemoveGas(Gas.Oxygen, freonBurnRate * oxygenBurnRate); gasMix.AddGas(Gas.CarbonDioxide, freonBurnRate); if (gasMix.Temperature < 160 && gasMix.Temperature > 120 && rnd.Next(0, 2) == 0) { SpawnSafeThread.SpawnPrefab(tilePos, AtmosManager.Instance.hotIce); } energyReleased += AtmosDefines.FIRE_FREON_ENERGY_RELEASED * freonBurnRate; } } if (energyReleased < 0) { var newHeatCap = gasMix.WholeHeatCapacity; if (newHeatCap > 0.0003f) { gasMix.SetTemperature((gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap); } } }
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.SetTemperature((temperature * heatCapacity + (Reactions.EnergyPerMole * TotalmolestoCO2)) / gasMix.WholeHeatCapacity); consumed = TotalmolestoCO2; } return(consumed); }
public static void React(GasMix gasMix, Matrix matrix) { foreach (Reaction reaction in reactions) { if (reaction.Satisfies(gasMix)) { reaction.React(gasMix, Vector3.zero, matrix); } } }
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) { //Used for updating tiles with the averagee Calculated gas for (int i = 0; i < Gas.Count; i++) { atmos.Gases[i] = gasMix.Gases[i]; } atmos.SetPressure(gasMix.Pressure); return(atmos); }
public void React(GasMix gasMix, MetaDataNode node) { var energyReleased = 0f; var oldHeatCap = gasMix.WholeHeatCapacity; 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); gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_OXY_FACTOR); energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_WEAK * burnedFuel; } else { burnedFuel = gasMix.GetMoles(Gas.Tritium); gasMix.RemoveGas(Gas.Tritium, burnedFuel / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR); gasMix.RemoveGas(Gas.Oxygen, burnedFuel); gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR); energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_RELEASED * burnedFuel; } if (burnedFuel != 0) { if (rnd.Next(0, 10) == 0 && burnedFuel > AtmosDefines.TRITIUM_MINIMUM_RADIATION_ENERGY) { RadiationManager.Instance.RequestPulse(node.Position.ToWorld(node.PositionMatrix).RoundToInt(), energyReleased / AtmosDefines.TRITIUM_BURN_RADIOACTIVITY_FACTOR, rnd.Next(Int32.MinValue, Int32.MaxValue)); } } if (energyReleased > 0) { var newHeatCap = gasMix.WholeHeatCapacity; if (newHeatCap > 0.0003f) { gasMix.SetTemperature((gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap); } } //Create fire if possible if (gasMix.Temperature > AtmosDefines.FIRE_MINIMUM_TEMPERATURE_TO_EXIST) { //Dont do expose as we are off the main thread node.ReactionManager.ExposeHotspot(node.Position, doExposure: false); } }
public static bool CanHoldHotspot(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); } } return(false); }
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); }
/// <summary> /// Use to set a rooms gas after the round has started, otherwise do it in the initialisation /// </summary> /// <param name="roomNumber">Room number to fill</param> /// <param name="gasMixToUse">GasMix to fill room with</param> public void SetRoomGas(int roomNumber, GasMix gasMixToUse) { BoundsInt bounds = metaTileMap.GetBounds(); foreach (Vector3Int position in bounds.allPositionsWithin) { MetaDataNode node = metaDataLayer.Get(position, false); if (node.IsRoom && node.RoomNumber == roomNumber) { node.GasMix = GasMix.NewGasMix(gasMixToUse); } } }
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, Vector3.zero); } } return(consumed); }
/// <summary> /// Use to set a rooms gas after the round has started, otherwise do it in the initialisation /// </summary> /// <param name="roomNumber">Room number to fill</param> /// <param name="gasMixToUse">GasMix to fill room with</param> public void SetRoomGas(int roomNumber, GasMix gasMixToUse) { var bounds = metaTileMap.GetLocalBounds(); foreach (Vector3Int position in bounds.allPositionsWithin()) { MetaDataNode node = metaDataLayer.Get(position, false); if (node.IsRoom && node.RoomNumber == roomNumber) { //Use ChangeGasMix to remove old gas overlays and add new overlays node.ChangeGasMix(GasMix.NewGasMix(gasMixToUse)); } } }
/// <summary> /// Transfers heat between an Open tile and a Solid tile /// Uses data from MetaDataNode for SolidNode and GasMix values for Open node /// </summary> private void ConductFromOpenToSolid(MetaDataNode solidNode, GasMix meanGasMix) { var tempDelta = solidNode.ConductivityTemperature - meanGasMix.Temperature; if (Mathf.Abs(tempDelta) <= AtmosDefines.MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) { return; } if (meanGasMix.WholeHeatCapacity <= AtmosConstants.MINIMUM_HEAT_CAPACITY) { return; } if (solidNode.HeatCapacity <= AtmosConstants.MINIMUM_HEAT_CAPACITY) { return; } //The larger the combined capacity the less is shared var heat = solidNode.ThermalConductivity * tempDelta * (solidNode.HeatCapacity * meanGasMix.WholeHeatCapacity / (solidNode.HeatCapacity + meanGasMix.WholeHeatCapacity)); solidNode.ConductivityTemperature = Mathf.Max( solidNode.ConductivityTemperature - (heat / solidNode.HeatCapacity), AtmosDefines.SPACE_TEMPERATURE); meanGasMix.SetTemperature(Mathf.Max( meanGasMix.Temperature + (heat / meanGasMix.WholeHeatCapacity), AtmosDefines.SPACE_TEMPERATURE)); //Do atmos update for the Solid node if temperature is allowed so it can do conduction //This is checking for the start temperature as this is how the cycle will begin if (solidNode.ConductivityTemperature < AtmosDefines.MINIMUM_TEMPERATURE_START_SUPERCONDUCTION) { return; } if (solidNode.AllowedToSuperConduct == false) { solidNode.AllowedToSuperConduct = true; //Allow this node to trigger other tiles super conduction solidNode.StartingSuperConduct = true; } AtmosManager.Update(solidNode); }
/// <summary> /// Calculate the average Gas tile if you averaged all the adjacent ones and itself /// </summary> /// <returns>The mean gas mix.</returns> private void CalcMeanGasMix() { meanGasMix.Clear(); var targetCount = 0; for (var i = 0; i < nodes.Count; i++) { MetaDataNode node = nodes[i]; if (node == null) { continue; } //If node is not occupied then we want to add it to the total if (node.IsOccupied == false && node.IsIsolatedNode == false) { meanGasMix.Volume += node.GasMix.Volume; GasMix.TransferGas(meanGasMix, node.GasMix, node.GasMix.Moles, true); targetCount++; } else if (node.IsIsolatedNode == false) { //Remove all overlays for occupied tiles RemovalAllGasOverlays(node); //We trap the gas in the walls to stop instances where you remove a wall and theres a vacuum there } } // Sometimes, we calculate the meanGasMix of a tile surrounded by IsOccupied tiles (no atmos, ie: walls) if (targetCount == 0) { return; } meanGasMix.Volume /= targetCount; //Note: this assumes the volume of all tiles are the same lock (meanGasMix.GasesArray) //no Double lock { for (int i = meanGasMix.GasesArray.Count - 1; i >= 0; i--) { var gasData = meanGasMix.GasesArray[i]; meanGasMix.GasData.SetMoles(gasData.GasSO, meanGasMix.GasData.GetGasMoles(gasData.GasSO) / targetCount); } } }