示例#1
0
 public override void clearState()
 {
     gapsInFront = new List<float>();
     gapsBehind = new List<float>();
     lastGapBehindReport = GapStatus.NONE;
     lastGapInFrontReport = GapStatus.NONE;
     gapBehindAtLastReport = -1;
     gapInFrontAtLastReport = -1;
     sectorsSinceLastReport = 0;
     sectorsUntilNextReport = 0;
     drsRange = 2;  // TODO: get the DRS range from somewhere
     hasDRS = false;
 }
示例#2
0
        public void SetStatus(GapStatus status, Context context)
        {
            Status = status;
            ((FragmentActivity)context).RunOnUiThread(() =>
            {
                switch (status)
                {
                case GapStatus.EMPTY:
                case GapStatus.PENDING:
                    Visual.SetBackgroundColor(Color.White);
                    Visual.SetTextColor(Color.Black);
                    Visual.Text = "-";
                    break;

                case GapStatus.FILLING:
                    Visual.SetBackgroundColor(Color.LightGreen);
                    Visual.SetTextColor(Color.Black);
                    break;

                case GapStatus.FILLED:
                    Visual.SetBackgroundColor(Color.LightBlue);
                    Visual.SetTextColor(Color.Black);
                    break;

                case GapStatus.ERASED:
                    Visual.SetBackgroundColor(Color.White);
                    Visual.SetTextColor(Color.Black);
                    Visual.Text = "-";
                    break;

                case GapStatus.ERROR:
                    Visual.SetBackgroundColor(Color.Red);
                    Visual.SetTextColor(Color.White);
                    break;
                }
            });
        }
示例#3
0
        //max number of lines present in the xml is 12
        public void SetStatus(string location, GapStatus status)
        {
            Activity.RunOnUiThread(() =>
            {
                switch (status)
                {
                case GapStatus.EMPTY:
                    trolleyArray[location].SetBackgroundColor(Color.White);
                    break;

                case GapStatus.FILLING:
                    trolleyArray[location].SetBackgroundColor(Color.Green);
                    break;

                case GapStatus.FILLED:
                    trolleyArray[location].SetBackgroundColor(Color.Blue);
                    break;

                case GapStatus.ERROR:
                    trolleyArray[location].SetBackgroundColor(Color.Red);
                    break;
                }
            });
        }
示例#4
0
        protected override void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            isLeading         = currentGameState.SessionData.Position == 1;
            isLast            = currentGameState.isLast();
            isRace            = currentGameState.SessionData.SessionType == SessionType.Race;
            currentGapInFront = currentGameState.SessionData.TimeDeltaFront;
            currentGapBehind  = currentGameState.SessionData.TimeDeltaBehind;

            if (currentGameState.SessionData.IsNewLap)
            {
                playedGapBehindForThisLap = false;
            }

            if (gapsInFront == null || gapsBehind == null)
            {
                clearState();
            }
            if (!currentGameState.SessionData.IsRacingSameCarInFront)
            {
                gapsInFront.Clear();
                gapInFrontAtLastReport = -1;
            }
            if (!currentGameState.SessionData.IsRacingSameCarBehind)
            {
                gapsBehind.Clear();
                gapBehindAtLastReport = -1;
            }
            if (previousGameState != null && previousGameState.SessionData.CompletedLaps <= currentGameState.FlagData.lapCountWhenLastWentGreen)
            {
                return;
            }
            if (!currentGameState.PitData.InPitlane && enableGapMessages)
            {
                if (isRace && !CrewChief.readOpponentDeltasForEveryLap &&
                    IsNewSectorOrGapPoint(previousGameState, currentGameState))
                {
                    sectorsSinceLastGapAheadReport++;
                    sectorsSinceLastGapBehindReport++;
                    sectorsSinceLastCloseCarAheadReport++;
                    sectorsSinceLastCloseCarBehindReport++;
                    GapStatus gapInFrontStatus = GapStatus.NONE;
                    GapStatus gapBehindStatus  = GapStatus.NONE;
                    if (currentGameState.SessionData.Position != 1)
                    {
                        // AMS / RF1 hack - sometimes the gap data is stale, so don't put the exact same gap in the list
                        if (gapsInFront.Count == 0 || gapsInFront[0] != currentGameState.SessionData.TimeDeltaFront)
                        {
                            gapsInFront.Insert(0, currentGameState.SessionData.TimeDeltaFront);
                            gapInFrontStatus = getGapStatus(gapsInFront, gapInFrontAtLastReport);
                        }
                    }
                    if (!isLast)
                    {
                        // AMS / RF1 hack - sometimes the gap data is stale, so don't put the exact same gap in the list
                        if (gapsBehind.Count == 0 || gapsBehind[0] != currentGameState.SessionData.TimeDeltaBehind)
                        {
                            gapsBehind.Insert(0, currentGameState.SessionData.TimeDeltaBehind);
                            gapBehindStatus = getGapStatus(gapsBehind, gapBehindAtLastReport);
                        }
                    }

                    // Play which ever is the smaller gap, but we're not interested if the gap is < 0.5 or > 20 seconds or hasn't changed:
                    Boolean playGapInFront = gapInFrontStatus != GapStatus.NONE &&
                                             (gapBehindStatus == GapStatus.NONE || (gapsInFront.Count() > 0 && gapsBehind.Count() > 0 && gapsInFront[0] < gapsBehind[0]));

                    Boolean playGapBehind = !playGapInFront && gapBehindStatus != GapStatus.NONE;
                    if (playGapInFront)
                    {
                        if (gapInFrontStatus == GapStatus.CLOSE)
                        {
                            if (sectorsSinceLastCloseCarAheadReport >= sectorsUntilNextCloseCarAheadReport)
                            {
                                sectorsSinceLastCloseCarAheadReport = 0;
                                // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                                if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                                {
                                    sectorsUntilNextCloseCarAheadReport = rand.Next(closeAheadMinSectorWait, closeAheadMaxSectorWait);
                                }
                                else
                                {
                                    sectorsUntilNextCloseCarAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                                    rand.Next(closeAheadMinSectorWait, closeAheadMaxSectorWait));
                                }
                                audioPlayer.playMessage(new QueuedMessage(folderBeingHeldUp, 0, this, new Dictionary <string, object> {
                                    { "position", currentGameState.SessionData.Position }
                                }));
                                OpponentData opponent = currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false);
                                if (!trackLandmarkAttackDriverNamesUsed.ContainsKey(opponent.DriverRawName) ||
                                    trackLandmarkAttackDriverNamesUsed[opponent.DriverRawName] + minTimeBetweenAttackOrDefendByDriver < currentGameState.Now)
                                {
                                    CrewChiefV4.GameState.TrackLandmarksTiming.LandmarkAndDeltaType landmarkAndDeltaType =
                                        currentGameState.SessionData.trackLandmarksTiming.getLandmarkWhereIAmFaster(opponent.trackLandmarksTiming, true);
                                    if (landmarkAndDeltaType.landmarkName != null)
                                    {
                                        // either we're faster on entry or faster through
                                        String attackFolder = landmarkAndDeltaType.deltaType == TrackLandmarksTiming.DeltaType.Time ? folderHeIsSlowerThroughCorner : folderHeIsSlowerEnteringCorner;
                                        audioPlayer.playMessage(new QueuedMessage("Timings/corner_to_attack_in", MessageContents(Pause(200), attackFolder, "corners/" + landmarkAndDeltaType.landmarkName), 0, this));
                                        trackLandmarkAttackDriverNamesUsed[opponent.DriverRawName] = currentGameState.Now;
                                    }
                                }
                                gapInFrontAtLastReport = gapsInFront[0];
                            }
                        }
                        else if (gapInFrontStatus != GapStatus.NONE && sectorsSinceLastGapAheadReport >= sectorsUntilNextGapAheadReport)
                        {
                            sectorsSinceLastGapAheadReport = 0;
                            // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                            if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                            {
                                sectorsUntilNextGapAheadReport = rand.Next(gapAheadMinSectorWait, gapAheadMaxSectorWait);
                            }
                            else
                            {
                                sectorsUntilNextGapAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                           rand.Next(gapAheadMinSectorWait, gapAheadMaxSectorWait));
                            }
                            TimeSpan gapInFront = TimeSpan.FromMilliseconds(gapsInFront[0] * 1000);
                            Boolean  readGap    = gapInFront.Seconds > 0 || gapInFront.Milliseconds > 50;
                            if (readGap)
                            {
                                if (gapInFrontStatus == GapStatus.INCREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false), folderAheadIsIncreasing,
                                                                                              gapInFront), MessageContents(folderGapInFrontIncreasing, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapInFrontStatus == GapStatus.DECREASING)
                                {
                                    OpponentData opponent = currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false);
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderYoureReeling, opponent, folderInTheGapIsNow, gapInFront),
                                                                              MessageContents(folderGapInFrontDecreasing, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                    if (!trackLandmarkAttackDriverNamesUsed.ContainsKey(opponent.DriverRawName) ||
                                        trackLandmarkAttackDriverNamesUsed[opponent.DriverRawName] + minTimeBetweenAttackOrDefendByDriver < currentGameState.Now)
                                    {
                                        CrewChiefV4.GameState.TrackLandmarksTiming.LandmarkAndDeltaType landmarkAndDeltaType =
                                            currentGameState.SessionData.trackLandmarksTiming.getLandmarkWhereIAmFaster(opponent.trackLandmarksTiming, true);
                                        if (landmarkAndDeltaType.landmarkName != null)
                                        {
                                            // either we're faster on entry or faster through
                                            String attackFolder = landmarkAndDeltaType.deltaType == TrackLandmarksTiming.DeltaType.Time ? folderHeIsSlowerThroughCorner : folderHeIsSlowerEnteringCorner;
                                            audioPlayer.playMessage(new QueuedMessage("Timings/corner_to_attack_in", MessageContents(Pause(200), attackFolder, "corners/" + landmarkAndDeltaType.landmarkName), 0, this));
                                            trackLandmarkAttackDriverNamesUsed[opponent.DriverRawName] = currentGameState.Now;
                                        }
                                    }
                                }
                                else if (gapInFrontStatus == GapStatus.OTHER)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false),
                                                                                              folderAheadIsNow, gapInFront), MessageContents(folderGapInFrontIsNow, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                            }
                            gapInFrontAtLastReport = gapsInFront[0];
                        }
                    }
                    else if (playGapBehind)
                    {
                        if (gapBehindStatus == GapStatus.CLOSE)
                        {
                            if (sectorsSinceLastCloseCarBehindReport >= sectorsUntilNextCloseCarBehindReport)
                            {
                                sectorsSinceLastCloseCarBehindReport = 0;
                                // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                                if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                                {
                                    sectorsUntilNextCloseCarBehindReport = rand.Next(closeBehindMinSectorWait, closeBehindMaxSectorWait);
                                }
                                else
                                {
                                    sectorsUntilNextCloseCarBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                                     rand.Next(closeBehindMinSectorWait, closeBehindMaxSectorWait));
                                }
                                audioPlayer.playMessage(new QueuedMessage(folderBeingPressured, 0, this, new Dictionary <string, object> {
                                    { "position", currentGameState.SessionData.Position }
                                }));
                                OpponentData opponent = currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false);
                                if (!trackLandmarkDefendDriverNamesUsed.ContainsKey(opponent.DriverRawName) ||
                                    trackLandmarkDefendDriverNamesUsed[opponent.DriverRawName] + minTimeBetweenAttackOrDefendByDriver < currentGameState.Now)
                                {
                                    CrewChiefV4.GameState.TrackLandmarksTiming.LandmarkAndDeltaType landmarkAndDeltaType =
                                        currentGameState.SessionData.trackLandmarksTiming.getLandmarkWhereIAmSlower(opponent.trackLandmarksTiming, true);
                                    if (landmarkAndDeltaType.landmarkName != null)
                                    {
                                        // either we're slower on entry or slower through
                                        String defendFolder = landmarkAndDeltaType.deltaType == TrackLandmarksTiming.DeltaType.Time ? folderHeIsFasterThroughCorner : folderHeIsFasterEnteringCorner;
                                        audioPlayer.playMessage(new QueuedMessage("Timings/corner_to_defend_in", MessageContents(Pause(200), defendFolder, "corners/" + landmarkAndDeltaType.landmarkName), 0, this));
                                        trackLandmarkDefendDriverNamesUsed[opponent.DriverRawName] = currentGameState.Now;
                                    }
                                }
                                gapBehindAtLastReport = gapsBehind[0];
                            }
                        }
                        else if (gapBehindStatus != GapStatus.NONE && sectorsSinceLastGapBehindReport >= sectorsUntilNextGapBehindReport)
                        {
                            sectorsSinceLastGapBehindReport = 0;
                            // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                            if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                            {
                                sectorsUntilNextGapBehindReport = rand.Next(gapBehindMinSectorWait, gapBehindMaxSectorWait);
                            }
                            else
                            {
                                sectorsUntilNextGapBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                            rand.Next(gapBehindMinSectorWait, gapBehindMaxSectorWait));
                            }
                            TimeSpan gapBehind = TimeSpan.FromMilliseconds(gapsBehind[0] * 1000);
                            Boolean  readGap   = gapBehind.Seconds > 0 || gapBehind.Milliseconds > 50;
                            if (readGap)
                            {
                                if (gapBehindStatus == GapStatus.INCREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false),
                                                                                              folderBehindIsIncreasing, gapBehind), MessageContents(folderGapBehindIncreasing, gapBehind), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapBehindStatus == GapStatus.DECREASING)
                                {
                                    OpponentData opponent = currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false);
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(opponent, folderIsReelingYouIn, gapBehind), MessageContents(folderGapBehindDecreasing, gapBehind),
                                                                              0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));

                                    if (!trackLandmarkDefendDriverNamesUsed.ContainsKey(opponent.DriverRawName) ||
                                        trackLandmarkDefendDriverNamesUsed[opponent.DriverRawName] + minTimeBetweenAttackOrDefendByDriver < currentGameState.Now)
                                    {
                                        CrewChiefV4.GameState.TrackLandmarksTiming.LandmarkAndDeltaType landmarkAndDeltaType =
                                            currentGameState.SessionData.trackLandmarksTiming.getLandmarkWhereIAmSlower(opponent.trackLandmarksTiming, true);
                                        if (landmarkAndDeltaType.landmarkName != null)
                                        {
                                            // either we're slower on entry or slower through
                                            String defendFolder = landmarkAndDeltaType.deltaType == TrackLandmarksTiming.DeltaType.Time ? folderHeIsFasterThroughCorner : folderHeIsFasterEnteringCorner;
                                            audioPlayer.playMessage(new QueuedMessage("Timings/corner_to_defend_in", MessageContents(Pause(200), defendFolder, "corners/" + landmarkAndDeltaType.landmarkName), 0, this));
                                            trackLandmarkDefendDriverNamesUsed[opponent.DriverRawName] = currentGameState.Now;
                                        }
                                    }
                                }
                                else if (gapBehindStatus == GapStatus.OTHER)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false),
                                                                                              folderBehindIsNow, gapBehind), MessageContents(folderGapBehindIsNow, gapBehind), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                            }
                            gapBehindAtLastReport = gapsBehind[0];
                        }
                    }
                }
                if (isRace && CrewChief.readOpponentDeltasForEveryLap && currentGameState.SessionData.CompletedLaps > 0)
                {
                    if (currentGameState.SessionData.Position > 1 && currentGameState.SessionData.IsNewLap)
                    {
                        if (currentGapInFront > 0.05)
                        {
                            TimeSpan      gap     = TimeSpan.FromSeconds(currentGapInFront);
                            QueuedMessage message = new QueuedMessage("Timings/gap_ahead", MessageContents(folderTheGapTo,
                                                                                                           currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false), folderAheadIsNow, gap),
                                                                      MessageContents(folderGapInFrontIsNow, gap), 0, this, new Dictionary <string, object> {
                                { "position", currentGameState.SessionData.Position }
                            });
                            message.playEvenWhenSilenced = true;
                            audioPlayer.playMessage(message);
                        }
                    }
                    if (!currentGameState.isLast())
                    {
                        if (!playedGapBehindForThisLap && currentGapBehind > 0.05 && currentGameState.SessionData.LapTimeCurrent > 0 &&
                            currentGameState.SessionData.LapTimeCurrent >= currentGapBehind &&
                            currentGameState.SessionData.LapTimeCurrent <= currentGapBehind + CrewChief._timeInterval.TotalSeconds)
                        {
                            playedGapBehindForThisLap = true;
                            TimeSpan      gap     = TimeSpan.FromSeconds(currentGapBehind);
                            QueuedMessage message = new QueuedMessage("Timings/gap_behind", MessageContents(folderTheGapTo,
                                                                                                            currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false), folderBehindIsNow, gap),
                                                                      MessageContents(folderGapBehindIsNow, gap), 0, this, new Dictionary <string, object> {
                                { "position", currentGameState.SessionData.Position }
                            });
                            message.playEvenWhenSilenced = true;
                            audioPlayer.playMessage(message);
                        }
                    }
                }
            }
        }
