示例#1
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.Temperature / 3731.5f, gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.CarbonDioxide), gasMix.GetMoles(Gas.BZ));

            var energyUsed = reactionEfficiency * 100;

            if (gasMix.GetMoles(Gas.Plasma) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.CarbonDioxide) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0)
            {
                //No reaction
                return(0f);
            }

            gasMix.RemoveGas(Gas.Plasma, 5 * reactionEfficiency);
            gasMix.RemoveGas(Gas.CarbonDioxide, reactionEfficiency);
            gasMix.RemoveGas(Gas.BZ, 0.25f * reactionEfficiency);

            gasMix.AddGas(Gas.Freon, reactionEfficiency * 2);

            if (energyUsed > 0)
            {
                gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f));
            }

            return(0f);
        }
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.Temperature / 37315, gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen));

            var energyUsed = reactionEfficiency * AtmosDefines.NITRYL_FORMATION_ENERGY;

            if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0)
            {
                //No reaction
                return;
            }

            gasMix.RemoveGas(Gas.Oxygen, 2 * reactionEfficiency);
            gasMix.RemoveGas(Gas.Nitrogen, reactionEfficiency);
            gasMix.RemoveGas(Gas.BZ, 0.05f * reactionEfficiency);

            gasMix.AddGas(Gas.Nitryl, reactionEfficiency);

            if (energyUsed > 0)
            {
                gasMix.SetTemperature(
                    Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity,
                              AtmosDefines.SPACE_TEMPERATURE));
            }
        }
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.Temperature / 3731.5f, gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.CarbonDioxide), gasMix.GetMoles(Gas.BZ));

            var energyUsed = reactionEfficiency * 100;

            if (gasMix.GetMoles(Gas.Plasma) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.CarbonDioxide) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0)
            {
                //No reaction
                return;
            }

            gasMix.RemoveGas(Gas.Plasma, 5 * reactionEfficiency);
            gasMix.RemoveGas(Gas.CarbonDioxide, reactionEfficiency);
            gasMix.RemoveGas(Gas.BZ, 0.25f * reactionEfficiency);

            gasMix.AddGas(Gas.Freon, reactionEfficiency * 2);

            if (energyUsed > 0)
            {
                gasMix.SetTemperature(
                    Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity,
                              AtmosDefines.SPACE_TEMPERATURE));
            }
        }
示例#4
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.Temperature / 37315, gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen));

            var energyUsed = reactionEfficiency * AtmosDefines.NITRYL_FORMATION_ENERGY;

            if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.BZ) - reactionEfficiency < 0)
            {
                //No reaction
                return(0f);
            }

            gasMix.RemoveGas(Gas.Oxygen, 2 * reactionEfficiency);
            gasMix.RemoveGas(Gas.Nitrogen, reactionEfficiency);
            gasMix.RemoveGas(Gas.BZ, 0.05f * reactionEfficiency);

            gasMix.AddGas(Gas.Nitryl, reactionEfficiency);

            if (energyUsed > 0)
            {
                gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f));
            }

            return(0f);
        }
示例#5
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.GetMoles(Gas.Oxygen), gasMix.GetMoles(Gas.Nitrogen));

            var energyUsed = reactionEfficiency * AtmosDefines.NITROUS_FORMATION_ENERGY;

            if (gasMix.GetMoles(Gas.Oxygen) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - reactionEfficiency < 0)
            {
                //No reaction
                return;
            }

            if (gasMix.Temperature > 250f)
            {
                //No reaction
                return;
            }

            gasMix.RemoveGas(Gas.Oxygen, reactionEfficiency);
            gasMix.RemoveGas(Gas.Nitrogen, 2 * reactionEfficiency);

            gasMix.AddGas(Gas.NitrousOxide, reactionEfficiency);

            if (energyUsed > 0)
            {
                gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f));
            }
        }
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var heatScale = Mathf.Min(gasMix.Temperature / AtmosDefines.STIMULUM_HEAT_SCALE, gasMix.GetMoles(Gas.Tritium), gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Nitryl));

            var stimEnergyChange = heatScale + AtmosDefines.STIMULUM_FIRST_RISE * Mathf.Pow(heatScale, 2) -
                                   AtmosDefines.STIMULUM_FIRST_DROP * Mathf.Pow(heatScale, 3) +
                                   AtmosDefines.STIMULUM_SECOND_RISE * Mathf.Pow(heatScale, 4) -
                                   AtmosDefines.STIMULUM_ABSOLUTE_DROP * Mathf.Pow(heatScale, 5);

            if (gasMix.GetMoles(Gas.Tritium) - heatScale < 0 || gasMix.GetMoles(Gas.Plasma) - heatScale < 0 || gasMix.GetMoles(Gas.Nitryl) - heatScale < 0)
            {
                //No reaction
                return(0f);
            }

            gasMix.AddGas(Gas.Stimulum, heatScale / 10f);

            gasMix.RemoveGas(Gas.Tritium, heatScale);
            gasMix.RemoveGas(Gas.Plasma, heatScale);
            gasMix.RemoveGas(Gas.Nitryl, heatScale);

            gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap + stimEnergyChange) / gasMix.WholeHeatCapacity, 2.7f));

            return(0f);
        }
