示例#1
0
        public static bool PassedBetween(EDLocation GatePost1, EDLocation GatePost2, EDLocation PreviousLocation, EDLocation CurrentLocation)
        {
            // Work out if the line from previous location to this one passed through the defined gate
            // We convert to x/y/z, and then just use the x and y.  This will be inaccurate, but should be good enough

            return(doLinesIntersect(new Point(GatePost1), new Point(GatePost2), new Point(PreviousLocation), new Point(CurrentLocation)));
        }
示例#2
0
        public bool WaypointHit(EDLocation currentLocation, EDLocation previousLocation, EDLocation previousWaypointLocation = null)
        {
            // Used for testing all waypoint types

            if (MaximumAltitude > 0 && currentLocation.Altitude > MaximumAltitude)
            {
                return(false);
            }
            if (currentLocation.Altitude < MinimumAltitude)
            {
                return(false);
            }

            if (!ExtendedWaypointInformation.ContainsKey("WaypointType"))
            {
                // This is a basic waypoint
                bool waypointHit = LocationIsWithinBasicWaypoint(currentLocation);
                if (!waypointHit && AllowPassing && previousWaypointLocation != null)
                {
                    waypointHit = WaypointIsBehind(currentLocation, EDLocation.BearingToLocation(previousWaypointLocation, Location));
                }
                return(waypointHit);
            }

            switch (ExtendedWaypointInformation["WaypointType"])
            {
            case "Gate":     // This type of waypoint requires the target to pass between two points
                return(GateHit(currentLocation, previousLocation));
            }
            return(false);
        }
示例#3
0
        private void CalculateDistances(bool force = false)
        {
            if (!force && Waypoints.Count == _distanceLeftAtWaypoint.Count)
            {
                return;
            }

            _distanceLeftAtWaypoint = new List <double>();
            _waypointDistances      = new List <double>();
            _totalWaypointDistance  = 0;
            if (Waypoints.Count < 2)
            {
                return;
            }

            for (int i = 0; i < Waypoints.Count - 1; i++)
            {
                _waypointDistances.Add(EDLocation.DistanceBetween(Waypoints[i].Location, Waypoints[i + 1].Location));
                _totalWaypointDistance += _waypointDistances[i];
            }

            _distanceLeftAtWaypoint.Add(_totalWaypointDistance);
            for (int i = 0; i < Waypoints.Count - 1; i++)
            {
                _distanceLeftAtWaypoint.Add(_distanceLeftAtWaypoint[i] - _waypointDistances[i]);
            }
        }
        public static List <EDWaypoint> PoleToPole(double PlanetaryRadius, int WaypointSeparationDistance, double StartLatitude = 0, double StartLongitude = 0)
        {
            List <EDWaypoint> waypoints = new List <EDWaypoint>();
            int numberOfWaypoints       = Convert.ToInt32(Circumference(PlanetaryRadius) / Convert.ToDouble(WaypointSeparationDistance));

            if (numberOfWaypoints > 1000)
            {
                return(null);
            }

            double anglePerWaypoint = 360 / (double)numberOfWaypoints;
            int    waypointRadius   = WaypointSeparationDistance / 2;

            if (waypointRadius > 1000)
            {
                waypointRadius = 1000;
            }

            for (int i = 0; i < numberOfWaypoints; i++)
            {
                double thisLatitude = StartLatitude + (anglePerWaypoint * i);
                if (thisLatitude > 180)
                {
                    thisLatitude -= 360;
                }
                else if (thisLatitude < -180)
                {
                    thisLatitude += 360;
                }
                EDLocation thisLocation = new EDLocation(thisLatitude, StartLongitude, 0, PlanetaryRadius);
                waypoints.Add(new EDWaypoint(thisLocation, DateTime.UtcNow, waypointRadius));
            }
            return(waypoints);
        }
