private LifeSupportVesselDisplayStat GetEvaKerbalStats(Vessel kerbal) { var lblColor = "FFD966"; var vstat = new LifeSupportVesselDisplayStat(); vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, kerbal.vesselName); vstat.LastUpdate = kerbal.missionTime; var sitString = "(EVA)"; var remEVATime = LifeSupportScenario.Instance.settings.GetSettings().EVATime - kerbal.missionTime; var timeString = LifeSupportUtilities.SmartDurationDisplay(Math.Max(0, remEVATime)); if (remEVATime > 0) { vstat.SummaryLabel = String.Format( "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2}</color><color=#3DB1FF> time remaining</color>" , kerbal.mainBody.bodyName , sitString , timeString.Substring(timeString.IndexOf(':') + 1)); } else { vstat.SummaryLabel = "<color=#FF8585>EVA Time Expired</color>"; } vstat.crew = new List <LifeSupportCrewDisplayStat>(); return(vstat); }
private string GetRemainingTimeWithGraceLabel(double timeLeft, double graceTime, string graceTimeDisplay, string inGraceTimeMessage, int effectWhenExpires) { if (effectWhenExpires == 0) { return("<color=#6FFF00>indefinite</color>"); } if (timeLeft > 0) { return(String.Format("<color=#6FFF00>{0} (+{1})</color>", LifeSupportUtilities.SmartDurationDisplay(timeLeft), graceTimeDisplay)); } else { var exceededTime = -timeLeft; if (exceededTime < graceTime / 2) { return(String.Format("<color=#FFE100>{0} ({1})</color>", LifeSupportUtilities.SmartDurationDisplay(graceTime - exceededTime), inGraceTimeMessage)); } else if (exceededTime < graceTime) { return(String.Format("<color=#FFAE00>{0} ({1})</color>", LifeSupportUtilities.SmartDurationDisplay(graceTime - exceededTime), inGraceTimeMessage)); } else // exceededTime > graceTime { return("<color=#FF5E5E>expired</color>"); } } }
private void GenerateWindow() { if (Planetarium.GetUniversalTime() > _lastGUIUpdate + _guiCheckInterval) { _lastGUIUpdate = Planetarium.GetUniversalTime(); EcGraceTimeDisplay = LifeSupportUtilities.CompactDurationDisplay(LifeSupportScenario.Instance.settings.GetSettings().ECTime); SuppliesGraceTimeDisplay = LifeSupportUtilities.CompactDurationDisplay(LifeSupportScenario.Instance.settings.GetSettings().SupplyTime); _guiStats = UpdateGUIStats(); } GUILayout.BeginVertical(); scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(800), GUILayout.Height(350)); GUILayout.BeginVertical(); try { foreach (var v in _guiStats) { DisplayVesselStats(v); } } catch (Exception ex) { Debug.Log(ex.StackTrace); } finally { GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); } }
internal static double GetTotalHabTime(VesselSupplyStatus sourceVessel, Vessel vsl, out int numSharedVessels) { //In the event that a vessel is not loaded, we just return the cached value. if (!vsl.loaded) { numSharedVessels = 0; return(sourceVessel.CachedHabTime); } double totHabSpace = sourceVessel.ExtraHabSpace; double totHabMult = sourceVessel.VesselHabMultiplier; int totCurCrew = sourceVessel.NumCrew; int totMaxCrew = sourceVessel.CrewCap; numSharedVessels = 0; var vList = LogisticsTools.GetNearbyVessels((float)LifeSupportScenario.Instance.settings.GetSettings().HabRange, false, vsl, false); var hList = new List <Vessel>(); var vCount = vList.Count; for (int i = 0; i < vCount; ++i) { var v = vList[i]; //Hab time starts with our baseline of the crew hab plus extra hab. //We then multiply it out based on the crew ratio, our global multiplier, and the vessel's multipler. //First - crew capacity. int crewCap = v.GetCrewCapacity(); totMaxCrew += crewCap; totCurCrew += v.GetCrewCount(); if (crewCap > 0) { numSharedVessels++; hList.Add(v); } } totHabSpace += (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *totMaxCrew); var hCount = hList.Count; for (int i = 0; i < hCount; ++i) { var v = hList[i]; // Calculate HabSpace and HabMult after we know totCurCrew and totMaxCrew totHabSpace += CalculateVesselHabExtraTime(v); totHabMult *= Math.Min(1, CalculateVesselHabMultiplier(v, totCurCrew)); } totHabMult += USI_GlobalBonuses.Instance.GetHabBonus(vsl.mainBody.flightGlobalsIndex); double habTotal = totHabSpace / (double)totCurCrew * (totHabMult + 1) * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier; //print(String.Format("THS: {0} TC:{1} THM: {2} HM: {3}", totHabSpace, totCurCrew, totHabMult, LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier)); sourceVessel.CachedHabTime = Math.Max(0, habTotal * LifeSupportUtilities.SecondsPerMonth()); LifeSupportManager.Instance.TrackVessel(sourceVessel); return(sourceVessel.CachedHabTime); }
internal static double GetTotalHabTime(VesselSupplyStatus sourceVessel, out int numSharedVessels) { var vsl = FlightGlobals.Vessels.FirstOrDefault(v => v.id.ToString() == sourceVessel.VesselId); double totHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *sourceVessel.CrewCap) + sourceVessel.ExtraHabSpace; double totHabMult = sourceVessel.VesselHabMultiplier; int totCurCrew = sourceVessel.NumCrew; int totMaxCrew = sourceVessel.CrewCap; numSharedVessels = 0; var vList = LogisticsTools.GetNearbyVessels((float)LifeSupportScenario.Instance.settings.GetSettings().HabRange, false, vsl, false); var hList = new List <Vessel>(); foreach (var v in vList) { //Hab time starts with our baseline of the crew hab plus extra hab. //We then multiply it out based on the crew ratio, our global multiplier, and the vessel's multipler. //First - crew capacity. int crewCap = v.GetCrewCapacity(); totMaxCrew += crewCap; totCurCrew += v.GetCrewCount(); if (crewCap > 0) { numSharedVessels++; hList.Add(v); } } foreach (var v in hList) { // Calculate HabSpace and HabMult after we know totCurCrew and totMaxCrew totHabSpace += (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *totMaxCrew) + CalculateVesselHabExtraTime(v); totHabMult += CalculateVesselHabMultiplier(v, totCurCrew); } totHabMult += USI_GlobalBonuses.Instance.GetHabBonus(vsl.mainBody.flightGlobalsIndex); double habTotal = totHabSpace / (double)totCurCrew * (totHabMult + 1) * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier; //print(String.Format("THS: {0} TC:{1} THM: {2} HM: {3}", totHabSpace, totCurCrew, totHabMult, LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier)); return(Math.Max(0, habTotal * LifeSupportUtilities.SecondsPerMonth())); }
internal void ComputeHome(ProtoCrewMember c, LifeSupportStatus cls) { var crewHomeString = "indefinite"; var lblHome = "6FFF00"; var useHabPenalties = LifeSupportManager.GetNoHomeEffect(c.name) > 0; if (useHabPenalties) { var homeTimeLeft = cls.MaxOffKerbinTime - Planetarium.GetUniversalTime(); UpdateEarliestExpiration(homeTimeLeft); var isScout = c.HasEffect("ExplorerSkill") && homeTimeLeft >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime; var isPermaHab = homeTimeLeft >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime; if (isScout || isPermaHab) { crewHomeString = "indefinite"; } else if (homeTimeLeft < 0) { lblHome = "FF5E5E"; crewHomeString = "expired"; } else { crewHomeString = LifeSupportUtilities.SmartDurationDisplay(homeTimeLeft); var secondsPerDay = LifeSupportUtilities.SecondsPerDay(); if (homeTimeLeft < secondsPerDay * 30) //15 days { lblHome = "FFE100"; } if (homeTimeLeft < secondsPerDay * 15) { lblHome = "FFAE00"; } } } HomeLabel = String.Format("<color=#{0}>{1}</color>", lblHome, crewHomeString); }
private void ApplyEffect(LifeSupportStatus trackedKerbal, ProtoCrewMember crewMember, int effectId, string reason) { //Tourists are immune to effects if (crewMember.type == ProtoCrewMember.KerbalType.Tourist || crewMember.experienceTrait.Config.Name == "Tourist") { return; } /* SIDE EFFECTS: * 0 = No Effect (The feature is effectively turned off) * 1 = Grouchy (they become a Tourist until rescued) * 2 = Mutinous (Also a tourist, but a random part of the ship is decoupled as they search for snacks) * 3 = Instantly 'wander' back to the KSC - don't ask us how! * 4 = M.I.A. (will eventually respawn) * 5 = K.I.A. */ var msg = ""; switch (effectId) { case 0: // No effect return; // No need to print case 1: //Grouchy msg = string.Format("{0} refuses to work {1}", crewMember.name, reason); trackedKerbal.OldTrait = crewMember.experienceTrait.Config.Name; crewMember.type = ProtoCrewMember.KerbalType.Tourist; KerbalRoster.SetExperienceTrait(crewMember, "Tourist"); trackedKerbal.IsGrouchy = true; LifeSupportManager.Instance.TrackKerbal(trackedKerbal); break; case 2: //Mutinous msg = string.Format("{0} has become mutinous due to {1}", crewMember.name, reason); trackedKerbal.OldTrait = crewMember.experienceTrait.Config.Name; crewMember.type = ProtoCrewMember.KerbalType.Tourist; KerbalRoster.SetExperienceTrait(crewMember, "Tourist"); trackedKerbal.IsGrouchy = true; LifeSupportManager.Instance.TrackKerbal(trackedKerbal); ClipRandomPart(); SpawnExtraSupplies(100f); break; case 3: //Return to KSC msg = string.Format("{0} gets fed up and wanders back to the KSC due to {1}", crewMember.name, reason); LifeSupportManager.Instance.UntrackKerbal(crewMember.name); crewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available; vessel.CrewListSetDirty(); LifeSupportUtilities.RemoveCrewFromPart(crewMember, vessel); break; case 4: //Despawn msg = string.Format("{0} has gone missing due to {1}", crewMember.name, reason); LifeSupportManager.Instance.UntrackKerbal(crewMember.name); vessel.CrewListSetDirty(); LifeSupportUtilities.RemoveCrewFromPart(crewMember, vessel); crewMember.rosterStatus = ProtoCrewMember.RosterStatus.Missing; break; case 5: //Kill msg = string.Format("{0} has died due to {1}", crewMember.name, reason); LifeSupportManager.Instance.UntrackKerbal(crewMember.name); vessel.CrewListSetDirty(); LifeSupportUtilities.RemoveCrewFromPart(crewMember, vessel); crewMember.rosterStatus = ProtoCrewMember.RosterStatus.Dead; break; } ScreenMessages.PostScreenMessage(msg, 5f, ScreenMessageStyle.UPPER_CENTER); }
private List <LifeSupportVesselDisplayStat> UpdateGUIStats() { var secondsPerDay = GameSettings.KERBIN_TIME ? (21600) : (86400); var useHabPenalties = (LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets + LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect > 0); LifeSupportManager.Instance.UpdateVesselStats(); var statList = new List <LifeSupportVesselDisplayStat>(); var checkVessels = new List <Guid>(); foreach (var v in FlightGlobals.Vessels.Where(v => v.isEVA)) { checkVessels.Add(v.id); } foreach (var vslId in checkVessels) { var vsl = FlightGlobals.Vessels.FirstOrDefault(v => v.id == vslId); if (vsl == null) { continue; } var lblColor = "FFD966"; var vstat = new LifeSupportVesselDisplayStat(); vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.vesselName); vstat.LastUpdate = vsl.missionTime; var sitString = "(EVA)"; var remEVATime = LifeSupportScenario.Instance.settings.GetSettings().EVATime - vsl.missionTime; var timeString = LifeSupportUtilities.SecondsToKerbinTime(Math.Max(0, remEVATime)); if (remEVATime > 0) { vstat.SummaryLabel = String.Format( "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2}</color><color=#3DB1FF> time remaining</color>" , vsl.mainBody.bodyName , sitString , timeString.Substring(timeString.IndexOf(':') + 1)); } else { vstat.SummaryLabel = "<color=#FF8585>EVA Time Expired</color>"; } vstat.crew = new List <LifeSupportCrewDisplayStat>(); statList.Add(vstat); } var vesselList = new List <VesselSupplyStatus>(); vesselList.AddRange(LifeSupportManager.Instance.VesselSupplyInfo); foreach (var vsl in vesselList) { var vstat = new LifeSupportVesselDisplayStat(); Vessel thisVessel = FlightGlobals.Vessels.First(v => v.id.ToString() == vsl.VesselId); double supmult = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount *Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier; var supPerDay = secondsPerDay * supmult; var estFood = supmult * (Planetarium.GetUniversalTime() - vsl.LastFeeding); double ecmult = LifeSupportScenario.Instance.settings.GetSettings().ECAmount *Convert.ToDouble(vsl.NumCrew); var ecPerDay = secondsPerDay * ecmult; var estEC = ecmult * (Planetarium.GetUniversalTime() - vsl.LastECCheck); int numSharedHabVessels = 0; var habTime = LifeSupportManager.GetTotalHabTime(vsl, out numSharedHabVessels); var supAmount = GetResourceInVessel(thisVessel, "Supplies"); if (supAmount == 0) { supAmount = Math.Max(0, (vsl.SuppliesLeft * supmult) - estFood); } var ecAmount = GetResourceInVessel(thisVessel, "ElectricCharge"); if (ecAmount == 0) { ecAmount = Math.Max(0, (vsl.ECLeft * ecmult) - estEC); } bool isOldData = Planetarium.GetUniversalTime() - vsl.LastUpdate > 2; var lblColor = isOldData ? "C4C4C4" : "ACFF40"; vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName); vstat.VesselId = vsl.VesselId; vstat.LastUpdate = vsl.LastUpdate; var sitString = "Orbiting"; thisVessel.checkSplashed(); if (thisVessel.Splashed) { sitString = "Splashed"; } thisVessel.checkLanded(); if (thisVessel.Landed) { sitString = "Landed"; } var habString = "indefinite"; if (useHabPenalties) { habString = LifeSupportUtilities.SecondsToKerbinTime(habTime, true); } vstat.SummaryLabel = String.Format( "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>" , thisVessel.mainBody.bodyName , sitString , supAmount , supPerDay , habString); vstat.crew = new List <LifeSupportCrewDisplayStat>(); if (useHabPenalties) { vstat.SummaryLabel += String.Format( "<color=#3DB1FF> (</color><color=#9EE4FF>{0}</color><color=#3DB1FF> {1} shared within </color><color=#9EE4FF>{2}</color><color=#3DB1FF>m)</color>", isOldData ? "?" : numSharedHabVessels.ToString(), numSharedHabVessels == 1 ? "vessel" : "vessels", LifeSupportScenario.Instance.settings.GetSettings().HabRange); } foreach (var c in thisVessel.GetVesselCrew()) { var cStat = new LifeSupportCrewDisplayStat(); var cls = LifeSupportManager.Instance.FetchKerbal(c); cStat.CrewName = String.Format("<color=#FFFFFF>{0} ({1})</color>", c.name, c.experienceTrait.Title.Substring(0, 1)); var ecLeft = (ecAmount / ecPerDay * secondsPerDay) + LifeSupportScenario.Instance.settings.GetSettings().ECTime; if (ecAmount <= LifeSupportScenario.Instance.settings.GetSettings().ECAmount&& !LifeSupportManager.IsOnKerbin(thisVessel)) { ecLeft = cls.LastEC - Planetarium.GetUniversalTime() + LifeSupportScenario.Instance.settings.GetSettings().ECTime; } var lblECTime = LifeSupportUtilities.SecondsToKerbinTime(ecLeft); var lblEC = "6FFF00"; if (ecLeft < LifeSupportScenario.Instance.settings.GetSettings().ECTime) { lblEC = "FFE100"; } if (ecLeft < LifeSupportScenario.Instance.settings.GetSettings().ECTime / 2) { lblEC = "FFAE00"; } if (ecLeft <= ResourceUtilities.FLOAT_TOLERANCE) { lblEC = "FF5E5E"; lblECTime = "expired"; } cStat.ECLabel = String.Format("<color=#{0}>{1}</color>", lblEC, lblECTime); var snacksLeft = (supAmount / supPerDay * secondsPerDay) + LifeSupportScenario.Instance.settings.GetSettings().SupplyTime; if (supAmount <= LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount&& !LifeSupportManager.IsOnKerbin(thisVessel)) { snacksLeft = cls.LastMeal - Planetarium.GetUniversalTime() + LifeSupportScenario.Instance.settings.GetSettings().SupplyTime; } var lblSupTime = LifeSupportUtilities.SecondsToKerbinTime(snacksLeft); var lblSup = "6FFF00"; if (snacksLeft < LifeSupportScenario.Instance.settings.GetSettings().SupplyTime) { lblSup = "FFE100"; } if (snacksLeft < LifeSupportScenario.Instance.settings.GetSettings().SupplyTime / 2) { lblSup = "FFAE00"; } if (snacksLeft <= ResourceUtilities.FLOAT_TOLERANCE) { lblSup = "FF5E5E"; lblSupTime = "expired"; } cStat.SupplyLabel = String.Format("<color=#{0}>{1}</color>", lblSup, lblSupTime); var habTimeLeft = habTime - (Planetarium.GetUniversalTime() - cls.TimeEnteredVessel); var homeTimeLeft = cls.MaxOffKerbinTime - Planetarium.GetUniversalTime(); var crewHabString = "indefinite"; var crewHomeString = "indefinite"; var lblHab = "6FFF00"; var lblHome = "6FFF00"; if (useHabPenalties) { crewHomeString = LifeSupportUtilities.SecondsToKerbinTime(homeTimeLeft); crewHabString = LifeSupportUtilities.SecondsToKerbinTime(habTimeLeft); } if (habTimeLeft < secondsPerDay * 30) { lblHab = "FFE100"; } if (habTimeLeft < secondsPerDay * 15) { lblHab = "FFAE00"; } if (habTimeLeft < 0) { lblHab = "FF5E5E"; crewHabString = "expired"; } cStat.HabLabel = String.Format("<color=#{0}>{1}</color>", lblHab, crewHabString); if (homeTimeLeft < secondsPerDay * 30) //15 days { lblHome = "FFE100"; } if (homeTimeLeft < secondsPerDay * 15) { lblHome = "FFAE00"; } if (homeTimeLeft < 0) { lblHome = "FF5E5E"; crewHomeString = "expired"; } cStat.HomeLabel = String.Format("<color=#{0}>{1}</color>", lblHome, crewHomeString); vstat.crew.Add(cStat); } statList.Add(vstat); } return(statList); }
private void GenerateWindow() { GUILayout.BeginVertical(); _scrollPos = GUILayout.BeginScrollView(_scrollPos, _scrollStyle, GUILayout.Width(645), GUILayout.Height(350)); GUILayout.BeginVertical(); if (EditorLogic.fetch != null) { if (EditorLogic.fetch.ship.parts.Count > 0) { // Colors string operColor = "99FF33"; string textColor = "FFFFFF"; string crewColor = "ADD8E6"; string fadeColor = "909090"; string partColor = "FFCC00"; string bonCapColor = "F9C004"; string bonusColor = "F9D904"; // SUMMARY { // column widths const int c1 = 90; const int c2 = 160; const int c3 = 160; const int c4 = 160; // LABELS GUILayout.BeginHorizontal(); GUILayout.Label("Crew", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(c3)); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c4)); GUILayout.EndHorizontal(); // CURRENT CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Current (", textColor) + CTag(Math.Max(1, curCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_curCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.DurationDisplay(totalBatteryTime / Math.Max(1, curCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(c4)); } GUILayout.EndHorizontal(); // CURRENT CREW WITH EXTENSIONS GUILayout.BeginHorizontal(); GUILayout.Label(CTag("+Fertilizer:", bonCapColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supplyExt_curCrew, bonusColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag("+Colony Supplies:", bonCapColor), _labelStyle, GUILayout.Width(c3)); if (useHabPenalties) { GUILayout.Label(CTag(habExt_curCrew, bonusColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", bonusColor), _labelStyle, GUILayout.Width(c4)); } GUILayout.EndHorizontal(); // MAX CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Max (", textColor) + CTag(Math.Max(1, maxCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_maxCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.DurationDisplay(totalBatteryTime / Math.Max(1, maxCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); // MAX WITH EXTENSIONS GUILayout.BeginHorizontal(); GUILayout.Label(CTag("+Fertilizer:", bonCapColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supplyExt_maxCrew, bonusColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag("+Colony Supplies:", bonCapColor), _labelStyle, GUILayout.Width(c3)); if (useHabPenalties) { GUILayout.Label(CTag(habExt_maxCrew, bonusColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", bonusColor), _labelStyle, GUILayout.Width(c4)); } GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Details</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // HABITATION EQUATION if (useHabPenalties) { // column widths const int c1 = 150; const int c2 = 80; const int c3 = 80; const int c4 = 90; const int c5 = 80; const int c6 = 50; const int c7 = 50; GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1 - 30)); GUILayout.Label(CTag("= ( (", operColor), _labelStyle, GUILayout.Width(30)); GUILayout.Label("BaseTime " + CTag("*", operColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label("MaxCrew " + CTag(") +", operColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label("ExtraTime " + CTag(") *", operColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label("Multiplier " + CTag("/", operColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label("Crew " + CTag("*", operColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label("Months", _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag("(1+" + (habMult - 1d) + ")", textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, curCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag("(1+" + (habMult - 1d) + ")", textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, maxCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Parts</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // RECYCLERS { // column widths const int c1 = 230; const int c2 = 80; const int c3 = 150; GUILayout.BeginHorizontal(); GUILayout.Label("Recycler", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Recycle %", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Crew-Capacity", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); var rCount = recyclers.Count; for (int x = 0; x < rCount; ++x) { var recycler = recyclers[x]; GUILayout.BeginHorizontal(); GUILayout.Label(CTag(recycler.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(((int)(recycler.RecyclePercent * 100)).ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(recycler.CrewCapacity.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } // HABITATION if (useHabPenalties) { GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("ExtraTime", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Multiplier", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); var hCount = habs.Count; for (int x = 0; x < hCount; ++x) { var hab = habs[x]; GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(hab.BaseKerbalMonths.ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(hab.BaseHabMultiplier.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } } } } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); }
private void UpdateGUIInfo(ShipConstruct ship) { ResetValues(); if (EditorLogic.fetch != null) { var parts = EditorLogic.fetch.ship.parts; var count = parts.Count; for (int i = 0; i < count; ++i) { var part = parts[i]; maxCrew += part.CrewCapacity; } var dialog = KSP.UI.CrewAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { curCrew = manifest.CrewCount; } } for (int i = 0; i < count; ++i) { var part = parts[i]; var swapOptions = part.FindModulesImplementing <AbstractSwapOption>(); var bays = part.FindModulesImplementing <USI_SwappableBay>(); if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0) { for (int x = 0; x < bays.Count; x++) { var bay = bays[x]; var loadout = swapOptions[bay.currentLoadout] as USILS_HabitationSwapOption; if (loadout != null) { habs.Add(loadout); //Certain modules, in addition to crew capacity, have living space. extraHabTime += loadout.BaseKerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += loadout.BaseHabMultiplier * Math.Min(1, loadout.CrewCapacity / Math.Max(curCrew, 1)); } } } if (part.Resources.Contains("ColonySupplies")) { colonySupplies += part.Resources["ColonySupplies"].amount; } if (part.Resources.Contains("Fertilizer")) { fertilizer += part.Resources["Fertilizer"].amount; } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. totalHabMult = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth(); totalBatteryTime = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount; totalSupplyTime = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; totalFertilizerTime = fertilizer * 10 / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { for (int i = 0; i < count; ++i) { var part = parts[i]; var swapOptions = part.FindModulesImplementing <AbstractSwapOption>(); var bays = part.FindModulesImplementing <USI_SwappableBay>(); if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0) { for (int x = 0; x < bays.Count; x++) { var bay = bays[x]; var loadout = swapOptions[bay.currentLoadout] as USILS_LifeSupportRecyclerSwapOption; if (loadout != null) { this.recyclers.Add(loadout); } } } } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); supply_curCrew = LifeSupportUtilities.DurationDisplay( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supply_maxCrew = LifeSupportUtilities.DurationDisplay( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); hab_curCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); hab_maxCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); supplyExt_curCrew = LifeSupportUtilities.DurationDisplay( (totalSupplyTime + totalFertilizerTime) / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supplyExt_maxCrew = LifeSupportUtilities.DurationDisplay( (totalSupplyTime + totalFertilizerTime) / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); //Standard is half a colony supply per hour, or 0.000139 per second. var csupPerSecond = 0.000139d; habExt_curCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, curCrew) * totalHabMult) + (colonySupplies / csupPerSecond / curCrew)); habExt_maxCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, maxCrew) * totalHabMult) + (colonySupplies / csupPerSecond / maxCrew)); } } }
private LifeSupportVesselDisplayStat GetVesselStats(VesselSupplyStatus vsl) { var secondsPerDay = GameSettings.KERBIN_TIME ? (21600) : (86400); var useHabPenalties = (LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffectVets + LifeSupportScenario.Instance.settings.GetSettings().NoHomeEffect > 0); Vessel thisVessel = FlightGlobals.Vessels.Find(v => v.id.ToString() == vsl.VesselId); var vstat = new LifeSupportVesselDisplayStat(); bool isOldData = Planetarium.GetUniversalTime() - vsl.LastUpdate > 2; var lblColor = isOldData ? "C4C4C4" : "ACFF40"; vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName); vstat.VesselId = vsl.VesselId; vstat.LastUpdate = vsl.LastUpdate; var situationString = GetSituationString(thisVessel); double suppliesPerSecond = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount *Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier; var suppliesPerDay = secondsPerDay * suppliesPerSecond; var supAmount = GetResourceInVessel(thisVessel, "Supplies"); var suppliesTimeLeft = (suppliesPerSecond > ResourceUtilities.FLOAT_TOLERANCE) ? (supAmount / suppliesPerSecond) : 0; if (supAmount == 0) { var suppliesConsumedSinceLastCheck = suppliesPerSecond * (Planetarium.GetUniversalTime() - vsl.LastFeeding); supAmount = Math.Max(0, (vsl.SuppliesLeft * suppliesPerSecond) - suppliesConsumedSinceLastCheck); suppliesTimeLeft = (vsl.SuppliesLeft - (Planetarium.GetUniversalTime() - vsl.LastFeeding)); } double ecPerSecond = LifeSupportScenario.Instance.settings.GetSettings().ECAmount *Convert.ToDouble(vsl.NumCrew); var ecAmount = GetResourceInVessel(thisVessel, "ElectricCharge"); var ecTimeLeft = (ecPerSecond > ResourceUtilities.FLOAT_TOLERANCE) ? (ecAmount / ecPerSecond) : 0; if (ecAmount == 0) { var ecConsumedSinceLastCheck = ecPerSecond * (Planetarium.GetUniversalTime() - vsl.LastECCheck); ecAmount = Math.Max(0, (vsl.ECLeft * ecPerSecond) - ecConsumedSinceLastCheck); ecTimeLeft = (vsl.ECLeft - (Planetarium.GetUniversalTime() - vsl.LastECCheck)); } int numSharedHabVessels = 0; var habTime = LifeSupportManager.GetTotalHabTime(vsl, thisVessel, out numSharedHabVessels); var habString = "indefinite"; if (useHabPenalties) { habString = LifeSupportUtilities.DurationDisplay(habTime, LifeSupportUtilities.TimeFormatLength.Short); } vstat.SummaryLabel = String.Format( "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>" , thisVessel.mainBody.bodyName , situationString , supAmount , suppliesPerDay , habString); vstat.crew = new List <LifeSupportCrewDisplayStat>(); if (useHabPenalties) { vstat.SummaryLabel += String.Format( "<color=#3DB1FF> (</color><color=#9EE4FF>{0}</color><color=#3DB1FF> {1} shared within </color><color=#9EE4FF>{2}</color><color=#3DB1FF>m)</color>", isOldData ? "?" : numSharedHabVessels.ToString(), numSharedHabVessels == 1 ? "vessel" : "vessels", LifeSupportScenario.Instance.settings.GetSettings().HabRange); } foreach (var c in thisVessel.GetVesselCrew()) { var crewStat = GetCrewStat(c, thisVessel, suppliesTimeLeft, ecTimeLeft, ecAmount, habTime); vstat.crew.Add(crewStat); } vstat.crew = vstat.crew.OrderBy(crewStat => crewStat.EarliestExpiration).ToList(); if (vstat.crew.Any()) { vstat.EarliestExpiration = vstat.crew.First().EarliestExpiration; } return(vstat); }
private void UpdateGUIInfo(ShipConstruct ship) { ResetValues(); if (EditorLogic.fetch != null) { foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } var dialog = KSP.UI.CrewAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { curCrew = manifest.CrewCount; } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModule <ModuleHabitation>(); if (hab != null) { var conList = part.Modules.GetModules <BaseConverter>(); var bayList = part.Modules.GetModules <ModuleSwappableConverter>(); if (bayList == null || bayList.Count == 0) { habs.Add(hab); //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, hab.CrewCapacity / Math.Max(curCrew, 1)); } else { foreach (var bay in bayList) { var con = conList[bay.currentLoadout] as ModuleHabitation; if (con != null) { habs.Add(con); extraHabTime += con.KerbalMonths; habMult += con.HabMultiplier * Math.Min(1, con.CrewCapacity / Math.Max(curCrew, 1)); } } } } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. totalHabMult = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth(); totalBatteryTime = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount; totalSupplyTime = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { foreach (var p in EditorLogic.fetch.ship.parts) { var rec = p.Modules.GetModule <ModuleLifeSupportRecycler>(); if (rec != null) { var conList = p.Modules.GetModules <BaseConverter>(); var bayList = p.Modules.GetModules <ModuleSwappableConverter>(); if (bayList == null || bayList.Count == 0) { recyclers.Add(rec); } else { foreach (var bay in bayList) { var con = conList[bay.currentLoadout] as ModuleLifeSupportRecycler; if (con != null) { recyclers.Add(con); } } } } } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); } } }
private List <LifeSupportVesselDisplayStat> UpdateGUIStats() { var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets + LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0); LifeSupportManager.Instance.UpdateVesselStats(); var statList = new List <LifeSupportVesselDisplayStat>(); var checkVessels = new List <Guid>(); foreach (var v in FlightGlobals.Vessels.Where(v => v.isEVA)) { checkVessels.Add(v.id); } foreach (var vslId in checkVessels) { var vsl = FlightGlobals.Vessels.FirstOrDefault(v => v.id == vslId); if (vsl == null) { continue; } var lblColor = "FFD966"; var vstat = new LifeSupportVesselDisplayStat(); vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.vesselName); vstat.LastUpdate = vsl.missionTime; var sitString = "(EVA)"; var remEVATime = LifeSupportSetup.Instance.LSConfig.EVATime - vsl.missionTime; var timeString = LifeSupportUtilities.SecondsToKerbinTime(Math.Max(0, remEVATime)); if (remEVATime > 0) { vstat.SummaryLabel = String.Format( "<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2}</color><color=#3DB1FF> time remaining</color>" , vsl.mainBody.bodyName , sitString , timeString.Substring(timeString.IndexOf(':') + 1)); } else { vstat.SummaryLabel = "<color=#FF8585>EVA Time Expired</color>"; } vstat.crew = new List <LifeSupportCrewDisplayStat>(); statList.Add(vstat); } var vesselList = new List <VesselSupplyStatus>(); vesselList.AddRange(LifeSupportManager.Instance.VesselSupplyInfo); foreach (var vsl in vesselList) { var vstat = new LifeSupportVesselDisplayStat(); Vessel thisVessel = FlightGlobals.Vessels.First(v => v.id.ToString() == vsl.VesselId); double supmult = LifeSupportSetup.Instance.LSConfig.SupplyAmount * Convert.ToDouble(vsl.NumCrew) * vsl.RecyclerMultiplier; var supPerDay = (21600 * supmult); var estFood = supmult * (Planetarium.GetUniversalTime() - vsl.LastFeeding); var habTime = LifeSupportManager.GetTotalHabTime(vsl); var supAmount = GetSuppliesInVessel(thisVessel); if (supAmount == 0) { supAmount = Math.Max(0, (vsl.SuppliesLeft * supmult) - estFood); } var lblColor = "ACFF40"; if (Planetarium.GetUniversalTime() - vsl.LastUpdate > 2) { lblColor = "C4C4C4"; } vstat.VesselName = String.Format("<color=#{0}>{1}</color>", lblColor, vsl.VesselName); vstat.LastUpdate = vsl.LastUpdate; var sitString = "Orbiting"; if (thisVessel.Splashed || thisVessel.heightFromTerrain < 1000) { sitString = "Splashed"; } if (thisVessel.Landed || thisVessel.heightFromTerrain < 1000) { sitString = "Landed"; } var habString = "indefinite"; if (useHabPenalties) { habString = LifeSupportUtilities.SecondsToKerbinTime(habTime, true); } vstat.SummaryLabel = String.Format("<color=#3DB1FF>{0}/{1} - </color><color=#9EE4FF>{2:0}</color><color=#3DB1FF> supplies (</color><color=#9EE4FF>{3:0.0}</color><color=#3DB1FF>/day) hab for </color><color=#9EE4FF>{4}</color>" , thisVessel.mainBody.bodyName , sitString , supAmount , supPerDay , habString); vstat.crew = new List <LifeSupportCrewDisplayStat>(); foreach (var c in thisVessel.GetVesselCrew()) { var cStat = new LifeSupportCrewDisplayStat(); var cls = LifeSupportManager.Instance.FetchKerbal(c); cStat.CrewName = String.Format("<color=#FFFFFF>{0} ({1})</color>", c.name, c.experienceTrait.Title.Substring(0, 1)); var snacksLeft = supAmount / supPerDay * 60 * 60 * 6; if (supAmount <= ResourceUtilities.FLOAT_TOLERANCE && !LifeSupportManager.IsOnKerbin(thisVessel)) { snacksLeft = cls.LastMeal - Planetarium.GetUniversalTime(); } var lblSup = "6FFF00"; if (snacksLeft < 60 * 60 * 6 * 15) //15 days { lblSup = "FFE100"; } if (snacksLeft < 0) { lblSup = "FFAE00"; } if (snacksLeft < -60 * 60 * 6 * 15) { lblSup = "FF5E5E"; } cStat.SupplyLabel = String.Format("<color=#{0}>{1}</color>", lblSup, LifeSupportUtilities.SecondsToKerbinTime(snacksLeft)); var timeLeft = Math.Min(cls.MaxOffKerbinTime - Planetarium.GetUniversalTime(), habTime - (Planetarium.GetUniversalTime() - cls.TimeEnteredVessel)); var lblHab = "6FFF00"; if (timeLeft < 60 * 60 * 6 * 15) //15 days { lblHab = "FFE100"; } if (timeLeft < 0) { lblHab = "FFAE00"; } if (timeLeft < -60 * 60 * 6 * 15) { lblHab = "FF5E5E"; } var crewHabString = "indefinite"; if (useHabPenalties) { crewHabString = LifeSupportUtilities.SecondsToKerbinTime(timeLeft); } cStat.HabLabel = String.Format("<color=#{0}>{1}</color>", lblHab, crewHabString); vstat.crew.Add(cStat); } statList.Add(vstat); } return(statList); }
private void GenerateWindow() { GUILayout.BeginVertical(); scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(600), GUILayout.Height(350)); GUILayout.BeginVertical(); var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets + LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0); if (EditorLogic.fetch != null) { var curCrew = 0; var maxCrew = 0; var supplies = 0d; var extraHabTime = 0d; var habMult = 1d; var batteryAmount = 0d; foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } CMAssignmentDialog dialog = CMAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { foreach (PartCrewManifest pcm in manifest) { int partCrewCount = pcm.GetPartCrew().Count(c => c != null); if (partCrewCount > 0) { curCrew += partCrewCount; } } } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault(); if (hab != null) { //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew)); } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d; var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount; var totalSupplyTime = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { GUILayout.BeginHorizontal(); GUILayout.Label("Crew", _labelStyle, GUILayout.Width(90)); GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(160)); GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(160)); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(160)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Current (" + curCrew + ")", _labelStyle, GUILayout.Width(90)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, curCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew)), _labelStyle, GUILayout.Width(160)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), _labelStyle, GUILayout.Width(160)); if (useHabPenalties) { GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Max (" + maxCrew + ")", _labelStyle, GUILayout.Width(90)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, maxCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew)), _labelStyle, GUILayout.Width(160)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), _labelStyle, GUILayout.Width(160)); if (useHabPenalties) { GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); }
private void GenerateWindow() { GUILayout.BeginVertical(); scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(645), GUILayout.Height(350)); GUILayout.BeginVertical(); var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets + LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0); if (EditorLogic.fetch != null) { var curCrew = 0; var maxCrew = 0; var supplies = 0d; var extraHabTime = 0d; var habMult = 1d; var batteryAmount = 0d; List <ModuleHabitation> habs = new List <ModuleHabitation>(); foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } CMAssignmentDialog dialog = CMAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { foreach (PartCrewManifest pcm in manifest) { int partCrewCount = pcm.GetPartCrew().Count(c => c != null); if (partCrewCount > 0) { curCrew += partCrewCount; } } } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault(); if (hab != null) { habs.Add(hab); //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew)); } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d; var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount; var totalSupplyTime = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { List <ModuleLifeSupportRecycler> recyclers = new List <ModuleLifeSupportRecycler>(); foreach (var p in EditorLogic.fetch.ship.parts) { var mod = p.FindModuleImplementing <ModuleLifeSupportRecycler>(); if (mod == null) { continue; } recyclers.Add(mod); } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); var supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); var supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); var hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); var hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); // Colors string operColor = "99FF33"; string textColor = "FFFFFF"; string crewColor = "ADD8E6"; string fadeColor = "909090"; string partColor = "FFCC00"; // SUMMARY { // column widths const int c1 = 90; const int c2 = 160; const int c3 = 160; const int c4 = 160; // LABELS GUILayout.BeginHorizontal(); GUILayout.Label("Crew", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(c3)); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c4)); GUILayout.EndHorizontal(); // CURRENT CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Current (", textColor) + CTag(Math.Max(1, curCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_curCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(c4)); } GUILayout.EndHorizontal(); // MAX CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Max (", textColor) + CTag(Math.Max(1, maxCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_maxCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Details</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // HABITATION EQUATION if (useHabPenalties) { // column widths const int c1 = 150; const int c2 = 80; const int c3 = 80; const int c4 = 90; const int c5 = 80; const int c6 = 50; const int c7 = 50; // hab = ((LSConfig.BaseHabTime * maxCrew) + ExtraHabTime) * Hab-Multiplier / Crew * LSConfig.HabMultiplier[Kerbin-Months] GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1 - 30)); GUILayout.Label(CTag("= ( (", operColor), _labelStyle, GUILayout.Width(30)); GUILayout.Label("BaseTime " + CTag("*", operColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label("MaxCrew " + CTag(") +", operColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label("ExtraTime " + CTag(") *", operColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label("Multiplier " + CTag("/", operColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label("Crew " + CTag("*", operColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label("Months", _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, curCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, maxCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Parts</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // RECYCLERS { // column widths const int c1 = 230; const int c2 = 80; const int c3 = 150; GUILayout.BeginHorizontal(); GUILayout.Label("Recycler", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Recycle %", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Crew-Capacity", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); foreach (var recycler in recyclers) { GUILayout.BeginHorizontal(); GUILayout.Label(CTag(recycler.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(((int)(recycler.RecyclePercent * 100)).ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(recycler.CrewCapacity.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } // HABITATION if (useHabPenalties) { GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("ExtraTime", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Multiplier", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); foreach (var hab in habs) { GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(hab.KerbalMonths.ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(hab.HabMultiplier.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } } } } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); }