Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }