Exemple #1
0
        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);
            }
        }
Exemple #2
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);
                }
            }

            vessel.latitude  = latitude;
            vessel.longitude = longitude;
            vessel.altitude  = altitude + vessel.heightFromTerrain;
            return(true);
        }
Exemple #3
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");
        }
        public void SetToActive()
        {
            if (this.vessel.targetObject == null || this.vessel.situation != Vessel.Situations.LANDED)
            {
                return;
            }
            Vessel targetVessel = this.vessel.targetObject.GetVessel();

            if (targetVessel == null)
            {
                ScreenMessages.PostScreenMessage("Target some suitable vessel first!");
                return;
            }

            if (targetVessel.mainBody == this.vessel.mainBody && targetVessel.situation == Vessel.Situations.LANDED)
            {
                Deactivate();
                this.distanceToTarget = GeoUtils.GetDistance(
                    this.vessel.latitude, this.vessel.longitude, targetVessel.latitude, targetVessel.longitude, this.vessel.mainBody.Radius
                    );

                double bearing = GeoUtils.InitialBearing(this.vessel.latitude, this.vessel.longitude, targetVessel.latitude, targetVessel.longitude);
                // We don't want to spawn inside vessel
                if (distanceToTarget == 0)
                {
                    return;
                }
                this.distanceToTarget -= 200;
                double[] newCoordinates = GeoUtils.GetLatitudeLongitude(this.vessel.latitude, this.vessel.longitude, bearing, distanceToTarget, this.vessel.mainBody.Radius);
                this.targetLatitude    = newCoordinates[0];
                this.targetLongitude   = newCoordinates[1];
                this.distanceTravelled = 0;
                FindPath();
            }
            else
            {
                ScreenMessages.PostScreenMessage("Your target is out there somewhere, this won't work!");
            }
        }
Exemple #5
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);
        }
Exemple #6
0
        //[KSPEvent(guiActive = true, guiName = "Set to active target")]
        public void SetToActive()
        {
            if (this.vessel.targetObject == null || this.vessel.situation != Vessel.Situations.LANDED)
            {
                return;
            }

            Vessel targetVessel = this.vessel.targetObject.GetVessel();

            if (targetVessel == null)
            {
                ScreenMessages.PostScreenMessage("Target some suitable vessel first!");
                return;
            }

            if (targetVessel.mainBody == this.vessel.mainBody && targetVessel.situation == Vessel.Situations.LANDED)
            {
                Deactivate();
                double[] newCoordinates =
                    GeoUtils.StepBack(
                        this.vessel.latitude,
                        this.vessel.longitude,
                        targetVessel.latitude,
                        targetVessel.longitude,
                        this.vessel.mainBody.Radius,
                        200
                        );
                this.targetLatitude    = newCoordinates[0];
                this.targetLongitude   = newCoordinates[1];
                this.distanceTravelled = 0;
                FindPath();
            }
            else
            {
                ScreenMessages.PostScreenMessage("Your target is out there somewhere, this won't work!");
            }
        }
Exemple #7
0
        /// <summary>
        /// Update rover.
        /// </summary>
        /// <param name="currentTime">Current time.</param>
        public void Update(double currentTime)
        {
            status2 = "";
            if (vessel.isActiveVessel)
            {
                status = "current";
                return;
            }

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

            Vector3d vesselPos = vessel.mainBody.position - vessel.GetWorldPos3D();
            Vector3d toKerbol  = vessel.mainBody.position - FlightGlobals.Bodies[0].position;

            //double angle = Vector3d.Angle(vesselPos, toKerbol);
            angle = Vector3d.Angle(vesselPos, toKerbol);

            // Speed penalties at twighlight and at night
            if (angle > 90 && isManned)
            {
                speedMultiplier = 0.25;
                status2         = " (night)";
            }
            else if (angle > 85 && isManned)
            {
                speedMultiplier = 0.5;
                status2         = " (twilight)";
            }
            else if (angle > 80 && isManned)
            {
                speedMultiplier = 0.75;
                status2         = " (twilight)";
            }
            else
            {
                speedMultiplier = 1.0;
            }

            // No moving at night, or when there's not enougth solar light for solar powered rovers
            //if (angle > 90 && solarPowered)
            // No moving at night, if there isn't power source
            if ((angle > 90) && (averageSpeedAtNight == 0.0))
            {
                status   = "awaiting sunlight";
                lastTime = currentTime;
                BVModule.SetValue("lastTime", currentTime.ToString());
                return;
            }

            double deltaT = currentTime - lastTime;

            double deltaS  = AverageSpeed * deltaT;
            double bearing = GeoUtils.InitialBearing(
                vessel.latitude,
                vessel.longitude,
                targetLatitude,
                targetLongitude
                );

            distanceTravelled += deltaS;
            if (distanceTravelled >= distanceToTarget)
            {
                if (!MoveSafe(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

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

                    if (BonVoyage.Instance.AutoDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3)
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0)
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " has arrived to destination at " + vessel.mainBody.bodyDisplayName.Replace("^N", ""));
                    }
                    HoneyImHome();
                }
                status = "idle";
            }
            else
            {
                try // There is sometimes exception during scene change to flight scene
                {
                    int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize));
                    double remainder = distanceTravelled % PathFinder.StepSize;

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

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

                    if (!MoveSafe(newCoordinates[0], newCoordinates[1]))
                    {
                        distanceTravelled -= deltaS;
                        status             = "idle";
                    }
                    else
                    {
                        status = "roving";
                    }
                }
                catch { };
            }
            Save(currentTime);
        }
Exemple #8
0
        /// <summary>
        /// Update vessel
        /// </summary>
        /// <param name="currentTime"></param>
        internal override void Update(double currentTime)
        {
            if (vessel == null)
            {
                return;
            }
            if (vessel.isActiveVessel)
            {
                lastTimeUpdated = 0;
                if (active)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_AutopilotActive"), 10f).color = Color.red;
                }
                return;
            }

            if (!active || vessel.loaded)
            {
                return;
            }

            // If we don't know the last time of update, then set it and wait for the next update cycle
            if (lastTimeUpdated == 0)
            {
                State           = VesselState.Idle;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            double deltaT = currentTime - lastTimeUpdated; // Time delta from the last update

            double deltaS = AverageSpeed * deltaT;         // Distance delta from the last update

            distanceTravelled += deltaS;

            if (distanceTravelled >= distanceToTarget) // We reached the target
            {
                if (!MoveSafely(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

                    active  = false;
                    arrived = true;
                    BVModule.SetValue("active", "False");
                    BVModule.SetValue("arrived", "True");
                    BVModule.SetValue("distanceTravelled", distanceToTarget.ToString());
                    BVModule.SetValue("pathEncoded", "");

                    // Dewarp
                    if (Configuration.AutomaticDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_VesselArrived") + " " + vessel.mainBody.bodyDisplayName.Replace("^N", ""), 5f);
                    }

                    NotifyArrival();
                }
                State = VesselState.Idle;
            }
            else
            {
                try                                                                                          // There is sometimes null ref exception during scene change
                {
                    int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize)); // In which step of the path we are
                    double remainder = distanceTravelled % PathFinder.StepSize;                              // Current remaining distance from the current step
                    double bearing   = 0;

                    if (step < path.Count - 1)
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the next step from previous step
                            path[step].latitude,
                            path[step].longitude,
                            path[step + 1].latitude,
                            path[step + 1].longitude
                            );
                    }
                    else
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the target from previous step
                            path[step].latitude,
                            path[step].longitude,
                            targetLatitude,
                            targetLongitude
                            );
                    }

                    // Compute new coordinates, we are moving from the current step, distance is "remainder"
                    double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
                        path[step].latitude,
                        path[step].longitude,
                        bearing,
                        remainder,
                        vessel.mainBody.Radius
                        );

                    // Move
                    if (!MoveSafely(newCoordinates[0], newCoordinates[1]))
                    {
                        distanceTravelled -= deltaS;
                        State              = VesselState.Idle;
                    }
                    else
                    {
                        State = VesselState.Moving;
                    }
                }
                catch { }
            }

            Save(currentTime);
        }
Exemple #9
0
        /// <summary>
        /// Update rover.
        /// </summary>
        /// <param name="currentTime">Current time.</param>
        public void Update(double currentTime)
        {
            if (vessel.isActiveVessel)
            {
                status = "current";
                return;
            }

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

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

            // Speed penalties at twighlight and at night
            if (angle > 90 && isManned)
            {
                speedMultiplier = 0.25;
            }
            else if (angle > 85 && isManned)
            {
                speedMultiplier = 0.5;
            }
            else if (angle > 80 && isManned)
            {
                speedMultiplier = 0.75;
            }
            else
            {
                speedMultiplier = 1.0;
            }

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

            double deltaT = currentTime - lastTime;

            double deltaS  = AverageSpeed * deltaT;
            double bearing = GeoUtils.InitialBearing(
                vessel.latitude,
                vessel.longitude,
                targetLatitude,
                targetLongitude
                );

            distanceTravelled += deltaS;
            if (distanceTravelled >= distanceToTarget)
            {
//				vessel.latitude = targetLatitude;
//				vessel.longitude = targetLongitude;
                if (!MoveSafe(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

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

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

                    if (BonVoyage.Instance.AutoDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3)
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0)
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " has arrived to destination at " + vessel.mainBody.name);
                    }
                    HoneyImHome();
                }
                status = "idle";
            }
            else
            {
                int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize));
                double remainder = distanceTravelled % PathFinder.StepSize;

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

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

//				vessel.latitude = newCoordinates[0];
//				vessel.longitude = newCoordinates[1];
                if (!MoveSafe(newCoordinates [0], newCoordinates [1]))
                {
                    distanceTravelled -= deltaS;
                    status             = "idle";
                }
                else
                {
                    status = "roving";
                }
            }
//			vessel.altitude = GeoUtils.TerrainHeightAt(vessel.latitude, vessel.longitude, vessel.mainBody);
            Save(currentTime);
        }
Exemple #10
0
        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);
            }
        }
Exemple #11
0
 private double Estimate(Hex hex)
 {
     return(GeoUtils.GetDistance(hex.Latitude, hex.Longitude, targetLatitude, targetLongitude, mainBody.Radius));
 }
Exemple #12
0
        /// <summary>
        /// Update vessel
        /// </summary>
        /// <param name="currentTime"></param>
        internal override void Update(double currentTime)
        {
            if (vessel == null)
            {
                return;
            }
            if (vessel.isActiveVessel)
            {
                lastTimeUpdated = 0;
                if (active)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_AutopilotActive"), 10f).color = Color.red;
                }
                return;
            }

            if (!active || vessel.loaded)
            {
                return;
            }

            // If we don't know the last time of update, then set it and wait for the next update cycle
            if (lastTimeUpdated == 0)
            {
                State           = VesselState.Idle;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            Vector3d roverPos   = vessel.mainBody.position - vessel.GetWorldPos3D();
            Vector3d toMainStar = vessel.mainBody.position - FlightGlobals.Bodies[mainStarIndex].position;

            angle = Vector3d.Angle(roverPos, toMainStar); // Angle between rover and the main star

            // Speed penalties at twighlight and at night
            if ((angle > 90) && manned) // night
            {
                speedMultiplier = 0.25;
            }
            else if ((angle > 85) && manned) // twilight
            {
                speedMultiplier = 0.5;
            }
            else if ((angle > 80) && manned) // twilight
            {
                speedMultiplier = 0.75;
            }
            else // day
            {
                speedMultiplier = 1.0;
            }

            // No moving at night, if there isn't enough power
            if ((angle > 90) && (averageSpeedAtNight == 0.0))
            {
                State           = VesselState.AwaitingSunlight;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            double deltaT = currentTime - lastTimeUpdated;
            double deltaS = AverageSpeed * deltaT;

            distanceTravelled += deltaS;

            if (distanceTravelled >= distanceToTarget) // We reached the target
            {
                if (!MoveSafely(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

                    active  = false;
                    arrived = true;
                    BVModule.SetValue("active", "False");
                    BVModule.SetValue("arrived", "True");
                    BVModule.SetValue("distanceTravelled", distanceToTarget.ToString());
                    BVModule.SetValue("pathEncoded", "");

                    // Dewarp
                    if (Configuration.AutomaticDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_VesselArrived") + " " + vessel.mainBody.bodyDisplayName.Replace("^N", ""), 5f);
                    }

                    NotifyArrival();
                }
                State = VesselState.Idle;
            }
            else
            {
                try                                                                                          // There is sometimes null ref exception during scene change
                {
                    int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize)); // In which step of the path we are
                    double remainder = distanceTravelled % PathFinder.StepSize;                              // Current remaining distance from the current step
                    double bearing   = 0;

                    if (step < path.Count - 1)
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the next step from previous step
                            path[step].latitude,
                            path[step].longitude,
                            path[step + 1].latitude,
                            path[step + 1].longitude
                            );
                    }
                    else
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the target from previous step
                            path[step].latitude,
                            path[step].longitude,
                            targetLatitude,
                            targetLongitude
                            );
                    }

                    // Compute new coordinates, we are moving from the current step, distance is "remainder"
                    double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
                        path[step].latitude,
                        path[step].longitude,
                        bearing,
                        remainder,
                        vessel.mainBody.Radius
                        );

                    // Move
                    if (!MoveSafely(newCoordinates[0], newCoordinates[1]))
                    {
                        distanceTravelled -= deltaS;
                        State              = VesselState.Idle;
                    }
                    else
                    {
                        State = VesselState.Moving;
                    }
                }
                catch { }
            }

            Save(currentTime);
        }
        /// <summary>
        /// Update vessel
        /// </summary>
        /// <param name="currentTime"></param>
        internal override void Update(double currentTime)
        {
            if (vessel == null)
            {
                return;
            }
            if (vessel.isActiveVessel)
            {
                lastTimeUpdated = 0;
                if (active)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_AutopilotActive"), 10f).color = Color.red;
                }
                return;
            }

            if (!active || vessel.loaded)
            {
                return;
            }

            // If we don't know the last time of update, then set it and wait for the next update cycle
            if (lastTimeUpdated == 0)
            {
                State           = VesselState.Idle;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            Vector3d roverPos   = vessel.mainBody.position - vessel.GetWorldPos3D();
            Vector3d toMainStar = vessel.mainBody.position - FlightGlobals.Bodies[mainStarIndex].position;

            angle = Vector3d.Angle(roverPos, toMainStar); // Angle between rover and the main star

            // Speed penalties at twighlight and at night
            if ((angle > 90) && manned) // night
            {
                speedMultiplier = 0.25;
            }
            else if ((angle > 85) && manned) // twilight
            {
                speedMultiplier = 0.5;
            }
            else if ((angle > 80) && manned) // twilight
            {
                speedMultiplier = 0.75;
            }
            else // day
            {
                speedMultiplier = 1.0;
            }

            double deltaT     = currentTime - lastTimeUpdated; // Time delta from the last update
            double deltaTOver = 0;                             // deltaT which is calculated from a value over the maximum resource amout available

            // Compute increase or decrease in EC from the last update
            if (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && !DetectKerbalism.Found())
            {
                // Process fuel cells before batteries
                if (!CheatOptions.InfinitePropellant &&
                    fuelCells.Use &&
                    ((angle > 90) ||
                     (batteries.ECPerSecondGenerated - fuelCells.OutputValue <= 0) ||
                     (batteries.CurrentEC < batteries.MaxUsedEC)))     // Night, not enough solar power or we need to recharge batteries
                {
                    if (!((angle > 90) && (batteries.CurrentEC == 0))) // Don't use fuel cells, if it's night and current EC of batteries is zero. This means, that there isn't enough power to recharge them and fuel is wasted.
                    {
                        var iList = fuelCells.InputResources;
                        for (int i = 0; i < iList.Count; i++)
                        {
                            iList[i].CurrentAmountUsed += iList[i].Ratio * deltaT;
                            if (iList[i].CurrentAmountUsed > iList[i].MaximumAmountAvailable)
                            {
                                deltaTOver = Math.Max(deltaTOver, (iList[i].CurrentAmountUsed - iList[i].MaximumAmountAvailable) / iList[i].Ratio);
                            }
                        }
                        if (deltaTOver > 0)
                        {
                            deltaT -= deltaTOver;
                            // Reduce the amount of used resources
                            for (int i = 0; i < iList.Count; i++)
                            {
                                iList[i].CurrentAmountUsed -= iList[i].Ratio * deltaTOver;
                            }
                        }
                    }
                }

                if (angle <= 90) // day
                {
                    batteries.CurrentEC = Math.Min(batteries.CurrentEC + batteries.ECPerSecondGenerated * deltaT, batteries.MaxUsedEC);
                }
                else // night
                {
                    batteries.CurrentEC = Math.Max(batteries.CurrentEC - batteries.ECPerSecondConsumed * deltaT, 0);
                }
            }

            // No moving at night, if there isn't enough power
            if ((angle > 90) && (averageSpeedAtNight == 0.0) && !(batteries.UseBatteries && (batteries.CurrentEC > 0)))
            {
                State           = VesselState.AwaitingSunlight;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            double deltaS = AverageSpeed * deltaT; // Distance delta from the last update

            distanceTravelled += deltaS;

            if (distanceTravelled >= distanceToTarget) // We reached the target
            {
                if (!MoveSafely(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

                    active  = false;
                    arrived = true;
                    BVModule.SetValue("active", "False");
                    BVModule.SetValue("arrived", "True");
                    BVModule.SetValue("distanceTravelled", distanceToTarget.ToString());
                    BVModule.SetValue("pathEncoded", "");

                    // Dewarp
                    if (Configuration.AutomaticDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_VesselArrived") + " " + vessel.mainBody.bodyDisplayName.Replace("^N", ""), 5f);
                    }

                    NotifyArrival();
                }
                State = VesselState.Idle;
            }
            else
            {
                try                                                                                          // There is sometimes null ref exception during scene change
                {
                    int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize)); // In which step of the path we are
                    double remainder = distanceTravelled % PathFinder.StepSize;                              // Current remaining distance from the current step
                    double bearing   = 0;

                    if (step < path.Count - 1)
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the next step from previous step
                            path[step].latitude,
                            path[step].longitude,
                            path[step + 1].latitude,
                            path[step + 1].longitude
                            );
                    }
                    else
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the target from previous step
                            path[step].latitude,
                            path[step].longitude,
                            targetLatitude,
                            targetLongitude
                            );
                    }

                    // Compute new coordinates, we are moving from the current step, distance is "remainder"
                    double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
                        path[step].latitude,
                        path[step].longitude,
                        bearing,
                        remainder,
                        vessel.mainBody.Radius
                        );

                    // Move
                    if (!MoveSafely(newCoordinates[0], newCoordinates[1]))
                    {
                        distanceTravelled -= deltaS;
                        State              = VesselState.Idle;
                    }
                    else
                    {
                        State = VesselState.Moving;
                    }
                }
                catch { }
            }

            Save(currentTime);

            // Stop the rover, we don't have enough of fuel
            if (deltaTOver > 0 ||  (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && batteries.CurrentEC <= 0.1))
            {
                active  = false;
                arrived = true;
                BVModule.SetValue("active", "False");
                BVModule.SetValue("arrived", "True");
                BVModule.SetValue("pathEncoded", "");

                // Dewarp
                if (Configuration.AutomaticDewarp)
                {
                    if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                    {
                        TimeWarp.SetRate(3, true);
                    }
                    if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                    {
                        TimeWarp.SetRate(0, false);
                    }
                    ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_Warning_Stopped") + ".", 5f).color = Color.red;
                }

                if (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && batteries.CurrentEC <= 0.1)
                {
                    NotifyBatteryEmpty();
                }
                else
                {
                    NotifyNotEnoughFuel();
                }

                State = VesselState.Idle;
            }
        }