Пример #1
0
 public override void OnFixedUpdate()
 {
     if (IsActivate)
     {
         target = FlightGlobals.fetch.VesselTarget;
         if (!IsTarget && target != null && target.GetVessel() != null)
         {
             targetvessel = target.GetVessel();
             if (IsDrogue(targetvessel))
             {
                 IsTarget = true;
             }
         }
         if (IsTarget)
         {
             if (!ProbeTransform)
             {
                 Debug.Log("ProbeTransformMissing");
             }
             if (!TriggerTransform)
             {
                 Debug.Log("TriggerTransformMissing");
             }
             if (!TDrogue)
             {
                 Debug.Log("TDrogueMissing");
             }
             ReP = ProbeTransform.InverseTransformDirection(ProbeTransform.position - TriggerTransform.transform.position);
             ReV = ProbeTransform.InverseTransformDirection(this.part.rb.velocity - TDrogue.rb.velocity);
             Vector3 RPCancel  = ReV + ReP;
             Vector3 GrabForce = ProbeTransform.TransformDirection(-RPCancel);
             foreach (Part p in this.vessel.parts)
             {
                 if ((p.physicalSignificance == Part.PhysicalSignificance.FULL) && (p.rb != null))
                 {
                     p.AddForce(GrabForce.normalized * p.rb.mass * 10f);
                 }
             }
             if (IsContact)
             {
                 foreach (Part p in this.vessel.parts)
                 {
                     if ((p.physicalSignificance == Part.PhysicalSignificance.FULL) && (p.rb != null))
                     {
                         p.AddForce(GrabForce.normalized * p.rb.mass * 10f);
                     }
                 }
                 if (ReP.magnitude > 0.5f)
                 {
                     Deactivate();
                 }
                 float FuelFinal = this.part.RequestResource(fuelType, -Drogue.FuelGain);
                 if (Drogue.FuelGain != 0 && -FuelFinal < Drogue.FuelGain)
                 {
                     Deactivate();
                 }
             }
         }
     }
 }
Пример #2
0
        internal static Orbit getTargetOrbit(CelestialBody refbody)
        {
            ITargetable tgt = FlightGlobals.fetch.VesselTarget;

            if (tgt == null || FlightGlobals.ActiveVessel == tgt.GetVessel())
            {
                return(null);
            }

            Orbit o = tgt.GetOrbit();

            if (o.referenceBody == refbody)
            {
                return(o);
            }

            while (o.nextPatch != null)
            {
                if (o.isClosed())
                {
                    return(null);
                }
                o = o.nextPatch;
                if (o.referenceBody == refbody)
                {
                    return(o);
                }
            }
            return(null);
        }
Пример #3
0
        //This code draws the target distance and closest approach
        private void rightGauge()
        {
            ITargetable itarget = FlightGlobals.fetch.VesselTarget;

            if (itarget != null && itarget.GetOrbit() != null)
            {
                Vessel target = itarget.GetVessel();
                //Calculate and draw the distance between active vessal and target
                Vector3d aPos = FlightGlobals.ActiveVessel.orbit.pos;
                Vector3d tPos = itarget.GetOrbit().pos;
                //double distance = Vector3d.Distance(tPos, aPos);
                double distance = SteamShip.TargetDist;
                drawDigits(981, 131, distance);
                //Draw closure light
                if (distance < closestRed)  //red light
                {
                    GUI.DrawTextureWithTexCoords(new Rect(1014f * Scale, 101f * Scale, 17f * Scale, 17f * Scale), texture, new Rect(0.5058f, 0.2625f, 0.0142f, 0.0142f));
                }
                else if (distance < closestYellow)   //yellow light
                {
                    GUI.DrawTextureWithTexCoords(new Rect(1014f * Scale, 101f * Scale, 17f * Scale, 17f * Scale), texture, new Rect(0.5225f, 0.2625f, 0.0142f, 0.0142f));
                }
                else if (distance < closestGreen)   //green light
                {
                    GUI.DrawTextureWithTexCoords(new Rect(1014f * Scale, 101f * Scale, 17f * Scale, 17f * Scale), texture, new Rect(0.4875f, 0.2625f, 0.0142f, 0.0142f));
                }

                //Crunch closest distance, and display
                //res Result = getClosestApproach();
                drawDigits(982, 197, SteamShip.ClosestApproach);
                drawTime(1019, 260, SteamShip.ClosestTime);
                //Maybe surround this gauge with a AN/DN offset?
            }
        }
Пример #4
0
            protected override float GetScaleOffset()
            {
                float  b      = GetLowerOffset();
                float  y      = b;
                Vessel vessel = FlightGlobals.ActiveVessel;

                if (vessel != null)
                {
                    ITargetable targetable = vessel.targetObject;
                    if (targetable != null)
                    {
                        Vessel target = targetable.GetVessel();
                        if (target != null)
                        {
                            double d = Vector3.Distance(vessel.GetWorldPos3D(), target.GetWorldPos3D());
                            if (d > MAX_DISTANCE)
                            {
                                d = MAX_DISTANCE;
                                OutOfLimits();
                            }
                            else
                            {
                                InLimits();
                            }
                            if (d < 0)
                            {
                                d = 0;
                            }
                            y = b + 69.75f * (float)Math.Log10(1 + d / 100) / 400.0f;
                        }
                    }
                }
                return(y);
            }
        public override void OnFixedUpdate()
        {
            //Restore the saved target when we are made active vessel
            if (!wasActiveVessel && vessel.isActiveVessel)
            {
                if (target != null && target.GetVessel() != null)
                {
                    FlightGlobals.fetch.SetVesselTarget(target);
                }
            }

            //notice when the user switches targets
            if (vessel.isActiveVessel && target != FlightGlobals.fetch.VesselTarget)
            {
                target = FlightGlobals.fetch.VesselTarget;
                if (target is Vessel && ((Vessel)target).LandedOrSplashed && (((Vessel)target).mainBody == vessel.mainBody))
                {
                    targetBody      = vessel.mainBody;
                    targetLatitude  = vessel.mainBody.GetLatitude(target.GetTransform().position);
                    targetLongitude = vessel.mainBody.GetLongitude(target.GetTransform().position);
                }
            }

            //Update targets that need updating:
            if (target is DirectionTarget)
            {
                ((DirectionTarget)target).Update(targetDirection);
            }
            else if (target is PositionTarget)
            {
                ((PositionTarget)target).Update(targetBody, targetLatitude, targetLongitude);
            }

            wasActiveVessel = vessel.isActiveVessel;
        }
        /// <summary>
        /// Update the current target.
        /// </summary>
        /// <param name="vessel"></param>
        private void RefreshTarget(Vessel vessel)
        {
            // Do we have a target?
            ITargetable target = vessel.targetObject;

            if (target == null)
            {
                targetOrbitalPeriod = double.NaN;
                return;
            }

            // We have a target. If it's a vessel, is it non-orbiting?
            Vessel targetVessel = target.GetVessel();

            if ((targetVessel != null) && (targetVessel.situation != Vessel.Situations.ORBITING))
            {
                targetOrbitalPeriod = double.NaN;
                return;
            }

            // It's something else.  Could be an orbiting vessel, could be a celestial body,
            // could be some other ITargetable (which I believe doesn't exist in the stock
            // game, but mods could introduce other types).  Does it have an orbit?
            Orbit orbit = target.GetOrbit();

            targetOrbitalPeriod = (orbit == null) ? double.NaN : orbit.period;
        }
Пример #7
0
        /// <summary>
        /// True if the craft is sitting on a surface (solid or liquid) rather than on an orbit.
        /// </summary>
        public static bool Landed(ITargetable t)
        {
            Vessel vessel = t?.GetVessel();

            return(vessel != null &&
                   (vessel.situation == Vessel.Situations.PRELAUNCH ||
                    vessel.situation == Vessel.Situations.LANDED ||
                    vessel.situation == Vessel.Situations.SPLASHED));
        }
Пример #8
0
        //Code fully by me
        //Come to within 150m of the target
        void RenezvousWithTarget(ITargetable target, Vessel attackVessel)
        {
            var oDriver = attackVessel.orbitDriver;
            var tOrbit  = target.GetOrbit();

            HardsetOrbit(oDriver, tOrbit);
            attackVessel.GoOffRails();
            target.GetVessel().GoOffRails();
        }
Пример #9
0
        public static bool TargetValid()
        {
            if (FlightGlobals.ActiveVessel == null ||
                FlightGlobals.ActiveVessel.targetObject == null ||
                FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody == null ||
                FlightGlobals.ActiveVessel.orbit == null ||
                FlightGlobals.ActiveVessel.orbit.referenceBody == null)
            {
                _targetBody      = null;
                _vesselIntersect = false;
                _bodyIntersect   = false;
                _updated         = false;
                _activeVessel    = null;
                _activeBody      = null;
                _targetObject    = null;
                _targetTransform = null;
                return(false);
            }

            _activeVessel = FlightGlobals.ActiveVessel;
            _activeBody   = FlightGlobals.currentMainBody;
            _targetObject = _activeVessel.targetObject;

            if (_targetObject.GetVessel() == null)
            {
                if (_targetObject.GetOrbit() == null)
                {
                    _targetBody  = null;
                    _isCelestial = false;
                    _isVessel    = false;
                }
                else if (_targetObject.GetOrbitDriver().celestialBody != null)
                {
                    _targetBody  = _targetObject.GetOrbitDriver().celestialBody;
                    _isCelestial = true;
                    _isVessel    = false;
                }
                else
                {
                    _targetBody  = null;
                    _isCelestial = false;
                    _isVessel    = false;
                }
            }
            else
            {
                _targetBody        = null;
                _isCelestial       = false;
                _isVessel          = true;
                _targetTransform   = FlightGlobals.fetch.vesselTargetTransform;
                _vesselTargetDelta = FlightGlobals.fetch.vesselTargetDelta;
            }

            return(true);
        }
