コード例 #1
0
        /// <summary>
        /// Save move of a rover. We need to prevent hitting an active vessel.
        /// </summary>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <returns>true if rover was moved, false otherwise</returns>
        private bool MoveSafely(double latitude, double longitude)
        {
            double altitude = GeoUtils.TerrainHeightAt(latitude, longitude, vessel.mainBody);

            if (FlightGlobals.ActiveVessel != null)
            {
                Vector3d newPos   = vessel.mainBody.GetWorldSurfacePosition(latitude, longitude, altitude);
                Vector3d actPos   = FlightGlobals.ActiveVessel.GetWorldPos3D();
                double   distance = Vector3d.Distance(newPos, actPos);
                if (distance <= 2400)
                {
                    return(false);
                }
            }

            vessel.latitude  = latitude;
            vessel.longitude = longitude;
            if (vessel.situation == Vessel.Situations.SPLASHED)
            {
                vessel.altitude = vesselHeightFromTerrain;
            }
            else
            {
                vessel.altitude = altitude + vesselHeightFromTerrain;
            }

            return(true);
        }
コード例 #2
0
        public double StraightPath()
        {
            double distanceToTarget = GeoUtils.GetDistance(startLatitude, startLongitude, targetLatitude, targetLongitude, mainBody.Radius);
//			if (distanceToTarget < 1000) return;
            double bearing  = GeoUtils.InitialBearing(startLatitude, startLongitude, targetLatitude, targetLongitude);
            double altitude = GeoUtils.TerrainHeightAt(startLatitude, startLongitude, mainBody);
            int    x        = 0;
            int    y        = 0;
            Hex    start    = new Hex(startLatitude, startLongitude, altitude, bearing, x, y, this);

            tiles.Add(start);

            double straightPath = 0;

            //			ScreenMessages.PostScreenMessage ("building straight " + DateTime.Now.ToString());
            while (straightPath < distanceToTarget - 500)
            {
                GetNeighbours(x, y, false);
                Hex current = tiles.Find(t => (t.X == x && t.Y == y));
                x += directions [0].X;
                y += directions [0].Y;
                Hex next = tiles.Find(t => (t.X == x && t.Y == y));
                if (next.Altitude < 0 ||
                    ((next.Altitude - current.Altitude) > 500) ||
                    ((next.Altitude - current.Altitude) < -500))
                {
                    return(0);
                }
                straightPath += 1000;
            }
            Hex destination = tiles.Find(t => (t.X == x + directions [180].X) && (t.Y == y + directions [180].Y));

            return(distanceToTarget);
        }
コード例 #3
0
        /// <summary>
        /// Find path to the target
        /// </summary>
        internal void FindPath()
        {
            double distanceToTarget = GeoUtils.GetDistance(startLatitude, startLongitude, targetLatitude, targetLongitude, mainBody.Radius);

            if (distanceToTarget < StepSize)
            {
                return;
            }

            double bearing  = GeoUtils.InitialBearing(startLatitude, startLongitude, targetLatitude, targetLongitude);
            double altitude = GeoUtils.TerrainHeightAt(startLatitude, startLongitude, mainBody);
            int    x        = 0;
            int    y        = 0;
            Hex    start    = new Hex(startLatitude, startLongitude, altitude, bearing, x, y, this);

            tiles.Add(start);

            double straightPath = 0;

            while (straightPath < distanceToTarget)
            {
                GetNeighbours(x, y, false);
                x            += directions[0].X;
                y            += directions[0].Y;
                straightPath += StepSize;
            }
            Hex destination = tiles.Find(t => (t.X == x + directions[180].X) && (t.Y == y + directions[180].Y));

            path = Path <Hex> .FindPath <Hex>(start, destination, distance, estimate);
        }
