示例#1
0
 // so far, only the laps remaining is populated for non-race sessions. This is a bit of an edge case anyway - non-race sessions
 // with fixed number of laps is an American thing really.
 public virtual void populateDerivedNonRaceSessionData(GameStateData currentGameState)
 {
     if (!currentGameState.SessionData.SessionHasFixedTime)
     {
         currentGameState.SessionData.SessionLapsRemaining = currentGameState.SessionData.SessionNumberOfLaps - currentGameState.SessionData.CompletedLaps;
     }
 }
示例#2
0
        // This method populates data derived from the mapped data, that's common to all games.
        // This is specific to race sessions. At the time of writing there's nothing needed for qual and
        // practice, but these may be added later
        public virtual void populateDerivedRaceSessionData(GameStateData currentGameState)
        {
            Boolean singleClass = GameStateData.NumberOfClasses == 1 || CrewChief.forceSingleClass;

            // always set the session start class position and lap start class position:
            if (currentGameState.SessionData.JustGoneGreen || currentGameState.SessionData.IsNewSession)
            {
                // NOTE: on new session, ClassPosition in rF2 is not correct.  It is updated with a bit of a delay.
                // Since this code triggers on JustGoneGreen as well, this is corrected at that point, but I am not yet sure
                // there are no bad side effects.
                currentGameState.SessionData.SessionStartClassPosition = currentGameState.SessionData.ClassPosition;
                if (singleClass)
                {
                    currentGameState.SessionData.NumCarsInPlayerClassAtStartOfSession = currentGameState.SessionData.NumCarsOverallAtStartOfSession;
                }
            }
            if (currentGameState.SessionData.JustGoneGreen)
            {
                currentGameState.SessionData.JustGoneGreenTime = currentGameState.Now;
            }
            if (currentGameState.SessionData.IsNewLap)
            {
                currentGameState.SessionData.ClassPositionAtStartOfCurrentLap = currentGameState.SessionData.ClassPosition;
            }

            float PitApproachPosition = currentGameState.SessionData.TrackDefinition != null ? currentGameState.SessionData.TrackDefinition.distanceForNearPitEntryChecks : -1;

            // sort out all the class position stuff
            int numCarsInPlayerClass = 1;
            int leaderLapsCompleted  = currentGameState.SessionData.CompletedLaps;

            foreach (OpponentData opponent in currentGameState.OpponentData.Values)
            {
                if (!opponent.IsActive)
                {
                    continue;
                }
                if (opponent.OverallPosition == 1)
                {
                    leaderLapsCompleted = opponent.CompletedLaps;
                }
                if (singleClass || CarData.IsCarClassEqual(opponent.CarClass, currentGameState.carClass))
                {
                    // special hack for iRacing until we finally kill those bastard opponent pitting spam messages
                    int minSecondsBetweenOpponentPitMessages = CrewChief.gameDefinition.gameEnum == GameEnum.IRACING ? 40 : 20;
                    // don't care about other classes
                    numCarsInPlayerClass++;
                    if (PitApproachPosition != -1 &&
                        opponent.DistanceRoundTrack < PitApproachPosition + 20 &&
                        opponent.DistanceRoundTrack > PitApproachPosition - 20)
                    {
                        opponent.PositionOnApproachToPitEntry = opponent.ClassPosition;
                    }
                    if (opponent.ClassPosition == 1)
                    {
                        if (opponent.ClassPositionAtPreviousTick != 1)
                        {
                            currentGameState.SessionData.HasLeadChanged = true;
                        }
                        currentGameState.SessionData.LeaderSectorNumber = opponent.CurrentSectorNumber;
                        if (opponent.JustEnteredPits && currentGameState.Now > nextLeaderPitMessageDue)
                        {
                            nextLeaderPitMessageDue = currentGameState.Now.AddSeconds(minSecondsBetweenOpponentPitMessages);
                            currentGameState.PitData.LeaderIsPitting          = true;
                            currentGameState.PitData.OpponentForLeaderPitting = opponent;
                        }
                        else
                        {
                            currentGameState.PitData.LeaderIsPitting          = false;
                            currentGameState.PitData.OpponentForLeaderPitting = null;
                        }
                    }
                    else if (opponent.ClassPosition == currentGameState.SessionData.ClassPosition - 1)
                    {
                        var useDerivedDeltas = true;
                        if (CrewChief.gameDefinition.gameEnum == GameEnum.PCARS2 || CrewChief.gameDefinition.gameEnum == GameEnum.RACE_ROOM || CrewChief.gameDefinition.gameEnum == GameEnum.RF2_64BIT || CrewChief.gameDefinition.gameEnum == GameEnum.RF1)
                        {
                            // special case for R3E, RF1, RF2 and PCars2 - gap ahead is provided by the game - use these
                            // (already set in the mapper) if the opponent is on the same lap
                            var lapDifference = opponent.DeltaTime.GetSignedLapDifference(currentGameState.SessionData.DeltaTime);
                            if (lapDifference == 0)
                            {
                                currentGameState.SessionData.LapsDeltaFront = 0;
                                useDerivedDeltas = false;
                            }
                        }
                        if (useDerivedDeltas)
                        {
                            var timeDelta = opponent.DeltaTime.GetAbsoluteTimeDeltaAllowingForLapDifferences(currentGameState.SessionData.DeltaTime);
                            currentGameState.SessionData.LapsDeltaFront = timeDelta.Item1;
                            currentGameState.SessionData.TimeDeltaFront = timeDelta.Item2;
                        }
                        if (opponent.JustEnteredPits && currentGameState.Now > nextOpponentAheadPitMessageDue)
                        {
                            nextOpponentAheadPitMessageDue = currentGameState.Now.AddSeconds(minSecondsBetweenOpponentPitMessages);
                            currentGameState.PitData.CarInFrontIsPitting        = true;
                            currentGameState.PitData.OpponentForCarAheadPitting = opponent;
                        }
                        else
                        {
                            currentGameState.PitData.CarInFrontIsPitting        = false;
                            currentGameState.PitData.OpponentForCarAheadPitting = null;
                        }
                    }
                    else if (opponent.ClassPosition == currentGameState.SessionData.ClassPosition + 1)
                    {
                        var useDerivedDeltas = true;
                        if (CrewChief.gameDefinition.gameEnum == GameEnum.PCARS2 || CrewChief.gameDefinition.gameEnum == GameEnum.RACE_ROOM)
                        {
                            // special case for R3E and PCars2 - gap behind is provided by the game - use these
                            // (already set in the mapper) if the opponent is on the same lap
                            var lapDifference = opponent.DeltaTime.GetSignedLapDifference(currentGameState.SessionData.DeltaTime);
                            if (lapDifference == 0)
                            {
                                currentGameState.SessionData.LapsDeltaBehind = 0;
                                useDerivedDeltas = false;
                            }
                        }
                        if (useDerivedDeltas)
                        {
                            var timeDelta = opponent.DeltaTime.GetAbsoluteTimeDeltaAllowingForLapDifferences(currentGameState.SessionData.DeltaTime);
                            currentGameState.SessionData.LapsDeltaBehind = timeDelta.Item1;
                            currentGameState.SessionData.TimeDeltaBehind = timeDelta.Item2;
                        }
                        if (opponent.JustEnteredPits && currentGameState.Now > nextOpponentBehindPitMessageDue)
                        {
                            nextOpponentBehindPitMessageDue                      = currentGameState.Now.AddSeconds(minSecondsBetweenOpponentPitMessages);
                            currentGameState.PitData.CarBehindIsPitting          = true;
                            currentGameState.PitData.OpponentForCarBehindPitting = opponent;
                        }
                        else
                        {
                            currentGameState.PitData.CarBehindIsPitting          = false;
                            currentGameState.PitData.OpponentForCarBehindPitting = null;
                        }
                    }
                }
            }
            if (!currentGameState.SessionData.SessionHasFixedTime)
            {
                // work out the laps remaining
                currentGameState.SessionData.SessionLapsRemaining = currentGameState.SessionData.SessionNumberOfLaps - leaderLapsCompleted;
            }

            if (currentGameState.SessionData.JustGoneGreen || currentGameState.SessionData.IsNewSession)
            {
                currentGameState.SessionData.NumCarsInPlayerClassAtStartOfSession = numCarsInPlayerClass;
            }
            currentGameState.SessionData.NumCarsInPlayerClass = numCarsInPlayerClass;

            // now derive some stuff that we always need to derive, using the correct class positions:
            String previousBehindKey = currentGameState.getOpponentKeyBehind(currentGameState.carClass, true);
            String currentBehindKey  = currentGameState.getOpponentKeyBehind(currentGameState.carClass);
            String previousAheadKey  = currentGameState.getOpponentKeyInFront(currentGameState.carClass, true);
            String currentAheadKey   = currentGameState.getOpponentKeyInFront(currentGameState.carClass);

            if (currentGameState.SessionData.ClassPosition > 2)
            {
                // if we're first or second we don't care about lead changes
                String previousLeaderKey = currentGameState.getOpponentKeyAtClassPosition(1, currentGameState.carClass, true);
                String currentLeaderKey  = currentGameState.getOpponentKeyAtClassPosition(1, currentGameState.carClass);
            }
            // don't really need this any more:

            /*
             * if (CrewChief.Debugging
             *  && ((currentBehindKey == null && currentGameState.SessionData.ClassPosition < currentGameState.SessionData.NumCarsInPlayerClass)
             || (currentAheadKey == null && currentGameState.SessionData.ClassPosition > 1)))
             ||{
             || Console.WriteLine("Non-contiguous class positions");
             || List<OpponentData> opponentsInClass = new List<OpponentData>();
             || foreach (OpponentData opponent in currentGameState.OpponentData.Values)
             || {
             ||     if (CarData.IsCarClassEqual(opponent.CarClass, currentGameState.carClass))
             ||     {
             ||         opponentsInClass.Add(opponent);
             ||     }
             ||     Console.WriteLine(String.Join("\n", opponentsInClass.OrderBy(o => o.ClassPosition)));
             || }
             ||}*/

            currentGameState.SessionData.IsRacingSameCarBehind  = currentBehindKey == previousBehindKey;
            currentGameState.SessionData.IsRacingSameCarInFront = currentAheadKey == previousAheadKey;
            if (!currentGameState.SessionData.IsRacingSameCarInFront)
            {
                currentGameState.SessionData.GameTimeAtLastPositionFrontChange = currentGameState.SessionData.SessionRunningTime;
            }
            if (!currentGameState.SessionData.IsRacingSameCarBehind)
            {
                currentGameState.SessionData.GameTimeAtLastPositionBehindChange = currentGameState.SessionData.SessionRunningTime;
            }
        }
示例#3
0
 /** May return null if the game state raw data is considered invalid */
 public abstract GameStateData mapToGameStateData(Object memoryMappedFileStruct, GameStateData previousGameState);