Пример #10
0
        public static void LogTargetInfo(ITargetable target)
        {
            var   method      = typeof(OrbitRenderer).GetMethod("GetOrbitColour", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            Color orbitColor2 = (Color)method.Invoke(target.GetOrbitDriver().Renderer, new object[0]);

            Logger.Debug("Target name: " + target.GetName());
            Logger.Debug("Target orbit color 1: " + target.GetOrbitDriver().Renderer.orbitColor);
            Logger.Debug("Target orbit color 2: " + orbitColor2);
            Logger.Debug("Target in vessel list: " + FlightGlobals.Vessels.Contains(target.GetVessel()));
            Logger.Debug("Target same orbit renderer: " + (target.GetOrbitDriver().Renderer == target.GetVessel().orbitRenderer));
            Logger.Debug("Target orbit renderer mode: " + target.GetOrbitDriver().Renderer.drawMode);
            Logger.Debug("Target isActive: " + target.GetOrbitDriver().Renderer.isActive);
            Logger.Debug("Target isFocused: " + target.GetOrbitDriver().Renderer.isFocused);
            Logger.Debug("Target orbit driver draw: " + target.GetOrbitDriver().drawOrbit);
            Logger.Debug("Target orbit driver update mode: " + target.GetOrbitDriver().updateMode);
            Logger.Debug("Target orbit driver last mode: " + target.GetOrbitDriver().lastMode);
            Logger.Debug("Target orbit driver color: " + target.GetOrbitDriver().orbitColor);
            Logger.Debug("Target has conic renderer: " + (target.GetVessel().patchedConicRenderer != null));
        }
Пример #11
0
        /// <summary>
        /// Returns the orbit of the currently targeted item or null if there is none.
        /// </summary>
        /// <returns>The orbit or null.</returns>
        public static Orbit getTargetOrbit()
        {
            ITargetable tgt = FlightGlobals.fetch.VesselTarget;

            if (tgt != null)
            {
                // if we have a null vessel it's a celestial body
                if (tgt.GetVessel() == null)
                {
                    return(tgt.GetOrbit());
                }
                // otherwise make sure we're not targeting ourselves.
                if (!FlightGlobals.fetch.activeVessel.Equals(tgt.GetVessel()))
                {
                    return(tgt.GetOrbit());
                }
            }
            return(null);
        }
Пример #12
0
        string GetTargetName(ITargetable obj)
        {
            string name;

            if (obj is ModuleDockingNode)
            {
                name = obj.GetVessel().GetDisplayName();
            }
            else if (obj is Vessel && obj.GetVessel().vesselType == VesselType.EVA)
            {
                name = obj.GetDisplayName().Split(' ')[0];
            }
            else
            {
                name = obj.GetDisplayName();
            }

            return(Localizer.Format("<<1>>", name));
        }
Пример #13
0
        void InitDocking()
        {
            lastTarget = core.target.Target;

            try
            {
                vesselBoundingBox = vessel.GetBoundingBox();
                targetBoundingBox = lastTarget.GetVessel().GetBoundingBox();

                targetSize = targetBoundingBox.size.magnitude;

                if (!overrideSafeDistance)
                {
                    safeDistance = vesselBoundingBox.size.magnitude + targetSize + 0.5f;
                }
                else
                {
                    safeDistance = (float)overridenSafeDistance.val;
                }

                if (core.target.Target is ModuleDockingNode)
                {
                    acquireRange = ((ModuleDockingNode)core.target.Target).acquireRange * 0.5;
                }
                else
                {
                    acquireRange = 0.25;
                }
            }
            catch (Exception e)
            {
                print(e);
            }

            if (zSep < 0)  //we're behind the target
            {
                dockingStep = DockingStep.WRONG_SIDE_BACKING_UP;
            }
            else if (lateralSep.magnitude > dockingcorridorRadius) // in front but far from docking axis
            {
                if (zSep < targetSize)
                {
                    dockingStep = DockingStep.BACKING_UP;
                }
                else
                {
                    dockingStep = DockingStep.MOVING_TO_START;
                }
            }
            else
            {
                dockingStep = DockingStep.DOCKING;
            }
        }
Пример #14
0
        public static void SetTarget(ITargetable val, Vessel currentVessel)
        {
            if (val is Vessel && (Vessel)val == currentVessel)
            {
                throw new Safe.Exceptions.KOSInvalidTargetException("A ship cannot set TARGET to itself.");
            }
            else if (val.GetVessel() == currentVessel)
            {
                throw new Safe.Exceptions.KOSInvalidTargetException("A ship cannot set TARGET to a part of itself.");
            }

            FlightGlobals.fetch.SetVesselTarget(val, true);
        }
        void InitDocking()
        {
            lastTarget = core.target.Target;

            try
            {
                Vector3Pair vesselBoundingBox = vessel.GetBoundingBox();
                Vector3Pair targetBoundingBox = lastTarget.GetVessel().GetBoundingBox();

                targetSize = Mathf.Max(targetBoundingBox.p1.magnitude, targetBoundingBox.p2.magnitude);

                safeDistance = Mathf.Max(vesselBoundingBox.p1.magnitude, vesselBoundingBox.p2.magnitude) + targetSize;


                if (core.target.Target is ModuleDockingNode)
                {
                    acquireRange = ((ModuleDockingNode)core.target.Target).acquireRange * 0.5;
                }
                else
                {
                    acquireRange = 0.25;
                }
            }
            catch (Exception e)
            {
                print(e);
            }

            if (zSep < 0)  //we're behind the target
            {
                dockingStep = DockingStep.WRONG_SIDE_BACKING_UP;
            }
            else if (lateralSep.magnitude > dockingcorridorRadius) // in front but far from docking axis
            {
                if (zSep < targetSize)
                {
                    dockingStep = DockingStep.BACKING_UP;
                }
                else
                {
                    dockingStep = DockingStep.MOVING_TO_START;
                }
            }
            else
            {
                dockingStep = DockingStep.DOCKING;
            }
        }
Пример #16
0
            protected override float GetScaleOffset()
            {
                float  m      = GetCenterOffset();
                float  y      = m;
                Vessel vessel = FlightGlobals.ActiveVessel;

                if (vessel != null)
                {
                    ITargetable targetable = vessel.targetObject;
                    if (targetable != null)
                    {
                        Vessel target = targetable.GetVessel();
                        if (target != null)
                        {
                            Vector3d velocity = target.obt_velocity - vessel.obt_velocity;
                            Vector3d dir      = vessel.CoM - target.CoM;
                            double   angle    = Vector3d.Angle(velocity, dir);
                            //Log.Test("ANGLE: " + angle);
                            double v = velocity.magnitude * (angle < 90.0?1:-1);
                            if (v > MAX_SPEED)
                            {
                                v = MAX_SPEED;
                                NotInLimits();
                            }
                            else if (v < MIN_SPEED)
                            {
                                v = MIN_SPEED;
                                NotInLimits();
                            }
                            else
                            {
                                InLimits();
                            }

                            if (v >= 0)
                            {
                                y = m + 37.5f * (float)Math.Log10(1 + v) / (float)SCALE_HEIGHT;
                            }
                            else
                            {
                                y = m - 37.5f * (float)Math.Log10(1 - v) / (float)SCALE_HEIGHT;
                            }
                        }
                    }
                }
                return(y);
            }
        public override void OnFixedUpdate()
        {
            //Restore the saved target when we are made active vessel
            if (!wasActiveVessel && vessel.isActiveVessel)
            {
                if (target != null && target.GetVessel() != null)
                {
                    vessel.targetObject = target;
                }
            }

            //notice when the user switches targets
            if (target != vessel.targetObject)
            {
                target = vessel.targetObject;
                if (target is Vessel && ((Vessel)target).LandedOrSplashed && (((Vessel)target).mainBody == vessel.mainBody))
                {
                    targetBody      = vessel.mainBody;
                    targetLatitude  = vessel.mainBody.GetLatitude(target.GetTransform().position);
                    targetLongitude = vessel.mainBody.GetLongitude(target.GetTransform().position);
                }
                if (target is CelestialBody)
                {
                    targetBody = (CelestialBody)target;
                }
            }

            // .23 temp fix until I understand better what's going on
            if (targetBody == null)
            {
                targetBody = vessel.mainBody;
            }

            //Update targets that need updating:
            if (target is DirectionTarget)
            {
                ((DirectionTarget)target).Update(targetDirection);
            }
            else if (target is PositionTarget)
            {
                ((PositionTarget)target).Update(targetBody, targetLatitude, targetLongitude);
            }

            wasActiveVessel = vessel.isActiveVessel;
        }
Пример #18
0
        private void clApp()
        {
            if (_patch == null)
            {
                return;
            }

            ITargetable tgt = FlightGlobals.fetch.VesselTarget;

            if (tgt == null)
            {
                return;
            }

            double clApp = 0;

            if (tgt.GetVessel() == null)
            {
                clApp = _patch.closestTgtApprUT;
            }
            else
            {
                clApp = ManeuverUtilities.closestVessel(0, _patch, tgt.GetOrbit(), true, 0, 0);
            }

            if (clApp <= 0)
            {
                return;
            }

            if (_patch.UTsoi > 0 && clApp > _patch.UTsoi)
            {
                return;
            }
            else if (clApp < Planetarium.GetUniversalTime())
            {
                return;
            }
            else
            {
                setNodeTime(clApp);
            }
        }
Пример #19
0
        private void TargetCam()
        {
            ITargetable target = TargetHelper.Target;

            if (target == null)
            {
                SetCurrentMode(true, false, false, false);
            }
            else
            {
                Vessel vessel = target.GetVessel();
                SetCurrentMode(false, false, false, true);
                Vector3 vector = vessel.transform.position - FlightGlobals.ActiveVessel.transform.position;
                vector.Normalize();
                camObject.transform.position = (vessel.CoM - vector * _targetOffset);
                Vector3 normalized = base.vessel.vesselTransform.up.normalized;
                camObject.transform.LookAt(vessel.transform, normalized);
            }
        }
Пример #20
0
        protected override string fieldUpdate()
        {
            if (!BasicTargetting.Updated)
            {
                return("---");
            }

            if (BasicTargetting.IsCelestial)
            {
                return(BasicTargetting.TargetBody.theName);
            }
            else if (BasicTargetting.IsVessel)
            {
                if (FlightGlobals.ActiveVessel.targetObject == null)
                {
                    return("---");
                }

                ITargetable tgt = FlightGlobals.ActiveVessel.targetObject;

                Vessel targetVessel = tgt.GetVessel();

                if (targetVessel == null)
                {
                    return("---");
                }

                if (targetVessel.loaded && targetVessel.GetReferenceTransformPart().FindModulesImplementing <ModuleDockingNode>().Count > 0)
                {
                    return(string.Format("{0} [{1}]", targetVessel.vesselName, targetVessel.GetReferenceTransformPart().partInfo.title));
                }
                else
                {
                    return(targetVessel.vesselName);
                }
            }
            else
            {
                return("---");
            }
        }
Пример #21
0
        public static void SetTarget(ITargetable val, Vessel currentVessel)
        {
            if (val is Vessel && (Vessel)val == currentVessel)
            {
                throw new Safe.Exceptions.KOSInvalidTargetException("A ship cannot set TARGET to itself.");
            }
            else if (val.GetVessel() == currentVessel)
            {
                throw new Safe.Exceptions.KOSInvalidTargetException("A ship cannot set TARGET to a part of itself.");
            }

            // If any kOS terminal (not just the one this CPU uses as its Shared.Window, but ANY kOS terminal
            // from any kOS CPU) is the focused window right now, causing input lockouts, we must
            // temporarily turn off that input lock in order for the main game allow the SetVesselTarget()
            // call in the lines below to perform its task fully:
            //
            // Note the preferred solution would be to walk all control locks and suppress *any* that are turning
            // off the targeting, regardless of whether they're kOS or not, but InputLockManager does not provide
            // any methods for iteratinng the collection of all control lock masks, and it's also not possible to turn
            // a lock OFF by masking it with a new control lock, since all the locks in the stack are OR'ed together.)

            ControlTypes termInputLock = InputLockManager.GetControlLock(Screen.TermWindow.CONTROL_LOCKOUT);

            // (Note, KSP returns ControlTypes.None rather than null when no such lock was found, because it's
            // a non-nullable enum)
            if (termInputLock != ControlTypes.None)
            {
                InputLockManager.RemoveControlLock(Screen.TermWindow.CONTROL_LOCKOUT);
            }

            FlightGlobals.fetch.SetVesselTarget(val, true);

            if (termInputLock != ControlTypes.None)
            {
                InputLockManager.SetControlLock(termInputLock, Screen.TermWindow.CONTROL_LOCKOUT);
            }
        }
Пример #22
0
        public void LateUpdate()
        {
            if (display != null)
            {
                FlightGlobals.SpeedDisplayModes mode = FlightGlobals.speedDisplayMode;


                switch (mode)
                {
                case FlightGlobals.SpeedDisplayModes.Surface:
                {
                    Vessel.Situations situation  = FlightGlobals.ActiveVessel.situation;
                    VesselType        vesselType = FlightGlobals.ActiveVessel.vesselType;

                    double spd = FlightGlobals.ActiveVessel.srfSpeed;
                    string titleText;

                    //VesselType.Base;          //Situations.LANDED
                    //VesselType.Debris         //Situations.SPLASHED
                    //VesselType.EVA            //Situations.PRELAUNCH
                    //VesselType.Flag           //Situations.FLYING
                    //VesselType.Lander         //Situations.SUB_ORBITAL
                    //VesselType.Plane;         //Situations.ORBITING
                    //VesselType.Probe          //Situations.ESCAPING
                    //VesselType.Relay          //Situations.DOCKED
                    //VesselType.Rover
                    //VesselType.Ship
                    //VesselType.SpaceObject
                    //VesselType.Station
                    //VesselType.Unknown

                    switch (vesselType)
                    {
                    case VesselType.Plane:
                    case VesselType.Rover:
                    {
                        // Boat or Submarine
                        if (situation == Vessel.Situations.SPLASHED)
                        {
                            bool isradar = HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_radar;

                            if (FlightGlobals.ActiveVessel.altitude < -20 && isradar)                 // Submarine
                            {
                                titleText = Surf3 + Unitize_short(FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.terrainAltitude) + "  " + (spd * kn_ms).ToString("F1") + kn;
                            }
                            else                                                                       // Boat
                            {
                                titleText = Surf5 + (spd * kn_ms).ToString("F1") + knots;
                            }
                        }
                        // Plane (not LANDED)
                        else if (vesselType == VesselType.Plane &&
                                 situation != Vessel.Situations.LANDED && situation != Vessel.Situations.PRELAUNCH)
                        {
                            bool isradar = HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_radar;
                            bool ismach  = HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_mach;
                            bool isATM   = FlightGlobals.ActiveVessel.atmDensity > 0.0;

                            if (isradar)
                            {
                                if (ismach)
                                {
                                    if (isATM)
                                    {
                                        titleText = Surf3 + Unitize_short(FlightGlobals.ActiveVessel.radarAltitude) + "  "
                                                    + Localizer.Format("#SpeedUnitAnnex_mach", FlightGlobals.ActiveVessel.mach.ToString("F1"));
                                    }

                                    else
                                    {
                                        titleText = Surf5 + Unitize_long(FlightGlobals.ActiveVessel.radarAltitude);
                                    }
                                }
                                else
                                {
                                    titleText = Surf3 + Unitize_short(FlightGlobals.ActiveVessel.radarAltitude) + "  "
                                                + (spd * kn_ms).ToString("F1") + kn;
                                }
                            }
                            else
                            {
                                if (ismach)
                                {
                                    if (isATM)
                                    {
                                        titleText = Surf5 + Localizer.Format("#SpeedUnitAnnex_mach", FlightGlobals.ActiveVessel.mach.ToString("F1"));
                                    }
                                    else
                                    {
                                        titleText = Surface;
                                    }
                                }
                                else
                                {
                                    titleText = Surf5 + (spd * kn_ms).ToString("F1") + knots;
                                }
                            }
                        }
                        // Rover (and LANDED Plane)  // and rover-carrier if ksp detect them as rover
                        // All mistake at ksp detecting vessel type can be fixed by some additional checking (ex. altitude for rover-carrier)
                        // but it make unclear to user, which values is showed up.
                        else                 //if FlightGlobals.ActiveVessel.radarAltitude < 100)
                        {
                            if (HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_kmph)
                            {
                                titleText = Surf5 + (spd * kmph_ms).ToString("F1") + kmph;
                            }
                            else
                            {
                                titleText = Surf5 + (spd * mph_ms).ToString("F1") + mph;
                            }
                        }
                    }
                    break;

                    case VesselType.EVA:
                    {
                        if (HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_radar)
                        {
                            double alt;

                            if (situation == Vessel.Situations.SPLASHED)
                            {
                                alt = FlightGlobals.ActiveVessel.radarAltitude + 0.2;
                            }
                            else
                            {
                                alt = FlightGlobals.ActiveVessel.radarAltitude - 0.2;
                            }

                            titleText = Surf3 + Unitize_short(alt) + " " + FlightGlobals.ActiveVessel.GetDisplayName();
                        }
                        else
                        {
                            titleText = Surf3 + FlightGlobals.ActiveVessel.GetDisplayName();
                        }

                        if (titleText.Length > 17)
                        {
                            titleText = titleText.Substring(0, 16) + "...";
                        }
                    }
                    break;

                    case VesselType.Flag:
                    {
                        titleText = Surf3 + FlightGlobals.ActiveVessel.GetDisplayName();

                        if (titleText.Length > 17)
                        {
                            titleText = titleText.Substring(0, 16) + "...";
                        }
                    }
                    break;

                    // Other: Rocket, Lander, Base etc
                    default:
                    {
                        if (HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_radar)
                        {
                            titleText = Surf5 + Unitize_long(FlightGlobals.ActiveVessel.radarAltitude);
                        }
                        else
                        {
                            titleText = Surface;
                        }
                    }
                    break;
                    }

                    display.textTitle.text = titleText;
                    break;
                }

                case FlightGlobals.SpeedDisplayModes.Orbit:
                {
                    if (FlightGlobals.ActiveVessel.vesselType == VesselType.EVA &&
                        HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_orbit_EVA)
                    {
                        string titleText = Orb + FlightGlobals.ActiveVessel.GetDisplayName();

                        if (titleText.Length > 17)
                        {
                            titleText = titleText.Substring(0, 16) + "...";
                        }

                        display.textTitle.text = titleText;
                    }
                    else if (HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_orbit)
                    {
                        string ApStr = Unitize_short(FlightGlobals.ship_orbit.ApA);
                        string PeStr = Unitize_short(FlightGlobals.ship_orbit.PeA);

                        display.textTitle.text = Orb + ApStr + " " + PeStr;
                    }

                    break;
                }

                case FlightGlobals.SpeedDisplayModes.Target:
                {
                    ITargetable obj = FlightGlobals.fetch.VesselTarget;

                    // ITargetable ->  CelestialBody;
                    //                 FlightCoMTracker;
                    //                 ModuleDockingNode;
                    //                 PositionTarget;
                    //                 Vessel;

                    string text;
                    string name;

                    if (obj is ModuleDockingNode)
                    {
                        name = obj.GetVessel().GetDisplayName();
                    }
                    else
                    {
                        name = obj.GetDisplayName();
                    }

                    if (name.Length > 1 && name.Substring(name.Length - 2, 1) == "^")
                    {
                        name = name.Substring(0, name.Length - 2);
                    }

                    if (HighLogic.CurrentGame.Parameters.CustomParams <SpeedUnitAnnexSettings>().setting_targetDistance)
                    {
                        // from Docking Port Alignment Indicator
                        Transform selfTransform    = FlightGlobals.ActiveVessel.ReferenceTransform;
                        Transform targetTransform  = FlightGlobals.fetch.VesselTarget.GetTransform();
                        Vector3   targetToOwnship  = selfTransform.position - targetTransform.position;
                        float     distanceToTarget = targetToOwnship.magnitude;

                        text = Trg + Unitize_short(distanceToTarget) + " " + name;
                    }
                    else
                    {
                        text = Trg + name;
                    }


                    if (text.Length <= 17)
                    {
                        display.textTitle.text = text;
                    }
                    else
                    {
                        display.textTitle.text = text.Substring(0, 16) + "...";
                    }

                    break;
                }
                }

                display.textTitle.alignment = TMPro.TextAlignmentOptions.MidlineLeft;
            }
        }
Пример #23
0
        void InitDocking()
        {
            lastTarget = core.target.Target;

            try
            {
                Vector3Pair vesselBoundingBox = vessel.GetBoundingBox();
                Vector3Pair targetBoundingBox = lastTarget.GetVessel().GetBoundingBox();

                targetSize = Mathf.Max(targetBoundingBox.p1.magnitude, targetBoundingBox.p2.magnitude);

                safeDistance = Mathf.Max(vesselBoundingBox.p1.magnitude, vesselBoundingBox.p2.magnitude) + targetSize;

                if (core.target.Target is ModuleDockingNode)
                    acquireRange = ((ModuleDockingNode)core.target.Target).acquireRange * 0.5;
                else
                    acquireRange = 0.25;

            }
            catch (Exception e)
            {
                print(e);
            }

            if (zSep < 0)  //we're behind the target
                dockingStep = DockingStep.WRONG_SIDE_BACKING_UP;
            else if (lateralSep.magnitude > dockingcorridorRadius) // in front but far from docking axis
                if (zSep < targetSize)
                    dockingStep = DockingStep.BACKING_UP;
                else
                    dockingStep = DockingStep.MOVING_TO_START;
            else
                dockingStep = DockingStep.DOCKING;
        }
Пример #24
0
        protected override string fieldUpdate()
        {
            if (FlightGlobals.ActiveVessel == null)
            {
                return("---");
            }

            if (!BasicTargetting.Updated)
            {
                return("---");
            }

            if (BasicTargetting.IsVessel)
            {
                if (FlightGlobals.ActiveVessel.targetObject == null)
                {
                    return("---");
                }

                ITargetable tgt = FlightGlobals.ActiveVessel.targetObject;

                Vessel targetVessel = tgt.GetVessel();

                if (targetVessel == null)
                {
                    return("---");
                }

                Vector3d targetPos = BasicTargetting.TargetOrbit.pos;
                Vector3d originPos = BasicTargetting.ShipOrbit.pos;

                if (targetVessel.loaded)
                {
                    if (FlightGlobals.ActiveVessel.GetReferenceTransformPart() != null &&
                        FlightGlobals.ActiveVessel.GetReferenceTransformPart().FindModulesImplementing <ModuleDockingNode>().Count > 0)
                    {
                        originPos = FlightGlobals.ActiveVessel.GetReferenceTransformPart().FindModulesImplementing <ModuleDockingNode>()[0].nodeTransform.position;

                        if (FlightGlobals.fetch != null)
                        {
                            targetPos = FlightGlobals.fetch.vesselTargetTransform.position;
                        }
                        else
                        {
                            targetPos = targetVessel.ReferenceTransform.position;
                        }
                    }
                    else if (FlightGlobals.fetch != null)
                    {
                        return(result(FlightGlobals.fetch.vesselTargetDelta.magnitude));
                    }
                    else
                    {
                        originPos = FlightGlobals.ActiveVessel.ReferenceTransform.position;
                        targetPos = targetVessel.ReferenceTransform.position;
                    }
                }

                return(result(Vector3d.Distance(targetPos, originPos)));
            }
            else if (BasicTargetting.IsCelestial)
            {
                return(result(Vector3d.Distance(BasicTargetting.TargetOrbit.pos, BasicTargetting.ShipOrbit.pos)));
            }
            else
            {
                return("---");
            }
        }
Пример #25
0
        void InitDocking()
        {
            lastTarget = core.target.Target;

            try
            {
                vesselBoundingBox = vessel.GetBoundingBox();
                targetBoundingBox = lastTarget.GetVessel().GetBoundingBox();

                if (!overrideTargetSize)
                {
                    targetSize = targetBoundingBox.size.magnitude;
                }
                else
                {
                    targetSize = (float)overridenTargetSize.val;
                }

                if (!overrideSafeDistance)
                {
                    safeDistance = vesselBoundingBox.size.magnitude + targetSize + 0.5f;
                }
                else
                {
                    safeDistance = (float)overridenSafeDistance.val;
                }

                if (core.target.Target is ModuleDockingNode)
                {
                    acquireRange = ((ModuleDockingNode)core.target.Target).acquireRange * 0.5;
                }
                else
                {
                    acquireRange = 0.25;
                }
            }
            catch (Exception e)
            {
                Log.err(e, this);
            }

            if (zSep < 0)  //we're behind the target
            {
                // If we're more than half our own bounding box size behind the target port then use wrong side behavior
                // Still needs improvement. The reason for these changes is that to prevent wrong side behavior when our
                // port slipped behind the target by a fractional amount. The result is that rather than avoiding the
                // target ship we end up trying to pass right through it.
                // What's really needed here is code that compares bounding box positions to determine if we just try to back up or change sides completely.
                if (Math.Abs(zSep) > vesselBoundingBox.size.magnitude * 0.5f)
                {
                    dockingStep = DockingStep.WRONG_SIDE_BACKING_UP;
                }
                else
                {
                    dockingStep = DockingStep.BACKING_UP; // Just back straight up.
                }
            }
            else if (lateralSep.magnitude > dockingcorridorRadius) // in front but far from docking axis
            {
                if (zSep < targetSize)
                {
                    dockingStep = DockingStep.BACKING_UP;
                }
                else
                {
                    dockingStep = DockingStep.MOVING_TO_START;
                }
            }
            else
            {
                dockingStep = DockingStep.DOCKING;
            }
        }
        public override void OnUpdate()
        {
            /*
             * Line_Forward.SetPosition(0, transform.position); Line_Forward.SetPosition(1, transform.position + vessel.vesselTransform.forward);
             * Line_Up.SetPosition(0, transform.position); Line_Up.SetPosition(1, transform.position + vessel.vesselTransform.up);
             * Line_Right.SetPosition(0, transform.position); Line_Right.SetPosition(1, transform.position + vessel.vesselTransform.right);
             */

            vTarget      = FlightGlobals.fetch.VesselTarget;
            vIsActive    = vessel.isActiveVessel;
            foundTarget  = vTarget != null;
            loadedTarget = foundTarget && vTarget.GetVessel() != null && vTarget.GetVessel().loaded;


            if (!toggle || !vIsActive || !foundTarget || !loadedTarget)
            {
                Line_Dock.SetPosition(0, Vector3.zero); Line_Dock.SetPosition(1, Vector3.zero);
                Line_Velocity.SetPosition(0, Vector3.zero); Line_Velocity.SetPosition(1, Vector3.zero);

                Line_V_Up.SetPosition(0, Vector3.zero); Line_V_Right.SetPosition(0, Vector3.zero); Line_V_Diff.SetPosition(0, Vector3.zero);
                Line_V_Up.SetPosition(1, Vector3.zero); Line_V_Right.SetPosition(1, Vector3.zero); Line_V_Diff.SetPosition(1, Vector3.zero);
                alignment = 0f;
                return;
            }

            velocity_smoothed = (velocity_smoothed * 0.9f + (vessel.rootPart.Rigidbody.velocity - vTarget.GetVessel().rootPart.Rigidbody.velocity) * Time.deltaTime * 0.1f) / 10f; // Sliding window

            arrow_point = vessel.GetTransform().position + velocity_smoothed.normalized;

            alignment = 100f * Vector3.Dot(velocity_smoothed.normalized, (vTarget.GetTransform().transform.position - vessel.GetTransform().position).normalized);
            if (alignment > 99.9f)
            {
                setLineColors(Line_Dock, Color_Velocity);
                setLineColors(Line_V_Diff, Color_Velocity);
                arrow_to_point = arrow_point;
            }
            else
            {
                setLineColors(Line_Dock, Color_Dock);
                setLineColors(Line_V_Diff, Color_Diff);
                arrow_to_point = Vector3.ProjectOnPlane(((vTarget.GetTransform().transform.position - vessel.GetTransform().position).normalized - arrow_point + vessel.GetTransform().position), vessel.GetTransform().up).normalized + arrow_point;
            }

            Line_Dock.SetPosition(0, vessel.GetTransform().position);  // GetTransform returns the point being controlled from
            Line_Dock.SetPosition(1, vTarget.GetTransform().position); // This is the other dock port
            Line_Velocity.SetPosition(0, vessel.GetTransform().position);
            if (velocity_smoothed.magnitude > 0.00001f)
            {
                Line_Velocity.SetPosition(1, arrow_point);
                // Line_V_Down.SetPosition(0, arrow_point); Line_V_Down.SetPosition(1, arrow_point + vessel.GetTransform().up * -1f);
                Line_V_Up.SetPosition(1, arrow_point + vessel.GetTransform().forward * -1f); // Weird right? "Up" is actually "Back" on a Kerbin ship
                // Line_V_Left.SetPosition(0, arrow_point); Line_V_Left.SetPosition(1, arrow_point + vessel.GetTransform().right * -1f);
                Line_V_Right.SetPosition(1, arrow_point + vessel.GetTransform().right);
                Line_V_Diff.SetPosition(1, arrow_to_point);
            }
            else
            {
                Line_Velocity.SetPosition(1, vessel.GetTransform().position);
                Line_V_Up.SetPosition(1, arrow_point); Line_V_Right.SetPosition(1, arrow_point); Line_V_Diff.SetPosition(1, arrow_point);
            }
            Line_V_Up.SetPosition(0, arrow_point);
            Line_V_Right.SetPosition(0, arrow_point);
            Line_V_Diff.SetPosition(0, arrow_point);
            // print("Velocity is " + part.Rigidbody.velocity * Time.deltaTime);
        }
Пример #27
0
        /// <summary>
        ///     Draws the target information when selected.
        /// </summary>
        private void DrawTarget(Unity.Flight.ISectionModule section)
        {
            ITargetable target = Flight.Readouts.Rendezvous.RendezvousProcessor.activeTarget;

            this.ResizeRequested = true;

            if (target != null)
            {
                if (HighLogic.LoadedSceneIsFlight)
                {
                    if (GUILayout.Button("Go Back to Target Selection", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                    {
                        FlightGlobals.fetch.SetVesselTarget(null);
                    }
                }
                else
                {
                    if (RendezvousProcessor.TrackingStationSource != target)
                    {
                        if (GUILayout.Button("Use " + RendezvousProcessor.nameForTargetable(target) + " As Reference", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                        {
                            RendezvousProcessor.TrackingStationSource = target;
                        }
                    }
                }

                if (HighLogic.LoadedSceneIsFlight)
                {
                    var act = FlightGlobals.ActiveVessel;

                    if (!(target is CelestialBody) && GUILayout.Button("Switch to Target", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                    {
                        FlightEngineerCore.SwitchToVessel(target.GetVessel(), act);
                    }

                    bool focusable = (target is CelestialBody || target is global::Vessel);

                    if (focusable)
                    {
                        MapObject targMo = null;

                        if (target is global::Vessel)
                        {
                            targMo = ((global::Vessel)(target)).mapObject;
                        }
                        else
                        {
                            targMo = ((CelestialBody)(target)).MapObject;
                        }

                        bool shouldFocus = targMo != null && (targMo != PlanetariumCamera.fetch.target || !MapView.MapIsEnabled);

                        if (shouldFocus && GUILayout.Button("Focus Target", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                        {
                            wasMapview = MapView.MapIsEnabled;
                            MapView.EnterMapView();
                            PlanetariumCamera.fetch.SetTarget(targMo);
                        }
                    }

                    bool switchBack = PlanetariumCamera.fetch.target != act.mapObject;

                    if (switchBack && MapView.MapIsEnabled && GUILayout.Button("Focus Vessel", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                    {
                        if (!wasMapview)
                        {
                            MapView.ExitMapView();
                        }
                        PlanetariumCamera.fetch.SetTarget(act.mapObject);
                    }

                    if (FlightCamera.fetch.mode != FlightCamera.Modes.LOCKED && !MapView.MapIsEnabled && GUILayout.Button("Look at Target", this.ButtonStyle, GUILayout.Width(this.ContentWidth)))
                    {
                        var pcam = PlanetariumCamera.fetch;
                        var fcam = FlightCamera.fetch;

                        Vector3 from = new Vector3();

                        if (target is global::Vessel && ((global::Vessel)target).LandedOrSplashed)
                        {
                            from = ((global::Vessel)target).GetWorldPos3D();
                        }
                        else
                        {
                            //I don't think it's possible to target the sun so this should always work but who knows.
                            if (target.GetOrbit() != null)
                            {
                                from = target.GetOrbit().getTruePositionAtUT(Planetarium.GetUniversalTime());
                            }
                        }


                        Vector3 to = FlightGlobals.fetch.activeVessel.GetWorldPos3D();

                        //  float pdist = pcam.Distance;
                        float fdist = fcam.Distance;

                        Vector3 n = (from - to).normalized;

                        if (!n.IsInvalid())
                        {
                            //   pcam.SetCamCoordsFromPosition(n * -pdist); //this does weird stuff
                            fcam.SetCamCoordsFromPosition(n * -fdist);
                        }
                    }
                }

                GUILayout.Space(3f);

                this.DrawLine("Selected Target", RendezvousProcessor.nameForTargetable(target), section.IsHud);

                if (RendezvousProcessor.sourceDisplay != null)
                {
                    if (RendezvousProcessor.landedSamePlanet || RendezvousProcessor.overrideANDN)
                    {
                        this.DrawLine("Ref Orbit", "Landed on " + RendezvousProcessor.activeVessel.GetOrbit().referenceBody.GetName(), section.IsHud);
                    }
                    else
                    {
                        this.DrawLine("Ref Orbit", RendezvousProcessor.sourceDisplay, section.IsHud);
                    }
                }

                if (RendezvousProcessor.targetDisplay != null)
                {
                    if (RendezvousProcessor.landedSamePlanet || RendezvousProcessor.overrideANDNRev)
                    {
                        this.DrawLine("Target Orbit", "Landed on " + target.GetOrbit().referenceBody.GetName(), section.IsHud);
                    }
                    else
                    {
                        this.DrawLine("Target Orbit", RendezvousProcessor.targetDisplay, section.IsHud);
                    }
                }
            }
        }
        private void FetchCommonData()
        {
            localGeeASL = vessel.orbit.referenceBody.GeeASL * gee;
            coM = vessel.findWorldCenterOfMass();
            localGeeDirect = FlightGlobals.getGeeForceAtPosition(coM).magnitude;
            up = (coM - vessel.mainBody.position).normalized;
            forward = vessel.GetTransform().up;
            right = vessel.GetTransform().right;
            north = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - coM).normalized;
            rotationSurface = Quaternion.LookRotation(north, up);
            rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface);

            velocityVesselOrbit = vessel.orbit.GetVel();
            velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(coM);

            speedVertical = Vector3d.Dot(velocityVesselSurface, up);
            speedVerticalRounded = Math.Ceiling(speedVertical * 20) / 20;
            target = FlightGlobals.fetch.VesselTarget;
            node = vessel.patchedConicSolver.maneuverNodes.Count > 0 ? vessel.patchedConicSolver.maneuverNodes[0] : null;
            time = Planetarium.GetUniversalTime();
            FetchAltitudes();
            terrainHeight = altitudeASL - altitudeTrue;
            if (time >= lastTimePerSecond + 1) {
                terrainDelta = terrainHeight - lastTerrainHeight;
                lastTerrainHeight = terrainHeight;
                lastTimePerSecond = time;
            }

            horzVelocity = (velocityVesselSurface - (speedVertical * up)).magnitude;
            horzVelocityForward = Vector3d.Dot(velocityVesselSurface, forward);
            horzVelocityRight = Vector3d.Dot(velocityVesselSurface, right);

            atmPressure = FlightGlobals.getStaticPressure(altitudeASL, vessel.mainBody);
            dynamicPressure = 0.5 * velocityVesselSurface.sqrMagnitude * vessel.atmDensity;

            if (target != null) {
                targetSeparation = vessel.GetTransform().position - target.GetTransform().position;
                targetOrientation = target.GetTransform().rotation;

                targetVessel = target as Vessel;
                targetBody = target as CelestialBody;
                targetDockingNode = target as ModuleDockingNode;

                targetDistance = Vector3.Distance(target.GetTransform().position, vessel.GetTransform().position);

                // This is kind of messy.
                targetOrbitSensibility = false;
                // All celestial bodies except the sun have orbits that make sense.
                targetOrbitSensibility |= targetBody != null && targetBody != Planetarium.fetch.Sun;

                if (targetVessel != null)
                    targetOrbitSensibility = JUtil.OrbitMakesSense(targetVessel);
                if (targetDockingNode != null)
                    targetOrbitSensibility = JUtil.OrbitMakesSense(target.GetVessel());

                if (targetOrbitSensibility)
                    targetOrbit = target.GetOrbit();

                // TODO: Actually, there's a lot of nonsensical cases here that need more reasonable handling.
                // Like what if we're targeting a vessel landed on a moon of another planet?...
                if (targetOrbit != null) {
                    velocityRelativeTarget = vessel.orbit.GetVel() - target.GetOrbit().GetVel();
                } else {
                    velocityRelativeTarget = vessel.orbit.GetVel();
                }

                // If our target is somehow our own celestial body, approach speed is equal to vertical speed.
                if (targetBody == vessel.mainBody)
                    approachSpeed = speedVertical;
                // In all other cases, that should work. I think.
                approachSpeed = Vector3d.Dot(velocityRelativeTarget, (target.GetTransform().position - vessel.GetTransform().position).normalized);
            } else {
                velocityRelativeTarget = targetSeparation = Vector3d.zero;
                targetOrbit = null;
                targetDistance = 0;
                approachSpeed = 0;
                targetBody = null;
                targetVessel = null;
                targetDockingNode = null;
                targetOrientation = vessel.GetTransform().rotation;
                targetOrbitSensibility = false;
            }
            orbitSensibility = JUtil.OrbitMakesSense(vessel);
            if (vessel.situation == Vessel.Situations.SUB_ORBITAL || vessel.situation == Vessel.Situations.FLYING) {
                // Mental note: the local g taken from vessel.mainBody.GeeASL will suffice.
                //  t = (v+sqrt(v²+2gd))/g or something.

                // What is the vertical component of current acceleration?
                double accelUp = Vector3d.Dot(vessel.acceleration, up);

                double altitude = altitudeTrue;
                if (vessel.mainBody.ocean && altitudeASL > 0.0) {
                    // AltitudeTrue shows distance above the floor of the ocean,
                    // so use ASL if it's closer in this case, and we're not
                    // already below SL.
                    altitude = Math.Min(altitudeASL, altitudeTrue);
                }

                if (accelUp < 0.0 || speedVertical >= 0.0 || Planetarium.TimeScale > 1.0) {
                    // If accelUp is negative, we can't use it in the general
                    // equation for finding time to impact, since it could
                    // make the term inside the sqrt go negative.
                    // If we're going up, we can use this as well, since
                    // the precision is not critical.
                    // If we are warping, accelUp is always zero, so if we
                    // do not use this case, we would fall to the simple
                    // formula, which is wrong.
                    secondsToImpact = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * localGeeASL * altitude)) / localGeeASL;
                } else if (accelUp > 0.005) {
                    // This general case takes into account vessel acceleration,
                    // so estimates on craft that include parachutes or do
                    // powered descents are more accurate.
                    secondsToImpact = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * accelUp * altitude)) / accelUp;
                } else {
                    // If accelUp is small, we get floating point precision
                    // errors that tend to make secondsToImpact get really big.
                    secondsToImpact = altitude / -speedVertical;
                }

                // MOARdV: I think this gets the computation right.  High thrust will
                // result in NaN, which is already handled.
                /*
                double accelerationAtMaxThrust = localG - (totalMaximumThrust / totalShipWetMass);
                double timeToImpactAtMaxThrust = (speedVertical + Math.Sqrt(speedVertical * speedVertical + 2 * accelerationAtMaxThrust * altitude)) / accelerationAtMaxThrust;
                bestPossibleSpeedAtImpact = speedVertical - accelerationAtMaxThrust * timeToImpactAtMaxThrust;
                if (double.IsNaN(bestPossibleSpeedAtImpact))
                    bestPossibleSpeedAtImpact = 0;
                */
                bestPossibleSpeedAtImpact = SpeedAtImpact(totalMaximumThrust, totalShipWetMass, localGeeASL, speedVertical, altitude);
                expectedSpeedAtImpact = SpeedAtImpact(totalCurrentThrust, totalShipWetMass, localGeeASL, speedVertical, altitude);

            } else {
                secondsToImpact = Double.NaN;
                bestPossibleSpeedAtImpact = 0;
                expectedSpeedAtImpact = 0;
            }
        }
        void InitDocking()
        {
            lastTarget = core.target.Target;

            try
            {
                vesselBoundingBox = vessel.GetBoundingBox();
                targetBoundingBox = lastTarget.GetVessel().GetBoundingBox();

                if (!overrideTargetSize)
                    targetSize = targetBoundingBox.size.magnitude;
                else
                    targetSize = (float)overridenTargetSize.val;

                if (!overrideSafeDistance)
                    safeDistance = vesselBoundingBox.size.magnitude + targetSize + 0.5f;
                else
                    safeDistance = (float)overridenSafeDistance.val;

                if (core.target.Target is ModuleDockingNode)
                    acquireRange = ((ModuleDockingNode)core.target.Target).acquireRange * 0.5;
                else
                    acquireRange = 0.25;

            }
            catch (Exception e)
            {
                print(e);
            }

            if (zSep < 0)  //we're behind the target
                dockingStep = DockingStep.WRONG_SIDE_BACKING_UP;
            else if (lateralSep.magnitude > dockingcorridorRadius) // in front but far from docking axis
                if (zSep < targetSize)
                    dockingStep = DockingStep.BACKING_UP;
                else
                    dockingStep = DockingStep.MOVING_TO_START;
            else
                dockingStep = DockingStep.DOCKING;
        }
Пример #30
0
        private void UpdateVP()
        {
            List <Part> ActiveEngines = new List <Part>();

            ActiveEngines = GetListOfActivatedEngines(AV);

            VP.FlightStatus = (byte)AV.situation;

            //Orbit
            VP.CurrentOrbit = OrbUtil.GetOrbitData(AV.orbit);

            VP.VVI = (float)AV.verticalSpeed;
            VP.G   = (float)AV.geeForce;

            double ASL = AV.mainBody.GetAltitude(AV.CoM);
            double AGL = (ASL - AV.terrainAltitude);

            if (AGL < ASL)
            {
                VP.RAlt = (float)AGL;
            }
            else
            {
                VP.RAlt = (float)ASL;
            }

            VP.Alt   = (float)ASL;
            VP.Vsurf = (float)AV.srfSpeed;
            VP.Lat   = (float)AV.latitude;
            VP.Lon   = (float)AV.longitude;

            TempR            = GetResourceTotal(AV, "LiquidFuel");
            VP.LiquidFuelTot = TempR.Max;
            VP.LiquidFuel    = TempR.Current;

            VP.LiquidFuelTotS = (float)ProspectForResourceMax("LiquidFuel", ActiveEngines);
            VP.LiquidFuelS    = (float)ProspectForResource("LiquidFuel", ActiveEngines);

            TempR          = GetResourceTotal(AV, "Oxidizer");
            VP.OxidizerTot = TempR.Max;
            VP.Oxidizer    = TempR.Current;

            VP.OxidizerTotS = (float)ProspectForResourceMax("Oxidizer", ActiveEngines);
            VP.OxidizerS    = (float)ProspectForResource("Oxidizer", ActiveEngines);

            TempR           = GetResourceTotal(AV, "ElectricCharge");
            VP.EChargeTot   = TempR.Max;
            VP.ECharge      = TempR.Current;
            TempR           = GetResourceTotal(AV, "MonoPropellant");
            VP.MonoPropTot  = TempR.Max;
            VP.MonoProp     = TempR.Current;
            TempR           = GetResourceTotal(AV, "IntakeAir");
            VP.IntakeAirTot = TempR.Max;
            VP.IntakeAir    = TempR.Current;
            TempR           = GetResourceTotal(AV, "SolidFuel");
            VP.SolidFuelTot = TempR.Max;
            VP.SolidFuel    = TempR.Current;
            TempR           = GetResourceTotal(AV, "XenonGas");
            VP.XenonGasTot  = TempR.Max;
            VP.XenonGas     = TempR.Current;

            VP.MissionTime = (float)AV.missionTime;
            VP.UT          = (float)Planetarium.GetUniversalTime();

            VP.VOrbit = (float)AV.orbit.GetVel().magnitude;

            VP.MNTime     = 0;
            VP.MNDeltaV   = 0;
            VP.TargetDist = 0;
            VP.TargetV    = 0;

            VP.HasTarget = (byte)(HasTarget() ? 1 : 0);

            //mathy stuff
            Quaternion rotationSurface;

            CoM   = AV.CoM;
            up    = (CoM - AV.mainBody.position).normalized;
            north = Vector3d.Exclude(up, (AV.mainBody.position + AV.mainBody.transform.up * (float)AV.mainBody.Radius) - CoM).normalized;

            east = Vector3d.Cross(up, north);

            rotationSurface = Quaternion.LookRotation(north, up);

            Vector3d attitude = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(AV.GetTransform().rotation) * rotationSurface).eulerAngles;

            VP.Roll    = (float)((attitude.z > 180) ? (attitude.z - 360.0) : attitude.z);
            VP.Pitch   = (float)((attitude.x > 180) ? (360.0 - attitude.x) : -attitude.x);
            VP.Heading = (float)attitude.y;

            Vector3d prograde = new Vector3d(0, 0, 0);

            switch (FlightGlobals.speedDisplayMode)
            {
            case FlightGlobals.SpeedDisplayModes.Surface:
                prograde = AV.srf_velocity.normalized;
                break;

            case FlightGlobals.SpeedDisplayModes.Orbit:
                prograde = AV.obt_velocity.normalized;
                break;

            case FlightGlobals.SpeedDisplayModes.Target:
                prograde = FlightGlobals.ship_tgtVelocity;
                break;
            }

            VP.Prograde = WorldVecToNavHeading(up, north, east, prograde);

            if (HasTarget())
            {
                ITargetable t = AV.targetObject;

                VP.Target     = WorldVecToNavHeading(up, north, east, t.GetTransform().position - AV.transform.position);
                VP.TargetDist = (float)Vector3.Distance(t.GetTransform().position, AV.transform.position);
                VP.TargetV    = (float)FlightGlobals.ship_tgtVelocity.magnitude;

                if (t is Vessel)
                {
                    attitude = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(t.GetVessel().GetTransform().rotation) * rotationSurface).eulerAngles;
                    VP.TargetRotation.Pitch   = (float)((attitude.x > 180) ? (360.0 - attitude.x) : -attitude.x);
                    VP.TargetRotation.Heading = (float)attitude.y;
                }
                else if (t is ModuleDockingNode)
                {
                    VP.TargetRotation = WorldVecToNavHeading(up, north, east, t.GetFwdVector());
                }
            }

            if (AV.patchedConicSolver != null)
            {
                if (AV.patchedConicSolver.maneuverNodes != null)
                {
                    if (AV.patchedConicSolver.maneuverNodes.Count > 0)
                    {
                        VP.MNTime   = (UInt32)Math.Round(AV.patchedConicSolver.maneuverNodes[0].UT - Planetarium.GetUniversalTime());
                        VP.MNDeltaV = (float)AV.patchedConicSolver.maneuverNodes[0].GetBurnVector(AV.patchedConicSolver.maneuverNodes[0].patch).magnitude; //Added JS

                        VP.Maneuver = WorldVecToNavHeading(up, north, east, AV.patchedConicSolver.maneuverNodes[0].GetBurnVector(AV.patchedConicSolver.maneuverNodes[0].patch));
                    }
                }
            }

            VP.MainControls = CalcMainControls();

            VP.ActionGroups = CalcActionGroups();

            VP.MaxOverHeat = GetMaxOverHeat(AV);
            VP.IAS         = (float)AV.indicatedAirSpeed;

            VP.CurrentStage = (byte)StageManager.CurrentStage;
            VP.TotalStage   = (byte)StageManager.StageCount;

            VP.SpeedMode = (byte)(FlightGlobals.speedDisplayMode + 1);
            VP.SASMode   = GetSASMode(true);

            VP.timeWarpRateIndex = GetTimeWarpIndex();
        }
Пример #31
0
        /// <summary>
        ///     Updates the details by recalculating if requested.
        /// </summary>
        public void Update()
        {
            ITargetable    target = null;
            global::Vessel vessel = null;

            landedSamePlanet = false;
            isLanded         = false;
            overrideANDN     = false;
            overrideANDNRev  = false;

            if (HighLogic.LoadedSceneIsFlight)
            {
                if (FlightGlobals.fetch == null ||
                    FlightGlobals.fetch.VesselTarget == null ||
                    FlightGlobals.ActiveVessel == null ||
                    FlightGlobals.ActiveVessel.targetObject == null ||
                    FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                    FlightGlobals.ship_orbit == null ||
                    FlightGlobals.ship_orbit.referenceBody == null)
                {
                    ShowDetails = false;
                    return;
                }
                else
                {
                    target = FlightGlobals.ActiveVessel.targetObject;
                    vessel = FlightGlobals.ActiveVessel;
                }
                TrackingStationSource = null;
            }
            else if (HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.CelestialBody)
                {
                    target = PlanetariumCamera.fetch.target.celestialBody;
                }
                else if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.Vessel)
                {
                    target = PlanetariumCamera.fetch.target.vessel;
                }

                if (TrackingStationSource != null)
                {
                    vessel = TrackingStationSource.GetVessel();
                }
                else
                {
                    TrackingStationSource = target;
                }
            }

            activeTarget = target;

            if (target == null)
            {
                ShowDetails = false;
                return;
            }

            ShowDetails = true;

            var actualSourceOrbit = vessel != null ? vessel.orbit : TrackingStationSource.GetOrbit();
            var actualTargetOrbit = target.GetOrbit();

            if (target is global::Vessel)
            {
                targetVessel = (global::Vessel)target;
            }
            else
            {
                targetVessel = null;
            }

            activeVessel = vessel;

            if (actualSourceOrbit == null)
            {
                //  Debug.Log("Source orbit is null!");
                TrackingStationSource = null;
                ShowDetails           = false;
                return;
            }

            if (actualTargetOrbit == null)
            {
                // Debug.Log("Target orbit is null!");
                ShowDetails = false;
                return;
            }

            isLanded = vessel != null && vessel.LandedOrSplashed;
            bool targetLanded = (target is global::Vessel && ((global::Vessel)target).LandedOrSplashed);

            landedSamePlanet = isLanded && targetLanded && actualSourceOrbit.referenceBody == actualTargetOrbit.referenceBody;

            var originOrbit = isLanded ? actualSourceOrbit.referenceBody.orbit : actualSourceOrbit;
            var targetOrbit = targetLanded ? actualTargetOrbit.referenceBody.orbit : actualTargetOrbit;

            if ((!isLanded && !targetLanded) || (actualSourceOrbit.referenceBody != actualTargetOrbit.referenceBody))
            {
                findConcentricParents(ref originOrbit, ref targetOrbit);
            }

            if (originOrbit == targetOrbit && !landedSamePlanet)
            {
                targetOrbit = actualTargetOrbit;
                originOrbit = null;
            }

            { //These are not 'rendezvous' calculations, just raw data about the target object.
                AltitudeSeaLevel    = targetOrbit.altitude;
                ApoapsisHeight      = targetOrbit.ApA;
                PeriapsisHeight     = targetOrbit.PeA;
                TimeToApoapsis      = targetOrbit.timeToAp;
                TimeToPeriapsis     = targetOrbit.timeToPe;
                SemiMajorAxis       = targetOrbit.semiMajorAxis;
                SemiMinorAxis       = targetOrbit.semiMinorAxis;
                OrbitalPeriod       = targetOrbit.period;
                RelativeInclination = targetOrbit.inclination;
            }

            { //Set everything else 0 incase some are not valid.
                TimeToAscendingNode   = 0;
                TimeToDescendingNode  = 0;
                AngleToAscendingNode  = 0;
                AngleToDescendingNode = 0;

                RelativeVelocity    = 0;
                RelativeSpeed       = 0;
                PhaseAngle          = 0;
                InterceptAngle      = 0;
                TimeToTransferAngle = 0;

                AngleToPlane[0] = 0;
                TimeToPlane[0]  = 0;
                AngleToPlane[1] = 0;
                TimeToPlane[1]  = 0;
                Distance        = 0;

                TimeTilEncounter      = double.NaN;
                SeparationAtEncounter = double.NaN;
                SpeedAtEncounter      = double.NaN;

                Orbital.ManoeuvreNode.ManoeuvreProcessor.PostBurnRelativeInclination = 0;
            }


            if (originOrbit != null)   //Actually calculating an encounter with 2 different things.

            {
                overrideANDN       = isLanded && actualSourceOrbit.referenceBody == targetOrbit.referenceBody;
                overrideANDNRev    = targetLanded && !isLanded && actualTargetOrbit.referenceBody == actualSourceOrbit.referenceBody && target.GetVessel() != null;
                bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                if (landedSamePlanet)   //this should only occur when landed targeting something else landed on same body.

                {
                    AltitudeSeaLevel = target.GetVessel().altitude;
                    ApoapsisHeight   = 0;
                    PeriapsisHeight  = 0;
                    TimeToApoapsis   = 0;
                    TimeToPeriapsis  = 0;
                    SemiMajorAxis    = 0;
                    SemiMinorAxis    = 0;
                    Distance         = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                    OrbitalPeriod    = bodyRotationPeriod;
                }
                else if (overrideANDN)    //launching

                {
                    if (vessel != null)
                    {
                        AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, vessel.latitude, vessel.longitude, targetOrbit);
                        TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                    }

                    RelativeInclination = targetOrbit.inclination;
                    PhaseAngle          = OrbitExtensions.GetPhaseAngle(actualSourceOrbit, actualTargetOrbit); //this works for some reason.
                }
                else if (overrideANDNRev)                                                                      //landing

                {
                    global::Vessel tgt = target.GetVessel();

                    if (vessel != null)
                    {
                        AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, tgt.latitude, tgt.longitude, originOrbit);
                        TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                    }

                    RelativeInclination = originOrbit.inclination;
                    Distance            = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                    AltitudeSeaLevel    = tgt.altitude;
                    PhaseAngle          = OrbitExtensions.GetPhaseAngle(actualSourceOrbit, actualTargetOrbit); //this works for some reason.
                }
                else                                                                                           //standard 2 orbits

                {
                    RelativeInclination = OrbitExtensions.GetRelativeInclination(originOrbit, targetOrbit);



                    if (FlightGlobals.ActiveVessel == null || FlightGlobals.ActiveVessel.patchedConicSolver == null ||
                        FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes == null ||
                        FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes.Count == 0)
                    {
                    }
                    else
                    {
                        var node = FlightGlobals.ActiveVessel.patchedConicSolver.maneuverNodes[0];
                        if (node != null && node.nextPatch != null)
                        {
                            Orbital.ManoeuvreNode.ManoeuvreProcessor.PostBurnRelativeInclination = OrbitExtensions.GetRelativeInclination(node.nextPatch, FlightGlobals.ActiveVessel.targetObject.GetOrbit());
                        }
                    }



                    RelativeSpeed    = originOrbit.GetRelativeVel().magnitude - target.GetObtVelocity().magnitude;
                    RelativeVelocity = (originOrbit.GetRelativeVel() - target.GetObtVelocity()).magnitude;

                    // FlightGlobals.ship_tgtVelocity = FlightGlobals.ship_obtVelocity - this.VesselTarget.GetObtVelocity();
                    // FlightGlobals.ship_tgtSpeed = FlightGlobals.ship_tgtVelocity.magnitude;

                    PhaseAngle     = OrbitExtensions.GetPhaseAngle(originOrbit, targetOrbit);
                    InterceptAngle = CalcInterceptAngle(targetOrbit, originOrbit);

                    double tspd = 360 / targetOrbit.period;
                    double sspd = 360 / originOrbit.period;

                    if (PhaseAngle < 0)
                    {
                        double diff = InterceptAngle - PhaseAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (tspd - sspd);
                    }
                    else
                    {
                        double diff = PhaseAngle - InterceptAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (sspd - tspd);
                    }


                    TimeToAscendingNode   = OrbitExtensions.GetTimeToVector(originOrbit, GetAscendingNode(targetOrbit, originOrbit));
                    TimeToDescendingNode  = OrbitExtensions.GetTimeToVector(originOrbit, GetDescendingNode(targetOrbit, originOrbit));
                    AngleToAscendingNode  = OrbitExtensions.GetAngleToVector(originOrbit, GetAscendingNode(targetOrbit, originOrbit));
                    AngleToDescendingNode = OrbitExtensions.GetAngleToVector(originOrbit, GetDescendingNode(targetOrbit, originOrbit));

                    Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);


                    //From OrbitTargeter
                    double tOne = 0;
                    if (target is CelestialBody)
                    {
                        Vector3d relativePositionAtUT  = originOrbit.getRelativePositionAtUT(originOrbit.closestTgtApprUT);
                        Vector3d relativePositionAtUT2 = targetOrbit.getRelativePositionAtUT(originOrbit.closestTgtApprUT);
                        double   separation            = (relativePositionAtUT - relativePositionAtUT2).magnitude;
                        tOne = originOrbit.closestTgtApprUT;
                    }
                    else
                    {
                        double num3       = 0.0;
                        double num4       = 0.0;
                        double num5       = 0.0;
                        double eVs        = 0.0;
                        double num6       = 0.0;
                        double eVs2       = 0.0;
                        int    iterations = 0;
                        int    num7       = Orbit.FindClosestPoints(originOrbit, targetOrbit, ref num3, ref num4, ref num5, ref eVs, ref num6, ref eVs2, 0.0001, 20, ref iterations);
                        tOne = originOrbit.StartUT + originOrbit.GetDTforTrueAnomaly(num5, 0.0);
                        double tTwo = originOrbit.StartUT + originOrbit.GetDTforTrueAnomaly(num6, 0.0);
                        if (tOne > tTwo)
                        {
                            UtilMath.SwapValues(ref tOne, ref tTwo);
                            UtilMath.SwapValues(ref num5, ref num6);
                            UtilMath.SwapValues(ref eVs, ref eVs2);
                        }
                    }

                    if (tOne > originOrbit.StartUT)
                    {
                        TimeTilEncounter      = tOne - originOrbit.StartUT;
                        SeparationAtEncounter = (originOrbit.getPositionAtUT(tOne) - targetOrbit.getPositionAtUT(tOne)).magnitude;
                        SpeedAtEncounter      = Math.Abs(originOrbit.getOrbitalSpeedAt(tOne) - targetOrbit.getOrbitalSpeedAt(tOne));
                    }
                }
            }

            if (actualTargetOrbit != targetOrbit)
            {
                targetDisplay = findNameForOrbit(targetOrbit, target);
            }
            else
            {
                targetDisplay = null;
            }

            if (originOrbit == null)
            {
                sourceDisplay = "N/A";
            }
            else if (actualSourceOrbit != originOrbit || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                sourceDisplay = findNameForOrbit(originOrbit, vessel != null ? vessel : TrackingStationSource);
            }
            else
            {
                sourceDisplay = null;
            }
        }
        /// <summary>
        ///     Updates the details by recalculating if requested.
        /// </summary>
        public void Update()
        {
            ITargetable    target = null;
            global::Vessel vessel = null;

            if (HighLogic.LoadedSceneIsFlight)
            {
                if (FlightGlobals.fetch == null ||
                    FlightGlobals.fetch.VesselTarget == null ||
                    FlightGlobals.ActiveVessel == null ||
                    FlightGlobals.ActiveVessel.targetObject == null ||
                    FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                    FlightGlobals.ship_orbit == null ||
                    FlightGlobals.ship_orbit.referenceBody == null)
                {
                    ShowDetails = false;
                    return;
                }
                else
                {
                    target = FlightGlobals.ActiveVessel.targetObject;
                    vessel = FlightGlobals.ActiveVessel;
                }
            }
            else if (HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.CelestialBody)
                {
                    target = PlanetariumCamera.fetch.target.celestialBody;
                }
                else if (PlanetariumCamera.fetch.target.type == MapObject.ObjectType.Vessel)
                {
                    target = PlanetariumCamera.fetch.target.vessel;
                }

                if (TrackingStationSource != null)
                {
                    vessel = TrackingStationSource.GetVessel();
                }
                else
                {
                    TrackingStationSource = target;
                }
            }

            activeTarget = target;

            if (target == null)
            {
                ShowDetails = false;
                return;
            }

            ShowDetails = true;

            var actualSourceOrbit = vessel != null ? vessel.orbit : TrackingStationSource.GetOrbit();
            var actualTargetOrbit = target.GetOrbit();

            if (target is global::Vessel)
            {
                targetVessel = (global::Vessel)target;
            }
            else
            {
                targetVessel = null;
            }

            activeVessel = vessel;

            if (actualSourceOrbit == null)
            {
                //  Debug.Log("Source orbit is null!");
                TrackingStationSource = null;
                ShowDetails           = false;
                return;
            }

            if (actualTargetOrbit == null)
            {
                // Debug.Log("Target orbit is null!");
                ShowDetails = false;
                return;
            }

            isLanded = vessel != null && vessel.LandedOrSplashed;
            bool targetLanded = (target is global::Vessel && ((global::Vessel)target).LandedOrSplashed);

            landedSamePlanet = isLanded && targetLanded && actualSourceOrbit.referenceBody == actualTargetOrbit.referenceBody;

            var originOrbit = isLanded ? actualSourceOrbit.referenceBody.orbit : actualSourceOrbit;
            var targetOrbit = targetLanded ? actualTargetOrbit.referenceBody.orbit : actualTargetOrbit;

            if ((!isLanded && !targetLanded) || (actualSourceOrbit.referenceBody != actualTargetOrbit.referenceBody))
            {
                findConcentricParents(ref originOrbit, ref targetOrbit);
            }

            if (originOrbit == targetOrbit && !landedSamePlanet)
            {
                targetOrbit = actualTargetOrbit;
                originOrbit = null;
            }

            AltitudeSeaLevel    = targetOrbit.altitude;
            ApoapsisHeight      = targetOrbit.ApA;
            PeriapsisHeight     = targetOrbit.PeA;
            TimeToApoapsis      = targetOrbit.timeToAp;
            TimeToPeriapsis     = targetOrbit.timeToPe;
            SemiMajorAxis       = targetOrbit.semiMajorAxis;
            SemiMinorAxis       = targetOrbit.semiMinorAxis;
            OrbitalPeriod       = targetOrbit.period;
            RelativeInclination = targetOrbit.inclination;

            TimeToAscendingNode   = 0;
            TimeToDescendingNode  = 0;
            AngleToAscendingNode  = 0;
            AngleToDescendingNode = 0;

            RelativeVelocity    = 0;
            RelativeSpeed       = 0;
            PhaseAngle          = 0;
            InterceptAngle      = 0;
            TimeToTransferAngle = 0;

            AngleToPlane[0] = 0;
            TimeToPlane[0]  = 0;
            AngleToPlane[1] = 0;
            TimeToPlane[1]  = 0;
            Distance        = 0;

            if (originOrbit != null)
            {
                overrideANDN    = isLanded && actualSourceOrbit.referenceBody == targetOrbit.referenceBody;
                overrideANDNRev = targetLanded && !isLanded && actualTargetOrbit.referenceBody == actualSourceOrbit.referenceBody && target.GetVessel() != null;

                if (landedSamePlanet)   //this should only occur when landed targeting something else landed on same body.

                {
                    AltitudeSeaLevel = target.GetVessel().altitude;
                    ApoapsisHeight   = 0;
                    PeriapsisHeight  = 0;
                    TimeToApoapsis   = 0;
                    TimeToPeriapsis  = 0;
                    SemiMajorAxis    = 0;
                    SemiMinorAxis    = 0;

                    bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                    Distance = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());

                    OrbitalPeriod = bodyRotationPeriod;

                    TimeToRendezvous       = 0;
                    RelativeRadialVelocity = 0;
                }
                else
                {
                    RelativeInclination = originOrbit.GetRelativeInclination(targetOrbit);
                    RelativeSpeed       = originOrbit.orbitalSpeed - targetOrbit.orbitalSpeed;
                    RelativeVelocity    = RelativeSpeed;
                    PhaseAngle          = originOrbit.GetPhaseAngle(targetOrbit);
                    InterceptAngle      = CalcInterceptAngle(targetOrbit, originOrbit);

                    double tspd = 360 / targetOrbit.period;
                    double sspd = 360 / originOrbit.period;


                    if (PhaseAngle < 0)
                    {
                        double diff = InterceptAngle - PhaseAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (tspd - sspd);
                    }
                    else
                    {
                        double diff = PhaseAngle - InterceptAngle;
                        if (diff < 0)
                        {
                            diff += 360;
                        }
                        if (diff > 340)
                        {
                            diff -= 360;
                        }
                        TimeToTransferAngle = sspd == tspd ? 0 : diff / (sspd - tspd);
                    }


                    TimeToAscendingNode   = originOrbit.GetTimeToVector(GetAscendingNode(targetOrbit, originOrbit));
                    TimeToDescendingNode  = originOrbit.GetTimeToVector(GetDescendingNode(targetOrbit, originOrbit));
                    AngleToAscendingNode  = originOrbit.GetAngleToVector(GetAscendingNode(targetOrbit, originOrbit));
                    AngleToDescendingNode = originOrbit.GetAngleToVector(GetDescendingNode(targetOrbit, originOrbit));

                    Distance = Vector3d.Distance(targetOrbit.pos, originOrbit.pos);

                    bodyRotationPeriod = actualSourceOrbit.referenceBody.rotationPeriod;

                    // beware that the order/sign of coordinates is inconsistent across different exposed variables
                    // in particular, v below does not equal to FlightGlobals.ship_tgtVelocity
                    Vector3d x  = targetOrbit.pos - originOrbit.pos;
                    Vector3d v  = targetOrbit.vel - originOrbit.vel;
                    double   xv = Vector3d.Dot(x, v);
                    TimeToRendezvous       = -xv / Vector3d.SqrMagnitude(v);
                    RelativeRadialVelocity = xv / Vector3d.Magnitude(x);

                    if (overrideANDN) //calc launch time
                    {
                        if (vessel != null)
                        {
                            AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, vessel.latitude, vessel.longitude, targetOrbit);
                            TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                            TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        }

                        RelativeInclination    = targetOrbit.inclination;
                        RelativeRadialVelocity = 0;
                        TimeToRendezvous       = 0;
                        PhaseAngle             = 0;
                        InterceptAngle         = 0;
                        TimeToTransferAngle    = 0;
                    }
                    else if (overrideANDNRev)     //calc land time.
                    {
                        global::Vessel tgt = target.GetVessel();

                        if (vessel != null)
                        {
                            AngleToPlane   = CalcAngleToPlane(vessel.GetOrbit().referenceBody, tgt.latitude, tgt.longitude, originOrbit);
                            TimeToPlane[0] = (AngleToPlane[0] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                            TimeToPlane[1] = (AngleToPlane[1] / 360) * vessel.GetOrbit().referenceBody.rotationPeriod;
                        }

                        RelativeInclination    = originOrbit.inclination;
                        Distance               = Vector3d.Distance(target.GetVessel().GetWorldPos3D(), vessel.GetWorldPos3D());
                        AltitudeSeaLevel       = tgt.altitude;
                        PhaseAngle             = 0;
                        InterceptAngle         = 0;
                        TimeToTransferAngle    = 0;
                        ApoapsisHeight         = 0;
                        PeriapsisHeight        = 0;
                        TimeToApoapsis         = 0;
                        TimeToPeriapsis        = 0;
                        SemiMajorAxis          = 0;
                        SemiMinorAxis          = 0;
                        OrbitalPeriod          = 0;
                        RelativeRadialVelocity = 0;
                        TimeToRendezvous       = 0;
                    }
                }
            }

            if (actualTargetOrbit != targetOrbit)
            {
                targetDisplay = findNameForOrbit(targetOrbit, target);
            }
            else
            {
                targetDisplay = null;
            }

            if (originOrbit == null)
            {
                sourceDisplay = "N/A";
            }
            else if (actualSourceOrbit != originOrbit || HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                sourceDisplay = findNameForOrbit(originOrbit, vessel != null ? vessel : TrackingStationSource);
            }
            else
            {
                sourceDisplay = null;
            }
        }
