示例#1
0
        private void SetSnow(int v)
        {
            isRain = true;
            if (EnableDynamic)
            {
                if (Canvas == null)
                {
                    return;
                }
                var task = Canvas.RunOnGameLoopThreadAsync(async() =>
                {
                    await rain.LoadSurfaceAsync(Canvas);
                });
            }
            switch (v)
            {
            default:
                rainLevel = RainLevel.sSnow;
                break;

            case 0:
                rainLevel = RainLevel.sSnow;
                break;

            case 1:
                rainLevel = RainLevel.lSnow;
                break;
            }
            SetOvercastBG();
            rain.ChangeConstants(rainLevel);
        }
示例#2
0
        public override int GetHashCode()
        {
            int hash = 1;

            if (CloudLevel != 0)
            {
                hash ^= CloudLevel.GetHashCode();
            }
            if (RainLevel != 0)
            {
                hash ^= RainLevel.GetHashCode();
            }
            if (WindLevel != 0)
            {
                hash ^= WindLevel.GetHashCode();
            }
            if (SnowLevel != 0)
            {
                hash ^= SnowLevel.GetHashCode();
            }
            if (FogLevel != 0)
            {
                hash ^= FogLevel.GetHashCode();
            }
            if (WindDirection != 0)
            {
                hash ^= WindDirection.GetHashCode();
            }
            if (_unknownFields != null)
            {
                hash ^= _unknownFields.GetHashCode();
            }
            return(hash);
        }
示例#3
0
        internal void ChangeConstants(RainLevel rainLevel)
        {
            this.rainLevel   = rainLevel;
            bitmap           = rainbitmap;
            bitmapCenter     = rainCenter;
            bitmapBounds     = rainBounds;
            minLifetime      = 0;
            maxLifetime      = 0;
            minRotationSpeed = 0;
            maxRotationSpeed = 0;
            switch (rainLevel)
            {
            case RainLevel.light:
                InitializeLight();
                break;

            case RainLevel.moderate:
                Initializemoderate();
                break;

            case RainLevel.heavy:
                Initializeheavy();
                break;

            case RainLevel.extreme:
                Initializeextreme();
                break;

            case RainLevel.sSnow:
                InitializesSnow();
                break;

            case RainLevel.lSnow:
                InitializelSnow();
                break;

            case RainLevel.shower:
                InitializeShower();
                break;

            default:
                InitializeLight();
                break;
            }
            blendState = CanvasBlend.Add;
        }
示例#4
0
 private void SetShower()
 {
     if (Canvas == null)
     {
         return;
     }
     if (EnableDynamic)
     {
         var task = Canvas.RunOnGameLoopThreadAsync(async() =>
         {
             await rain.LoadSurfaceAsync(Canvas);
         });
     }
     isRain    = true;
     rainLevel = RainLevel.shower;
     SetOvercastBG();
     rain.ChangeConstants(rainLevel);
 }
示例#5
0
 /// <summary>
 /// 根据雨的规模设置初始化参数(已弃用,使用 <see cref="ChangeConstants(RainLevel)"/>)
 /// </summary>
 /// <param name="rainLevel"></param>
 protected void InitializeConstants(RainLevel rainLevel)
 {
 }