示例#7
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);
        }
示例#8
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            if (gasMix.Temperature > AtmosDefines.WATER_VAPOR_FREEZE)
            {
                return;
            }

            if (gasMix.GetMoles(Gas.WaterVapor) < 2f)
            {
                //Not enough moles to freeze
                return;
            }

            var numberOfIceToSpawn = (int)Mathf.Floor(gasMix.GetMoles(Gas.WaterVapor) / 2f);

            //Stack size of ice is 50
            if (numberOfIceToSpawn > 50)
            {
                numberOfIceToSpawn = 50;
            }

            if (numberOfIceToSpawn < 1)
            {
                return;
            }

            SpawnSafeThread.SpawnPrefab(tilePos, AtmosManager.Instance.iceShard, amountIfStackable: numberOfIceToSpawn);

            gasMix.RemoveGas(Gas.WaterVapor, numberOfIceToSpawn * 2f);
        }
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var heatScale = Mathf.Min(gasMix.Temperature / AtmosDefines.STIMULUM_HEAT_SCALE,
                                      gasMix.GetMoles(Gas.Tritium), gasMix.GetMoles(Gas.Plasma), gasMix.GetMoles(Gas.Nitryl));

            var stimEnergyChange = heatScale + AtmosDefines.STIMULUM_FIRST_RISE * Mathf.Pow(heatScale, 2) -
                                   AtmosDefines.STIMULUM_FIRST_DROP * Mathf.Pow(heatScale, 3) +
                                   AtmosDefines.STIMULUM_SECOND_RISE * Mathf.Pow(heatScale, 4) -
                                   AtmosDefines.STIMULUM_ABSOLUTE_DROP * Mathf.Pow(heatScale, 5);

            if (gasMix.GetMoles(Gas.Tritium) - heatScale < 0 || gasMix.GetMoles(Gas.Nitryl) - heatScale < 0)
            {
                //No reaction
                return;
            }

            gasMix.AddGas(Gas.Stimulum, heatScale / 10f);

            gasMix.RemoveGas(Gas.Tritium, heatScale);
            gasMix.RemoveGas(Gas.Nitryl, heatScale);

            gasMix.SetTemperature(
                Mathf.Max((gasMix.Temperature * oldHeatCap + stimEnergyChange) / gasMix.WholeHeatCapacity,
                          AtmosDefines.SPACE_TEMPERATURE));
        }