示例#5
0
        protected override void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            isLeading         = currentGameState.SessionData.Position == 1;
            isLast            = currentGameState.isLast();
            isRace            = currentGameState.SessionData.SessionType == SessionType.Race;
            currentGapInFront = currentGameState.SessionData.TimeDeltaFront;
            currentGapBehind  = currentGameState.SessionData.TimeDeltaBehind;

            if (currentGameState.SessionData.IsNewLap)
            {
                playedGapBehindForThisLap = false;
            }

            if (gapsInFront == null || gapsBehind == null)
            {
                clearState();
            }
            if (!currentGameState.SessionData.IsRacingSameCarInFront)
            {
                gapsInFront.Clear();
            }
            if (!currentGameState.SessionData.IsRacingSameCarBehind)
            {
                gapsBehind.Clear();
            }
            if (!currentGameState.PitData.InPitlane && enableGapMessages)
            {
                if (isRace && !CrewChief.readOpponentDeltasForEveryLap &&
                    IsNewSectorOrGapPoint(previousGameState, currentGameState))
                {
                    sectorsSinceLastGapAheadReport++;
                    sectorsSinceLastGapBehindReport++;
                    sectorsSinceLastCloseCarAheadReport++;
                    sectorsSinceLastCloseCarBehindReport++;
                    GapStatus gapInFrontStatus = GapStatus.NONE;
                    GapStatus gapBehindStatus  = GapStatus.NONE;
                    if (currentGameState.SessionData.Position != 1)
                    {
                        gapsInFront.Insert(0, currentGameState.SessionData.TimeDeltaFront);
                        gapInFrontStatus = getGapStatus(gapsInFront, gapInFrontAtLastReport);
                    }
                    if (!isLast)
                    {
                        gapsBehind.Insert(0, currentGameState.SessionData.TimeDeltaBehind);
                        gapBehindStatus = getGapStatus(gapsBehind, gapBehindAtLastReport);
                    }

                    // Play which ever is the smaller gap, but we're not interested if the gap is < 0.5 or > 20 seconds or hasn't changed:
                    Boolean playGapInFront = gapInFrontStatus != GapStatus.NONE &&
                                             (gapBehindStatus == GapStatus.NONE || (gapsInFront.Count() > 0 && gapsBehind.Count() > 0 && gapsInFront[0] < gapsBehind[0]));

                    Boolean playGapBehind = !playGapInFront && gapBehindStatus != GapStatus.NONE;
                    if (playGapInFront)
                    {
                        if (gapInFrontStatus == GapStatus.CLOSE)
                        {
                            if (sectorsSinceLastCloseCarAheadReport >= sectorsUntilNextCloseCarAheadReport)
                            {
                                sectorsSinceLastCloseCarAheadReport = 0;
                                // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                                if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                                {
                                    sectorsUntilNextCloseCarAheadReport = rand.Next(closeAheadMinSectorWait, closeAheadMaxSectorWait);
                                }
                                else
                                {
                                    sectorsUntilNextCloseCarAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                                    rand.Next(closeAheadMinSectorWait, closeAheadMaxSectorWait));
                                }
                                audioPlayer.playMessage(new QueuedMessage(folderBeingHeldUp, 0, this, new Dictionary <string, object> {
                                    { "position", currentGameState.SessionData.Position }
                                }));
                                gapInFrontAtLastReport = gapsInFront[0];
                            }
                        }
                        else if (gapInFrontStatus != GapStatus.NONE && sectorsSinceLastGapAheadReport >= sectorsUntilNextGapAheadReport)
                        {
                            sectorsSinceLastGapAheadReport = 0;
                            // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                            if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                            {
                                sectorsUntilNextGapAheadReport = rand.Next(gapAheadMinSectorWait, gapAheadMaxSectorWait);
                            }
                            else
                            {
                                sectorsUntilNextGapAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                           rand.Next(gapAheadMinSectorWait, gapAheadMaxSectorWait));
                            }
                            TimeSpan gapInFront = TimeSpan.FromMilliseconds(gapsInFront[0] * 1000);
                            Boolean  readGap    = gapInFront.Seconds > 0 || gapInFront.Milliseconds > 50;
                            if (readGap)
                            {
                                if (gapInFrontStatus == GapStatus.INCREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false), folderAheadIsIncreasing,
                                                                                              gapInFront), MessageContents(folderGapInFrontIncreasing, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapInFrontStatus == GapStatus.DECREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderYoureReeling, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false),
                                                                                              folderInTheGapIsNow, gapInFront), MessageContents(folderGapInFrontDecreasing, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapInFrontStatus == GapStatus.OTHER)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_in_front",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false),
                                                                                              folderAheadIsNow, gapInFront), MessageContents(folderGapInFrontIsNow, gapInFront), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                            }
                            gapInFrontAtLastReport = gapsInFront[0];
                        }
                    }
                    else if (playGapBehind)
                    {
                        if (gapBehindStatus == GapStatus.CLOSE)
                        {
                            if (sectorsSinceLastCloseCarBehindReport >= sectorsUntilNextCloseCarBehindReport)
                            {
                                sectorsSinceLastCloseCarBehindReport = 0;
                                // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                                if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                                {
                                    sectorsUntilNextCloseCarBehindReport = rand.Next(closeBehindMinSectorWait, closeBehindMaxSectorWait);
                                }
                                else
                                {
                                    sectorsUntilNextCloseCarBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                                     rand.Next(closeBehindMinSectorWait, closeBehindMaxSectorWait));
                                }
                                audioPlayer.playMessage(new QueuedMessage(folderBeingPressured, 0, this, new Dictionary <string, object> {
                                    { "position", currentGameState.SessionData.Position }
                                }));
                                gapBehindAtLastReport = gapsBehind[0];
                            }
                        }
                        else if (gapBehindStatus != GapStatus.NONE && sectorsSinceLastGapBehindReport >= sectorsUntilNextGapBehindReport)
                        {
                            sectorsSinceLastGapBehindReport = 0;
                            // only prefer mid-lap gap reports if we're on a track with no ad-hoc gapPoints
                            if (currentGameState.SessionData.TrackDefinition.gapPoints.Count() > 0)
                            {
                                sectorsUntilNextGapBehindReport = rand.Next(gapBehindMinSectorWait, gapBehindMaxSectorWait);
                            }
                            else
                            {
                                sectorsUntilNextGapBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber,
                                                                                            rand.Next(gapBehindMinSectorWait, gapBehindMaxSectorWait));
                            }
                            TimeSpan gapBehind = TimeSpan.FromMilliseconds(gapsBehind[0] * 1000);
                            Boolean  readGap   = gapBehind.Seconds > 0 || gapBehind.Milliseconds > 50;
                            if (readGap)
                            {
                                if (gapBehindStatus == GapStatus.INCREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false),
                                                                                              folderBehindIsIncreasing, gapBehind), MessageContents(folderGapBehindIncreasing, gapBehind), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapBehindStatus == GapStatus.DECREASING)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false), folderIsReelingYouIn, gapBehind),
                                                                              MessageContents(folderGapBehindDecreasing, gapBehind), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                                else if (gapBehindStatus == GapStatus.OTHER)
                                {
                                    audioPlayer.playMessage(new QueuedMessage("Timings/gap_behind",
                                                                              MessageContents(folderTheGapTo, currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false),
                                                                                              folderBehindIsNow, gapBehind), MessageContents(folderGapBehindIsNow, gapBehind), 0, this, new Dictionary <string, object> {
                                        { "position", currentGameState.SessionData.Position }
                                    }));
                                }
                            }
                            gapBehindAtLastReport = gapsBehind[0];
                        }
                    }
                }
                if (isRace && CrewChief.readOpponentDeltasForEveryLap && currentGameState.SessionData.CompletedLaps > 0)
                {
                    if (currentGameState.SessionData.Position > 1 && currentGameState.SessionData.IsNewLap)
                    {
                        if (currentGapInFront > 0.05)
                        {
                            TimeSpan      gap     = TimeSpan.FromSeconds(currentGapInFront);
                            QueuedMessage message = new QueuedMessage("Timings/gap_ahead", MessageContents(folderTheGapTo,
                                                                                                           currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false), folderAheadIsNow, gap),
                                                                      MessageContents(folderGapInFrontIsNow, gap), 0, this, new Dictionary <string, object> {
                                { "position", currentGameState.SessionData.Position }
                            });
                            message.playEvenWhenSilenced = true;
                            audioPlayer.playMessage(message);
                        }
                    }
                    if (!currentGameState.isLast())
                    {
                        if (!playedGapBehindForThisLap && currentGapBehind > 0.05 && currentGameState.SessionData.LapTimeCurrent > 0 &&
                            currentGameState.SessionData.LapTimeCurrent >= currentGapBehind &&
                            currentGameState.SessionData.LapTimeCurrent <= currentGapBehind + CrewChief._timeInterval.TotalSeconds)
                        {
                            playedGapBehindForThisLap = true;
                            TimeSpan      gap     = TimeSpan.FromSeconds(currentGapBehind);
                            QueuedMessage message = new QueuedMessage("Timings/gap_behind", MessageContents(folderTheGapTo,
                                                                                                            currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position + 1, false), folderBehindIsNow, gap),
                                                                      MessageContents(folderGapBehindIsNow, gap), 0, this, new Dictionary <string, object> {
                                { "position", currentGameState.SessionData.Position }
                            });
                            message.playEvenWhenSilenced = true;
                            audioPlayer.playMessage(message);
                        }
                    }
                }
            }
        }
