private void StockProcFairing_st_idle_replacement(bool save, Part part)
        {
            var module = part.Module <ModuleProceduralFairing>();

            MethodInfo[] m = part.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            FieldInfo[] fields = module.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (replacement_st_editor_idle == null)
            {
                replacement_st_editor_idle = new KFSMState("st_idle");
                replacement_st_editor_idle.OnLateUpdate = delegate
                {
                    MouseFadeUpdate();
                };
            }

            foreach (FieldInfo fi in fields)
            {
                if (fi.Name == "fsm")
                {
                    fsm = (KerbalFSM)fi.GetValue(module);
                    FieldInfo[] fsmFields = fsm.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                    foreach (FieldInfo fsmFi in fsmFields)
                    {
                        if (fsmFi.Name == "States")
                        {
                            List <KFSMState> States = (List <KFSMState>)fsmFi.GetValue(fsm);

                            foreach (var s in States)
                            {
                                log.debug(string.Format("KFSMState name: {0}", s.name));
                                if (s.name == "st_idle")
                                {
                                    if (save)
                                    {
                                        saved_st_editor_idle = s;
                                        States.Remove(s);
                                        fsm.AddState(replacement_st_editor_idle);
                                    }
                                    else
                                    {
                                        States.Remove(s);
                                        fsm.AddState(saved_st_editor_idle);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    fsm.StartFSM("st_idle");
                    if (!save)
                    {
                        foreach (var p in module.Panels)
                        {
                            p.SetExplodedView(0);
                            p.SetOpacity(1);
                        }
                    }
                    break;
                }
            }
        }
        /// <summary>
        /// Intiialize the maneuver pilot FSM.
        /// </summary>
        private void ManeuverPilotInitialize()
        {
            KFSMState idleState = new KFSMState("Idle");

            idleState.updateMode = KFSMUpdateMode.FIXEDUPDATE;

            KFSMState coastState = new KFSMState("Coasting");

            coastState.updateMode = KFSMUpdateMode.FIXEDUPDATE;

            MASFlyState flyState = new MASFlyState("Flying", this);

            flyState.updateMode    = KFSMUpdateMode.FIXEDUPDATE;
            flyState.OnEnter       = flyState.OnEnterImpl;
            flyState.OnFixedUpdate = flyState.OnFixedUpdateImpl;

            KFSMEvent stopPilot = new KFSMEvent("Stop Pilot");

            stopPilot.updateMode       = KFSMUpdateMode.FIXEDUPDATE;
            stopPilot.OnCheckCondition = (KFSMState currentState) =>
            {
                bool stopThisPilot = (maneuverPilotEngaged == false || attitudePilotEngaged == false || node == null);
                if (stopThisPilot)
                {
                    CancelAutopilots();
                    //Utility.LogMessage(this, "StopPilot  event: Transitioning");
                }
                return(stopThisPilot);
            };
            stopPilot.GoToStateOnEvent = idleState;

            KFSMEvent startPilot = new KFSMEvent("Start Pilot");

            startPilot.updateMode       = KFSMUpdateMode.FIXEDUPDATE;
            startPilot.OnCheckCondition = (KFSMState currentState) =>
            {
                return(maneuverPilotEngaged);
            };
            startPilot.GoToStateOnEvent = coastState;

            KFSMEvent flyPilot = new KFSMEvent("Fly Pilot");

            flyPilot.updateMode       = KFSMUpdateMode.FIXEDUPDATE;
            flyPilot.OnCheckCondition = (KFSMState currentState) =>
            {
                if (maneuverPilotEngaged)     // Should be redundant?
                {
                    double burnTime = NodeBurnTime();

                    if (burnTime > 0.0 && burnTime * 0.5 >= -maneuverNodeTime)
                    {
#if VERBOSE_AUTOPILOT_LOGGING
                        Utility.LogMessage(this, "FlyPilot   event: Transitioning");
#endif
                        return(true);
                    }
                }
                return(false);
            };
            flyPilot.GoToStateOnEvent = flyState;

            KFSMEvent doneFlying = new KFSMEvent("Done Event");
            doneFlying.updateMode       = KFSMUpdateMode.FIXEDUPDATE;
            doneFlying.OnCheckCondition = (KFSMState currentState) =>
            {
                if (maneuverNodeDeltaV < 0.15)
                {
                    CancelAutopilots();
                    if (vessel.patchedConicSolver != null)
                    {
                        vessel.patchedConicSolver.maneuverNodes.Clear();
                    }
                    try
                    {
                        FlightInputHandler.state.mainThrottle = 0.0f;
                    }
                    catch
                    {
                    }
#if VERBOSE_AUTOPILOT_LOGGING
                    Utility.LogMessage(this, "Done flying...");
#endif
                    return(true);
                }
                return(false);
            };
            doneFlying.GoToStateOnEvent = idleState;

            idleState.AddEvent(startPilot);
            coastState.AddEvent(stopPilot);
            coastState.AddEvent(flyPilot);
            flyState.AddEvent(stopPilot);
            flyState.AddEvent(doneFlying);

            maneuverPilot.AddState(idleState);
            maneuverPilot.AddState(coastState);
            maneuverPilot.AddState(flyState);

            maneuverPilot.StartFSM(idleState);
        }
        public void SetupFSM()
        {
            fsm = new KerbalFSM();

            st_stowed = new KFSMState("stowed");
            fsm.AddState(st_stowed);
            st_stowed_locked = new KFSMState("stowed_locked");
            fsm.AddState(st_stowed_locked);
            st_deploying = new KFSMState("deploying");
            fsm.AddState(st_deploying);
            st_deployed = new KFSMState("deployed");
            fsm.AddState(st_deployed);
            st_deployed_locked = new KFSMState("deployed_locked");
            fsm.AddState(st_deployed_locked);
            st_stowing = new KFSMState("stowing");
            fsm.AddState(st_stowing);

            on_deploy = new KFSMEvent("on_deploy")
            {
                GoToStateOnEvent = st_deploying
            };
            fsm.AddEvent(on_deploy, st_stowed, st_stowing);
            on_stow = new KFSMEvent("on_stow")
            {
                GoToStateOnEvent = st_stowing
            };
            fsm.AddEvent(on_stow, st_deployed, st_deploying);
            on_deployed = new KFSMEvent("on_deployed")
            {
                GoToStateOnEvent = st_deployed, updateMode = KFSMUpdateMode.UPDATE, OnCheckCondition = (st) => (deployAnimator?.animTime ?? 1) == 1
            };
            fsm.AddEvent(on_deployed, st_deploying);
            on_stowed = new KFSMEvent("on_stowed")
            {
                GoToStateOnEvent = st_stowed, updateMode = KFSMUpdateMode.UPDATE, OnCheckCondition = (st) => (deployAnimator?.animTime ?? 0) == 0
            };
            fsm.AddEvent(on_stowed, st_stowing);
            on_lock_deployed = new KFSMEvent("on_lock_deployed")
            {
                GoToStateOnEvent = st_deployed_locked, OnEvent = DisableAnimation
            };
            fsm.AddEvent(on_lock_deployed, st_deployed);
            on_unlock_deployed = new KFSMEvent("on_unlock_deployed")
            {
                GoToStateOnEvent = st_deployed, OnEvent = EnableAnimation
            };
            fsm.AddEvent(on_unlock_deployed, st_deployed_locked);
            on_lock_stowed = new KFSMEvent("on_lock_stowed")
            {
                GoToStateOnEvent = st_stowed_locked, OnEvent = DisableAnimation
            };
            fsm.AddEvent(on_lock_stowed, st_stowed);
            on_unlock_stowed = new KFSMEvent("on_unlock_stowed")
            {
                GoToStateOnEvent = st_stowed, OnEvent = EnableAnimation
            };
            fsm.AddEvent(on_unlock_stowed, st_stowed_locked);

            //fsm.OnStateChange = (fromSt, toSt, e) => UnityEngine.Debug.LogFormat("Moved from {0} to {1} by {2}", fromSt.name, toSt.name, e.name);

            CustomizeFSM();
        }