示例#1
0
        /// <summary>
        /// parts that have experiments can't get their module info (what is shown in the VAB tooltip) correctly setup
        /// because the ExperimentInfo database isn't available at loading time, so we recompile their info manually.
        /// </summary>
        public void CompileModuleInfos()
        {
            if (PartLoader.LoadedPartsList == null)
            {
                Lib.Log("Dazed and confused: PartLoader.LoadedPartsList == null");
                return;
            }

            foreach (AvailablePart ap in PartLoader.LoadedPartsList)
            {
                if (ap == null || ap.partPrefab == null)
                {
                    Lib.Log("AvailablePart is null or without prefab: " + ap);
                    continue;
                }

                foreach (PartModule module in ap.partPrefab.Modules)
                {
                    if (module is Experiment expModule)
                    {
                        // don't show configurable experiments
                        if (!expModule.isConfigurable && expModule.experiment_id == ExperimentId)
                        {
                            expModule.ExpInfo = this;

                            // get module info for the ExperimentInfo, once
                            if (string.IsNullOrEmpty(ModuleInfo))
                            {
                                ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                                ModuleInfo += "\n";
                                ModuleInfo += expModule.GetInfo();
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(ModuleInfo))
                    {
                        continue;
                    }

                    if (module is ModuleScienceExperiment stockExpModule)
                    {
                        if (stockExpModule.experimentID == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\n" + Local.Experimentinfo_Datasize + ": ";                         //Data size
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            if (stockExpModule.xmitDataScalar < Science.maxXmitDataScalarForSample)
                            {
                                ModuleInfo += "\n" + Local.Experimentinfo_generatesample;                              //Will generate a sample.
                                ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";                            //Sample size:
                                ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                            }
                            ModuleInfo += "\n\n";
                            ModuleInfo += Lib.Color(Local.Experimentinfo_Situations, Lib.Kolor.Cyan, true);                            //"Situations:\n"

                            foreach (string s in AvailableSituations())
                            {
                                ModuleInfo += Lib.BuildString("• <b>", s, "</b>\n");
                            }

                            ModuleInfo += "\n";
                            ModuleInfo += stockExpModule.GetInfo();
                        }
                    }

#if !KSP15_16
                    else if (module is ModuleGroundExperiment groundExpModule)
                    {
                        if (groundExpModule.experimentId == ExperimentId)
                        {
                            ModuleInfo  = Lib.Color(Title, Lib.Kolor.Cyan, true);
                            ModuleInfo += "\n" + Local.Experimentinfo_Datasize + ": ";                            //Data size
                            ModuleInfo += Lib.HumanReadableDataSize(DataSize);
                            ModuleInfo += "\n\n";
                            ModuleInfo += groundExpModule.GetInfo();
                        }
                    }
#endif
                }

                // special cases
                if (ExperimentId == "asteroidSample" || ExperimentId.StartsWith("cometSample_", StringComparison.Ordinal))
                {
                    ModuleInfo  = Local.Experimentinfo_Asteroid;                   //"Asteroid samples can be taken by kerbals on EVA"
                    ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";    //Sample size:
                    ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                    ModuleInfo += "\n" + Local.Experimentinfo_Samplemass + " ";    //Sample mass:
                    ModuleInfo += Lib.HumanReadableMass(DataSize * Settings.AsteroidSampleMassPerMB);
                }

#if !KSP15_16
                else if (IsROC)
                {
                    string        rocType = ExperimentId.Substring(ExperimentId.IndexOf('_') + 1);
                    ROCDefinition rocDef  = ROCManager.Instance.rocDefinitions.Find(p => p.type == rocType);
                    if (rocDef != null)
                    {
                        ModuleInfo  = Lib.Color(rocDef.displayName, Lib.Kolor.Cyan, true);
                        ModuleInfo += "\n- " + Local.Experimentinfo_scannerarm;                        //Analyse with a scanner arm
                        ModuleInfo += "\n  " + Local.Experimentinfo_Datasize + ": ";                   //Data size
                        ModuleInfo += Lib.HumanReadableDataSize(DataSize);

                        if (rocDef.smallRoc)
                        {
                            ModuleInfo += "\n- " + Local.Experimentinfo_smallRoc;                            //Collectable on EVA as a sample"
                            ModuleInfo += "\n" + Local.Experimentinfo_Samplesize + " ";                      //Sample size:
                            ModuleInfo += Lib.HumanReadableSampleSize(DataSize);
                        }
                        else
                        {
                            ModuleInfo += "\n- " + Local.Experimentinfo_smallRoc2;                          //Can't be collected on EVA
                        }

                        foreach (RocCBDefinition body in rocDef.myCelestialBodies)
                        {
                            ModuleInfo += Lib.Color("\n\n" + Local.Experimentinfo_smallRoc3.Format(body.name), Lib.Kolor.Cyan, true);                            //"Found on <<1>>'s :"
                            foreach (string biome in body.biomes)
                            {
                                ModuleInfo += "\n- ";
                                ModuleInfo += biome;
                            }
                        }
                    }
                }
#endif
            }
        }
示例#2
0
        /// <summary>
        /// If short_strings parameter is true then the strings used for display of the data will be shorter when inflight.
        /// </summary>
        public static void Fileman(this Panel p, Vessel v, bool short_strings = false)
        {
            // avoid corner-case when this is called in a lambda after scene changes
            v = FlightGlobals.FindVessel(v.id);

            // if vessel doesn't exist anymore, leave the panel empty
            if (v == null)
            {
                return;
            }

            // get info from the cache
            Vessel_info vi = Cache.VesselInfo(v);

            // if not a valid vessel, leave the panel empty
            if (!vi.is_valid)
            {
                return;
            }

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, Styles.ScaleStringLength(40)), " <color=#cccccc>FILE MANAGER</color>"));
            p.Width(Styles.ScaleWidthFloat(465.0f));
            p.paneltype = Panel.PanelType.data;

            // time-out simulation
            if (p.Timeout(vi))
            {
                return;
            }

            var drives = Drive.GetDriveParts(v);

            int    filesCount        = 0;
            double usedDataCapacity  = 0;
            double totalDataCapacity = 0;

            int    samplesCount     = 0;
            int    usedSlots        = 0;
            int    totalSlots       = 0;
            double totalMass        = 0;
            bool   unlimitedData    = false;
            bool   unlimitedSamples = false;

            foreach (var idDrivePair in drives)
            {
                var drive = idDrivePair.Value;

                if (!drive.is_private)
                {
                    usedDataCapacity  += drive.FilesSize();
                    totalDataCapacity += drive.dataCapacity;

                    unlimitedData    |= drive.dataCapacity < 0;
                    unlimitedSamples |= drive.sampleCapacity < 0;

                    usedSlots  += drive.SamplesSize();
                    totalSlots += drive.sampleCapacity;
                }

                filesCount   += drive.files.Count;
                samplesCount += drive.samples.Count;
                foreach (var sample in drive.samples.Values)
                {
                    totalMass += sample.mass;
                }
            }

            if (filesCount > 0 || totalDataCapacity > 0)
            {
                var title = "DATA " + Lib.HumanReadableDataSize(usedDataCapacity);
                if (!unlimitedData)
                {
                    title += Lib.BuildString(" (", Lib.HumanReadablePerc((totalDataCapacity - usedDataCapacity) / totalDataCapacity), " available)");
                }
                p.AddSection(title);

                foreach (var idDrivePair in drives)
                {
                    uint partId = idDrivePair.Key;
                    var  drive  = idDrivePair.Value;
                    foreach (var pair in drive.files)
                    {
                        string filename = pair.Key;
                        File   file     = pair.Value;
                        Render_file(p, partId, filename, file, drive, short_strings && Lib.IsFlight(), v);
                    }
                }

                if (filesCount == 0)
                {
                    p.AddContent("<i>no files</i>", string.Empty);
                }
            }

            if (samplesCount > 0 || totalSlots > 0)
            {
                var title = "SAMPLES " + Lib.HumanReadableMass(totalMass) + " " + Lib.HumanReadableSampleSize(usedSlots);
                if (totalSlots > 0 && !unlimitedSamples)
                {
                    title += ", " + Lib.HumanReadableSampleSize(totalSlots) + " available";
                }
                p.AddSection(title);

                foreach (var idDrivePair in drives)
                {
                    uint partId = idDrivePair.Key;
                    var  drive  = idDrivePair.Value;
                    foreach (var pair in drive.samples)
                    {
                        string samplename = pair.Key;
                        Sample sample     = pair.Value;
                        Render_sample(p, partId, samplename, sample, drive, short_strings && Lib.IsFlight());
                    }
                }

                if (samplesCount == 0)
                {
                    p.AddContent("<i>no samples</i>", string.Empty);
                }
            }
        }