Пример #33
0
        public static void Update()
        {
            _update = false;

            if (FlightGlobals.ActiveVessel == null ||
                FlightGlobals.ActiveVessel.targetObject == null ||
                FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null ||
                FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody == null ||
                FlightGlobals.ActiveVessel.orbit == null ||
                FlightGlobals.ActiveVessel.orbit.referenceBody == null)
            {
                _updated = false;
                return;
            }

            _updated = true;

            Orbit active = _activeVessel.orbit;
            Orbit target = _targetObject.GetOrbit();

            _trueShipOrbit = active;

            _showAngle   = false;
            _showPhasing = false;

            _shipOrbit   = null;
            _targetOrbit = null;

            if (active.referenceBody == target.referenceBody)
            {
                _shipOrbit   = active;
                _targetOrbit = target;
            }
            else
            {
                if (active.referenceBody == Planetarium.fetch.Sun)
                {
                    _shipOrbit   = active;
                    _targetOrbit = target;
                }
                else
                {
                    _showAngle = true;
                }

                _showPhasing = true;

                DrillDownOrbits(active, target);
            }

            Vessel.Situations sit = _activeVessel.situation;

            if ((sit |= Vessel.Situations.LANDED | Vessel.Situations.SPLASHED | Vessel.Situations.PRELAUNCH) == 0)
            {
                _vesselIntersect = false;
                _bodyIntersect   = false;
            }
            else
            {
                if (!_isVessel && !_isCelestial)
                {
                    _vesselIntersect = false;
                    _bodyIntersect   = false;
                }
                else
                {
                    OrbitTargeter      oTargeter = _activeVessel.orbitTargeter;
                    PatchedConicSolver solver    = _activeVessel.patchedConicSolver;

                    if (oTargeter == null || solver == null)
                    {
                        _vesselIntersect = false;
                        _bodyIntersect   = false;
                    }
                    else if (!MapView.MapIsEnabled)
                    {
                        if (_isVessel)
                        {
                            _bodyIntersect = false;

                            Vessel tgt = _targetObject.GetVessel();

                            if (tgt == null || tgt.LandedOrSplashed)
                            {
                                _vesselIntersect = false;
                                return;
                            }

                            Orbit _refPatch = null;

                            if (solver.maneuverNodes.Count > 0)
                            {
                                _refPatch = GetReferencePatch(oTargeter, solver, target.referenceBody, null, true);
                            }
                            else
                            {
                                _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter);
                            }

                            Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter);

                            _vesselIntersect = GetClosestVessel(_refPatch, _tgtRefPatch);
                        }
                        else
                        {
                            _vesselIntersect = false;

                            double Pe = GetLowestPeA(solver);

                            if (Pe < BasicExtensions.AlmostMaxValue)
                            {
                                _closestDist   = Pe;
                                _bodyIntersect = true;
                            }
                            else
                            {
                                Orbit _refPatch = null;

                                if (solver.maneuverNodes.Count > 0)
                                {
                                    _refPatch = GetReferencePatch(oTargeter, solver, _targetBody, target.referenceBody, false);
                                }
                                else
                                {
                                    _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter);
                                }

                                if (_refPatch != null && _refPatch.closestTgtApprUT <= 0)
                                {
                                    _bodyIntersect = false;
                                    return;
                                }

                                Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter);

                                _bodyIntersect = GetClosestCelestial(_refPatch, _tgtRefPatch);
                            }
                        }
                    }
                    else
                    {
                        if (_markers == null || _markers.Count <= 0)
                        {
                            _markers = BasicOrbitReflection.GetOrbitMarkers(oTargeter);
                        }

                        if (_markers == null || _markers.Count <= 0)
                        {
                            _vesselIntersect = false;
                            _bodyIntersect   = false;
                        }
                        else if (_isVessel)
                        {
                            _bodyIntersect = false;

                            if (solver.maneuverNodes.Count > 0)
                            {
                                Orbit _refPatch    = GetReferencePatch(oTargeter, solver, target.referenceBody, null, true);
                                Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter);

                                _vesselIntersect = GetClosestVessel(_refPatch, _tgtRefPatch);
                            }
                            else
                            {
                                OrbitTargeter.ISectMarker _intersectOne = null;
                                OrbitTargeter.ISectMarker _intersectTwo = null;

                                for (int i = _markers.Count - 1; i >= 0; i--)
                                {
                                    OrbitTargeter.Marker m = _markers[i];

                                    if (m == null)
                                    {
                                        continue;
                                    }

                                    if (!(m is OrbitTargeter.ISectMarker))
                                    {
                                        continue;
                                    }

                                    int num = ((OrbitTargeter.ISectMarker)m).num;

                                    if (num == 1)
                                    {
                                        _intersectOne = m as OrbitTargeter.ISectMarker;
                                    }
                                    else if (num == 2)
                                    {
                                        _intersectTwo = m as OrbitTargeter.ISectMarker;
                                    }
                                }

                                OrbitTargeter.ISectMarker _closestIntersect = null;

                                if (_intersectOne != null && _intersectTwo != null)
                                {
                                    _closestIntersect = _intersectOne.separation > _intersectTwo.separation ? _intersectTwo : _intersectOne;
                                }
                                else if (_intersectOne != null)
                                {
                                    _closestIntersect = _intersectOne;
                                }
                                else if (_intersectTwo != null)
                                {
                                    _closestIntersect = _intersectTwo;
                                }
                                else
                                {
                                    _closestIntersect = null;
                                }

                                if (_closestIntersect == null)
                                {
                                    _vesselIntersect = false;
                                }
                                else
                                {
                                    _vesselIntersect = true;
                                    _closestDist     = _closestIntersect.separation * 1000;
                                    _closestRelVel   = _closestIntersect.relSpeed;
                                    _closestTime     = _closestIntersect.UT;
                                }
                            }
                        }
                        else
                        {
                            _vesselIntersect = false;

                            double Pe = GetLowestPeA(solver);

                            if (Pe < BasicExtensions.AlmostMaxValue)
                            {
                                _closestDist   = Pe;
                                _bodyIntersect = true;
                            }
                            else
                            {
                                if (solver.maneuverNodes.Count > 0)
                                {
                                    Orbit _refPatch    = GetReferencePatch(oTargeter, solver, _targetBody, target.referenceBody, false);
                                    Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter);

                                    _bodyIntersect = GetClosestCelestial(_refPatch, _tgtRefPatch);
                                }
                                else
                                {
                                    OrbitTargeter.ClApprMarker _approach = null;

                                    for (int i = _markers.Count - 1; i >= 0; i--)
                                    {
                                        OrbitTargeter.Marker m = _markers[i];

                                        if (m == null)
                                        {
                                            continue;
                                        }

                                        if (!(m is OrbitTargeter.ClApprMarker))
                                        {
                                            continue;
                                        }

                                        _approach = m as OrbitTargeter.ClApprMarker;
                                    }

                                    if (_approach == null)
                                    {
                                        _bodyIntersect = false;
                                    }
                                    else
                                    {
                                        _bodyIntersect = true;
                                        _closestDist   = _approach.separation * 1000;
                                        _closestTime   = (_approach.dT * -1) + Planetarium.GetUniversalTime();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }