public float RaceTimeBehindNext() { _Racer RacerNext = GetPosionNext(); if (RacerNext == this) { return(0); } if (RacerNext == null) { return(0); } int RacerThisSectorCount = CumulativeSectorTimeStamps.Count(); if (RacerThisSectorCount > RacerNext.CumulativeSectorTimeStamps.Count()) { return(0); } float RacerNextTimestamp = RacerNext.CumulativeSectorTimeStamps[RacerThisSectorCount - 1]; float RacerThisTimestamp = CumulativeSectorTimeStamps[RacerThisSectorCount - 1]; float TimeBehind = RacerThisTimestamp - RacerNextTimestamp; return(TimeBehind); }
public float RaceTimeAheadOfPrev() { _Racer RacerPrev = GetPosionPrev(); if (RacerPrev == this) { return(0); } if (RacerPrev == null) { return(0); } int RacerPrevSectorCount = RacerPrev.CumulativeSectorTimeStamps.Count(); if (CumulativeSectorTimeStamps.Count() < RacerPrevSectorCount) { return(0); } float RacerPrevTimestamp = RacerPrev.CumulativeSectorTimeStamps[RacerPrevSectorCount - 1]; float RacerThisTimestamp = CumulativeSectorTimeStamps[RacerPrevSectorCount - 1]; float TimeAhead = RacerThisTimestamp - RacerPrevTimestamp; return(TimeAhead); }
public _Racer AddRacer(Client ThisClient) { lock (Racers) { _Racer ThisRacer = new _Racer(ThisClient, this); Racers.Add(ThisRacer); return(ThisRacer); } }
public string RaceTimeGetTimeBehindString() { _Racer Next = GetPosionNext(); if (Next == this | Next == null) { return("<ERROR>"); } return("P" + Race.GetPositionOfRacer(Next) + " " + Next.Client.Username.Resize(16).Replace('\0', ' ') + " " + RaceTimeBehindNext().AsFormattedTimeDifference()); }
public string RaceTimeGetTimeAheadString() { _Racer Prev = GetPosionPrev(); if (Prev == this | Prev == null) { return("<ERROR>"); } return("P" + Race.GetPositionOfRacer(Prev) + " " + Prev.Client.Username.Resize(16).Replace('\0', ' ') + " " + RaceTimeAheadOfPrev().AsFormattedTimeDifference()); }
public int GetPositionOfRacer(_Racer ThisRacer) { int Position = 1; try { Position += RacersSortedByPosition.IndexOf(ThisRacer); } catch { Position = 0; } return(Position); }
public Race(List <_Racer> _SortedList) { ID = GetNextRaceID(); int i = 1; foreach (_Racer ThisRacer in _SortedList) { _Racer NewRacer = AddRacer(ThisRacer.Client); if (NewRacer == null) { //race not in stopped state! return; } NewRacer.QualifyingPosition = i; i++; } }
public void CheckIntersections(_Racer ThisRacer) { List <Client> NONRACING = Clients.AllClients.Except(ThisRacer.Race.Racers.Select(x => x.Client)).ToList(); List <Client> RACING = ThisRacer.Race.Racers.Select(x => x.Client).ToList(); if (RaceEnds <= DateTime.Now & Status.IsInProgress() & RaceEnds > RaceStarted) { //The session has timed out! lock (Threads.GenericThreadSafeLock) { if (!Status.IsFinished()) { Status.SetFinished(); } foreach (_Racer DNFRacer in Racers.Where(x => x.CurrentCheckpoint / (Path.Points.Count) < TotalLapCount)) { DNFRacer.Client.SendMessage("RACE OVER ##" + " P" + GetPositionOfRacer(DNFRacer) + " ## RACE OVER"); } } } if (ThisRacer.CurrentLap > TotalLapCount && TotalLapCount > 0) { //stop counting for this racer, they finished the race! return; } Client ThisClient = ThisRacer.Client; Vehicle ThisVehicle = ThisRacer.Client.Vehicle; if (ThisVehicle == Vehicles.NoVehicle) { return; } World.Objects.Path ThisPath = Path; World.Objects.Path._Point ThisPoint; try { ThisPoint = ThisPath.Points[(ThisRacer.CurrentCheckpoint + 1) % ThisPath.Points.Count]; } catch { return; } //Target point will be the next checkpoint the vehicle has to pass! #region Set up the 3D Maths required. //if (!ActiveCheckPoints.Select(x => x.CheckPoint).Contains(ThisPath.Points[0]) & ThisPoint != ThisPath.Points[0]) continue; Math3D.Point3 Previous = new Math3D.Point3(ThisVehicle.Prev_PosX, ThisVehicle.Prev_PosY, ThisVehicle.Prev_PosZ); Math3D.Point3 Current = new Math3D.Point3(ThisVehicle.PosX, ThisVehicle.PosY, ThisVehicle.PosZ); Math3D.Segment3 Segment = new Math3D.Segment3(Previous, Current); Math3D.Point3 Point = new Math3D.Point3(ThisPoint.X, ThisPoint.Y, ThisPoint.Z); double Tolerance = Math3D.Distance(Previous, Current); Tolerance /= (ThisVehicle.TimeStamp - ThisVehicle.Prev_TimeStamp); float HitRadius = (float)ThisVehicle.CachedAircraft.HTRADIUS; if (Tolerance < HitRadius * 5) { Tolerance = HitRadius * 5; } #endregion if (Math3D.DoesSegmentPassNearPoint(Segment, Point, Tolerance)) { int ModulatedCheckPointCount = (ThisRacer.CurrentCheckpoint + 1) % ThisPath.Points.Count; //increment point count! ThisRacer.CurrentCheckpoint++; string CurrentLapTime = "<ERROR>"; string CurrentSplitTime = "<ERROR>"; #region GET SPLIT/LAP TIME //float starttime = ThisRacer.TimeStamp_LastCheckpoint; float endtime = ThisRacer.TimeStamp_LastCheckpoint; float laptime = 0; float splittime = 0; try { double Distance = Math3D.GetPointSegmentDistanceIfIntersecting(Point, Segment); if (Distance == Double.PositiveInfinity | Distance == Double.NegativeInfinity) { //no intersection??? return; } double FractionOfTime = Distance / Segment.Length(); endtime = (float)(FractionOfTime * (ThisVehicle.TimeStamp - ThisVehicle.Prev_TimeStamp)) + ThisVehicle.Prev_TimeStamp; TimeSpan StartLapTimeSpan = new TimeSpan(0, 0, 0, 0, (int)(ThisRacer.TimeStamp_LapStarted * 1000)); TimeSpan StartSplitTimeSpan = new TimeSpan(0, 0, 0, 0, (int)(ThisRacer.TimeStamp_LastCheckpoint * 1000)); TimeSpan EndTimeSpan = new TimeSpan(0, 0, 0, 0, (int)(endtime * 1000)); CurrentLapTime = StartLapTimeSpan.GetTimeDifference(EndTimeSpan); laptime = (float)((EndTimeSpan - StartLapTimeSpan).TotalSeconds); splittime = (float)((EndTimeSpan - StartSplitTimeSpan).TotalSeconds); CurrentSplitTime = StartSplitTimeSpan.GetTimeDifference(EndTimeSpan); } catch { } #endregion if (ThisRacer.CumulativeSectorTimeStamps.Count > 0) { ThisRacer.CumulativeSectorTimeStamps.Add(splittime + ThisRacer.CumulativeSectorTimeStamps.Last()); } else { ThisRacer.CumulativeSectorTimeStamps.Add(splittime); } ThisRacer.SectorTimeStamps.Add(splittime); if (ModulatedCheckPointCount == 0) { //just passed the start/finish line! bool YellowLap = false; bool RedLap = false; if (CurrentLapTime == "00:00:00.000") { return; } float ThisLapTime = laptime; float LapTimeDifference = ThisLapTime - FastestLap; if (ThisRacer.FastestLap == 0) { ThisRacer.FastestLap = ThisLapTime; if (FastestLap == 0) { LapTimeDifference = 0; } else { LapTimeDifference = ThisLapTime - FastestLap; } } string PositionDifference = "<ERROR>"; string LapCountString = "<ERROR>"; if (FastestLap == 0) { //No fastest lap set yet! FastestLap = ThisLapTime; LapTimeDifference = 0; RedLap = true; } if (LapTimeDifference < 0) { //New Circuit Record! FastestLap = ThisLapTime; RedLap = true; NONRACING.SendMessage("&a" + ThisRacer.Client.Username + " Just set a new lap record on " + Path.Identify); NONRACING.SendMessage("&a Using a &3" + ThisRacer.Client.Vehicle.Identify); NONRACING.SendMessage("&a LapTime: &e" + ThisLapTime.AsFormattedTimeDifference().Substring(1) + "&c!"); RACING.Exclude(ThisRacer.Client).SendMessage("&a" + ThisRacer.Client.Username + " New lap record: &e" + ThisLapTime.AsFormattedTimeDifference().Substring(1) + "&c!"); } if (ThisRacer.FastestLap > ThisLapTime) { //New Personal Best! ThisRacer.FastestLap = ThisLapTime; YellowLap = true; } string LapBonusMarker = ""; if (YellowLap) { LapBonusMarker = "[&e+&f]"; } if (RedLap) { LapBonusMarker = "[&c#&f]"; } if (RaceTypeIsTimeTrial()) { LapCountString = "L" + ThisRacer.CurrentLap.ToString() + " P" + GetPositionOfRacer(ThisRacer); PositionDifference = LapTimeDifference.AsFormattedTimeDifference(); ThisClient.SendMessage(LapCountString + " - " + CurrentLapTime + " (" + PositionDifference + ")" + LapBonusMarker); } if (RaceTypeIsRace()) { string LapsRemaining = (TotalLapCount - ThisRacer.CurrentLap).ToString(); if (ThisRacer.CurrentLap < TotalLapCount) { LapCountString = "L" + LapsRemaining + " P" + GetPositionOfRacer(ThisRacer); } else { LapCountString = "P" + GetPositionOfRacer(ThisRacer); } int CurrentPosition = GetPositionOfRacer(ThisRacer); string PosAhead = ""; string PosBehind = ""; if (CurrentPosition != Racers.Count()) //Not Last { PosAhead = ThisRacer.RaceTimeGetTimeAheadString(); } if (CurrentPosition != 1) //Not First { PosBehind = ThisRacer.RaceTimeGetTimeBehindString(); } if (ThisRacer.CurrentLap < TotalLapCount) { ThisClient.SendMessage(LapCountString + " - " + CurrentLapTime + LapBonusMarker); } else { if (GetPositionOfRacer(ThisRacer) == 1) { ThisClient.SendMessage("RACE OVER ## " + LapCountString + " - " + ThisRacer.RaceTimeGetTotalTime() + LapBonusMarker + " ## RACE OVER"); } else { float Time = RacersSortedByPosition[0].RaceTimeGetTotalTime(); float Difference = ThisRacer.RaceTimeGetTotalTime() - Time; string StrDiff = Difference.AsFormattedTimeDifference(); ThisClient.SendMessage("RACE OVER ## " + LapCountString + " - " + ThisRacer.RaceTimeGetTotalTime() + LapBonusMarker + "(" + StrDiff + ")" + " ## RACE OVER"); } } if (PosAhead != "") { ThisClient.SendMessage(" " + PosAhead); } if (PosBehind != "") { ThisClient.SendMessage(" " + PosBehind); } } ThisRacer.TimeStamp_LapStarted = endtime; ThisRacer.TimeStamp_LastCheckpoint = endtime; if (GetPositionOfRacer(ThisRacer) == 1 & ThisRacer.CurrentLap == TotalLapCount & TotalLapCount != 0) { //coming first //completed the last lap //not a 0 lap race... //... Means this racer WON the race! RaceEnds = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(FastestLap * 1000 * 2)); //double the fastest lap time of the race should be plenty of time for the stragglers to catch up! } ThisRacer.CurrentLap++; } else { //normal checkpoint. bool YellowSector = false; bool RedSector = false; #region FastestSectors if (FastestSectors[ModulatedCheckPointCount] == 0) { //no time set for this sector, set it now! FastestSectors[ModulatedCheckPointCount] = splittime; } if (splittime < FastestSectors[ModulatedCheckPointCount]) { //New circuit record sector! FastestSectors[ModulatedCheckPointCount] = splittime; } if (splittime < ThisRacer.FastestSectors[ModulatedCheckPointCount]) { //New personal best sector! ThisRacer.FastestSectors[ModulatedCheckPointCount] = splittime; } #endregion #region CumulativeSectors float Difference = laptime - CumulativeSectors[ModulatedCheckPointCount]; if (CumulativeSectors[ModulatedCheckPointCount] == 0) { //no time set for this sector, set it now! CumulativeSectors[ModulatedCheckPointCount] = laptime; RedSector = true; Difference = 0; } if (laptime < CumulativeSectors[ModulatedCheckPointCount]) { //New circuit record sector! CumulativeSectors[ModulatedCheckPointCount] = laptime; RedSector = true; } if (laptime < ThisRacer.CumulativeSectors[ModulatedCheckPointCount]) { //New personal best sector! ThisRacer.CumulativeSectors[ModulatedCheckPointCount] = laptime; YellowSector = true; } #endregion string StrDiff = Difference.AsFormattedTimeDifference(); string SectorBonusMarker = ""; if (YellowSector) { SectorBonusMarker = "[&e+&f]"; } if (RedSector) { SectorBonusMarker = "[&c#&f]"; } ThisClient.SendMessage("Split " + ModulatedCheckPointCount + " - " + CurrentSplitTime + "(" + StrDiff + ")" + SectorBonusMarker); ThisRacer.TimeStamp_LastCheckpoint = endtime; } } }