示例#10
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            var energyReleased = 0f;
            var oldHeatCap     = gasMix.WholeHeatCapacity;

            var temperatureScale = 1f;

            if (gasMix.Temperature < AtmosDefines.FREON_LOWER_TEMPERATURE)
            {
                temperatureScale = 0;
            }
            else
            {
                temperatureScale = (AtmosDefines.FREON_MAXIMUM_BURN_TEMPERATURE - gasMix.Temperature) / (AtmosDefines.FREON_MAXIMUM_BURN_TEMPERATURE - AtmosDefines.FREON_LOWER_TEMPERATURE);
            }

            if (temperatureScale >= 0)
            {
                var oxygenBurnRate = AtmosDefines.OXYGEN_BURN_RATE_BASE - temperatureScale;

                var freonBurnRate = 0f;

                if (gasMix.GetMoles(Gas.Oxygen) > gasMix.GetMoles(Gas.Freon) * AtmosDefines.FREON_OXYGEN_FULLBURN)
                {
                    freonBurnRate = gasMix.GetMoles(Gas.Freon) * temperatureScale /
                                    AtmosDefines.FREON_BURN_RATE_DELTA;
                }
                else
                {
                    freonBurnRate = (temperatureScale * (gasMix.GetMoles(Gas.Oxygen) / AtmosDefines.FREON_OXYGEN_FULLBURN) / AtmosDefines.FREON_BURN_RATE_DELTA);
                }

                if (freonBurnRate > 0.0001f)
                {
                    freonBurnRate = Mathf.Min(freonBurnRate, gasMix.GetMoles(Gas.Freon), gasMix.GetMoles(Gas.Oxygen));

                    gasMix.RemoveGas(Gas.Freon, freonBurnRate);
                    gasMix.RemoveGas(Gas.Oxygen, freonBurnRate * oxygenBurnRate);

                    gasMix.AddGas(Gas.CarbonDioxide, freonBurnRate);

                    if (gasMix.Temperature < 160 && gasMix.Temperature > 120 && rnd.Next(0, 2) == 0)
                    {
                        SpawnSafeThread.SpawnPrefab(tilePos, AtmosManager.Instance.hotIce);
                    }

                    energyReleased += AtmosDefines.FIRE_FREON_ENERGY_RELEASED * freonBurnRate;
                }
            }

            if (energyReleased < 0)
            {
                var newHeatCap = gasMix.WholeHeatCapacity;
                if (newHeatCap > 0.0003f)
                {
                    gasMix.SetTemperature((gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap);
                }
            }
        }
示例#11
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            float consumed = 0;

            float temperature = gasMix.Temperature;

            float BurnRate = GetOxygenContact(gasMix);

            //Logger.Log(BurnRate.ToString() + "BurnRate");
            if (BurnRate > 0)
            {
                var superSaturated = false;

                float MolesPlasmaBurnt = gasMix.GetMoles(Gas.Plasma) * Reactions.BurningDelta * BurnRate;
                if (MolesPlasmaBurnt * 2 > gasMix.GetMoles(Gas.Oxygen))
                {
                    MolesPlasmaBurnt = (gasMix.GetMoles(Gas.Oxygen) * Reactions.BurningDelta * BurnRate) / 2;
                }

                if (MolesPlasmaBurnt < 0)
                {
                    return(0);
                }

                if (gasMix.GetMoles(Gas.Oxygen) / gasMix.GetMoles(Gas.Plasma) > AtmosDefines.SUPER_SATURATION_THRESHOLD)
                {
                    superSaturated = true;
                }

                gasMix.RemoveGas(Gas.Plasma, MolesPlasmaBurnt);
                if (gasMix.Gases[Gas.Plasma] < 0)
                {
                    gasMix.Gases[Gas.Plasma] = 0;
                }

                gasMix.RemoveGas(Gas.Oxygen, MolesPlasmaBurnt * 2);
                if (gasMix.Gases[Gas.Oxygen] < 0)
                {
                    gasMix.Gases[Gas.Oxygen] = 0;
                }
                var TotalmolestoCO2 = MolesPlasmaBurnt + (MolesPlasmaBurnt * 2);

                if (superSaturated)
                {
                    gasMix.AddGas(Gas.Tritium, TotalmolestoCO2 / 3);
                }
                else
                {
                    gasMix.AddGas(Gas.CarbonDioxide, TotalmolestoCO2 / 3);
                }

                float heatCapacity = gasMix.WholeHeatCapacity;
                gasMix.SetTemperature((temperature * heatCapacity + (Reactions.EnergyPerMole * TotalmolestoCO2)) / gasMix.WholeHeatCapacity);
                consumed = TotalmolestoCO2;
            }
            return(consumed);
        }
 public static bool CanHoldHotspot(GasMix gasMix)
 {
     if (gasMix.Temperature > Reactions.PlasmaMaintainFire && gasMix.GetMoles(Gas.Plasma) > 0.1f &&
         gasMix.GetMoles(Gas.Oxygen) > 0.1f)
     {
         if (GetOxygenContact(gasMix) > Reactions.MinimumOxygenContact)
         {
             return(true);
         }
     }
     return(false);
 }
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var energyReleased = 0f;
            var oldHeatCap     = gasMix.WholeHeatCapacity;
            var burnedFuel     = 0f;

            if (gasMix.GetMoles(Gas.Oxygen) < gasMix.GetMoles(Gas.Tritium) || AtmosDefines.MINIMUM_TRIT_OXYBURN_ENERGY > gasMix.InternalEnergy)
            {
                burnedFuel = gasMix.GetMoles(Gas.Oxygen) / AtmosDefines.TRITIUM_BURN_OXY_FACTOR;

                gasMix.RemoveGas(Gas.Tritium, burnedFuel);
                gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_OXY_FACTOR);

                energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_WEAK * burnedFuel;
            }
            else
            {
                burnedFuel = gasMix.GetMoles(Gas.Tritium);

                gasMix.RemoveGas(Gas.Tritium, burnedFuel / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR);
                gasMix.RemoveGas(Gas.Oxygen, burnedFuel);

                gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR);

                energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_RELEASED * burnedFuel;
            }

            if (burnedFuel != 0)
            {
                if (rnd.Next(0, 10) == 0 && burnedFuel > AtmosDefines.TRITIUM_MINIMUM_RADIATION_ENERGY)
                {
                    RadiationManager.Instance.RequestPulse(node.Position.ToWorld(node.PositionMatrix).RoundToInt(),
                                                           energyReleased / AtmosDefines.TRITIUM_BURN_RADIOACTIVITY_FACTOR,
                                                           rnd.Next(Int32.MinValue, Int32.MaxValue));
                }
            }

            if (energyReleased > 0)
            {
                var newHeatCap = gasMix.WholeHeatCapacity;
                if (newHeatCap > 0.0003f)
                {
                    gasMix.SetTemperature((gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap);
                }
            }

            //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);
            }
        }
