Beispiel #1
0
                public CheckPointDescriptor(Vehicle _ThisVehicle, World.Objects.Path._Point _CheckPoint)
                {
                    CheckPoint = _CheckPoint;
                    Vehicle    = _ThisVehicle;
                    World.Objects.Path._Point ThisPoint = _CheckPoint;
                    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;
                    }
                    if (Math3D.DoesSegmentPassNearPoint(Segment, Point, Tolerance))
                    {
                        Math3D.Point3 ClosestPoint = Math3D.GetPointSegmentClosestPointIfIntersecting(Point, Segment);
                        if (ClosestPoint == null)
                        {
                            //Doesn't even intersect! Let's say it crossed this point at the last second!
                            TimeStamp = _ThisVehicle.TimeStamp;
                        }
                        else
                        {
                            //Does intersect! find the exact millisecond the intersection took place!
                            double Numerator          = Math3D.Distance(Previous, ClosestPoint);
                            double Denominator        = Math3D.Distance(Previous, Current);
                            float  TimeSpanDifference = _ThisVehicle.TimeStamp - _ThisVehicle.Prev_TimeStamp;
                            TimeStamp = _ThisVehicle.Prev_TimeStamp + (float)((Numerator / Denominator) * TimeSpanDifference);
                        }
                    }
                }
Beispiel #2
0
            public static void CheckIntersections(Client ThisClient)
            {
                Vehicle ThisVehicle = ThisClient.Vehicle;

                if (ThisVehicle == Vehicles.NoVehicle)
                {
                    return;
                }
                for (int j = 0; j < World.Objects.PathList.Count; j++)
                {
                    World.Objects.Path ThisPath = World.Objects.PathList[j];
                    for (int k = ThisPath.Points.Count - 1; k >= 0; k--)
                    {
                        #region Segment Testings Maths...
                        World.Objects.Path._Point ThisPoint = ThisPath.Points[k];
                        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))
                        {
                            lock (ActiveCheckPoints)
                            {
                                List <World.Objects.Path._Point> Intersection = ActiveCheckPoints.Select(x => x.CheckPoint).Intersect(ThisPath.Points).ToList();
                                if (ThisPath.Points.Count > Intersection.Count)
                                {
                                    if (ThisPath.Points[Intersection.Count] == ThisPoint) //Allow to go forwards or backwards on the track!
                                    {
                                        #region Add the new point.
                                        ActiveCheckPoints.Add(new CheckPointDescriptor(ThisVehicle, ThisPoint));
                                        #endregion
                                        #region Update the data-set intersection
                                        Intersection = ActiveCheckPoints.Select(x => x.CheckPoint).Intersect(ThisPath.Points).ToList();
                                        #endregion
                                        #region GET SPLIT TIME
                                        string SplitTimeResult = "<ERROR>";
                                        try
                                        {
                                            float starttime = 0;
                                            float endtime   = 0;

                                            if (ActiveCheckPoints.Count > 0)
                                            {
                                                starttime = ActiveCheckPoints.Where(x => x.Vehicle == ThisVehicle).Where(y => y.CheckPoint == Intersection[0]).ToArray()[0].TimeStamp;
                                                endtime   = ActiveCheckPoints.Where(x => x.Vehicle == ThisVehicle).Where(y => y.CheckPoint == ThisPoint).ToArray()[0].TimeStamp;
                                            }
                                            else
                                            {
                                                starttime = ThisVehicle.TimeStamp;
                                                endtime   = ThisVehicle.TimeStamp;
                                            }

                                            TimeSpan StartTimeSpan = new TimeSpan(0, 0, 0, 0, (int)(starttime * 1000));
                                            TimeSpan EndTimeSpan   = new TimeSpan(0, 0, 0, 0, (int)(endtime * 1000));
                                            TimeSpan LapTime       = EndTimeSpan - StartTimeSpan;
                                            string   Hours         = LapTime.Hours.ToString();
                                            while (Hours.Length < 2)
                                            {
                                                Hours = "0" + Hours;
                                            }
                                            if (Hours.Length > 2)
                                            {
                                                Hours = "99";
                                            }

                                            string Minutes = LapTime.Minutes.ToString();
                                            while (Minutes.Length < 2)
                                            {
                                                Minutes = "0" + Minutes;
                                            }
                                            if (Minutes.Length > 2)
                                            {
                                                Minutes = "99";
                                            }

                                            string Seconds = LapTime.Seconds.ToString();
                                            while (Seconds.Length < 2)
                                            {
                                                Seconds = "0" + Seconds;
                                            }
                                            if (Seconds.Length > 2)
                                            {
                                                Seconds = "99";
                                            }

                                            string Milliseconds = LapTime.Milliseconds.ToString();
                                            while (Milliseconds.Length < 3)
                                            {
                                                Milliseconds = "0" + Milliseconds;
                                            }
                                            if (Milliseconds.Length > 3)
                                            {
                                                Milliseconds = "999";
                                            }

                                            SplitTimeResult = Hours + ":" + Minutes + ":" + Seconds + "." + Milliseconds;
                                        }
                                        catch
                                        {
                                        }
                                        #endregion
                                        if (SplitTimeResult == "00:00:00.000")
                                        {
                                            continue;                                    //ThisClient.SendMessage(ThisPath.Identify + " Split " + (k - 1) + " -  " + SplitTimeResult);
                                        }
                                        else
                                        {
                                            if (ThisPoint == ThisPath.Points[ThisPath.Points.Count - 1] & Intersection.Count == ThisPath.Points.Count) //Finish Line!
                                            {
                                                ThisClient.SendMessage("[" + ThisPath.Identify + "]" + " Lap - " + SplitTimeResult);
                                            }
                                            else
                                            {
                                                ThisClient.SendMessage("[" + ThisPath.Identify + "]" + " Split " + k + " - " + SplitTimeResult);
                                            }
                                        }
                                    }
                                }
                                if (ThisPoint == ThisPath.Points[ThisPath.Points.Count - 1] & Intersection.Count == ThisPath.Points.Count)
                                {
                                    ActiveCheckPoints.OrderBy(x => x.TimeStamp);
                                    foreach (World.Objects.Path._Point ThisUnionPoint in Intersection)
                                    {
                                        CheckPointDescriptor CheckPointToRemove = ActiveCheckPoints.Where(x => x.CheckPoint == ThisUnionPoint).Where(y => y.Vehicle == ThisVehicle).ToArray()[0];
                                        ActiveCheckPoints.Remove(CheckPointToRemove);
                                    }
                                    Intersection = ActiveCheckPoints.Select(x => x.CheckPoint).Intersect(ThisPath.Points).ToList(); //need to update this!
                                }
                                if (ThisPoint == ThisPath.Points[0] & Intersection.Count == 1)
                                {
                                    //ThisClient.SendMessage("START LAP" + ActiveCheckPoints.Count.ToString());
                                    //ActiveCheckPoints.Add(new CheckPointDescriptor(ThisVehicle, ThisPoint));
                                    //continue;
                                    //k = 0;  //Restart the check, we may have passed another checkpoint a second ago!
                                }
                            }
                        }
                    }
                }
            }
                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;
                        }
                    }
                }