예제 #1
0
파일: CrewHandler.cs 프로젝트: Eccta/RP-0
        public string GetTrainingString(ProtoCrewMember pcm)
        {
            bool   found       = false;
            string trainingStr = "\n\nTraining:";

            foreach (FlightLog.Entry ent in pcm.careerLog.Entries)
            {
                string pretty = GetPrettyCourseName(ent.type);
                if (!string.IsNullOrEmpty(pretty))
                {
                    if (ent.type == "TRAINING_proficiency")
                    {
                        found        = true;
                        trainingStr += $"\n  {pretty}{ent.target}";
                    }
                    else if (ent.type == "TRAINING_mission")
                    {
                        double exp = GetExpiration(pcm.name, ent);
                        if (exp > 0d)
                        {
                            trainingStr += $"\n  {pretty}{ent.target}. Expires {KSPUtil.PrintDate(exp, false)}";
                        }
                    }
                }
            }

            if (found)
            {
                return(trainingStr);
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #2
0
        public SaveGameInfo(string saveFile)
        {
            SaveFile = new FileInfo(saveFile);
            MetaData = new Dictionary <string, string>();

            var metaFile = Path.ChangeExtension(saveFile, "loadmeta");

            if (File.Exists(metaFile))
            {
                var content = File.ReadAllLines(metaFile);
                foreach (var line in content)
                {
                    var idx   = line.IndexOf("=");
                    var key   = line.Substring(0, idx).Trim();
                    var value = line.Substring(idx + 1).Trim();
                    MetaData[key] = value;
                }
            }

            string funds = "";

            if (MetaData.TryGetValue("funds", out funds))
            {
                double fundsAmount;
                if (double.TryParse(funds, out fundsAmount))
                {
                    fundsAmount /= 1000.0;
                    string suffix = "k";
                    if (fundsAmount > 1000)
                    {
                        fundsAmount /= 1000.0;
                        suffix       = "m";
                    }
                    if (fundsAmount > 1000)
                    {
                        fundsAmount /= 1000.0;
                        suffix       = "b";
                    }
                    funds = Math.Round(fundsAmount, 1).ToString() + suffix + " funds";
                }
            }

            string gameTime = "";

            if (MetaData.TryGetValue("UT", out gameTime))
            {
                double gameTimeVal;
                if (double.TryParse(gameTime, out gameTimeVal))
                {
                    GameTime     = gameTimeVal;
                    GameTimeText = KSPUtil.PrintDate(GameTime, includeTime: true);
                }
            }

            ButtonText = String.Format("  {0}\n  {1}\n  {2}\n  {3}",
                                       SaveFile.LastWriteTime,
                                       Path.GetFileNameWithoutExtension(SaveFile.Name),
                                       funds,
                                       GameTimeText);
        }
예제 #3
0
 public tabs newCourseTab()
 {
     GUILayout.BeginHorizontal();
     try {
         GUILayout.FlexibleSpace();
         GUILayout.Label(selectedCourse.name);
         GUILayout.FlexibleSpace();
     } finally {
         GUILayout.EndHorizontal();
     }
     GUILayout.Label(selectedCourse.description);
     summaryBody(tabs.NewCourse);
     if (selectedCourse.seatMax > 0)
     {
         GUILayout.Label(selectedCourse.seatMax - selectedCourse.Students.Count + " remaining seat(s).");
     }
     if (selectedCourse.seatMin > selectedCourse.Students.Count)
     {
         GUILayout.Label(selectedCourse.seatMin - selectedCourse.Students.Count + " more student(s) required.");
     }
     GUILayout.Label("Will take " + KSPUtil.PrintDateDeltaCompact(selectedCourse.GetTime(), false, false));
     GUILayout.Label("and finish on " + KSPUtil.PrintDate(selectedCourse.CompletionTime(), false));
     if (GUILayout.Button("Start Course", GUILayout.ExpandWidth(false)))
     {
         if (selectedCourse.StartCourse())
         {
             CrewHandler.Instance.ActiveCourses.Add(selectedCourse);
             selectedCourse = null;
         }
     }
     return(selectedCourse == null ? tabs.Training : tabs.NewCourse);
 }
예제 #4
0
        public void nautTab()
        {
            updateActiveMap();
            GUILayout.BeginHorizontal();
            try {
                GUILayout.FlexibleSpace();
                GUILayout.Label(selectedNaut.name);
                GUILayout.FlexibleSpace();
            } finally {
                GUILayout.EndHorizontal();
            }
            GUILayout.BeginHorizontal();
            try {
                GUILayout.Label($"{selectedNaut.trait} {selectedNaut.experienceLevel.ToString():D}");
                if (CrewHandler.Instance.RetirementEnabled && CrewHandler.Instance.KerbalRetireTimes.ContainsKey(selectedNaut.name))
                {
                    GUILayout.Space(8);
                    GUILayout.Label($"Retires NET {KSPUtil.PrintDate(CrewHandler.Instance.KerbalRetireTimes[selectedNaut.name], false)}", rightLabel);
                }
            } finally {
                GUILayout.EndHorizontal();
            }

            double nlt = CrewHandler.Instance.GetLatestRetireTime(selectedNaut);

            if (nlt > 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label(string.Empty, GUILayout.ExpandWidth(true));
                GUILayout.Label($"Retires NLT {KSPUtil.PrintDate(nlt, false)}", rightLabel);
                GUILayout.EndHorizontal();
            }

            if (activeMap.ContainsKey(selectedNaut))
            {
                ActiveCourse currentCourse = activeMap[selectedNaut];
                GUILayout.BeginHorizontal();
                try {
                    GUILayout.Label($"Studying {currentCourse.name} until {KSPUtil.PrintDate(currentCourse.CompletionTime(), false)}");
                    if (currentCourse.seatMin > 1)
                    {
                        if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
                        {
                            cancelCourse(currentCourse);
                        }
                    }
                    else
                    {
                        if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
                        {
                            leaveCourse(currentCourse, selectedNaut);
                        }
                    }
                } finally {
                    GUILayout.EndHorizontal();
                }
            }
            GUILayout.Label(CrewHandler.Instance.GetTrainingString(selectedNaut));
        }
예제 #5
0
        public void FixedUpdate()
        {
            if (!isCompatible)
            {
                return;
            }
            if (!(HighLogic.LoadedSceneIsFlight || HighLogic.LoadedScene == GameScenes.SPACECENTER))
            {
                return;
            }

            if (!dumpOrbits)
            {
                return;
            }
            counter += TimeWarp.fixedDeltaTime;
            if (counter < 3600)
            {
                return;
            }
            counter = 0;
            if (FlightGlobals.Bodies == null)
            {
                print("**RSS OBTDUMP*** - null body list!");
                return;
            }
            print("**RSS OBTDUMP***");
            int time = (int)Planetarium.GetUniversalTime();

            print("At time " + time + ", " + KSPUtil.PrintDate(time, true, true));
            for (int i = 0; i < FlightGlobals.Bodies.Count; i++)
            {
                CelestialBody body = FlightGlobals.Bodies[i];
                if (body == null || body.orbitDriver == null)
                {
                    continue;
                }
                if (body.orbitDriver.orbit == null)
                {
                    continue;
                }
                Orbit o = body.orbitDriver.orbit;
                print("********* BODY **********");
                print("name = " + body.name + "(" + i + ")");
                Type oType = o.GetType();
                foreach (FieldInfo f in oType.GetFields())
                {
                    if (f == null || f.GetValue(o) == null)
                    {
                        continue;
                    }
                    print(f.Name + " = " + f.GetValue(o));
                }
            }
        }
예제 #6
0
 private void ScheduleStorm()
 {
     try
     {
         nextStorm = Planetarium.GetUniversalTime() + 3600 * 6 * 2 + Core.Instance.mRandom.Next(3600 * 6 * 98);
         Logging.Log("Next storm scheduled for " + KSPUtil.PrintDate((int)nextStorm, true, true));
     }
     catch (NullReferenceException exc)
     {
         Logging.Log("Failed to schedule storm: " + exc.Message + "\n" + exc.StackTrace);
     }
 }
예제 #7
0
파일: CrewHandler.cs 프로젝트: m4gus88/RP-0
        public string GetTrainingString(ProtoCrewMember pcm)
        {
            HashSet <string> expiredProfs = new HashSet <string>();
            bool             found        = false;
            string           trainingStr  = "\n\nTraining:";
            int lastFlight = pcm.careerLog.Last() == null ? 0 : pcm.careerLog.Last().flight;

            foreach (FlightLog.Entry ent in pcm.careerLog.Entries)
            {
                string pretty = GetPrettyCourseName(ent.type);
                if (!string.IsNullOrEmpty(pretty))
                {
                    if (ent.type == "expired_TRAINING_proficiency")
                    {
                        found = true;
                        expiredProfs.Add(ent.target);
                    }
                    else
                    {
                        if (ent.type == "TRAINING_mission" && ent.flight != lastFlight)
                        {
                            continue;
                        }

                        found        = true;
                        trainingStr += "\n  " + pretty + ent.target;
                        double exp = GetExpiration(pcm.name, ent);
                        if (exp > 0d)
                        {
                            trainingStr += ". Expires " + KSPUtil.PrintDate(exp, false);
                        }
                    }
                }
            }
            if (expiredProfs.Count > 0)
            {
                trainingStr += "\n  Expired proficiencies:";
            }
            foreach (string s in expiredProfs)
            {
                trainingStr += "\n    " + s;
            }

            if (found)
            {
                return(trainingStr);
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #8
0
        internal static void Display()
        {
            _scrollDetailsPosition = GUILayout.BeginScrollView(_scrollDetailsPosition, RMStyle.ScrollStyle, GUILayout.Height(230), GUILayout.Width(WindowRoster.ViewerWidth));
            GUILayout.Label(WindowRoster.SelectedKerbal.IsNew ? "Create a Kerbal" : "Kerbal Attributes", RMStyle.LabelStyleBold);

            GUILayout.BeginHorizontal();
            if (RMSettings.EnableKerbalRename)
            {
                GUILayout.Label("Name:", GUILayout.Width(80));
                WindowRoster.SelectedKerbal.Name = GUILayout.TextField(WindowRoster.SelectedKerbal.Name, GUILayout.Width(230));
                GUILayout.Label(" - (" + WindowRoster.SelectedKerbal.Kerbal.trait + ")");
                if (RMLifeSpan.Instance.RMGameSettings.EnableAging)
                {
                    GUILayout.Label("Age: " + WindowRoster.SelectedKerbal.Age.ToString("##0"));
                    GUILayout.Label("Next Bday: " + KSPUtil.PrintDate((int)WindowRoster.SelectedKerbal.TimeNextBirthday, false));
                }
            }
            else
            {
                GUILayout.Label(WindowRoster.SelectedKerbal.Name + " - (" + WindowRoster.SelectedKerbal.Trait + ")", RMStyle.LabelStyleBold, GUILayout.Width(300));
                if (RMLifeSpan.Instance.RMGameSettings.EnableAging)
                {
                    GUILayout.Label("Age: " + WindowRoster.SelectedKerbal.Age.ToString("##0"));
                    GUILayout.Label("Next Bday: " + KSPUtil.PrintDate((int)WindowRoster.SelectedKerbal.TimeNextBirthday, false));
                }
            }
            GUILayout.EndHorizontal();

            if (!string.IsNullOrEmpty(RMAddon.SaveMessage))
            {
                GUILayout.Label(RMAddon.SaveMessage, RMStyle.ErrorLabelRedStyle);
            }
            if (RMSettings.EnableKerbalRename)
            {
                WindowRoster.DisplaySelectProfession();
            }
            WindowRoster.DisplaySelectGender();

            WindowRoster.DisplaySelectSuit(ref WindowRoster.SelectedKerbal.Suit);

            GUILayout.Label("Courage");
            WindowRoster.SelectedKerbal.Courage = GUILayout.HorizontalSlider(WindowRoster.SelectedKerbal.Courage, 0, 1, GUILayout.Width(300));

            GUILayout.Label("Stupidity");
            WindowRoster.SelectedKerbal.Stupidity = GUILayout.HorizontalSlider(WindowRoster.SelectedKerbal.Stupidity, 0, 1, GUILayout.Width(300));

            WindowRoster.SelectedKerbal.Badass = GUILayout.Toggle(WindowRoster.SelectedKerbal.Badass, "Badass");

            GUILayout.EndScrollView();

            WindowRoster.DisplayActionButtonsEdit();
        }
예제 #9
0
        /// <summary>
        /// Deduct the appropriate life support
        /// when first loading a vessel
        /// </summary>
        /// <param name="part">The Part with the life support PartModule</param>
        /// <param name="resource_name">The resource to drain</param>
        /// <param name="resource_rate">The resource drain rate (per second)</param>
        /// <returns>Returns the number of seconds remaining after LifeSupport is deducted</returns>
        public static double StartupRequest(PartModule module, string resource_name, double resource_rate)
        {
            if (module.part.protoModuleCrew.Count == 0)
            {
                Util.Log("Part " + module.part.name + " has no crew - skipping LSM startup");
                return(0.0);
            }

            if (Util.BreathableAir(module.vessel))
            {
                Util.Log("Vessel " + module.vessel.name + " is O2 atmo at " + module.vessel.altitude);
                Util.Log("Startup resource will not be drained");
                return(0.0);
            }

            // Universal Time in seconds
            double lastUT = module.vessel.lastUT;
            double currUT = HighLogic.CurrentGame.UniversalTime;

            // Integer logic could overflow after 233 Kerbin years,
            // so maintain double values for arithmetic
            double delta   = currUT - lastUT;
            double request = module.part.protoModuleCrew.Count * resource_rate * delta;

            // Startup should not be zero unless user is REALLY quick with the mouse
            // (i.e. never).
            if (request < C.DOUBLE_MARGIN)
            {
                Util.Log("CheckThis -> Startup request is zero. This is unexpected. Factors:");
                Util.Log("    Crew count    = " + module.part.protoModuleCrew.Count);
                Util.Log("    Resource rate = " + resource_rate);
                Util.Log("    Time delta    = " + delta);
                return(0.0);
            }

            Util.Log("LastUT = " + lastUT + " (" + KSPUtil.PrintDate((int)lastUT, true, true) + ")");
            Util.Log("CurrUT = " + currUT + " (" + KSPUtil.PrintDate((int)currUT, true, true) + ")");
            Util.Log("Time elapsed: " + delta + " (" + KSPUtil.PrintDateDelta((int)delta, true, true) + ")");
            Util.Log("Initial resource request (" + resource_name + "): " + request);

            // If user has disabled flow of LifeSupport to crewed part, assume this was in error
            // Re-enable so Kerbals don't immediately die upon vessel load
            module.part.Resources[resource_name].flowState = true;

            double obtained = module.part.RequestResource(resource_name, request, C.FLOWMODE_LIFESUPPORT);

            // Calculate remaining time that needs to be deducted from EVA LifeSupport (if applicable)
            return(((request - obtained) / request) * delta);
        }
예제 #10
0
 public void nautTab()
 {
     updateActiveMap();
     GUILayout.BeginHorizontal();
     try {
         GUILayout.FlexibleSpace();
         GUILayout.Label(selectedNaut.name);
         GUILayout.FlexibleSpace();
     } finally {
         GUILayout.EndHorizontal();
     }
     GUILayout.BeginHorizontal();
     try {
         GUILayout.Label(String.Format("{0} {1:D}", selectedNaut.trait, selectedNaut.experienceLevel.ToString()));
         if (CrewHandler.Instance.retirementEnabled && CrewHandler.Instance.kerbalRetireTimes.ContainsKey(selectedNaut.name))
         {
             GUILayout.Space(8);
             GUILayout.Label(String.Format("Retires NET {0}", KSPUtil.PrintDate(CrewHandler.Instance.kerbalRetireTimes[selectedNaut.name], false)),
                             rightLabel);
         }
     } finally {
         GUILayout.EndHorizontal();
     }
     if (activeMap.ContainsKey(selectedNaut))
     {
         ActiveCourse currentCourse = activeMap[selectedNaut];
         GUILayout.BeginHorizontal();
         try {
             GUILayout.Label("Studying " + currentCourse.name + " until " + KSPUtil.PrintDate(currentCourse.CompletionTime(), false));
             if (currentCourse.seatMin > 1)
             {
                 if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
                 {
                     cancelCourse(currentCourse);
                 }
             }
             else
             {
                 if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
                 {
                     leaveCourse(currentCourse, selectedNaut);
                 }
             }
         } finally {
             GUILayout.EndHorizontal();
         }
     }
     GUILayout.Label(CrewHandler.Instance.GetTrainingString(selectedNaut));
 }
예제 #11
0
        public Tabs newCourseTab()
        {
            if (tempCourseLblStyle == null)
            {
                tempCourseLblStyle = new GUIStyle(GUI.skin.label);
                tempCourseLblStyle.normal.textColor = Color.yellow;
            }

            GUILayout.BeginHorizontal();
            try {
                GUILayout.FlexibleSpace();
                GUILayout.Label(selectedCourse.name);
                GUILayout.FlexibleSpace();
            } finally {
                GUILayout.EndHorizontal();
            }
            if (!string.IsNullOrEmpty(selectedCourse.description))
            {
                GUILayout.Label(selectedCourse.description);
            }
            if (selectedCourse.isTemporary)
            {
                GUILayout.Label("Tech for this part is still being researched", tempCourseLblStyle);
            }
            summaryBody(Tabs.NewCourse);
            if (selectedCourse.seatMax > 0)
            {
                GUILayout.Label(selectedCourse.seatMax - selectedCourse.Students.Count + " remaining seat(s).");
            }
            if (selectedCourse.seatMin > selectedCourse.Students.Count)
            {
                GUILayout.Label(selectedCourse.seatMin - selectedCourse.Students.Count + " more student(s) required.");
            }
            GUILayout.Label("Will take " + KSPUtil.PrintDateDeltaCompact(selectedCourse.GetTime(), true, false));
            GUILayout.Label("and finish on " + KSPUtil.PrintDate(selectedCourse.CompletionTime(), false));
            if (GUILayout.Button("Start Course", GUILayout.ExpandWidth(false)))
            {
                if (selectedCourse.StartCourse())
                {
                    CrewHandler.Instance.ActiveCourses.Add(selectedCourse);
                    selectedCourse = null;
                    MaintenanceHandler.Instance?.UpdateUpkeep();
                }
            }
            return(selectedCourse == null ? Tabs.Training : Tabs.NewCourse);
        }
예제 #12
0
파일: FSGUI.cs 프로젝트: KvaNTy/RP-0
        public UITab RenderNewCourseTab()
        {
            if (_tempCourseLblStyle == null)
            {
                _tempCourseLblStyle = new GUIStyle(GUI.skin.label);
                _tempCourseLblStyle.normal.textColor = Color.yellow;
            }

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label(_selectedCourse.name);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            if (!string.IsNullOrEmpty(_selectedCourse.description))
            {
                GUILayout.Label(_selectedCourse.description);
            }
            if (_selectedCourse.isTemporary)
            {
                GUILayout.Label("Tech for this part is still being researched", _tempCourseLblStyle);
            }

            RenderSummaryBody(UITab.NewCourse);
            if (_selectedCourse.seatMax > 0)
            {
                GUILayout.Label($"{_selectedCourse.seatMax - _selectedCourse.Students.Count} remaining seat(s).");
            }
            if (_selectedCourse.seatMin > _selectedCourse.Students.Count)
            {
                GUILayout.Label($"{_selectedCourse.seatMin - _selectedCourse.Students.Count} more student(s) required.");
            }
            GUILayout.Label($"Will take {KSPUtil.PrintDateDeltaCompact(_selectedCourse.GetTime(), true, false)}");
            GUILayout.Label($"and finish on {KSPUtil.PrintDate(_selectedCourse.CompletionTime(), false)}");
            if (GUILayout.Button("Start Course", HighLogic.Skin.button, GUILayout.ExpandWidth(false)))
            {
                if (_selectedCourse.StartCourse())
                {
                    CrewHandler.Instance.ActiveCourses.Add(_selectedCourse);
                    _selectedCourse = null;
                    MaintenanceHandler.Instance?.UpdateUpkeep();
                }
            }
            return(_selectedCourse == null ? UITab.Training : UITab.NewCourse);
        }
예제 #13
0
        /// <summary>
        /// Replaces the common tokens like "[year]" with their appropriate values as gathered from KSP
        /// </summary>
        /// <param name="sourceString">The source string to act on</param>
        /// <returns>The string post replacements</returns>
        public static string ReplaceStandardTokens(string sourceString)
        {
            string str = sourceString;

            str = ReplaceToken(str, "UT", Planetarium.fetch != null ? Math.Round(Planetarium.GetUniversalTime()).ToString() : "0");
            str = ReplaceToken(str, "save", HighLogic.SaveFolder != null && HighLogic.SaveFolder.Trim().Length > 0 ? HighLogic.SaveFolder : "NA");
            str = ReplaceToken(str, "version", Versioning.GetVersionString());
            str = ReplaceToken(str, "vessel", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.vesselName : "NA");
            str = ReplaceToken(str, "body", Planetarium.fetch != null ? Planetarium.fetch.CurrentMainBody.GetDisplayName() : "NA");
            str = ReplaceToken(str, "situation", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.situation.ToString() : "NA");
            str = ReplaceToken(str, "biome", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude) : "NA");


            double ut = 0;

            int[] times = { 0, 0, 0, 0, 0 };
            if (Planetarium.fetch != null)
            {
                ut    = Planetarium.GetUniversalTime();
                times = Utilities.ConvertUT(ut);
            }
            str = ReplaceToken(str, "year", times[0].ToString());
            str = ReplaceToken(str, "year0", times[0].ToString("D3"));
            str = ReplaceToken(str, "day", times[1].ToString());
            str = ReplaceToken(str, "day0", times[1].ToString("D3"));
            str = ReplaceToken(str, "hour", times[2].ToString());
            str = ReplaceToken(str, "hour0", times[2].ToString("D2"));
            str = ReplaceToken(str, "min", times[3].ToString());
            str = ReplaceToken(str, "min0", times[3].ToString("D2"));
            str = ReplaceToken(str, "sec", times[4].ToString());
            str = ReplaceToken(str, "sec0", times[4].ToString("D2"));
            str = ReplaceToken(str, "kspDate", KSPUtil.PrintDate(ut, false).Trim());

            string time = KSPUtil.PrintTimeCompact(0, false);

            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null)
            {
                time = KSPUtil.PrintTimeCompact((int)FlightGlobals.ActiveVessel.missionTime, false);
            }
            time = time.Replace(":", "-"); //Can't use colons in filenames on Windows, so we'll replace them with "-"

            str = ReplaceToken(str, "MET", time);

            return(str);
        }
예제 #14
0
파일: CrewHandler.cs 프로젝트: Eccta/RP-0
        private void FixTooltip(CrewListItem cli)
        {
            ProtoCrewMember pcm = cli.GetCrewRef();

            if (RetirementEnabled && KerbalRetireTimes.TryGetValue(pcm.name, out double retTime))
            {
                cli.SetTooltip(pcm);
                var ttc = _cliTooltip.GetValue(cli) as TooltipController_CrewAC;
                ttc.descriptionString += $"\n\nRetires no earlier than {KSPUtil.PrintDate(retTime, false)}";

                // Training
                string trainingStr = GetTrainingString(pcm);
                if (!string.IsNullOrEmpty(trainingStr))
                {
                    ttc.descriptionString += trainingStr;
                }
            }
        }
예제 #15
0
        public static void Log(string message, bool msg = true)
        {
            string ut = "";

            try
            {
                int t = (int)Planetarium.GetUniversalTime();
                ut = KSPUtil.PrintDate(t, true, true);
            }
            catch (NullReferenceException)
            {
            }
            UnityEngine.Debug.Log("kapparay: [" + ut + "] " + (msg ? "" : "Log: ") + message);
            #if DEBUG
            if (msg)
            {
                Message("kapparay: debug: " + message, false);
            }
            #endif
        }
예제 #16
0
        protected void FixTooltip(KSP.UI.CrewListItem cli)
        {
            ProtoCrewMember pcm = cli.GetCrewRef();
            double          retTime;

            if (retirementEnabled && kerbalRetireTimes.TryGetValue(pcm.name, out retTime))
            {
                cli.SetTooltip(pcm);
                KSP.UI.TooltipTypes.TooltipController_CrewAC ttc = cliTooltip.GetValue(cli) as KSP.UI.TooltipTypes.TooltipController_CrewAC;
                ttc.descriptionString += "\n\nRetires no earlier than " + KSPUtil.PrintDate(retTime, false);

                // Training

                string trainingStr = GetTrainingString(pcm);
                if (!string.IsNullOrEmpty(trainingStr))
                {
                    ttc.descriptionString += trainingStr;
                }
            }
        }
예제 #17
0
파일: CrewHandler.cs 프로젝트: KvaNTy/RP-0
        private void ProcessFirstLoad()
        {
            var newHires = new List <string>();

            foreach (ProtoCrewMember pcm in HighLogic.CurrentGame.CrewRoster.Crew)
            {
                if ((pcm.rosterStatus == ProtoCrewMember.RosterStatus.Assigned || pcm.rosterStatus == ProtoCrewMember.RosterStatus.Available) &&
                    !KerbalRetireTimes.ContainsKey(pcm.name))
                {
                    if (pcm.trait != KerbalRoster.pilotTrait)
                    {
                        KerbalRoster.SetExperienceTrait(pcm, KerbalRoster.pilotTrait);
                    }

                    newHires.Add(pcm.name);
                    OnCrewHired(pcm, int.MinValue);
                }
            }

            if (newHires.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Earliest crew retirement dates:");
                foreach (string s in newHires)
                {
                    sb.Append($"\n{s}, {KSPUtil.PrintDate(KerbalRetireTimes[s], false)}");
                }

                sb.Append($"\n\nInteresting flights will delay retirement up to an additional {Math.Round(Settings.retireIncreaseCap / 31536000)} years.");
                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "InitialRetirementDateNotification",
                                             "Initial Retirement Dates",
                                             sb.ToString(),
                                             "OK",
                                             false,
                                             HighLogic.UISkin);
            }
        }
예제 #18
0
        private void ProcessFirstLoad()
        {
            var newHires = new List <string>();

            foreach (ProtoCrewMember pcm in HighLogic.CurrentGame.CrewRoster.Crew)
            {
                if ((pcm.rosterStatus == ProtoCrewMember.RosterStatus.Assigned || pcm.rosterStatus == ProtoCrewMember.RosterStatus.Available) &&
                    !KerbalRetireTimes.ContainsKey(pcm.name))
                {
                    if (pcm.trait != KerbalRoster.pilotTrait)
                    {
                        KerbalRoster.SetExperienceTrait(pcm, KerbalRoster.pilotTrait);
                    }

                    newHires.Add(pcm.name);
                    OnCrewHired(pcm, int.MinValue);
                }
            }

            if (newHires.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Crew will retire as follows:");
                foreach (string s in newHires)
                {
                    sb.Append($"\n{s}, no earlier than {KSPUtil.PrintDate(KerbalRetireTimes[s], false)}");
                }

                sb.Append("\n(Retirement will be delayed the more interesting flights they fly.)");
                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "InitialRetirementDateNotification",
                                             "Initial Retirement Date",
                                             sb.ToString(),
                                             "OK",
                                             false,
                                             HighLogic.UISkin);
            }
        }
