Example #1
0
 public void Update()
 {
     if (GameSettings.MODIFIER_KEY.GetKey() && GameSettings.SAS_TOGGLE.GetKeyDown())
     {
         bArmed = !bArmed;
     }
     if (bArmed)
     {
         if (GameSettings.SAS_TOGGLE.GetKeyDown())
         {
             ActivitySwitch(!ActivityCheck());
         }
         if (GameSettings.SAS_HOLD.GetKey())
         {
             updateTarget();
         }
     }
     if (vesModule.vesselRef.Autopilot != null)
     {
         if (currentMode != vesModule.vesselRef.Autopilot.Mode && currentMode == VesselAutopilot.AutopilotMode.StabilityAssist)
         {
             updateTarget();
         }
         if (referenceMode == FlightUIController.SpeedDisplayModes.Surface && FlightUIController.speedDisplayMode != FlightUIController.SpeedDisplayModes.Surface)
         {
             orbitalTarget = vesModule.vesselRef.transform.rotation;
         }
         currentMode   = vesModule.vesselRef.Autopilot.Mode;
         referenceMode = FlightUIController.speedDisplayMode;
     }
     if (bActive[(int)SASList.Hdg])
     {
         SASList.Hdg.GetSAS(this).SetPoint = Utils.calculateTargetHeading(currentTarget, vesModule);
     }
 }
 /// <summary>
 /// Common function for setting the autopilot mode
 /// </summary>
 /// <param name="mode"></param>
 private void ButtonSASModeClick(VesselAutopilot.AutopilotMode mode)
 {
     if (vessel != null)
     {
         vessel.Autopilot.SetActualMode(mode);
     }
 }
Example #3
0
        public void FixedUpdate()
        {
            if (IsEnabled == false)
            {
                return;
            }

            if (vessel == null)
            {
                return;
            }

            if (countdown > 0 && ratioHeadingVersusRequest > 0.999)
            {
                countdown--;

                if (persistentAutopilotMode != vessel.Autopilot.Mode)
                {
                    vessel.Autopilot.SetMode(persistentAutopilotMode);
                    return;
                }
                else
                {
                    ratioHeadingVersusRequest = vessel.PersistHeading(true);
                }
            }

            // persist heading and drop out of warp when previously was maintaining heading
            ratioHeadingVersusRequest = vessel.PersistHeading(false, ratioHeadingVersusRequest == 1);
            persistentAutopilotMode   = vessel.Autopilot.Mode;
        }
 /// <summary>
 /// Force the SAS mode buttons on the flight view to update when we
 /// update modes under the hood.  Code from
 /// http://forum.kerbalspaceprogram.com/threads/105074-Updating-the-auto-pilot-UI?p=1633958&viewfull=1#post1633958
 /// </summary>
 /// <param name="newMode">The new autopilot mode</param>
 private void ForceUpdateSASModeToggleButtons(VesselAutopilot.AutopilotMode newMode)
 {
     // find the UI object on screen
     RUIToggleButton[] SASbtns = UnityEngine.Object.FindObjectOfType <VesselAutopilotUI>().modeButtons;
     // set our mode, note it takes the mode as an int, generally top to bottom, left to right, as seen on the screen. Maneuver node being the exception, it is 9
     SASbtns.ElementAt <RUIToggleButton>((int)newMode).SetTrue(true, true);
 }
        public void autopilotModeCallback(byte ID, object Data)
        {
            byte[] payload = (byte[])Data;

            VesselAutopilot autopilot = FlightGlobals.ActiveVessel.Autopilot;

            if (autopilot == null)
            {
                Debug.Log("KerbalSimpit : Ignoring a SAS MODE Message since I could not find the autopilot");
                return;
            }

            mySASMode = (VesselAutopilot.AutopilotMode)(payload[0]);

            if (autopilot.CanSetMode(mySASMode))
            {
                autopilot.SetMode(mySASMode);
                if (KSPit.Config.Verbose)
                {
                    Debug.Log(String.Format("KerbalSimpit: payload is {0}", mySASMode));
                    Debug.Log(String.Format("KerbalSimpit: SAS mode is {0}", FlightGlobals.ActiveVessel.Autopilot.Mode.ToString()));
                }
            }
            else
            {
                Debug.Log(String.Format("KerbalSimpit: Unable to set SAS mode to {0}", mySASMode.ToString()));
            }
        }
        public void FixedUpdate()
        {
            if (HighLogic.LoadedSceneIsEditor)
            {
                return;
            }

            if (_reactionWheel == null)
            {
                return;
            }

            // save or restore AutopilotMode
            if (_fixedUpdateCount++ > 100)
            {
                persistentAutopilotMode = vessel.Autopilot.Mode;
            }
            else
            {
                vessel.Autopilot.SetMode(persistentAutopilotMode);
            }

            // detect if vessel is heading
            headingSpinDelta     = (previousPartHeading - part.transform.up).magnitude / TimeWarp.deltaTime;
            rotationSpinDelta    = (previousPartRotation - part.transform.rotation.eulerAngles).magnitude / TimeWarp.deltaTime;
            previousPartRotation = part.transform.rotation.eulerAngles;
            previousPartHeading  = part.transform.up;

            var isStabilized = false;

            if (isAutoStabilizing)
            {
                isStabilized = StabilizeWhenPossible(0.0005f, 1, 1, 1);
            }

            var torqueRatio = GetTorqueRatio(isStabilized);

            _torqueRatioQueue.Enqueue(torqueRatio);
            if (_torqueRatioQueue.Count > 4)
            {
                _torqueRatioQueue.Dequeue();
            }

            maxPowerCostMj = maxPowerCost / GameConstants.ecPerMJ;
            var requiredPower  = torqueRatio * maxPowerCostMj;
            var requestedPower = Math.Max(1e-8, _torqueRatioQueue.Max() * maxPowerCostMj - _bufferOvercapacity);
            var receivedPower  = ConsumeMegawatts(requestedPower, true, true, true);

            _bufferPower        = Math.Max(0, _bufferPower + receivedPower - requiredPower);
            _bufferOvercapacity = Math.Min(maxBufferCapacity, Math.Max(0, _bufferPower - maxBufferCapacity));
            _bufferPower        = Math.Min(_bufferPower, maxBufferCapacity);

            powerFactor = requiredPower > 0 ? Math.Min(1, (receivedPower + _bufferPower) / requiredPower) : 1;

            UpdateReactionWheelTorque();
        }
 private static bool setAutopilotMode(VesselAutopilot.AutopilotMode mode)
 {
     //Debug.Log("setAutopilotMode, mode: " + mode);
     if (FlightGlobals.ActiveVessel.Autopilot.CanSetMode(mode))
     {
         FlightGlobals.ActiveVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
         FlightGlobals.ActiveVessel.Autopilot.Update();
         FlightGlobals.ActiveVessel.Autopilot.SetMode(mode);
         return(true);
     }
     return(false);
 }
 private static VesselAutopilot.AutopilotMode ConvertMode(VesselAutopilot.AutopilotMode mode)
 {
     if (mode == VesselAutopilot.AutopilotMode.RadialIn)
     {
         mode = VesselAutopilot.AutopilotMode.RadialOut;
     }
     else if (mode == VesselAutopilot.AutopilotMode.RadialOut)
     {
         mode = VesselAutopilot.AutopilotMode.RadialIn;
     }
     return(mode);
 }