示例#6
0
        private IReadOnlyDictionary <string, string> GetProperties(DiscordGuild guild, WhConfig whConfig, string city, string weatherImageUrl)
        {
            var weather                 = Translator.Instance.GetWeather(GameplayCondition);
            var weatherKey              = $"weather_{Convert.ToInt32(GameplayCondition)}";
            var weatherEmoji            = MasterFile.Instance.Emojis.ContainsKey(weatherKey) && GameplayCondition != WeatherCondition.None ? GameplayCondition.GetWeatherEmojiIcon() : string.Empty;
            var hasWeather              = GameplayCondition != WeatherCondition.None;
            var gmapsLink               = string.Format(Strings.GoogleMaps, Latitude, Longitude);
            var appleMapsLink           = string.Format(Strings.AppleMaps, Latitude, Longitude);
            var wazeMapsLink            = string.Format(Strings.WazeMaps, Latitude, Longitude);
            var scannerMapsLink         = string.Format(whConfig.Urls.ScannerMap, Latitude, Longitude);
            var staticMapLink           = StaticMap.GetUrl(whConfig.Urls.StaticMap, whConfig.StaticMaps["weather"], Latitude, Longitude, weatherImageUrl, PokemonTeam.All, null, Polygon);
            var gmapsLocationLink       = UrlShortener.CreateShortUrl(whConfig.ShortUrlApiUrl, gmapsLink);
            var appleMapsLocationLink   = UrlShortener.CreateShortUrl(whConfig.ShortUrlApiUrl, appleMapsLink);
            var wazeMapsLocationLink    = UrlShortener.CreateShortUrl(whConfig.ShortUrlApiUrl, wazeMapsLink);
            var scannerMapsLocationLink = UrlShortener.CreateShortUrl(whConfig.ShortUrlApiUrl, scannerMapsLink);
            var address                 = new Location(null, city, Latitude, Longitude).GetAddress(whConfig);
            //var staticMapLocationLink = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? staticMapLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, staticMapLink);

            const string defaultMissingValue = "?";
            var          dict = new Dictionary <string, string>
            {
                //Main properties
                { "id", Id.ToString() },
                { "weather_condition", weather },
                { "has_weather", Convert.ToString(hasWeather) },
                { "weather", weather ?? defaultMissingValue },
                { "weather_emoji", weatherEmoji ?? defaultMissingValue },
                { "weather_img_url", weatherImageUrl },

                { "wind_direction", WindDirection.ToString() },
                { "wind_level", WindLevel.ToString() },
                { "raid_level", RainLevel.ToString() },
                { "cloud_level", CloudLevel.ToString() },
                { "fog_level", FogLevel.ToString() },
                { "snow_level", SnowLevel.ToString() },
                { "warn_weather", Convert.ToString(WarnWeather ?? false) },
                { "special_effect_level", SpecialEffectLevel.ToString() },
                { "severity", Severity.ToString() },

                //Location properties
                { "geofence", city ?? defaultMissingValue },
                { "lat", Latitude.ToString() },
                { "lng", Longitude.ToString() },
                { "lat_5", Latitude.ToString("0.00000") },
                { "lng_5", Longitude.ToString("0.00000") },

                //Location links
                { "tilemaps_url", staticMapLink },
                { "gmaps_url", gmapsLocationLink },
                { "applemaps_url", appleMapsLocationLink },
                { "wazemaps_url", wazeMapsLocationLink },
                { "scanmaps_url", scannerMapsLocationLink },

                { "address", address?.Address },

                // Discord Guild properties
                { "guild_name", guild?.Name },
                { "guild_img_url", guild?.IconUrl },

                { "date_time", DateTime.Now.ToString() },

                //Misc properties
                { "br", "\r\n" }
            };

            return(dict);
        }