示例#6
0
        protected override void triggerInternal(Data.Shared lastState, Data.Shared currentState)
        {
            if (!hasDRS && currentState.DrsAvailable == 1)
            {
                hasDRS = true;
            }
            if (gapsInFront == null || gapsBehind == null) {
                clearState();
            }
            if (CommonData.isRaceStarted && CommonData.isNewSector)
            {
                sectorsSinceLastReport++;
                if (!CommonData.racingSameCarInFront)
                {
                    gapsInFront.Clear();
                }
                if (!CommonData.racingSameCarBehind)
                {
                    gapsBehind.Clear();
                }
                GapStatus gapInFrontStatus = GapStatus.NONE;
                GapStatus gapBehindStatus = GapStatus.NONE;
                if (currentState.Position != 1)
                {
                    gapsInFront.Insert(0, currentState.TimeDeltaFront);
                    gapInFrontStatus = getGapStatus(gapsInFront, gapInFrontAtLastReport);
                }
                if (!CommonData.isLast)
                {
                    gapsBehind.Insert(0, currentState.TimeDeltaBehind);
                    gapBehindStatus = getGapStatus(gapsBehind, gapBehindAtLastReport);
                }

                // Play which ever is the smaller gap, but we're not interested if the gap is < 0.5 or > 20 seconds or hasn't changed:
                Boolean playGapInFront = gapInFrontStatus != GapStatus.NONE &&
                    (gapBehindStatus == GapStatus.NONE || (gapsInFront.Count() > 0 && gapsBehind.Count() > 0 && gapsInFront[0] < gapsBehind[0]));

                Boolean playGapBehind = !playGapInFront && gapBehindStatus != GapStatus.NONE;

                if (playGapInFront && sectorsSinceLastReport >= sectorsUntilNextReport)
                {
                    sectorsSinceLastReport = 0;
                    // here we report on gaps semi-randomly, we'll see how this sounds...
                    sectorsUntilNextReport = rand.Next(3, 5);
                    switch (gapInFrontStatus)
                    {
                        case GapStatus.INCREASING:
                            audioPlayer.queueClip(QueuedMessage.compoundMessageIdentifier + "Timings/gaps", new QueuedMessage(folderGapInFrontIncreasing, folderSeconds,
                                TimeSpan.FromMilliseconds(gapsInFront[0] * 1000), 0, this));
                            lastGapInFrontReport = GapStatus.INCREASING;
                            gapInFrontAtLastReport = gapsInFront[0];
                            break;
                        case GapStatus.DECREASING:
                            audioPlayer.queueClip(QueuedMessage.compoundMessageIdentifier + "Timings/gaps", new QueuedMessage(folderGapInFrontDecreasing, folderSeconds,
                                TimeSpan.FromMilliseconds(gapsInFront[0] * 1000), 0, this));
                            lastGapInFrontReport = GapStatus.DECREASING;
                            gapInFrontAtLastReport = gapsInFront[0];
                            break;
                        case GapStatus.CLOSE:
                            audioPlayer.queueClip(folderBeingHeldUp, 0, this);
                            lastGapInFrontReport = GapStatus.CLOSE;
                            gapInFrontAtLastReport = gapsInFront[0];
                            break;
                    }
                }
                if (playGapBehind && sectorsSinceLastReport > sectorsUntilNextReport)
                {
                    sectorsSinceLastReport = 0;
                    sectorsUntilNextReport = rand.Next(2, 6);
                    switch (gapBehindStatus)
                    {
                        case GapStatus.INCREASING:
                            audioPlayer.queueClip(QueuedMessage.compoundMessageIdentifier + "Timings/gaps", new QueuedMessage(folderGapBehindIncreasing, folderSeconds,
                                TimeSpan.FromMilliseconds(gapsBehind[0] * 1000), 0, this));
                            lastGapBehindReport = GapStatus.INCREASING;
                            gapBehindAtLastReport = gapsBehind[0];
                            break;
                        case GapStatus.DECREASING:
                            audioPlayer.queueClip(QueuedMessage.compoundMessageIdentifier + "Timings/gaps", new QueuedMessage(folderGapBehindDecreasing, folderSeconds,
                                TimeSpan.FromMilliseconds(gapsBehind[0] * 1000), 0, this));
                            lastGapBehindReport = GapStatus.DECREASING;
                            gapBehindAtLastReport = gapsBehind[0];
                            break;
                        case GapStatus.CLOSE:
                            audioPlayer.queueClip(folderBeingPressured, 0, this);
                            lastGapBehindReport = GapStatus.CLOSE;
                            gapBehindAtLastReport = gapsBehind[0];
                            break;
                    }
                }
            }
        }