public void Update() { if (!KerbalHealthGeneralSettings.Instance.modEnabled) { if (reportWindow != null) { reportWindow.Dismiss(); } return; } if ((reportWindow != null) && dirty) { if (gridContents == null) { Core.Log("gridContents is null.", LogLevel.Error); return; } // # of tracked kerbals has changed => close & reopen the window if (gridContents.Count != (ShipConstruction.ShipManifest.CrewCount + 1) * colNum) { Core.Log("Kerbals' number has changed. Recreating the Health Report window.", LogLevel.Important); UndisplayData(); DisplayData(); } // Fill the Health Report's grid with kerbals' health data int i = 0; KerbalHealthStatus khs = null; HealthModifierSet.VesselCache.Clear(); List <ModuleKerbalHealth> trainingParts = Core.GetTrainingCapableParts(EditorLogic.SortedShipList); foreach (ProtoCrewMember pcm in ShipConstruction.ShipManifest.GetAllCrew(false).Where(pcm => pcm != null)) { khs = Core.KerbalHealthList[pcm]?.Clone(); if (khs == null) { Core.Log("Could not create a clone of KerbalHealthStatus for " + pcm.name + ". It is " + ((Core.KerbalHealthList[pcm] == null) ? "not " : "") + "found in KerbalHealthList, which contains " + Core.KerbalHealthList.Count + " records.", LogLevel.Error); i++; continue; } gridContents[(i + 1) * colNum].SetOptionText(khs.FullName); khs.HP = khs.MaxHP; // Making this call here, so that GetBalanceHP doesn't have to: double changePerDay = khs.HealthChangePerDay(); double balanceHP = khs.GetBalanceHP(); string s = balanceHP > 0 ? "-> " + balanceHP.ToString("F0") + " HP (" + (balanceHP / khs.MaxHP * 100).ToString("F0") + "%)" : Localizer.Format("#KH_ER_HealthPerDay", changePerDay.ToString("F1")); // + " HP/day" gridContents[(i + 1) * colNum + 1].SetOptionText(s); s = balanceHP > khs.NextConditionHP() ? "—" : ((khs.LastRecuperation > khs.LastDecay) ? "> " : "") + Core.ParseUT(khs.TimeToNextCondition(), false, 100); gridContents[(i + 1) * colNum + 2].SetOptionText(s); gridContents[(i + 1) * colNum + 3].SetOptionText(KerbalHealthFactorsSettings.Instance.TrainingEnabled ? Core.ParseUT(TrainingTime(khs, trainingParts), false, 100) : "N/A"); i++; } spaceLbl.SetOptionText("<color=\"white\">" + khs.VesselModifiers.Space.ToString("F1") + "</color>"); recupLbl.SetOptionText("<color=\"white\">" + khs.VesselModifiers.Recuperation.ToString("F1") + "%</color>"); shieldingLbl.SetOptionText("<color=\"white\">" + khs.VesselModifiers.Shielding.ToString("F1") + "</color>"); exposureLbl.SetOptionText("<color=\"white\">" + khs.LastExposure.ToString("P1") + "</color>"); shelterExposureLbl.SetOptionText("<color=\"white\">" + khs.VesselModifiers.ShelterExposure.ToString("P1") + "</color>"); dirty = false; } }
/// <summary> /// Displays actual values in Health Monitor /// </summary> public void Update() { if (!Core.ModEnabled) { if (monitorWindow != null) { monitorWindow.Dismiss(); } return; } if ((monitorWindow == null) || !dirty) { return; } if (gridContents == null) { Core.Log("KerbalHealthScenario.gridContents is null.", Core.LogLevel.Error); return; } if (selectedKHS == null) // Showing list of all kerbals { if (crewChanged) { Core.KerbalHealthList.RegisterKerbals(); if ((page >= PageCount) || (Core.KerbalHealthList.Count == LinesPerPage + 1)) { Invalidate(); } crewChanged = false; } // Fill the Health Monitor's grid with kerbals' health data for (int i = 0; i < LineCount; i++) { List <KerbalHealthStatus> kerbals = new List <KerbalHealth.KerbalHealthStatus>(Core.KerbalHealthList.Values); KerbalHealthStatus khs = kerbals[FirstLine + i]; bool frozen = khs.HasCondition("Frozen"); double ch = khs.LastChangeTotal; gridContents[(i + 1) * colNumMain].SetOptionText(khs.Name); gridContents[(i + 1) * colNumMain + 1].SetOptionText(khs.ConditionString); gridContents[(i + 1) * colNumMain + 2].SetOptionText((100 * khs.Health).ToString("F2") + "% (" + khs.HP.ToString("F2") + ")"); gridContents[(i + 1) * colNumMain + 3].SetOptionText((frozen || (khs.Health >= 1)) ? "—" : (((ch > 0) ? "+" : "") + ch.ToString("F2"))); double b = khs.GetBalanceHP(); string s = ""; if (frozen || (b > khs.NextConditionHP())) { s = "—"; } else { s = ((b > 0) ? "> " : "") + Core.ParseUT(khs.TimeToNextCondition(), true, 100); } gridContents[(i + 1) * colNumMain + 4].SetOptionText(s); gridContents[(i + 1) * colNumMain + 5].SetOptionText(khs.Dose.ToString("N0") + (khs.Radiation != 0 ? " (+" + khs.Radiation.ToString("N0") + "/day)" : "")); } } else // Showing details for one particular kerbal { ProtoCrewMember pcm = selectedKHS.PCM; bool frozen = selectedKHS.HasCondition("Frozen"); gridContents[1].SetOptionText(selectedKHS.Name); gridContents[3].SetOptionText(pcm.experienceLevel.ToString()); string s = ""; foreach (Quirk q in selectedKHS.Quirks) { if (q.IsVisible) { s += ((s != "") ? ", " : "") + q.Title; } } if (s == "") { s = "None"; } gridContents[5].SetOptionText(s); gridContents[7].SetOptionText(pcm.rosterStatus.ToString()); gridContents[9].SetOptionText(selectedKHS.MaxHP.ToString("F2")); gridContents[11].SetOptionText(selectedKHS.HP.ToString("F2") + " (" + selectedKHS.Health.ToString("P2") + ")"); gridContents[13].SetOptionText(frozen ? "—" : selectedKHS.LastChangeTotal.ToString("F2")); int i = 15; if (Core.IsKerbalLoaded(selectedKHS.PCM) && !frozen) { foreach (HealthFactor f in Core.Factors) { gridContents[i].SetOptionText(selectedKHS.Factors.ContainsKey(f.Name) ? selectedKHS.Factors[f.Name].ToString("F2") : "N/A"); i += 2; } } gridContents[i].SetOptionText(frozen ? "N/A" : selectedKHS.LastRecuperation.ToString("F1") + "% (" + selectedKHS.MarginalChange.ToString("F2") + " HP/day)"); gridContents[i + 2].SetOptionText(selectedKHS.ConditionString); gridContents[i + 4].SetOptionText(selectedKHS.Exposure.ToString("P2")); gridContents[i + 6].SetOptionText(selectedKHS.Radiation.ToString("N2") + "/day"); gridContents[i + 8].SetOptionText(selectedKHS.Dose.ToString("N2")); gridContents[i + 10].SetOptionText((1 - selectedKHS.RadiationMaxHPModifier).ToString("P2")); } dirty = false; }
public void Update() { if (!Core.ModEnabled) { if (reportWindow != null) { reportWindow.Dismiss(); } return; } if ((reportWindow != null) && dirty) { if (gridContents == null) { Core.Log("gridContents is null.", Core.LogLevel.Error); return; } if (gridContents.Count != (ShipConstruction.ShipManifest.CrewCount + 1) * colNum) // # of tracked kerbals has changed => close & reopen the window { Core.Log("Kerbals' number has changed. Recreating the Health Report window.", Core.LogLevel.Important); UndisplayData(); DisplayData(); } // Fill the Health Report's grid with kerbals' health data int i = 0; KerbalHealthStatus khs = null; VesselHealthInfo.Cache.Clear(); foreach (ProtoCrewMember pcm in ShipConstruction.ShipManifest.GetAllCrew(false)) { if (pcm == null) { continue; } gridContents[(i + 1) * colNum].SetOptionText(pcm.name); khs = Core.KerbalHealthList?.Find(pcm)?.Clone(); if (khs == null) { Core.Log("Could not create a clone of KerbalHealthStatus for " + pcm.name + ". It is " + ((Core.KerbalHealthList?.Find(pcm) == null) ? "not " : "") + "found in KerbalHealthList, which contains " + Core.KerbalHealthList.Count + " records.", Core.LogLevel.Error); i++; continue; } khs.HP = khs.MaxHP; double ch = khs.HealthChangePerDay(); double b = khs.GetBalanceHP(); string s = ""; if (b > 0) { s = "-> " + b.ToString("F0") + " HP (" + (b / khs.MaxHP * 100).ToString("F0") + "%)"; } else { s = ch.ToString("F1") + " HP/day"; } gridContents[(i + 1) * colNum + 1].SetOptionText(s); if (b > khs.NextConditionHP()) { s = "—"; } else { s = ((khs.LastRecuperation > khs.LastDecay) ? "> " : "") + Core.ParseUT(khs.TimeToNextCondition()); } gridContents[(i + 1) * colNum + 2].SetOptionText(s); i++; } spaceLbl.SetOptionText(khs.VesselHealthInfo.Space.ToString("F1")); recupLbl.SetOptionText(khs.VesselHealthInfo.Recuperation.ToString("F1") + "%"); shieldingLbl.SetOptionText(khs.VesselHealthInfo.Shielding.ToString("F1")); exposureLbl.SetOptionText(khs.Exposure.ToString("P1")); dirty = false; } }
/// <summary> /// Displays actual values in Health Monitor /// </summary> public void Update() { if (!Core.ModEnabled) { if (monitorWindow != null) { monitorWindow.Dismiss(); } return; } if ((monitorWindow == null) || !dirty) { return; } if (gridContents == null) { Core.Log("KerbalHealthScenario.gridContents is null.", Core.LogLevel.Error); monitorWindow.Dismiss(); return; } if (selectedKHS == null) // Showing list of all kerbals { if (crewChanged) { Core.KerbalHealthList.RegisterKerbals(); Invalidate(); crewChanged = false; } Core.Log(kerbals.Count + " kerbals in Health Monitor list."); // Fill the Health Monitor's grid with kerbals' health data for (int i = 0; i < LineCount; i++) { KerbalHealthStatus khs = kerbals.Values[FirstLine + i]; bool healthFrozen = khs.IsFrozen || khs.IsDecontaminating; double ch = khs.LastChangeTotal; double b = khs.GetBalanceHP(); string formatTag = "", formatUntag = ""; string s = ""; if (healthFrozen || ((b - khs.NextConditionHP()) * ch <= 0)) { s = "—"; } else { s = Core.ParseUT(khs.TimeToNextCondition(), true, 100); if (ch < 0) { if (khs.TimeToNextCondition() < KSPUtil.dateTimeFormatter.Day) { formatTag = "<color=\"red\">"; } else { formatTag = "<color=\"orange\">"; } formatUntag = "</color>"; } } gridContents[(i + 1) * colNumMain].SetOptionText(formatTag + khs.Name + formatUntag); gridContents[(i + 1) * colNumMain + 1].SetOptionText(formatTag + khs.LocationString + formatUntag); gridContents[(i + 1) * colNumMain + 2].SetOptionText(formatTag + khs.ConditionString + formatUntag); gridContents[(i + 1) * colNumMain + 3].SetOptionText(formatTag + (100 * khs.Health).ToString("F2") + "% (" + khs.HP.ToString("F2") + ")" + formatUntag); gridContents[(i + 1) * colNumMain + 4].SetOptionText(formatTag + ((healthFrozen || (khs.Health >= 1)) ? "—" : (((ch > 0) ? "+" : "") + ch.ToString("F2"))) + formatUntag); gridContents[(i + 1) * colNumMain + 5].SetOptionText(formatTag + s + formatUntag); gridContents[(i + 1) * colNumMain + 6].SetOptionText(formatTag + Core.PrefixFormat(khs.Dose, 5) + (khs.Radiation != 0 ? " (" + Core.PrefixFormat(khs.Radiation, 4, true) + "/day)" : "") + formatUntag); } } else // Showing details for one particular kerbal { ProtoCrewMember pcm = selectedKHS.PCM; if (pcm == null) { selectedKHS = null; Invalidate(); } bool healthFrozen = selectedKHS.IsFrozen || selectedKHS.IsDecontaminating; gridContents[1].SetOptionText("<color=\"white\">" + selectedKHS.Name + "</color>"); gridContents[3].SetOptionText("<color=\"white\">" + pcm.experienceLevel + "</color>"); gridContents[5].SetOptionText("<color=\"white\">" + selectedKHS.ConditionString + "</color>"); string s = ""; foreach (Quirk q in selectedKHS.Quirks) { if (q.IsVisible) { s += ((s != "") ? ", " : "") + q.Title; } } if (s == "") { s = "None"; } gridContents[7].SetOptionText("<color=\"white\">" + s + "</color>"); gridContents[9].SetOptionText("<color=\"white\">" + selectedKHS.MaxHP.ToString("F2") + "</color>"); gridContents[11].SetOptionText("<color=\"white\">" + selectedKHS.HP.ToString("F2") + " (" + selectedKHS.Health.ToString("P2") + ")" + "</color>"); gridContents[13].SetOptionText("<color=\"white\">" + (healthFrozen ? "—" : selectedKHS.LastChangeTotal.ToString("F2")) + "</color>"); int i = 15; if (Core.IsKerbalLoaded(selectedKHS.PCM) && !healthFrozen) { foreach (HealthFactor f in Core.Factors) { gridContents[i].SetOptionText("<color=\"white\">" + (selectedKHS.Factors.ContainsKey(f.Name) ? selectedKHS.Factors[f.Name].ToString("F2") : "N/A") + "</color>"); i += 2; } } gridContents[i].SetOptionText("<color=\"white\">" + (healthFrozen ? "N/A" : (selectedKHS.LastRecuperation.ToString("F1") + "%" + (selectedKHS.LastDecay != 0 ? ("/ " + (-selectedKHS.LastDecay).ToString("F1") + "%") : "") + " (" + selectedKHS.MarginalChange.ToString("F2") + " HP)")) + "</color>"); gridContents[i + 2].SetOptionText("<color=\"white\">" + selectedKHS.LastExposure.ToString("P2") + "</color>"); gridContents[i + 4].SetOptionText("<color=\"white\">" + selectedKHS.Radiation.ToString("N0") + "/day</color>"); gridContents[i + 6].children[0].SetOptionText("<color=\"white\">" + selectedKHS.Dose.ToString("N0") + "</color>"); gridContents[i + 8].SetOptionText("<color=\"white\">" + (1 - selectedKHS.RadiationMaxHPModifier).ToString("P2") + "</color>"); } dirty = false; }