protected override void update_ETA()
        {
            update_workforce();
            var lastEndUT = EndUT;

            if (EffectiveWorkforce > 0)
            {
                if (LastUpdateTime < 0)
                {
                    LastUpdateTime = Planetarium.GetUniversalTime();
                }
                CurrentTask.Kit.CheckinWorker(this);
                var ETA = CurrentTask.Kit.CurrentTaskETA;
                if (ETA > 0)
                {
                    var time = Planetarium.GetUniversalTime();
                    EndUT       = time + ETA;
                    ETA_Display = "Time left: " + KSPUtil.PrintTimeCompact(ETA, false);
                }
            }
            else
            {
                EndUT = -1;
            }
            if (EndUT < 0)
            {
                ETA_Display = "Stalled...";
            }
            if (Math.Abs(EndUT - lastEndUT) > 1)
            {
                checkin();
            }
        }
Exemplo n.º 2
0
        // Failure methods
        public override void DoFailure()
        {
            if (!TestFlightEnabled)
            {
                return;
            }
            Failed = true;
            float           multiplier = 0;
            ITestFlightCore core       = TestFlightUtil.GetCore(this.part, Configuration);

            if (core != null)
            {
                core.ModifyFlightData(duFail, true);
                string met = KSPUtil.PrintTimeCompact((int)Math.Floor(this.vessel.missionTime), false);
                if (dynPressurePenalties)
                {
                    multiplier = pressureCurve.Evaluate((float)(part.dynamicPressurekPa * 1000d));
                    if (multiplier <= 0f)
                    {
                        multiplier = 1f;
                    }
                }

                if (multiplier > float.Epsilon)
                {
                    FlightLogger.eventLog.Add($"[{met}] {core.Title} failed: Ignition Failure.  {(float)(part.dynamicPressurekPa * 1000d)}Pa dynamic pressure cased a {(1f-multiplier) * 100f}% reduction in normal ignition reliability.");
                }
                else
                {
                    FlightLogger.eventLog.Add($"[{met}] {core.Title} failed: Ignition Failure.");
                }
            }
            Log(String.Format("IgnitionFail: Failing {0} engine(s)", engines.Count));
            for (int i = 0; i < engines.Count; i++)
            {
                EngineHandler engine = engines[i];
                if (engine.failEngine)
                {
                    engine.engine.Shutdown();

                    if (severity.ToLowerInvariant() == "major")
                    {
                        // For some reason, need to disable GUI as well
                        engine.engine.Events["Activate"].active    = false;
                        engine.engine.Events["Shutdown"].active    = false;
                        engine.engine.Events["Activate"].guiActive = false;
                        engine.engine.Events["Shutdown"].guiActive = false;
                    }
                    if ((restoreIgnitionCharge) || (this.vessel.situation == Vessel.Situations.PRELAUNCH))
                    {
                        RestoreIgnitor();
                    }
                    engines[i].failEngine = false;
                }
            }
        }
 /// <summary>
 /// Triggers the failure controlled by the failure module
 /// </summary>
 public virtual void DoFailure()
 {
     Failed = true;
     ITestFlightCore core = TestFlightUtil.GetCore(this.part, Configuration);
     if (core != null)
     {
         core.ModifyFlightData(duFail, true);
         FlightLogger.eventLog.Add(String.Format("[{0}] {1} failed: {2}", KSPUtil.PrintTimeCompact((int)Math.Floor(this.vessel.missionTime), false), core.Title, failureTitle));
     }
 }
