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 ReactionResult React(GasMixture mixture, IGasMixtureHolder holder, GridTileLookupSystem gridLookup) { var result = ReactionResult.NoReaction; foreach (var effect in _effects) { result |= effect.React(mixture, holder, gridLookup); } return(result); }
public TileAtmosphere(GridAtmosphereComponent atmosphereComponent, GridId gridIndex, Vector2i gridIndices, GasMixture mixture = null, bool immutable = false) { IoCManager.InjectDependencies(this); _gridAtmosphereComponent = atmosphereComponent; _gridTileLookupSystem = _entityManager.EntitySysManager.GetEntitySystem<GridTileLookupSystem>(); GridIndex = gridIndex; GridIndices = gridIndices; Air = mixture; if(immutable) Air?.MarkImmutable(); }
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, 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); }