/// <summary> /// Causes the starting part's failure. /// </summary> private void CauseStartingPartFailure() { // If a valid game tick. if (ticksSinceFailureStart % ticksBetweenPartExplosions == 0) { // Need to start overloading the thrust and increase the part's temperature. thrustOverload += (int)(startingPartEngineModule.maxThrust / 30.0); startingPartEngineModule.rigidbody.AddRelativeForce(Vector3.forward * thrustOverload); startingPart.temperature += startingPart.maxTemp / 20.0; } // When the part explodes to overheating. if (startingPart.temperature >= startingPart.maxTemp) { // Log flight data. KLFUtils.LogFlightData(activeVessel, "Random failure of " + startingPart.partInfo.title + "."); // If the auto abort sequence is on and this is the starting part, trigger the Abort action group. if (KLFSettings.Instance.AutoAbort) { activeVessel.ActionGroups.SetGroup(KSPActionGroup.Abort, true); } // Gather the doomed parts at the time of failure. PrepareDoomedParts(); // Nullify the starting part. startingPart = null; } }
public void AddAndReportScience() { if (scienceAfterFailure > 0) { KLFUtils.LogFlightData(activeVessel, scienceAfterFailure.ToString() + " Science gained due to lessons learned."); ResearchAndDevelopment.Instance.AddScience(scienceAfterFailure, TransactionReasons.VesselLoss); } }
/// <summary> /// Explodes the next doomed part. /// </summary> private void ExplodeNextDoomedPart() { // The next part to explode. Part nextDoomedPart = GetNextDoomedPart(); // Tick was invalid here. if (nextDoomedPart == null) { return; } // Log flight data. KLFUtils.LogFlightData(activeVessel, nextDoomedPart.partInfo.title + " disassembly due to an earlier failure."); // The fun stuff... nextDoomedPart.explode(); }
/// <summary> /// Causes the starting part's failure. /// </summary> private bool CauseStartingPartFailure() { if (activeVessel.Parts.Where(o => o == startingPart).Count() == 0) { ScreenMessages.PostScreenMessage("Failing " + startingPart.partInfo.title + " no longer attached to vessel", 5.0f, ScreenMessageStyle.UPPER_CENTER); // Log flight data. KLFUtils.LogFlightData(activeVessel, "Failing " + startingPart.partInfo.title + " no longer attached to vessel."); // Nullify the starting part. startingPart = null; doomedParts = null; return(false); } if (preFailureTime + preFailureWarningTime > Planetarium.GetUniversalTime()) { // This makes sure that one message a second is put to the screen if (lastWarningtime < Planetarium.GetUniversalTime()) { ScreenMessages.PostScreenMessage("Imminent Failure on " + startingPart.partInfo.title, 1.0f, ScreenMessageStyle.UPPER_CENTER); HighlightFailingPart(startingPart); lastWarningtime = Planetarium.GetUniversalTime() + 1; } return(true); } // If a valid game tick. if (ticksSinceFailureStart % ticksBetweenPartFailures == 0 && (startingPartEngineModule != null && startingPartEngineModule.finalThrust > 0)) { // Need to start overloading the thrust and increase the part's temperature. // Calculate actual throttle, the lower of either the throttle setting or the current thrust / max thrust float throttle = startingPartEngineModule.finalThrust / startingPartEngineModule.maxThrust; if (overThrust) { thrustOverload += (int)(startingPartEngineModule.maxThrust / 30.0 * throttle); startingPartEngineModule.part.Rigidbody.AddRelativeForce(Vector3.up * thrustOverload); // startingPart.temperature += startingPart.maxTemp / 20.0; startingPart.temperature += startingPart.maxTemp / 20.0 * throttle; } else { // Underthrust will change every 1/2 second if (underthrustTime < Planetarium.GetUniversalTime()) { underThrustStart = underThrustEnd; underThrustEnd = (float)((0.9 - KLFUtils.RNG.NextDouble() / 2) * 100); //if (startingPartEngineModule.thrustPercentage < 0) // startingPartEngineModule.thrustPercentage = KLFUtils.RNG.NextDouble() / 4; // startingPartEngineModule.part.Rigidbody.AddRelativeForce(Vector3.up * thrustOverload); underthrustTime = Planetarium.GetUniversalTime() + 0.5; // startingPart.temperature += startingPart.maxTemp / 50.0 * throttle; } startingPartEngineModule.thrustPercentage = Mathf.Lerp(underThrustStart, underThrustEnd, 1 - (float)(Planetarium.GetUniversalTime() - underthrustTime) / 0.5f); } // startingPart.temperature += startingPart.maxTemp / 20.0 * throttle; } if (ticksSinceFailureStart % ticksBetweenPartFailures == 0 && failureType != FailureType.engine) { ++decouplerForceCnt; //Log.Info("decouplerForceCnt: " + decouplerForceCnt.ToString()); if (decouplerForceCnt > 20) { startingPart.decouple(startingPart.breakingForce + 1); } } // When the part explodes to overheating. if (startingPart.temperature >= startingPart.maxTemp || decouplerForceCnt > 20) { // Log flight data. if (failureType != FailureType.engine) { KLFUtils.LogFlightData(activeVessel, "Random structural failure of " + startingPart.partInfo.title + "."); } else { if (overThrust) { KLFUtils.LogFlightData(activeVessel, "Random failure of " + startingPart.partInfo.title + "."); } else { KLFUtils.LogFlightData(activeVessel, "Underthrust of " + startingPart.partInfo.title + "."); } } // Gather the doomed parts at the time of failure. PrepareDoomedParts(); failureTime = Double.MaxValue; // Nullify the starting part. startingPart = null; } else { if (lastWarningtime < Planetarium.GetUniversalTime() && (startingPart.temperature >= lastTemp || decouplerForceCnt > 20)) { HighlightFailingPart(startingPart); if (failureType != FailureType.engine) { ScreenMessages.PostScreenMessage(startingPart.partInfo.title + " structural failure imminent ", 1.0f, ScreenMessageStyle.UPPER_CENTER); } else { if (overThrust) { ScreenMessages.PostScreenMessage(startingPart.partInfo.title + " temperature exceeding limits: " + Math.Round(startingPart.temperature, 1).ToString(), 1.0f, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage(startingPart.partInfo.title + " losing thrust", 1.0f, ScreenMessageStyle.UPPER_CENTER); } } lastWarningtime = Planetarium.GetUniversalTime() + 1; lastTemp = startingPart.temperature; } // If the auto abort sequence is on and this is the starting part, trigger the Abort action group. if (KLFSettings.Instance.AutoAbort) { if (failureTime == 0) { failureTime = Planetarium.GetUniversalTime(); } else { Debug.Log("failureTime: " + failureTime.ToString() + " AutoAbortDelay: " + KLFSettings.Instance.AutoAbortDelay.ToString() + " Planetarium.GetUniversalTime: " + Planetarium.GetUniversalTime().ToString()); if (failureTime + KLFSettings.Instance.AutoAbortDelay < Planetarium.GetUniversalTime()) { Debug.Log("Triggering autoabort"); activeVessel.ActionGroups.SetGroup(KSPActionGroup.Abort, true); AddAndReportScience(); // Following just to be sure the abort isn't triggered more than once failureTime = Double.MaxValue; } } } } return(true); }