Exemplo n.º 4
0
        private void triggerFailure(int type)
        {
            failure_du += failureData[type];
            failureTypes ft = (failureTypes)type;

            updateCore();             /* Make sure we save our failureData, just in case we explode the part */
            Logging.LogFormat("Failing engine {0}: {1}", configuration, ft.ToString());
            ScreenMessages.PostScreenMessage(String.Format("[TestLite] {0} on {1}", failureDescription[type], configuration), 5f);
            FlightLogger.eventLog.Add(String.Format("[{0}] {1} on {2}", KSPUtil.PrintTimeCompact((int)Math.Floor(this.vessel.missionTime), false), failureDescription[type], configuration));
            switch (severityType[type])
            {
            case 0:
                transient_failure = true;
                break;

            case 1:
                minor_failure = true;
                break;

            case 2:
                major_failure = true;
                break;
            }
            switch (ft)
            {
            case failureTypes.TRANSIENT:
            case failureTypes.IGNITION:
                engine.Shutdown();
                break;

            case failureTypes.PERMANENT:
                engine.Shutdown();
                /* It's permanently dead.  It might even explode. */
                engine.ignitions = 0;
                if (Core.Instance.rand.Next(3) == 0)
                {
                    part.explode();
                }
                break;

            case failureTypes.PERFLOSS:
                engine.ispMult *= 0.4d + Core.Instance.rand.NextDouble() * 0.2d;
                break;

            case failureTypes.THRUSTLOSS:
                engine.flowMult *= 0.4d + Core.Instance.rand.NextDouble() * 0.2d;
                break;
            }
            setColour();
        }