示例#7
0
        private IReadOnlyDictionary <string, string> GetProperties(DiscordGuild guild, WhConfig whConfig, string city, string weatherImageUrl)
        {
            var weather                 = Translator.Instance.GetWeather(GameplayCondition);
            var weatherKey              = $"weather_{Convert.ToInt32(GameplayCondition)}";
            var weatherEmoji            = MasterFile.Instance.Emojis.ContainsKey(weatherKey) && GameplayCondition != WeatherType.None ? GameplayCondition.GetWeatherEmojiIcon() : string.Empty;
            var hasWeather              = GameplayCondition != WeatherType.None;
            var gmapsLink               = string.Format(Strings.GoogleMaps, Latitude, Longitude);
            var appleMapsLink           = string.Format(Strings.AppleMaps, Latitude, Longitude);
            var wazeMapsLink            = string.Format(Strings.WazeMaps, Latitude, Longitude);
            var scannerMapsLink         = string.Format(whConfig.Urls.ScannerMap, Latitude, Longitude);
            var templatePath            = Path.Combine(whConfig.StaticMaps.TemplatesFolder, whConfig.StaticMaps.Weather.TemplateFile);
            var staticMapLink           = Utils.GetStaticMapsUrl(templatePath, whConfig.Urls.StaticMap, whConfig.StaticMaps.Weather.ZoomLevel, Latitude, Longitude, weatherImageUrl, null);
            var gmapsLocationLink       = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? gmapsLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, gmapsLink);
            var appleMapsLocationLink   = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? appleMapsLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, appleMapsLink);
            var wazeMapsLocationLink    = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? wazeMapsLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, wazeMapsLink);
            var scannerMapsLocationLink = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? scannerMapsLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, scannerMapsLink);

            Geofence.Location address = null;
            if (!string.IsNullOrEmpty(whConfig.GoogleMapsKey))
            {
                address = Utils.GetGoogleAddress(city, Latitude, Longitude, whConfig.GoogleMapsKey);
            }
            else if (!string.IsNullOrEmpty(whConfig.NominatimEndpoint))
            {
                address = Utils.GetNominatimAddress(city, Latitude, Longitude, whConfig.NominatimEndpoint);
            }
            //var staticMapLocationLink = string.IsNullOrEmpty(whConfig.ShortUrlApiUrl) ? staticMapLink : NetUtil.CreateShortUrl(whConfig.ShortUrlApiUrl, staticMapLink);

            const string defaultMissingValue = "?";
            var          dict = new Dictionary <string, string>
            {
                //Main properties
                { "id", Id.ToString() },
                { "weather_condition", weather },
                { "has_weather", Convert.ToString(hasWeather) },
                { "weather", weather ?? defaultMissingValue },
                { "weather_emoji", weatherEmoji ?? defaultMissingValue },
                { "weather_img_url", weatherImageUrl },

                { "wind_direction", WindDirection.ToString() },
                { "wind_level", WindLevel.ToString() },
                { "raid_level", RainLevel.ToString() },
                { "cloud_level", CloudLevel.ToString() },
                { "fog_level", FogLevel.ToString() },
                { "snow_level", SnowLevel.ToString() },
                { "warn_weather", Convert.ToString(WarnWeather ?? false) },
                { "special_effect_level", SpecialEffectLevel.ToString() },
                { "severity", Severity.ToString() },

                //Location properties
                { "geofence", city ?? defaultMissingValue },
                { "lat", Latitude.ToString() },
                { "lng", Longitude.ToString() },
                { "lat_5", Math.Round(Latitude, 5).ToString() },
                { "lng_5", Math.Round(Longitude, 5).ToString() },

                //Location links
                { "tilemaps_url", staticMapLink },
                { "gmaps_url", gmapsLocationLink },
                { "applemaps_url", appleMapsLocationLink },
                { "wazemaps_url", wazeMapsLocationLink },
                { "scanmaps_url", scannerMapsLocationLink },

                { "address", address?.Address },

                // Discord Guild properties
                { "guild_name", guild?.Name },
                { "guild_img_url", guild?.IconUrl },

                { "date_time", DateTime.Now.ToString() },

                //Misc properties
                { "br", "\r\n" }
            };

            return(dict);
        }
 private void SetShower()
 {
     if (Canvas == null)
         return;
     if (EnableDynamic)
     {
         var task = Canvas.RunOnGameLoopThreadAsync(async () =>
         {
             await rain.LoadSurfaceAsync(Canvas);
         });
     }
     isRain = true;
     rainLevel = RainLevel.shower;
     SetOvercastBG();
     rain.ChangeConstants(rainLevel);
 }
 private void SetRain(int v)
 {
     isRain = true;
     if (EnableDynamic)
     {
         if (Canvas == null)
             return;
         var task = Canvas.RunOnGameLoopThreadAsync(async () =>
         {
             await rain.LoadSurfaceAsync(Canvas);
         });
     }
     switch (v)
     {
         default:
             rainLevel = RainLevel.light;
             break;
         case 0:
             rainLevel = RainLevel.light;
             break;
         case 1:
             rainLevel = RainLevel.moderate;
             break;
         case 2:
             rainLevel = RainLevel.heavy;
             break;
         case 3:
             rainLevel = RainLevel.extreme;
             break;
     }
     SetOvercastBG();
     rain.ChangeConstants(rainLevel);
 }
        /// <summary>
        /// 根据雨的规模设置初始化参数(已弃用,使用 <see cref="ChangeConstants(RainLevel)"/>)
        /// </summary>
        /// <param name="rainLevel"></param>
        protected void InitializeConstants(RainLevel rainLevel)
        {

        }
 internal void ChangeConstants(RainLevel rainLevel)
 {
     this.rainLevel = rainLevel;
     bitmap = rainbitmap;
     bitmapCenter = rainCenter;
     bitmapBounds = rainBounds;
     minLifetime = 0;
     maxLifetime = 0;
     minRotationSpeed = 0;
     maxRotationSpeed = 0;
     switch (rainLevel)
     {
         case RainLevel.light:
             InitializeLight();
             break;
         case RainLevel.moderate:
             Initializemoderate();
             break;
         case RainLevel.heavy:
             Initializeheavy();
             break;
         case RainLevel.extreme:
             Initializeextreme();
             break;
         case RainLevel.sSnow:
             InitializesSnow();
             break;
         case RainLevel.lSnow:
             InitializelSnow();
             break;
         case RainLevel.shower:
             InitializeShower();
             break;
         default:
             InitializeLight();
             break;
     }
     blendState = CanvasBlend.Add;
 }
