コード例 #1
0
ファイル: NO2Formation.cs プロジェクト: ewy0/unitystation
        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));
            }
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        /// <summary>
        /// The thing that actually equalises the tiles
        /// </summary>
        private void Equalize()
        {
            // If there is just one isolated tile, it's not nescessary to calculate the mean.  Speeds up things a bit.
            if (nodes.Count > 1)
            {
                //Calculate the average gas from adding up all the adjacent tiles and dividing by the number of tiles
                GasMix MeanGasMix = CalcMeanGasMix();

                for (var i = 0; i < nodes.Count; i++)
                {
                    MetaDataNode node = nodes[i];

                    if (!node.IsOccupied)
                    {
                        node.GasMix = CalcAtmos(node.GasMix, MeanGasMix);

                        if (node.IsSpace)
                        {
                            //Set to 0 if space
                            node.GasMix *= 0;
                        }
                    }
                }
            }
        }
コード例 #4
0
        public float React(ref GasMix gasMix, Vector3 tilePos)
        {
            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);
                }
            }

            return(0f);
        }
コード例 #5
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);
        }
コード例 #6
0
        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));
            }
        }
コード例 #7
0
        public void React(GasMix gasMix, MetaDataNode node)
        {
            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,
                          AtmosDefines.SPACE_TEMPERATURE));
        }
コード例 #8
0
ファイル: AtmosSystem.cs プロジェクト: ktndrnl/unitystation
        public override void Initialize()
        {
            if (!CustomNetworkManager.IsServer)
            {
                return;
            }

            //We have bool to stop null checks on every pos
            var hasCustomMix = defaultRoomGasMixOverride != null;

            foreach (var gasSetter in GetComponentsInChildren <RoomGasSetter>())
            {
                gasSetter.SetUp();
            }

            BoundsInt bounds = metaTileMap.GetBounds();

            foreach (Vector3Int position in bounds.allPositionsWithin)
            {
                //Get top tile at pos to check if it should spawn with no air
                bool spawnWithNoAir = false;

                var topTile = metaTileMap.GetTile(position, LayerTypeSelection.Effects | LayerTypeSelection.Underfloor);
                if (topTile is BasicTile tile)
                {
                    spawnWithNoAir = tile.SpawnWithNoAir;
                }

                MetaDataNode node = metaDataLayer.Get(position, false);
                if ((node.IsRoom || node.IsOccupied) && !spawnWithNoAir)
                {
                    //Check to see if theres a special room mix
                    if (toSet.Count > 0 && toSet.TryGetValue(node.RoomNumber, out var gasSetter))
                    {
                        node.GasMix = GasMix.NewGasMix(gasSetter.GasMixToSpawn);
                    }
                    //See if the whole matrix has a custom mix
                    else if (hasCustomMix)
                    {
                        node.GasMix = GasMix.NewGasMix(defaultRoomGasMixOverride.BaseGasMix);
                    }
                    //Default to air mix otherwise
                    else
                    {
                        node.GasMix = GasMix.NewGasMix(GasMixes.BaseAirMix);
                    }
                }
                else
                {
                    node.GasMix = GasMix.NewGasMix(GasMixes.BaseSpaceMix);
                }
            }

            foreach (var gasSetter in toSet)
            {
                _ = Despawn.ServerSingle(gasSetter.Value.gameObject);
            }

            toSet.Clear();
        }
コード例 #9
0
ファイル: BZFormation.cs プロジェクト: ewy0/unitystation
        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));
        }
コード例 #10
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);
        }
コード例 #11
0
        public void ExposeHotspot(Vector3Int localPosition)
        {
            if (!hotspots.ContainsKey(localPosition) || hotspots[localPosition].Hotspot == null)
            {
                Profiler.BeginSample("MarkForAddition");
                MetaDataNode node   = metaDataLayer.Get(localPosition);
                GasMix       gasMix = node.GasMix;

                if (PlasmaFireReaction.CanHoldHotspot(gasMix))
                {
                    // igniting
                    //addition will be done later in Update
                    hotspotsToAdd.Add(new Hotspot(node));
                }

                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);
            }
        }
コード例 #12
0
        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));
            }
        }
コード例 #13
0
        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);
        }
コード例 #14
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);
        }
コード例 #15
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);
        }
