예제 #1
0
        //********Idle State FixedUpdate********

        void GroundedJetpackCheck_PreFixedUpdate(KerbalEVA eva)
        {
            //If the jetpack is on, use jetpack controls while grounded.
            if (eva.JetpackDeployed)
            {
                FirstPersonEVA.instance.fpStateFloating.evtHook_PreOnFixedUpdate(eva);
            }

            DEBUG_DeltaHdg(eva, "Grounded Replacement_CorrectGroundedRotation ");
            Replacement_CorrectGroundedRotation(eva);
            DEBUG_DeltaHdg(eva, "Grounded Replacement_UpdateMovement ");
            Replacement_UpdateMovement(eva);
            DEBUG_DeltaHdg(eva, "Grounded Replacement_UpdateHeading ");
            Replacement_UpdateHeading(eva);
            DEBUG_DeltaHdg(eva, "Grounded eva_m_UpdatePackLinear ");
            ReflectedMembers.eva_m_UpdatePackLinear(eva);
            DEBUG_DeltaHdg(eva, "Grounded Replacement_UpdateRagdollVelocities ");
            Replacement_UpdateRagdollVelocities(eva);
            DEBUG_DeltaHdg(eva, "Grounded Done ");

            //If the jetpack is on, use jetpack controls while grounded.
            if (eva.JetpackDeployed)
            {
                FirstPersonEVA.instance.fpStateFloating.evtHook_PostOnFixedUpdate(eva);
            }
        }
예제 #2
0
        void ResetControlOrientation(KerbalEVA eva)
        {
            DEBUG_DeltaHdg(eva, "ResetControlOrientation ");

            //Re-run the movement input calculations from fixedupdate
            eva.fUp = FlightCamera.fetch.getReferenceFrame() * Vector3.up;
            //eva.fUp = (eva.transform.position - FlightGlobals.currentMainBody.position).normalized;
            eva.fFwd = Vector3.ProjectOnPlane(walk_start_fwd, eva.fUp).normalized;
            eva.fRgt = Vector3.Cross(eva.fUp, eva.fFwd);

            ReflectedMembers.eva_deltaHdg.SetValue(eva, 0f);
            ReflectedMembers.eva_cmdRot.SetValue(eva, Vector3.zero);
            ReflectedMembers.eva_packLinear.SetValue(eva, Vector3.zero);
            ReflectedMembers.eva_fuelFlowRate.SetValue(eva, 0f);
            ReflectedMembers.eva_tgtRpos.SetValue(eva, Vector3.zero);
            ReflectedMembers.eva_ladderTgtRPos.SetValue(eva, Vector3.zero);
            ReflectedMembers.eva_packTgtRPos.SetValue(eva, Vector3.zero);
            ReflectedMembers.eva_packRRot.SetValue(eva, Vector3.zero);

            bool rem = FlightInputHandler.SPACENAV_USE_AS_FLIGHT_CONTROL;

            FlightInputHandler.SPACENAV_USE_AS_FLIGHT_CONTROL = false;
            ReflectedMembers.eva_m_HandleMovementInput(eva);
            FlightInputHandler.SPACENAV_USE_AS_FLIGHT_CONTROL = rem;
        }
예제 #3
0
        //*********Increase bound timeout*********
        bool Replacement_On_bound_fall_OnCheckCondition(KFSMState currentstate)
        {
            if (ReflectedMembers.eva_m_SurfaceOrSplashed(myeva))
            {
                return(false);
            }

            double boundtimeout = (double)myeva.lastBoundStep;

            boundtimeout *= Mathf.Lerp(myeva.boundFallThreshold, myeva.boundFallThreshold * 5f,
                                       (myeva.minWalkingGee - (float)myeva.vessel.mainBody.GeeASL) / myeva.minWalkingGee);

            //KSPLog.print ("Bound fall? " + myeva.fsm.TimeAtCurrentState.ToString() + " / " + boundtimeout.ToString());
            return(myeva.fsm.TimeAtCurrentState > boundtimeout);
        }
예제 #4
0
        public void resetCamera(Vessel previousVessel)
        {
            ReflectedMembers.Initialize();

            GameObject.Destroy(fpgui);

            if (!isFirstPerson)
            {
                return;
            }

            Vessel       pVessel   = FlightGlobals.ActiveVessel;
            FlightCamera flightCam = FlightCamera.fetch;

            cameraState.recallState(flightCam);

            if (FlightGlobals.ActiveVessel != null)
            {
                flightCam.SetTargetTransform(pVessel.transform);
            }
            flightCam.ActivateUpdate();

            isFirstPerson = false;

            EnableRenderingOnPrevious(previousVessel);

            //Exit first person

            if (OnExitFirstPerson != null)
            {
                OnExitFirstPerson(currentfpeva);
            }
            currentfpeva = null;

            //Restore stuff that changed in the evacontroller
            if (previousVessel != null && previousVessel.evaController != null)
            {
                //Axis control settings
                ReflectedMembers.eva_manualAxisControl.SetValue(previousVessel.evaController, false);
                ReflectedMembers.eva_cmdRot.SetValue(previousVessel.evaController, Vector3.zero);

                //Pack power (from fine controls)
                previousVessel.evaController.rotPower = 1f;
                previousVessel.evaController.linPower = 0.3f;
            }

            KeyDisabler.instance.restoreAllKeys(KeyDisabler.eDisableLockSource.FirstPersonEVA);
        }
예제 #5
0
        EVABoundFix(KerbalEVA eva)
        {
            myeva = eva;

            ReflectedMembers.Initialize();

            //*********Increase bound timeout*********
            myeva.On_bound_fall.OnCheckCondition = Replacement_On_bound_fall_OnCheckCondition;

            //*********Fix for "cannot land" on steep surfaces*********
            myeva.On_bound_land.OnCheckCondition = Replacement_On_bound_land_OnCheckCondition;

            //See if we are hooked yet.
            bool found_packtoggle_bound = false;

            for (int i = 0; i < myeva.st_bound_fl.StateEvents.Count; ++i)
            {
                if (myeva.st_bound_fl.StateEvents [i].name == "Pack Toggle (Bound)")
                {
                    found_packtoggle_bound = true;
                    break;
                }
            }

            if (!found_packtoggle_bound)
            {
                //KSPLog.print ("Bound Pack Toggle not found, adding.");

                //*********Bound floating RCS toggle*********
                evt_packtoggle_bound                  = new KFSMEvent("Pack Toggle (Bound)");
                evt_packtoggle_bound.updateMode       = KFSMUpdateMode.UPDATE;
                evt_packtoggle_bound.GoToStateOnEvent = myeva.st_idle_fl;
                evt_packtoggle_bound.OnCheckCondition = Check_Bound_Jetpack;
                evt_packtoggle_bound.OnEvent          = Do_Toggle_Jetpack;
                myeva.fsm.AddEvent(evt_packtoggle_bound, myeva.st_bound_fl);

                //*********Ability to break out of long bound*********
                evt_long_bound_breakout                  = new KFSMEvent("Long Bound Breakout");
                evt_long_bound_breakout.updateMode       = KFSMUpdateMode.UPDATE;
                evt_long_bound_breakout.GoToStateOnEvent = myeva.st_idle_fl;
                evt_long_bound_breakout.OnCheckCondition = Check_Bound_Breakout;
                myeva.fsm.AddEvent(evt_long_bound_breakout, myeva.st_bound_fl);
            }
        }
예제 #6
0
        public void evtHook_PostOnFixedUpdate(KerbalEVA eva)
        {
            ReflectedMembers.Initialize();

            //Recalculate fuel flow: proportional to power factor
            //Default power factors: rot 1, lin 0.3
            if (eva.JetpackDeployed)
            {
                float newflowrate = 0f;

                Vector3 cmdrot     = (Vector3)ReflectedMembers.eva_cmdRot.GetValue(eva);
                Vector3 packlinear = (Vector3)ReflectedMembers.eva_packLinear.GetValue(eva);

                newflowrate += cmdrot.magnitude * Time.fixedDeltaTime * eva.rotPower / 1f;
                newflowrate += packlinear.magnitude * Time.fixedDeltaTime * eva.linPower / 0.3f;

                //KSPLog.print ("Flow rates: " + ((float)ReflectedMembers.eva_fuelFlowRate.GetValue(eva)).ToString() + " -> " + newflowrate.ToString());
                ReflectedMembers.eva_fuelFlowRate.SetValue(eva, newflowrate);
            }
        }
