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; }
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); }
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); }
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; }
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; }
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; }
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; }
// 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); }