Exemple #1
0
        public GameStateMapper getGameStateMapper(GameDefinition gameDefinition)
        {
            lock (this)
            {
                switch (gameDefinition.gameEnum)
                {
                case GameEnum.PCARS_NETWORK:
                case GameEnum.PCARS_32BIT:
                case GameEnum.PCARS_64BIT:
                    if (pcarsGameStateMapper == null)
                    {
                        pcarsGameStateMapper = new PCarsGameStateMapper();
                    }
                    return(pcarsGameStateMapper);

                case GameEnum.RACE_ROOM:
                    if (r3eGameStateMapper == null)
                    {
                        r3eGameStateMapper = new R3EGameStateMapper();
                    }
                    return(r3eGameStateMapper);

                case GameEnum.RF1:
                    if (rf1GameStateMapper == null)
                    {
                        rf1GameStateMapper = new RF1GameStateMapper();
                    }
                    return(rf1GameStateMapper);

                case GameEnum.ASSETTO_64BIT:
                case GameEnum.ASSETTO_32BIT:
                    if (ascGameStateMapper == null)
                    {
                        ascGameStateMapper = new ACSGameStateMapper();
                    }
                    return(ascGameStateMapper);

                case GameEnum.RF2_64BIT:
                    if (rf2GameStateMapper == null)
                    {
                        rf2GameStateMapper = new RF2GameStateMapper();
                    }
                    return(rf2GameStateMapper);
                }
            }
            return(null);
        }
