// pseudo-ctor public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // update RMB ui Fields["Status"].guiName = title; Actions["Action"].active = toggle; if (toggle) { Events["Toggle"].guiActiveUnfocused = require_eva; Events["Toggle"].guiActive = !require_eva || Lib.IsEditor(); } // deal with non-toggable if (!toggle) { deployed = true; } // create animator deploy_anim = new Animator(part, animation); // set animation initial state deploy_anim.Still(deployed ? 1.0 : 0.0); deploy_cs = new CrewSpecs(crew_operate); }
public static void BackgroundUpdate(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, Laboratory lab, resource_info ec, double elapsed_s) { // if enabled if (Lib.Proto.GetBool(m, "running")) { // if a researcher is not required, or the researcher is present CrewSpecs researcher_cs = new CrewSpecs(lab.researcher); if (!researcher_cs || researcher_cs.check(p.protoModuleCrew)) { // get sample to analyze string sample_filename = next_sample(v); // if there is a sample to analyze if (sample_filename.Length > 0) { // consume EC ec.Consume(lab.ec_rate * elapsed_s); // if there was ec // - comparing against amount in previous simulation step if (ec.amount > double.Epsilon) { // analyze the sample analyze(v, sample_filename, lab.analysis_rate * elapsed_s); } } } } }
CrewSpecs repair_cs; // crew specs public override void OnStart(StartState state) { // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // cache list of modules modules = part.FindModulesImplementing <PartModule>().FindAll(k => k.moduleName == type); // parse crew specs repair_cs = new CrewSpecs(repair); // setup ui Fields["Status"].guiName = title; Events["Inspect"].guiName = Lib.BuildString("Inspect <b>", title, "</b>"); Events["Repair"].guiName = Lib.BuildString("Repair <b>", title, "</b>"); // sync monobehaviour state with module state // - required as the monobehaviour state is not serialized if (broken) { foreach (PartModule m in modules) { m.enabled = false; } } // type-specific hacks if (broken) { apply(true); } }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // set UI text Actions["Action"].guiName = Localizer.Format("#KERBALISM_Laboratory_Action"); Events["CleanExperiments"].guiName = Localizer.Format("#KERBALISM_Laboratory_Clean"); // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // parse crew specs researcher_cs = new CrewSpecs(researcher); var hardDrive = part.FindModuleImplementing <HardDrive>(); if (hardDrive != null) { drive = hardDrive.GetDrive(); } else { drive = DB.Vessel(vessel).BestDrive(); } }
string status = string.Empty; // string to show next to the ui button public override void OnStart(StartState state) { // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // parse crew specs researcher_cs = new CrewSpecs(researcher); }
public static double AdjustedRate(Harvester harvester, CrewSpecs engineer_cs, List <ProtoCrewMember> crew, double abundance) { // Bonus(..., -2): a level 0 engineer will alreaday add 2 bonus points jsut because he's there, // regardless of level. efficiency will raise further with higher levels. int bonus = engineer_cs.Bonus(crew, -2); double crew_gain = 1 + bonus * Settings.HarvesterCrewLevelBonus; crew_gain = Lib.Clamp(crew_gain, 1, Settings.MaxHarvesterBonus); return(harvester.rate * crew_gain * (abundance / harvester.abundance_rate)); }
public override void OnStart(StartState state) { // create animator deploy_anim = new Animator(part, deploy); // set initial animation state deploy_anim.still(recording ? 1.0 : 0.0); // parse crew specs operator_cs = new CrewSpecs(crew); // get experiment title exp_name = ResearchAndDevelopment.GetExperiment(experiment).experimentTitle; }
public override void OnStart(StartState state) { // parse all setups from string data var archive = new ReadArchive(data); int count; archive.load(out count); setups = new List <ConfigureSetup>(count); while (count-- > 0) { setups.Add(new ConfigureSetup(archive)); } // parse configuration from string data archive = new ReadArchive(cfg); archive.load(out count); selected = new List <string>(count); while (count-- > 0) { string s; archive.load(out s); selected.Add(s); } // parse previous configuration from string data archive = new ReadArchive(prev_cfg); archive.load(out count); prev_selected = new List <string>(count); while (count-- > 0) { string s; archive.load(out s); prev_selected.Add(s); } // default title to part name if (title.Length == 0) { title = Lib.PartName(part); } // parse crew specs reconfigure_cs = new CrewSpecs(reconfigure); // set toggle window button label Events["ToggleWindow"].guiName = Lib.BuildString("Configure <b>", title, "</b>"); // only show toggle in flight if this is reconfigurable Events["ToggleWindow"].active = Lib.IsEditor() || reconfigure_cs; // store configuration changes changes = new Dictionary <int, int>(); }
public static void BackgroundUpdate(Vessel v, ProtoPartModuleSnapshot m, Experiment exp, resource_info ec, double elapsed_s) { // if experiment is active if (Lib.Proto.GetBool(m, "recording")) { // detect conditions // - comparing against amount in previous step bool has_ec = ec.amount > double.Epsilon; bool has_operator = new CrewSpecs(exp.crew).check(v); string sit = Science.situation(v, exp.situations); // deduce issues string issue = string.Empty; if (sit.Length == 0) { issue = "invalid situation"; } else if (!has_operator) { issue = "no operator"; } else if (!has_ec) { issue = "missing <b>EC</b>"; } Lib.Proto.Set(m, "issue", issue); // if there are no issues if (issue.Length == 0) { // generate subject id string subject_id = Science.generate_subject(exp.experiment, v.mainBody, sit, Science.biome(v, sit), Science.multiplier(v, sit)); // record in drive if (exp.transmissible) { DB.Vessel(v).drive.record_file(subject_id, exp.data_rate * elapsed_s); } else { DB.Vessel(v).drive.record_sample(subject_id, exp.data_rate * elapsed_s); } // consume ec ec.Consume(exp.ec_rate * elapsed_s); } } }
string status = string.Empty; // string to show next to the ui button public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // parse crew specs researcher_cs = new CrewSpecs(researcher); }
public static void BackgroundUpdate(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, Laboratory lab, Resource_info ec, double elapsed_s) { // if enabled if (Lib.Proto.GetBool(m, "running")) { // if a researcher is not required, or the researcher is present background_researcher_cs = new CrewSpecs(lab.researcher); if (!background_researcher_cs || background_researcher_cs.Check(p.protoModuleCrew)) { double rate = lab.analysis_rate; if (background_researcher_cs) { int bonus = background_researcher_cs.Bonus(p.protoModuleCrew); double crew_gain = 1 + bonus * Settings.LaboratoryCrewLevelBonus; crew_gain = Lib.Clamp(crew_gain, 1, Settings.MaxLaborartoryBonus); rate *= crew_gain; } // get sample to analyze background_sample = NextSample(v); // if there is a sample to analyze if (background_sample != null) { // consume EC ec.Consume(lab.ec_rate * elapsed_s); // if there was ec // - comparing against amount in previous simulation step if (ec.amount > double.Epsilon) { // analyze the sample var status = Analyze(v, background_sample, rate * elapsed_s); if (status != Status.RUNNING) { Lib.Proto.Set(m, "running", false); } } } } } }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // create animator deploy_anim = new Animator(part, deploy); // set initial animation state deploy_anim.still(recording ? 1.0 : 0.0); // parse crew specs operator_cs = new CrewSpecs(crew); // get experiment title exp_name = ResearchAndDevelopment.GetExperiment(experiment).experimentTitle; }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // set UI text Actions["Action"].guiName = Localizer.Format("#KERBALISM_Laboratory_Action"); Events["CleanExperiments"].guiName = Localizer.Format("#KERBALISM_Laboratory_Clean"); // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } // parse crew specs researcher_cs = new CrewSpecs(researcher); }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } if (remainingSampleMass < 0) { remainingSampleMass = sample_mass; if (sample_reservoir > float.Epsilon) { remainingSampleMass = sample_reservoir; } } // create animator deployAnimator = new Animator(part, anim_deploy); // set initial animation state deployAnimator.Still(recording ? 1.0 : 0.0); // parse crew specs if (!string.IsNullOrEmpty(crew_operate)) { operator_cs = new CrewSpecs(crew_operate); } if (!string.IsNullOrEmpty(crew_reset)) { reset_cs = new CrewSpecs(crew_reset); } if (!string.IsNullOrEmpty(crew_prepare)) { prepare_cs = new CrewSpecs(crew_prepare); } exp = ResearchAndDevelopment.GetExperiment(experiment_id); }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } Fields["Status"].guiName = title; #if DEBUG_RELIABILITY Events["Break"].guiName = "Break " + title + " [DEBUG]"; #endif // do nothing in the editors and when compiling parts if (!Lib.IsFlight()) { return; } if (last_inspection <= 0) { last_inspection = Planetarium.GetUniversalTime(); } // cache list of modules if (type.StartsWith("ModuleEngines", StringComparison.Ordinal)) { // do this generically. there are many different engine types derived from ModuleEngines: // ModuleEnginesFX, ModuleEnginesRF, all the SolverEngines, possibly more // this will also reduce the amount of configuration overhead, no need to duplicate the same // config for stock with ModuleEngines and ModuleEnginesFX modules = new List <PartModule>(); var engines = part.FindModulesImplementing <ModuleEngines>(); foreach (var engine in engines) { modules.Add(engine); } } else { modules = part.FindModulesImplementing <PartModule>().FindAll(k => k.moduleName == type); } // parse crew specs repair_cs = new CrewSpecs(repair); // setup ui Events["Inspect"].guiName = Lib.BuildString("Inspect <b>", title, "</b>"); Events["Repair"].guiName = Lib.BuildString("Repair <b>", title, "</b>"); // sync monobehaviour state with module state // - required as the monobehaviour state is not serialized if (broken) { foreach (PartModule m in modules) { m.enabled = false; m.isEnabled = false; } } if (broken) { StartCoroutine(DeferredApply()); } }
// specifics support public Specifics Specs() { var specs = new Specifics(); var exp = Science.Experiment(experiment_id); if (exp == null) { specs.Add(Localizer.Format("#KERBALISM_ExperimentInfo_Unknown")); return(specs); } specs.Add(Lib.BuildString("<b>", exp.name, "</b>")); if (!string.IsNullOrEmpty(experiment_desc)) { specs.Add(Lib.BuildString("<i>", experiment_desc, "</i>")); } specs.Add(string.Empty); double expSize = exp.max_amount; if (sample_mass < float.Epsilon) { specs.Add("Data", Lib.HumanReadableDataSize(expSize)); specs.Add("Data rate", Lib.HumanReadableDataRate(data_rate)); specs.Add("Duration", Lib.HumanReadableDuration(expSize / data_rate)); } else { specs.Add("Sample size", Lib.HumanReadableSampleSize(expSize)); specs.Add("Sample mass", Lib.HumanReadableMass(sample_mass)); if (!sample_collecting && Math.Abs(sample_reservoir - sample_mass) > double.Epsilon && sample_mass > double.Epsilon) { specs.Add("Experiments", "" + Math.Round(sample_reservoir / sample_mass, 0)); } specs.Add("Duration", Lib.HumanReadableDuration(expSize / data_rate)); } List <string> situations = exp.Situations(); if (situations.Count > 0) { specs.Add(string.Empty); specs.Add("<color=#00ffff>Situations:</color>", string.Empty); foreach (string s in situations) { specs.Add(Lib.BuildString("• <b>", s, "</b>")); } } specs.Add(string.Empty); specs.Add("<color=#00ffff>Needs:</color>"); specs.Add("EC", Lib.HumanReadableRate(ec_rate)); foreach (var p in KerbalismProcess.ParseResources(resources)) { specs.Add(p.Key, Lib.HumanReadableRate(p.Value)); } if (crew_prepare.Length > 0) { var cs = new CrewSpecs(crew_prepare); specs.Add("Preparation", cs ? cs.Info() : "none"); } if (crew_operate.Length > 0) { var cs = new CrewSpecs(crew_operate); specs.Add("Operation", cs ? cs.Info() : "unmanned"); } if (crew_reset.Length > 0) { var cs = new CrewSpecs(crew_reset); specs.Add("Reset", cs ? cs.Info() : "none"); } if (!string.IsNullOrEmpty(requires)) { specs.Add(string.Empty); specs.Add("<color=#00ffff>Requires:</color>", string.Empty); var tokens = Lib.Tokenize(requires, ','); foreach (string s in tokens) { specs.Add(Lib.BuildString("• <b>", Science.RequirementText(s), "</b>")); } } return(specs); }
private static string TestForIssues(Vessel v, Resource_info ec, Experiment experiment, uint hdId, bool broken, double remainingSampleMass, bool didPrepare, bool isShrouded, string last_subject_id) { var subject_id = Science.Generate_subject_id(experiment.experiment_id, v); if (broken) { return("broken"); } if (isShrouded && !experiment.allow_shrouded) { return("shrouded"); } bool needsReset = experiment.crew_reset.Length > 0 && !string.IsNullOrEmpty(last_subject_id) && subject_id != last_subject_id; if (needsReset) { return("reset required"); } if (ec.amount < double.Epsilon && experiment.ec_rate > double.Epsilon) { return("no Electricity"); } if (!string.IsNullOrEmpty(experiment.crew_operate)) { var cs = new CrewSpecs(experiment.crew_operate); if (!cs && Lib.CrewCount(v) > 0) { return("crew on board"); } else if (cs && !cs.Check(v)) { return(cs.Warning()); } } if (!experiment.sample_collecting && remainingSampleMass < double.Epsilon && experiment.sample_mass > double.Epsilon) { return("depleted"); } if (!didPrepare && !string.IsNullOrEmpty(experiment.crew_prepare)) { return("not prepared"); } string situationIssue = Science.TestRequirements(experiment.experiment_id, experiment.requires, v); if (situationIssue.Length > 0) { return(Science.RequirementText(situationIssue)); } var experimentSize = Science.Experiment(subject_id).max_amount; double chunkSize = Math.Min(experiment.data_rate * Kerbalism.elapsed_s, experimentSize); Drive drive = GetDrive(experiment, v, hdId, chunkSize, subject_id); var isFile = experiment.sample_mass < double.Epsilon; double available = 0; if (isFile) { available = drive.FileCapacityAvailable(); available += Cache.WarpCache(v).FileCapacityAvailable(); } else { available = drive.SampleCapacityAvailable(subject_id); } if (Math.Min(experiment.data_rate * Kerbalism.elapsed_s, experimentSize) > available) { return(insufficient_storage); } return(string.Empty); }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // initialize the remaining sample mass in case it was not configured in the cfg. if (remainingSampleMass < float.Epsilon && string.IsNullOrEmpty(issue) && !sample_collecting) { remainingSampleMass = sample_mass; if (sample_reservoir > float.Epsilon) { remainingSampleMass = sample_reservoir; } } // create animators deployAnimator = new Animator(part, anim_deploy); deployAnimator.reversed = anim_deploy_reverse; loopAnimator = new Animator(part, anim_loop); loopAnimator.reversed = anim_loop_reverse; // set initial animation states deployAnimator.Still(recording ? 1.0 : 0.0); loopAnimator.Still(recording ? 1.0 : 0.0); if (recording) { loopAnimator.Play(false, true); } // parse crew specs if (!string.IsNullOrEmpty(crew_operate)) { operator_cs = new CrewSpecs(crew_operate); } if (!string.IsNullOrEmpty(crew_reset)) { reset_cs = new CrewSpecs(crew_reset); } if (!string.IsNullOrEmpty(crew_prepare)) { prepare_cs = new CrewSpecs(crew_prepare); } resourceDefs = KerbalismProcess.ParseResources(resources); foreach (var hd in part.FindModulesImplementing <HardDrive>()) { if (hd.experiment_id == experiment_id) { privateHdId = part.flightID; } } Events["Toggle"].guiActiveUncommand = true; Events["Toggle"].externalToEVAOnly = true; Events["Toggle"].requireFullControl = false; Events["Prepare"].guiActiveUncommand = true; Events["Prepare"].externalToEVAOnly = true; Events["Prepare"].requireFullControl = false; Events["Reset"].guiActiveUncommand = true; Events["Reset"].externalToEVAOnly = true; Events["Reset"].requireFullControl = false; }
public override void OnStart(StartState state) { // don't break tutorial scenarios if (Lib.DisableScenario(this)) { return; } // parse all setups from string data var archive = new ReadArchive(data); int count; archive.load(out count); setups = new List <ConfigureSetup>(count); while (count-- > 0) { setups.Add(new ConfigureSetup(archive)); } // parse configuration from string data // - we avoid corner case when cfg was never set up (because craft was never in VAB) selected = new List <string>(); if (!string.IsNullOrEmpty(cfg)) { archive = new ReadArchive(cfg); archive.load(out count); while (count-- > 0) { string s; archive.load(out s); selected.Add(s); } } // parse previous configuration from string data // - we avoid corner case when prev_cfg was never set up (because craft was never in VAB) prev_selected = new List <string>(); if (!string.IsNullOrEmpty(prev_cfg)) { archive = new ReadArchive(prev_cfg); archive.load(out count); while (count-- > 0) { string s; archive.load(out s); prev_selected.Add(s); } } // default title to part name if (title.Length == 0) { title = Lib.PartName(part); } // parse crew specs reconfigure_cs = new CrewSpecs(reconfigure); // set toggle window button label Events["ToggleWindow"].guiName = Lib.BuildString("Configure <b>", title, "</b>"); // only show toggle in flight if this is reconfigurable Events["ToggleWindow"].active = Lib.IsEditor() || reconfigure_cs; // store configuration changes changes = new Dictionary <int, int>(); }
private static string TestForIssues(Vessel v, ScienceExperiment exp, Resource_info ec, Experiment experiment, bool broken, double remainingSampleMass, bool didPrepare, bool isShrouded, string last_subject_id, out string subject_id) { var sit = ScienceUtil.GetExperimentSituation(v); var biome = ScienceUtil.GetExperimentBiome(v.mainBody, v.latitude, v.longitude); subject_id = Science.Generate_subject(exp, v.mainBody, sit, biome); if (broken) { return("broken"); } if (isShrouded && !experiment.allow_shrouded) { return("shrouded"); } bool needsReset = experiment.crew_reset.Length > 0 && !string.IsNullOrEmpty(last_subject_id) && subject_id != last_subject_id; if (needsReset) { return("reset required"); } if (ec.amount < double.Epsilon && experiment.ec_rate > double.Epsilon) { return("no <b>Electricity</b>"); } if (!string.IsNullOrEmpty(experiment.crew_operate)) { var cs = new CrewSpecs(experiment.crew_operate); if (!cs.Check(v)) { return(cs.Warning()); } } if (!experiment.sample_collecting && remainingSampleMass < double.Epsilon && experiment.sample_mass > double.Epsilon) { return("depleted"); } string situationIssue = Science.TestRequirements(experiment.requires, v); if (situationIssue.Length > 0) { return(Science.RequirementText(situationIssue)); } if (!exp.IsAvailableWhile(sit, v.mainBody)) { return("invalid situation"); } if (!didPrepare && !string.IsNullOrEmpty(experiment.crew_prepare)) { return("not prepared"); } var drive = DB.Vessel(v).BestDrive(); double available = experiment.sample_mass < float.Epsilon ? drive.FileCapacityAvailable() : drive.SampleCapacityAvailable(); if (experiment.data_rate * Kerbalism.elapsed_s > available) { return("insufficient storage"); } return(string.Empty); }