示例#14
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            if (gasMix.GetMoles(Gas.WaterVapor) != 0 && gasMix.GetMoles(Gas.WaterVapor) / gasMix.Moles > 0.1)
            {
                //No reaction
                return;
            }

            var cleanedAir = Mathf.Min(gasMix.GetMoles(Gas.Miasma), 20 + (gasMix.Temperature - 373.15f - 70) / 20);

            gasMix.RemoveGas(Gas.Miasma, cleanedAir);

            gasMix.AddGas(Gas.Oxygen, cleanedAir);

            gasMix.SetTemperature(gasMix.Temperature + cleanedAir * 0.002f);
        }
示例#15
0
        private static bool ReactionMoleCheck(GasReactions gasReaction, GasMix gasMix)
        {
            foreach (var data in gasReaction.GasReactionData)
            {
                if (gasMix.GetMoles(data.Key) == 0)
                {
                    return(true);
                }

                if (gasMix.GetMoles(data.Key) < data.Value.minimumMolesToReact)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#16
0
 public bool Satisfies(GasMix gasMix)
 {
     if (gasMix.Temperature > Reactions.PlasmaMaintainFire && gasMix.GetMoles(Gas.Plasma) > 0.1f &&
         gasMix.GetMoles(Gas.Oxygen) > 0.1f)
     {
         if (GetOxygenContact(gasMix) > Reactions.MinimumOxygenContact)
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     else
     {
         return(false);
     }
 }
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            if (gasMix.Temperature <= AtmosDefines.WATER_VAPOR_FREEZE)
            {
                if (gasMix.GetMoles(Gas.WaterVapor) < 2f)
                {
                    //Not enough moles to freeze
                    return;
                }

                var numberOfIceToSpawn = Mathf.Floor(gasMix.GetMoles(Gas.WaterVapor) / 2f);

                for (var i = 0; i < numberOfIceToSpawn; i++)
                {
                    SpawnSafeThread.SpawnPrefab(tilePos, AtmosManager.Instance.iceShard);
                }

                gasMix.RemoveGas(Gas.WaterVapor, numberOfIceToSpawn * 2f);
            }
        }
示例#18
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(gasMix.GetMoles(Gas.Nitrogen) + gasMix.GetMoles(Gas.Tritium) / 100, gasMix.GetMoles(Gas.Tritium) / 10, gasMix.GetMoles(Gas.Nitrogen) / 20);

            var energyUsed = reactionEfficiency * (AtmosDefines.NOBLIUM_FORMATION_ENERGY / Mathf.Max(gasMix.GetMoles(Gas.BZ), 1f));

            if (gasMix.GetMoles(Gas.Tritium) - 10 * reactionEfficiency < 0 || gasMix.GetMoles(Gas.Nitrogen) - 20 * reactionEfficiency < 0)
            {
                //No reaction
                return;
            }

            gasMix.RemoveGas(Gas.Tritium, 10 * reactionEfficiency);
            gasMix.RemoveGas(Gas.Nitrogen, 20 * reactionEfficiency);

            gasMix.AddGas(Gas.HyperNoblium, reactionEfficiency);

            gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap - energyUsed) / gasMix.WholeHeatCapacity, 2.7f));
        }
