public double ForceRepair() { if (activeFailure == null) { return(0); } double repairStatus = activeFailure.ForceRepair(); if (repairStatus == 0) { activeFailure = null; failureAcknowledged = false; operatingTime = 0; return(0); } else { return(repairStatus); } }
public static List <ITestFlightFailure> GetFailureModules(Part part, string configuration) { List <ITestFlightFailure> failureModules; if (part == null || part.Modules == null) { return(null); } failureModules = new List <ITestFlightFailure>(); foreach (PartModule pm in part.Modules) { ITestFlightFailure failureModule = pm as ITestFlightFailure; if (failureModule != null && failureModule.TestFlightEnabled && failureModule.Configuration == configuration) { failureModules.Add(failureModule); } } return(failureModules); }
// Get all Failure Modules - can be more than one. public static List <ITestFlightFailure> GetFailureModules(Part part, string alias) { if (part == null || part.Modules == null) { return(null); } var failureModules = new List <ITestFlightFailure>(); for (int i = 0, partModulesCount = part.Modules.Count; i < partModulesCount; i++) { PartModule pm = part.Modules[i]; ITestFlightFailure failureModule = pm as ITestFlightFailure; if (failureModule != null && failureModule.TestFlightEnabled && String.Equals(failureModule.Configuration, alias, StringComparison.InvariantCultureIgnoreCase)) { failureModules.Add(failureModule); } } return(failureModules); }
public static List <PartModule> GetAllTestFlightModulesForAlias(Part part, string alias) { if (part == null || part.Modules == null) { return(null); } List <PartModule> modules = new List <PartModule>(); for (int i = 0, partModulesCount = part.Modules.Count; i < partModulesCount; i++) { PartModule pm = part.Modules[i]; // FlightDataRecorder IFlightDataRecorder dataRecorder = pm as IFlightDataRecorder; if (dataRecorder != null && dataRecorder.Configuration.Equals(alias, StringComparison.InvariantCultureIgnoreCase)) { modules.Add(pm); continue; } // TestFlightReliability ITestFlightReliability reliabilityModule = pm as ITestFlightReliability; if (reliabilityModule != null && reliabilityModule.Configuration.Equals(alias, StringComparison.InvariantCultureIgnoreCase)) { modules.Add(pm); continue; } // TestFlightFailure ITestFlightFailure failureModule = pm as ITestFlightFailure; if (failureModule != null && failureModule.Configuration.Equals(alias, StringComparison.InvariantCultureIgnoreCase)) { modules.Add(pm); continue; } } return(modules); }
// Get all Failure Modules - can be more than one. public static List <ITestFlightFailure> GetFailureModules(Part part, string alias, bool checkEnabled = true) { if (part == null || part.Modules == null) { return(null); } var failureModules = new List <ITestFlightFailure>(); for (int i = 0, partModulesCount = part.Modules.Count; i < partModulesCount; i++) { PartModule pm = part.Modules[i]; ITestFlightFailure failureModule = pm as ITestFlightFailure; if (failureModule != null) { // failureModule.SetActiveConfig(alias); failureModules.Add(failureModule); } } return(failureModules); }
public static List <PartModule> GetAllTestFlightModulesForPart(Part part) { if (part == null || part.Modules == null) { return(null); } List <PartModule> modules = new List <PartModule>(); for (int i = 0, partModulesCount = part.Modules.Count; i < partModulesCount; i++) { PartModule pm = part.Modules[i]; // FlightDataRecorder IFlightDataRecorder dataRecorder = pm as IFlightDataRecorder; if (dataRecorder != null) { modules.Add(pm); continue; } // TestFlightReliability ITestFlightReliability reliabilityModule = pm as ITestFlightReliability; if (reliabilityModule != null) { modules.Add(pm); continue; } // TestFlightFailure ITestFlightFailure failureModule = pm as ITestFlightFailure; if (failureModule != null) { modules.Add(pm); continue; } } return(modules); }
internal override void DrawWindow(Int32 id) { if (tfManager == null) { return; } Dictionary <Guid, MasterStatusItem> masterStatus = tfManager.GetMasterStatus(); GUIContent settingsButton = new GUIContent(TestFlight.Resources.btnChevronDown, "Open Settings Panel"); if (tfScenario.userSettings.displaySettingsWindow) { settingsButton.image = TestFlight.Resources.btnChevronUp; settingsButton.tooltip = "Close Settings Panel"; } if (masterStatus == null) { GUILayout.BeginVertical(); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("TestFlight is starting up..."); if (GUILayout.Button(settingsButton, GUILayout.Width(38))) { tfScenario.userSettings.displaySettingsWindow = !tfScenario.userSettings.displaySettingsWindow; CalculateWindowBounds(); tfScenario.userSettings.Save(); } GUILayout.EndHorizontal(); } else if (masterStatus.Count() <= 0) { GUILayout.BeginVertical(); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("TestFlight is not currently tracking any vessels"); if (GUILayout.Button(settingsButton, GUILayout.Width(38))) { tfScenario.userSettings.displaySettingsWindow = !tfScenario.userSettings.displaySettingsWindow; CalculateWindowBounds(); tfScenario.userSettings.Save(); } GUILayout.EndHorizontal(); } else { GUILayout.BeginVertical(); GUILayout.Space(10); // Display information on active vessel Guid currentVessel = FlightGlobals.ActiveVessel.id; if (masterStatus.ContainsKey(currentVessel) && masterStatus[currentVessel].allPartsStatus.Count > 0) { tfScenario.userSettings.currentMSDScrollPosition = GUILayout.BeginScrollView(tfScenario.userSettings.currentMSDScrollPosition); foreach (PartStatus status in masterStatus[currentVessel].allPartsStatus) { // Display part data // GUILayout.Label(String.Format("{0,50}", status.partName)); // GUILayout.Label(String.Format("{0,7:F2}du", status.flightData)); // GUILayout.Label(String.Format("{0,7:F2}%", status.reliability)); if (tfScenario.userSettings.showFailedPartsOnlyInMSD && status.failures == null) { continue; } if (tfScenario.userSettings.showFailedPartsOnlyInMSD && status.failures.Count <= 0) { continue; } GUILayout.BeginHorizontal(); string partDisplay; // Part Name string tooltip = ""; if (status.failures == null || status.failures.Count <= 0) { tooltip = "Status OK"; } else { for (int i = 0; i < status.failures.Count; i++) { tooltip += string.Format("<color=#{0}>{1}</color>\n", status.failures[i].GetFailureDetails().severity.ToLowerInvariant() == "major" ? "dc322fff" : "b58900ff", status.failures[i].GetFailureDetails().failureTitle); } } if (tfScenario.userSettings.shortenPartNameInMSD) { GUILayout.Label(new GUIContent(status.partName, tooltip), GUILayout.Width(100)); } else { GUILayout.Label(new GUIContent(status.partName, tooltip), GUILayout.Width(200)); } GUILayout.Space(10); // Flight Data if (tfScenario.userSettings.showFlightDataInMSD) { GUILayout.Label(String.Format("{0,-7:F2}<b>du</b>", status.flightData), GUILayout.Width(75)); GUILayout.Space(10); } // Resting Reliability if (tfScenario.userSettings.showMTBFStringInMSD) { GUILayout.Label(String.Format("{0} <b>MTBF</b>", status.mtbfString), GUILayout.Width(130)); GUILayout.Space(10); } // Momentary Reliability if (tfScenario.userSettings.showFailureRateInMSD) { GUILayout.Label(String.Format("{0:F6}", status.momentaryFailureRate), GUILayout.Width(60)); GUILayout.Space(10); } // Part Status Text if (tfScenario.userSettings.showStatusTextInMSD) { if (status.failures == null || status.failures.Count <= 0) { partDisplay = String.Format("<color=#859900ff>{0,-30}</color>", "OK"); } else { ITestFlightFailure latestFailure = status.failures.Last(); if (latestFailure.GetFailureDetails().severity.ToLowerInvariant() == "major") { partDisplay = String.Format("<color=#dc322fff>{0,-30}</color>", latestFailure.GetFailureDetails().failureTitle); } else { partDisplay = String.Format("<color=#b58900ff>{0,-30}</color>", latestFailure.GetFailureDetails().failureTitle); } } GUILayout.Label(partDisplay, GUILayout.Width(100)); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (GUILayout.Button(settingsButton, GUILayout.Width(38))) { tfScenario.userSettings.displaySettingsWindow = !tfScenario.userSettings.displaySettingsWindow; CalculateWindowBounds(); tfScenario.userSettings.Save(); } } } // Draw settings pane if opened if (tfScenario.userSettings.displaySettingsWindow) { GUILayout.Space(15); if (ddlSettingsPage == null) { GUILayout.Space(10); GUILayout.EndVertical(); return; } ddlSettingsPage.styleListBox = Styles.styleDropDownListBoxUnity; ddlSettingsPage.styleListBlocker = Styles.styleDropDownListBoxUnity; ddlSettingsPage.SelectedIndex = tfScenario.userSettings.settingsPage; ddlSettingsPage.DrawButton(); switch (tfScenario.userSettings.settingsPage) { case 0: GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.showFailedPartsOnlyInMSD, "Show Failed Parts Only", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.shortenPartNameInMSD, "Short Part Names", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.showFlightDataInMSD, "Show Flight Data", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.showMTBFStringInMSD, "Show MTBF", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.showFailureRateInMSD, "Show Failure Rate", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.showStatusTextInMSD, "Show Part Status Text", Styles.styleToggle)) { tfScenario.userSettings.Save(); CalculateWindowBounds(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.mainWindowLocked, "Lock MSD Position", Styles.styleToggle)) { if (tfScenario.userSettings.mainWindowLocked) { tfScenario.userSettings.mainWindowLocked = true; CalculateWindowBounds(); tfScenario.userSettings.mainWindowPosition = WindowRect; DragEnabled = false; tfScenario.userSettings.showMSD = false; } else { tfScenario.userSettings.showMSD = Visible; DragEnabled = true; } tfScenario.userSettings.Save(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("MSD Size", GUILayout.Width(200)); tfScenario.userSettings.currentMSDSize = GUILayout.Toolbar(tfScenario.userSettings.currentMSDSize, guiSizes); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.enableHUD, "Enable Flight HUD", Styles.styleToggle)) { tfScenario.userSettings.Save(); if (tfScenario.userSettings.enableHUD) { hud = gameObject.AddComponent(typeof(TestFlightHUD)) as TestFlightHUD; if (hud != null) { Log("Starting up Flight HUD"); hud.Startup(this); } GameEvents.onGameSceneLoadRequested.Add(Event_OnGameSceneLoadRequested); } else { Log("Destroying Flight HUD"); hud.Shutdown(); Destroy(hud); hud = null; GameEvents.onGameSceneLoadRequested.Remove(Event_OnGameSceneLoadRequested); } } GUILayout.EndHorizontal(); break; case 1: GUILayout.BeginHorizontal(); GUILayout.Label(new GUIContent("Flight Data Multiplier", "Overall difficulty slider.\n" + "Increase to make all parts accumuate flight data faster. Decrease to make them accumulate flight data slower.\n" + "A setting of 1 is normal rate"), GUILayout.Width(200) ); if (DrawHorizontalSlider(ref tfScenario.userSettings.flightDataMultiplier, 0.5f, 2f, GUILayout.Width(150))) { tfScenario.userSettings.Save(); } GUILayout.Label(String.Format("{0,5:f2}", tfScenario.userSettings.flightDataMultiplier), GUILayout.Width(75)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(new GUIContent("Flight Data Engineer Multiplier", "Overall difficulty slider\n" + "Increases or decreases the bonus applied to the accumulation of flight data from having Engineers in your crew.\n" + "A setting of 1 is normal difficulty."), GUILayout.Width(200) ); if (DrawHorizontalSlider(ref tfScenario.userSettings.flightDataEngineerMultiplier, 0.5f, 2f, GUILayout.Width(150))) { tfScenario.userSettings.Save(); } GUILayout.Label(String.Format("{0,5:f2}", tfScenario.userSettings.flightDataEngineerMultiplier), GUILayout.Width(75)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.singleScope, "Use a single scope for all data", Styles.styleToggle)) { tfScenario.userSettings.Save(); } GUILayout.EndHorizontal(); break; case 2: GUILayout.BeginHorizontal(); if (DrawToggle(ref tfScenario.userSettings.debugLog, "Enable Debugging", Styles.styleToggle)) { tfScenario.userSettings.Save(); } GUILayout.EndHorizontal(); break; case 3: GUILayout.BeginHorizontal(); bool saveEnabled = tfScenario.SettingsEnabled; if (DrawToggle(ref saveEnabled, "TestFlight Enabled", Styles.styleToggle)) { tfScenario.SettingsEnabled = saveEnabled; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); bool saveMaxData = tfScenario.SettingsAlwaysMaxData; if (DrawToggle(ref saveMaxData, "Parts always have Maximum Data", Styles.styleToggle)) { tfScenario.SettingsAlwaysMaxData = saveMaxData; } GUILayout.EndHorizontal(); break; } } GUILayout.Space(10); GUILayout.EndVertical(); if (GUI.changed) { CalculateWindowBounds(); tfScenario.userSettings.Save(); } }
// Cause a failure to occur, either a random failure or a specific one // If fallbackToRandom is true, then if the specified failure can't be found or can't be triggered, a random failure will be triggered instead // Returns the triggered failure module, or null if none public ITestFlightFailure TriggerFailure(string severity) { severity = severity.ToLowerInvariant(); Log(string.Format("Triggering random {0} failure", severity)); // Failure occurs. Determine which failure module to trigger int totalWeight = 0; int currentWeight = 0; int chosenWeight = 0; List <ITestFlightFailure> failureModules = null; // Get all failure modules on the part // Then filter only the ones that are not disabled and are of the desired severity List <ITestFlightFailure> allFailureModules = TestFlightUtil.GetFailureModules(this.part, Alias); for (int i = 0, allFailureModulesCount = allFailureModules.Count; i < allFailureModulesCount; i++) { ITestFlightFailure fm = allFailureModules[i]; PartModule pm = fm as PartModule; if (fm.GetFailureDetails().severity.ToLowerInvariant() == severity || severity == "any") { if (fm.Failed) { Log(string.Format("Skipping {0} because it is already active", pm.moduleName)); continue; } if (!disabledFailures.Contains(pm.moduleName.Trim().ToLowerInvariant())) { if (failureModules == null) { failureModules = new List <ITestFlightFailure>(); } failureModules.Add(fm); } } else { Log(string.Format("Skipping {0} because it doesn't have a matching severity ({1} != {2}", pm.moduleName, fm.GetFailureDetails().severity, severity)); } } if (failureModules == null || failureModules.Count == 0) { Log("No failure modules to trigger"); return(null); } for (int i = 0, failureModulesCount = failureModules.Count; i < failureModulesCount; i++) { ITestFlightFailure fm = failureModules[i]; totalWeight += fm.GetFailureDetails().weight; } chosenWeight = RandomGenerator.Next(1, totalWeight); for (int i = 0, failureModulesCount = failureModules.Count; i < failureModulesCount; i++) { ITestFlightFailure fm = failureModules[i]; currentWeight += fm.GetFailureDetails().weight; if (currentWeight >= chosenWeight) { // Trigger this module's failure PartModule pm = fm as PartModule; if (pm != null) { return(TriggerNamedFailure(pm.moduleName, false)); } } } return(null); }
// PARTMODULE functions public override void Update() { base.Update(); if (!firstStaged) return; if (!TestFlightEnabled) return; if (HighLogic.LoadedSceneIsFlight) { if (TestFlightManagerScenario.Instance == null) return; if (activeFailure != null) { float repairStatus = activeFailure.GetSecondsUntilRepair(); if (repairStatus == 0) { Log("Part has been repaired"); activeFailure = null; failureAcknowledged = false; operatingTime = 0; } } float currentMET = (float)Planetarium.GetUniversalTime() - (float)missionStartTime; Log("Operating Time: " + operatingTime); Log("Current MET: " + currentMET + ", Last MET: " + lastMET); if (operatingTime != -1 && IsPartOperating()) { Log("Adding " + (currentMET - lastMET) + " seconds to operatingTime"); operatingTime += currentMET - lastMET; } lastMET = currentMET; } }
public ITestFlightFailure TriggerNamedFailure(String failureModuleName, bool fallbackToRandom) { // We won't trigger a failure if we are already failed if (activeFailure != null) return null; failureModuleName = failureModuleName.ToLower().Trim(); List<ITestFlightFailure> failureModules; failureModules = TestFlightUtil.GetFailureModules(this.part); foreach(ITestFlightFailure fm in failureModules) { PartModule pm = fm as PartModule; if (pm.moduleName.ToLower().Trim() == failureModuleName) { if (fm == null && fallbackToRandom) return TriggerFailure(); else if (fm == null & !fallbackToRandom) return null; else { Log("Triggering Failure: " + pm.moduleName); if (!fm.OneShot) { activeFailure = fm; failureAcknowledged = false; operatingTime = -1; } fm.DoFailure(); return fm; } } } if (fallbackToRandom) return TriggerFailure(); return null; }
public float ForceRepair() { if (activeFailure == null) return 0; float repairStatus = activeFailure.ForceRepair(); if (repairStatus == 0) { activeFailure = null; failureAcknowledged = false; operatingTime = 0; return 0; } else return repairStatus; }
public float AttemptRepair() { if (activeFailure == null) return 0; if (activeFailure.CanAttemptRepair()) { float repairStatus = activeFailure.AttemptRepair(); if (repairStatus == 0) { Log("Part has been repaired"); activeFailure = null; failureAcknowledged = false; operatingTime = 0; return 0; } else return repairStatus; } return -1; }
public float ForceRepair(ITestFlightFailure failure) { if (failure == null) return 0; failure.ForceRepair(); // update our major failure flag in case this repair changes things hasMajorFailure = HasMajorFailure(); return 0; }