예제 #19
0
 private void nautList()
 {
     GUILayout.BeginHorizontal();
     try {
         GUILayout.Space(20);
         GUILayout.Label("Name", HighLogic.Skin.label, GUILayout.Width(144));
         GUILayout.Label("Retires NET", HighLogic.Skin.label, GUILayout.Width(160));
     } finally {
         GUILayout.EndHorizontal();
     }
     foreach (string name in Crew.CrewHandler.Instance.kerbalRetireTimes.Keys)
     {
         GUILayout.BeginHorizontal();
         try {
             GUILayout.Space(20);
             double rt = Crew.CrewHandler.Instance.kerbalRetireTimes[name];
             GUILayout.Label(name, HighLogic.Skin.label, GUILayout.Width(144));
             GUILayout.Label(Crew.CrewHandler.Instance.retirementEnabled ? KSPUtil.PrintDate(rt, false) : "(n/a)", HighLogic.Skin.label, GUILayout.Width(160));
         } finally {
             GUILayout.EndHorizontal();
         }
     }
 }
예제 #20
0
파일: CrewHandler.cs 프로젝트: KvaNTy/RP-0
        public string GetTrainingString(ProtoCrewMember pcm)
        {
            bool          found = false;
            StringBuilder sb    = new StringBuilder();

            sb.Append("\n\nTraining:");
            foreach (FlightLog.Entry ent in pcm.careerLog.Entries)
            {
                string pretty = GetPrettyCourseName(ent.type);
                if (!string.IsNullOrEmpty(pretty))
                {
                    if (ent.type == TrainingType_Proficiency)
                    {
                        found = true;
                        sb.Append($"\n  {pretty}{ent.target}");
                    }
                    else if (ent.type == TrainingType_Mission)
                    {
                        double exp = GetExpiration(pcm.name, ent);
                        if (exp > 0d)
                        {
                            sb.Append($"\n  {pretty}{ent.target}. Expires {KSPUtil.PrintDate(exp, false)}");
                        }
                    }
                }
            }

            if (found)
            {
                return(sb.ToString());
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #21
0
파일: CrewHandler.cs 프로젝트: KvaNTy/RP-0
        private void FixAstronauComplexUI()
        {
            if (_astronautComplex == null)
            {
                AstronautComplex[] mbs = FindObjectsOfType <AstronautComplex>();
                int maxCount           = -1;
                foreach (AstronautComplex c in mbs)
                {
                    int count = c.ScrollListApplicants.Count + c.ScrollListAssigned.Count + c.ScrollListAvailable.Count + c.ScrollListKia.Count;
                    if (count > maxCount)
                    {
                        maxCount          = count;
                        _astronautComplex = c;
                    }
                }

                if (_astronautComplex == null)
                {
                    return;
                }
            }
            int newAv   = _astronautComplex.ScrollListAvailable.Count;
            int newAsgn = _astronautComplex.ScrollListAssigned.Count;
            int newKIA  = _astronautComplex.ScrollListKia.Count;

            if (newAv != _countAvailable || newKIA != _countKIA || newAsgn != _countAssigned)
            {
                _countAvailable = newAv;
                _countAssigned  = newAsgn;
                _countKIA       = newKIA;

                foreach (UIListData <UIListItem> u in _astronautComplex.ScrollListAvailable)
                {
                    CrewListItem cli = u.listItem.GetComponent <CrewListItem>();
                    if (cli == null)
                    {
                        continue;
                    }

                    FixTooltip(cli);
                    if (cli.GetCrewRef().inactive)
                    {
                        cli.MouseoverEnabled = false;
                        bool notTraining = true;
                        for (int i = ActiveCourses.Count; i-- > 0 && notTraining;)
                        {
                            foreach (ProtoCrewMember pcm in ActiveCourses[i].Students)
                            {
                                if (pcm == cli.GetCrewRef())
                                {
                                    notTraining = false;
                                    cli.SetLabel("Training, done " + KSPUtil.PrintDate(ActiveCourses[i].startTime + ActiveCourses[i].GetTime(ActiveCourses[i].Students), false));
                                    break;
                                }
                            }
                        }
                        if (notTraining)
                        {
                            cli.SetLabel("Recovering");
                        }
                    }
                }

                foreach (UIListData <UIListItem> u in _astronautComplex.ScrollListAssigned)
                {
                    CrewListItem cli = u.listItem.GetComponent <CrewListItem>();
                    if (cli != null)
                    {
                        FixTooltip(cli);
                    }
                }

                foreach (UIListData <UIListItem> u in _astronautComplex.ScrollListKia)
                {
                    CrewListItem cli = u.listItem.GetComponent <CrewListItem>();
                    if (cli != null)
                    {
                        if (_retirees.Contains(cli.GetName()))
                        {
                            cli.SetLabel("Retired");
                            cli.MouseoverEnabled = false;
                        }
                    }
                }
            }
        }
예제 #22
0
파일: CrewHandler.cs 프로젝트: KvaNTy/RP-0
        private void OnCrewHired(ProtoCrewMember pcm, int idx)
        {
            double retireTime;

            // Skip updating the retirement time if this is an existing kerbal.
            if (KerbalRetireTimes.ContainsKey(pcm.name))
            {
                retireTime = KerbalRetireTimes[pcm.name];
            }
            else
            {
                retireTime = KSPUtils.GetUT() + GetServiceTime(pcm);
                KerbalRetireTimes[pcm.name] = retireTime;
            }

            if (RetirementEnabled && idx != int.MinValue)
            {
                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "InitialRetirementDateNotification",
                                             "Initial Retirement Date",
                                             $"{pcm.name} will retire no earlier than {KSPUtil.PrintDate(retireTime, false)}\n(Retirement will be delayed the more interesting flights they fly.)",
                                             "OK",
                                             false,
                                             HighLogic.UISkin);
            }
        }
예제 #23
0
파일: CrewHandler.cs 프로젝트: KvaNTy/RP-0
        private void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog mrDialog, float data)
        {
            Debug.Log("[RP-0] - Vessel recovery processing");

            var retirementChanges = new List <string>();
            var inactivity        = new List <string>();

            double UT = KSPUtils.GetUT();

            // normally we would use v.missionTime, but that doesn't seem to update
            // when you're not actually controlling the vessel
            double elapsedTime = UT - v.launchTime;

            Debug.Log($"[RP-0] mission elapsedTime: {KSPUtil.PrintDateDeltaCompact(elapsedTime, true, true)}");

            // When flight duration was too short, mission training should not be set as expired.
            // This can happen when an on-the-pad failure occurs and the vessel is recovered.
            // We could perhaps override this if they're not actually in flight
            // (if the user didn't recover right from the pad I think this is a fair assumption)
            if (elapsedTime < Settings.minFlightDurationSecondsForTrainingExpire)
            {
                Debug.Log($"[RP-0] - mission time too short for crew to be inactive (elapsed time was {elapsedTime}, settings set for {Settings.minFlightDurationSecondsForTrainingExpire})");
                return;
            }

            var validStatuses = new List <string>
            {
                FlightLog.EntryType.Flight.ToString(), Situation_FlightHigh, FlightLog.EntryType.Suborbit.ToString(),
                FlightLog.EntryType.Orbit.ToString(), FlightLog.EntryType.ExitVessel.ToString(),
                FlightLog.EntryType.Land.ToString(), FlightLog.EntryType.Flyby.ToString()
            };

            foreach (ProtoCrewMember pcm in v.GetVesselCrew())
            {
                Debug.Log("[RP-0] - Found ProtoCrewMember: " + pcm.displayName);

                var    allFlightsDict = new Dictionary <string, int>();
                int    curFlight      = pcm.careerLog.Last().flight;
                double inactivityMult = 0;
                double retirementMult = 0;

                foreach (FlightLog.Entry e in pcm.careerLog.Entries)
                {
                    if (e.type == "Nationality")
                    {
                        continue;
                    }
                    if (e.type == TrainingType_Mission)
                    {
                        SetExpiration(pcm.name, e, KSPUtils.GetUT());
                    }

                    if (validStatuses.Contains(e.type))
                    {
                        int situationCount;
                        var key = $"{e.target}-{e.type}";
                        if (allFlightsDict.ContainsKey(key))
                        {
                            situationCount      = allFlightsDict[key];
                            allFlightsDict[key] = ++situationCount;
                        }
                        else
                        {
                            situationCount = 1;
                            allFlightsDict.Add(key, situationCount);
                        }

                        if (e.flight != curFlight)
                        {
                            continue;
                        }

                        if (TryGetBestSituationMatch(e.target, e.type, "Retire", out double situationMult))
                        {
                            double countMult = 1 + Math.Pow(situationCount - 1, Settings.retireOffsetFlightNumPow);
                            retirementMult += situationMult / countMult;
                        }

                        if (TryGetBestSituationMatch(e.target, e.type, "Inactive", out double inactivMult))
                        {
                            inactivityMult += inactivMult;
                        }
                    }
                }

                Debug.Log("[RP-0]  retirementMult: " + retirementMult);
                Debug.Log("[RP-0]  inactivityMult: " + inactivityMult);

                double acMult = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) + 1;
                Debug.Log("[RP-0]  AC multiplier: " + acMult);

                if (KerbalRetireTimes.TryGetValue(pcm.name, out double retTime))
                {
                    double stupidityPenalty = UtilMath.Lerp(Settings.retireOffsetStupidMin, Settings.retireOffsetStupidMax, pcm.stupidity);
                    Debug.Log($"[RP-0]  stupidityPenalty for {pcm.stupidity}: {stupidityPenalty}");
                    double retireOffset = retirementMult * 86400 * Settings.retireOffsetBaseMult / stupidityPenalty;

                    if (retireOffset > 0)
                    {
                        KerbalRetireIncreases.TryGetValue(pcm.name, out double retIncreaseTotal);
                        retIncreaseTotal += retireOffset;
                        if (retIncreaseTotal > Settings.retireIncreaseCap)
                        {
                            // Cap the total retirement increase at a specific number of years
                            retireOffset    -= retIncreaseTotal - Settings.retireIncreaseCap;
                            retIncreaseTotal = Settings.retireIncreaseCap;
                        }
                        KerbalRetireIncreases[pcm.name] = retIncreaseTotal;

                        string sRetireOffset = KSPUtil.PrintDateDelta(retireOffset, false, false);
                        Debug.Log("[RP-0] retire date increased by: " + sRetireOffset);

                        retTime += retireOffset;
                        KerbalRetireTimes[pcm.name] = retTime;
                        retirementChanges.Add($"\n{pcm.name}, +{sRetireOffset}, no earlier than {KSPUtil.PrintDate(retTime, false)}");
                    }
                }

                inactivityMult = Math.Max(1, inactivityMult);
                double elapsedTimeDays  = elapsedTime / 86400;
                double inactiveTimeDays = Math.Pow(Math.Max(Settings.inactivityMinFlightDurationDays, elapsedTimeDays), Settings.inactivityFlightDurationExponent) *
                                          Math.Min(Settings.inactivityMaxSituationMult, inactivityMult) / acMult;
                double inactiveTime = inactiveTimeDays * 86400;
                Debug.Log("[RP-0] inactive for: " + KSPUtil.PrintDateDeltaCompact(inactiveTime, true, false));

                pcm.SetInactive(inactiveTime, false);
                inactivity.Add($"\n{pcm.name}, until {KSPUtil.PrintDate(inactiveTime + UT, true, false)}");
            }

            if (inactivity.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("The following crew members will be on leave:");
                foreach (string s in inactivity)
                {
                    sb.Append(s);
                }

                if (RetirementEnabled && retirementChanges.Count > 0)
                {
                    sb.Append("\n\nThe following retirement changes have occurred:");
                    foreach (string s in retirementChanges)
                    {
                        sb.Append(s);
                    }
                }

                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "CrewUpdateNotification",
                                             "Crew Updates",
                                             sb.ToString(),
                                             "OK",
                                             true,
                                             HighLogic.UISkin);
            }
        }
