public override void OnSave(ConfigNode node) { try { // Check for zombies: if (CLLS.killList.Count > 0) { foreach (ProtoCrewMember kerbal in HighLogic.CurrentGame.CrewRoster.Kerbals(ProtoCrewMember.KerbalType.Crew)) { if (CLLS.killList.Contains(kerbal.name) && kerbal.rosterStatus != ProtoCrewMember.RosterStatus.Dead) { Debug.Log("[CLLS] killing zombie " + kerbal.name); kerbal.rosterStatus = ProtoCrewMember.RosterStatus.Dead; } } } // Update all vessels before their stats are made persistant. This way we don't have to store our // tracking-list with all the meta-information about the vessels: CLLS.UpdateAllTrackedVessels(); // Save the kill-list so that a re-load of a save in the same session (or a switching of the game-scene, // which works by saving and then loading) causes dead kerbals to become alive again: foreach (string kerbalName in CLLS.killList) { node.AddValue("kill_list", kerbalName); } } catch (Exception e) { Debug.LogError("[CLLS] OnSave(): " + e.ToString()); } }
public static string FormatDuration(double duration) { int dayLength = CLLS.GetDayLength(); double seconds = duration % 60; int minutes = ((int)(duration / 60)) % 60; int hours = ((int)(duration / 60 / 60)) % dayLength; int days = ((int)(duration / 60 / 60 / dayLength)); return(String.Format("{0:0} / {1:00}:{2:00}:{3:00.00}", days, hours, minutes, seconds)); }
public override void OnUpdate() { base.OnUpdate(); Vessel vessel = this.part.vessel; if (!vessel.loaded) { return; // Shouldn't happen, but better safe than sorry } TrackedVessel trackedVessel = CLLS.GetTrackedVessel(vessel); // Only calculate the remaining days of life support if there are kerbals on board and they use it: if (trackedVessel.cachedCrewCount <= 0 || trackedVessel.cachedLifeSupportDeltaPerHour > 0) { lifeSupportStatus = "On Standby"; } else { double lifeSupport = trackedVessel.cachedLifeSupport; double consumptionPerHour = -trackedVessel.cachedLifeSupportDeltaPerHour; double displayRate; string unit; displayRate = (float)((lifeSupport / consumptionPerHour)) / CLLS.GetDayLength(); // Show remaining days unit = " days "; // If there is only very little left, go to hours or even minutes: if (displayRate < 2) { displayRate *= 6; unit = " hours "; } if (displayRate < 1) { displayRate *= 60; unit = " min. "; } if (lifeSupport <= 0) { lifeSupportStatus = "DEPLETED"; } else { lifeSupportStatus = displayRate.ToString("0.00") + unit; } } }
public static void DrawWindow() { if (!showGui) { return; } try { int red = 0xD10D0D; int green = 0x00C000; int orange = 0xD79507; GUILayout.BeginVertical(); // Title: GUILayout.BeginArea(new Rect(0, 3, windowStyle.fixedWidth, 20)); GUILayout.Label("<size=14><b>Closed Loop Life Support</b></size>", new GUIStyle(GUI.labelStyle) { fixedWidth = windowStyle.fixedWidth, alignment = TextAnchor.MiddleCenter }); GUILayout.EndArea(); // Find all vessels which we want to display (we don't need debris, asterioids, etc): List <TrackedVessel> trackedVesselsToDisplay = new List <TrackedVessel>(); foreach (TrackedVessel trackedVessel in CLLS.trackedVessels) { if (trackedVessel.cachedCrewCapacity == 0 && trackedVessel.cachedLifeSupport == 0) { continue; } if (trackedVessel.IsUnowned()) { continue; } trackedVesselsToDisplay.Add(trackedVessel); } // Sort by remaining amount ascending but with empty vessels at the bottom: trackedVesselsToDisplay.Sort((x, y) => x.cachedCrewCount == 0 && y.cachedCrewCount != 0 ? 1 : x.cachedCrewCount != 0 && y.cachedCrewCount == 0 ? -1 : x.CalculateCurrentLifeSupportAmount().CompareTo(y.CalculateCurrentLifeSupportAmount()) ); // Content-Box: scrollPos = GUILayout.BeginScrollView(scrollPos, GUI.scrollStyle); if (trackedVesselsToDisplay.Count == 0) { GUILayout.Label("<b>No active flights.</b>"); } else { double curTime = Planetarium.GetUniversalTime(); List <GUIContent> contents = new List <GUIContent>(); // MissionController.missions.Sort((x, y) => x.eta.CompareTo(y.eta)); // Sort list by ETA foreach (TrackedVessel trackedVessel in trackedVesselsToDisplay) { string situation = ""; switch (trackedVessel.vessel.situation) { case Vessel.Situations.DOCKED: situation = "docked near "; break; case Vessel.Situations.ESCAPING: situation = "escaping"; break; case Vessel.Situations.FLYING: situation = "flying at "; break; case Vessel.Situations.LANDED: situation = "landed on "; break; case Vessel.Situations.ORBITING: situation = "orbiting "; break; case Vessel.Situations.PRELAUNCH: situation = "pre-launch on "; break; case Vessel.Situations.SPLASHED: situation = "splashed on "; break; case Vessel.Situations.SUB_ORBITAL: situation = "sub-orbital at "; break; } situation += trackedVessel.vessel.mainBody.name; string content = "<color=#FFFFFF><color=#F9FA86><b><size=14>" + trackedVessel.vessel.vesselName + "</size></b></color> (" + situation + ")\n"; content += "<b>Crew:</b> " + trackedVessel.cachedCrewCount.ToString() + " / " + trackedVessel.cachedCrewCapacity.ToString() + " "; double lifeSupport = trackedVessel.CalculateCurrentLifeSupportAmount(); int color = trackedVessel.cachedLifeSupportDeltaPerHour < 0 ? red : green; content += "<b>Life Support:</b> " + lifeSupport.ToString("#,##0.00") + " / " + trackedVessel.cachedMaxLifeSupport.ToString("#,##0.00") + " "; if (trackedVessel.cachedLifeSupportDeltaPerHour != 0 || trackedVessel.cachedCrewCount > 0) { content += "<color=#" + color.ToString("X6") + ">(Δ " + (trackedVessel.cachedLifeSupportDeltaPerHour * CLLS.GetDayLength()).ToString("+0.00;-0.00") + "/day)</color>\n"; } if (trackedVessel.cachedCrewCount > 0) { content += "<b>Remaining:</b> "; if (trackedVessel.cachedLifeSupportDeltaPerHour >= 0) { content += "<color=#" + green.ToString("X6") + "><b>infinite</b></color>"; } else if (trackedVessel.cachedLifeSupportDeltaPerHour < 0) { double timeRemaining = lifeSupport / -(trackedVessel.cachedLifeSupportDeltaPerHour / 3600d); double boundsUpper = 3600 * 6 * 30; // 30 kerbin-days double boundsLower = 3600 * 6; // 1 kerbin-day if (timeRemaining > boundsUpper) { color = green; } else if (timeRemaining > boundsLower) { color = ScaleRGB(green, orange, (timeRemaining - boundsLower) / (boundsUpper - boundsLower)); } else { color = ScaleRGB(orange, red, timeRemaining / boundsLower); } content += "<color=#" + color.ToString("X6") + ">" + FormatDuration(timeRemaining) + "</color>"; } } content += "</color>"; contents.Add(new GUIContent(content)); } GUILayout.SelectionGrid(-1, contents.ToArray(), 1, GUI.selectionGridStyle); } GUILayout.EndScrollView(); GUILayout.EndVertical(); UnityEngine.GUI.DragWindow(); } catch (Exception e) { Debug.LogError("[CLLS] DrawWindow(): " + e.ToString()); } }
protected void UpdateGUI() { if (isRunning) { Events["StartUp"].active = false; Events["ShutDown"].active = true; displayStatus = "Running"; } else { Events["StartUp"].active = true; Events["ShutDown"].active = false; displayStatus = "Stopped"; } // KSP-Gui elements only work with float, but we are using double, so we use extra varaiables for dispalying these values: efficiencyGui = (float)efficiency; currentProductionRatePerDayGui = (float)(currentProductionRatePerDay * (6f / CLLS.GetDayLength())); // Maybe convert this to 24 hour days currentElectricityRatePerSecGui = (float)currentElectricityRatePerSec; }