示例#5
0
        private bool CalculateDistances(EDLocation CurrentLocation)
        {
            double distanceTravelled = EDLocation.DistanceBetween(_lastLocation, CurrentLocation);

            CurrentHeading = (int)EDLocation.BearingToLocation(_lastLocation, CurrentLocation);
            _telemetry["CurrentHeading"] = $"{CurrentHeading}°";
            _lastLocation = CurrentLocation;

            // Sanity check to avoid silly readings
            if (_lastDistanceMeasurement < 40 && distanceTravelled > 100)
            {
                return(false);
            }
            if (_lastDistanceMeasurement > 40)
            {
                if (distanceTravelled > (_lastDistanceMeasurement * 2))
                {
                    return(false);
                }
            }

            _lastDistanceMeasurement             = distanceTravelled;
            TotalDistanceTravelled              += distanceTravelled;
            _telemetry["TotalDistanceTravelled"] = EDLocation.DistanceToString(TotalDistanceTravelled);
            _telemetry["DistanceFromStart"]      = EDLocation.DistanceToString(EDLocation.DistanceBetween(SessionStartLocation, CurrentLocation));
            return(true);
        }
示例#6
0
        private void InitLapCalculations()
        {
            if (Laps < 1)
            {
                return;
            }

            // For lap calculations, we need to work out the total length of the course
            _lapLength    = Route.TotalDistanceLeftAtWaypoint(0);
            _preLapLength = 0;
            if (LapStartWaypoint > 0)
            {
                // We have custom laps, so need to work out lap length differently
                _preLapLength = _lapLength - Route.TotalDistanceLeftAtWaypoint(LapStartWaypoint - 1);
                _lapLength    = _lapLength - Route.TotalDistanceLeftAtWaypoint(LapEndWaypoint - 1) - _preLapLength;
                _distanceFromLastLapWPToFirst = EDLocation.DistanceBetween(Route.Waypoints[LapEndWaypoint - 1].Location, Route.Waypoints[LapStartWaypoint - 1].Location);
                _postLapLength = Route.TotalDistanceLeftAtWaypoint(LapEndWaypoint - 1);
            }
            else
            {
                _distanceFromLastLapWPToFirst = EDLocation.DistanceBetween(Route.Waypoints[Route.Waypoints.Count - 1].Location, Route.Waypoints[0].Location);
            }
            _lapLength += _distanceFromLastLapWPToFirst;
            if (LapStartWaypoint > 0)
            {
                _totalRaceDistance = (_lapLength * Laps) + _preLapLength + _postLapLength;
            }
            else
            {
                _totalRaceDistance = _lapLength * Laps;
            }
        }
示例#7
0
 public EDWaypoint(EDLocation location)
 {
     Location = location;
     if (!String.IsNullOrEmpty(location.Name))
     {
         Name = location.Name;
     }
 }
示例#8
0
        private void CalculateSpeed()
        {
            TimeSpan timeBetweenLocations = TimeStamp.Subtract(_speedCalculationTimeStamp);

            if (timeBetweenLocations.TotalMilliseconds > 750)
            {
                // We take a speed calculation once every 750 milliseconds

                double speedInMS = 0;
                if (_speedCalculationPreviousLocation != null)
                {
                    double distanceBetweenLocations = EDLocation.DistanceBetween(_speedCalculationPreviousLocation, Location);
                    speedInMS = distanceBetweenLocations * 1000 / (double)timeBetweenLocations.TotalMilliseconds;
                    if (isFlagSet(StatusFlags.In_SRV) && (speedInMS - _lastSpeedInMs) > 200 && (timeBetweenLocations.TotalMilliseconds < 3000))
                    {
                        // If the speed increases by more than 200m/s in three seconds, this is most likely due to respawn (i.e. invalid)
                        speedInMS = 0;
                        _speedCalculationPreviousLocation = null;
                    }
                    else
                    {
                        _speedCalculationPreviousLocation = Location.Copy();
                        _speedCalculationTimeStamp        = TimeStamp;
                    }
                }
                else
                {
                    _speedCalculationPreviousLocation = Location.Copy();
                    _speedCalculationTimeStamp        = TimeStamp;
                }

                // Update the total average speed
                _totalOfSpeedReadings += speedInMS;
                _numberOfSpeedReadings++;
                AverageSpeedInMS = _totalOfSpeedReadings / _numberOfSpeedReadings;

                _lastThreeSpeedReadings[_oldestSpeedReading] = speedInMS;
                _oldestSpeedReading++;
                if (_oldestSpeedReading > 2)
                {
                    _oldestSpeedReading = 0;
                }
                SpeedInMS = (_lastThreeSpeedReadings[0] + _lastThreeSpeedReadings[1] + _lastThreeSpeedReadings[2]) / 3; // Returning an average of the last three readings should prevent blips
            }

            if (SpeedInMS > MaxSpeedInMS)
            {
                MaxSpeedInMS = SpeedInMS;
                if (MaxSpeedInMS > _lastLoggedMaxSpeed + 5)
                {
                    AddRaceHistory($"New maximum speed: {MaxSpeedInMS:F1}m/s");
                    _lastLoggedMaxSpeed = MaxSpeedInMS;
                }
            }

            _lastSpeedInMs = SpeedInMS;
        }
