예제 #1
0
        void Analyze_radiation(List <Part> parts, ResourceSimulator sim)
        {
            // scan the parts
            emitted = 0.0;
            foreach (Part p in parts)
            {
                // for each module
                foreach (PartModule m in p.Modules)
                {
                    // skip disabled modules
                    if (!m.isEnabled)
                    {
                        continue;
                    }

                    // accumulate emitter radiation
                    if (m.moduleName == "Emitter")
                    {
                        Emitter emitter = m as Emitter;

                        emitted += emitter.running ? emitter.radiation : 0.0;
                    }
                }
            }

            // calculate shielding factor
            double amount   = sim.Resource("Shielding").amount;
            double capacity = sim.Resource("Shielding").capacity;

            shielding = (capacity > double.Epsilon ? amount / capacity : 1.0) * PreferencesStorm.Instance.shieldingEfficiency;
        }
예제 #2
0
        void Analyze_qol(List <Part> parts, ResourceSimulator sim, EnvironmentAnalyzer env)
        {
            // calculate living space factor
            living_space = Lib.Clamp((volume / Math.Max(crew_count, 1u)) / PreferencesComfort.Instance.livingSpace, 0.1, 1.0);

            // calculate comfort factor
            comforts = new Comforts(parts, env.landed, crew_count > 1, has_comms);
        }
예제 #3
0
        public void Analyze(List <Part> parts, ResourceSimulator sim, EnvironmentAnalyzer env)
        {
            // note: vessel analysis require resource analysis, but at the same time resource analysis
            // require vessel analysis, so we are using resource analysis from previous frame (that's okay)
            // in the past, it was the other way around - however that triggered a corner case when va.comforts
            // was null (because the vessel analysis was still never done) and some specific rule/process
            // in resource analysis triggered an exception, leading to the vessel analysis never happening
            // inverting their order avoided this corner-case

            Analyze_crew(parts);
            Analyze_habitat(parts, sim, env);
            Analyze_radiation(parts, sim);
            Analyze_reliability(parts);
            Analyze_qol(parts, sim, env);
            Analyze_comms(parts);
        }
예제 #4
0
        void Analyze_habitat(List <Part> parts, ResourceSimulator sim, EnvironmentAnalyzer env)
        {
            // calculate total volume
            volume = sim.Resource("Atmosphere").capacity / 1e3;

            // calculate total surface
            surface = sim.Resource("Shielding").capacity;

            // determine if the vessel has pressure control capabilities
            pressurized = sim.Resource("Atmosphere").produced > 0.0 || env.breathable;

            // determine number of EVA's using available Nitrogen
            evas = (uint)(Math.Max(0, sim.Resource("Nitrogen").amount - 330) / PreferencesLifeSupport.Instance.evaAtmoLoss);

            // determine if the vessel has scrubbing capabilities
            scrubbed = sim.Resource("WasteAtmosphere").consumed > 0.0 || env.breathable;

            // determine if the vessel has humidity control capabilities
            humid = sim.Resource("MoistAtmosphere").consumed > 0.0 || env.breathable;

            // scan the parts
            double max_pressure = 1.0;

            foreach (Part p in parts)
            {
                // for each module
                foreach (PartModule m in p.Modules)
                {
                    // skip disabled modules
                    if (!m.isEnabled)
                    {
                        continue;
                    }

                    if (m.moduleName == "Habitat")
                    {
                        Habitat h = m as Habitat;
                        max_pressure = Math.Min(max_pressure, h.max_pressure);
                    }
                }
            }

            pressurized &= max_pressure >= Settings.PressureThreshold;
        }
예제 #5
0
        void Analyze_radiation(List <Part> parts, ResourceSimulator sim)
        {
            // scan the parts
            emitted = 0.0;
            foreach (Part p in parts)
            {
                // for each module
                foreach (PartModule m in p.Modules)
                {
                    // skip disabled modules
                    if (!m.isEnabled)
                    {
                        continue;
                    }

                    // accumulate emitter radiation
                    if (m.moduleName == "Emitter")
                    {
                        Emitter emitter = m as Emitter;
                        emitter.Recalculate();

                        if (emitter.running)
                        {
                            if (emitter.radiation > 0)
                            {
                                emitted += emitter.radiation * emitter.radiation_impact;
                            }
                            else
                            {
                                emitted += emitter.radiation;
                            }
                        }
                    }
                }
            }

            // calculate shielding factor
            double amount   = sim.Resource("Shielding").amount;
            double capacity = sim.Resource("Shielding").capacity;

            shielding = capacity > 0
                                ? Radiation.ShieldingEfficiency(amount / capacity)
                                : 0;
        }