예제 #24
0
        protected void OnCrewHired(ProtoCrewMember pcm, int idx)
        {
            double retireTime = Planetarium.GetUniversalTime() + GetServiceTime(pcm);

            kerbalRetireTimes[pcm.name] = retireTime;

            if (retirementEnabled && idx != int.MinValue)
            {
                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "InitialRetirementDateNotification",
                                             "Initial Retirement Date",
                                             pcm.name + " will retire no earlier than " + KSPUtil.PrintDate(retireTime, false)
                                             + "\n(Retirement will be delayed the more interesting flights they fly.)",
                                             "OK",
                                             false,
                                             HighLogic.UISkin);
            }
        }
예제 #25
0
        private void VesselRecoveryProcessing(ProtoVessel v, MissionRecoveryDialog mrDialog, float data)
        {
            Debug.Log("[VR] - Vessel recovery processing");

            List <string> retirementChanges = new List <string>();
            List <string> inactivity        = new List <string>();

            double UT = Planetarium.GetUniversalTime();

            // normally we would use v.missionTime, but that doesn't seem to update
            // when you're not actually controlling the vessel
            double elapsedTime = UT - v.launchTime;

            // When flight duration was too short, mission training should not be set as expired.
            // This can happen when an on-the-pad failure occurs and the vessel is recovered.
            // We could perhaps override this if they're not actually in flight
            // (if the user didn't recover right from the pad I think this is a fair assumption)
            if (elapsedTime < settings.minFlightDurationSecondsForTrainingExpire)
            {
                Debug.Log("[VR] - mission time too short for crew to be inactive (elapsed time was " + elapsedTime + ", settings set for " + settings.minFlightDurationSecondsForTrainingExpire + ")");
                return;
            }

            foreach (ProtoCrewMember pcm in v.GetVesselCrew())
            {
                Debug.Log("[VR] - Found ProtoCrewMember: " + pcm.displayName);

                bool hasSpace      = false;
                bool hasOrbit      = false;
                bool hasEVA        = false;
                bool hasEVAOther   = false;
                bool hasOther      = false;
                bool hasOrbitOther = false;
                bool hasLandOther  = false;
                int  curFlight     = pcm.careerLog.Last().flight;
                foreach (FlightLog.Entry e in pcm.careerLog.Entries)
                {
                    if (e.type == "TRAINING_mission")
                    {
                        SetExpiration(pcm.name, e, Planetarium.GetUniversalTime());
                    }

                    if (e.flight != curFlight)
                    {
                        continue;
                    }

                    bool isOther = false;
                    if (!string.IsNullOrEmpty(e.target) && e.target != Planetarium.fetch.Home.name)
                    {
                        isOther = hasOther = true;
                    }

                    if (!string.IsNullOrEmpty(e.type))
                    {
                        switch (e.type)
                        {
                        case "Suborbit":
                            hasSpace = true;
                            break;

                        case "Orbit":
                            if (isOther)
                            {
                                hasOrbitOther = true;
                            }
                            else
                            {
                                hasOrbit = true;
                            }
                            break;

                        case "ExitVessel":
                            if (isOther)
                            {
                                hasEVAOther = true;
                            }
                            else
                            {
                                hasEVA = true;
                            }
                            break;

                        case "Land":
                            if (isOther)
                            {
                                hasLandOther = true;
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }
                double multiplier = 1d;
                double constant   = 0.5d;
                if (hasSpace)
                {
                    multiplier += settings.recSpace.x;
                    constant   += settings.recSpace.y;
                }
                if (hasOrbit)
                {
                    multiplier += settings.recOrbit.x;
                    constant   += settings.recOrbit.y;
                }
                if (hasOther)
                {
                    multiplier += settings.recOtherBody.x;
                    constant   += settings.recOtherBody.y;
                }
                if (hasOrbit && hasEVA)    // EVA should only count while in orbit, not when walking on Earth
                {
                    multiplier += settings.recEVA.x;
                    constant   += settings.recEVA.y;
                }
                if (hasEVAOther)
                {
                    multiplier += settings.recEVAOther.x;
                    constant   += settings.recEVAOther.y;
                }
                if (hasOrbitOther)
                {
                    multiplier += settings.recOrbitOther.x;
                    constant   += settings.recOrbitOther.y;
                }
                if (hasLandOther)
                {
                    multiplier += settings.recLandOther.x;
                    constant   += settings.recLandOther.y;
                }

                double retTime;
                if (kerbalRetireTimes.TryGetValue(pcm.name, out retTime))
                {
                    double offset = constant * 86400d * settings.retireOffsetBaseMult / (1 + Math.Pow(Math.Max(curFlight + settings.retireOffsetFlightNumOffset, 0d), settings.retireOffsetFlightNumPow)
                                                                                         * UtilMath.Lerp(settings.retireOffsetStupidMin, settings.retireOffsetStupidMax, pcm.stupidity));
                    if (offset > 0d)
                    {
                        retTime += offset;
                        kerbalRetireTimes[pcm.name] = retTime;
                        retirementChanges.Add("\n" + pcm.name + ", no earlier than " + KSPUtil.PrintDate(retTime, false));
                    }
                }

                multiplier /= (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) + 1d);

                double inactiveTime = elapsedTime * multiplier + constant * 86400d;
                pcm.SetInactive(inactiveTime, false);
                inactivity.Add("\n" + pcm.name + ", until " + KSPUtil.PrintDate(inactiveTime + UT, true, false));
            }
            if (inactivity.Count > 0)
            {
                Debug.Log("[VR] - showing on leave message");

                string msgStr = "The following crew members will be on leave:";
                foreach (string s in inactivity)
                {
                    msgStr += s;
                }

                if (retirementEnabled && retirementChanges.Count > 0)
                {
                    msgStr += "\n\nThe following retirement changes have occurred:";
                    foreach (string s in retirementChanges)
                    {
                        msgStr += s;
                    }
                }

                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "CrewUpdateNotification",
                                             "Crew Updates",
                                             msgStr,
                                             "OK",
                                             true,
                                             HighLogic.UISkin);
            }
        }
예제 #26
0
        public void Update()
        {
            if (HighLogic.CurrentGame == null || HighLogic.CurrentGame.CrewRoster == null)
            {
                return;
            }

            // Catch earlies
            if (firstLoad)
            {
                firstLoad = false;
                List <string> newHires = new List <string>();

                foreach (ProtoCrewMember pcm in HighLogic.CurrentGame.CrewRoster.Crew)
                {
                    if ((pcm.rosterStatus == ProtoCrewMember.RosterStatus.Assigned || pcm.rosterStatus == ProtoCrewMember.RosterStatus.Available) && !kerbalRetireTimes.ContainsKey(pcm.name))
                    {
                        newHires.Add(pcm.name);
                        OnCrewHired(pcm, int.MinValue);
                    }
                }
                if (newHires.Count > 0)
                {
                    string msgStr = "Crew will retire as follows:";
                    foreach (string s in newHires)
                    {
                        msgStr += "\n" + s + ", no earlier than " + KSPUtil.PrintDate(kerbalRetireTimes[s], false);
                    }

                    PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                                 new Vector2(0.5f, 0.5f),
                                                 "InitialRetirementDateNotification",
                                                 "Initial Retirement Date",
                                                 msgStr
                                                 + "\n(Retirement will be delayed the more interesting flights they fly.)",
                                                 "OK",
                                                 false,
                                                 HighLogic.UISkin);
                }
            }

            // Retirements
            double time = Planetarium.GetUniversalTime();

            if (nextUpdate < time)
            {
                // Ensure that CrewHandler updates happen at predictable times so that accurate KAC alarms can be set.
                do
                {
                    nextUpdate += updateInterval;
                }while (nextUpdate < time);

                if (retirementEnabled)
                {
                    foreach (KeyValuePair <string, double> kvp in kerbalRetireTimes)
                    {
                        ProtoCrewMember pcm = HighLogic.CurrentGame.CrewRoster[kvp.Key];
                        if (pcm == null)
                        {
                            toRemove.Add(kvp.Key);
                        }
                        else
                        {
                            if (pcm.rosterStatus != ProtoCrewMember.RosterStatus.Available)
                            {
                                if (pcm.rosterStatus != ProtoCrewMember.RosterStatus.Assigned)
                                {
                                    toRemove.Add(kvp.Key);
                                }

                                continue;
                            }

                            if (pcm.inactive)
                            {
                                continue;
                            }

                            if (time > kvp.Value)
                            {
                                toRemove.Add(kvp.Key);
                                retirees.Add(kvp.Key);
                                pcm.rosterStatus = ProtoCrewMember.RosterStatus.Dead;
                            }
                        }
                    }
                }

                bool anyCourseEnded = false;
                for (int i = ActiveCourses.Count; i-- > 0;)
                {
                    ActiveCourse course = ActiveCourses[i];
                    if (course.ProgressTime(time)) //returns true when the course completes
                    {
                        ActiveCourses.RemoveAt(i);
                        anyCourseEnded = true;
                    }
                }

                for (int i = expireTimes.Count; i-- > 0;)
                {
                    TrainingExpiration e = expireTimes[i];
                    if (time > e.expiration)
                    {
                        ProtoCrewMember pcm = HighLogic.CurrentGame.CrewRoster[e.pcmName];
                        if (pcm != null)
                        {
                            for (int j = pcm.careerLog.Entries.Count; j-- > 0;)
                            {
                                int eC = e.entries.Count;
                                if (eC == 0)
                                {
                                    break;
                                }
                                FlightLog.Entry ent = pcm.careerLog[j];
                                for (int k = eC; k-- > 0;)
                                {
                                    // Allow only mission trainings to expire.
                                    // This check is actually only needed for old savegames as only these can have expirations on proficiencies.
                                    if (ent.type == "TRAINING_mission" && e.Compare(k, ent))
                                    {
                                        ScreenMessages.PostScreenMessage(pcm.name + ": Expired: " + GetPrettyCourseName(ent.type) + ent.target);
                                        ent.type = "expired_" + ent.type;
                                        e.entries.RemoveAt(k);
                                    }
                                }
                            }
                        }
                        expireTimes.RemoveAt(i);
                    }
                }

                // TODO remove from courses? Except I think they won't retire if inactive either so that's ok.
                if (toRemove.Count > 0)
                {
                    string msgStr = string.Empty;
                    foreach (string s in toRemove)
                    {
                        kerbalRetireTimes.Remove(s);
                        if (HighLogic.CurrentGame.CrewRoster[s] != null)
                        {
                            msgStr += "\n" + s;
                        }
                    }
                    if (!string.IsNullOrEmpty(msgStr))
                    {
                        PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                                     new Vector2(0.5f, 0.5f),
                                                     "CrewRetirementNotification",
                                                     "Crew Retirement",
                                                     "The following retirements have occurred:\n" + msgStr,
                                                     "OK",
                                                     true,
                                                     HighLogic.UISkin);
                    }

                    toRemove.Clear();
                }

                if (anyCourseEnded || toRemove.Count > 0)
                {
                    MaintenanceHandler.Instance.UpdateUpkeep();
                }
            }

            // UI fixing
            if (inAC)
            {
                if (astronautComplex == null)
                {
                    KSP.UI.Screens.AstronautComplex[] mbs = GameObject.FindObjectsOfType <KSP.UI.Screens.AstronautComplex>();
                    int maxCount = -1;
                    foreach (KSP.UI.Screens.AstronautComplex c in mbs)
                    {
                        int count = c.ScrollListApplicants.Count + c.ScrollListAssigned.Count + c.ScrollListAvailable.Count + c.ScrollListKia.Count;
                        if (count > maxCount)
                        {
                            maxCount         = count;
                            astronautComplex = c;
                        }
                    }

                    if (astronautComplex == null)
                    {
                        return;
                    }
                }
                int newAv   = astronautComplex.ScrollListAvailable.Count;
                int newAsgn = astronautComplex.ScrollListAssigned.Count;
                int newKIA  = astronautComplex.ScrollListKia.Count;
                if (newAv != countAvailable || newKIA != countKIA || newAsgn != countAssigned)
                {
                    countAvailable = newAv;
                    countAssigned  = newAsgn;
                    countKIA       = newKIA;

                    foreach (KSP.UI.UIListData <KSP.UI.UIListItem> u in astronautComplex.ScrollListAvailable)
                    {
                        KSP.UI.CrewListItem cli = u.listItem.GetComponent <KSP.UI.CrewListItem>();
                        if (cli != null)
                        {
                            FixTooltip(cli);
                            if (cli.GetCrewRef().inactive)
                            {
                                cli.MouseoverEnabled = false;
                                bool notTraining = true;
                                for (int i = ActiveCourses.Count; i-- > 0 && notTraining;)
                                {
                                    foreach (ProtoCrewMember pcm in ActiveCourses[i].Students)
                                    {
                                        if (pcm == cli.GetCrewRef())
                                        {
                                            notTraining = false;
                                            cli.SetLabel("Training, done " + KSPUtil.PrintDate(ActiveCourses[i].startTime + ActiveCourses[i].GetTime(ActiveCourses[i].Students), false));
                                            break;
                                        }
                                    }
                                }
                                if (notTraining)
                                {
                                    cli.SetLabel("Recovering");
                                }
                            }
                        }
                    }

                    foreach (KSP.UI.UIListData <KSP.UI.UIListItem> u in astronautComplex.ScrollListAssigned)
                    {
                        KSP.UI.CrewListItem cli = u.listItem.GetComponent <KSP.UI.CrewListItem>();
                        if (cli != null)
                        {
                            FixTooltip(cli);
                        }
                    }

                    foreach (KSP.UI.UIListData <KSP.UI.UIListItem> u in astronautComplex.ScrollListKia)
                    {
                        KSP.UI.CrewListItem cli = u.listItem.GetComponent <KSP.UI.CrewListItem>();
                        if (cli != null)
                        {
                            if (retirees.Contains(cli.GetName()))
                            {
                                cli.SetLabel("Retired");
                                cli.MouseoverEnabled = false;
                            }
                        }
                    }
                }
            }
        }