コード例 #16
0
        public override void Initialize()
        {
            if (!CustomNetworkManager.IsServer)
            {
                return;
            }

            BoundsInt bounds = metaTileMap.GetBounds();

            foreach (Vector3Int position in bounds.allPositionsWithin)
            {
                //get toptile at pos to check if it should spawn with no air
                bool spawnWithNoAir = false;
                var  topTile        = metaTileMap.GetTile(position, LayerTypeSelection.Effects | LayerTypeSelection.Underfloor);
                if (topTile is BasicTile tile)
                {
                    spawnWithNoAir = tile.SpawnWithNoAir;
                }
                MetaDataNode node = metaDataLayer.Get(position, false);
                if ((node.IsRoom || node.IsOccupied) && !spawnWithNoAir)
                {
                    node.GasMix = GasMix.NewGasMix(GasMixes.BaseAirMix);
                }
                else
                {
                    node.GasMix = GasMix.NewGasMix(GasMixes.BaseSpaceMix);
                }
            }
        }
コード例 #17
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);
                }
            }
        }
コード例 #18
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);
        }
コード例 #19
0
 public static void React(GasMix gasMix, Matrix matrix)
 {
     foreach (Reaction reaction in reactions)
     {
         if (reaction.Satisfies(gasMix))
         {
             reaction.React(gasMix, Vector3.zero, matrix);
         }
     }
 }
コード例 #20
0
ファイル: GasMix.cs プロジェクト: Wrackbang/unitystation
        public void Copy(GasMix other)
        {
            for (int i = 0; i < Gas.Count; i++)
            {
                Gases[i] = other.Gases[i];
            }

            SetPressure(other.Pressure);
            Volume = other.Volume;
        }
コード例 #21
0
        private GasMix CalcAtmos(GasMix atmos, GasMix gasMix)
        {
            //Used for updating tiles with the averagee Calculated gas
            for (int i = 0; i < Gas.Count; i++)
            {
                atmos.Gases[i] = gasMix.Gases[i];
            }

            atmos.SetPressure(gasMix.Pressure);

            return(atmos);
        }
コード例 #22
0
        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);
            }
        }
コード例 #23
0
 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);
 }
コード例 #24
0
ファイル: GasMix.cs プロジェクト: Wrackbang/unitystation
        public GasMix RemoveVolume(float volume, bool setVolume = false)
        {
            GasMix removed = RemoveRatio(volume / Volume);

            if (setVolume)
            {
                removed.Volume = volume;
                removed        = FromTemperature(removed.Gases, Temperature, volume);
            }

            return(removed);
        }
コード例 #25
0
ファイル: AtmosSystem.cs プロジェクト: ktndrnl/unitystation
        /// <summary>
        /// Use to set a rooms gas after the round has started, otherwise do it in the initialisation
        /// </summary>
        /// <param name="roomNumber">Room number to fill</param>
        /// <param name="gasMixToUse">GasMix to fill room with</param>
        public void SetRoomGas(int roomNumber, GasMix gasMixToUse)
        {
            BoundsInt bounds = metaTileMap.GetBounds();

            foreach (Vector3Int position in bounds.allPositionsWithin)
            {
                MetaDataNode node = metaDataLayer.Get(position, false);
                if (node.IsRoom && node.RoomNumber == roomNumber)
                {
                    node.GasMix = GasMix.NewGasMix(gasMixToUse);
                }
            }
        }
コード例 #26
0
ファイル: GasMix.cs プロジェクト: Wrackbang/unitystation
        public GasMix RemoveRatio(float ratio)
        {
            GasMix removed = this * ratio;

            for (int i = 0; i < Gas.Count; i++)
            {
                Gases[i] -= removed.Gases[i];
            }

            SetPressure(Pressure -= removed.Pressure * removed.Volume / Volume);

            return(removed);
        }
コード例 #27
0
ファイル: Reactions.cs プロジェクト: talentone/unitystation
        public static float React(ref GasMix gasMix)
        {
            float consumed = 0;

            foreach (Reaction reaction in reactions)
            {
                if (reaction.Satisfies(gasMix))
                {
                    consumed += reaction.React(ref gasMix, Vector3.zero);
                }
            }

            return(consumed);
        }