Exemple #2
0
        public override void trigger(Object lastStateObj, Object currentStateObj, GameStateData currentGameState)
        {
#if TRACE_SPOTTER_ELAPSED_TIME
            var watch = System.Diagnostics.Stopwatch.StartNew();
#endif
            if (this.paused)
            {
                return;
            }

            var lastState    = lastStateObj as CrewChiefV4.rFactor2.RF2SharedMemoryReader.RF2StructWrapper;
            var currentState = currentStateObj as CrewChiefV4.rFactor2.RF2SharedMemoryReader.RF2StructWrapper;

            if (!this.enabled ||
                currentState.scoring.mScoringInfo.mCurrentET < this.timeAfterRaceStartToActivate ||
                currentState.extended.mInRealtimeFC == 0 ||
                currentState.scoring.mScoringInfo.mInRealtime == 0 ||
                currentGameState.OpponentData.Count == 0 ||
                lastState.extended.mInRealtimeFC == 0 ||
                lastState.scoring.mScoringInfo.mInRealtime == 0)
            {
                return;
            }

            // turn off spotter for formation lap before going green
            if (currentState.scoring.mScoringInfo.mGamePhase == (int)rFactor2Constants.rF2GamePhase.Formation)
            {
                return;
            }

            var now = DateTime.UtcNow;
            rF2VehicleScoring currentPlayerScoring;
            rF2VehicleScoring previousPlayerScoring;
            float             timeDiffSeconds;
            try
            {
                currentPlayerScoring  = this.getVehicleInfo(currentState);
                previousPlayerScoring = this.getVehicleInfo(lastState);
                timeDiffSeconds       = ((float)(now - this.previousTime).TotalMilliseconds) / 1000.0f;
                this.previousTime     = now;

                if (timeDiffSeconds <= 0.0f)
                {
                    // In pits probably.
                    return;
                }
            }
            catch (Exception)
            {
                return;
            }

            if (currentPlayerScoring.mInPits != 0)  // No spotter in pits.
            {
                return;
            }

            if (currentGameState != null)
            {
                var carClass = currentGameState.carClass;
                if (carClass != null && !string.Equals(this.currentPlayerCarClassID, carClass.getClassIdentifier()))
                {
                    // Retrieve and use user overridable spotter car length/width.
                    this.internalSpotter.setCarDimensions(GlobalBehaviourSettings.spotterVehicleLength, GlobalBehaviourSettings.spotterVehicleWidth);
                    this.currentPlayerCarClassID = carClass.getClassIdentifier();
                }
            }

            var idsToTelIndicesMap = RF2GameStateMapper.getIdsToTelIndicesMap(ref currentState.telemetry);

            // Initialize current player information.
            float[] currentPlayerPosition = null;
            float   currentPlayerSpeed    = -1.0f;
            float   playerRotation        = 0.0f;

            int playerTelIdx = -1;
            if (idsToTelIndicesMap.TryGetValue(currentPlayerScoring.mID, out playerTelIdx))
            {
                var currentPlayerTelemetry = currentState.telemetry.mVehicles[playerTelIdx];

                currentPlayerPosition = new float[] { (float)currentPlayerTelemetry.mPos.x, (float)currentPlayerTelemetry.mPos.z };
                currentPlayerSpeed    = (float)Math.Sqrt((currentPlayerTelemetry.mLocalVel.x * currentPlayerTelemetry.mLocalVel.x)
                                                         + (currentPlayerTelemetry.mLocalVel.y * currentPlayerTelemetry.mLocalVel.y)
                                                         + (currentPlayerTelemetry.mLocalVel.z * currentPlayerTelemetry.mLocalVel.z));

                playerRotation = (float)(Math.Atan2(currentPlayerTelemetry.mOri[rFactor2Constants.RowZ].x, currentPlayerTelemetry.mOri[rFactor2Constants.RowZ].z));
            }
            else
            {
                // Telemetry is not available, fall back to scoring info.  This is corner case, should not happen often.
                currentPlayerPosition = new float[] { (float)currentPlayerScoring.mPos.x, (float)currentPlayerScoring.mPos.z };
                currentPlayerSpeed    = (float)Math.Sqrt((currentPlayerScoring.mLocalVel.x * currentPlayerScoring.mLocalVel.x)
                                                         + (currentPlayerScoring.mLocalVel.y * currentPlayerScoring.mLocalVel.y)
                                                         + (currentPlayerScoring.mLocalVel.z * currentPlayerScoring.mLocalVel.z));

                playerRotation = (float)(Math.Atan2(currentPlayerScoring.mOri[rFactor2Constants.RowZ].x, currentPlayerScoring.mOri[rFactor2Constants.RowZ].z));
            }

            if (playerRotation < 0.0f)
            {
                playerRotation = (float)(2.0f * Math.PI) + playerRotation;
            }

            // Find position data for previous player vehicle.  Default to scoring pos, but use telemetry if available (corner case, should not happen often).
            var previousPlayerPosition = new float[] { (float)previousPlayerScoring.mPos.x, (float)previousPlayerScoring.mPos.z };
            for (int i = 0; i < lastState.telemetry.mNumVehicles; ++i)
            {
                if (previousPlayerScoring.mID == lastState.telemetry.mVehicles[i].mID)
                {
                    previousPlayerPosition = new float[] { (float)lastState.telemetry.mVehicles[i].mPos.x, (float)lastState.telemetry.mVehicles[i].mPos.z };
                    break;
                }
            }

            var playerVelocityData = new float[] {
                currentPlayerSpeed,
                (currentPlayerPosition[0] - previousPlayerPosition[0]) / timeDiffSeconds,
                (currentPlayerPosition[1] - previousPlayerPosition[1]) / timeDiffSeconds
            };

            var currentOpponentPositions = new List <float[]>();
            for (int i = 0; i < currentState.scoring.mScoringInfo.mNumVehicles; ++i)
            {
                var vehicle = currentState.scoring.mVehicles[i];
                if (vehicle.mIsPlayer == 1 || vehicle.mInPits == 1 || vehicle.mLapDist < 0.0f)
                {
                    continue;
                }

                int opponentTelIdx = -1;
                if (idsToTelIndicesMap.TryGetValue(vehicle.mID, out opponentTelIdx))
                {
                    var opponentTelemetry = currentState.telemetry.mVehicles[opponentTelIdx];
                    currentOpponentPositions.Add(new float[] { (float)opponentTelemetry.mPos.x, (float)opponentTelemetry.mPos.z });
                }
                else
                {
                    currentOpponentPositions.Add(new float[] { (float)vehicle.mPos.x, (float)vehicle.mPos.z });  // Use scoring if telemetry isn't available.
                }
            }

            this.internalSpotter.triggerInternal(playerRotation, currentPlayerPosition, playerVelocityData, currentOpponentPositions);

#if TRACE_SPOTTER_ELAPSED_TIME
            watch.Stop();
            var microseconds = watch.ElapsedTicks * 1000000 / System.Diagnostics.Stopwatch.Frequency;
            System.Console.WriteLine("Spotter microseconds: " + microseconds);
#endif
        }