Exemplo n.º 5
0
        private static void AppendDeltaTime(double subspaceTime)
        {
            var currentTime = TimeSyncerSystem.UniversalTime;

            if (subspaceTime < currentTime)
            {
                StringBuilder.Append(NegativeDeltaTimePrefix).Append(KSPUtil.PrintTimeCompact(currentTime - subspaceTime, false));
            }
            else
            {
                StringBuilder.Append(PositiveDeltaTimePrefix).Append(KSPUtil.PrintTimeCompact(subspaceTime - currentTime, false));
            }

            StringBuilder.Append(CloseDeltaTime);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Replaces the common tokens like "[year]" with their appropriate values as gathered from KSP
        /// </summary>
        /// <param name="sourceString">The source string to act on</param>
        /// <returns>The string post replacements</returns>
        public static string ReplaceStandardTokens(string sourceString)
        {
            string str = sourceString;

            str = ReplaceToken(str, "UT", Planetarium.fetch != null ? Math.Round(Planetarium.GetUniversalTime()).ToString() : "0");
            str = ReplaceToken(str, "save", HighLogic.SaveFolder != null && HighLogic.SaveFolder.Trim().Length > 0 ? HighLogic.SaveFolder : "NA");
            str = ReplaceToken(str, "version", Versioning.GetVersionString());
            str = ReplaceToken(str, "vessel", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.vesselName : "NA");
            str = ReplaceToken(str, "body", Planetarium.fetch != null ? Planetarium.fetch.CurrentMainBody.GetDisplayName() : "NA");
            str = ReplaceToken(str, "situation", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.situation.ToString() : "NA");
            str = ReplaceToken(str, "biome", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude) : "NA");


            double ut = 0;

            int[] times = { 0, 0, 0, 0, 0 };
            if (Planetarium.fetch != null)
            {
                ut    = Planetarium.GetUniversalTime();
                times = Utilities.ConvertUT(ut);
            }
            str = ReplaceToken(str, "year", times[0].ToString());
            str = ReplaceToken(str, "year0", times[0].ToString("D3"));
            str = ReplaceToken(str, "day", times[1].ToString());
            str = ReplaceToken(str, "day0", times[1].ToString("D3"));
            str = ReplaceToken(str, "hour", times[2].ToString());
            str = ReplaceToken(str, "hour0", times[2].ToString("D2"));
            str = ReplaceToken(str, "min", times[3].ToString());
            str = ReplaceToken(str, "min0", times[3].ToString("D2"));
            str = ReplaceToken(str, "sec", times[4].ToString());
            str = ReplaceToken(str, "sec0", times[4].ToString("D2"));
            str = ReplaceToken(str, "kspDate", KSPUtil.PrintDate(ut, false).Trim());

            string time = KSPUtil.PrintTimeCompact(0, false);

            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null)
            {
                time = KSPUtil.PrintTimeCompact((int)FlightGlobals.ActiveVessel.missionTime, false);
            }
            time = time.Replace(":", "-"); //Can't use colons in filenames on Windows, so we'll replace them with "-"

            str = ReplaceToken(str, "MET", time);

            return(str);
        }
 public bool CheckETA(double now)
 {
     if (State != ProtoGroundWorkshop.Status.ACTIVE)
     {
         return(false);
     }
     if (EndUT > 0 && EndUT < now)
     {
         Utils.Message(10, "Engineers at '{0}' should have assembled the '{1}' by now.",
                       VesselName, KitName);
         State = ProtoGroundWorkshop.Status.COMPLETE;
         EndUT = -1;
         return(true);
     }
     ETA = EndUT > 0?
           "Time left: " + KSPUtil.PrintTimeCompact(EndUT - now, false) : "Stalled...";
     return(false);
 }
 public void FixedUpdate()
 {
     if (HighLogic.LoadedSceneIsFlight && onePresent)
     {
         if (recordingActive)
         {
             if (base.resHandler.UpdateModuleResourceInputs(ref readoutInfo, 1.0, 0.9, true, true))
             {
                 if (!anim.IsPlaying(anim.name))
                 {
                     anim.Play();
                 }
                 DateTime now = DateTime.Now;
                 if (!headerCreated)
                 {
                     KBDataLog.Writelog("//Data recording began on: " + base.vessel.mainBody.ToString());
                     KBDataLog.Writelog("//" + now.ToString(dateFormat));
                     KBDataLog.Writelog("//Format: ");
                     KBDataLog.Writelog(optionstring + ",Altitude");
                     headerCreated = true;
                 }
                 checkTime -= Time.deltaTime;
                 Debug.Log(checkTime);
                 if (checkTime <= 0f)
                 {
                     string text = "";
                     foreach (ModuleEnviroSensor item in EnvSensor)
                     {
                         if (item.sensorType == ModuleEnviroSensor.SensorType.TEMP)
                         {
                             if (item.sensorActive)
                             {
                                 ThermOn = true;
                                 text    = text + "," + base.vessel.atmosphericTemperature;
                             }
                             else
                             {
                                 ThermOn = false;
                                 text   += ",Sensor Inactive";
                             }
                         }
                         if (item.sensorType == ModuleEnviroSensor.SensorType.GRAV)
                         {
                             if (item.sensorActive)
                             {
                                 double distFromCenter = base.vessel.mainBody.Radius + base.vessel.altitude;
                                 text = text + "," + base.vessel.mainBody.gravParameter / (double)Mathf.Pow((float)distFromCenter, 2f);
                             }
                             else
                             {
                                 text += ",Sensor Inactive";
                             }
                         }
                         if (item.sensorType == ModuleEnviroSensor.SensorType.PRES)
                         {
                             if (item.sensorActive)
                             {
                                 BaramOn = true;
                                 text    = text + "," + base.vessel.staticPressurekPa;
                             }
                             else
                             {
                                 BaramOn = false;
                                 text   += ",Sensor Inactive";
                             }
                         }
                         if (item.sensorType == ModuleEnviroSensor.SensorType.ACC)
                         {
                             text = ((!item.sensorActive) ? (text + ",Sensor Inactive") : (text + "," + base.vessel.geeForce));
                         }
                     }
                     foreach (KBModuleEnviroSensor item2 in KBEnvSensor)
                     {
                         if (item2.sensorType == KBModuleEnviroSensor.SensorType.TIME)
                         {
                             text = ((!item2.sensorActive) ? ("Sensor Inactive,Sensor Inactive,Sensor Inactive" + text) : (now.ToString(hourFormat) + "," + KSPUtil.PrintTimeCompact(Planetarium.GetUniversalTime(), true) + "," + base.vessel.missionTime + text));
                         }
                         if (ThermPresent && BaromPresent)
                         {
                             text = ((!ThermOn || !BaramOn) ? (text + ",Sensor Inactive") : (text + "," + base.vessel.atmDensity));
                         }
                         if (item2.sensorType == KBModuleEnviroSensor.SensorType.SEXT)
                         {
                             text = ((!item2.sensorActive) ? (text + ",Sensor Inactive,Sensor Inactive") : (text + "," + base.vessel.latitude + "," + base.vessel.longitude));
                         }
                     }
                     text = text + "," + base.vessel.altitude;
                     KBDataLog.Writelog(text);
                     checkTime = recordingSeconds + Math.Abs(checkTime);
                 }
             }
         }
         else
         {
             DoReset();
         }
     }
 }