示例#12
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;
                            }
                        }
                    }
                }
            }
        }
        override protected void triggerInternal(GameStateData previousGameState, GameStateData currentGameState)
        {
            currentConditions = currentGameState.Conditions.getMostRecentConditions();
            if (currentConditions != null)
            {
                if (airTempAtLastReport == float.MinValue)
                {
                    airTempAtLastReport   = currentConditions.AmbientTemperature;
                    trackTempAtLastReport = currentConditions.TrackTemperature;
                    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;
                    if (canReportAirChange || canReportTrackChange)
                    {
                        if (currentConditions.TrackTemperature > trackTempAtLastReport + minTrackTempDeltaToReport && currentConditions.AmbientTemperature > airTempAtLastReport + minAirTempDeltaToReport)
                        {
                            airTempAtLastReport   = currentConditions.AmbientTemperature;
                            trackTempAtLastReport = currentConditions.TrackTemperature;
                            lastAirTempReport     = currentGameState.Now;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airAndTrackTemp", MessageContents
                                                                          (folderAirAndTrackTempIncreasing, folderAirTempIsNow, convertTemp(currentConditions.AmbientTemperature),
                                                                          folderTrackTempIsNow, convertTemp(currentConditions.TrackTemperature), getTempUnit()), 0, this));
                            reportedCombinedTemps = true;
                        }
                        else if (currentConditions.TrackTemperature < trackTempAtLastReport - minTrackTempDeltaToReport && currentConditions.AmbientTemperature < airTempAtLastReport - minAirTempDeltaToReport)
                        {
                            airTempAtLastReport   = currentConditions.AmbientTemperature;
                            trackTempAtLastReport = currentConditions.TrackTemperature;
                            lastAirTempReport     = currentGameState.Now;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airAndTrackTemp", MessageContents
                                                                          (folderAirAndTrackTempDecreasing, folderAirTempIsNow, convertTemp(currentConditions.AmbientTemperature),
                                                                          folderTrackTempIsNow, convertTemp(currentConditions.TrackTemperature), getTempUnit()), 0, this));
                            reportedCombinedTemps = true;
                        }
                    }
                    if (!reportedCombinedTemps && canReportAirChange)
                    {
                        if (currentConditions.AmbientTemperature > airTempAtLastReport + minAirTempDeltaToReport)
                        {
                            airTempAtLastReport = currentConditions.AmbientTemperature;
                            lastAirTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airTemp", MessageContents
                                                                          (folderAirTempIncreasing, convertTemp(currentConditions.AmbientTemperature), getTempUnit()), 0, this));
                        }
                        else if (currentConditions.AmbientTemperature < airTempAtLastReport - minAirTempDeltaToReport)
                        {
                            airTempAtLastReport = currentConditions.AmbientTemperature;
                            lastAirTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("airTemp", MessageContents
                                                                          (folderAirTempDecreasing, convertTemp(currentConditions.AmbientTemperature), getTempUnit()), 0, this));
                        }
                    }
                    if (!reportedCombinedTemps && canReportTrackChange)
                    {
                        if (currentConditions.TrackTemperature > trackTempAtLastReport + minTrackTempDeltaToReport)
                        {
                            trackTempAtLastReport = currentConditions.TrackTemperature;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("trackTemp", MessageContents
                                                                          (folderTrackTempIncreasing, convertTemp(currentConditions.TrackTemperature), getTempUnit()), 0, this));
                        }
                        else if (currentConditions.TrackTemperature < trackTempAtLastReport - minTrackTempDeltaToReport)
                        {
                            trackTempAtLastReport = currentConditions.TrackTemperature;
                            lastTrackTempReport   = currentGameState.Now;
                            // do the reporting
                            audioPlayer.playMessage(new QueuedMessage("trackTemp", MessageContents
                                                                          (folderTrackTempDecreasing, convertTemp(currentConditions.TrackTemperature), getTempUnit()), 0, this));
                        }
                    }
                    if (currentGameState.Now > lastRainReport.Add(CrewChief.gameDefinition.gameEnum == GameEnum.RF2_64BIT ? RainReportMaxFrequencyRF2 : RainReportMaxFrequencyPCars))
                    {
                        // 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 (currentConditions.RainDensity == 0 && rainAtLastReport == 1)
                            {
                                rainAtLastReport = currentConditions.RainDensity;
                                lastRainReport   = currentGameState.Now;
                                audioPlayer.playMessage(new QueuedMessage(folderStoppedRaining, 0, this));
                            }
                            else if (currentConditions.RainDensity == 1 && rainAtLastReport == 0)
                            {
                                rainAtLastReport = currentConditions.RainDensity;
                                lastRainReport   = currentGameState.Now;
                                audioPlayer.playMessage(new QueuedMessage(folderSeeingSomeRain, 0, this));
                            }
                        }
                        else if (CrewChief.gameDefinition.gameEnum == GameEnum.RF2_64BIT)
                        {
                            RainLevel currentRainLevel      = getRainLevel(currentConditions.RainDensity);
                            RainLevel lastReportedRainLevel = getRainLevel(rainAtLastReport);
                            if (currentRainLevel != lastReportedRainLevel)
                            {
                                Boolean increasing = currentConditions.RainDensity > rainAtLastReport;
                                switch (currentRainLevel)
                                {
                                case RainLevel.DRIZZLE:
                                    audioPlayer.playMessage(new QueuedMessage(folderDrizzleIncreasing, 0, this));
                                    break;

                                case RainLevel.LIGHT:
                                    audioPlayer.playMessage(new QueuedMessage(increasing ? folderRainLightIncreasing : folderRainLightDecreasing, 0, this));
                                    break;

                                case RainLevel.MID:
                                    audioPlayer.playMessage(new QueuedMessage(increasing ? folderRainMidIncreasing : folderRainMidDecreasing, 0, this));
                                    break;

                                case RainLevel.HEAVY:
                                    audioPlayer.playMessage(new QueuedMessage(increasing ? folderRainHeavyIncreasing : folderRainHeavyDecreasing, 0, this));
                                    break;

                                case RainLevel.STORM:
                                    audioPlayer.playMessage(new QueuedMessage(folderRainMax, 0, this));
                                    break;

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