예제 #6
0
        void Analyze_habitat(ResourceSimulator sim, EnvironmentAnalyzer env)
        {
            // calculate total volume
            volume = sim.Resource("Atmosphere").capacity / 1e3;

            // calculate total surface
            surface = sim.Resource("Shielding").capacity;

            // determine if the vessel has pressure control capabilities
            pressurized = sim.Resource("Atmosphere").produced > 0.0 || env.breathable;

            // determine number of EVA's using available Nitrogen
            evas = (uint)(Math.Max(0, sim.Resource("Nitrogen").amount - 330) / PreferencesLifeSupport.Instance.evaAtmoLoss);

            // determine if the vessel has scrubbing capabilities
            scrubbed = sim.Resource("WasteAtmosphere").consumed > 0.0 || env.breathable;

            // determine if the vessel has humidity control capabilities
            humid = sim.Resource("MoistAtmosphere").consumed > 0.0 || env.breathable;
        }
예제 #7
0
        void Analyze_habitat(List <Part> parts, ResourceSimulator sim, EnvironmentAnalyzer env)
        {
            // calculate total volume
            volume = sim.Resource("Atmosphere").capacity / 1e3;

            // calculate total surface
            surface = sim.Resource("Shielding").capacity;

            // determine if the vessel has pressure control capabilities
            pressurized = sim.Resource("Atmosphere").produced > 0.0 || env.breathable;

            // determine if the vessel has scrubbing capabilities
            scrubbed = sim.Resource("WasteAtmosphere").consumed > 0.0 || env.breathable;

            // scan the parts
            double max_pressure = 1.0;

            foreach (Part p in parts)
            {
                // for each module
                foreach (PartModule m in p.Modules)
                {
                    // skip disabled modules
                    if (!m.isEnabled)
                    {
                        continue;
                    }

                    if (m.moduleName == "Habitat")
                    {
                        Habitat h = m as Habitat;
                        max_pressure = Math.Min(max_pressure, h.max_pressure);
                    }
                }
            }

            pressurized &= max_pressure >= Settings.PressureThreshold;
        }
예제 #8
0
        // execute the recipe
        public bool Execute(ResourceSimulator sim)
        {
            // determine worst input ratio
            double worst_input = left;

            if (outputs.Count > 0)
            {
                for (int i = 0; i < inputs.Count; ++i)
                {
                    Resource_recipe.Entry e   = inputs[i];
                    SimulatedResourceView res = sim.Resource(e.name).GetSimulatedResourceView(loaded_part);
                    // handle combined inputs
                    if (e.combined != null)
                    {
                        // is combined resource the primary
                        if (e.combined != "")
                        {
                            Resource_recipe.Entry sec_e = inputs.Find(x => x.name.Contains(e.combined));
                            SimulatedResourceView sec   = sim.Resource(sec_e.name).GetSimulatedResourceView(loaded_part);
                            double pri_worst            = Lib.Clamp(res.amount * e.inv_quantity, 0.0, worst_input);
                            if (pri_worst > 0.0)
                            {
                                worst_input = pri_worst;
                            }
                            else
                            {
                                worst_input = Lib.Clamp(sec.amount * sec_e.inv_quantity, 0.0, worst_input);
                            }
                        }
                    }
                    else
                    {
                        worst_input = Lib.Clamp(res.amount * e.inv_quantity, 0.0, worst_input);
                    }
                }
            }

            // determine worst output ratio
            double worst_output = left;

            if (inputs.Count > 0)
            {
                for (int i = 0; i < outputs.Count; ++i)
                {
                    Resource_recipe.Entry e = outputs[i];
                    if (!e.dump)                     // ignore outputs that can dump overboard
                    {
                        SimulatedResourceView res = sim.Resource(e.name).GetSimulatedResourceView(loaded_part);
                        worst_output = Lib.Clamp((res.capacity - res.amount) * e.inv_quantity, 0.0, worst_output);
                    }
                }
            }

            // determine worst-io
            double worst_io = Math.Min(worst_input, worst_output);

            // consume inputs
            for (int i = 0; i < inputs.Count; ++i)
            {
                Resource_recipe.Entry e   = inputs[i];
                SimulatedResource     res = sim.Resource(e.name);
                // handle combined inputs
                if (e.combined != null)
                {
                    // is combined resource the primary
                    if (e.combined != "")
                    {
                        Resource_recipe.Entry sec_e = inputs.Find(x => x.name.Contains(e.combined));
                        SimulatedResourceView sec   = sim.Resource(sec_e.name).GetSimulatedResourceView(loaded_part);
                        double need = (e.quantity * worst_io) + (sec_e.quantity * worst_io);
                        // do we have enough primary to satisfy needs, if so don't consume secondary
                        if (res.amount >= need)
                        {
                            res.Consume(need, name);
                        }
                        // consume primary if any available and secondary
                        else
                        {
                            need -= res.amount;
                            res.Consume(res.amount, name);
                            sec.Consume(need, name);
                        }
                    }
                }
                else
                {
                    res.Consume(e.quantity * worst_io, name);
                }
            }

            // produce outputs
            for (int i = 0; i < outputs.Count; ++i)
            {
                Resource_recipe.Entry e   = outputs[i];
                SimulatedResourceView res = sim.Resource(e.name).GetSimulatedResourceView(loaded_part);
                res.Produce(e.quantity * worst_io, name);
            }

            // update amount left to execute
            left -= worst_io;

            // the recipe was executed, at least partially
            return(worst_io > double.Epsilon);
        }