Exemplo n.º 9
0
        /// <summary>
        /// Replaces the common tokens like "[year]" with their appropriate values as gathered from KSP
        /// </summary>
        /// <param name="sourceString">The source string to act on</param>
        /// <returns>The string post replacements</returns>
        public static string ReplaceStandardTokens(string sourceString)
        {
            string str = sourceString;

            bool counterFound = str.Contains("cnt");



            str = ReplaceToken(str, "UT", Planetarium.fetch != null ? Math.Round(Planetarium.GetUniversalTime()).ToString() : "0");
            //str = ReplaceToken(str, "save", HighLogic.SaveFolder != null && HighLogic.SaveFolder.Trim().Length > 0 ? HighLogic.SaveFolder : "NA");
            //str = ReplaceToken(str, "version", Versioning.GetVersionString());
            str = ReplaceToken(str, "vessel", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.vesselName : "");
            str = ReplaceToken(str, "body", Planetarium.fetch != null ? Planetarium.fetch.CurrentMainBody.GetDisplayName() : "");
            str = ReplaceToken(str, "situation", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.situation.ToString() : "");
            str = ReplaceToken(str, "biome", HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null ? ScienceUtil.GetExperimentBiome(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude) : "");


            int[] times = { 0, 0, 0, 0, 0 };
            if (Planetarium.fetch != null)
            {
                times = ConvertUT(Planetarium.GetUniversalTime());
            }
            if (!counterFound)
            {
                str = ReplaceToken(str, "year", times[0].ToString());
            }
            str = ReplaceToken(str, "year0", times[0].ToString("D3"));
            if (!counterFound)
            {
                str = ReplaceToken(str, "day", times[1].ToString());
            }
            str = ReplaceToken(str, "day0", times[1].ToString("D3"));
            if (!counterFound)
            {
                str = ReplaceToken(str, "hour", times[2].ToString());
            }
            str = ReplaceToken(str, "hour0", times[2].ToString("D2"));
            if (!counterFound)
            {
                str = ReplaceToken(str, "min", times[3].ToString());
            }
            str = ReplaceToken(str, "min0", times[3].ToString("D2"));
            if (!counterFound)
            {
                str = ReplaceToken(str, "sec", times[4].ToString());
            }
            str = ReplaceToken(str, "sec0", times[4].ToString("D2"));


            string time = KSPUtil.PrintTimeCompact(0, false);

            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel != null)
            {
                time = KSPUtil.PrintTimeCompact((int)FlightGlobals.ActiveVessel.missionTime, false);
            }
            time = time.Replace(":", "-"); //Can't use colons in filenames on Windows, so we'll replace them with "-"

            str = ReplaceToken(str, "MET", time);

            if (str.Contains("cnt"))
            {
                int zeroes = 0;
                while (str.Contains("cnt" + Repeated('0', zeroes + 1)))
                {
                    zeroes++;
                }
                string token = "cnt" + Repeated('0', zeroes);

                string   searchstr = ReplaceToken(str, token, "*.sfs");
                int      beginning = str.IndexOf(token);
                string[] files     = Directory.GetFiles(SaveDir, searchstr);
                int      cnt       = files.Length;
                for (int i = 0; i < files.Length; i++)
                {
                    int    z          = zeroes;
                    string counterStr = files[i].Substring(SaveDir.Length + beginning);
                    if (zeroes == 0)
                    {
                        while (z < counterStr.Length && Char.IsDigit(counterStr[z]))
                        {
                            z++;
                        }
                    }
                    counterStr = counterStr.Substring(0, z);

                    int x = 0;
                    int.TryParse(counterStr, out x);
                    cnt = Math.Max(cnt, x);
                }
                str = ReplaceToken(str, token, (cnt + 1).ToString("D" + zeroes.ToString()));
            }
            return(str);
        }
Exemplo n.º 10
0
 public static string GetTimeLabel(SubspaceDisplayEntry currentEntry)
 {
     return($"T: +{KSPUtil.PrintTimeCompact(SystemsContainer.Get<WarpSystem>().GetSubspaceTime(currentEntry.SubspaceId), false)}");
 }