コード例 #4
0
        /// <summary>
        /// Decodes the path.
        /// </summary>
        /// <returns>The path.</returns>
        /// <param name="pathEncoded">Path encoded.</param>
        /// <param name="body">Body.</param>
        internal static List <Vector3d> DecodePath(string pathEncoded, CelestialBody body)
        {
            List <Vector3d> result = new List <Vector3d> ();

            if (pathEncoded == null || pathEncoded.Length == 0)
            {
                return(result);
            }

            // Path is compressed, decompress
            // For compatibility purposes only
            if (!pathEncoded.Contains(";"))
            {
                pathEncoded = LZString.decompressFromBase64(pathEncoded);
            }

            char[]   separators = new char[] { ';' };
            string[] wps        = pathEncoded.Split(separators, StringSplitOptions.RemoveEmptyEntries);

            foreach (var wp in wps)
            {
                string[] latlon          = wp.Split(':');
                double   latitude        = double.Parse(latlon [0]);
                double   longitude       = double.Parse(latlon [1]);
                double   altitude        = GeoUtils.TerrainHeightAt(latitude, longitude, body);
                Vector3d localSpacePoint = body.GetWorldSurfacePosition(latitude, longitude, altitude);
                result.Add(localSpacePoint);
            }

            return(result);
        }
コード例 #5
0
        internal IEnumerable <Hex> GetNeighbours(int x, int y, bool passable = true)
        {
            var tile = tiles.Find(t => (t.X == x) && (t.Y == y));

            if (tile == null)
            {
                return(null);
            }

            List <Hex> neighbours = new List <Hex>();

            foreach (var direction in directions)
            {
                int dirX      = direction.Value.X;
                int dirY      = direction.Value.Y;
                var neighbour = tiles.Find(n => (n.X == tile.X + dirX) && (n.Y == tile.Y + dirY));
                if (neighbour == null)
                {
                    double[] coords     = GeoUtils.GetLatitudeLongitude(tile.Latitude, tile.Longitude, tile.Bearing + direction.Key, StepSize, mainBody.Radius);
                    double   newBearing = GeoUtils.FinalBearing(tile.Latitude, tile.Longitude, coords[0], coords[1]);
                    newBearing = (newBearing - direction.Key + 360) % 360;
                    double altitude = GeoUtils.TerrainHeightAt(coords[0], coords[1], mainBody);
                    neighbour = new Hex(coords[0], coords[1], altitude, newBearing, tile.X + dirX, tile.Y + dirY, this);
                }
                neighbours.Add(neighbour);
                tiles.Add(neighbour);
            }
            if (passable)
            {
                switch (tileTypes)
                {
                case TileTypes.Land | TileTypes.Ocean:
                    return(neighbours.Where(
                               n =>
                               ((n.Altitude - tile.Altitude) < StepSize / 2) &&
                               ((n.Altitude - tile.Altitude) > 0 - StepSize / 2)
                               ));

                case TileTypes.Land:
                    return(neighbours.Where(
                               n => (n.Altitude >= 0 || !mainBody.ocean) &&
                               ((n.Altitude - tile.Altitude) < StepSize / 2) &&
                               ((n.Altitude - tile.Altitude) > 0 - StepSize / 2)
                               ));

                case TileTypes.Ocean:
                    return(neighbours.Where(
                               n => (n.Altitude <= 0)
                               ));

                default:
                    return(neighbours);
                }
            }
            else
            {
                return(neighbours);
            }
        }
