public ReactionResult React(GasMixture mixture, IGasMixtureHolder?holder, AtmosphereSystem atmosphereSystem) { // 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 override void Initialize() { base.Initialize(); _atmosphereSystem = Get <AtmosphereSystem>(); _playerManager.PlayerStatusChanged += OnPlayerStatusChanged; }
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 override void Initialize(Node sourceNode) { base.Initialize(sourceNode); _atmosphereSystem = EntitySystem.Get <AtmosphereSystem>(); GridAtmos?.AddPipeNet(this); }
public override void Initialize() { base.Initialize(); SubscribeNetworkEvent <GasOverlayMessage>(HandleGasOverlayMessage); _mapManager.OnGridRemoved += OnGridRemoved; _atmosphereSystem = Get <AtmosphereSystem>(); for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { var overlay = _atmosphereSystem.GetOverlay(i); switch (overlay) { case SpriteSpecifier.Rsi animated: var rsi = _resourceCache.GetResource <RSIResource>(animated.RsiPath).RSI; var stateId = animated.RsiState; if (!rsi.TryGetState(stateId, out var state)) { continue; } _frames[i] = state.GetFrames(RSI.State.Direction.South); _frameDelays[i] = state.GetDelays(); _frameCounter[i] = 0; break; case SpriteSpecifier.Texture texture: _frames[i] = new[] { texture.Frame0() }; _frameDelays[i] = Array.Empty <float>(); break; case null: _frames[i] = Array.Empty <Texture>(); _frameDelays[i] = Array.Empty <float>(); break; } } var fire = _resourceCache.GetResource <RSIResource>(FireRsiPath).RSI; for (var i = 0; i < FireStates; i++) { if (!fire.TryGetState((i + 1).ToString(), out var state)) { throw new ArgumentOutOfRangeException($"Fire RSI doesn't have state \"{i}\"!"); } _fireFrames[i] = state.GetFrames(RSI.State.Direction.South); _fireFrameDelays[i] = state.GetDelays(); _fireFrameCounter[i] = 0; } var overlayManager = IoCManager.Resolve <IOverlayManager>(); if (!overlayManager.HasOverlay(nameof(GasTileOverlay))) { overlayManager.AddOverlay(new GasTileOverlay()); } }
public override void Initialize() { base.Initialize(); _atmosphereSystem = Get <AtmosphereSystem>(); _playerManager.PlayerStatusChanged += OnPlayerStatusChanged; _configManager.RegisterCVar("net.atmosdbgoverlaytickrate", 3.0f); }
public void Update(GasMixture air, float frameDelta, AtmosphereSystem atmosphereSystem) { // TODO: I'm coming for you next, TemperatureComponent... Fear me for I am death, destroyer of shitcode. if (_temperatureComponent != null) { var temperatureDelta = air.Temperature - _temperatureComponent.CurrentTemperature; var tileHeatCapacity = atmosphereSystem.GetHeatCapacity(air); var heat = temperatureDelta * (tileHeatCapacity * _temperatureComponent.HeatCapacity / (tileHeatCapacity + _temperatureComponent.HeatCapacity)); _temperatureComponent.ReceiveHeat(heat); _temperatureComponent.Update(); } }
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 void Update(GasMixture air, float frameDelta, AtmosphereSystem atmosphereSystem) { if (_temperatureComponent != null) { var temperatureDelta = air.Temperature - _temperatureComponent.CurrentTemperature; var tileHeatCapacity = atmosphereSystem.GetHeatCapacity(air); var heat = temperatureDelta * (tileHeatCapacity * _temperatureComponent.HeatCapacity / (tileHeatCapacity + _temperatureComponent.HeatCapacity)); _temperatureComponent.ReceiveHeat(heat); _temperatureComponent.Update(); } _barotraumaComponent?.Update(air.Pressure); _flammableComponent?.Update(air); }
public override void Initialize() { base.Initialize(); SubscribeNetworkEvent <AtmosDebugOverlayMessage>(HandleAtmosDebugOverlayMessage); _mapManager.OnGridRemoved += OnGridRemoved; _atmosphereSystem = Get <AtmosphereSystem>(); var overlayManager = IoCManager.Resolve <IOverlayManager>(); if (!overlayManager.HasOverlay(nameof(AtmosDebugOverlay))) { overlayManager.AddOverlay(new AtmosDebugOverlay()); } }
public override void Initialize() { base.Initialize(); _atmosSystem = EntitySystem.Get <AtmosphereSystem>(); if (!Owner.TryGetComponent <NodeContainerComponent>(out var container)) { JoinedGridAtmos?.RemovePipeNetDevice(this); Logger.Error($"{typeof(BaseSiphonComponent)} on entity {Owner.Uid} did not have a {nameof(NodeContainerComponent)}."); return; } _scrubberOutlet = container.Nodes.OfType <PipeNode>().FirstOrDefault(); if (_scrubberOutlet == null) { JoinedGridAtmos?.RemovePipeNetDevice(this); Logger.Error($"{typeof(BaseSiphonComponent)} on entity {Owner.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}."); return; } }
private void Scrub(AtmosphereSystem atmosphereSystem, GasVentScrubberComponent scrubber, AppearanceComponent?appearance, GasMixture?tile, PipeNode outlet) { // Cannot scrub if tile is null or air-blocked. if (tile == null) { return; } // Cannot scrub if pressure too high. if (outlet.Air.Pressure >= 50 * Atmospherics.OneAtmosphere) { return; } if (scrubber.PumpDirection == ScrubberPumpDirection.Scrubbing) { appearance?.SetData(ScrubberVisuals.State, scrubber.WideNet ? ScrubberState.WideScrub : ScrubberState.Scrub); var transferMoles = MathF.Min(1f, (scrubber.VolumeRate / tile.Volume) * tile.TotalMoles); // Take a gas sample. var removed = tile.Remove(transferMoles); // Nothing left to remove from the tile. if (MathHelper.CloseTo(removed.TotalMoles, 0f)) { return; } atmosphereSystem.ScrubInto(removed, outlet.Air, scrubber.FilterGases); // Remix the gases. atmosphereSystem.Merge(tile, removed); } else if (scrubber.PumpDirection == ScrubberPumpDirection.Siphoning) { appearance?.SetData(ScrubberVisuals.State, ScrubberState.Siphon); var transferMoles = tile.TotalMoles * (scrubber.VolumeRate / tile.Volume); var removed = tile.Remove(transferMoles); outlet.AssumeAir(removed); } }
private bool CheckMinerOperation(AtmosphereSystem atmosphereSystem, GasMinerComponent miner, [NotNullWhen(true)] out GasMixture?environment) { environment = atmosphereSystem.GetTileMixture(miner.Owner.Transform.Coordinates, true); // Space. if (atmosphereSystem.IsTileSpace(miner.Owner.Transform.Coordinates)) { miner.Broken = true; return(false); } // Air-blocked location. if (environment == null) { miner.Broken = true; return(false); } // External pressure above threshold. if (!float.IsInfinity(miner.MaxExternalPressure) && environment.Pressure > miner.MaxExternalPressure - miner.SpawnAmount * miner.SpawnTemperature * Atmospherics.R / environment.Volume) { miner.Broken = true; return(false); } // External gas amount above threshold. if (!float.IsInfinity(miner.MaxExternalAmount) && environment.TotalMoles > miner.MaxExternalAmount) { miner.Broken = true; return(false); } miner.Broken = false; return(true); }
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, AtmosphereSystem atmosphereSystem) { var energyReleased = 0f; var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); 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 = atmosphereSystem.GetHeatCapacity(mixture); if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) { mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); } } if (location != null) { temperature = mixture.Temperature; if (temperature > Atmospherics.FireMinimumTemperatureToExist) { atmosphereSystem.HotspotExpose(location.GridIndex, location.GridIndices, 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; 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 = atmosphereSystem.GetHeatCapacity(mixture); 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)) { 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); }