示例#9
0
 public EDWaypoint(EDLocation location, double hitRadius, int hitDirection) : this(location)
 {
     Radius    = hitRadius;
     Direction = hitDirection;
     if (!String.IsNullOrEmpty(location.Name))
     {
         Name = location.Name;
     }
 }
示例#10
0
 public EDWaypoint(EDLocation location, DateTime timeTracked, double radius) : this(location)
 {
     TimeTracked = timeTracked;
     Radius      = radius;
     if (!String.IsNullOrEmpty(location.Name))
     {
         Name = location.Name;
     }
 }
示例#11
0
        private bool ProcessLocationUpdate(EDEvent edEvent)
        {
            EDLocation currentLocation = edEvent.Location();

            if (currentLocation == null)
            {
                return(false);
            }

            if (SessionStartLocation == null)
            {
                SessionStartLocation = currentLocation;
            }

            _telemetry["CurrentAltitude"] = EDLocation.DistanceToString(edEvent.Altitude);
            if ((int)edEvent.Altitude > MaximumAltitude)
            {
                MaximumAltitude = (int)edEvent.Altitude;
                _telemetry["MaximumAltitude"] = EDLocation.DistanceToString(MaximumAltitude);
            }
            else if (!_playerIsInSRV && (int)edEvent.Altitude < MinimumAltitude)
            {
                MinimumAltitude = (int)edEvent.Altitude;
                _telemetry["MinimumAltitude"] = EDLocation.DistanceToString(MinimumAltitude);
            }



            if (_lastLocation == null)
            {
                _lastLocation = currentLocation;
                return(false);
            }
            if (_lastLocation.Latitude.Equals(currentLocation.Latitude) && _lastLocation.Longitude.Equals(currentLocation.Longitude))
            {
                return(false);
            }

            _telemetry["CurrentLatitude"]  = currentLocation.Latitude.ToString();
            _telemetry["CurrentLongitude"] = currentLocation.Longitude.ToString();

            // Update distance/speed statistics
            if (CalculateDistances(currentLocation))
            {
                CalculateSpeed(currentLocation, edEvent.TimeStamp);
                if (SessionStartTime == DateTime.MinValue)
                {
                    // We set session start time on first detected movement
                    SessionStartTime = DateTime.UtcNow;
                    _telemetry["SessionStartTime"] = SessionStartTime.ToString("HH:mm:ss");
                    _telemetry["SessionDate"]      = SessionStartTime.ToShortDateString();
                }
                return(true);
            }
            return(false);
        }
示例#12
0
 private bool GateHit(EDLocation currentLocation, EDLocation previousLocation)
 {
     //  We need to test if the line between current and last location intersects
     // the line of the gate
     if (AdditionalLocations.Count < 2 || AdditionalLocations[0] == null || previousLocation == null)
     {
         return(false);
     }
     return(EDLocation.PassedBetween(AdditionalLocations[0], AdditionalLocations[1], previousLocation, currentLocation));
 }
示例#13
0
 public EDLocation Location()
 {
     if (HasCoordinates())
     {
         EDLocation eventLocation = new EDLocation(Latitude, Longitude, Altitude, PlanetRadius);
         eventLocation.PlanetName = BodyName;
         return(eventLocation);
     }
     return(null);
 }
