/// <summary> /// Multiplier that reduces the chance of failure right after an inspection. /// </summary> private float InspectionLambdaMultiplier() { float elapsed = (DangIt.Now() - this.TimeOfLastInspection); // Constrain it between 0 and 1 return(Math.Max(0f, Math.Min(elapsed / this.InspectionBonus, 1f))); }
public void Inspect() { StringBuilder sb = new StringBuilder(); List <FailureModule> failModules = part.Modules.OfType <FailureModule>().ToList(); // The part doesn't have any failure module: // instead of a black message, return a placeholder if (failModules.Count == 0) { sb.AppendLine("This part seems to be as good as new"); } else { foreach (FailureModule fm in failModules) { fm.TimeOfLastInspection = DangIt.Now(); // set the time of inspection so that the module gains the inspection bonus sb.AppendLine(fm.ScreenName + ":"); sb.AppendLine(fm.InspectionMessage()); sb.AppendLine(""); } } DangIt.PostMessage("Inspection results", sb.ToString(), MessageSystemButton.MessageButtonColor.BLUE, MessageSystemButton.ButtonIcons.MESSAGE, overrideMute: true); }
public void Inspect() { StringBuilder sb = new StringBuilder(); List <FailureModule> failModules = part.Modules.OfType <FailureModule>().ToList(); if (failModules.Count == 0) { sb.AppendLine("This part seems to be as good as new"); } foreach (FailureModule fm in failModules) { fm.TimeOfLastInspection = DangIt.Now(); sb.AppendLine(fm.InspectionName + ":"); sb.AppendLine(fm.InspectionMessage()); sb.AppendLine(""); } DangIt.PostMessage("Inspection results", sb.ToString(), MessageSystemButton.MessageButtonColor.BLUE, MessageSystemButton.ButtonIcons.MESSAGE, overrideMute: true); }
/// <summary> /// Module re-start logic. OnStart will be called usually once for each scene, /// editor included. /// Put your custom start logic in DI_Start(): if you need to act on other part's /// variable, this is the place to do it, not DI_Reset() /// </summary> public override void OnStart(PartModule.StartState state) { try { if (HighLogic.LoadedSceneIsFlight) // nothing to do in editor { this.Log("Starting in flight: last reset " + TimeOfLastReset + ", now " + DangIt.Now()); // Reset the internal state at the beginning of the flight // this condition also catches a revert to launch (+1 second for safety) if (DangIt.Now() < (this.TimeOfLastReset + 1)) this.Reset(); // If the part was saved when it was failed, // re-run the failure logic to disable it // ONLY THE DISABLING PART IS RUN! if (this.HasFailed) this.DI_Disable(); DangIt.ResetShipGlow(this.part.vessel); } this.DI_Start(state); this.StartCoroutine("RuntimeFetch"); } catch (Exception e) { OnError(e); } }
/// <summary> /// Update logic on every physics frame update. /// Place your custom update logic in DI_Update() /// </summary> public void FixedUpdate() { try { // Only update the module during flight and after the re-initialization has run if (HighLogic.LoadedSceneIsFlight && this.HasInitted) { float now = DangIt.Now(); float dt = now - LastFixedUpdate; this.LastFixedUpdate = now; // The temperature aging is independent from the use of the part this.Age += (dt * this.TemperatureMultiplier()); if (!PartIsActive() || !DangIt.Instance.CurrentSettings.EnabledForSave) { return; } else { this.Age += dt; this.CurrentMTBF = this.MTBF * this.ExponentialDecay(); // If the part has not already failed, toss the dice if (!this.HasFailed) { float f = this.Lambda(); #if DEBUG if (printChances) { print("this.Lambda: " + f.ToString()); } #endif if (UnityEngine.Random.Range(0f, 1f) < f) { this.Fail(); } } // Run custom update logic this.DI_Update(); } } } catch (Exception e) { OnError(e); } }
/// <summary> /// Multiplier that reduces the chance of failure right after an inspection. /// </summary> private float InspectionLambdaMultiplier() { float elapsed = (DangIt.Now() - this.TimeOfLastInspection); // Constrain it between 0 and 1 float f = Math.Max(0f, Math.Min(elapsed / this.InspectionBonus, 1f)); #if DEBUG if (printChances) print("InspectionLambdaMultiplier: " + f.ToString()); #endif return f; }
/// <summary> /// Resets the failure state and age tracker. /// This must be called only at the beginning of the flight to initialize the age tracking. /// Put your reset logic in DI_Reset() /// </summary> protected void Reset() { Debug.Log("Reset(), HasInitted: " + HasInitted.ToString()); #region Fail and repair events this.Events["Fail"].guiName = this.FailGuiName; this.Events["EvaRepair"].guiName = this.EvaRepairGuiName; this.Events["EvaRepair"].active = false; this.Events["Maintenance"].guiName = this.MaintenanceString; if (this.HasInitted) return; #endregion try { this.FailureLog("Resetting"); float now = DangIt.Now(); #region Internal state this.Age = 0; this.TimeOfLastReset = now; this.LastFixedUpdate = now; this.TimeOfLastInspection = float.NegativeInfinity; this.CurrentMTBF = this.MTBF * HighLogic.CurrentGame.Parameters.CustomParams<DangItCustomParams1>().MTBF_Multiplier; this.LifeTimeSecs = this.LifeTime * HighLogic.CurrentGame.Parameters.CustomParams<DangItCustomParams1>().Lifetime_Multiplier * 3600f; this.HasFailed = false; #endregion // Run the custom reset of the subclasses this.DI_Reset(); this.HasInitted = true; } catch (Exception e) { OnError(e); } }
/// <summary> /// Update logic on every physics frame update. /// Place your custom update logic in DI_Update() /// </summary> public void FixedUpdate() { try { // Only update the module during flight and after the re-initialization has run if (HighLogic.LoadedSceneIsFlight && this.HasInitted) { float now = DangIt.Now(); float dt = now - LastFixedUpdate; // The temperature aging is independent from the use of the part this.Age += dt * this.TemperatureMultiplier(); if (!PartIsActive()) { this.LastFixedUpdate = now; return; } // If control reaches this point, the part is active: add the elapsed time to the age this.Age += dt; this.CurrentMTBF = this.MTBF * this.ExponentialDecay(); // If the part has not already failed, toss the dice if (!this.HasFailed) { if (UnityEngine.Random.Range(0f, 1f) < this.Lambda()) { this.Fail(); } } // Run custom update logic this.DI_Update(); this.LastFixedUpdate = now; } } catch (Exception e) { OnError(e); } }
/// <summary> /// Resets the failure state and age tracker. /// This must be called only at the beginning of the flight to initialize the age tracking. /// Put your reset logic in DI_Reset() /// </summary> protected void Reset() { try { this.Log("Resetting"); float now = DangIt.Now(); #region Internal state this.Age = 0; this.TimeOfLastReset = now; this.LastFixedUpdate = now; this.TimeOfLastInspection = float.NegativeInfinity; this.CurrentMTBF = this.MTBF; this.LifeTimeSecs = this.LifeTime * 3600f; this.HasFailed = false; #endregion #region Fail and repair events this.Events["Fail"].guiName = this.FailGuiName; this.Events["EvaRepair"].guiName = this.EvaRepairGuiName; this.Events["EvaRepair"].active = false; this.Events["Maintenance"].guiName = this.MaintenanceString; #endregion // Run the custom reset of the subclasses this.DI_Reset(); this.HasInitted = true; } catch (Exception e) { OnError(e); } }
private float InspectionMultiplier() { float elapsed = (DangIt.Now() - this.TimeOfLastInspection); return Math.Max(0f, Math.Min(elapsed / this.InspectionBonus, 1f)); }
/// <summary> /// Update logic on every physics frame update. /// Place your custom update logic in DI_Update() /// </summary> public void FixedUpdate() { try { // Only update the module during flight and after the re-initialization has run if (HighLogic.LoadedSceneIsFlight && this.HasInitted) { // Highlighting the part, which contains this updating FailureModule if it is in a 'failed' state, // it is not in 'silent' state and 'glow' is globally enabled // Actually, there is not any place in a code of the whole mod where that 'silent' state is turning on // (maybe some FailureModules can be defined as 'silent' by editing files) if (this.HasFailed && !this.Silent && (DangIt.Instance.CurrentSettings.Glow && (AlarmManager.visibleUI || !DangIt.Instance.CurrentSettings.DisableGlowOnF2))) { this.part.SetHighlightDefault(); this.part.SetHighlightColor(Color.red); this.part.SetHighlightType(Part.HighlightType.AlwaysOn); this.part.highlighter.ConstantOn(Color.red); this.part.highlighter.SeeThroughOn(); this.part.SetHighlight(true, false); } else // Turning off the highlighting of the part, which contains this updating FailureModule // if it is not in a 'failed' state, or it is in 'silent' state, or if 'glow' is globally disabled // if (!this.HasFailed || this.Silent || !DangIt.Instance.CurrentSettings.Glow || (!visibleUI && DangIt.Instance.CurrentSettings.DisableGlowOnF2)) { if (!AlarmManager.partFailures.ContainsKey(this.part)) this.part.SetHighlightDefault(); } float now = DangIt.Now(); float dt = now - LastFixedUpdate; this.LastFixedUpdate = now; // The temperature aging is independent from the use of the part this.Age += (dt * this.TemperatureMultiplier()); if (!PartIsActive() || !DangIt.Instance.CurrentSettings.EnabledForSave) return; else { this.Age += dt; this.CurrentMTBF = this.MTBF * HighLogic.CurrentGame.Parameters.CustomParams<DangItCustomParams1>().MTBF_Multiplier * this.ExponentialDecay(); // If the part has not already failed, toss the dice if (!this.HasFailed) { float f = this.Lambda(); #if DEBUG // if (printChances) // Logger.Debug("this.Lambda: " + f.ToString()); #endif if (UnityEngine.Random.Range(0f, 1f) < f) { this.Fail(); } } // Run custom update logic this.DI_Update(); } } } catch (Exception e) { OnError(e); } }
/// <summary> /// Module re-start logic. OnStart will be called usually once for each scene, editor included. /// Put your custom start logic in DI_Start(): if you need to act on other part's /// variable, this is the place to do it, not DI_Reset() /// </summary> public override void OnStart(PartModule.StartState state) { Logger.Info("FailureModule.OnStart"); try { if (HighLogic.LoadedSceneIsFlight) // nothing to do in editor { this.FailureLog("Starting in flight: last reset " + TimeOfLastReset + ", now " + DangIt.Now()); if (!DangIt.Instance.CurrentSettings.EnabledForSave) { //Disable if we've disabled DangIt foreach (var e in this.Events) { e.guiActive = false; } } // Reset the internal state at the beginning of the flight // this condition also catches a revert to launch (+1 second for safety) // if (DangIt.Now() < (this.TimeOfLastReset + 1)) this.Reset(); // If the part was saved when it was failed, // re-run the failure logic to disable it // ONLY THE DISABLING PART IS RUN! if (this.HasFailed) this.DI_Disable(); } if (DangIt.Instance.CurrentSettings.EnabledForSave) { this.DI_Start(state); this.StartCoroutine("RuntimeFetch"); } } catch (Exception e) { OnError(e); } }