示例#3
0
        public void Update()
        {
            if (Lib.IsFlight())
            {
                Drive drive = DB.Vessel(vessel).drive;

                // if no location was ever specified, set it here
                if (drive.location == 0)
                {
                    drive.location = part.flightID;
                }

                // if this is the location the data is stored
                if (drive.location == part.flightID)
                {
                    // get data size
                    double size = drive.size();

                    // show DATA UI button, with size info
                    Events["ToggleUI"].guiName = Lib.StatusToggle("Data", size > double.Epsilon ? Lib.HumanReadableDataSize(size) : "empty");
                    Events["ToggleUI"].active  = true;

                    // show TakeData eva action button, if there is something to take
                    Events["TakeData"].active = size > double.Epsilon;

                    // show StoreData eva action button, if active vessel is an eva kerbal and there is something to store from it
                    Vessel v = FlightGlobals.ActiveVessel;
                    Events["StoreData"].active = v != null && v.isEVA && !EVA.IsDead(v) && DB.Vessel(v).drive.size() > double.Epsilon;

                    // hide TransferLocation button
                    Events["TransferData"].active = false;
                }
                // if this is not the location the data is stored
                else
                {
                    // hide DATA UI button
                    Events["ToggleUI"].active = false;

                    // hide EVA actions
                    Events["TakeData"].active  = false;
                    Events["StoreData"].active = false;

                    // show TransferData button
                    Events["TransferData"].active = true;
                }
            }
        }
