public override bool FailureAllowed() { if (KRASHWrapper.simulationActive()) { return(false); } return(HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().SRBFailureModuleAllowed); }
protected override bool FailureAllowed() { if (KRASHWrapper.simulationActive()) { return(false); } if (engine.currentThrottle > 0) { return(false); } return(HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().SRBFailureModuleAllowed); }
private void ActivateFailures() { if (KRASHWrapper.simulationActive()) { return; } launched = true; Initialise(); UPFMUtils.instance.testedParts.Add(SYP.ID); if (HighLogic.LoadedScene == GameScenes.FLIGHT && isSRB && FailureAllowed() && UPFMUtils.instance._randomiser.NextDouble() < chanceOfFailure) { InvokeRepeating("FailPart", 0.01f, 0.01f); } }
//Part will just shutdown and not be restartable. public override void FailPart() { if (KRASHWrapper.simulationActive()) { return; } if (engine.currentThrottle == 0) { return; } engine.allowShutdown = true; engine.allowRestart = false; hasFailed = true; engine.Shutdown(); if (!message) { if (vessel.vesselType != VesselType.Debris) { ScreenMessages.PostScreenMessage(part.partInfo.title + " has failed to ignite"); } StringBuilder msg = new StringBuilder(); msg.AppendLine(part.vessel.vesselName); msg.AppendLine(""); msg.AppendLine(part.partInfo.title + " has suffered an " + failureType); msg.AppendLine(""); MessageSystem.Message m = new MessageSystem.Message("OhScrap", msg.ToString(), MessageSystemButton.MessageButtonColor.ORANGE, MessageSystemButton.ButtonIcons.ALERT); MessageSystem.Instance.AddMessage(m); message = true; } if (OhScrap.highlight) { OhScrap.SetFailedHighlight(); } CancelInvoke("FailPart"); Logger.instance.Log("[OhScrap]: " + part.partInfo.title + " has failed to ignite"); }
//This determines whether or not the part will fail. public bool FailCheck(bool recalcChance) { int standardisedGeneration = OhScrap.generation; if (standardisedGeneration > 10) { standardisedGeneration = 10; } if (SYP.TimesRecovered == 0) { chanceOfFailure = baseChanceOfFailure / standardisedGeneration + randomisation; } else { chanceOfFailure = ((baseChanceOfFailure / standardisedGeneration) + randomisation) * (SYP.TimesRecovered / (float)expectedLifetime); } //Chance of Failure can never exceed the safety threshold unless the part has reached "end of life" if (chanceOfFailure > baseChanceOfFailure) { chanceOfFailure = baseChanceOfFailure; } //If the part has reached it's "end of life" the failure rate will quickly deteriorate. float endOfLifeMultiplier = (SYP.TimesRecovered - expectedLifetime) / 5.0f; if (endOfLifeMultiplier > 0) { if (!endOfLife) { endOfLife = Randomiser.instance.NextDouble() < endOfLifeMultiplier; } if (endOfLife) { chanceOfFailure = chanceOfFailure + endOfLifeMultiplier; } } // more repairs = more failure events. if (numberOfRepairs > 0) { chanceOfFailure = chanceOfFailure * numberOfRepairs; } displayChance = (int)(chanceOfFailure * 100); #if DEBUG if (part != null) { Debug.Log("[UPFM]: Chances of " + SYP.ID + " " + moduleName + " failing calculated to be " + chanceOfFailure * 100 + "%"); } #endif //No Failures if this is a KRASH simulation, a mission, we are in the editor, or the player has disabled failures for this module. if (HighLogic.CurrentGame.Mode == Game.Modes.MISSION) { return(false); } if (HighLogic.LoadedSceneIsEditor) { return(false); } if (KRASHWrapper.simulationActive()) { return(false); } if (!FailureAllowed()) { return(false); } //every time a part fails the check, we increment the failure Check multiplier if (Randomiser.instance.NextDouble() < chanceOfFailure) { UPFMUtils.instance.numberOfFailures.TryGetValue(part.name, out int i); UPFMUtils.instance.numberOfFailures.Remove(part.name); i++; UPFMUtils.instance.numberOfFailures.Add(part.name, i); #if DEBUG Debug.Log("[UPFM]: " + part.name + " has now failed " + i + " times"); #endif return(true); } return(false); }
private void CheckForFailures() { if (!FlightGlobals.ready) { return; } if (KRASHWrapper.simulationActive()) { return; } if (FlightGlobals.ActiveVessel.FindPartModuleImplementing <ModuleUPFMEvents>() != null) { if (FlightGlobals.ActiveVessel.FindPartModuleImplementing <ModuleUPFMEvents>().tested == false) { return; } } if (Planetarium.GetUniversalTime() < nextFailureCheck) { return; } if (vesselSafetyRating == -1) { return; } List <BaseFailureModule> failureModules = FlightGlobals.ActiveVessel.FindPartModulesImplementing <BaseFailureModule>(); if (failureModules.Count == 0) { return; } if (!VesselIsLaunched()) { return; } chanceOfFailure = 0.11 - (vesselSafetyRating * 0.01); if (chanceOfFailure < minimumFailureChance) { chanceOfFailure = minimumFailureChance; } SetNextCheck(failureModules); double failureRoll = _randomiser.NextDouble(); if (HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().logging) { Logger.instance.Log("Failure Chance: " + chanceOfFailure + ", Rolled: " + failureRoll + " Succeeded: " + (failureRoll <= chanceOfFailure).ToString()); } if (failureRoll > chanceOfFailure) { return; } Logger.instance.Log("Failure Event! Safety Rating: " + vesselSafetyRating + ", MET: " + FlightGlobals.ActiveVessel.missionTime); BaseFailureModule failedModule = null; int counter = failureModules.Count() - 1; failureModules = failureModules.OrderBy(f => f.chanceOfFailure).ToList(); while (counter >= 0) { failedModule = failureModules.ElementAt(counter); counter--; if (failedModule.hasFailed) { continue; } if (failedModule.isSRB) { continue; } if (failedModule.excluded) { continue; } if (!failedModule.launched) { return; } if (!failedModule.FailureAllowed()) { continue; } if (_randomiser.NextDouble() < failedModule.chanceOfFailure) { if (failedModule.hasFailed) { continue; } StartFailure(failedModule); Logger.instance.Log("Failing " + failedModule.part.partInfo.title); break; } } if (counter < 0) { Logger.instance.Log("No parts failed this time. Aborted failure"); } }