public getOpponentAtPosition ( int position, System.Boolean useUnfilteredPosition ) : |
||
position | int | |
useUnfilteredPosition | System.Boolean | |
Résultat |
public override bool isMessageStillValid(string eventSubType, GameStateData currentGameState, Dictionary<String, Object> validationData) { if (validationData != null && validationData.ContainsKey(validationDriverAheadKey)) { String expectedOpponentName = (String)validationData[validationDriverAheadKey]; OpponentData opponentInFront = currentGameState.SessionData.Position > 1 ? currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false) : null; String actualOpponentName = opponentInFront == null ? null : opponentInFront.DriverRawName; if (actualOpponentName != expectedOpponentName) { if (actualOpponentName != null && expectedOpponentName != null) { Console.WriteLine("new car in front message for opponent " + expectedOpponentName + " no longer valid - driver in front is now " + actualOpponentName); } return false; } } return true; }
private float getOpponentBestLap(int opponentPosition, int lapsToCheck, GameStateData gameState) { OpponentData opponent = gameState.getOpponentAtPosition(opponentPosition, false); if (opponent == null || opponent.OpponentLapData.Count < lapsToCheck) { return -1; } float bestLap = -1; for (int i = opponent.OpponentLapData.Count - 1; i >= opponent.OpponentLapData.Count - lapsToCheck; i--) { if (bestLap == -1 || bestLap > opponent.OpponentLapData[i].LapTime) { bestLap = opponent.OpponentLapData[i].LapTime; } } return bestLap; }
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 && currentGameState.SessionData.IsNewSector) { 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; sectorsUntilNextCloseCarAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber, rand.Next(closeAheadMinSectorWait, closeAheadMaxSectorWait)); audioPlayer.queueClip(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; sectorsUntilNextGapAheadReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber, rand.Next(gapAheadMinSectorWait, gapAheadMaxSectorWait)); TimeSpanWrapper gapInFront = TimeSpanWrapper.FromMilliseconds(gapsInFront[0] * 1000, true); Boolean readGap = gapInFront.timeSpan.Seconds > 0 || gapInFront.timeSpan.Milliseconds > 50; if (readGap) { if (gapInFrontStatus == GapStatus.INCREASING) { audioPlayer.queueClip(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.queueClip(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.queueClip(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; sectorsUntilNextCloseCarBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber, rand.Next(closeBehindMinSectorWait, closeBehindMaxSectorWait)); audioPlayer.queueClip(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; sectorsUntilNextGapBehindReport = adjustForMidLapPreference(currentGameState.SessionData.SectorNumber, rand.Next(gapBehindMinSectorWait, gapBehindMaxSectorWait)); TimeSpanWrapper gapBehind = TimeSpanWrapper.FromMilliseconds(gapsBehind[0] * 1000, true); Boolean readGap = gapBehind.timeSpan.Seconds > 0 || gapBehind.timeSpan.Milliseconds > 50; if (readGap) { if (gapBehindStatus == GapStatus.INCREASING) { audioPlayer.queueClip(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.queueClip(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.queueClip(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) { TimeSpanWrapper gap = TimeSpanWrapper.FromSeconds(currentGapInFront, true); 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.queueClip(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; TimeSpanWrapper gap = TimeSpanWrapper.FromSeconds(currentGapBehind, true); 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.queueClip(message); } } } } }
protected override void triggerInternal(GameStateData previousGameState, GameStateData currentGameState) { this.currentGameState = currentGameState; if (nextCarAheadChangeMessage == DateTime.MinValue) { nextCarAheadChangeMessage = currentGameState.Now.Add(TimeSpan.FromSeconds(30)); } if (nextLeadChangeMessage == DateTime.MinValue) { nextLeadChangeMessage = currentGameState.Now.Add(TimeSpan.FromSeconds(30)); } if (currentGameState.SessionData.SessionType != SessionType.Race || frequencyOfOpponentRaceLapTimes > 0) { foreach (KeyValuePair<Object, OpponentData> entry in currentGameState.OpponentData) { Object opponentKey = entry.Key; OpponentData opponentData = entry.Value; if (opponentData.IsNewLap && opponentData.LastLapTime > 0 && opponentData.OpponentLapData.Count > 1 && opponentData.LastLapValid && opponentData.CurrentBestLapTime != -1) { float currentFastestLap; if (currentGameState.SessionData.PlayerLapTimeSessionBest == -1) { currentFastestLap = currentGameState.SessionData.OpponentsLapTimeSessionBestOverall; } else if (currentGameState.SessionData.OpponentsLapTimeSessionBestOverall == -1) { currentFastestLap = currentGameState.SessionData.PlayerLapTimeSessionBest; } else { currentFastestLap = Math.Min(currentGameState.SessionData.PlayerLapTimeSessionBest, currentGameState.SessionData.OpponentsLapTimeSessionBestOverall); } // this opponent has just completed a lap - do we need to report it? if it's fast overall and more than // a tenth quicker then his previous best we do... if (((currentGameState.SessionData.SessionType == SessionType.Race && opponentData.CompletedLaps > 2) || (currentGameState.SessionData.SessionType != SessionType.Race && opponentData.CompletedLaps > 1)) && opponentData.LastLapTime <= currentFastestLap && AudioPlayer.availableDriverNames.Contains(DriverNameHelper.getUsableNameForRawName(opponentData.DriverRawName))) { audioPlayer.queueClip(new QueuedMessage("new_fastest_lap", MessageContents(folderNewFastestLapFor, opponentData, TimeSpan.FromSeconds(opponentData.LastLapTime)), 0, this)); } else if ((currentGameState.SessionData.SessionType == SessionType.Race && (opponentData.LastLapTime <= opponentData.CurrentBestLapTime && opponentData.LastLapTime < opponentData.PreviousBestLapTime - minImprovementBeforeReadingOpponentRaceTime && opponentData.LastLapTime < currentFastestLap + maxOffPaceBeforeReadingOpponentRaceTime)) || ((currentGameState.SessionData.SessionType == SessionType.Practice || currentGameState.SessionData.SessionType == SessionType.Qualify) && opponentData.LastLapTime <= opponentData.CurrentBestLapTime)) { if (currentGameState.SessionData.UnFilteredPosition > 1 && opponentData.UnFilteredPosition == 1 && (currentGameState.SessionData.SessionType == SessionType.Race || frequencyOfOpponentPracticeAndQualLapTimes > 0)) { // he's leading, and has recorded 3 or more laps, and this one's his fastest Console.WriteLine("Leader fast lap - this lap time = " + opponentData.LastLapTime +" session best = " + currentFastestLap); audioPlayer.queueClip(new QueuedMessage("leader_good_laptime", MessageContents(folderLeaderHasJustDoneA, TimeSpan.FromSeconds(opponentData.LastLapTime)), 0, this)); } else if (currentGameState.SessionData.UnFilteredPosition > 1 && opponentData.UnFilteredPosition == currentGameState.SessionData.Position - 1 && (currentGameState.SessionData.SessionType == SessionType.Race || random.Next(10) < frequencyOfOpponentPracticeAndQualLapTimes)) { // he's ahead of us, and has recorded 3 or more laps, and this one's his fastest Console.WriteLine("Car ahead fast lap - this lap time = " + opponentData.LastLapTime + " session best = " + currentFastestLap); audioPlayer.queueClip(new QueuedMessage("car_ahead_good_laptime", MessageContents(folderTheCarAheadHasJustDoneA, TimeSpan.FromSeconds(opponentData.LastLapTime)), 0, this)); } else if (!currentGameState.isLast() && opponentData.UnFilteredPosition == currentGameState.SessionData.Position + 1 && (currentGameState.SessionData.SessionType == SessionType.Race || random.Next(10) < frequencyOfOpponentPracticeAndQualLapTimes)) { // he's behind us, and has recorded 3 or more laps, and this one's his fastest Console.WriteLine("Car behind fast lap - this lap time = " + opponentData.LastLapTime + " session best = " + currentFastestLap); audioPlayer.queueClip(new QueuedMessage("car_behind_good_laptime", MessageContents(folderTheCarBehindHasJustDoneA, TimeSpan.FromSeconds(opponentData.LastLapTime)), 0, this)); } } } } } if (currentGameState.SessionData.SessionType == SessionType.Race) { if (!currentGameState.SessionData.IsRacingSameCarInFront) { if (currentGameState.SessionData.Position > 2 && currentGameState.Now > nextCarAheadChangeMessage && !currentGameState.PitData.InPitlane && currentGameState.SessionData.CompletedLaps > 0) { OpponentData opponentData = currentGameState.getOpponentAtPosition(currentGameState.SessionData.Position - 1, false); if (opponentData != null && !opponentData.isEnteringPits()) { audioPlayer.queueClip(new QueuedMessage("new_car_ahead", MessageContents(folderNextCarIs, opponentData), random.Next(Position.maxSecondsToWaitBeforeReportingPass + 1, Position.maxSecondsToWaitBeforeReportingPass + 3), this, new Dictionary<string, object> { { validationDriverAheadKey, opponentData.DriverRawName } })); nextCarAheadChangeMessage = currentGameState.Now.Add(TimeSpan.FromSeconds(30)); } } } if (currentGameState.SessionData.HasLeadChanged) { OpponentData leader = currentGameState.getOpponentAtPosition(1, false); if (leader != null) { String name = leader.DriverRawName; if (currentGameState.SessionData.Position > 1 && previousGameState.SessionData.Position > 1 && currentGameState.Now > nextLeadChangeMessage) { Console.WriteLine("Lead change, current leader is " + name + " laps completed = " + currentGameState.SessionData.CompletedLaps); audioPlayer.queueClip(new QueuedMessage("new_leader", MessageContents(currentGameState.getOpponentAtPosition(1, false), folderIsNowLeading), 0, this)); nextLeadChangeMessage = currentGameState.Now.Add(TimeSpan.FromSeconds(30)); } } } if (currentGameState.PitData.LeaderIsPitting && currentGameState.SessionData.SessionPhase != SessionPhase.Countdown && currentGameState.SessionData.SessionPhase != SessionPhase.Formation) { audioPlayer.queueClip(new QueuedMessage("leader_is_pitting", MessageContents(folderTheLeader, currentGameState.PitData.OpponentForLeaderPitting, folderIsPitting), MessageContents(folderLeaderIsPitting), 0, this)); } if (currentGameState.PitData.CarInFrontIsPitting && currentGameState.SessionData.TimeDeltaFront > 3 && currentGameState.SessionData.SessionPhase != SessionPhase.Countdown && currentGameState.SessionData.SessionPhase != SessionPhase.Formation) { audioPlayer.queueClip(new QueuedMessage("car_in_front_is_pitting", MessageContents(currentGameState.PitData.OpponentForCarAheadPitting, folderAheadIsPitting), MessageContents(folderCarAheadIsPitting), 0, this)); } if (currentGameState.PitData.CarBehindIsPitting && currentGameState.SessionData.TimeDeltaBehind > 3 && currentGameState.SessionData.SessionPhase != SessionPhase.Countdown && currentGameState.SessionData.SessionPhase != SessionPhase.Formation) { audioPlayer.queueClip(new QueuedMessage("car_behind_is_pitting", MessageContents(currentGameState.PitData.OpponentForCarBehindPitting, folderBehindIsPitting), MessageContents(folderCarBehindIsPitting), 0, this)); } } }