public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { var initialN2 = mixture.GetMoles(Gas.Nitrogen); var initialOxy = mixture.GetMoles(Gas.Oxygen); var initialTrit = mixture.GetMoles(Gas.Tritium); var efficiency = mixture.Temperature / Atmospherics.FrezonProductionMaxEfficiencyTemperature; var loss = 1 - efficiency; // Less N2 is required the more efficient it is. var minimumN2 = (initialOxy + initialTrit) / (Atmospherics.FrezonProductionNitrogenRatio * efficiency); if (initialN2 < minimumN2) { return(ReactionResult.NoReaction); } var oxyConversion = initialOxy / Atmospherics.FrezonProductionConversionRate; var tritConversion = initialTrit / Atmospherics.FrezonProductionConversionRate; var total = oxyConversion + tritConversion; mixture.AdjustMoles(Gas.Oxygen, -oxyConversion); mixture.AdjustMoles(Gas.Tritium, -tritConversion); mixture.AdjustMoles(Gas.Frezon, total * efficiency); mixture.AdjustMoles(Gas.Nitrogen, total * loss); return(ReactionResult.Reacting); }
public void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length == 0) { shell.WriteError("Not enough arguments."); return; } var mapManager = IoCManager.Resolve <IMapManager>(); var entityManager = IoCManager.Resolve <IEntityManager>(); var mixture = new GasMixture(Atmospherics.CellVolume) { Temperature = Atmospherics.T20C }; mixture.AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard); mixture.AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard); foreach (var gid in args) { // I like offering detailed error messages, that's why I don't use one of the extension methods. if (!int.TryParse(gid, out var i) || i <= 0) { shell.WriteError($"Invalid grid ID \"{gid}\"."); continue; } if (!mapManager.TryGetGrid(new GridId(i), out var grid)) { shell.WriteError($"Grid \"{i}\" doesn't exist."); continue; } if (!entityManager.TryGetEntity(grid.GridEntityId, out var entity)) { shell.WriteError($"Grid entity for grid \"{i}\" doesn't exist."); continue; } var gridAtmosphere = new GridAtmosphereComponent() { Owner = entity }; // Inject dependencies manually or a NRE will eat your face. IoCManager.InjectDependencies(gridAtmosphere); entityManager.ComponentManager.AddComponent(entity, gridAtmosphere, true); gridAtmosphere.RepopulateTiles(); foreach (var tile in gridAtmosphere) { tile.Air = (GasMixture)mixture.Clone(); tile.Air.Volume = gridAtmosphere.GetVolumeForCells(1); tile.Invalidate(); } } }
public async Task RemoveRatio(float ratio) { await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true }); var server = pairTracker.Pair.Server; await server.WaitAssertion(() => { var a = new GasMixture(10f); a.AdjustMoles(Gas.Oxygen, 100); a.AdjustMoles(Gas.Nitrogen, 100); var origTotal = a.TotalMoles; // we remove moles from the mixture with a ratio. var b = a.RemoveRatio(ratio); // check that the amount of moles in the original and the new mixture are correct. Assert.That(b.TotalMoles, Is.EqualTo(origTotal *ratio)); Assert.That(a.TotalMoles, Is.EqualTo(origTotal - b.TotalMoles)); Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(100 * ratio)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(100 * ratio)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(100 - b.GetMoles(Gas.Oxygen))); Assert.That(a.GetMoles(Gas.Nitrogen), Is.EqualTo(100 - b.GetMoles(Gas.Nitrogen))); }); await pairTracker.CleanReturnAsync(); }
public async Task RemoveRatio(float ratio) { var server = StartServer(); server.Assert(() => { var a = new GasMixture(10f); a.AdjustMoles(Gas.Oxygen, 100); a.AdjustMoles(Gas.Nitrogen, 100); var origTotal = a.TotalMoles; // we remove moles from the mixture with a ratio. var b = a.RemoveRatio(ratio); // check that the amount of moles in the original and the new mixture are correct. Assert.That(b.TotalMoles, Is.EqualTo(origTotal * ratio)); Assert.That(a.TotalMoles, Is.EqualTo(origTotal - b.TotalMoles)); Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(100 * ratio)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(100 * ratio)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(100 - b.GetMoles(Gas.Oxygen))); Assert.That(a.GetMoles(Gas.Nitrogen), Is.EqualTo(100 - b.GetMoles(Gas.Nitrogen))); }); await server.WaitIdleAsync(); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { var initialMiasma = mixture.GetMoles(Gas.Miasma); var initialFrezon = mixture.GetMoles(Gas.Frezon); var convert = Math.Min(Math.Min(initialFrezon, initialMiasma), Atmospherics.MiasmicSubsumationMaxConversionRate); mixture.AdjustMoles(Gas.Miasma, convert); mixture.AdjustMoles(Gas.Frezon, -convert); return(ReactionResult.Reacting); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var temperature = mixture.Temperature; var energyModifier = 1f; var scale = (temperature - Atmospherics.FrezonCoolLowerTemperature) / (Atmospherics.FrezonCoolMidTemperature - Atmospherics.FrezonCoolLowerTemperature); if (scale > 1f) { // Scale energy but not frezon usage if we're in a very, very hot place energyModifier = Math.Min(scale, Atmospherics.FrezonCoolMaximumEnergyModifier); scale = 1f; } if (scale <= 0) { return(ReactionResult.NoReaction); } var initialNit = mixture.GetMoles(Gas.Nitrogen); var initialFrezon = mixture.GetMoles(Gas.Frezon); var burnRate = initialFrezon * scale / Atmospherics.FrezonCoolRateModifier; var energyReleased = 0f; if (burnRate > Atmospherics.MinimumHeatCapacity) { var nitAmt = Math.Min(burnRate * Atmospherics.FrezonNitrogenCoolRatio, initialNit); var frezonAmt = Math.Min(burnRate, initialFrezon); mixture.AdjustMoles(Gas.Nitrogen, -nitAmt); mixture.AdjustMoles(Gas.Frezon, -frezonAmt); mixture.AdjustMoles(Gas.NitrousOxide, nitAmt + frezonAmt); energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier; } if (energyReleased >= 0f) { return(ReactionResult.NoReaction); } var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity; } return(ReactionResult.Reacting); }
public async Task TestMerge() { var server = StartServerDummyTicker(); server.Assert(() => { var a = new GasMixture(10f); var b = new GasMixture(10f); a.AdjustMoles(Gas.Oxygen, 50); b.AdjustMoles(Gas.Nitrogen, 50); // a now has 50 moles of oxygen Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); // b now has 50 moles of nitrogen Assert.That(b.TotalMoles, Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); b.Merge(a); // b now has its contents and the contents of a Assert.That(b.TotalMoles, Is.EqualTo(100)); Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); // a should be the same, however. Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); }); await server.WaitIdleAsync(); }
public GasMixture Clean(BloodstreamComponent bloodstream) { var gasMixture = new GasMixture(bloodstream.Air.Volume) { Temperature = bloodstream.Air.Temperature }; for (Gas gas = 0; gas < (Gas)Atmospherics.TotalNumberOfGases; gas++) { float amount; var molesInBlood = bloodstream.Air.GetMoles(gas); if (!NeedsGases.TryGetValue(gas, out var needed)) { amount = molesInBlood; } else { var overflowThreshold = needed * 1.5f; amount = molesInBlood > overflowThreshold ? molesInBlood - overflowThreshold : 0; } gasMixture.AdjustMoles(gas, amount); bloodstream.Air.AdjustMoles(gas, -amount); } return(gasMixture); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, GridTileLookupSystem gridTileLookup) { // If any of the prototypes is invalid, we do nothing. if (string.IsNullOrEmpty(Reagent) || string.IsNullOrEmpty(PuddlePrototype)) { return(ReactionResult.NoReaction); } // If we're not reacting on a tile, do nothing. if (holder is not TileAtmosphere tile) { return(ReactionResult.NoReaction); } // If we don't have enough moles of the specified gas, do nothing. if (mixture.GetMoles(GasId) < MolesPerUnit) { return(ReactionResult.NoReaction); } // Remove the moles from the mixture... mixture.AdjustMoles(GasId, -MolesPerUnit); var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex); tileRef.SpillAt(new Solution(Reagent, ReagentUnit.New(MolesPerUnit)), PuddlePrototype, sound: false); return(ReactionResult.Reacting); }
public void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length == 0) { shell.WriteError("Not enough arguments."); return; } var mapManager = IoCManager.Resolve <IMapManager>(); var atmosphereSystem = EntitySystem.Get <AtmosphereSystem>(); var mixture = new GasMixture(Atmospherics.CellVolume) { Temperature = Atmospherics.T20C }; mixture.AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard); mixture.AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard); foreach (var gid in args) { // I like offering detailed error messages, that's why I don't use one of the extension methods. if (!int.TryParse(gid, out var i) || i <= 0) { shell.WriteError($"Invalid grid ID \"{gid}\"."); continue; } var gridId = new GridId(i); if (!mapManager.TryGetGrid(gridId, out _)) { shell.WriteError($"Grid \"{i}\" doesn't exist."); continue; } foreach (var tile in atmosphereSystem.GetAllTileMixtures(gridId, true)) { tile.Clear(); atmosphereSystem.Merge(tile, mixture); tile.Temperature = mixture.Temperature; } } }
public void ScrubInto(GasMixture mixture, GasMixture destination, IReadOnlyCollection <Gas> filterGases) { var buffer = new GasMixture(mixture.Volume) { Temperature = mixture.Temperature }; foreach (var gas in filterGases) { buffer.AdjustMoles(gas, mixture.GetMoles(gas)); mixture.SetMoles(gas, 0f); } Merge(destination, buffer); }
public async Task TestMerge() { var server = StartServer(); await server.WaitIdleAsync(); var atmosphereSystem = server.ResolveDependency <IEntitySystemManager>().GetEntitySystem <AtmosphereSystem>(); server.Assert(() => { var a = new GasMixture(10f); var b = new GasMixture(10f); a.AdjustMoles(Gas.Oxygen, 50); b.AdjustMoles(Gas.Nitrogen, 50); // a now has 50 moles of oxygen Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); // b now has 50 moles of nitrogen Assert.That(b.TotalMoles, Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); atmosphereSystem.Merge(b, a); // b now has its contents and the contents of a Assert.That(b.TotalMoles, Is.EqualTo(100)); Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); // a should be the same, however. Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); }); await server.WaitIdleAsync(); }
public async Task TestMerge() { await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true }); var server = pairTracker.Pair.Server; var atmosphereSystem = server.ResolveDependency <IEntitySystemManager>().GetEntitySystem <AtmosphereSystem>(); await server.WaitAssertion(() => { var a = new GasMixture(10f); var b = new GasMixture(10f); a.AdjustMoles(Gas.Oxygen, 50); b.AdjustMoles(Gas.Nitrogen, 50); // a now has 50 moles of oxygen Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); // b now has 50 moles of nitrogen Assert.That(b.TotalMoles, Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); atmosphereSystem.Merge(b, a); // b now has its contents and the contents of a Assert.That(b.TotalMoles, Is.EqualTo(100)); Assert.That(b.GetMoles(Gas.Oxygen), Is.EqualTo(50)); Assert.That(b.GetMoles(Gas.Nitrogen), Is.EqualTo(50)); // a should be the same, however. Assert.That(a.TotalMoles, Is.EqualTo(50)); Assert.That(a.GetMoles(Gas.Oxygen), Is.EqualTo(50)); }); await pairTracker.CleanReturnAsync(); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder) { var energyReleased = 0f; var oldHeatCapacity = mixture.HeatCapacity; var temperature = mixture.Temperature; var location = holder as TileAtmosphere; // More phoron released at higher temperatures var temperatureScale = 0f; var superSaturation = false; if (temperature > Atmospherics.PhoronUpperTemperature) { temperatureScale = 1f; } else { temperatureScale = (temperature - Atmospherics.PhoronMinimumBurnTemperature) / (Atmospherics.PhoronUpperTemperature - Atmospherics.PhoronMinimumBurnTemperature); } if (temperatureScale > 0f) { var phoronBurnRate = 0f; var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale; if (mixture.GetMoles(Gas.Oxygen) / mixture.GetMoles(Gas.Phoron) > Atmospherics.SuperSaturationThreshold) { superSaturation = true; } if (mixture.GetMoles(Gas.Oxygen) > mixture.GetMoles(Gas.Phoron) * Atmospherics.PhoronOxygenFullburn) { phoronBurnRate = (mixture.GetMoles(Gas.Phoron) * temperatureScale) / Atmospherics.PhoronBurnRateDelta; } else { phoronBurnRate = (temperatureScale * (mixture.GetMoles(Gas.Oxygen) / Atmospherics.PhoronOxygenFullburn)) / Atmospherics.PhoronBurnRateDelta; } if (phoronBurnRate > Atmospherics.MinimumHeatCapacity) { phoronBurnRate = MathF.Min(MathF.Min(phoronBurnRate, mixture.GetMoles(Gas.Phoron)), mixture.GetMoles(Gas.Oxygen) / oxygenBurnRate); mixture.SetMoles(Gas.Phoron, mixture.GetMoles(Gas.Phoron) - phoronBurnRate); mixture.SetMoles(Gas.Oxygen, mixture.GetMoles(Gas.Oxygen) - (phoronBurnRate * oxygenBurnRate)); mixture.AdjustMoles(superSaturation ? Gas.Tritium : Gas.CarbonDioxide, phoronBurnRate); energyReleased += Atmospherics.FirePhoronEnergyReleased * (phoronBurnRate); mixture.ReactionResults[GasReaction.Fire] += (phoronBurnRate) * (1 + oxygenBurnRate); } } if (energyReleased > 0) { var newHeatCapacity = mixture.HeatCapacity; if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); } } if (location != null) { temperature = mixture.Temperature; if (temperature > Atmospherics.FireMinimumTemperatureToExist) { location.HotspotExpose(temperature, mixture.Volume); // TODO ATMOS Expose temperature all items on cell location.TemperatureExpose(mixture, temperature, mixture.Volume); } } return(mixture.ReactionResults[GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, GridTileLookupSystem gridTileLookup) { var energyReleased = 0f; var oldHeatCapacity = mixture.HeatCapacity; var temperature = mixture.Temperature; var location = holder as TileAtmosphere; // More plasma released at higher temperatures var temperatureScale = 0f; var superSaturation = false; if (temperature > Atmospherics.PlasmaUpperTemperature) { temperatureScale = 1f; } else { temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) / (Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature); } if (temperatureScale > 0f) { var plasmaBurnRate = 0f; var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale; if (mixture.GetMoles(Gas.Oxygen) / mixture.GetMoles(Gas.Plasma) > Atmospherics.SuperSaturationThreshold) { superSaturation = true; } if (mixture.GetMoles(Gas.Oxygen) > mixture.GetMoles(Gas.Plasma) * Atmospherics.PlasmaOxygenFullburn) { plasmaBurnRate = (mixture.GetMoles(Gas.Plasma) * temperatureScale) / Atmospherics.PlasmaBurnRateDelta; } else { plasmaBurnRate = (temperatureScale * (mixture.GetMoles(Gas.Oxygen) / Atmospherics.PlasmaOxygenFullburn)) / Atmospherics.PlasmaBurnRateDelta; } if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity) { plasmaBurnRate = MathF.Min(MathF.Min(plasmaBurnRate, mixture.GetMoles(Gas.Plasma)), mixture.GetMoles(Gas.Oxygen) / oxygenBurnRate); mixture.SetMoles(Gas.Plasma, mixture.GetMoles(Gas.Plasma) - plasmaBurnRate); mixture.SetMoles(Gas.Oxygen, mixture.GetMoles(Gas.Oxygen) - (plasmaBurnRate * oxygenBurnRate)); mixture.AdjustMoles(superSaturation ? Gas.Tritium : Gas.CarbonDioxide, plasmaBurnRate); energyReleased += Atmospherics.FirePlasmaEnergyReleased * (plasmaBurnRate); mixture.ReactionResults[GasReaction.Fire] += (plasmaBurnRate) * (1 + oxygenBurnRate); } } if (energyReleased > 0) { var newHeatCapacity = mixture.HeatCapacity; if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); } } if (location != null) { temperature = mixture.Temperature; if (temperature > Atmospherics.FireMinimumTemperatureToExist) { location.HotspotExpose(temperature, mixture.Volume); foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex, gridTileLookup)) { foreach (var temperatureExpose in entity.GetAllComponents <ITemperatureExpose>()) { temperatureExpose.TemperatureExpose(mixture, temperature, mixture.Volume); } } location.TemperatureExpose(mixture, temperature, mixture.Volume); } } return(mixture.ReactionResults[GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { var energyReleased = 0f; var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var temperature = mixture.Temperature; var location = holder as TileAtmosphere; mixture.ReactionResults[GasReaction.Fire] = 0; // More plasma released at higher temperatures. var temperatureScale = 0f; if (temperature > Atmospherics.PlasmaUpperTemperature) { temperatureScale = 1f; } else { temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) / (Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature); } if (temperatureScale > 0) { var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale; var plasmaBurnRate = 0f; var initialOxygenMoles = mixture.GetMoles(Gas.Oxygen); var initialPlasmaMoles = mixture.GetMoles(Gas.Plasma); // Supersaturation makes tritium. var supersaturation = initialOxygenMoles / initialPlasmaMoles > Atmospherics.SuperSaturationThreshold; if (initialOxygenMoles > initialPlasmaMoles * Atmospherics.PlasmaOxygenFullburn) { plasmaBurnRate = initialPlasmaMoles * temperatureScale / Atmospherics.PlasmaBurnRateDelta; } else { plasmaBurnRate = temperatureScale * (initialOxygenMoles / Atmospherics.PlasmaOxygenFullburn) / Atmospherics.PlasmaBurnRateDelta; } if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity) { plasmaBurnRate = MathF.Min(plasmaBurnRate, MathF.Min(initialPlasmaMoles, initialOxygenMoles / oxygenBurnRate)); mixture.SetMoles(Gas.Plasma, initialPlasmaMoles - plasmaBurnRate); mixture.SetMoles(Gas.Oxygen, initialOxygenMoles - plasmaBurnRate * oxygenBurnRate); mixture.AdjustMoles(supersaturation ? Gas.Tritium : Gas.CarbonDioxide, plasmaBurnRate); energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate; mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate); } } if (energyReleased > 0) { var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity; } } if (location != null) { var mixTemperature = mixture.Temperature; if (mixTemperature > Atmospherics.FireMinimumTemperatureToExist) { atmosphereSystem.HotspotExpose(location.GridIndex, location.GridIndices, mixTemperature, mixture.Volume); } } return(mixture.ReactionResults[GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction); }
public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, GridTileLookupSystem gridTileLookup) { var energyReleased = 0f; var oldHeatCapacity = mixture.HeatCapacity; var temperature = mixture.Temperature; var location = holder as TileAtmosphere; mixture.ReactionResults[GasReaction.Fire] = 0f; var burnedFuel = 0f; var initialTrit = mixture.GetMoles(Gas.Tritium); if (mixture.GetMoles(Gas.Oxygen) < initialTrit || Atmospherics.MinimumTritiumOxyburnEnergy > (temperature * oldHeatCapacity)) { burnedFuel = mixture.GetMoles(Gas.Oxygen) / Atmospherics.TritiumBurnOxyFactor; if (burnedFuel > initialTrit) { burnedFuel = initialTrit; } mixture.AdjustMoles(Gas.Tritium, -burnedFuel); } else { burnedFuel = initialTrit; mixture.SetMoles(Gas.Tritium, mixture.GetMoles(Gas.Tritium) * (1 - 1 / Atmospherics.TritiumBurnTritFactor)); mixture.AdjustMoles(Gas.Oxygen, -mixture.GetMoles(Gas.Tritium)); energyReleased += (Atmospherics.FireHydrogenEnergyReleased * burnedFuel * (Atmospherics.TritiumBurnTritFactor - 1)); } if (burnedFuel > 0) { energyReleased += (Atmospherics.FireHydrogenEnergyReleased * burnedFuel); // TODO ATMOS Radiation pulse here! // Conservation of mass is important. mixture.AdjustMoles(Gas.WaterVapor, burnedFuel); mixture.ReactionResults[GasReaction.Fire] += burnedFuel; } if (energyReleased > 0) { var newHeatCapacity = mixture.HeatCapacity; if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); } } if (location != null) { temperature = mixture.Temperature; if (temperature > Atmospherics.FireMinimumTemperatureToExist) { location.HotspotExpose(temperature, mixture.Volume); foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex, gridTileLookup)) { foreach (var temperatureExpose in entity.GetAllComponents <ITemperatureExpose>()) { temperatureExpose.TemperatureExpose(mixture, temperature, mixture.Volume); } } location.TemperatureExpose(mixture, temperature, mixture.Volume); } } return(mixture.ReactionResults[GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction); }
public async Task AirConsistencyTest() { var options = new ServerContentIntegrationOption { ExtraPrototypes = Prototypes }; var server = StartServerDummyTicker(options); server.Assert(() => { var mapManager = IoCManager.Resolve <IMapManager>(); var mapId = mapManager.CreateMap(); var entityManager = IoCManager.Resolve <IEntityManager>(); var human = entityManager.SpawnEntity("HumanBodyAndBloodstreamDummy", new MapCoordinates(Vector2.Zero, mapId)); Assert.That(human.TryGetComponent(out SharedBodyComponent body)); Assert.That(body.TryGetMechanismBehaviors(out List <LungBehavior> lungs)); Assert.That(lungs.Count, Is.EqualTo(1)); Assert.That(human.TryGetComponent(out BloodstreamComponent bloodstream)); var gas = new GasMixture(1); var originalOxygen = 2; var originalNitrogen = 8; var breathedPercentage = Atmospherics.BreathVolume / gas.Volume; gas.AdjustMoles(Gas.Oxygen, originalOxygen); gas.AdjustMoles(Gas.Nitrogen, originalNitrogen); var lung = lungs[0]; lung.Inhale(1, gas); var lungOxygen = originalOxygen * breathedPercentage; var lungNitrogen = originalNitrogen * breathedPercentage; Assert.That(bloodstream.Air.GetMoles(Gas.Oxygen), Is.EqualTo(lungOxygen)); Assert.That(bloodstream.Air.GetMoles(Gas.Nitrogen), Is.EqualTo(lungNitrogen)); var mixtureOxygen = originalOxygen - lungOxygen; var mixtureNitrogen = originalNitrogen - lungNitrogen; Assert.That(gas.GetMoles(Gas.Oxygen), Is.EqualTo(mixtureOxygen)); Assert.That(gas.GetMoles(Gas.Nitrogen), Is.EqualTo(mixtureNitrogen)); var lungOxygenBeforeExhale = lung.Air.GetMoles(Gas.Oxygen); var lungNitrogenBeforeExhale = lung.Air.GetMoles(Gas.Nitrogen); // Empty after it transfer to the bloodstream Assert.Zero(lungOxygenBeforeExhale); Assert.Zero(lungNitrogenBeforeExhale); lung.Exhale(1, gas); var lungOxygenAfterExhale = lung.Air.GetMoles(Gas.Oxygen); var exhaledOxygen = Math.Abs(lungOxygenBeforeExhale - lungOxygenAfterExhale); // Not completely empty Assert.Positive(lung.Air.Gases.Sum()); // Retains needed gas Assert.Positive(bloodstream.Air.GetMoles(Gas.Oxygen)); // Expels toxins Assert.Zero(bloodstream.Air.GetMoles(Gas.Nitrogen)); mixtureOxygen += exhaledOxygen; var finalTotalOxygen = gas.GetMoles(Gas.Oxygen) + bloodstream.Air.GetMoles(Gas.Oxygen) + lung.Air.GetMoles(Gas.Oxygen); // No ticks were run, metabolism doesn't run and so no oxygen is used up Assert.That(finalTotalOxygen, Is.EqualTo(originalOxygen)); Assert.That(gas.GetMoles(Gas.Oxygen), Is.EqualTo(mixtureOxygen).Within(0.000001f)); var finalTotalNitrogen = gas.GetMoles(Gas.Nitrogen) + bloodstream.Air.GetMoles(Gas.Nitrogen) + lung.Air.GetMoles(Gas.Nitrogen); // Nitrogen stays constant Assert.That(finalTotalNitrogen, Is.EqualTo(originalNitrogen).Within(0.000001f)); }); await server.WaitIdleAsync(); }
public async Task AirConsistencyTest() { var server = StartServerDummyTicker(); server.Assert(() => { var mapManager = IoCManager.Resolve <IMapManager>(); mapManager.CreateNewMapEntity(MapId.Nullspace); var entityManager = IoCManager.Resolve <IEntityManager>(); var human = entityManager.SpawnEntity("HumanMob_Content", MapCoordinates.Nullspace); Assert.True(human.TryGetComponent(out LungComponent lung)); Assert.True(human.TryGetComponent(out BloodstreamComponent bloodstream)); var gas = new GasMixture(1); var originalOxygen = 2; var originalNitrogen = 8; var breathedPercentage = Atmospherics.BreathPercentage; gas.AdjustMoles(Gas.Oxygen, originalOxygen); gas.AdjustMoles(Gas.Nitrogen, originalNitrogen); lung.Inhale(1, gas); var lungOxygen = originalOxygen * breathedPercentage; var lungNitrogen = originalNitrogen * breathedPercentage; Assert.That(bloodstream.Air.GetMoles(Gas.Oxygen), Is.EqualTo(lungOxygen)); Assert.That(bloodstream.Air.GetMoles(Gas.Nitrogen), Is.EqualTo(lungNitrogen)); var mixtureOxygen = originalOxygen - lungOxygen; var mixtureNitrogen = originalNitrogen - lungNitrogen; Assert.That(gas.GetMoles(Gas.Oxygen), Is.EqualTo(mixtureOxygen)); Assert.That(gas.GetMoles(Gas.Nitrogen), Is.EqualTo(mixtureNitrogen)); var lungOxygenBeforeExhale = lung.Air.GetMoles(Gas.Oxygen); var lungNitrogenBeforeExhale = lung.Air.GetMoles(Gas.Nitrogen); // Empty after it transfer to the bloodstream Assert.Zero(lungOxygenBeforeExhale); Assert.Zero(lungNitrogenBeforeExhale); lung.Exhale(1, gas); var lungOxygenAfterExhale = lung.Air.GetMoles(Gas.Oxygen); var exhaledOxygen = lungOxygenBeforeExhale - lungOxygenAfterExhale; // Not completely empty Assert.Positive(lung.Air.Gases.Sum()); // Retains needed gas Assert.Positive(bloodstream.Air.GetMoles(Gas.Oxygen)); // Expels toxins Assert.Zero(bloodstream.Air.GetMoles(Gas.Nitrogen)); mixtureOxygen += exhaledOxygen; var finalTotalOxygen = gas.GetMoles(Gas.Oxygen) + bloodstream.Air.GetMoles(Gas.Oxygen) + lung.Air.GetMoles(Gas.Oxygen); // No ticks were run, metabolism doesn't run and so no oxygen is used up Assert.That(finalTotalOxygen, Is.EqualTo(originalOxygen)); Assert.That(gas.GetMoles(Gas.Oxygen), Is.EqualTo(mixtureOxygen).Within(0.000001f)); var finalTotalNitrogen = gas.GetMoles(Gas.Nitrogen) + bloodstream.Air.GetMoles(Gas.Nitrogen) + lung.Air.GetMoles(Gas.Nitrogen); // Nitrogen stays constant Assert.That(finalTotalNitrogen, Is.EqualTo(originalNitrogen).Within(0.000001f)); }); await server.WaitIdleAsync(); }