コード例 #6
0
ファイル: PathUtils.cs プロジェクト: yadenisyur/KSP-BonVoyage
        /// <summary>
        /// Decodes the path.
        /// </summary>
        /// <returns>The path.</returns>
        /// <param name="pathEncoded">Path encoded.</param>
        /// <param name="body">Body.</param>
        internal static List <Vector3d> DecodePath(string pathEncoded, CelestialBody body)
        {
            List <Vector3d> result = new List <Vector3d> ();

            if (pathEncoded == null || pathEncoded.Length == 0)
            {
                return(result);
            }

            // Path is compressed, decompress
            // For compatibility purposes only
            if (!pathEncoded.Contains(";"))
            {
                //pathEncoded = LZString.decompressFromBase64(pathEncoded);

                // Change LZString implementation of base64 to native functions
                // Replace # with forward slash (two forward slashes seems to be interpreted as a start of the comment when read from a save file)
                string temp         = pathEncoded;
                var    encodedBytes = System.Convert.FromBase64String(temp.Replace('#', '/'));
                temp = System.Text.Encoding.UTF8.GetString(encodedBytes);
                if (temp.Contains(":")) // backward compatibility for path encoded with LZString
                {
                    pathEncoded = temp;
                }
                else
                {
                    pathEncoded = LZString.decompressFromBase64(pathEncoded);
                }
            }

            char[]   separators = new char[] { ';' };
            string[] wps        = pathEncoded.Split(separators, StringSplitOptions.RemoveEmptyEntries);

            foreach (var wp in wps)
            {
                string[] latlon          = wp.Split(':');
                double   latitude        = double.Parse(latlon [0]);
                double   longitude       = double.Parse(latlon [1]);
                double   altitude        = GeoUtils.TerrainHeightAt(latitude, longitude, body);
                Vector3d localSpacePoint = body.GetWorldSurfacePosition(latitude, longitude, altitude);
                result.Add(localSpacePoint);
            }

            return(result);
        }
コード例 #7
0
ファイル: PathFinder.cs プロジェクト: ntwest/KSP-BonVoyage
        internal IEnumerable <Hex> GetNeighbours(int x, int y, bool passable = true)
        {
            //			Debug.Log (String.Format("bonvoyage - finding neighbours for {0}, {1}", x, y));
            var tile = tiles.Find(t => (t.X == x) && (t.Y == y));

            if (tile == null)
            {
                //				Debug.Log ("bonvoyage - tile not found");
                return(null);
            }
            List <Hex> neighbours = new List <Hex> ();

            foreach (var direction in directions)
            {
                int dirX      = direction.Value.X;
                int dirY      = direction.Value.Y;
                var neighbour = tiles.Find(n => (n.X == tile.X + dirX) && (n.Y == tile.Y + dirY));
                if (neighbour == null)
                {
                    //					Debug.Log ("bonvoyage - neighbour not found");
                    double[] coords     = GeoUtils.GetLatitudeLongitude(tile.Latitude, tile.Longitude, tile.Bearing + direction.Key, StepSize, mainBody.Radius);
                    double   newBearing = GeoUtils.FinalBearing(tile.Latitude, tile.Longitude, coords [0], coords [1]);
                    newBearing = (newBearing - direction.Key + 360) % 360;
                    double altitude = GeoUtils.TerrainHeightAt(coords [0], coords [1], mainBody);
                    neighbour = new Hex(coords [0], coords [1], altitude, newBearing, tile.X + dirX, tile.Y + dirY, this);
                }
                neighbours.Add(neighbour);
                tiles.Add(neighbour);
            }
            if (passable)
            {
                return(neighbours.Where(
                           n => (n.Altitude >= 0 || !mainBody.ocean) &&
                           ((n.Altitude - tile.Altitude) < StepSize / 2) &&
                           ((n.Altitude - tile.Altitude) > 0 - StepSize / 2)
                           ));
            }
            else
            {
                return(neighbours);
            }
        }
コード例 #8
0
        public void FindPath()
        {
            double distanceToTarget = GeoUtils.GetDistance(startLatitude, startLongitude, targetLatitude, targetLongitude, mainBody.Radius);

            if (distanceToTarget < 1000)
            {
                return;
            }
            double bearing  = GeoUtils.InitialBearing(startLatitude, startLongitude, targetLatitude, targetLongitude);
            double altitude = GeoUtils.TerrainHeightAt(startLatitude, startLongitude, mainBody);
            int    x        = 0;
            int    y        = 0;
            Hex    start    = new Hex(startLatitude, startLongitude, altitude, bearing, x, y, this);

            tiles.Add(start);

            double straightPath = 0;

//			ScreenMessages.PostScreenMessage ("building straight " + DateTime.Now.ToString());
            while (straightPath < distanceToTarget - 500)
            {
                GetNeighbours(x, y, false);
                x            += directions [0].X;
                y            += directions [0].Y;
                straightPath += 1000;
            }
            Hex destination = tiles.Find(t => (t.X == x + directions [180].X) && (t.Y == y + directions [180].Y));

/*			KSP.IO.File.AppendAllText<BonVoyage> (
 *                              //				String.Format("lat: {0}\nlon: {1}\nbea: {2}\n----\n", this.latitude, this.longitude, this.bearing),
 *                              String.Format("start: {0}, destination: {1}\n----\n", start.Id, destination.Id),
 *                              "path"
 *                      );*/

//			ScreenMessages.PostScreenMessage ("started caclulation " + DateTime.Now.ToString());
            path = Path <Hex> .FindPath <Hex> (start, destination, distance, estimate);

            ScreenMessages.PostScreenMessage("Path build");
        }
コード例 #9
0
        /// <summary>
        /// Prevent crazy torpedoing active vessel :D
        /// </summary>
        /// <returns><c>true</c>, if rover was moved, <c>false</c> otherwise.</returns>
        /// <param name="latitude">Latitude.</param>
        /// <param name="longitude">Longitude.</param>
        private bool MoveSafe(double latitude, double longitude)
        {
            double altitude = GeoUtils.TerrainHeightAt(latitude, longitude, vessel.mainBody);

            if (FlightGlobals.ActiveVessel != null)
            {
                Vector3d newPos   = vessel.mainBody.GetWorldSurfacePosition(latitude, longitude, altitude);
                Vector3d actPos   = FlightGlobals.ActiveVessel.GetWorldPos3D();
                double   distance = Vector3d.Distance(newPos, actPos);
                if (distance <= 2400)
                {
                    return(false);
                }
//				VesselRanges ranges = active.vesselRanges.GetSituationRanges(Vessel.Situations.LANDED || Vessel.Situations.FLYING);
//				vessel.GoOffRails ();
//				vessel.Load ();
            }

            vessel.latitude  = latitude;
            vessel.longitude = longitude;
            vessel.altitude  = altitude;
            return(true);
        }
コード例 #10
0
ファイル: BonVoyage.cs プロジェクト: ayan4m1/KSP-BonVoyage
        public void Update()
        {
            if (lastUpdated.AddSeconds(1) > DateTime.Now)
            {
                return;
            }

            lastUpdated = DateTime.Now;

            double currentTime = Planetarium.GetUniversalTime();

            foreach (var rover in activeRovers)
            {
                if (rover.vessel.isActiveVessel)
                {
                    rover.status = "current";
                    continue;
                }

                if (!rover.bvActive || rover.vessel.loaded)
                {
                    rover.status = "idle";
                    continue;
                }

                Vector3d vesselPos = rover.vessel.mainBody.position - rover.vessel.GetWorldPos3D();
                Vector3d toKerbol  = rover.vessel.mainBody.position - FlightGlobals.Bodies[0].position;
                double   angle     = Vector3d.Angle(vesselPos, toKerbol);

                // No moving at night, or when there's not enougth solar light
                if (angle >= 85 && rover.solarPowered)
                {
                    rover.status   = "awaiting sunlight";
                    rover.lastTime = currentTime;
                    rover.BVModule.SetValue("lastTime", currentTime.ToString());
                    rover.vessel.protoVessel = new ProtoVessel(rover.vesselConfigNode, HighLogic.CurrentGame);
                    continue;
                }

                double deltaT = currentTime - rover.lastTime;

                double deltaS  = rover.averageSpeed * deltaT;
                double bearing = GeoUtils.InitialBearing(
                    rover.vessel.latitude,
                    rover.vessel.longitude,
                    rover.targetLatitude,
                    rover.targetLongitude
                    );
                rover.distanceTravelled += deltaS;
                if (rover.distanceTravelled >= rover.distanceToTarget)
                {
                    rover.distanceTravelled = rover.distanceToTarget;
                    rover.vessel.latitude   = rover.targetLatitude;
                    rover.vessel.longitude  = rover.targetLongitude;

                    rover.bvActive = false;
                    rover.BVModule.SetValue("isActive", "False");
                    rover.BVModule.SetValue("distanceTravelled", rover.distanceToTarget.ToString());

                    rover.BVModule.GetNode("EVENTS").GetNode("Activate").SetValue("active", "True");
                    rover.BVModule.GetNode("EVENTS").GetNode("Deactivate").SetValue("active", "False");

                    if (autoDewarp)
                    {
                        TimeWarp.SetRate(0, false);
                        ScreenMessages.PostScreenMessage(rover.vessel.vesselName + " has arrived to destination at " + rover.vessel.mainBody.name);
                    }

                    MessageSystem.Message message = new MessageSystem.Message(
                        "Rover arrived",
                        //------------------------------------------
                        rover.vessel.vesselName + " has arrived to destination\nLAT:" +
                        rover.targetLatitude.ToString("F2") + "\nLON:" + rover.targetLongitude.ToString("F2") +
                        "\nAt " + rover.vessel.mainBody.name + ". \n" +
                        "Distance travelled: " + rover.distanceTravelled.ToString("N") + " meters",
                        //------------------------------------------
                        MessageSystemButton.MessageButtonColor.GREEN,
                        MessageSystemButton.ButtonIcons.COMPLETE
                        );
                    MessageSystem.Instance.AddMessage(message);
                    rover.status = "idle";
                }
                else
                {
                    int    step      = Convert.ToInt32(Math.Floor(rover.distanceTravelled / 1000));
                    double remainder = rover.distanceTravelled % 1000;

                    if (step < rover.path.Count - 1)
                    {
                        bearing = GeoUtils.InitialBearing(
                            rover.path[step].latitude,
                            rover.path[step].longitude,
                            rover.path[step + 1].latitude,
                            rover.path[step + 1].longitude
                            );
                    }
                    else
                    {
                        bearing = GeoUtils.InitialBearing(
                            rover.path[step].latitude,
                            rover.path[step].longitude,
                            rover.targetLatitude,
                            rover.targetLongitude
                            );
                    }

                    double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
                        rover.path[step].latitude,
                        rover.path[step].longitude,
                        bearing,
                        remainder,
                        rover.vessel.mainBody.Radius
                        );

                    rover.vessel.latitude  = newCoordinates[0];
                    rover.vessel.longitude = newCoordinates[1];
                    rover.status           = "roving";
                }
                rover.vessel.altitude = GeoUtils.TerrainHeightAt(rover.vessel.latitude, rover.vessel.longitude, rover.vessel.mainBody);
//				rover.toTravel = rover.distanceToTarget - rover.distanceTravelled;
                rover.lastTime = currentTime;

                // Save data to protovessel
                rover.vesselConfigNode.SetValue("lat", rover.vessel.latitude.ToString());
                rover.vesselConfigNode.SetValue("lon", rover.vessel.longitude.ToString());
                rover.vesselConfigNode.SetValue("alt", rover.vessel.altitude.ToString());
                rover.vesselConfigNode.SetValue("landedAt", rover.vessel.mainBody.theName);
                rover.BVModule.SetValue("distanceTravelled", (rover.distanceTravelled).ToString());
                rover.BVModule.SetValue("lastTime", currentTime.ToString());
                rover.vessel.protoVessel = new ProtoVessel(rover.vesselConfigNode, HighLogic.CurrentGame);
            }
        }