Beispiel #1
0
        public AudioPlayer(CrewChief crewChief)
        {
            this.crewChief = crewChief;
            String soundPackLocationOverride = UserSettings.GetUserSettings().getString("override_default_sound_pack_location");

            if (soundPackLocationOverride != null && soundPackLocationOverride.Length > 0)
            {
                soundFilesPath = soundPackLocationOverride;
            }
            else
            {
                soundFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\CrewChiefV4\sounds";
            }
            DirectoryInfo soundDirectory = new DirectoryInfo(soundFilesPath);

            if (soundDirectory.Exists)
            {
                soundPackVersion   = getSoundPackVersion(soundDirectory);
                driverNamesVersion = getDriverNamesVersion(soundDirectory);
                soundPackLanguage  = getSoundPackLanguage(soundDirectory);
            }
            else
            {
                soundDirectory.Create();
            }
        }
Beispiel #2
0
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            Boolean checkPushToGain = currentGameState.SessionData.SessionRunningTime - currentGameState.SessionData.GameTimeAtLastPositionFrontChange < minTimeToBeInThisPosition;
            Boolean checkPushToHold = currentGameState.SessionData.SessionRunningTime - currentGameState.SessionData.GameTimeAtLastPositionBehindChange < minTimeToBeInThisPosition;

            if (currentGameState.SessionData.SessionType == SessionType.Race && !currentGameState.PitData.InPitlane)
            {
                if ((checkPushToGain || checkPushToHold) && !playedNearEndTimePush && currentGameState.SessionData.SessionNumberOfLaps <= 0 &&
                    currentGameState.SessionData.SessionTimeRemaining < 4 * 60 && currentGameState.SessionData.SessionTimeRemaining > 2 * 60)
                {
                    // estimate the number of remaining laps - be optimistic...
                    int numLapsLeft = (int)Math.Ceiling((double)currentGameState.SessionData.SessionTimeRemaining / (double)currentGameState.SessionData.PlayerLapTimeSessionBest);
                    if (currentGameState.carClass.carClassEnum == CarData.CarClassEnum.DTM_2015)
                    {
                        numLapsLeft = numLapsLeft + 1;
                    }
                    playedNearEndTimePush = checkGaps(currentGameState, numLapsLeft, checkPushToGain, checkPushToHold);
                }
                else if ((checkPushToGain || checkPushToHold) && !playedNearEndLapsPush && currentGameState.SessionData.SessionNumberOfLaps > 0 &&
                         currentGameState.SessionData.SessionNumberOfLaps - currentGameState.SessionData.CompletedLaps <= 4)
                {
                    playedNearEndLapsPush = checkGaps(currentGameState, currentGameState.SessionData.SessionNumberOfLaps - currentGameState.SessionData.CompletedLaps, checkPushToGain, checkPushToHold);
                }
            }
            if (currentGameState.PitData.IsAtPitExit && currentGameState.PositionAndMotionData.CarSpeed > 5)
            {
                // we've just been handed control back after a pitstop
                if (isOpponentApproachingPitExit(currentGameState))
                {
                    // we've exited into clean air
                    audioPlayer.playMessage(new QueuedMessage(folderTrafficBehindExitingPits, 0, this));
                }
                else
                {
                    audioPlayer.playMessage(new QueuedMessage(folderPushExitingPits, 0, this));
                }
                // now try and report the current brake and tyre temp status
                try
                {
                    if (brakeTempWarningOnPitExit)
                    {
                        ((TyreMonitor)CrewChief.getEvent("TyreMonitor")).reportBrakeTempStatus(false, false);
                    }
                    if (tyreTempWarningOnPitExit)
                    {
                        ((TyreMonitor)CrewChief.getEvent("TyreMonitor")).reportCurrentTyreTempStatus(false);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Failed to report brake temp status on pit exit");
                }
            }
        }