Example #9
0
        private static bool Prefix(VesselAutopilot.AutopilotMode mode, Vessel vessel, ref bool __result)
        {
            __result = vessel.VesselValues.AutopilotSkill.value >= mode.GetRequiredSkill();
            return(false);

            // Okay seriously, that looks waaaaay simpler than it actually is, so verbose pseudocode + documentation is in order here!

            /*
             *  if (requirePilotForSAS)
             *  {
             *      // Despite not tracking kerbal experience (i.e. all crew always at Lvl 5) we can make specializations more meaningful
             *      // Require Pilot (ExperienceEffect.AutopilotSkill) for crewed, ModuleSAS for uncrewed
             *      // Basically, stock default career behavior, except that all pilots are always Lvl 5.
             *      // This is the expression you see above
             *      __result = vessel.VesselValues.AutopilotSkill.value >= mode.GetRequiredSkill();
             *  }
             *  else
             *  {
             *      // Allow any crewmember to provide full SAS, but require ModuleSAS for uncrewed
             *      // The stock default sandbox behavior is buggy and brittle, so we have to implement a better version of it
             *      // Something like:
             *      __result = hasAnyCrewAutopilot(vessel) || hasProbeAutopilot(mode, vessel);
             *
             *      // Checking probes is easy:
             *      bool hasProbeAutopilot(mode, vessel) {
             *          return vessel.VesselValues.AutopilotSASSkill.value >= mode.GetRequiredSkill();
             *      }
             *
             *      // Checking crew is the part that needs fixing:
             *      // Stock default sandbox behavior ( EnableKerbalExperience FALSE, EnableFullSASInSandbox FALSE ) purports to give all crew full SAS
             *      // But testing shows that it seems to actually check for ExperienceEffect.{ AutopilotSkill, RepairSkill, ScienceSkill } in lieu of { Pilot, Engineer, Scientist } respectively
             *      // This means that other specializations (from mods) will not qualify if they don't have one of these three skills!
             *
             *      // One way to fix it would be to check for any onboard ProtoCrewMember of pcm.type == KerbalType.Crew rather than KerbalType.Tourist
             *      // However, that approach would break expected behavior for other mods that involve disabling kerbal skills, e.g.
             *      //  - mods that modify pcm.trait to Tourist (without changing pcm.type)
             *      //  - Kerbal Status Effects
             *
             *      // Instead, we implement our own skill SandboxAutopilotSkill : ExperienceEffect
             *      // and grant it to all non-tourist/civilian specializations (EXPERIENCE_TRAIT)s
             *
             *      // Then, naively, the first thought would be to implement hasAnyCrewAutopilot(vessel) check in one of two ways:
             *      //  - iterate through all command module occupants looking for pcm.HasEffect<SandboxAutopilotSkill>() (potentially costly) or
             *      //  - build infrastructure similar to PartValues / VesselValues specifically for the SandboxAutopilotSkill skill
             *
             *      // Or, we could be smart about it, and have SandboxAutopilotSkill perform OnRegister(part)/OnUnregister(part) selectively
             *      // i.e. only when the necessary combination of game mode and GameParameters is satisfied
             *      // Registration of the skill to a part adds it to the already existent part.PartValues.AutopilotSkill
             *      // This little trick allows us to arrive at the same expression used for the (requirePilotForSAS == true) case!
             * }
             */
        }