示例#4
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);
        }
示例#5
0
 // return size of data stored in Mb (including samples)
 public string Size()
 {
     return(Lib.BuildString(Lib.HumanReadableDataSize(FilesSize()), "  ", Lib.HumanReadableSampleSize(SamplesSize())));
 }
示例#6
0
        public override void OnStart(StartState state)
        {
            // don't break tutorial scenarios
            if (Lib.DisableScenario(this))
            {
                return;
            }

            if (Lib.IsEditor())
            {
                if (effectiveDataCapacity == -1.0)
                {
                    effectiveDataCapacity = dataCapacity;
                }

                if (dataCapacity > 0.0 && maxDataCapacityFactor > 0)
                {
                    Fields["dataCapacityUI"].guiActiveEditor = true;
                    var o = (UI_ChooseOption)Fields["dataCapacityUI"].uiControlEditor;

                    dataCapacities = GetDataCapacitySizes();
                    int currentCapacityIndex = dataCapacities.FindIndex(p => p.Value == effectiveDataCapacity);
                    if (currentCapacityIndex >= 0)
                    {
                        dataCapacityUI = dataCapacities[currentCapacityIndex].Key;
                    }
                    else
                    {
                        effectiveDataCapacity = dataCapacities[0].Value;
                        dataCapacityUI        = dataCapacities[0].Key;
                    }

                    string[] dataOptions = new string[dataCapacities.Count];
                    for (int i = 0; i < dataCapacities.Count; i++)
                    {
                        dataOptions[i] = Lib.HumanReadableDataSize(dataCapacities[i].Value);
                    }
                    o.options = dataOptions;
                }

                if (effectiveSampleCapacity == -1)
                {
                    effectiveSampleCapacity = sampleCapacity;
                }

                if (sampleCapacity > 0 && maxSampleCapacityFactor > 0)
                {
                    Fields["sampleCapacityUI"].guiActiveEditor = true;
                    var o = (UI_ChooseOption)Fields["sampleCapacityUI"].uiControlEditor;

                    sampleCapacities = GetSampleCapacitySizes();
                    int currentCapacityIndex = sampleCapacities.FindIndex(p => p.Value == effectiveSampleCapacity);
                    if (currentCapacityIndex >= 0)
                    {
                        sampleCapacityUI = sampleCapacities[currentCapacityIndex].Key;
                    }
                    else
                    {
                        effectiveSampleCapacity = sampleCapacities[0].Value;
                        sampleCapacityUI        = sampleCapacities[0].Key;
                    }

                    string[] sampleOptions = new string[sampleCapacities.Count];
                    for (int i = 0; i < sampleCapacities.Count; i++)
                    {
                        sampleOptions[i] = Lib.HumanReadableSampleSize(sampleCapacities[i].Value);
                    }
                    o.options = sampleOptions;
                }
            }

            if (Lib.IsFlight() && hdId == 0)
            {
                hdId = part.flightID;
            }

            if (drive == null)
            {
                if (!Lib.IsFlight())
                {
                    drive = new Drive(title, effectiveDataCapacity, effectiveSampleCapacity, !string.IsNullOrEmpty(experiment_id));
                }
                else
                {
                    PartData pd = vessel.KerbalismData().GetPartData(part.flightID);
                    if (pd.Drive == null)
                    {
                        drive    = new Drive(part.partInfo.title, effectiveDataCapacity, effectiveSampleCapacity, !string.IsNullOrEmpty(experiment_id));
                        pd.Drive = drive;
                    }
                    else
                    {
                        drive = pd.Drive;
                    }
                }
            }

            UpdateCapacity();
        }