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, Vector3 tilePos, Matrix matrix) { var oldHeatCap = gasMix.WholeHeatCapacity; var reactionEnergy = 0f; var initialPlasma = gasMix.GetMoles(Gas.Plasma); var initialCarbon = gasMix.GetMoles(Gas.CarbonDioxide); var scaleFactor = gasMix.Volume / Mathf.PI; var toroidalSize = (2 * Mathf.PI) + ((Mathf.PI / 180) * Mathf.Atan((gasMix.Volume - AtmosDefines.TOROID_VOLUME_BREAKEVEN) / AtmosDefines.TOROID_VOLUME_BREAKEVEN)); var gasPower = 0f; foreach (var gas in Gas.All) { gasPower += gas.FusionPower * gasMix.GetMoles(gas); } var instability = Mathf.Pow(gasPower * AtmosDefines.INSTABILITY_GAS_POWER_FACTOR, 2) % toroidalSize; var plasma = (initialPlasma - AtmosDefines.FUSION_MOLE_THRESHOLD) / scaleFactor; var carbon = (initialCarbon - AtmosDefines.FUSION_MOLE_THRESHOLD) / scaleFactor; plasma = (plasma - instability * Mathf.Sin(carbon)) % toroidalSize; carbon = (carbon - plasma) % toroidalSize; gasMix.SetGas(Gas.Plasma, plasma * scaleFactor + AtmosDefines.FUSION_MOLE_THRESHOLD); gasMix.SetGas(Gas.CarbonDioxide, carbon * scaleFactor + AtmosDefines.FUSION_MOLE_THRESHOLD); var deltaPlasma = initialPlasma - gasMix.GetMoles(Gas.Plasma); reactionEnergy += deltaPlasma * AtmosDefines.PLASMA_BINDING_ENERGY; if (instability < AtmosDefines.FUSION_INSTABILITY_ENDOTHERMALITY) { reactionEnergy = Mathf.Max(reactionEnergy, 0); } else if (reactionEnergy < 0) { reactionEnergy *= Mathf.Pow(instability - AtmosDefines.FUSION_INSTABILITY_ENDOTHERMALITY, 5); } if (gasMix.InternalEnergy + reactionEnergy < 0) { gasMix.SetGas(Gas.Plasma, initialPlasma); gasMix.SetGas(Gas.CarbonDioxide, initialCarbon); return; } gasMix.RemoveGas(Gas.Tritium, AtmosDefines.FUSION_TRITIUM_MOLES_USED); if (reactionEnergy > 0) { gasMix.AddGas(Gas.Oxygen, AtmosDefines.FUSION_TRITIUM_MOLES_USED * (reactionEnergy * AtmosDefines.FUSION_TRITIUM_CONVERSION_COEFFICIENT)); gasMix.AddGas(Gas.NitrousOxide, AtmosDefines.FUSION_TRITIUM_MOLES_USED * (reactionEnergy * AtmosDefines.FUSION_TRITIUM_CONVERSION_COEFFICIENT)); } if (reactionEnergy != 0) { RadiationManager.Instance.RequestPulse(matrix, tilePos.RoundToInt(), Mathf.Max((AtmosDefines.FUSION_RAD_COEFFICIENT / instability) + AtmosDefines.FUSION_RAD_MAX, 0), rnd.Next(Int32.MinValue, Int32.MaxValue)); var newHeatCap = gasMix.WholeHeatCapacity; if (newHeatCap > 0.0003f && (gasMix.Temperature <= AtmosDefines.FUSION_MAXIMUM_TEMPERATURE || reactionEnergy <= 0)) { gasMix.SetTemperature(Mathf.Clamp(((gasMix.Temperature * oldHeatCap + reactionEnergy) / newHeatCap), 2.7f, Single.PositiveInfinity)); } } }
public void React(GasMix gasMix, MetaDataNode node) { var energyReleased = 0f; var temperature = gasMix.Temperature; var oldHeatCapacity = gasMix.WholeHeatCapacity; //More plasma released at higher temperatures float temperatureScale; if (temperature > AtmosDefines.PLASMA_UPPER_TEMPERATURE) { temperatureScale = 1; } else { //Will be decimal until PLASMA_UPPER_TEMPERATURE is reached temperatureScale = (temperature - AtmosDefines.PLASMA_MINIMUM_BURN_TEMPERATURE) / (AtmosDefines.PLASMA_UPPER_TEMPERATURE - AtmosDefines.PLASMA_MINIMUM_BURN_TEMPERATURE); } if (temperatureScale > 0) { //Handle plasma burning var oxygenMoles = gasMix.GetMoles(Gas.Oxygen); var plasmaMoles = gasMix.GetMoles(Gas.Plasma); float plasmaBurnRate; var oxygenBurnRate = AtmosDefines.OXYGEN_BURN_RATE_BASE - temperatureScale; var superSaturation = oxygenMoles / plasmaMoles > AtmosDefines.SUPER_SATURATION_THRESHOLD; if (oxygenMoles > plasmaMoles * AtmosDefines.PLASMA_OXYGEN_FULLBURN) { plasmaBurnRate = (plasmaMoles * temperatureScale) / AtmosDefines.PLASMA_BURN_RATE_DELTA; } else { plasmaBurnRate = (temperatureScale * (oxygenMoles / AtmosDefines.PLASMA_OXYGEN_FULLBURN)) / AtmosDefines.PLASMA_BURN_RATE_DELTA; } if (plasmaBurnRate > AtmosConstants.MINIMUM_HEAT_CAPACITY) { //Ensures matter is conserved properly plasmaBurnRate = Mathf.Min(plasmaBurnRate, plasmaMoles, oxygenMoles / oxygenBurnRate); gasMix.SetGas(Gas.Plasma, plasmaMoles - plasmaBurnRate); gasMix.SetGas(Gas.Oxygen, oxygenMoles - (plasmaBurnRate * oxygenBurnRate)); if (superSaturation) { gasMix.AddGas(Gas.Tritium, plasmaBurnRate); } else { gasMix.AddGas(Gas.CarbonDioxide, plasmaBurnRate * 0.75f); gasMix.AddGas(Gas.WaterVapor, plasmaBurnRate * 0.25f); } energyReleased += AtmosDefines.FIRE_PLASMA_ENERGY_RELEASED * plasmaBurnRate; } } if (energyReleased > 0) { var newHeatCapacity = gasMix.WholeHeatCapacity; if (newHeatCapacity > AtmosConstants.MINIMUM_HEAT_CAPACITY) { gasMix.SetTemperature((gasMix.Temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); } } //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); } }