예제 #7
0
        public void evtHook_PreOnFixedUpdate(KerbalEVA eva)
        {
            ReflectedMembers.Initialize();

            if ((FlightGlobals.ActiveVessel.situation != Vessel.Situations.SPLASHED
                 //&& FlightGlobals.ActiveVessel.situation != Vessel.Situations.LANDED //Allow landed jetpack operation
                 ) &&
                FlightGlobals.ActiveVessel.evaController.JetpackDeployed)
            {
                //************Rotation************
                Quaternion manualRotation          = Quaternion.identity;
                Vector3    commandedManualRotation = Vector3.zero;
                if (GameSettings.YAW_LEFT.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)(-(double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.up);
                    commandedManualRotation -= eva.transform.up;
                    //KSPLog.print ("YAW LEFT");
                }
                else if (GameSettings.YAW_RIGHT.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)((double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.up);
                    commandedManualRotation += eva.transform.up;
                    //KSPLog.print ("YAW RIGHT");
                }

                if (GameSettings.PITCH_UP.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)(-(double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.right);
                    commandedManualRotation -= eva.transform.right;
                    //KSPLog.print ("PITCH UP");
                }
                else if (GameSettings.PITCH_DOWN.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)((double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.right);
                    commandedManualRotation += eva.transform.right;
                    //KSPLog.print ("PITCH DOWN");
                }

                if (GameSettings.ROLL_RIGHT.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)(-(double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.forward);
                    commandedManualRotation -= eva.transform.forward;
                    //KSPLog.print ("ROLL RIGHT");
                }
                else if (GameSettings.ROLL_LEFT.GetKey(false))
                {
                    manualRotation           = manualRotation * Quaternion.AngleAxis((float)((double)FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.forward);
                    commandedManualRotation += eva.transform.forward;
                    //KSPLog.print ("ROLL LEFT");
                }

                //Testing
                Vector3 kp = new Vector3(3.0f, 3.0f, 3.0f);
                Vector3 ki = new Vector3(0.25f, 0.25f, 0.25f);
                Vector3 kd = new Vector3(0.001f, 0.001f, 0.001f);

                //Reduce pid response in physical time acceleration.
                if (TimeWarp.WarpMode == TimeWarp.Modes.LOW)
                {
                    float warprate = TimeWarp.fetch.physicsWarpRates [TimeWarp.fetch.current_rate_index];
                    if (warprate > 1f)
                    {
                        kp = kp / warprate;
                    }
                }

                ReflectedMembers.eva_manualAxisControl.SetValue(eva, true);
                if (manualRotation == Quaternion.identity)
                {
                    //No rotation controls active. SAS active, maybe.

                    //Set manual mode based on SAS mode.
                    if (GameSettings.EVA_ROTATE_ON_MOVE && FlightGlobals.ActiveVessel.situation != Vessel.Situations.LANDED)
                    {
                        //Run PID.
                        Vector3 angularvelocity = eva.part.Rigidbody.angularVelocity;
                        Vector3 currenterror    = -Helpers.ClampVectorComponents(angularvelocity, -0.5f, 0.5f);
                        imgr.state.rotationpid_integral = Helpers.ClampVectorComponents(imgr.state.rotationpid_integral + currenterror * Time.fixedDeltaTime, -1f, 1f);
                        Vector3 derivative = (currenterror - imgr.state.rotationpid_previouserror) / Time.fixedDeltaTime;
                        Vector3 pidresult  = Helpers.PairwiseMultiplyVectors(kp, currenterror)
                                             + Helpers.PairwiseMultiplyVectors(ki, imgr.state.rotationpid_integral)
                                             + Helpers.PairwiseMultiplyVectors(kd, derivative);

                        //KSPLog.print ("currenterror: " + currenterror.ToString ());
                        //KSPLog.print ("rotationpid_integral: " + imgr.state.rotationpid_integral.ToString ());
                        //KSPLog.print ("derivative: " + derivative.ToString ());

                        imgr.state.rotationpid_previouserror = currenterror;

                        //Assign command
                        ReflectedMembers.eva_cmdRot.SetValue(eva, pidresult);
                        //KSPLog.print ("SAS on, no command, PID result: " + pidresult.ToString () + ", actual velocity: " + angularvelocity.ToString ());
                    }
                    else
                    {
                        //KSPLog.print ("SAS off, no command");

                        //This is so when landed the PID is reset.
                        imgr.state.rotationpid_integral      = Vector3.zero;
                        imgr.state.rotationpid_previouserror = Vector3.zero;

                        //Idle and SAS off. Do nothing.
                        ReflectedMembers.eva_cmdRot.SetValue(eva, Vector3.zero);
                    }
                }
                else
                {
                    //Rotation controls active.

                    //Reset PID
                    imgr.state.rotationpid_integral      = Vector3.zero;
                    imgr.state.rotationpid_previouserror = Vector3.zero;

                    ReflectedMembers.eva_cmdRot.SetValue(eva, commandedManualRotation);

                    //KSPLog.print ("Manual command");
                }

                //************Translation************
                Vector3 manualTranslation = Vector3.zero;
                if (GameSettings.TRANSLATE_LEFT.GetKey(false))
                {
                    manualTranslation += Vector3.left;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) (-(double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.up);
                    //KSPLog.print ("TRANSLATE LEFT");
                }
                else if (GameSettings.TRANSLATE_RIGHT.GetKey(false))
                {
                    manualTranslation += Vector3.right;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) ((double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.up);
                    //KSPLog.print ("TRANSLATE RIGHT");
                }

                if (GameSettings.TRANSLATE_UP.GetKey(false))
                {
                    manualTranslation += Vector3.up;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) (-(double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.right);
                    //KSPLog.print ("TRANSLATE UP");
                }
                else if (GameSettings.TRANSLATE_DOWN.GetKey(false))
                {
                    manualTranslation += Vector3.down;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) ((double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.right);
                    //KSPLog.print ("TRANSLATE DOWN");
                }

                if (GameSettings.TRANSLATE_FWD.GetKey(false))
                {
                    manualTranslation += Vector3.forward;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) (-(double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.forward);
                    //KSPLog.print ("TRANSLATE RIGHT");
                }
                else if (GameSettings.TRANSLATE_BACK.GetKey(false))
                {
                    manualTranslation += Vector3.back;
                    //manualRotation = manualRotation * Quaternion.AngleAxis((float) ((double) FlightGlobals.ActiveVessel.evaController.turnRate * Mathf.Rad2Deg) * Time.deltaTime, FlightGlobals.ActiveVessel.evaController.transform.forward);
                    //KSPLog.print ("TRANSLATE LEFT");
                }

                manualTranslation.Normalize();
                manualTranslation = FlightGlobals.ActiveVessel.transform.rotation * manualTranslation;

                //KSPLog.print ("Resetting rpos. Old value: " + ((Vector3)ReflectedMembers.eva_packTgtRPos.GetValue (FlightGlobals.ActiveVessel.evaController)).ToString ()
                //+ ", new value: " + manualTranslation.ToString ());
                ReflectedMembers.eva_packTgtRPos.SetValue(FlightGlobals.ActiveVessel.evaController, manualTranslation);

                //************Set power**************
                eva.rotPower = 1f * imgr.state.eva_throttle;
                eva.linPower = 0.3f * imgr.state.eva_throttle;
            }
        }
예제 #8
0
 void Do_Toggle_Jetpack()
 {
     ReflectedMembers.eva_m_ToggleJetpackBool(myeva, !myeva.JetpackDeployed);
 }
예제 #9
0
        public void Hook(KerbalEVA peva)
        {
            if (ishooked)
            {
                throw new Exception("HookedKerbalFSMState already hooked.");
            }
            ishooked = true;
            eva      = peva;

            ReflectedMembers.Initialize();

            //******************************************
            //Add the original events back to our state.
            for (int i = 0; i < originalstate.StateEvents.Count; ++i)
            {
                AddEvent(originalstate.StateEvents [i]);
            }

            //*******************************************
            //Replace references to our state in the FSM.
            List <KFSMState> States;
            KFSMState        currentState;
            KFSMState        lastState;

            States       = (List <KFSMState>)ReflectedMembers.fsm_states.GetValue(eva.fsm);
            currentState = (KFSMState)ReflectedMembers.fsm_currentstate.GetValue(eva.fsm);
            lastState    = (KFSMState)ReflectedMembers.fsm_laststate.GetValue(eva.fsm);

            for (int i = 0; i < States.Count; ++i)
            {
                if (States [i] == originalstate)
                {
                    States [i] = this;
                    break;
                }
            }
            if (currentState == originalstate)
            {
                ReflectedMembers.fsm_currentstate.SetValue(eva.fsm, this);
            }
            if (lastState == originalstate)
            {
                ReflectedMembers.fsm_laststate.SetValue(eva.fsm, this);
            }

            //*******************************************
            //Replace references to our state in the EVA.
            for (int i = 0; i < ReflectedMembers.eva_type_kfsmstate.Count; ++i)
            {
                System.Reflection.FieldInfo f = ReflectedMembers.eva_type_kfsmstate [i];
                KFSMState refval = f.GetValue(eva) as KFSMState;
                if (refval == null)
                {
                    continue;
                }
                if (refval == originalstate)
                {
                    f.SetValue(eva, this);
                }
            }

            //******************************************
            //Replace references to our state in events.
            for (int i = 0; i < States.Count; ++i)
            {
                List <KFSMEvent> thisstateevents = States [i].StateEvents;
                for (int j = 0; j < thisstateevents.Count; ++j)
                {
                    KFSMEvent thisevent = thisstateevents [j];

                    if (thisevent.GoToStateOnEvent == originalstate)
                    {
                        thisevent.GoToStateOnEvent = this;
                    }
                }
            }
        }
예제 #10
0
 void Replacement_UpdateRagdollVelocities(KerbalEVA eva)
 {
     DEBUG_DeltaHdg(eva, "Replacement_UpdateRagdollVelocities ");
     ReflectedMembers.eva_m_updateRagdollVelocities(eva);
 }
예제 #11
0
        void Replacement_UpdateMovement(KerbalEVA eva)
        {
            DEBUG_DeltaHdg(eva, "Replacement_UpdateMovement ");

            ReflectedMembers.eva_m_UpdateMovement(eva);
        }
예제 #12
0
        void Replacement_CorrectGroundedRotation(KerbalEVA eva)
        {
            DEBUG_DeltaHdg(eva, "Replacement_CorrectGroundedRotation ");

            ReflectedMembers.eva_m_correctGroundedRotation(eva);
        }
예제 #13
0
        void evt_OnEnterFirstPerson(KerbalEVA eva)
        {
            //Hook it!
            ReflectedMembers.Initialize();

            //*********************
            //***Walk/Run States***
            if (!(eva.st_walk_acd is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_walk_acd, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_walk_fps is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_walk_fps, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_run_acd is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_run_acd, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_run_fps is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_run_fps, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_bound_gr_acd is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_bound_gr_acd, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_bound_gr_fps is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_bound_gr_fps, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }
            if (!(eva.st_bound_fl is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_bound_fl, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }

            //*********************
            //***Turn to Heading***
            if (!(eva.st_heading_acquire is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_heading_acquire, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.PreOnFixedUpdate      += ApplyModifiedDeltaHeading;
                st.Override_OnFixedUpdate = true;
            }

            //*******************
            //***Idle Grounded***
            if (!(eva.st_idle_gr is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_idle_gr, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter       += ResetJetpackManualControls;
                st.PreOnFixedUpdate += ForceArcadeMode;
                st.PreOnFixedUpdate += ResetTurningBasisVector;
                st.PreOnFixedUpdate += ApplyNoForwardTarget;
                st.PreOnFixedUpdate += GroundedJetpackCheck_PreFixedUpdate;

                st.Override_OnFixedUpdate = true;
            }

            //*************
            //***Jumping***
            if (!(eva.st_jump is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_jump, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnUpdate      += Replacement_UpdateMovement;
                st.PreOnUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate += Replacement_UpdateRagdollVelocities;

                st.Override_OnUpdate      = true;
                st.Override_OnFixedUpdate = true;
            }

            //**************
            //***Swimming***
            if (!(eva.st_swim_fwd is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_swim_fwd, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetControlOrientation;
                st.PreOnFixedUpdate      += ApplyKerbalForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.Override_OnFixedUpdate = true;
            }

            if (!(eva.st_swim_idle is HookedKerbalFSMState))
            {
                HookedKerbalFSMState st = new HookedKerbalFSMState(eva.st_swim_idle, IsThisEVAIVA);
                st.Hook(eva);
                st.PreOnEnter            += ResetJetpackManualControls;
                st.PreOnFixedUpdate      += ForceArcadeMode;
                st.PreOnFixedUpdate      += ResetTurningBasisVector;
                st.PreOnFixedUpdate      += ApplyNoForwardTarget;
                st.PreOnFixedUpdate      += Replacement_CorrectGroundedRotation;
                st.PreOnFixedUpdate      += Replacement_UpdateMovement;
                st.PreOnFixedUpdate      += Replacement_UpdateHeading;
                st.PreOnFixedUpdate      += Replacement_UpdateRagdollVelocities;
                st.Override_OnFixedUpdate = true;
            }

            walk_start_fwd = eva.transform.forward;
            //directionkeypresscount = 0;
            //h_integral = 0f;
            //h_previouserror = 0f;
        }