示例#14
0
        private void ProcessFlags()
        {
            if (Flags < 1)
            {
                return;
            }

            if (_race != null && !(_race.SRVAllowed && _race.FighterAllowed && _race.ShipAllowed && _race.FeetAllowed))
            {
                // Not all locomotion is allowed, so check that the current one is valid
                if (isFlagSet(StatusFlags.In_SRV) || isFlagSet(StatusFlags.In_MainShip) || isFlagSet(StatusFlags.In_Fighter))
                {
                    // We have a valid vehicle flag, so check the vehicle is allowed
                    bool vehicleDisallowed = false;
                    if (!_race.SRVAllowed && isFlagSet(StatusFlags.In_SRV))
                    {
                        vehicleDisallowed = true;
                    }
                    if (!_race.ShipAllowed && isFlagSet(StatusFlags.In_MainShip))
                    {
                        if (_race.AllowPitstops)
                        {
                            vehicleDisallowed = !isFlagSet(StatusFlags.Landed_on_planet_surface) && !isFlagSet(StatusFlags.Docked_on_a_landing_pad);
                        }
                        else
                        {
                            vehicleDisallowed = true;
                        }
                    }
                    if (!_race.FighterAllowed && isFlagSet(StatusFlags.In_Fighter))
                    {
                        vehicleDisallowed = true;
                    }

                    if (vehicleDisallowed && !Eliminated)
                    {
                        Eliminate("Commander using invalid mode of transport");
                        DistanceToWaypoint = double.MaxValue;
                        SpeedInMS          = 0;
                        _speedCalculationPreviousLocation = null;
                    }
                }
            }

            if (_inPits)
            {
                if (isFlagSet(StatusFlags.In_SRV) && !isFlagSet(StatusFlags.Srv_UnderShip))
                {
                    _inPits = false;
                }
            }

            _lowFuel = isFlagSet(StatusFlags.Low_Fuel);
        }
示例#15
0
        private void InitSession()
        {
            CurrentGroundSpeed     = 0;
            _numberOfSpeedReadings = 0;
            _totalOfSpeedReadings  = 0;
            AverageGroundSpeed     = 0;
            MaximumGroundSpeed     = 0;
            MaximumAltitude        = 0;
            MinimumAltitude        = int.MaxValue;
            SpeedAltitudeAdjusted  = 0;
            TotalDistanceTravelled = 0;
            TotalShipRepairs       = 0;
            TotalSynthRepairs      = 0;
            _lastLocation          = null;
            SessionStartTime       = DateTime.MinValue;
            SessionStartLocation   = null;
            TotalSRVsDestroyed     = 0;

            string commanderName = "";

            if (_telemetry.ContainsKey("CommanderName"))
            {
                commanderName = _telemetry["CommanderName"];
            }

            _telemetry.Clear();
            _telemetry.Add("CommanderName", commanderName);
            _telemetry.Add("CurrentGroundSpeed", "0 m/s");
            _telemetry.Add("CurrentHeading", "Unknown");
            _telemetry.Add("HullStrength", $"{(HullHealth * 100).ToString("F1")}%");
            _telemetry.Add("Pips", String.Join(",", Pips));
            _telemetry.Add("Shield", "Unknown");
            _telemetry.Add("CargoScoop", "Unknown");
            _telemetry.Add("AverageGroundSpeed", "0 m/s");
            _telemetry.Add("MaximumGroundSpeed", "0 m/s");
            _telemetry.Add("DistanceFromStart", "0");
            _telemetry.Add("TotalDistanceTravelled", "0");
            _telemetry.Add("TotalShipRepairs", "0");
            _telemetry.Add("TotalSynthRepairs", "0");
            _telemetry.Add("TotalSRVsDestroyed", "0");
            _telemetry.Add("SessionStartTime", "");
            _telemetry.Add("SessionDate", "");
            _telemetry.Add("SessionTime", "00:00:00");
            _telemetry.Add("CurrentAltitude", "0");
            _telemetry.Add("MaximumAltitude", "NA");
            _telemetry.Add("MinimumAltitude", "NA");
            _telemetry.Add("CurrentLatitude", "NA");
            _telemetry.Add("CurrentLongitude", "NA");
            _telemetry.Add("SpeedAltitudeAdjusted", SpeedAltitudeAdjusted.ToString());
            _telemetry.Add("MaximumSpeedAltitudeAdjusted", MaximumSpeedAltitudeAdjusted.ToString());

            SessionHistory.Clear();
            _srvTelemetryDisplay?.UpdateTargetData(Telemetry());
        }
示例#16
0
        public static double BearingToLocation(EDLocation sourceLocation, EDLocation targetLocation)
        {
            double dLon = (ConvertToRadians(targetLocation.Longitude - sourceLocation.Longitude));
            double dPhi = Math.Log(
                Math.Tan(ConvertToRadians(targetLocation.Latitude) / 2 + Math.PI / 4) / Math.Tan(ConvertToRadians(sourceLocation.Latitude) / 2 + Math.PI / 4));

            if (Math.Abs(dLon) > Math.PI)
            {
                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
            }
            return(ConvertToBearing(Math.Atan2(dLon, dPhi)));
        }