Beispiel #3
0
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            if (GameStateData.onManualFormationLap)
            {
                return;
            }
            if (currentGameState.SessionData.IsNewLap && currentGameState.PositionAndMotionData.CarSpeed > maxSpeedWhenCrossingLine)
            {
                maxSpeedWhenCrossingLine = currentGameState.PositionAndMotionData.CarSpeed;
                // the distance at which we check if there's a car exiting the pits will be speed dependent.
                // The faster we are over the line, the more notice we'll need. * 3 is a number I pulled out of my arse,
                // it may be shit.
                distanceBeforeStartLineToWarnOfPitExit = maxSpeedWhenCrossingLine * 3;
            }
            Boolean checkPushToGain = currentGameState.SessionData.SessionRunningTime - currentGameState.SessionData.GameTimeAtLastPositionFrontChange < minTimeToBeInThisPosition;
            Boolean checkPushToHold = currentGameState.SessionData.SessionRunningTime - currentGameState.SessionData.GameTimeAtLastPositionBehindChange < minTimeToBeInThisPosition;

            if (currentGameState.SessionData.SessionType == SessionType.Race && !currentGameState.PitData.InPitlane)
            {
                if ((checkPushToGain || checkPushToHold) && !playedNearEndTimePush && currentGameState.SessionData.SessionHasFixedTime &&
                    currentGameState.SessionData.SessionTimeRemaining < 4 * 60 && currentGameState.SessionData.SessionTimeRemaining > 2 * 60)
                {
                    // estimate the number of remaining laps - be optimistic...
                    int numLapsLeft = (int)Math.Ceiling((double)currentGameState.SessionData.SessionTimeRemaining / (double)currentGameState.SessionData.PlayerLapTimeSessionBest);
                    if (currentGameState.SessionData.HasExtraLap)
                    {
                        numLapsLeft = numLapsLeft + 1;
                    }
                    playedNearEndTimePush = checkGaps(currentGameState, numLapsLeft, checkPushToGain, checkPushToHold);
                }
                else if ((checkPushToGain || checkPushToHold) && !playedNearEndLapsPush && !currentGameState.SessionData.SessionHasFixedTime &&
                         ((currentGameState.SessionData.SessionLapsRemaining <= 4 && currentGameState.SessionData.TrackDefinition.trackLengthClass <= TrackData.TrackLengthClass.MEDIUM) ||
                          (currentGameState.SessionData.SessionLapsRemaining <= 2 && currentGameState.SessionData.TrackDefinition.trackLengthClass <= TrackData.TrackLengthClass.LONG) ||
                          (currentGameState.SessionData.SessionLapsRemaining == 1 && currentGameState.SessionData.TrackDefinition.trackLengthClass <= TrackData.TrackLengthClass.VERY_LONG)))
                {
                    playedNearEndLapsPush = checkGaps(currentGameState, currentGameState.SessionData.SessionLapsRemaining, checkPushToGain, checkPushToHold);
                }
            }
            if (currentGameState.PitData.IsAtPitExit && currentGameState.PositionAndMotionData.CarSpeed > 5)
            {
                // we've just been handed control back after a pitstop
                if (currentGameState.SessionData.SessionRunningTime > 30 && isOpponentApproachingPitExit(currentGameState))
                {
                    // we've exited into clean air
                    audioPlayer.playMessageImmediately(new QueuedMessage(folderTrafficBehindExitingPits, 3, abstractEvent: this,
                                                                         type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                }
                else
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(folderPushExitingPits, 3, abstractEvent: this,
                                                                         type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                }
                // now try and report the current brake and tyre temp status
                try
                {
                    if (brakeTempWarningOnPitExit)
                    {
                        ((TyreMonitor)CrewChief.getEvent("TyreMonitor")).reportBrakeTempStatus(false, false);
                    }
                    if (tyreTempWarningOnPitExit)
                    {
                        ((TyreMonitor)CrewChief.getEvent("TyreMonitor")).reportCurrentTyreTempStatus(false);
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Failed to report brake temp status on pit exit");
                }
                if (!playedQualExitMessage && currentGameState.SessionData.SessionType == SessionType.Qualify)
                {
                    playedQualExitMessage = true;
                    if (currentGameState.SessionData.SessionNumberOfLaps > 0)
                    {
                        // special case for iracing - AFAIK no other games have number-of-laps in qual sessions
                        audioPlayer.playMessageImmediately(new QueuedMessage("qual_pit_exit", 5,
                                                                             messageFragments: MessageContents(folderQualExitIntro, currentGameState.SessionData.SessionNumberOfLaps, folderQualExitOutroLaps),
                                                                             abstractEvent: this, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                    }
                    else if (currentGameState.SessionData.SessionHasFixedTime)
                    {
                        int minutesLeft = (int)Math.Floor(currentGameState.SessionData.SessionTimeRemaining / 60f);
                        if (minutesLeft > 1)
                        {
                            audioPlayer.playMessageImmediately(new QueuedMessage("qual_pit_exit", 5,
                                                                                 messageFragments: MessageContents(folderQualExitIntro, minutesLeft, folderQualExitOutroMinutes),
                                                                                 abstractEvent: this, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                        }
                    }
                }
            }
            if (previousGameState != null &&
                currentGameState.SessionData.SectorNumber == 3 &&
                currentGameState.PositionAndMotionData.CarSpeed > 5 &&
                !currentGameState.PitData.InPitlane &&
                isApproachingStartLine(currentGameState.SessionData.TrackDefinition, previousGameState.PositionAndMotionData.DistanceRoundTrack, currentGameState.PositionAndMotionData.DistanceRoundTrack) &&
                isOpponentLeavingPits(currentGameState))
            {
                audioPlayer.playMessageImmediately(new QueuedMessage(folderOpponentExitingPits, 2, abstractEvent: this, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
            }
        }
        public void execute(String recognitionResult, Boolean supressConfirmationMessage)
        {
            // blocking...
            Boolean isR3e = CrewChief.gameDefinition == GameDefinition.raceRoom;
            int     multiplePressCountFromVoiceCommand = 0;

            if (macro.integerVariableVoiceTrigger != null && macro.integerVariableVoiceTrigger.Length > 0)
            {
                multiplePressCountFromVoiceCommand = macro.extractInt(recognitionResult, macro.startPhrase, macro.endPhrase);
            }
            foreach (CommandSet commandSet in macro.commandSets)
            {
                // only execute for the requested game - is this check sensible?
                if (CrewChief.gameDefinition.gameEnum.ToString().Equals(commandSet.gameDefinition) &&
                    assignmentsByGame.ContainsKey(commandSet.gameDefinition))
                {
                    Boolean isValid = checkValidAndPlayConfirmation(commandSet, supressConfirmationMessage);
                    if (isValid)
                    {
                        ThreadManager.UnregisterTemporaryThread(executableCommandMacroThread);
                        executableCommandMacroThread = new Thread(() =>
                        {
                            // only allow macros to excute one at a time
                            lock (ExecutableCommandMacro.mutex)
                            {
                                IntPtr currentForgroundWindow  = GetForegroundWindow();
                                bool hasChangedForgroundWindow = BringGameWindowToFront(CrewChief.gameDefinition.processName, CrewChief.gameDefinition.alternativeProcessNames, currentForgroundWindow);

                                foreach (ActionItem actionItem in commandSet.getActionItems())
                                {
                                    if (MacroManager.stopped)
                                    {
                                        break;
                                    }
                                    if (MacroManager.WAIT_IDENTIFIER.Equals(actionItem.extendedType))
                                    {
                                        Thread.Sleep(actionItem.extendedTypeNumericParam);
                                    }
                                    else
                                    {
                                        int count;
                                        if (MacroManager.MULTIPLE_PRESS_IDENTIFIER.Equals(actionItem.extendedType))
                                        {
                                            if (actionItem.extendedTypeTextParam != null)
                                            {
                                                if (MacroManager.MULTIPLE_PRESS_FROM_VOICE_TRIGGER_IDENTIFIER.Equals(actionItem.extendedTypeTextParam))
                                                {
                                                    count = multiplePressCountFromVoiceCommand;
                                                }
                                                else
                                                {
                                                    count = CrewChief.getEvent(actionItem.extendedTypeTextParam).resolveMacroKeyPressCount(macro.name);
                                                }
                                                // hack for R3E: fuel menu needs 3 presses to get it from the start to 0
                                                if (isR3e && macro.name.Contains("fuel"))
                                                {
                                                    count = count + 3;
                                                }
                                            }
                                            else
                                            {
                                                count = actionItem.extendedTypeNumericParam;
                                            }
                                        }
                                        else
                                        {
                                            count = 1;
                                        }
                                        sendKeys(count, actionItem, commandSet.keyPressTime, commandSet.waitBetweenEachCommand);
                                    }
                                }
                                if (hasChangedForgroundWindow)
                                {
                                    SetForegroundWindow(currentForgroundWindow);
                                }
                            }
                        });
                        executableCommandMacroThread.Name = "CommandMacro.executableCommandMacroThread";
                        ThreadManager.RegisterTemporaryThread(executableCommandMacroThread);
                        executableCommandMacroThread.Start();
                    }
                    break;
                }
            }
        }
 public static void SetCrewChief(CrewChief cc)
 {
     PlaybackModerator.crewChief = cc;
 }
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            if (CrewChief.gameDefinition.gameEnum != GameEnum.IRACING)
            {
                return;
            }
            lastColdFLPressure = (int)currentGameState.TyreData.FrontLeftPressure;
            lastColdFRPressure = (int)currentGameState.TyreData.FrontRightPressure;
            lastColdRLPressure = (int)currentGameState.TyreData.RearLeftPressure;
            lastColdRRPressure = (int)currentGameState.TyreData.RearRightPressure;

            maxIncidentCount    = currentGameState.SessionData.MaxIncidentCount;
            incidentsCount      = currentGameState.SessionData.CurrentIncidentCount;
            hasLimitedIncidents = currentGameState.SessionData.HasLimitedIncidents;
            licenseLevel        = currentGameState.SessionData.LicenseLevel;
            iRating             = currentGameState.SessionData.iRating;
            strenghtOfField     = currentGameState.SessionData.StrengthOfField;
            fuelCapacity        = currentGameState.FuelData.FuelCapacity;
            currentFuel         = currentGameState.FuelData.FuelLeft;
            if (autoFuelToEnd)
            {
                if (previousGameState != null && !previousGameState.PitData.InPitlane && currentGameState.PitData.InPitlane &&
                    currentGameState.SessionData.SessionType == SessionType.Race && currentGameState.SessionData.SessionRunningTime > 15 &&
                    !previousGameState.PitData.IsInGarage && !currentGameState.PitData.JumpedToPits)
                {
                    Fuel  fuelEvent    = (Fuel)CrewChief.getEvent("Fuel");
                    float litresNeeded = fuelEvent.getLitresToEndOfRace(true);

                    if (litresNeeded == float.MaxValue)
                    {
                        audioPlayer.playMessage(new QueuedMessage(AudioPlayer.folderNoData, 0));
                    }
                    else if (litresNeeded <= 0)
                    {
                        audioPlayer.playMessage(new QueuedMessage(Fuel.folderPlentyOfFuel, 0));
                    }
                    else if (litresNeeded > 0)
                    {
                        int roundedLitresNeeded = (int)Math.Ceiling(litresNeeded);
                        AddFuel(roundedLitresNeeded);
                        Console.WriteLine("Auto refuel to the end of the race, adding " + roundedLitresNeeded + " liters of fuel");
                        if (roundedLitresNeeded > fuelCapacity - currentFuel)
                        {
                            // if we have a known fuel capacity and this is less than the calculated amount of fuel we need, warn about it.
                            audioPlayer.playMessage(new QueuedMessage(Fuel.folderWillNeedToStopAgain, 0, secondsDelay: 4, abstractEvent: this));
                        }
                        else
                        {
                            audioPlayer.playMessage(new QueuedMessage(AudioPlayer.folderFuelToEnd, 0));
                        }
                    }
                }
            }

/*
 *          if (hasLimitedIncidents)
 *          {
 *              //play < 5 incident left warning.
 *              if (incidentsCount >= maxIncidentCount - 5 && !playedIncidentsWarning)
 *              {
 *                  playedIncidentsWarning = true;
 *                  audioPlayer.playMessageImmediately(new QueuedMessage("Incidents/limit", MessageContents(folderYouHave, incidentsCount, folderincidentPoints,
 *                      Pause(200), folderincidentPointslimit, maxIncidentCount), 0));
 *
 *              }
 *              else if (incidentsCount >= maxIncidentCount - 1 && !playedLastIncidentsLeftWarning)
 *              {
 *                  playedLastIncidentsLeftWarning = true;
 *                  //play 1 incident left warning.
 *              }
 *          }
 */
        }
        public override void respond(String voiceMessage)
        {
            if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_ADD))
            {
                int amount = 0;
                foreach (KeyValuePair <String[], int> entry in SpeechRecogniser.numberToNumber)
                {
                    foreach (String numberStr in entry.Key)
                    {
                        if (voiceMessage.Contains(" " + numberStr + " "))
                        {
                            amount = entry.Value;
                            break;
                        }
                    }
                }
                if (amount == 0)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderDidntUnderstand, 0));
                    return;
                }
                if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.LITERS))
                {
                    AddFuel(amount);
                    audioPlayer.playMessageImmediately(new QueuedMessage("iracing_add_fuel", 0,
                                                                         messageFragments: MessageContents(AudioPlayer.folderAcknowlegeOK, amount, amount == 1 ? Fuel.folderLitre : Fuel.folderLitres)));
                }
                else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.GALLONS))
                {
                    AddFuel(convertGallonsToLitres(amount));
                    audioPlayer.playMessageImmediately(new QueuedMessage("iracing_add_fuel", 0,
                                                                         messageFragments: MessageContents(AudioPlayer.folderAcknowlegeOK, amount, amount == 1 ? Fuel.folderGallon : Fuel.folderGallons)));
                }
                else
                {
                    Console.WriteLine("Got fuel request with no unit, assuming " + (Fuel.fuelReportsInGallon ? " gallons" : "litres"));
                    if (!Fuel.fuelReportsInGallon)
                    {
                        AddFuel(amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage("iracing_add_fuel", 0,
                                                                             messageFragments: MessageContents(AudioPlayer.folderAcknowlegeOK, amount, amount == 1 ? Fuel.folderLitre : Fuel.folderLitres)));
                    }
                    else
                    {
                        AddFuel(convertGallonsToLitres(amount));
                        audioPlayer.playMessageImmediately(new QueuedMessage("iracing_add_fuel", 0,
                                                                             messageFragments: MessageContents(AudioPlayer.folderAcknowlegeOK, amount, amount == 1 ? Fuel.folderGallon : Fuel.folderGallons)));
                    }
                }
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_FUEL_TO_THE_END))
            {
                Fuel  fuelEvent    = (Fuel)CrewChief.getEvent("Fuel");
                float litresNeeded = fuelEvent.getLitresToEndOfRace(true);

                if (litresNeeded == float.MaxValue)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderNoData, 0));
                }
                else if (litresNeeded <= 0)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(Fuel.folderPlentyOfFuel, 0));
                }
                else if (litresNeeded > 0)
                {
                    int roundedLitresNeeded = (int)Math.Ceiling(litresNeeded);
                    AddFuel(roundedLitresNeeded);
                    if (roundedLitresNeeded > fuelCapacity - currentFuel)
                    {
                        // if we have a known fuel capacity and this is less than the calculated amount of fuel we need, warn about it.
                        audioPlayer.playMessage(new QueuedMessage(Fuel.folderWillNeedToStopAgain, 0, secondsDelay: 4, abstractEvent: this));
                    }
                    else
                    {
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderFuelToEnd, 0));
                    }
                    return;
                }
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_TEAROFF))
            {
                Tearoff();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_FAST_REPAIR))
            {
                FastRepair();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CLEAR_ALL))
            {
                ClearAll();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CLEAR_TYRES))
            {
                ClearTires();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CLEAR_WIND_SCREEN))
            {
                ClearTearoff();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CLEAR_FAST_REPAIR))
            {
                ClearFastRepair();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CLEAR_FUEL))
            {
                ClearFuel();
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_TYRE_PRESSURE) ||
                     SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_LEFT_TYRE_PRESSURE) ||
                     SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_RIGHT_TYRE_PRESSURE) ||
                     SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_LEFT_TYRE_PRESSURE) ||
                     SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_RIGHT_TYRE_PRESSURE))
            {
                int amount = 0;
                foreach (KeyValuePair <String[], int> entry in SpeechRecogniser.numberToNumber)
                {
                    foreach (String numberStr in entry.Key)
                    {
                        if (voiceMessage.Contains(" " + numberStr))
                        {
                            amount = entry.Value;
                            break;
                        }
                    }
                }
                if (amount == 0)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderDidntUnderstand, 0));
                    return;
                }
                else
                {
                    if (pressureUnit == PressureUnit.PSI)
                    {
                        amount = convertPSItoKPA(amount);
                    }
                    if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_TYRE_PRESSURE))
                    {
                        ChangeTire(PitCommandModeTypes.LF, amount);
                        ChangeTire(PitCommandModeTypes.RF, amount);
                        ChangeTire(PitCommandModeTypes.LR, amount);
                        ChangeTire(PitCommandModeTypes.RR, amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                        return;
                    }
                    else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_LEFT_TYRE_PRESSURE))
                    {
                        ChangeTire(PitCommandModeTypes.LF, amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                        return;
                    }
                    else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_RIGHT_TYRE_PRESSURE))
                    {
                        ChangeTire(PitCommandModeTypes.RF, amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                        return;
                    }
                    else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_LEFT_TYRE_PRESSURE))
                    {
                        ChangeTire(PitCommandModeTypes.LR, amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                        return;
                    }
                    else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_RIGHT_TYRE_PRESSURE))
                    {
                        ChangeTire(PitCommandModeTypes.RR, amount);
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                        return;
                    }
                }
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_ALL_TYRES))
            {
                ChangeTire(PitCommandModeTypes.LF, lastColdFLPressure);
                ChangeTire(PitCommandModeTypes.RF, lastColdFRPressure);
                ChangeTire(PitCommandModeTypes.LR, lastColdRLPressure);
                ChangeTire(PitCommandModeTypes.RR, lastColdRRPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_LEFT_TYRE))
            {
                ChangeTire(PitCommandModeTypes.LF, lastColdFLPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_FRONT_RIGHT_TYRE))
            {
                ChangeTire(PitCommandModeTypes.RF, lastColdFRPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_LEFT_TYRE))
            {
                ChangeTire(PitCommandModeTypes.LR, lastColdRLPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_REAR_RIGHT_TYRE))
            {
                ChangeTire(PitCommandModeTypes.RR, lastColdRRPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_LEFT_SIDE_TYRES))
            {
                ClearTires();
                ChangeTire(PitCommandModeTypes.LF, lastColdFLPressure);
                ChangeTire(PitCommandModeTypes.LR, lastColdRLPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.PIT_STOP_CHANGE_RIGHT_SIDE_TYRES))
            {
                ClearTires();
                ChangeTire(PitCommandModeTypes.RF, lastColdFRPressure);
                ChangeTire(PitCommandModeTypes.RR, lastColdRRPressure);
                audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderAcknowlegeOK, 0));
                return;
            }

            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.HOW_MANY_INCIDENT_POINTS))
            {
                audioPlayer.playMessageImmediately(new QueuedMessage("Incidents/incidents", 0, messageFragments: MessageContents(folderYouHave, incidentsCount, folderincidents)));
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.WHATS_THE_INCIDENT_LIMIT))
            {
                if (hasLimitedIncidents)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage("Incidents/limit", 0, messageFragments: MessageContents(folderincidentlimit, maxIncidentCount)));
                }
                else
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage("Incidents/limit", 0, messageFragments: MessageContents(folderUnlimited)));
                }
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.WHATS_MY_IRATING))
            {
                if (iRating != -1)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage("license/irating", 0, messageFragments: MessageContents(iRating)));
                    return;
                }
                else
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderNoData, 0));
                    return;
                }
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.WHATS_MY_LICENSE_CLASS))
            {
                if (licenseLevel.Item2 == -1)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderNoData, 0));
                    return;
                }
                if (licenseLevel.Item2 != -1)
                {
                    Tuple <int, int>       wholeandfractional = Utilities.WholeAndFractionalPart(licenseLevel.Item2, 2);
                    List <MessageFragment> messageFragments   = new List <MessageFragment>();

                    if (licenseLevel.Item1.ToLower() == "a")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicenseA));
                    }
                    else if (licenseLevel.Item1.ToLower() == "b")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicenseB));
                    }
                    else if (licenseLevel.Item1.ToLower() == "c")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicenseC));
                    }
                    else if (licenseLevel.Item1.ToLower() == "d")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicenseD));
                    }
                    else if (licenseLevel.Item1.ToLower() == "r")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicenseR));
                    }
                    else if (licenseLevel.Item1.ToLower() == "wc")
                    {
                        messageFragments.Add(MessageFragment.Text(folderLicensePro));
                    }
                    else
                    {
                        audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderNoData, 0));
                        return;
                    }
                    messageFragments.AddRange(MessageContents(wholeandfractional.Item1, NumberReader.folderPoint, wholeandfractional.Item2));
                    QueuedMessage licenceLevelMessage = new QueuedMessage("License/license", 0, messageFragments: messageFragments);
                    audioPlayer.playDelayedImmediateMessage(licenceLevelMessage);
                }
                return;
            }
            else if (SpeechRecogniser.ResultContains(voiceMessage, SpeechRecogniser.WHATS_THE_SOF))
            {
                if (strenghtOfField != -1)
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage("license/irating", 0, messageFragments: MessageContents(strenghtOfField)));
                    return;
                }
                else
                {
                    audioPlayer.playMessageImmediately(new QueuedMessage(AudioPlayer.folderNoData, 0));
                    return;
                }
            }
        }
        public AudioPlayer(CrewChief crewChief)
        {
            this.crewChief = crewChief;
            String        soundPackLocationOverride = UserSettings.GetUserSettings().getString("override_default_sound_pack_location");
            String        defaultSoundFilesPath     = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\CrewChiefV4\sounds";
            DirectoryInfo defaultSoundDirectory     = new DirectoryInfo(defaultSoundFilesPath);
            DirectoryInfo overrideSoundDirectory    = null;
            DirectoryInfo soundDirectory            = null;
            Boolean       useOverride = false;

            if (soundPackLocationOverride != null && soundPackLocationOverride.Length > 0)
            {
                try
                {
                    overrideSoundDirectory = new DirectoryInfo(soundPackLocationOverride);
                    if (overrideSoundDirectory.Exists)
                    {
                        useOverride = true;
                    }
                    else
                    {
                        Console.WriteLine("Specified sound pack override folder " + soundPackLocationOverride + " doesn't exist, using default");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Unable to set override sound folder ", e.Message);
                }
            }
            if (useOverride && overrideSoundDirectory != null)
            {
                soundFilesPath = soundPackLocationOverride;
                soundDirectory = overrideSoundDirectory;
            }
            else
            {
                soundFilesPath = defaultSoundFilesPath;
                soundDirectory = defaultSoundDirectory;
            }
            if (soundDirectory.Exists)
            {
                soundPackVersion        = getSoundPackVersion(soundDirectory);
                driverNamesVersion      = getDriverNamesVersion(soundDirectory);
                soundPackLanguage       = getSoundPackLanguage(soundDirectory);
                personalisationsVersion = getPersonalisationsVersion(soundDirectory);
            }
            else
            {
                soundDirectory.Create();
            }

            // populate the personalisations list
            DirectoryInfo personalisationsDirectory = new DirectoryInfo(soundFilesPath + @"\personalisations");

            if (personalisationsDirectory.Exists)
            {
                List <String> personalisationsList = new List <string>();
                personalisationsList.Add(NO_PERSONALISATION_SELECTED);
                foreach (DirectoryInfo folderInPersonalisationsDirectory in personalisationsDirectory.GetDirectories())
                {
                    personalisationsList.Add(folderInPersonalisationsDirectory.Name);
                }
                personalisationsArray = personalisationsList.ToArray();
            }
            String savedPersonalisation = UserSettings.GetUserSettings().getString("PERSONALISATION_NAME");

            if (savedPersonalisation != null && savedPersonalisation.Length > 0)
            {
                selectedPersonalisation = savedPersonalisation;
            }
        }
Beispiel #10
0
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            currentConditions = currentGameState.Conditions.getMostRecentConditions();
            if (currentGameState.SessionData.IsNewLap)
            {
                conditionsAtStartOfThisLap = currentConditions;
            }

            if (currentConditions != null)
            {
                // for pcars track temp, we're only interested in changes at the start line (a single point on the track) because the track
                // temp is localised. The air temp is (probably) localised too, but will be less variable
                float trackTempToUse = CrewChief.isPCars() && conditionsAtStartOfThisLap != null ? conditionsAtStartOfThisLap.TrackTemperature : currentConditions.TrackTemperature;
                if (airTempAtLastReport == float.MinValue)
                {
                    airTempAtLastReport   = currentConditions.AmbientTemperature;
                    trackTempAtLastReport = trackTempToUse;
                    rainAtLastReport      = currentConditions.RainDensity;
                    lastRainReport        = currentGameState.Now;
                    lastTrackTempReport   = currentGameState.Now;
                    lastAirTempReport     = currentGameState.Now;
                }
                else
                {
                    Boolean canReportAirChange = enableTrackAndAirTempReports &&
                                                 currentGameState.Now > lastAirTempReport.Add(AirTemperatureReportMaxFrequency);
                    Boolean canReportTrackChange = enableTrackAndAirTempReports &&
                                                   currentGameState.Now > lastTrackTempReport.Add(TrackTemperatureReportMaxFrequency);
                    Boolean  reportedCombinedTemps = false;
                    TimeSpan rainReportFrequency   = CrewChief.gameDefinition.gameEnum == GameEnum.RF2_64BIT ? RainReportMaxFrequencyRF2 : RainReportMaxFrequencyPCars;
                    if (canReportAirChange || canReportTrackChange)
                    {
                        if (trackTempToUse > trackTempAtLastReport + minTrackTempDeltaToReport && currentConditions.AmbientTemperature > airTempAtLastReport + minAirTempDeltaToReport)
                        {
                            airTempAtLastReport   = currentConditions.AmbientTemperature;
                            trackTempAtLastReport = trackTempToUse;
                            lastAirTempReport     = currentGameState.Now;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airAndTrackTemp", 10, messageFragments: MessageContents
                                                                          (folderAirAndTrackTempIncreasing, folderAirTempIsNow, convertTemp(currentConditions.AmbientTemperature),
                                                                          folderTrackTempIsNow, convertTemp(trackTempToUse), getTempUnit()), abstractEvent: this, priority: 0));
                            reportedCombinedTemps = true;
                        }
                        else if (trackTempToUse < trackTempAtLastReport - minTrackTempDeltaToReport && currentConditions.AmbientTemperature < airTempAtLastReport - minAirTempDeltaToReport)
                        {
                            airTempAtLastReport   = currentConditions.AmbientTemperature;
                            trackTempAtLastReport = trackTempToUse;
                            lastAirTempReport     = currentGameState.Now;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airAndTrackTemp", 10, messageFragments: MessageContents
                                                                          (folderAirAndTrackTempDecreasing, folderAirTempIsNow, convertTemp(currentConditions.AmbientTemperature),
                                                                          folderTrackTempIsNow, convertTemp(trackTempToUse), getTempUnit()), abstractEvent: this, priority: 0));
                            reportedCombinedTemps = true;
                        }
                    }
                    if (!reportedCombinedTemps && canReportAirChange)
                    {
                        if (currentConditions.AmbientTemperature > airTempAtLastReport + minAirTempDeltaToReport)
                        {
                            airTempAtLastReport = currentConditions.AmbientTemperature;
                            lastAirTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airTemp", 10, messageFragments: MessageContents
                                                                          (folderAirTempIncreasing, convertTemp(currentConditions.AmbientTemperature), getTempUnit()), abstractEvent: this, priority: 0));
                        }
                        else if (currentConditions.AmbientTemperature < airTempAtLastReport - minAirTempDeltaToReport)
                        {
                            airTempAtLastReport = currentConditions.AmbientTemperature;
                            lastAirTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airTemp", 10, messageFragments: MessageContents
                                                                          (folderAirTempDecreasing, convertTemp(currentConditions.AmbientTemperature), getTempUnit()), abstractEvent: this, priority: 0));
                        }
                    }
                    if (!reportedCombinedTemps && canReportTrackChange)
                    {
                        if (trackTempToUse > trackTempAtLastReport + minTrackTempDeltaToReport)
                        {
                            trackTempAtLastReport = trackTempToUse;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("trackTemp", 10, messageFragments: MessageContents
                                                                          (folderTrackTempIncreasing, convertTemp(trackTempToUse), getTempUnit()), abstractEvent: this, priority: 0));
                        }
                        else if (trackTempToUse < trackTempAtLastReport - minTrackTempDeltaToReport)
                        {
                            trackTempAtLastReport = trackTempToUse;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("trackTemp", 10, messageFragments: MessageContents
                                                                          (folderTrackTempDecreasing, convertTemp(trackTempToUse), getTempUnit()), abstractEvent: this, priority: 0));
                        }
                    }
                    //pcars2 test warning
                    if (enablePCarsRainPrediction && CrewChief.isPCars())
                    {
                        if (previousGameState != null && currentGameState.SessionData.SessionRunningTime > 10)
                        {
                            if (currentGameState.RainDensity == 0)
                            {
                                // not raining so see if we can guess when it might start
                                if (!waitingForRainEstimate)
                                {
                                    if (previousGameState.CloudBrightness == 2 && currentGameState.CloudBrightness < 2)
                                    {
                                        timeWhenCloudIncreased = previousGameState.Now;
                                        waitingForRainEstimate = true;
                                    }
                                }
                                else if (currentGameState.CloudBrightness < 1.98)
                                {
                                    // big enough change to calculate expected rain time
                                    TimeSpan timeDelta = currentGameState.Now - timeWhenCloudIncreased;
                                    // assume rain just after it hits 1.9
                                    float millisTillRain = (float)timeDelta.TotalMilliseconds * 6f;
                                    // this is usually really inaccurate and can go either way
                                    timeWhenRainExpected   = timeWhenCloudIncreased.AddMilliseconds(millisTillRain);
                                    waitingForRainEstimate = false;
                                    timeWhenCloudIncreased = DateTime.MinValue;
                                    DateTime when = currentGameState.Now.AddMilliseconds(millisTillRain);
                                    Console.WriteLine("It is now " + currentGameState.Now + ", we expect rain at game time " + when);
                                    int minutes = (int)Math.Round(millisTillRain / 60000);

                                    if (minutes > 2)
                                    {
                                        audioPlayer.playMessage(new QueuedMessage("expecting_rain", 10, messageFragments: MessageContents(folderExpectRain,
                                                                                                                                          new TimeSpanWrapper(TimeSpan.FromMinutes(minutes), Precision.MINUTES)), abstractEvent: this));
                                    }
                                }
                            }
                            else
                            {
                                // cancel waiting for rain
                                waitingForRainEstimate = false;
                                timeWhenCloudIncreased = DateTime.MinValue;
                            }
                        }
                    }
                    if (currentGameState.Now > lastRainReport.Add(rainReportFrequency))
                    {
                        // for PCars mRainDensity value is 0 or 1
                        if (CrewChief.gameDefinition.gameEnum == GameEnum.PCARS_32BIT ||
                            CrewChief.gameDefinition.gameEnum == GameEnum.PCARS_64BIT ||
                            CrewChief.gameDefinition.gameEnum == GameEnum.PCARS_NETWORK)
                        {
                            if (currentGameState.RainDensity == 0 && rainAtLastReport == 1)
                            {
                                rainAtLastReport = currentGameState.RainDensity;
                                lastRainReport   = currentGameState.Now;
                                audioPlayer.playMessage(new QueuedMessage(folderStoppedRaining, 10, abstractEvent: this, priority: 2));
                            }
                            else if (currentConditions.RainDensity == 1 && rainAtLastReport == 0)
                            {
                                rainAtLastReport = currentGameState.RainDensity;
                                lastRainReport   = currentGameState.Now;
                                audioPlayer.playMessage(new QueuedMessage(folderSeeingSomeRain, 10, abstractEvent: this, priority: 5));
                            }
                        }
                        else if (CrewChief.gameDefinition.gameEnum == GameEnum.RF2_64BIT || CrewChief.gameDefinition.gameEnum == GameEnum.PCARS2)
                        {
                            if (rainDensityAtLastCheck != -1 && rainDensityAtLastCheck != currentConditions.RainDensity)
                            {
                                float rainChangeRate = (float)(Math.Abs(rainDensityAtLastCheck - currentConditions.RainDensity) / rainReportFrequency.TotalSeconds);
                                if (rainChangeRate > ConditionsMonitor.maxRainChangeRate)
                                {
                                    ConditionsMonitor.maxRainChangeRate = rainChangeRate;
                                }
                            }
                            rainDensityAtLastCheck = currentConditions.RainDensity;
                            RainLevel currentRainLevel      = getRainLevel(currentConditions.RainDensity);
                            RainLevel lastReportedRainLevel = getRainLevel(rainAtLastReport);
                            if (currentRainLevel != lastReportedRainLevel)
                            {
                                Boolean increasing = currentConditions.RainDensity > rainAtLastReport;
                                switch (currentRainLevel)
                                {
                                case RainLevel.DRIZZLE:
                                    audioPlayer.playMessageImmediately(new QueuedMessage(increasing ? folderDrizzleIncreasing : folderDrizzleDecreasing, 0, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                                    break;

                                case RainLevel.LIGHT:
                                    audioPlayer.playMessageImmediately(new QueuedMessage(increasing ? folderRainLightIncreasing : folderRainLightDecreasing, 0, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                                    break;

                                case RainLevel.MID:
                                    audioPlayer.playMessageImmediately(new QueuedMessage(increasing ? folderRainMidIncreasing : folderRainMidDecreasing, 0, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                                    break;

                                case RainLevel.HEAVY:
                                    audioPlayer.playMessageImmediately(new QueuedMessage(increasing ? folderRainHeavyIncreasing : folderRainHeavyDecreasing, 0, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                                    break;

                                case RainLevel.STORM:
                                    audioPlayer.playMessageImmediately(new QueuedMessage(folderRainMax, 0, type: SoundType.IMPORTANT_MESSAGE, priority: 0));
                                    break;

                                case RainLevel.NONE:
                                    audioPlayer.playMessage(new QueuedMessage(folderStoppedRaining, 10, abstractEvent: this, priority: 3));
                                    break;
                                }
                                lastRainReport   = currentGameState.Now;
                                rainAtLastReport = currentConditions.RainDensity;
                            }
                        }
                    }
                }
            }
        }