/// <summary> /// Implements the core state machine, handling common state transition logic and dispatching for specific states. /// </summary> public void OnLateUpdate() { // reset if vessel changed while enabled if (MasterSwitch.IsEnabled && ( !LastActiveVesselPersistentId.HasValue || LastActiveVesselPersistentId.Value != KspVars.ActiveVesselPersistentId ) ) { LogUtility.Log("Vessel Changed - Resetting."); Reset(); return; } LastActiveVesselPersistentId = KspVars.ActiveVesselPersistentId; // if master switch is enabled without a maneuver, // and current state is not Done and next state is not Idle // reset and don't go any further if ((MasterSwitch.IsEnabled && !KspVars.IsManeuverPlanned) && CurrentState != LogicState.Done && !(NextState.HasValue && NextState.Value == LogicState.Idle)) { LogUtility.Log("Cannot engage - No maneuver planned - Resetting."); Reset(); return; } // switch to idle state if in any other state while master switch is disabled if (CurrentState != LogicState.Idle && !MasterSwitch.IsEnabled) { NextState = LogicState.Idle; } // if transitioning state if (NextState.HasValue && NextState.Value != CurrentState) { // if going idle, do a full reset if (NextState.Value == LogicState.Idle) { LogUtility.Log("Going Idle - Resetting."); Reset(); return; } else { // otherwise, set next as current, reset the state tracking vars, and set the StateChanged flag var priorState = CurrentState; CurrentState = NextState.Value; ResetCurrentState(); StateChanged = true; LogUtility.Log($"State Changed --> {CurrentState}"); } } else { // otherwise (when not transitioning state) clear the StateChanged flag and calculate state age StateChanged = false; StateAgeUT = KspVars.CurrentUT - StateEnteredUT; } // increment late update count LateUpdateCountInState++; // handle current state switch (CurrentState) { case LogicState.Idle: ImplementState_Idle(); break; case LogicState.FarAim: ImplementState_FarAim(); break; case LogicState.FarAimStabilize: ImplementState_FarAimStabilize(); break; case LogicState.FarWarpStart: ImplementState_FarWarpStart(); break; case LogicState.FarWarpWait: ImplementState_FarWarpWait(); break; case LogicState.FarWarpRest: ImplementState_FarWarpRest(); break; case LogicState.NearAim: ImplementState_NearAim(); break; case LogicState.NearAimStabilize: ImplementState_NearAimStabilize(); break; case LogicState.NearWarpStart: ImplementState_NearWarpStart(); break; case LogicState.NearWarpWait: ImplementState_NearWarpWait(); break; case LogicState.NearWarpRest: ImplementState_NearWarpRest(); break; case LogicState.Countdown: ImplementState_Countdown(); break; case LogicState.ThrottleUp: ImplementState_ThrottleUp(); break; case LogicState.ThrottleMax: ImplementState_ThrottleMax(); break; case LogicState.ThrottleDown: ImplementState_ThrottleDown(); break; case LogicState.ThrottleZero: ImplementState_ThrottleZero(); break; case LogicState.Done: ImplementState_Done(); break; case LogicState.Staging: ImplementState_Staging(); break; case LogicState.NextManeuver: ImplementState_NextManeuver(); break; } }