예제 #27
0
        private static void DisplayKerbal(RMKerbal kerbal)
        {
            GUIStyle labelStyle;

            if (kerbal.Status == ProtoCrewMember.RosterStatus.Dead || kerbal.Status == ProtoCrewMember.RosterStatus.Missing ||
                (kerbal.SalaryContractDispute && kerbal.Trait == "Tourist"))
            {
                labelStyle = RMStyle.LabelStyleRed;
            }
            else if (kerbal.SalaryContractDispute && kerbal.Trait != "Tourist")
            {
                labelStyle = RMStyle.LabelStyleMagenta;
            }
            else if (kerbal.Status == ProtoCrewMember.RosterStatus.Assigned)
            {
                labelStyle = RMStyle.LabelStyleYellow;
            }
            else
            {
                labelStyle = RMStyle.LabelStyle;
            }
            if (InstalledMods.IsDfInstalled && kerbal.Type == ProtoCrewMember.KerbalType.Unowned)
            {
                labelStyle = RMStyle.LabelStyleCyan;
            }

            string buttonToolTip = "Crew Member Name.";

            GUILayout.Label(new GUIContent(kerbal.Name, buttonToolTip), labelStyle, GUILayout.Width(130));
            Rect rect = GUILayoutUtility.GetLastRect();

            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "Crew Member's Current Salary.";
            GUILayout.Label(new GUIContent(kerbal.Salary.ToString("###,##0"), buttonToolTip), labelStyle, GUILayout.Width(55));
            rect = GUILayoutUtility.GetLastRect();
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "Crew Member's Current Outstanding/Owing Salary.";
            GUILayout.Label(new GUIContent(kerbal.OwedSalary.ToString("###,##0"), buttonToolTip), labelStyle, GUILayout.Width(60));
            rect = GUILayoutUtility.GetLastRect();
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "How many Pay periods salary has been in dispute.";
            GUILayout.Label(new GUIContent(kerbal.SalaryContractDisputePeriods.ToString("#0"), buttonToolTip), labelStyle, GUILayout.Width(15));
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "Payrise Requested.";
            GUILayout.Label(new GUIContent(kerbal.PayriseRequired.ToString("###,##0"), buttonToolTip), labelStyle, GUILayout.Width(55));
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "Kerbals usual Profession.";
            GUILayout.Label(new GUIContent(kerbal.RealTrait, buttonToolTip), labelStyle, GUILayout.Width(75));
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }

            buttonToolTip = "Next Salary payment is due on:";
            GUILayout.Label(new GUIContent(KSPUtil.PrintDate((int)kerbal.TimeSalaryDue, false), buttonToolTip), labelStyle, GUILayout.Width(65));
            if (Event.current.type == EventType.Repaint && ShowToolTips)
            {
                ToolTip = RMToolTips.SetActiveToolTip(rect, GUI.tooltip, ref ToolTipActive, 10);
            }
        }