Exemplo n.º 11
0
        public void DrawContent(int windowId)
        {
            GUILayout.BeginVertical();
            GUI.DragWindow(MoveRect);

            #region Horizontal toolbar

            GUILayout.BeginHorizontal();

            GUILayout.FlexibleSpace();
            var chatButtonStyle = ButtonStyle;
            if (ChatSystem.Singleton.ChatButtonHighlighted)
            {
                chatButtonStyle = HighlightStyle;
            }
            if (!SettingsSystem.ServerSettings.DropControlOnVesselSwitching)
            {
                var tooltip = "Drops control of the vessels that you are not controlling so other players can control them";
                if (GUILayout.Button(new GUIContent("DropCtrl", tooltip), ButtonStyle))
                {
                    VesselLockSystem.Singleton.DropAllOtherVesselControlLocks();
                }
            }
            ChatWindow.Singleton.Display         = GUILayout.Toggle(ChatWindow.Singleton.Display, "Chat", chatButtonStyle);
            CraftLibraryWindow.Singleton.Display = GUILayout.Toggle(CraftLibraryWindow.Singleton.Display, "Craft", ButtonStyle);
            DebugWindow.Singleton.Display        = GUILayout.Toggle(DebugWindow.Singleton.Display, "Debug", ButtonStyle);

            GUILayout.EndHorizontal();

            #endregion

            #region Players information

            ScrollPosition = GUILayout.BeginScrollView(ScrollPosition, ScrollStyle);

            //Draw other subspaces
            foreach (var currentEntry in SubspaceDisplay)
            {
                if (currentEntry.SubspaceId == -1)
                {
                    //Draw the warping players
                    GUILayout.BeginHorizontal(SubspaceStyle);
                    GUILayout.Label("WARPING");
                    GUILayout.EndHorizontal();
                }
                else
                {
                    GUILayout.BeginHorizontal(SubspaceStyle);
                    GUILayout.Label("T: +" + KSPUtil.PrintTimeCompact(WarpSystem.Singleton.GetSubspaceTime(currentEntry.SubspaceId), false));
                    GUILayout.FlexibleSpace();
                    if (NotWarpingAndIsFutureSubspace(currentEntry.SubspaceId) && GUILayout.Button("Sync", ButtonStyle))
                    {
                        WarpSystem.Singleton.CurrentSubspace = currentEntry.SubspaceId;
                    }
                    GUILayout.EndHorizontal();
                }

                foreach (var currentPlayer in currentEntry.Players)
                {
                    DrawPlayerEntry(currentPlayer == SettingsSystem.CurrentSettings.PlayerName
                        ? StatusSystem.Singleton.MyPlayerStatus
                        : StatusSystem.Singleton.GetPlayerStatus(currentPlayer));
                }
            }

            GUILayout.EndScrollView();

            #endregion

            GUILayout.FlexibleSpace();
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Disconnect", ButtonStyle))
            {
                DisconnectEventHandled = false;
            }
            OptionsWindow.Singleton.Display = GUILayout.Toggle(OptionsWindow.Singleton.Display, "Options", ButtonStyle);
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();
        }
Exemplo n.º 12
0
 public static string GetTimeLabel(SubspaceDisplayEntry currentEntry)
 {
     return($"T: +{KSPUtil.PrintTimeCompact(WarpSystem.Singleton.GetSubspaceTime(currentEntry.SubspaceId), false)}");
 }
Exemplo n.º 13
0
 private bool ExecuteDestroyAction()
 {
     if (FlightGlobals.ActiveVessel != null)
     {
         FlightLogger.eventLog.Add(string.Format("[{0}]: Craft destroyed by range safety.", KSPUtil.PrintTimeCompact((int)Math.Floor(FlightGlobals.ActiveVessel.missionTime), false)));
         FlightGlobals.ActiveVessel.Die();
     }
     return(true);
 }
Exemplo n.º 14
0
 private bool ExecuteAbortAction()
 {
     if (FlightGlobals.ActiveVessel != null)
     {
         abortMET = FlightGlobals.ActiveVessel.missionTime;
         FlightLogger.eventLog.Add(string.Format("[{0}]: ABORT triggered by range safety.", KSPUtil.PrintTimeCompact((int)Math.Floor(abortMET.Value), false)));
         FlightGlobals.ActiveVessel.ActionGroups.ToggleGroup(KSPActionGroup.Abort);
     }
     return(true);
 }
