예제 #1
0
        // 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);
        }
예제 #2
0
        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);
                        }
                    }
                }
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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));
        }
예제 #7
0
        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;
        }
예제 #8
0
        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>();
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #12
0
        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;
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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());
            }
        }
예제 #16
0
        // 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);
        }
예제 #17
0
        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);
        }
예제 #18
0
        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;
        }
예제 #19
0
        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>();
        }
예제 #20
0
        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);
        }