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))); }
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); }
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); }
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); }
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; } }
public EDWaypoint(EDLocation location) { Location = location; if (!String.IsNullOrEmpty(location.Name)) { Name = location.Name; } }
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; }
public EDWaypoint(EDLocation location, double hitRadius, int hitDirection) : this(location) { Radius = hitRadius; Direction = hitDirection; if (!String.IsNullOrEmpty(location.Name)) { Name = location.Name; } }
public EDWaypoint(EDLocation location, DateTime timeTracked, double radius) : this(location) { TimeTracked = timeTracked; Radius = radius; if (!String.IsNullOrEmpty(location.Name)) { Name = location.Name; } }
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); }
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)); }
public EDLocation Location() { if (HasCoordinates()) { EDLocation eventLocation = new EDLocation(Latitude, Longitude, Altitude, PlanetRadius); eventLocation.PlanetName = BodyName; return(eventLocation); } return(null); }
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); }
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()); }
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))); }
public bool Equals(EDLocation location) { if (Latitude != location.Latitude) { return(false); } if (Longitude != location.Longitude) { return(false); } return(true); }
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); }
private bool LocationIsWithinBasicWaypoint(EDLocation location) { if (location.PlanetaryRadius != Location.PlanetaryRadius) { return(false); } if (EDLocation.DistanceBetween(Location, location) < Radius) { return(true); } return(false); }
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); }
public bool Resurrect() { if (Eliminated) { TimeStamp = DateTime.UtcNow; Eliminated = false; DistanceToWaypoint = double.MaxValue; _speedCalculationPreviousLocation = null; AddRaceHistory("Resurrected (elimination manually rescinded)"); return(true); } return(false); }
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); }
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); }
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))); }
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)); }
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); }
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)); }
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; } }
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); }
private void ResetSpeedCalc() { _speedCalculationPreviousLocation = null; _speedCalculationTimeStamp = DateTime.UtcNow; }