Exemplo n.º 15
0
 private void EnterSafeState(FlightStatus triggerStatus)
 {
     FlightLogger.eventLog.Add(string.Format("[{0}]: Range safety entered SAFE state: {1}", KSPUtil.PrintTimeCompact((int)Math.Floor(FlightGlobals.ActiveVessel.missionTime), false), FlightCorridorBase.GetFlightStatusText(triggerStatus)));
     State = RangeState.Safe;
 }
Exemplo n.º 16
0
        private void EnterArmedState(FlightStatus triggerStatus)
        {
            FlightLogger.eventLog.Add(string.Format("[{0}]: Range safety entered ARM state: {1}", KSPUtil.PrintTimeCompact((int)Math.Floor(FlightGlobals.ActiveVessel.missionTime), false), FlightCorridorBase.GetFlightStatusText(triggerStatus)));
            State = RangeState.Armed;

            if (rangeSafetyInstance.settings.terminateThrustOnArm)
            {
                actionQueue.Enqueue(RangeActions.TerminateThrust);
            }
            if (rangeSafetyInstance.settings.destroySolids)
            {
                actionQueue.Enqueue(RangeActions.DestroySolids);
            }
            if (rangeSafetyInstance.settings.coastToApogeeBeforeAbort)
            {
                actionQueue.Enqueue(RangeActions.CoastToApogee);
            }
            if (rangeSafetyInstance.settings.abortOnArm)
            {
                actionQueue.Enqueue(RangeActions.ExecuteAbort);
            }
            if (rangeSafetyInstance.settings.delay3secAfterAbort)
            {
                actionQueue.Enqueue(RangeActions.WaitForAbortToClear);
            }
            if (rangeSafetyInstance.settings.destroyLaunchVehicle)
            {
                actionQueue.Enqueue(RangeActions.TerminateFlight);
            }
        }
Exemplo n.º 17
0
        private void triggerFailure(int type)
        {
            if (isSolid)               /* Map non-solid-appropriate failureTypes to more suitable ones */
            {
                if (type == (int)failureTypes.TRANSIENT)
                {
                    type = (int)failureTypes.PERMANENT;
                }
                else if (type == (int)failureTypes.THRUSTLOSS)
                {
                    type = (int)failureTypes.PERFLOSS;
                }
            }
            double fdScale  = Math.Min(1.0, (remainingBurnTime + ratedContinuousBurnTime + 5.0 - currentRunTime) / ratedContinuousBurnTime);
            double award_du = failureData[type] * Math.Pow(fdScale, 2.0);

            failure_du += award_du;
            failureTypes ft = (failureTypes)type;

            updateCore();             /* Make sure we save our failureData, just in case we explode the part */
            Logging.LogFormat("Failing engine {0}: {1}; awarding {2} du", configuration, ft.ToString(), award_du);
            ScreenMessages.PostScreenMessage(String.Format("[TestLite] {0} on {1}", failureDescription[type], configuration), 5f);
            FlightLogger.eventLog.Add(String.Format("[{0}] {1} on {2}", KSPUtil.PrintTimeCompact((int)Math.Floor(this.vessel.missionTime), false), failureDescription[type], configuration));
            switch (severityType[type])
            {
            case 0:
                transient_failure = true;
                break;

            case 1:
                minor_failure = true;
                break;

            case 2:
                major_failure = true;
                break;
            }
            switch (ft)
            {
            case failureTypes.TRANSIENT:
            case failureTypes.IGNITION:
                engine.Shutdown();
                break;

            case failureTypes.PERMANENT:
                engine.Shutdown();
                /* It's permanently dead.  It might even explode. */
                engine.ignitions = 0;
                if (isSolid || Core.Instance.rand.Next(3) == 0)                   /* Solids always explode */
                {
                    part.explode();
                    if (!determinismMode)
                    {
                        fraternalDamage();
                    }
                }
                break;

            case failureTypes.PERFLOSS:
                engine.ispMult *= 0.4d + Core.Instance.rand.NextDouble() * 0.2d;
                break;

            case failureTypes.THRUSTLOSS:
                engine.flowMult *= 0.4d + Core.Instance.rand.NextDouble() * 0.2d;
                break;
            }
            setColour();
        }