예제 #28
0
파일: CrewHandler.cs 프로젝트: m4gus88/RP-0
        protected void VesselRecoveryRequested(Vessel v)
        {
            double        elapsedTime       = v.missionTime;
            List <string> retirementChanges = new List <string>();
            List <string> inactivity        = new List <string>();

            double UT = Planetarium.GetUniversalTime();

            foreach (ProtoCrewMember pcm in v.GetVesselCrew())
            {
                bool hasSpace      = false;
                bool hasOrbit      = false;
                bool hasEVA        = false;
                bool hasEVAOther   = false;
                bool hasOther      = false;
                bool hasOrbitOther = false;
                bool hasLandOther  = false;
                int  curFlight     = pcm.careerLog.Last().flight;
                foreach (FlightLog.Entry e in pcm.careerLog.Entries)
                {
                    if (e.type == "TRAINING_mission")
                    {
                        SetExpiration(pcm.name, e, Planetarium.GetUniversalTime());
                    }

                    if (e.flight != curFlight)
                    {
                        continue;
                    }

                    bool isOther = false;
                    if (!string.IsNullOrEmpty(e.target) && e.target != Planetarium.fetch.Home.name)
                    {
                        isOther = hasOther = true;
                    }

                    if (!string.IsNullOrEmpty(e.type))
                    {
                        switch (e.type)
                        {
                        case "Suborbit":
                            hasSpace = true;
                            break;

                        case "Orbit":
                            if (isOther)
                            {
                                hasOrbitOther = true;
                            }
                            else
                            {
                                hasOrbit = true;
                            }
                            break;

                        case "ExitVessel":
                            if (isOther)
                            {
                                hasEVAOther = true;
                            }
                            else
                            {
                                hasEVA = true;
                            }
                            break;

                        case "Land":
                            if (isOther)
                            {
                                hasLandOther = true;
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }
                double multiplier = 1d;
                double constant   = 0.5d;
                if (hasSpace)
                {
                    multiplier += settings.recSpace.x;
                    constant   += settings.recSpace.y;
                }
                if (hasOrbit)
                {
                    multiplier += settings.recOrbit.x;
                    constant   += settings.recOrbit.y;
                }
                if (hasOther)
                {
                    multiplier += settings.recOtherBody.x;
                    constant   += settings.recOtherBody.y;
                }
                if (hasEVA)
                {
                    multiplier += settings.recEVA.x;
                    constant   += settings.recEVA.y;
                }
                if (hasEVAOther)
                {
                    multiplier += settings.recEVAOther.x;
                    constant   += settings.recEVAOther.y;
                }
                if (hasOrbitOther)
                {
                    multiplier += settings.recOrbitOther.x;
                    constant   += settings.recOrbitOther.y;
                }
                if (hasLandOther)
                {
                    multiplier += settings.recLandOther.x;
                    constant   += settings.recLandOther.y;
                }

                double retTime;
                if (kerbalRetireTimes.TryGetValue(pcm.name, out retTime))
                {
                    double offset = constant * 86400d * settings.retireOffsetBaseMult / (1 + Math.Pow(Math.Max(curFlight + settings.retireOffsetFlightNumOffset, 0d), settings.retireOffsetFlightNumPow)
                                                                                         * UtilMath.Lerp(settings.retireOffsetStupidMin, settings.retireOffsetStupidMax, pcm.stupidity));
                    if (offset > 0d)
                    {
                        retTime += offset;
                        kerbalRetireTimes[pcm.name] = retTime;
                        retirementChanges.Add("\n" + pcm.name + ", no earlier than " + KSPUtil.PrintDate(retTime, false));
                    }
                }

                multiplier /= (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex) + 1d);

                double inactiveTime = elapsedTime * multiplier + constant * 86400d;
                pcm.SetInactive(inactiveTime, false);
                inactivity.Add("\n" + pcm.name + ", until " + KSPUtil.PrintDate(inactiveTime + UT, true, false));
            }
            if (inactivity.Count > 0)
            {
                string msgStr = "The following crew members will be on leave:";
                foreach (string s in inactivity)
                {
                    msgStr += s;
                }

                if (retirementEnabled && retirementChanges.Count > 0)
                {
                    msgStr += "\n\nThe following retirement changes have occurred:";
                    foreach (string s in retirementChanges)
                    {
                        msgStr += s;
                    }
                }

                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
                                             new Vector2(0.5f, 0.5f),
                                             "CrewUpdateNotification",
                                             "Crew Updates",
                                             msgStr,
                                             "OK",
                                             true,
                                             HighLogic.UISkin);
            }
        }
예제 #29
0
        protected void nautListRow(tabs currentTab, ProtoCrewMember student)
        {
            GUIStyle     style         = HighLogic.Skin.label;
            ActiveCourse currentCourse = null;

            if (activeMap.ContainsKey(student))
            {
                currentCourse = activeMap[student];
            }
            bool onSelectedCourse = selectedCourse != null && currentCourse != null && currentCourse.id == selectedCourse.id;

            if (onSelectedCourse)
            {
                style = boldLabel;
            }
            bool selectedForCourse = selectedCourse != null && selectedCourse.Students.Contains(student);

            GUILayout.BeginHorizontal();
            try {
                GUILayout.Label(String.Format("{0} {1}", student.trait.Substring(0, 1), student.experienceLevel), GUILayout.Width(24));
                if (currentCourse == null && selectedCourse != null && (selectedForCourse || selectedCourse.MeetsStudentReqs(student)))
                {
                    if (toggleButton(student.name, selectedForCourse, GUILayout.Width(144)))
                    {
                        if (selectedForCourse)
                        {
                            selectedCourse.RemoveStudent(student);
                        }
                        else
                        {
                            selectedCourse.AddStudent(student);
                        }
                    }
                }
                else if (currentTab == tabs.Training)
                {
                    if (GUILayout.Button(student.name, GUILayout.Width(144)))
                    {
                        selectedNaut = student;
                    }
                }
                else
                {
                    GUILayout.Label(student.name, GUILayout.Width(144));
                }
                string course, complete, retires;
                if (currentCourse == null)
                {
                    if (student.inactive)
                    {
                        course   = "(inactive)";
                        complete = KSPUtil.PrintDate(student.inactiveTimeEnd, false);
                    }
                    else
                    {
                        course   = "(free)";
                        complete = "(n/a)";
                    }
                }
                else
                {
                    course   = currentCourse.name;
                    complete = KSPUtil.PrintDate(currentCourse.CompletionTime(), false);
                }
                GUILayout.Label(course, GUILayout.Width(96));
                GUILayout.Label(complete, GUILayout.Width(80));
                if (CrewHandler.Instance.kerbalRetireTimes.ContainsKey(student.name))
                {
                    retires = CrewHandler.Instance.retirementEnabled ? KSPUtil.PrintDate(CrewHandler.Instance.kerbalRetireTimes[student.name], false) : "(n/a)";
                }
                else
                {
                    retires = "(unknown)";
                }
                GUILayout.Label(retires, GUILayout.Width(80));
                if (currentCourse != null)
                {
                    if (currentCourse.seatMin > 1)
                    {
                        if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
                        {
                            cancelCourse(currentCourse);
                        }
                    }
                    else
                    {
                        if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
                        {
                            leaveCourse(currentCourse, student);
                        }
                    }
                }
            } finally {
                GUILayout.EndHorizontal();
            }
        }
예제 #30
0
파일: FSGUI.cs 프로젝트: pianojosh/RP-0
        protected void nautListRow(tabs currentTab, ProtoCrewMember student)
        {
            GUIStyle     style         = HighLogic.Skin.label;
            ActiveCourse currentCourse = null;

            if (activeMap.ContainsKey(student))
            {
                currentCourse = activeMap[student];
            }
            bool onSelectedCourse = selectedCourse != null && currentCourse != null && currentCourse.id == selectedCourse.id;

            if (onSelectedCourse)
            {
                style = boldLabel;
            }
            bool selectedForCourse = selectedCourse != null && selectedCourse.Students.Contains(student);

            GUILayout.BeginHorizontal();
            try {
                GUILayout.Label(String.Format("{0} {1}", student.trait.Substring(0, 1), student.experienceLevel), GUILayout.Width(24));
                if (currentCourse == null && selectedCourse != null && (selectedForCourse || selectedCourse.MeetsStudentReqs(student)))
                {
                    if (toggleButton(student.name, selectedForCourse, GUILayout.Width(144)))
                    {
                        if (selectedForCourse)
                        {
                            selectedCourse.RemoveStudent(student);
                        }
                        else
                        {
                            selectedCourse.AddStudent(student);
                        }
                    }
                }
                else if (currentTab == tabs.Training)
                {
                    if (GUILayout.Button(student.name, GUILayout.Width(144)))
                    {
                        selectedNaut = student;
                    }
                }
                else
                {
                    GUILayout.Label(student.name, GUILayout.Width(144));
                }
                string course, complete, retires;
                if (currentCourse == null)
                {
                    if (student.inactive)
                    {
                        course   = "(inactive)";
                        complete = KSPUtil.PrintDate(student.inactiveTimeEnd, false);
                    }
                    else
                    {
                        course   = "(free)";
                        complete = "(n/a)";
                    }
                }
                else
                {
                    course   = currentCourse.name;
                    complete = KSPUtil.PrintDate(currentCourse.CompletionTime(), false);
                }
                GUILayout.Label(course, GUILayout.Width(96));
                GUILayout.Label(complete, GUILayout.Width(80));
                if (CrewHandler.Instance.kerbalRetireTimes.ContainsKey(student.name))
                {
                    retires = CrewHandler.Instance.retirementEnabled ? KSPUtil.PrintDate(CrewHandler.Instance.kerbalRetireTimes[student.name], false) : "(n/a)";
                }
                else
                {
                    retires = "(unknown)";
                }
                GUILayout.Label(retires, GUILayout.Width(80));
                if (currentCourse != null)
                {
                    if (currentCourse.seatMin > 1)
                    {
                        if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
                        {
                            cancelCourse(currentCourse);
                        }
                    }
                    else
                    {
                        if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
                        {
                            leaveCourse(currentCourse, student);
                        }
                    }

                    if (KACWrapper.APIReady && GUILayout.Button(nautRowAlarmBtnContent, GUILayout.ExpandWidth(false)))
                    {
                        // CrewHandler processes trainings every 3600 seconds. Need to account for that to set up accurate KAC alarms.
                        double completeUT = currentCourse.CompletionTime();
                        double timeDiff   = completeUT - CrewHandler.Instance.nextUpdate;
                        double timesChRun = Math.Ceiling(timeDiff / CrewHandler.Instance.updateInterval);
                        double alarmUT    = CrewHandler.Instance.nextUpdate + timesChRun * CrewHandler.Instance.updateInterval;
                        string alarmTxt   = $"{currentCourse.name} - {student.name}";
                        KACWrapper.KAC.CreateAlarm(KACWrapper.KACAPI.AlarmTypeEnum.Crew, alarmTxt, alarmUT);
                    }
                }
            } finally {
                GUILayout.EndHorizontal();
            }
        }