示例#17
0
 public bool Equals(EDLocation location)
 {
     if (Latitude != location.Latitude)
     {
         return(false);
     }
     if (Longitude != location.Longitude)
     {
         return(false);
     }
     return(true);
 }
示例#18
0
        public double TotalDistanceLeftAtWaypoint(int WaypointIndex, int Lap)
        {
            if (Lap > Laps)
            {
                return(0);
            }

            double distanceLeft = 0;

            if (LapStartWaypoint == 0)
            {
                if (Lap < 1)
                {
                    return(_lapLength * Laps);
                }
                distanceLeft = _lapLength * (Laps - Lap);
                if (WaypointIndex > 0)
                {
                    distanceLeft += Route.TotalDistanceLeftAtWaypoint(WaypointIndex) + _distanceFromLastLapWPToFirst;
                }
                return(distanceLeft);
            }

            // Custom laps
            if (Lap == 0) // We haven't reached the start lap waypoint yet
            {
                distanceLeft = _totalRaceDistance;
                for (int i = 1; i < WaypointIndex; i++)
                {
                    distanceLeft -= EDLocation.DistanceBetween(Route.Waypoints[i - 1].Location, Route.Waypoints[i].Location);
                }
                return(distanceLeft);
            }
            if (Lap == Laps)
            {
                // Last lap, so we can just use distance left at waypoint
                return(Route.TotalDistanceLeftAtWaypoint(WaypointIndex));
            }

            distanceLeft = (_lapLength * (Laps - Lap));

            if (WaypointIndex < LapEndWaypoint - 1)
            {
                distanceLeft += _postLapLength;
                for (int i = WaypointIndex + 1; i < LapEndWaypoint; i++)
                {
                    distanceLeft += EDLocation.DistanceBetween(Route.Waypoints[i - 1].Location, Route.Waypoints[i].Location);
                }
            }

            return(distanceLeft);
        }
示例#19
0
        private bool LocationIsWithinBasicWaypoint(EDLocation location)
        {
            if (location.PlanetaryRadius != Location.PlanetaryRadius)
            {
                return(false);
            }
            if (EDLocation.DistanceBetween(Location, location) < Radius)
            {
                return(true);
            }

            return(false);
        }
示例#20
0
            public Point(EDLocation location)
            {
                double planetaryRadius = location.PlanetaryRadius;

                if (planetaryRadius < 1)
                {
                    planetaryRadius = 1;
                }

                x = planetaryRadius * (double)Math.Cos((double)location.Latitude) * (double)Math.Cos((double)location.Longitude);
                y = planetaryRadius * (double)Math.Cos((double)location.Latitude) * (double)Math.Sin((double)location.Longitude);
                z = planetaryRadius * (double)Math.Sin((double)location.Latitude);
            }
示例#21
0
 public bool Resurrect()
 {
     if (Eliminated)
     {
         TimeStamp          = DateTime.UtcNow;
         Eliminated         = false;
         DistanceToWaypoint = double.MaxValue;
         _speedCalculationPreviousLocation = null;
         AddRaceHistory("Resurrected (elimination manually rescinded)");
         return(true);
     }
     return(false);
 }