Example #10
0
 private static bool setAutopilotMode(VesselAutopilot.AutopilotMode mode, int ui_button)
 {
     if (FlightGlobals.ActiveVessel.Autopilot.CanSetMode(mode))
     {
         FlightGlobals.ActiveVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
         FlightGlobals.ActiveVessel.Autopilot.Update();
         FlightGlobals.ActiveVessel.Autopilot.SetMode(mode);
         setSASUI(ui_button);
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #11
0
        // ReSharper disable once InconsistentNaming
        private void SetSAS(VesselAutopilot.AutopilotMode mode)
        {
            if (!vessel.Autopilot.SAS.CanEngageSAS())
            {
                ScreenMessages.PostScreenMessage(message: "Vessel cannot engage SAS");
                return;
            }

            if (!vessel.Autopilot.CanSetMode(mode: mode))
            {
                ScreenMessages.PostScreenMessage(message: $"Vessel cannot set SAS to {mode}");
                return;
            }


            vessel.ActionGroups.SetGroup(@group: KSPActionGroup.SAS, active: true); // turn on SAS
            vessel.Autopilot.Enable(mode: mode);                                    // set SAS mode
        }
        public static bool SetActualMode(this VesselAutopilot autopilot, VesselAutopilot.AutopilotMode mode)
        {
            mode = ConvertMode(mode);

            if (autopilot.CanSetMode(mode))
            {
                var result = autopilot.SetMode(mode);

                var autopilotUI = GameObject.FindObjectOfType <VesselAutopilotUI>();
                if (autopilotUI != null && mode >= 0 && (int)mode < autopilotUI.modeButtons.Length)
                {
                    autopilotUI.modeButtons[(int)mode].SetState(true);
                }

                return(result);
            }

            return(false);
        }
Example #13
0
 public void Update()
 {
     if (GameSettings.MODIFIER_KEY.GetKey() && GameSettings.SAS_TOGGLE.GetKeyDown())
     {
         bArmed = !bArmed;
     }
     if (bArmed)
     {
         pauseManager();
         if (GameSettings.SAS_TOGGLE.GetKeyDown())
         {
             ActivitySwitch(!ActivityCheck());
         }
         if (GameSettings.SAS_HOLD.GetKey())
         {
             updateTarget();
         }
     }
     if (ves.Autopilot != null)
     {
         if (APMode != ves.Autopilot.Mode && APMode == VesselAutopilot.AutopilotMode.StabilityAssist)
         {
             updateTarget();
         }
         if (spdMode != FlightUIController.speedDisplayMode)
         {
             if (spdMode == FlightUIController.SpeedDisplayModes.Surface)
             {
             }
             else
             {
                 orbitalTarget = ves.transform.rotation;
             }
         }
         APMode  = ves.Autopilot.Mode;
         spdMode = FlightUIController.speedDisplayMode;
     }
     if (bActive[(int)SASList.Hdg])
     {
         GetSAS(SASList.Hdg).SetPoint = calculateTargetHeading(currentTarget, ves);
     }
 }
Example #14
0
        public void autopilotModeCallback(byte ID, object Data)
        {
            byte[] payload = (byte[])Data;
            mySASMode      = (VesselAutopilot.AutopilotMode)(payload[0]);
            myActiveVessel = FlightGlobals.ActiveVessel;

            if (myActiveVessel.Autopilot.CanSetMode(mySASMode))
            {
                myActiveVessel.Autopilot.SetMode((VesselAutopilot.AutopilotMode)mySASMode);
                if (KSPit.Config.Verbose)
                {
                    Debug.Log(String.Format("KerbalSimpit: payload is {0}", mySASMode));
                    Debug.Log(String.Format("KerbalSimpit: SAS mode is {0}", myActiveVessel.Autopilot.Mode.ToString()));
                }
            }
            else
            {
                Debug.Log(String.Format("KerbalSimpit: Unable to set SAS mode to {0}", mySASMode.ToString()));
            }
        }
Example #15
0
 public void SelectAutopilotMode(VesselAutopilot.AutopilotMode autopilotMode)
 {
     if (currentVessel.Autopilot.Mode != autopilotMode)
     {
         if (!currentVessel.Autopilot.CanSetMode(autopilotMode))
         {
             // throw an exception if the mode is not available
             throw new Safe.Exceptions.KOSException(
                       string.Format("Cannot set autopilot value, pilot/probe does not support {0}, or there is no node/target", autopilotMode));
         }
         currentVessel.Autopilot.SetMode(autopilotMode);
         //currentVessel.Autopilot.Enable();
         // change the autopilot indicator
         ((Module.kOSProcessor)Shared.Processor).SetAutopilotMode((int)autopilotMode);
         if (RemoteTechHook.IsAvailable(currentVessel.id))
         {
             Debug.Log(string.Format("kOS: Adding RemoteTechPilot: autopilot For : " + currentVessel.id));
             // TODO: figure out how to make RemoteTech allow the built in autopilot control.  This may require modification to RemoteTech itself.
         }
     }
 }
Example #16
0
        public static AutoPilotModeEnum ToPTIEnum(this VesselAutopilot.AutopilotMode mode)
        {
            switch (mode)
            {
            case VesselAutopilot.AutopilotMode.StabilityAssist:
                return(AutoPilotModeEnum.StabilityAssist);

            case VesselAutopilot.AutopilotMode.Prograde:
                return(AutoPilotModeEnum.Prograde);

            case VesselAutopilot.AutopilotMode.Retrograde:
                return(AutoPilotModeEnum.Retrograde);

            case VesselAutopilot.AutopilotMode.Normal:
                return(AutoPilotModeEnum.Normal);

            case VesselAutopilot.AutopilotMode.Antinormal:
                return(AutoPilotModeEnum.Antinormal);

            case VesselAutopilot.AutopilotMode.RadialIn:
                return(AutoPilotModeEnum.RadialIn);

            case VesselAutopilot.AutopilotMode.RadialOut:
                return(AutoPilotModeEnum.RadialOut);

            case VesselAutopilot.AutopilotMode.Target:
                return(AutoPilotModeEnum.Target);

            case VesselAutopilot.AutopilotMode.AntiTarget:
                return(AutoPilotModeEnum.AntiTarget);

            case VesselAutopilot.AutopilotMode.Maneuver:
                return(AutoPilotModeEnum.Maneuver);

            default:
                return(AutoPilotModeEnum.StabilityAssist);
            }
        }
Example #17
0
        public static KRPC.SpaceCenter.Services.SASMode ToSASMode(this VesselAutopilot.AutopilotMode mode)
        {
            switch (mode)
            {
            case VesselAutopilot.AutopilotMode.StabilityAssist:
                return(KRPC.SpaceCenter.Services.SASMode.StabilityAssist);

            case VesselAutopilot.AutopilotMode.Maneuver:
                return(KRPC.SpaceCenter.Services.SASMode.Maneuver);

            case VesselAutopilot.AutopilotMode.Prograde:
                return(KRPC.SpaceCenter.Services.SASMode.Prograde);

            case VesselAutopilot.AutopilotMode.Retrograde:
                return(KRPC.SpaceCenter.Services.SASMode.Retrograde);

            case VesselAutopilot.AutopilotMode.Normal:
                return(KRPC.SpaceCenter.Services.SASMode.Normal);

            case VesselAutopilot.AutopilotMode.Antinormal:
                return(KRPC.SpaceCenter.Services.SASMode.AntiNormal);

            case VesselAutopilot.AutopilotMode.RadialIn:
                return(KRPC.SpaceCenter.Services.SASMode.Radial);

            case VesselAutopilot.AutopilotMode.RadialOut:
                return(KRPC.SpaceCenter.Services.SASMode.AntiRadial);

            case VesselAutopilot.AutopilotMode.Target:
                return(KRPC.SpaceCenter.Services.SASMode.Target);

            case VesselAutopilot.AutopilotMode.AntiTarget:
                return(KRPC.SpaceCenter.Services.SASMode.AntiTarget);

            default:
                throw new ArgumentOutOfRangeException("mode");
            }
        }
Example #18
0
        IEnumerator startSAS(VesselAutopilot.AutopilotMode autoPilot)
        {
            if (TimeWarp.CurrentRate > 1 && TimeWarp.WarpMode == TimeWarp.Modes.HIGH)
            {
                TimeWarp.fetch.CancelAutoWarp();
                TimeWarp.SetRate(0, false);
            }
            while (TimeWarp.CurrentRate > 1 && TimeWarp.WarpMode == TimeWarp.Modes.HIGH)
            {
                yield return(0);
            }
            yield return(new WaitForFixedUpdate());

            Vessel _vessel = FlightGlobals.ActiveVessel;

            if (!_vessel.Autopilot.SAS.dampingMode)
            {
                _vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true);
            }
            yield return(new WaitForFixedUpdate());

            _vessel.Autopilot.SetMode(autoPilot);
        }
        //protected override void OnLoad(ConfigNode node)
        //{
        //    base.OnLoad(node);
        //}

        //protected override void OnSave(ConfigNode node)
        //{
        //    base.OnSave(node);
        //}

        ////When the scene changes and the mod is destroyed
        //public void OnDestroy()
        //{
        //    //If we're in the MainMenu, don't do anything
        //    if (forbiddenScenes.Contains(HighLogic.LoadedScene))
        //        return;
        //}

        //public override void OnLoadVessel()
        //{
        //    base.OnLoadVessel();
        //}

        //public override void OnUnloadVessel()
        //{
        //    base.OnUnloadVessel();
        //}

        //public override void OnGoOnRails()
        //{
        //    base.OnGoOnRails();
        //}

        //public override void OnGoOffRails()
        //{
        //    base.OnGoOffRails();
        //}

        //public override bool ShouldBeActive()
        //{
        //    return base.ShouldBeActive();
        //}

        /// <summary>
        /// Is called on every frame
        /// </summary>
        public void FixedUpdate()
        {
            // ignore Kerbals
            if (vessel.isEVA)
            {
                return;
            }

            // ignore irrelevant vessel types
            if (vessel.vesselType == VesselType.Debris ||
                vessel.vesselType == VesselType.Flag ||
                vessel.vesselType == VesselType.SpaceObject ||
                vessel.vesselType == VesselType.DeployedSciencePart ||
                vessel.vesselType == VesselType.DeployedScienceController
                )
            {
                return;
            }

            // lookup vessel data
            PersistentScenarioModule.VesselDataDict.TryGetValue(vessel.id, out VesselData vesselData);

            if (vesselData == null)
            {
                return;
            }

            if (vessel.loaded == false)
            {
                vesselData.PersistentAutopilotMode        = persistentAutopilotMode;
                vesselData.persistentVesselTargetId       = persistentVesselTargetId;
                vesselData.persistentVesselTargetBodyName = persistentVesselTargetBodyName;
                vesselData.persistentManeuverUT           = persistentManeuverUT;
                vesselData.persistentManeuverNextPatch    = persistentManeuverNextPatch;
                vesselData.persistentManeuverPatch        = persistentManeuverPatch;

                return;
            }

            if (fixedUpdateCount++ > 100)
            {
                persistentAutopilotMode = vessel.Autopilot.Mode;

                if (vessel.targetObject != null)
                {
                    var orbitDriver = vessel.targetObject.GetOrbitDriver();
                    if (orbitDriver.vessel != null)
                    {
                        persistentVesselTargetId       = orbitDriver.vessel.id.ToString();
                        persistentVesselTargetBodyName = string.Empty;
                    }
                    else if (orbitDriver.celestialBody != null)
                    {
                        persistentVesselTargetId       = Guid.Empty.ToString();
                        persistentVesselTargetBodyName = orbitDriver.celestialBody.bodyName;
                    }
                }
                else
                {
                    persistentVesselTargetId       = Guid.Empty.ToString();
                    persistentVesselTargetBodyName = string.Empty;
                }

                if (vessel.patchedConicSolver != null && vessel.patchedConicSolver.maneuverNodes.Count > 0)
                {
                    var maneuverNode = vessel.patchedConicSolver.maneuverNodes[0];

                    persistentManeuverUT        = maneuverNode.UT;
                    persistentManeuverNextPatch = maneuverNode.patch.Serialize();
                    persistentManeuverPatch     = maneuverNode.patch.Serialize();
                }
            }
            else
            {
                vessel.Autopilot.SetMode(persistentAutopilotMode);
                vessel.PersistHeading(TimeWarp.fixedDeltaTime, headingTolerance, true);
            }
        }
Example #20
0
 private static bool Prefix(VesselAutopilot.AutopilotMode mode, int skillLvl, ref bool __result)
 {
     __result = skillLvl >= mode.GetRequiredSkill();
     return(false);
 }
Example #21
0
 public void Update()
 {
     if (GameSettings.MODIFIER_KEY.GetKey() && GameSettings.SAS_TOGGLE.GetKeyDown())
         bArmed = !bArmed;
     if (bArmed)
     {
         if (GameSettings.SAS_TOGGLE.GetKeyDown())
             ActivitySwitch(!ActivityCheck());
         if (GameSettings.SAS_HOLD.GetKey())
             updateTarget();
     }
     if (vesModule.vesselRef.Autopilot != null)
     {
         if (currentMode != vesModule.vesselRef.Autopilot.Mode && currentMode == VesselAutopilot.AutopilotMode.StabilityAssist)
             updateTarget();
         if (referenceMode == FlightUIController.SpeedDisplayModes.Surface && FlightUIController.speedDisplayMode != FlightUIController.SpeedDisplayModes.Surface)
             orbitalTarget = vesModule.vesselRef.transform.rotation;
         currentMode = vesModule.vesselRef.Autopilot.Mode;
         referenceMode = FlightUIController.speedDisplayMode;
     }
     if (bActive[(int)SASList.Hdg])
         SASList.Hdg.GetSAS(this).SetPoint = Utils.calculateTargetHeading(currentTarget, vesModule);
 }
 /// <summary>
 /// returns a boolean indicating whether the specified SAS mode is active
 /// </summary>
 /// <param name="mode"></param>
 /// <returns></returns>
 private bool ButtonSASModeState(VesselAutopilot.AutopilotMode mode)
 {
     return(vessel != null && vessel.Autopilot.GetActualMode() == mode);
 }
 public static bool CanSetActualMode(this VesselAutopilot autopilot, VesselAutopilot.AutopilotMode mode)
 {
     return(autopilot.CanSetMode(ConvertMode(mode)));
 }
Example #24
0
        public void Update()
        {
            if (GameSettings.MODIFIER_KEY.GetKey() && GameSettings.SAS_TOGGLE.GetKeyDown())
                bArmed = !bArmed;
            if (bArmed)
            {
                pauseManager();
                if (GameSettings.SAS_TOGGLE.GetKeyDown())
                    ActivitySwitch(!ActivityCheck());
                if (GameSettings.SAS_HOLD.GetKey())
                    updateTarget();
            }
            if (ves.Autopilot != null)
            {
                if (APMode != ves.Autopilot.Mode && APMode == VesselAutopilot.AutopilotMode.StabilityAssist)
                    updateTarget();
                if (spdMode != FlightUIController.speedDisplayMode)
                {
                    if (spdMode == FlightUIController.SpeedDisplayModes.Surface)
                    {

                    }
                    else
                        orbitalTarget = ves.transform.rotation;
                }
                APMode = ves.Autopilot.Mode;
                spdMode = FlightUIController.speedDisplayMode;
            }
            if (bActive[(int)SASList.Hdg])
                GetSAS(SASList.Hdg).SetPoint = calculateTargetHeading(currentTarget, ves);
        }
        // Physics update
        public void FixedUpdate() // FixedUpdate is also called while not staged
        {
            if (this.vessel is null || currentEngine.engine is null || !isEnabled)
            {
                return;
            }

            fixedUpdateCount++;
            var universalTime = Planetarium.GetUniversalTime();

            // restore heading at load
            if (HasPersistentHeadingEnabled && fixedUpdateCount <= 60 && vesselAlignmentWithAutopilotMode > 0.995)
            {
                vessel.Autopilot.SetMode(persistentAutopilotMode);
                vessel.PersistHeading(TimeWarp.fixedDeltaTime, headingTolerance, vesselChangedSoiCountdown > 0);
            }
            else
            {
                persistentAutopilotMode = vessel.Autopilot.Mode;
            }

            //vesselHeadingVersusManeuver = vessel.VesselOrbitHeadingVersusManeuverVector();
            //vesselHeadingVersusManeuverInDegrees = Math.Acos(Math.Max(-1, Math.Min(1, vesselHeadingVersusManeuver))) * Rad2Deg;

            _kerbalismResourceChangeRequest.Clear();

            if (vesselChangedSoiCountdown > 0)
            {
                vesselChangedSoiCountdown--;
            }

            // Checks if moduleEngine mode wasn't switched
            FetchActiveMode();

            var processedEngines = isMultiMode ? new[] { currentEngine } : moduleEngines;

            // Realtime mode
            if (!vessel.packed)
            {
                vesselAlignmentWithAutopilotMode = vessel.HeadingVersusAutopilotVector(universalTime);

                // Update persistent thrust throttle if NOT transitioning from warp to realtime
                if (!warpToReal)
                {
                    UpdatePersistentThrottle();
                }

                for (var i = 0; i < processedEngines.Length; i++)
                {
                    currentEngine = processedEngines[i];

                    ResetMonitoringVariables();

                    // Update persistent thrust isp if NOT transitioning from warp to realtime
                    if (!warpToReal)
                    {
                        UpdatePersistentIsp();
                    }

                    currentEngine.engineHasAnyMassLessPropellants = currentEngine.engine.propellants.Any(m => m.resourceDef.density == 0);

                    if (processMasslessSeparately && currentEngine.engineHasAnyMassLessPropellants)
                    {
                        ReloadPropellantsWithoutMasslessPropellants();
                    }

                    //if (vesselHeadingVersusManeuverInDegrees > maneuverTolerance)
                    //{
                    //    moduleEngine.maxFuelFlow = 1e-10f;
                    //    finalThrust = 0;
                    //}
                    //else

                    if (!currentEngine.engine.getIgnitionState)
                    {
                        currentEngine.finalThrust = 0;

                        // restore maximum flow
                        RestoreMaxFuelFlow();
                    }
                    else if (!currentEngine.engineHasAnyMassLessPropellants && currentEngine.engine.propellantReqMet > 0)
                    {
                        // Mass flow rate
                        var massFlowRate = currentEngine.persistentIsp > 0
                            ? currentEngine.engine.currentThrottle * currentEngine.engine.maxThrust / (currentEngine.persistentIsp * PhysicsGlobals.GravitationalAcceleration)
                            : 0;
                        // Change in mass over time interval dT
                        var deltaMass = massFlowRate * TimeWarp.fixedDeltaTime;
                        // Resource demand from propellants with mass
                        currentEngine.demandMass = currentEngine.averageDensity > 0 ? deltaMass / currentEngine.averageDensity : 0;
                        // Calculate resource demands
                        currentEngine.fuelDemands = CalculateDemands(currentEngine.demandMass);
                        // Apply resource demands & test for resource depletion
                        ApplyDemands(currentEngine.fuelDemands, ref currentEngine.propellantReqMetFactor);

                        // calculate maximum flow
                        var maxFuelFlow = currentEngine.persistentIsp > 0 ? currentEngine.engine.maxThrust / (currentEngine.persistentIsp * PhysicsGlobals.GravitationalAcceleration) : 0;

                        // adjust fuel flow
                        currentEngine.engine.maxFuelFlow = maxFuelFlow > 0 && currentEngine.propellantReqMetFactor > 0 ? (float)(maxFuelFlow * currentEngine.propellantReqMetFactor) : 1e-10f;

                        // update displayed thrust and fx
                        currentEngine.finalThrust = currentEngine.engine.currentThrottle * currentEngine.engine.maxThrust * Math.Min(currentEngine.propellantReqMetFactor, currentEngine.engine.propellantReqMet * 0.01f);
                    }
                    else
                    {
                        // restore maximum flow
                        RestoreMaxFuelFlow();

                        currentEngine.propellantReqMetFactor = currentEngine.engine.propellantReqMet * 0.01f;

                        currentEngine.finalThrust = currentEngine.engine.GetCurrentThrust();
                    }

                    UpdatePropellantReqMetFactorQueue();

                    UpdateFX();

                    SetThrottleAnimation();

                    UpdateBuffers();
                }
            }
            else
            {
                for (var i = 0; i < processedEngines.Length; i++)
                {
                    currentEngine = processedEngines[i];

                    ResetMonitoringVariables();

                    // restore maximum flow
                    RestoreMaxFuelFlow();

                    if (persistentThrottle > 0 && currentEngine.persistentIsp > 0 && isPersistentEngine && HasPersistentThrust)
                    {
                        if (TimeWarp.CurrentRateIndex == 0)
                        {
                            warpToReal = true; // Set to true for transition to realtime
                        }
                        // Calculated requested thrust
                        //var requestedThrust = vesselHeadingVersusManeuverInDegrees <= maneuverTolerance ? moduleEngine.thrustPercentage * 0.01f * persistentThrottle * moduleEngine.maxThrust : 0;
                        var requestedThrust = currentEngine.engine.thrustPercentage * 0.01f * persistentThrottle * currentEngine.engine.maxThrust;

                        var thrustVector = part.transform.up; // Thrust direction unit vector
                        // Calculate deltaV vector & resource demand from propellants with mass
                        var deltaVVector = CalculateDeltaVVector(currentEngine.averageDensity, vessel.totalMass, TimeWarp.fixedDeltaTime, requestedThrust, currentEngine.persistentIsp, thrustVector, out currentEngine.demandMass);
                        // Calculate resource demands
                        currentEngine.fuelDemands = CalculateDemands(currentEngine.demandMass);
                        // Apply resource demands & test for resource depletion
                        ApplyDemands(currentEngine.fuelDemands, ref currentEngine.propellantReqMetFactor);

                        // Apply deltaV vector at UT & dT to orbit if resources not depleted
                        if (currentEngine.propellantReqMetFactor > 0)
                        {
                            currentEngine.finalThrust = requestedThrust * currentEngine.propellantReqMetFactor;
                            vessel.orbit.Perturb(deltaVVector * currentEngine.propellantReqMetFactor, universalTime);
                        }

                        // Otherwise log warning and drop out of TimeWarp if throttle on & depleted
                        else if (persistentThrottle > 0)
                        {
                            currentEngine.finalThrust = 0;
                            Debug.Log("[PersistentThrust]: Thrust warp stopped - propellant depleted");
                            ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_PT_StoppedDepleted"), 5.0f, ScreenMessageStyle.UPPER_CENTER);
                            // Return to realtime
                            TimeWarp.SetRate(0, true);
                            if (!vessel.IsControllable)
                            {
                                persistentThrottle            = 0;
                                vessel.ctrlState.mainThrottle = 0;
                            }
                        }
                        else
                        {
                            currentEngine.finalThrust = 0;
                        }

                        SetThrottleAnimation();

                        UpdateFX();
                    }
                    else
                    {
                        currentEngine.finalThrust = 0;

                        SetThrottleAnimation();

                        UpdateFX();

                        UpdateBuffers();
                    }
                }

                if (vessel.IsControllable && HasPersistentHeadingEnabled)
                {
                    vesselAlignmentWithAutopilotMode = vessel.PersistHeading(TimeWarp.fixedDeltaTime, headingTolerance, vesselChangedSoiCountdown > 0, vesselAlignmentWithAutopilotMode == 1);
                }
            }
            // display final thrust in a user friendly way
            thrustTxt = Utils.FormatThrust(moduleEngines.Sum(m => m.finalThrust));

            previousFixedDeltaTime = TimeWarp.fixedDeltaTime;

            UpdateMasslessConsumption();
        }