コード例 #28
0
        /// <summary>
        /// Use to set a rooms gas after the round has started, otherwise do it in the initialisation
        /// </summary>
        /// <param name="roomNumber">Room number to fill</param>
        /// <param name="gasMixToUse">GasMix to fill room with</param>
        public void SetRoomGas(int roomNumber, GasMix gasMixToUse)
        {
            var bounds = metaTileMap.GetLocalBounds();

            foreach (Vector3Int position in bounds.allPositionsWithin())
            {
                MetaDataNode node = metaDataLayer.Get(position, false);
                if (node.IsRoom && node.RoomNumber == roomNumber)
                {
                    //Use ChangeGasMix to remove old gas overlays and add new overlays
                    node.ChangeGasMix(GasMix.NewGasMix(gasMixToUse));
                }
            }
        }
コード例 #29
0
        /// <summary>
        /// Transfers heat between an Open tile and a Solid tile
        /// Uses data from MetaDataNode for SolidNode and GasMix values for Open node
        /// </summary>
        private void ConductFromOpenToSolid(MetaDataNode solidNode, GasMix meanGasMix)
        {
            var tempDelta = solidNode.ConductivityTemperature - meanGasMix.Temperature;

            if (Mathf.Abs(tempDelta) <= AtmosDefines.MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
            {
                return;
            }

            if (meanGasMix.WholeHeatCapacity <= AtmosConstants.MINIMUM_HEAT_CAPACITY)
            {
                return;
            }

            if (solidNode.HeatCapacity <= AtmosConstants.MINIMUM_HEAT_CAPACITY)
            {
                return;
            }

            //The larger the combined capacity the less is shared
            var heat = solidNode.ThermalConductivity * tempDelta *
                       (solidNode.HeatCapacity * meanGasMix.WholeHeatCapacity /
                        (solidNode.HeatCapacity + meanGasMix.WholeHeatCapacity));

            solidNode.ConductivityTemperature = Mathf.Max(
                solidNode.ConductivityTemperature - (heat / solidNode.HeatCapacity),
                AtmosDefines.SPACE_TEMPERATURE);

            meanGasMix.SetTemperature(Mathf.Max(
                                          meanGasMix.Temperature + (heat / meanGasMix.WholeHeatCapacity),
                                          AtmosDefines.SPACE_TEMPERATURE));

            //Do atmos update for the Solid node if temperature is allowed so it can do conduction
            //This is checking for the start temperature as this is how the cycle will begin
            if (solidNode.ConductivityTemperature < AtmosDefines.MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
            {
                return;
            }

            if (solidNode.AllowedToSuperConduct == false)
            {
                solidNode.AllowedToSuperConduct = true;

                //Allow this node to trigger other tiles super conduction
                solidNode.StartingSuperConduct = true;
            }

            AtmosManager.Update(solidNode);
        }
コード例 #30
0
        /// <summary>
        /// Calculate the average Gas tile if you averaged all the adjacent ones and itself
        /// </summary>
        /// <returns>The mean gas mix.</returns>
        private void CalcMeanGasMix()
        {
            meanGasMix.Clear();

            var targetCount = 0;

            for (var i = 0; i < nodes.Count; i++)
            {
                MetaDataNode node = nodes[i];

                if (node == null)
                {
                    continue;
                }

                //If node is not occupied then we want to add it to the total
                if (node.IsOccupied == false && node.IsIsolatedNode == false)
                {
                    meanGasMix.Volume += node.GasMix.Volume;
                    GasMix.TransferGas(meanGasMix, node.GasMix, node.GasMix.Moles, true);
                    targetCount++;
                }
                else if (node.IsIsolatedNode == false)
                {
                    //Remove all overlays for occupied tiles
                    RemovalAllGasOverlays(node);

                    //We trap the gas in the walls to stop instances where you remove a wall and theres a vacuum there
                }
            }

            // Sometimes, we calculate the meanGasMix of a tile surrounded by IsOccupied tiles (no atmos, ie: walls)
            if (targetCount == 0)
            {
                return;
            }

            meanGasMix.Volume /= targetCount;             //Note: this assumes the volume of all tiles are the same


            lock (meanGasMix.GasesArray)             //no Double lock
            {
                for (int i = meanGasMix.GasesArray.Count - 1; i >= 0; i--)
                {
                    var gasData = meanGasMix.GasesArray[i];
                    meanGasMix.GasData.SetMoles(gasData.GasSO, meanGasMix.GasData.GetGasMoles(gasData.GasSO) / targetCount);
                }
            }
        }