示例#19
0
        public void React(GasMix gasMix, MetaDataNode node)
        {
            var waterMoles = gasMix.GetMoles(Gas.WaterVapor);

            if (waterMoles != 0 && waterMoles / gasMix.Moles > 0.1)
            {
                //No reaction
                return;
            }

            var cleanedAir =
                Mathf.Min(
                    gasMix.GetMoles(Gas.Miasma),
                    20 + (gasMix.Temperature - AtmosDefines.FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20);

            gasMix.RemoveGas(Gas.Miasma, cleanedAir);

            gasMix.AddGas(Gas.Oxygen, cleanedAir);

            gasMix.SetTemperature(gasMix.Temperature + cleanedAir * 0.002f);
        }
示例#20
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var reactionEfficiency = Mathf.Min(
                //More efficient at less than 10 Kpa
                (float)(1 / ((gasMix.Pressure / (0.1 * 101.325))))
                * (Mathf.Max(gasMix.GetMoles(Gas.Plasma) * gasMix.GetMoles(Gas.NitrousOxide), 1f)),

                gasMix.GetMoles(Gas.NitrousOxide),
                gasMix.GetMoles(Gas.Plasma) / 2);

            var energyReleased = 2 * reactionEfficiency * AtmosDefines.FIRE_CARBON_ENERGY_RELEASED;

            if (gasMix.GetMoles(Gas.NitrousOxide) - reactionEfficiency < 0 || gasMix.GetMoles(Gas.Plasma) - 2 * reactionEfficiency < 0 || energyReleased <= 0)
            {
                //No reaction
                return;
            }

            gasMix.AddGas(Gas.BZ, reactionEfficiency);

            gasMix.RemoveGas(Gas.NitrousOxide, reactionEfficiency);
            gasMix.RemoveGas(Gas.Plasma, 2 * reactionEfficiency);

            gasMix.SetTemperature(Mathf.Max((gasMix.Temperature * oldHeatCap + energyReleased) / gasMix.WholeHeatCapacity, 2.7f));
        }
示例#21
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            if (gasMix.Temperature <= AtmosDefines.WATER_VAPOR_FREEZE)
            {
                if (gasMix.GetMoles(Gas.WaterVapor) < 2f)
                {
                    //Not enough moles to freeze
                    return(0f);
                }

                var numberOfIceToSpawn = Mathf.Floor(gasMix.GetMoles(Gas.WaterVapor) / 2f);

                for (var i = 0; i < numberOfIceToSpawn; i++)
                {
                    Spawn.ServerPrefab(AtmosManager.Instance.iceShard, tilePos, MatrixManager.GetDefaultParent(tilePos, true));
                }

                gasMix.RemoveGas(Gas.WaterVapor, numberOfIceToSpawn * 2f);
            }

            return(0f);
        }
示例#22
0
        public void ExposeHotspot(Vector3Int localPosition, float temperature, float volume)
        {
            if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null)
            {
                // TODO soh?
                hotspots[localPosition].Hotspot.UpdateValues(volume * 25, temperature);
            }
            else
            {
                Profiler.BeginSample("MarkForAddition");
                MetaDataNode node   = metaDataLayer.Get(localPosition);
                GasMix       gasMix = node.GasMix;

                if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 &&
                    temperature > Reactions.PlasmaMaintainFire)
                {
                    // igniting
                    //addition will be done later in Update
                    hotspotsToAdd.Add(new Hotspot(node, temperature, volume * 25));
                }

                Profiler.EndSample();
            }

            if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null)
            {
                //expose everything on this tile
                Expose(localPosition, localPosition);

                //expose impassable things on the adjacent tile
                Expose(localPosition, localPosition + Vector3Int.right);
                Expose(localPosition, localPosition + Vector3Int.left);
                Expose(localPosition, localPosition + Vector3Int.up);
                Expose(localPosition, localPosition + Vector3Int.down);
            }
        }
