Esempio n. 1
0
        public void FixedUpdate()
        {
            var vessel = GetComponent <Vessel>();

            if (vessel != FlightGlobals.ActiveVessel)
            {
                Destroy(this);
                return;
            }

            if (TimeWarp.CurrentRateIndex != 0)
            {
                TimeWarp.SetRate(0, true);
                Extensions.Log("Kill time warp for safety reasons!");
            }

            if (AlreadyTeleported)
            {
                if (vessel.LandedOrSplashed)
                {
                    Destroy(this);
                }
                else
                {
                    var accel = (vessel.srf_velocity + vessel.upAxis) * -0.5;
                    vessel.ChangeWorldVelocity(accel);

                    /*
                     * RateLimitedLogger.Log(_accelLogObject,
                     *  $"(Happening every frame) Soft-lander changed ship velocity this frame by vector {accel.x},{accel.y},{accel.z} (mag {accel.magnitude})");
                     */
                }
            }
            else
            {
                //NOT AlreadyTeleported
                //Still calculating
                var pqs = Body.pqsController;
                if (pqs == null)
                {
                    // The sun has no terrain.  Everthing else has a PQScontroller.
                    Destroy(this);
                    return;
                }

                var alt    = pqs.GetSurfaceHeight(Body.GetRelSurfaceNVector(Latitude, Longitude)) - Body.Radius;
                var tmpAlt = Body.TerrainAltitude(Latitude, Longitude);

                double landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude;

                double finalAltitude = 0.0; //trying to isolate this for debugging!

                var    checkAlt    = FlightGlobals.ActiveVessel.altitude;
                var    checkPQSAlt = FlightGlobals.ActiveVessel.pqsAltitude;
                double terrainAlt  = GetTerrainAltitude();

                Extensions.ALog("-------------------");
                Extensions.ALog("m1. Body.Radius  = ", Body.Radius);
                Extensions.ALog("m2. PQS SurfaceHeight = ", pqs.GetSurfaceHeight(Body.GetRelSurfaceNVector(Latitude, Longitude)));
                Extensions.ALog("alt ( m2 - m1 ) = ", alt);
                Extensions.ALog("Body.TerrainAltitude = ", tmpAlt);
                Extensions.ALog("checkAlt    = ", checkAlt);
                Extensions.ALog("checkPQSAlt = ", checkPQSAlt);
                Extensions.ALog("landheight  = ", landHeight);
                Extensions.ALog("terrainAlt  = ", terrainAlt);
                Extensions.ALog("-------------------");
                Extensions.ALog("Latitude: ", Latitude, "Longitude: ", Longitude);
                Extensions.ALog("-------------------");

                alt = Math.Max(alt, 0d); // Make sure we're not underwater!

                // HoldVesselUnpack is in display frames, not physics frames

                Vector3d teleportPosition;

                if (!teleportedToLandingAlt)
                {
                    Extensions.ALog("teleportedToLandingAlt == false");
                    Extensions.ALog("interimAltitude: ", InterimAltitude);
                    Extensions.ALog("Altitude: ", Altitude);

                    if (InterimAltitude > Altitude)
                    {
                        if (Planetarium.GetUniversalTime() - lastUpdate >= 0.5)
                        {
                            InterimAltitude = InterimAltitude / 10;
                            terrainAlt      = GetTerrainAltitude();

                            if (InterimAltitude < terrainAlt)
                            {
                                InterimAltitude = terrainAlt + Altitude;
                            }

                            //InterimAltitude = terrainAlt + Altitude;

                            teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, InterimAltitude) - Body.position;

                            Extensions.ALog("1. teleportPosition = ", teleportPosition);
                            Extensions.ALog("1. interimAltitude: ", InterimAltitude);

                            if (lastUpdate != 0)
                            {
                                InterimAltitude = Altitude;
                            }
                            lastUpdate = Planetarium.GetUniversalTime();
                        }
                        else
                        {
                            Extensions.Log("teleportPositionAltitude (no time change):");

                            teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, alt + InterimAltitude) - Body.position;

                            Extensions.ALog("2. teleportPosition = ", teleportPosition);
                            Extensions.ALog("2. alt: ", alt);
                            Extensions.ALog("2. interimAltitude: ", InterimAltitude);
                        }
                    }
                    else
                    {
                        //InterimAltitude <= Altitude
                        Extensions.Log("3. teleportedToLandingAlt sets to true");

                        landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude;
                        terrainAlt = GetTerrainAltitude();

                        //trying to find the correct altitude here.

                        if (checkPQSAlt > terrainAlt)
                        {
                            alt = checkPQSAlt;
                        }
                        else
                        {
                            alt = terrainAlt;
                        }

                        if (alt == 0.0)
                        {
                            //now what?
                        }

                        /*
                         * landHeight factors into the final altitude somehow. Possibly.
                         */

                        teleportedToLandingAlt = true;
                        //finalAltitude = alt + Altitude;
                        if (alt < 0)
                        {
                            finalAltitude = Altitude;
                        }
                        else if (alt > 0)
                        {
                            finalAltitude = alt + Altitude;
                        }
                        else
                        {
                            finalAltitude = alt + Altitude;
                        }

                        teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, finalAltitude) - Body.position;

                        Extensions.ALog("3. teleportPosition = ", teleportPosition);
                        Extensions.ALog("3. alt = ", alt, "Altitude = ", Altitude, "InterimAltitude = ", InterimAltitude);
                        Extensions.ALog("3. TerrainAlt = ", terrainAlt, "landHeight = ", landHeight);
                    }
                }
                else
                {
                    /*
                     * With the current way of calculating, it seems like this part of the conditional
                     * never gets called. (Well not so far in my (@fronbow) testing.
                     */

                    Extensions.Log("teleportedToLandingAlt == true");

                    landHeight = FlightGlobals.ActiveVessel.altitude - FlightGlobals.ActiveVessel.pqsAltitude;
                    terrainAlt = GetTerrainAltitude();

                    Extensions.ALog("4. finalAltitude = ", finalAltitude);

                    /*
                     * Depending on finalAltitude, we might not need to calculate it again here.
                     */

                    //finalAltitude = alt + Altitude;
                    if (alt < 0)
                    {
                        finalAltitude = Altitude;
                    }
                    else if (alt > 0)
                    {
                        finalAltitude = alt + Altitude;
                    }
                    else
                    {
                        finalAltitude = alt + Altitude;
                    }

                    //teleportPosition = Body.GetRelSurfacePosition(Latitude, Longitude, finalAltitude);
                    teleportPosition = Body.GetWorldSurfacePosition(Latitude, Longitude, finalAltitude) - Body.position;

                    Extensions.ALog("4. teleportPosition = ", teleportPosition);
                    Extensions.ALog("4. alt = ", alt, "Altitude = ", Altitude, "InterimAltitude = ", InterimAltitude);
                    Extensions.ALog("4. TerrainAlt = ", terrainAlt, "landHeight = ", landHeight);
                    Extensions.ALog("4. finalAltitude = ", finalAltitude);
                }

                var teleportVelocity = Vector3d.Cross(Body.angularVelocity, teleportPosition);

                // convert from world space to orbit space

                teleportPosition = teleportPosition.xzy;
                teleportVelocity = teleportVelocity.xzy;

                Extensions.ALog("0. teleportPosition(xzy): ", teleportPosition);
                Extensions.ALog("0. teleportVelocity(xzy): ", teleportVelocity);
                Extensions.ALog("0. Body                 : ", Body);

                // counter for the momentary fall when on rails (about one second)
                teleportVelocity += teleportPosition.normalized * (Body.gravParameter / teleportPosition.sqrMagnitude);

                Quaternion rotation;


                if (SetRotation)
                {
                    // Need to check vessel and find up for the root command pod
                    vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, false); //hopefully this disables SAS as it causes unknown results!

                    var from = Vector3d.up;                                  //Sensible default for all vessels

                    if (vessel.displaylandedAt == "Runway" || vessel.vesselType.ToString() == "Plane")
                    {
                        from = vessel.vesselTransform.up;
                    }


                    var to = teleportPosition.xzy.normalized;
                    rotation = Quaternion.FromToRotation(from, to);
                }
                else
                {
                    var oldUp = vessel.orbit.pos.xzy.normalized;
                    var newUp = teleportPosition.xzy.normalized;
                    rotation = Quaternion.FromToRotation(oldUp, newUp) * vessel.vesselTransform.rotation;
                }

                var orbit = vessel.orbitDriver.orbit.Clone();
                orbit.UpdateFromStateVectors(teleportPosition, teleportVelocity, Body, Planetarium.GetUniversalTime());

                vessel.SetOrbit(orbit);
                vessel.SetRotation(rotation);

                if (teleportedToLandingAlt)
                {
                    AlreadyTeleported = true;
                    Extensions.Log(" :FINISHED TELEPORTING:");
                }
            }
        }