示例#22
0
        private bool CalculateSpeed(EDLocation CurrentLocation, DateTime TimeStamp)
        {
            if (_speedCalculationPreviousLocation == null)
            {
                _speedCalculationPreviousLocation = CurrentLocation;
                _speedCalculationTimeStamp        = TimeStamp;
                return(false);
            }

            TimeSpan timeBetweenLocations = TimeStamp.Subtract(_speedCalculationTimeStamp);

            if (timeBetweenLocations.TotalMilliseconds < 750)
            {
                return(false);
            }
            // We take a speed calculation once every 750 milliseconds

            double distanceBetweenLocations = EDLocation.DistanceBetween(_speedCalculationPreviousLocation, CurrentLocation);//EDLocation.DistanceBetweenIncludingAltitude(_speedCalculationPreviousLocation, CurrentLocation);

            if (_speedCalculationPreviousLocation.Altitude != CurrentLocation.Altitude)
            {
                double distanceWithAltitudeAdjustment = Math.Sqrt(Math.Pow(distanceBetweenLocations, 2) + Math.Pow(Math.Abs(_speedCalculationPreviousLocation.Altitude - CurrentLocation.Altitude), 2));
                SpeedAltitudeAdjusted = Convert.ToInt32((distanceWithAltitudeAdjustment * 1000) / (double)timeBetweenLocations.TotalMilliseconds);
                _telemetry["SpeedAltitudeAdjusted"] = $"{SpeedAltitudeAdjusted.ToString()} m/s";
                if (SpeedAltitudeAdjusted > MaximumSpeedAltitudeAdjusted)
                {
                    MaximumSpeedAltitudeAdjusted = SpeedAltitudeAdjusted;
                    _telemetry["MaximumSpeedAltitudeAdjusted"] = $"{MaximumSpeedAltitudeAdjusted.ToString()} m/s";
                }
            }
            double speedInMS = (distanceBetweenLocations * 1000) / (double)timeBetweenLocations.TotalMilliseconds;

            _speedCalculationPreviousLocation = CurrentLocation;
            _speedCalculationTimeStamp        = TimeStamp;

            // Update the total average speed
            _totalOfSpeedReadings += speedInMS;
            _numberOfSpeedReadings++;
            AverageGroundSpeed = (int)(_totalOfSpeedReadings / _numberOfSpeedReadings);
            _telemetry["AverageGroundSpeed"] = $"{AverageGroundSpeed} m/s";

            CurrentGroundSpeed = (int)speedInMS;
            _telemetry["CurrentGroundSpeed"] = $"{CurrentGroundSpeed} m/s";
            if (CurrentGroundSpeed > MaximumGroundSpeed)
            {
                MaximumGroundSpeed = CurrentGroundSpeed;
                _telemetry["MaximumGroundSpeed"] = $"{MaximumGroundSpeed} m/s";
            }
            return(true);
        }
示例#23
0
        public bool WaypointIsBehind(EDLocation location, double DirectionOfTravel)
        {
            // Checks whether the waypoint is behind the given location (given the direction of travel)
            // This allows moving on to the next waypoint even if we don't go through one

            double bearingToWaypoint   = EDLocation.BearingToLocation(location, Location);
            double directionOfWaypoint = EDLocation.BearingDelta(bearingToWaypoint, DirectionOfTravel);

            if (Math.Abs(directionOfWaypoint) > 90)
            {
                return(true);
            }
            return(false);
        }
示例#24
0
        public static double DistanceBetweenIncludingAltitude(EDLocation location1, EDLocation location2)
        {
            if (location1.PlanetaryRadius != location2.PlanetaryRadius)
            {
                return(0);
            }

            double R = (double)location1.PlanetaryRadius;

            if (R <= 0)
            {
                return(0);
            }

            return(Math.Sqrt(Math.Pow(DistanceBetween(location1, location2), 2) + Math.Pow(Math.Abs(location1.Altitude - location2.Altitude), 2)));
        }
示例#25
0
        public static EDLocation LocationFrom(EDLocation SourceLocation, double Bearing, double Distance)
        {
            // Return the location that is the specified distance away from source location at the given bearing

            double r = (double)SourceLocation.PlanetaryRadius;

            if (r < 1)
            {
                return(null);
            }
            double lat1 = ConvertToRadians(SourceLocation.Latitude);
            double lon1 = ConvertToRadians(SourceLocation.Longitude);


            double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos((double)Distance / r) + Math.Cos(lat1) * Math.Sin((double)Distance / r) * Math.Cos((double)Bearing));
            double lon2 = lon1 + Math.Atan2(Math.Sin((double)Bearing) * Math.Sin((double)Distance / r) * Math.Cos(lat1),
                                            Math.Cos((double)Distance / r) - Math.Sin(lat1) * Math.Sin(lat2));

            return(new EDLocation(ConvertToDegrees(lat2), ConvertToDegrees(lon2), 0, SourceLocation.PlanetaryRadius));
        }
示例#26
0
        private bool ProcessLocationUpdate(EDEvent edEvent)
        {
            EDLocation currentLocation = edEvent.Location();

            if (currentLocation == null)
            {
                return(false);
            }

            if (SessionStartLocation == null)
            {
                SessionStartLocation = currentLocation;
            }

            _telemetry["CurrentAltitude"] = EDLocation.DistanceToString(edEvent.Altitude);
            if ((int)edEvent.Altitude > MaximumAltitude)
            {
                MaximumAltitude = (int)edEvent.Altitude;
                _telemetry["MaximumAltitude"] = EDLocation.DistanceToString(MaximumAltitude);
            }

            if (_lastLocation == null)
            {
                _lastLocation    = currentLocation;
                SessionStartTime = edEvent.TimeStamp;
                return(false);
            }
            if (_lastLocation.Latitude.Equals(currentLocation.Latitude) && _lastLocation.Longitude.Equals(currentLocation.Longitude))
            {
                return(false);
            }

            // Update distance/speed statistics
            if (CalculateDistances(currentLocation))
            {
                CalculateSpeed(currentLocation, edEvent.TimeStamp);
                return(true);
            }
            return(false);
        }
示例#27
0
        public static double DistanceBetween(EDLocation location1, EDLocation location2)
        {
            if (location1 == null || location2 == null || location1.PlanetaryRadius != location2.PlanetaryRadius)
            {
                return(0);
            }

            double R = location1.PlanetaryRadius;

            if (R <= 0)
            {
                return(0);
            }

            double latDelta = ConvertToRadians(location2.Latitude - location1.Latitude);
            double lonDelta = ConvertToRadians(location2.Longitude - location1.Longitude);
            double h1       = Math.Sin(latDelta / 2) * Math.Sin(latDelta / 2) +
                              Math.Cos(ConvertToRadians(location1.Latitude)) * Math.Cos(ConvertToRadians(location2.Latitude)) *
                              Math.Sin(lonDelta / 2) * Math.Sin(lonDelta / 2);
            double h2 = (double)(2 * Math.Asin(Math.Min(1, Math.Sqrt(h1))));

            return(Math.Abs(R * h2));
        }
示例#28
0
        private void ProcessLocationChange()
        {
            if (_race == null)
            {
                return;
            }

            if (!_race.WaypointsMustBeVisitedInOrder)
            {
                ProcessUnorderedRouteLocationChange();
                return;
            }

            DistanceToWaypoint = EDLocation.DistanceBetween(Location, _race.Route.Waypoints[WaypointIndex].Location);

            int lapStartWaypoint = _race.LapStartWaypoint - 1;

            if (_race.Laps == 0)
            {
                TotalDistanceLeft = _race.Route.TotalDistanceLeftAtWaypoint(WaypointIndex) + DistanceToWaypoint;
            }
            else
            {
                // Total distance left needs to take into account the laps
                TotalDistanceLeft = _race.TotalDistanceLeftAtWaypoint(WaypointIndex, Lap) + DistanceToWaypoint;
                if (lapStartWaypoint < 0)
                {
                    lapStartWaypoint = 0;
                }
            }
            if ((_race.Leader == null) || (TotalDistanceLeft < _race.Leader.TotalDistanceLeft))
            {
                _race.Leader = this;
            }

            EDWaypoint previousWaypoint = null;

            if (WaypointIndex > 0)
            {
                previousWaypoint = _race.Route.Waypoints[WaypointIndex - 1];
            }
            else if (_race.Laps > 0)
            {
                previousWaypoint = _race.Route.Waypoints[_race.Route.Waypoints.Count - 1];
            }

            if (_race.Route.Waypoints[WaypointIndex].WaypointHit(Location, _previousLocation, previousWaypoint?.Location))
            {
                // Commander has reached the target waypoint
                NumberOfWaypointsVisited++;
                if (_race.Laps > 0)
                {
                    if (WaypointIndex != lapStartWaypoint)
                    {
                        AddRaceHistory($"Arrived at {_race.Route.Waypoints[WaypointIndex].Name} (lap {Lap})");
                    }
                    else
                    {
                        // We're at the start waypoint, so have completed a lap
                        DateTime lapEndTime = TimeStamp;
                        LapEndTimes.Add(lapEndTime);
                        TimeSpan thisLapTime = lapEndTime.Subtract(LapStartTime);
                        LapTimes.Add(thisLapTime);
                        LapStartTime = lapEndTime;
                        string lapTime = $"{thisLapTime:hh\\:mm\\:ss}";

                        if (Lap == 1)
                        {
                            FastestLap = 1;
                        }
                        else if (thisLapTime < FastestLapTime())
                        {
                            FastestLap = Lap;
                        }

                        Lap++;

                        // We've only finished if this lap number is greater than the number of laps
                        if (Lap > _race.Laps)
                        {
                            Finished = true;
                            if (!Eliminated)
                            {
                                FinishTime = DateTime.UtcNow;
                                string raceTime = $"{FinishTime.Subtract(StartTime):hh\\:mm\\:ss}";
                                notableEvents?.AddStatusEvent("CompletedNotification", Commander, $" ({raceTime})");
                                AddRaceHistory($"Completed in {raceTime}");
                            }
                            WaypointIndex      = 0;
                            DistanceToWaypoint = 0;
                        }
                        else if (!Eliminated)
                        {
                            notableEvents?.AddStatusEvent("CompletedLap", Commander, $" {Lap - 1} ({lapTime})");
                            AddRaceHistory($"Completed lap {Lap - 1} in {lapTime}");
                        }
                        if (Lap > 2 && FastestLap == Lap - 1)
                        {
                            notableEvents?.AddStatusEvent("FastestLapNotification", Commander, lapTime);
                        }
                    }
                }
                else
                {
                    AddRaceHistory($"Arrived at {_race.Route.Waypoints[WaypointIndex].Name}");
                }

                WaypointIndex++;

                if ((_race.Laps > 0) && (WaypointIndex > _race.LapEndWaypoint) && (Lap <= _race.Laps))
                {
                    WaypointIndex = lapStartWaypoint;
                }
                else if (WaypointIndex >= _race.Route.Waypoints.Count)
                {
                    if (!Eliminated)
                    {
                        Finished   = true;
                        FinishTime = DateTime.UtcNow;
                        string raceTime = $"{FinishTime.Subtract(StartTime):hh\\:mm\\:ss}";
                        notableEvents?.AddStatusEvent("CompletedNotification", Commander, $" ({raceTime})");
                        AddRaceHistory($"Completed in {raceTime}");
                        WaypointIndex      = 0;
                        DistanceToWaypoint = 0;
                    }
                }
            }

            if (DistanceToWaypoint < _nextLogDistanceToWaypoint)
            {
                AddRaceHistory($"{(DistanceToWaypoint / 1000):F1}km to {_race.Route.Waypoints[WaypointIndex].Name}");
                _nextLogDistanceToWaypoint = DistanceToWaypoint - 5000;
            }
        }