示例#23
0
        private bool IsAllowedHotSpot(MetaDataNode node, float exposeTemperature = -1f)
        {
            //Only need to check stuff which has nodes as we are checking gas contents afterwards
            if (node == null)
            {
                return(false);
            }

            GasMix gasMix = node.GasMix;

            if (exposeTemperature < 0)
            {
                exposeTemperature = gasMix.Temperature;
            }

            //Minimum temperature requirement
            if (exposeTemperature < AtmosDefines.FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
            {
                return(false);
            }

            //Minimum oxygen requirement
            if (gasMix.GetMoles(Gas.Oxygen) < 0.5f)
            {
                return(false);
            }

            //Minimum plasma/tritium requirement
            if (gasMix.GetMoles(Gas.Plasma) < 0.5f && gasMix.GetMoles(Gas.Tritium) < 0.5f)
            {
                return(false);
            }

            //Passed all checks, this position is allowed a hotspot
            return(true);
        }
示例#24
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            var energyReleased = 0f;
            var oldHeatCap     = gasMix.WholeHeatCapacity;

            var burnedFuel = 0f;

            if (gasMix.GetMoles(Gas.Oxygen) < gasMix.GetMoles(Gas.Tritium) || AtmosDefines.MINIMUM_TRIT_OXYBURN_ENERGY > gasMix.InternalEnergy)
            {
                burnedFuel = gasMix.GetMoles(Gas.Oxygen) / AtmosDefines.TRITIUM_BURN_OXY_FACTOR;
                gasMix.RemoveGas(Gas.Tritium, burnedFuel);
            }
            else
            {
                burnedFuel = gasMix.GetMoles(Gas.Tritium) * AtmosDefines.TRITIUM_BURN_TRIT_FACTOR;
                gasMix.RemoveGas(Gas.Tritium, gasMix.GetMoles(Gas.Tritium) / AtmosDefines.TRITIUM_BURN_TRIT_FACTOR);
                gasMix.RemoveGas(Gas.Oxygen, gasMix.GetMoles(Gas.Tritium));
            }

            if (burnedFuel != 0)
            {
                energyReleased += AtmosDefines.FIRE_HYDROGEN_ENERGY_RELEASED * burnedFuel;

                if (Random.Range(0, 10) == 0 && burnedFuel > AtmosDefines.TRITIUM_MINIMUM_RADIATION_ENERGY)
                {
                    RadiationManager.Instance.RequestPulse(MatrixManager.AtPoint(tilePos.RoundToInt(), true).Matrix, tilePos.RoundToInt(), energyReleased / AtmosDefines.TRITIUM_BURN_RADIOACTIVITY_FACTOR, Random.Range(Int32.MinValue, Int32.MaxValue));
                }

                gasMix.AddGas(Gas.WaterVapor, burnedFuel / AtmosDefines.TRITIUM_BURN_OXY_FACTOR);
            }

            if (energyReleased > 0)
            {
                var newHeatCap = gasMix.WholeHeatCapacity;
                if (newHeatCap > 0.0003f)
                {
                    gasMix.SetTemperature((gasMix.Temperature * oldHeatCap + energyReleased) / newHeatCap);
                }
            }

            return(0f);
        }
示例#25
0
        public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix)
        {
            var oldHeatCap = gasMix.WholeHeatCapacity;

            var burnedFuel = 0f;

            burnedFuel = Mathf.Max(0f, 0.00002f * (gasMix.Temperature - (0.00001f * Mathf.Pow(gasMix.Temperature, 2)))) * gasMix.GetMoles(Gas.NitrousOxide);
            gasMix.RemoveGas(Gas.NitrousOxide, burnedFuel);

            if (burnedFuel != 0)
            {
                var energyReleased = AtmosDefines.N2O_DECOMPOSITION_ENERGY_RELEASED * burnedFuel;

                gasMix.AddGas(Gas.Oxygen, burnedFuel / 2f);
                gasMix.AddGas(Gas.Nitrogen, burnedFuel);

                var newHeatCap = gasMix.WholeHeatCapacity;
                if (newHeatCap > 0.0003f)
                {
                    gasMix.SetTemperature((gasMix.Temperature + energyReleased) / newHeatCap);
                }
            }
        }
        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);
            }
        }
示例#27
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));
                }
            }
        }