示例#29
0
        public void UpdateStatus(EDEvent updateEvent)
        {
            // Update our status based on the passed event

            if (updateEvent.TimeStamp > DateTime.MinValue)
            {
                TimeStamp = updateEvent.TimeStamp;
            }

            if (Finished)  // We keep tracking when eliminated in case of mistake (racers can be restored)
            {
                return;
            }

            if ((updateEvent.Flags > 0) && (Flags != updateEvent.Flags))
            {
                _lastFlags = Flags;
                Flags      = updateEvent.Flags;
            }
            Flags2 = updateEvent.Flags2;

            Pips    = (byte[])updateEvent.Pips.Clone();
            Heading = updateEvent.Heading;

            if (updateEvent.Health >= 0)
            {
                Hull = updateEvent.Health;
                AddRaceHistory($"Hull percentage: {Hull*100:F1}");
            }

            if (updateEvent.HasCoordinates())
            {
                _previousLocation = Location;
                Location          = updateEvent.Location();
                ProcessLocationChange();
                CalculateSpeed();
            }

            if (!Started)
            {
                return;
            }

            ProcessFlags();

            switch (updateEvent.EventName)
            {
            case "SRVDestroyed":
                ProcessSRVDestroyedEvent();
                break;

            case "FighterDestroyed":
                ProcessFighterDestroyedEvent();
                break;

            case "ShipTargeted":
                ProcessShipTargetedEvent(updateEvent);
                break;

            case "Touchdown":
                ProcessTouchdownEvent(updateEvent);
                break;

            case "Liftoff":
                _lastTouchDown = DateTime.MinValue;
                break;

            case "DockSRV":
                ProcessDockSRVEvent(updateEvent);
                break;

            case "LaunchSRV":
                ProcessLaunchSRVEvent();
                break;

            case "Synthesis":
                ProcessSynthesisEvent(updateEvent);
                break;
            }

            GenerateStatus();
            if (_status.Equals(_lastStatus))
            {
                return;
            }

            AddRaceHistory(_status);
            _lastStatus = _status;
            StatusChanged?.Invoke(null, Commander, _status);
        }
示例#30
0
 private void ResetSpeedCalc()
 {
     _speedCalculationPreviousLocation = null;
     _speedCalculationTimeStamp        = DateTime.UtcNow;
 }