/// <summary> Main mod function. </summary> /// <param name="helper">The helper. </param> public override void Entry(IModHelper helper) { RWeatherIcon = new Rectangle(); WeatherOpt = helper.ReadConfig <WeatherConfig>(); Dice = new MersenneTwister(); DebugOutput = new StringBuilder(); OurMoon = new SDVMoon(WeatherOpt, Dice); OurIcons = new Sprites.Icons(Helper.Content); CropList = new List <Vector2>(); Conditions = new WeatherConditions(OurIcons, Dice, Helper.Translation, Monitor, WeatherOpt); StaminaMngr = new StaminaDrain(WeatherOpt, Helper.Translation, Monitor); SeedsForDialogue = new int[] { Dice.Next(), Dice.Next() }; DescriptionEngine = new Descriptions(Helper.Translation, Dice, WeatherOpt, Monitor); queuedMsg = null; Vector2 snowPos = Vector2.Zero; TicksOutside = 0; TicksTotal = 0; ExpireTime = 0; if (WeatherOpt.Verbose) { Monitor.Log($"Loading climate type: {WeatherOpt.ClimateType} from file", LogLevel.Trace); } string path = Path.Combine("data", "weather", WeatherOpt.ClimateType + ".json"); GameClimate = helper.ReadJsonFile <FerngillClimate>(path); if (GameClimate is null) { this.Monitor.Log($"The required '{path}' file is missing. Try reinstalling the mod to fix that.", LogLevel.Error); this.Monitor.Log("This mod will now disable itself.", LogLevel.Error); this.Disabled = true; } if (!Disabled) { //subscribe to events TimeEvents.AfterDayStarted += HandleNewDay; SaveEvents.BeforeSave += OnEndOfDay; TimeEvents.TimeOfDayChanged += TenMinuteUpdate; MenuEvents.MenuChanged += MenuEvents_MenuChanged; GameEvents.UpdateTick += CheckForChanges; SaveEvents.AfterReturnToTitle += ResetMod; SaveEvents.AfterLoad += SaveEvents_AfterLoad; GraphicsEvents.OnPostRenderGuiEvent += DrawOverMenus; GraphicsEvents.OnPreRenderHudEvent += DrawPreHudObjects; GraphicsEvents.OnPostRenderHudEvent += DrawObjects; LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; ControlEvents.KeyPressed += (sender, e) => this.ReceiveKeyPress(e.KeyPressed, this.WeatherOpt.Keyboard); MenuEvents.MenuClosed += (sender, e) => this.ReceiveMenuClosed(e.PriorMenu); //console commands helper.ConsoleCommands .Add("weather_settommorow", helper.Translation.Get("console-text.desc_tmrweather"), TomorrowWeatherChangeFromConsole) .Add("weather_changeweather", helper.Translation.Get("console-text.desc_setweather"), WeatherChangeFromConsole) .Add("world_solareclipse", "Starts the solar eclipse.", SolarEclipseEvent_CommandFired); } }
private string GetEveningFog(WeatherConditions Current) { if (Current.GenerateEveningFog) { var fList = Current.GetWeatherMatchingType("Fog"); foreach (ISDVWeather weat in fList) { if (weat is FerngillFog fWeat) { if (Current.GetWeatherMatchingType("Fog").First().IsWeatherVisible&& (SDVTime.CurrentTime > new SDVTime(1200))) { return(Helper.Get("weather-condition.fog", new { fogTime = fWeat.WeatherExpirationTime.ToString() })); } else { if (fWeat.WeatherBeginTime != fWeat.WeatherExpirationTime) { return(Helper.Get("weather-condition.evenFog", new { startTime = fWeat.WeatherBeginTime.ToString(), endTime = fWeat.WeatherExpirationTime.ToString() })); } else { return(""); } } } } return(""); } else { return(""); } }
private string GetCondWarning(WeatherConditions Current) { int rNumber = OurDice.Next(2); if (Current.ContainsCondition(CurrentWeather.Heatwave)) { return(Helper.Get($"weather-condition.heatwave.{rNumber}")); } if (Current.ContainsCondition(CurrentWeather.Frost)) { return(Helper.Get($"weather-condition.frost.{rNumber}")); } if (Current.ContainsCondition(CurrentWeather.WhiteOut)) { return(Helper.Get($"weather-condition.whiteout.{rNumber}")); } if (Current.ContainsCondition(CurrentWeather.ThunderFrenzy)) { return(Helper.Get($"weather-condition.thunderfrenzy.{rNumber}")); } return(""); }
internal static void SetWeatherTomorrow(string Result, MersenneTwister Dice, FerngillClimate GameClimate, double stormOdds, RangePair TmrwTemps) { //now parse the result. if (Result == "rain") { SDVUtilities.SetWeather(Game1.weather_rain); if (Game1.currentSeason == "winter") { SDVUtilities.SetWeather(Game1.weather_snow); if (GameClimate.AllowRainInWinter && ClimatesOfFerngill.Conditions.TomorrowHigh >= -2.5) { SDVUtilities.SetWeather(Game1.weather_rain); } } //Moved from the *wrong function and logic gate* //snow applies first if (WeatherConditions.IsValidWeatherForSnow(TmrwTemps) && Game1.currentSeason != "spring") { if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"Snow is enabled, with the High for the day being: {TmrwTemps.HigherBound}" + $" and the calculated midpoint temperature being {TmrwTemps.GetMidPoint()}"); } SDVUtilities.SetWeather(Game1.weather_snow); } //apply lightning logic. if (Dice.NextDoublePositive() >= stormOdds && Game1.weatherForTomorrow == Game1.weather_rain) { SDVUtilities.SetWeather(Game1.weather_lightning); if (SDate.Now().Year == 1 && SDate.Now().Season == "spring" && !ClimatesOfFerngill.WeatherOpt.AllowStormsSpringYear1) { SDVUtilities.SetWeather(Game1.weather_rain); } } //tracking time! - Snow fall on Fall 28, if the flag is set. if (Game1.dayOfMonth == 28 && Game1.currentSeason == "fall" && ClimatesOfFerngill.WeatherOpt.SnowOnFall28) { ClimatesOfFerngill.Conditions.ForceTodayTemps(2, -1); SDVUtilities.SetWeather(Game1.weather_snow); } } if (Result == "debris") { SDVUtilities.SetWeather(Game1.weather_debris); } if (Result == "sunny") { SDVUtilities.SetWeather(Game1.weather_sunny); } }
/********* ** Public methods *********/ /**** ** Constructors ****/ /// <summary>Construct an instance.</summary> public WeatherMenu(Sprites.Icons Icon, WeatherConditions weat, string text) { // save data MenuText = text; CurrentWeather = weat; IconSheet = Icon; // update layout UpdateLayout(); }
/// <summary> /// This function returns a description of the object. A very important note that this is meant for debugging, and as such does not do localization. /// </summary> /// <returns>A string describing the object.</returns> public override string ToString() { string ret = ""; ret += $"Low for today is {TodayTemps?.LowerBound:N3} with the high being {TodayTemps?.HigherBound:N3}. The current conditions are {Weathers[(int)CurrentConditionsN].ConditionName}."; foreach (ISDVWeather weather in CurrentWeathers) ret += weather.ToString() + Environment.NewLine; ret += $"Weather set for tommorow is {Weathers[(int)(WeatherConditions.ConvertToCurrentWeather(Game1.weatherForTomorrow))].ConditionName} with high {TomorrowTemps?.HigherBound:N3} and low {TomorrowTemps?.LowerBound:N3}. Evening fog generated {GenerateEveningFog} "; return ret; }
/********* ** Public methods *********/ /**** ** Constructors ****/ /// <summary>Construct an instance.</summary> /// <param name="monitor">Encapsulates logging and monitoring.</param> public WeatherMenu(IMonitor monitor, IReflectionHelper reflectionHelper, Sprites.Icons Icon, WeatherConditions weat, string text) { // save data MenuText = text; Monitor = monitor; Reflection = reflectionHelper; CurrentWeather = weat; IconSheet = Icon; // update layout UpdateLayout(); }
private string GetBasicWeather(WeatherConditions Weather) { if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconBlizzard || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWhiteOut) { return(Translator.Get($"weather_blizzard")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSandstorm) { return(Translator.Get($"weather_sandstorm")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSpringDebris || Weather.CurrentWeatherIconBasic == WeatherIcon.IconDebris) { return(Translator.Get($"weather_wind")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconDryLightning) { return(Translator.Get($"weather_drylightning")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime < Game1.getModeratelyDarkTime()) { return(Translator.Get($"weather_sunny_daytime")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime >= Game1.getModeratelyDarkTime()) { return(Translator.Get($"weather_sunny_nighttime")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconStorm) { return(Translator.Get($"weather_lightning")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSnow) { return(Translator.Get($"weather_snow")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconRain) { return(Translator.Get($"weather_rainy")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconThunderSnow) { return(Translator.Get($"weather_thundersnow")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding) { return(Translator.Get($"weather_wedding")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival) { return(Translator.Get($"weather_festival")); } return("ERROR"); }
private string GetWeather(WeatherConditions Weather, int day, string season) { if (day == 28) { season = GetNextSeason(season); } int rNumber = OurDice.Next(2); if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconBlizzard || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWhiteOut) { return(Helper.Get($"weat-{season}.blizzard.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSpringDebris || Weather.CurrentWeatherIconBasic == WeatherIcon.IconDebris) { return(Helper.Get($"weat-{season}.debris.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconDryLightning) { return(Helper.Get($"weat-{season}.drylightning.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding || Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival || Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny && SDVTime.CurrentIntTime < Game1.getModeratelyDarkTime()) { return(Helper.Get($"weat-{season}.sunny_daytime.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSunny || Weather.CurrentWeatherIconBasic == WeatherIcon.IconWedding || Weather.CurrentWeatherIconBasic == WeatherIcon.IconFestival && SDVTime.CurrentIntTime >= Game1.getModeratelyDarkTime()) { return(Helper.Get($"weat-{season}.sunny_nighttime.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconStorm) { return(Helper.Get($"weat-{season}.stormy.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconSnow) { return(Helper.Get($"weat-{season}.snow.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconRain) { return(Helper.Get($"weat-{season}.rainy.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconThunderSnow) { return(Helper.Get($"weat-{season}.thundersnow.{rNumber}")); } else if (Weather.CurrentWeatherIconBasic == WeatherIcon.IconBloodMoon) { return(Helper.Get($"weat-bloodmoon")); } return("ERROR"); }
/********* ** Public methods *********/ /**** ** Constructors ****/ /// <summary>Construct an instance.</summary> /// <param name="monitor">Encapsulates logging and monitoring.</param> public WeatherMenu(IMonitor monitor, IReflectionHelper reflectionHelper, Sprites.Icons Icon, ITranslationHelper Helper, WeatherConditions weat, SDVMoon Termina, WeatherConfig ModCon, string text) { // save data this.MenuText = text; this.Monitor = monitor; this.Reflection = reflectionHelper; this.Helper = Helper; this.CurrentWeather = weat; this.IconSheet = Icon; this.OurMoon = Termina; this.OurConfig = ModCon; // update layout this.UpdateLayout(); }
internal static HUDMessage HandleOnSaving(WeatherConditions Conditions, MersenneTwister Dice) { if (Conditions.HasWeather(CurrentWeather.Frost) && ClimatesOfFerngill.WeatherOpt.AllowCropDeath) { Farm f = Game1.getFarm(); int count = 0, maxCrops = (int)Math.Floor(SDVUtilities.CropCountInFarm(f) * ClimatesOfFerngill.WeatherOpt.DeadCropPercentage); foreach (KeyValuePair <Vector2, TerrainFeature> tf in f.terrainFeatures.Pairs) { if (count >= maxCrops) { break; } if (tf.Value is HoeDirt curr && curr.crop != null) { Crop test = new Crop(curr.crop.indexOfHarvest.Value, 0, 0); if (Dice.NextDouble() > ClimatesOfFerngill.WeatherOpt.CropResistance && (!test.seasonsToGrowIn.Contains("winter") || !SDVUtilities.IsWinterForageable(test.indexOfHarvest.Value))) { CropList.Add(tf.Key); count++; } } } if (count > 0) { foreach (Vector2 v in CropList) { HoeDirt hd = (HoeDirt)f.terrainFeatures[v]; hd.crop.dead.Value = true; } return(new HUDMessage( ClimatesOfFerngill.Translator.Get("hud-text.desc_frost_killed", new { deadCrops = count }), Color.SeaGreen, 5250f, true) { whatType = 2 }); } } return(null); }
internal static void CheckForStaticRainChanges(WeatherConditions curr, MersenneTwister Dice, double ChanceForNonNormalRain) { if (Game1.isLightning && Game1.isRaining) { curr.SetRainAmt(130); } double rainOdds, newRainOdds; rainOdds = Dice.NextDouble(); newRainOdds = Dice.NextDouble(); //random chance to just set rain at a differnt number if (rainOdds < ChanceForNonNormalRain) { //yay use of probablity distribution ProbabilityDistribution <RainLevels> RainSpread = new ProbabilityDistribution <RainLevels>(RainLevels.Normal); RainSpread.AddNewCappedEndPoint(.12, RainLevels.Sunshower); RainSpread.AddNewCappedEndPoint(.28, RainLevels.Light); RainSpread.AddNewCappedEndPoint(.351, RainLevels.Normal); RainSpread.AddNewCappedEndPoint(.1362, RainLevels.Moderate); RainSpread.AddNewCappedEndPoint(.09563, RainLevels.Heavy); RainSpread.AddNewCappedEndPoint(.0382, RainLevels.Severe); RainSpread.AddNewCappedEndPoint(.0094, RainLevels.Torrential); RainSpread.AddNewCappedEndPoint(.0049, RainLevels.Typhoon); RainSpread.AddNewCappedEndPoint(.00287, RainLevels.NoahsFlood); if (!(RainSpread.GetEntryFromProb(newRainOdds, out RainLevels Result))) { Result = RainLevels.Normal; ClimatesOfFerngill.Logger.Log("The rain probablity spread has failed to find an rain level. Falling back to normal rain", LogLevel.Error); } curr.SetRainAmt(WeatherUtilities.ReturnRndRainAmtInLevel(Dice, Result)); if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"We've set the rain to a non normal value - with roll {rainOdds} for setting non normal, and {newRainOdds} for category {Result}, resulting in new rain target {curr.AmtOfRainDrops} in category {WeatherUtilities.GetRainCategory(curr.AmtOfRainDrops)}"); } } curr.TodayRain += curr.AmtOfRainDrops; curr.RefreshRainAmt(); }
internal TemporaryAnimatedSprite GetWeatherOverlay(WeatherConditions Current, TV tv) { Rectangle placement = new Rectangle(413, 333, 13, 13); switch (Current.CurrentWeatherIconBasic) { case WeatherIcon.IconSunny: case WeatherIcon.IconWedding: case WeatherIcon.IconDryLightning: placement = new Rectangle(413, 333, 13, 13); break; case WeatherIcon.IconRain: placement = new Rectangle(465, 333, 13, 13); break; case WeatherIcon.IconDebris: placement = (Game1.currentSeason.Equals("fall") ? new Rectangle(413, 359, 13, 13) : new Rectangle(465, 346, 13, 13)); break; case WeatherIcon.IconSpringDebris: placement = new Rectangle(465, 359, 13, 13); break; case WeatherIcon.IconStorm: placement = new Rectangle(413, 346, 13, 13); break; case WeatherIcon.IconFestival: placement = new Rectangle(413, 372, 13, 13); break; case WeatherIcon.IconSnow: case WeatherIcon.IconBlizzard: case WeatherIcon.IconWhiteOut: placement = new Rectangle(465, 346, 13, 13); break; } return(new TemporaryAnimatedSprite("LooseSprites\\Cursors", placement, 100f, 4, 999999, tv.getScreenPosition() + new Vector2(3f, 3f) * tv.getScreenSizeModifier(), false, false, (float)((double)(tv.boundingBox.Bottom - 1) / 10000.0 + 1.99999994947575E-05), 0.0f, Color.White, tv.getScreenSizeModifier(), 0.0f, 0.0f, 0.0f, false)); }
internal static double GetWeatherSystemOddsForNewDay(WeatherConditions conditions) { int nextDay = conditions.trackerModel.WeatherSystemDays + 1; double defaultOdds = -.08333333 * nextDay + .14; //+14% not +1400% self. :| //Console.WriteLine($"Odds generated for day {nextDay} of system are {defaultOdds} before curving the results"); //this slope is added to give a small curve to the slope. if (nextDay >= 6) { defaultOdds += -.083333333 * nextDay + .5; } //Console.WriteLine($"Odds generated for day {nextDay} of system are {defaultOdds} after curving the results"); if (defaultOdds < 0) { return(0); } return(defaultOdds); }
internal string GenerateTVForecast(WeatherConditions Current, MersenneTwister Dice, double fogOdds, string MoonPhase = "", bool IsMoonUp = false) { string ret = ""; //opening string ret += Translator.Get("weather-tv.opening", new { location = Translator.Get("fern-loc." + Dice.Next(12)), playerLocation = Translator.Get("weather-location.player." + Dice.Next(4)) }); //hazard warning if (MoonPhase == "Blood Moon" && IsMoonUp) { ret += Translator.Get("weather-tv.bloodmoon"); } if (Current.WeatherIsHazardous()) { string hazard = "", rainfallW = "", hazardT = "", hazardF; if (Current.HasWeather(CurrentWeather.Heatwave)) { hazardT = Translator.Get("weather-tv.hazard.hw"); } if (Current.HasWeather(CurrentWeather.Frost)) { hazardT = Translator.Get("weather-tv.hazard.frost"); } if (Current.HasWeather(CurrentWeather.Blizzard)) { hazard = Translator.Get("weather-tv.hazard.blizzard"); } if (Current.HasWeather(CurrentWeather.WhiteOut)) { hazard = Translator.Get("weather-tv.hazard.whiteout"); } if (Current.HasWeather(CurrentWeather.ThunderFrenzy)) { hazard = Translator.Get("weather-tv.hazard.thunderfrenzy"); } if (Current.HasWeather(CurrentWeather.Sandstorm)) { hazard = Translator.Get("weather-tv.hazard.sandstorm"); } if (WeatherUtilities.IsSevereRainFall(Current.AmtOfRainDrops)) { switch (WeatherUtilities.GetRainCategory(Current.AmtOfRainDrops)) { case RainLevels.Severe: hazard = Translator.Get("weather-tv.hazard.rainfall.severe"); break; case RainLevels.Torrential: hazard = Translator.Get("weather-tv.hazard.rainfall.torrential"); break; case RainLevels.Typhoon: hazard = Translator.Get("weather-tv.hazard.rainfall.typhoon"); break; case RainLevels.NoahsFlood: hazard = Translator.Get("weather-tv.hazard.rainfall.noahsflood"); break; default: hazard = Translator.Get("weather-tv.hazard.rainfall.severe"); break; } rainfallW = Translator.Get("weather-tv.hazard.rainfallW"); } if (!String.IsNullOrEmpty(hazard) && !String.IsNullOrEmpty(hazardT)) { hazardF = Translator.Get("weather-tv.twoHazardString", new { hazardOne = hazard, hazardTwo = hazardT }); } else if (!String.IsNullOrEmpty(hazard)) { hazardF = hazard; } else { hazardF = hazardT; } ret += Translator.Get("weather-tv.hazard", new { hazard = hazardF, repLocation = Translator.Get("weather-location.reporter." + Dice.Next(4)), rainfallWarning = rainfallW }); } //current conditions string time; switch (SDVTime.CurrentTimePeriod) { case SDVTimePeriods.Morning: time = Translator.Get("weather-tv.time.morning"); break; case SDVTimePeriods.Noon: case SDVTimePeriods.Afternoon: time = Translator.Get("weather-tv.time.afternoon"); break; case SDVTimePeriods.Evening: time = Translator.Get("weather-tv.time.evening"); break; case SDVTimePeriods.Night: time = Translator.Get("weather-tv.time.night"); break; case SDVTimePeriods.Midnight: case SDVTimePeriods.LateNight: time = Translator.Get("weather-tv.time.latenight"); break; default: time = Translator.Get("weather-tv.time.generic"); break; } string abText = ""; if (Current.IsAbnormalHeat) { abText = Translator.Get("weather-tv.abnormalHeat"); } if (Current.IsAbnormalChill) { abText = Translator.Get("weather-tv.abnormalChill"); } string sysText = ""; if (Current.trackerModel.WeatherSystemDays > 0) { if (Current.trackerModel.IsWeatherSystem) { sysText = Translator.Get("weather-tv.systemMaint"); } } //the first monster, describing the weather. string dWeather = ""; if (!String.IsNullOrEmpty(SDVUtilities.GetFestivalName(SDate.Now()))) { dWeather = Translator.Get("weather-tv.weat.festival", new { festivalName = SDVUtilities.GetFestivalName(SDate.Now()) }); } if (Current.HasWeather(CurrentWeather.Wedding)) { dWeather = Translator.Get("weather-tv.weat.wedding"); } if (Current.HasWeather(CurrentWeather.Sunny)) { dWeather = Translator.Get("weather-tv.weat.sunny"); } if (Current.HasWeather(CurrentWeather.Rain) && !Current.HasWeather(CurrentWeather.Lightning)) { dWeather = (Current.IsVariableRain ? Translator.Get("weather-tv.weat.rain.variable", new { rainDesc = GetRainDesc(Current.AmtOfRainDrops).Trim() }) : Translator.Get("weather-tv.weat.rain", new { rainDesc = GetRainDesc(Current.AmtOfRainDrops).Trim() })); } if (Current.HasWeather(CurrentWeather.Rain) && Current.HasWeather(CurrentWeather.Lightning) && !Current.HasWeather(CurrentWeather.ThunderFrenzy)) { dWeather = Translator.Get("weather-tv.weat.thunderstorm"); } if (Current.HasWeather(CurrentWeather.ThunderFrenzy)) { dWeather = Translator.Get("weather-tv.weat.thunderfrenzy"); } if (!Current.HasWeather(CurrentWeather.Rain) && Current.HasWeather(CurrentWeather.Lightning)) { dWeather = Translator.Get("weather-tv.weat.drylightning"); } if (Current.HasWeather(CurrentWeather.Blizzard) && !Current.HasWeather(CurrentWeather.WhiteOut)) { dWeather = Translator.Get("weather-tv.weat.blizzard"); } if (Current.HasWeather(CurrentWeather.WhiteOut)) { dWeather = Translator.Get("weather-tv.weat.whiteout"); } if (Current.HasWeather(CurrentWeather.Snow) && !Current.HasWeather(CurrentWeather.Blizzard) && !Current.HasWeather(CurrentWeather.WhiteOut) && !Current.HasWeather(CurrentWeather.Lightning)) { dWeather = Translator.Get("weather-tv.weat.snowy"); } if (Current.HasWeather(CurrentWeather.Snow) && !Current.HasWeather(CurrentWeather.Blizzard) && !Current.HasWeather(CurrentWeather.WhiteOut) && Current.HasWeather(CurrentWeather.Lightning)) { dWeather = Translator.Get("weather-tv.weat.thundersnow"); } if (Current.HasWeather(CurrentWeather.Sandstorm)) { dWeather = Translator.Get("weather-tv.weat.sandstorms"); } if (Current.HasWeather(CurrentWeather.Wind)) { if (Game1.currentSeason == "winter") { dWeather = Translator.Get("weather-tv.weat.windy.winter"); } else { dWeather = Translator.Get("weather-tv.weat.windy"); } } string fog = ""; if (Current.HasWeather(CurrentWeather.Fog)) { if (!Current.HasWeather(CurrentWeather.Wedding)) { fog = Translator.Get("weather-tv.weat.fog", new { time = Current.GetFogTime() }); } else { fog = Translator.Get("weather-tv.weat.fogWed", new { time = Current.GetFogTime() }); } } //ending up the current conditions. string tHazard = ""; if (Current.HasWeather(CurrentWeather.Heatwave)) { tHazard = Translator.Get("weather-tv.tempHazard.heat"); } if (Current.HasWeather(CurrentWeather.Frost)) { tHazard = Translator.Get("weather-tv.tempHazard.cold", new { time = (Game1.currentSeason == "spring" ? Translator.Get("weather-tv.tempHazard.cold.spring") : Translator.Get("weather-tv.tempHazard.cold.fall")) }); } string rRate = ""; if (Current.HasWeather(CurrentWeather.Rain)) { rRate = Translator.Get("weather-tv.rainfallRate", new { rate = WeatherUtilities.GetRainfallAmt(Current.AmtOfRainDrops).ToString("N2") }); } var transParams = new Dictionary <string, string> { { "time", time }, { "currentTemp", GetTemperatureString(Current.GetCurrentTemperature(Game1.timeOfDay)) }, { "abnormalText", abText }, { "systemText", sysText }, { "descWeather", dWeather }, { "fogText", fog }, { "tempHazard", tHazard }, { "rainfallRate", rRate } }; ret += Translator.Get("weather-tv.currentCond", transParams); transParams.Clear(); //now, tomorrow!! :D sysText = ""; if (Current.trackerModel.WeatherSystemDays > 0) { if (Current.trackerModel.IsWeatherSystem) { sysText = Translator.Get("weather-tv.tmrw.systemMaint", new { desc = Translator.Get("weather-location.system.desc." + Dice.Next(6)) }); } if (!Current.trackerModel.IsWeatherSystem && (Game1.weatherForTomorrow != WeatherUtilities.GetWeatherCode())) { sysText = Translator.Get("weather-tv.tmrw.systemEnding", new { desc = Translator.Get("weather-location.system.desc." + Dice.Next(6)), direction = Translator.Get("weather-location.system.move." + Dice.Next(4)) }); } } else { sysText = Translator.Get("weather-tv.tmrw.systemNone"); } //now weather switch (Game1.weatherForTomorrow) { case Game1.weather_rain: dWeather = Translator.Get("weather-tv.rain." + Dice.Next(2)); break; case Game1.weather_festival: dWeather = Translator.Get("weather-tv.festival", new { festName = SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) }); break; case Game1.weather_debris: dWeather = Translator.Get("weather-tv.debris." + Dice.Next(2)); break; case Game1.weather_snow: dWeather = Translator.Get("weather-tv.snowy." + Dice.Next(2)); break; case Game1.weather_wedding: dWeather = Translator.Get("weather-tv.wedding"); break; case Game1.weather_lightning: dWeather = Translator.Get("weather-tv.tstorm." + Dice.Next(2)); break; case Game1.weather_sunny: default: dWeather = Translator.Get("weather-tv.sunny." + Dice.Next(2)); break; } //overrides for festival and wedding (just in case, my paranoia is spiking. :|) if (!String.IsNullOrEmpty(SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)))) { dWeather = Translator.Get("weather-tv.festival", new { festName = SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) }); } if (Game1.player.spouse != null && Game1.player.isEngaged() && Game1.player.friendshipData[Game1.player.spouse].CountdownToWedding == 1) { dWeather = Translator.Get("weather-tv.wedding"); } fog = ""; //now, the fog string if (fogOdds >= .6) { fog = Translator.Get("weather-tv.fogChance"); } //tHazard string if (Current.TomorrowHigh > (Current.TodayHigh + 1.5)) { tHazard = Translator.Get("weather-tv.tmrw.warmer", new { high = GetTemperatureString(Current.TomorrowHigh), low = GetTemperatureString(Current.TomorrowLow), }); } else if ((Current.TomorrowHigh < (Current.TodayHigh - 1.5))) { tHazard = Translator.Get("weather-tv.tmrw.cooler", new { high = GetTemperatureString(Current.TomorrowHigh), low = GetTemperatureString(Current.TomorrowLow), }); } else { tHazard = Translator.Get("weather-tv.tmrw.effsame", new { high = GetTemperatureString(Current.TomorrowHigh), low = GetTemperatureString(Current.TomorrowLow), }); } transParams.Add("sysText", sysText); transParams.Add("weather", dWeather); transParams.Add("fogChance", fog); transParams.Add("tempString", tHazard); ret += Translator.Get("weather-tv.tomorrowForecast", transParams); return(ret); }
internal string GenerateMenuPopup(WeatherConditions Current, string MoonPhase = "", string NightTime = "") { string text; if (SDate.Now().Season == "spring" && SDate.Now().Day == 1) { text = Translator.Get("weather-menu.openingS1D1", new { descDay = Translator.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } else if (SDate.Now().Season == "winter" && SDate.Now().Day == 28) { text = Translator.Get("weather-menu.openingS4D28", new { descDay = Translator.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } else { text = Translator.Get("weather-menu.opening", new { descDay = Translator.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.Sandstorm)) { text += Translator.Get("weather-menu.condition.sandstorm") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.Heatwave)) { text += Translator.Get("weather-menu.condition.heatwave") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.Frost)) { text += Translator.Get("weather-menu.condition.frost") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.WhiteOut)) { text += Translator.Get("weather-menu.condition.whiteOut") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.ThunderFrenzy)) { text += Translator.Get("weather-menu.condition.thunderFrenzy") + Environment.NewLine; } if (Current.IsVariableRain) { switch (WeatherUtilities.GetRainCategory(Current.AmtOfRainDrops)) { case RainLevels.Severe: text += Translator.Get("weather-condition.vrain.severe_sw") + Environment.NewLine; break; case RainLevels.Torrential: text += Translator.Get("weather-condition.vrain.torrential_sw") + Environment.NewLine; break; case RainLevels.Typhoon: text += Translator.Get("weather-condition.vrain.typhoon_sw") + Environment.NewLine; break; case RainLevels.NoahsFlood: text += Translator.Get("weather-condition.vrain.godswrath_sw") + Environment.NewLine; break; default: break; } } if (MoonPhase == "Blood Moon") { text += Translator.Get("weather-menu.condition.bloodmoon") + Environment.NewLine; } if (ClimatesOfFerngill.UseLunarDisturbancesApi && ClimatesOfFerngill.MoonAPI.IsSolarEclipse()) { text += Translator.Get("weather-menu.condition.solareclipse") + Environment.NewLine; } ISDVWeather CurrentFog = Current.GetWeatherMatchingType("Fog").First(); string fogString = ""; // If the fog is visible, we don't need to display fog information. However, if it's in the morning, // and we know evening fog is likely, we should display the message it's expected // That said, if it's not, we need to pull the fog information down, assuming it's been reset. This checks that the fog end // time is *before* now. To avoid nested trinary statements.. if (SDVTime.CurrentTime < CurrentFog.WeatherExpirationTime && Current.GenerateEveningFog && CurrentFog.WeatherBeginTime < new SDVTime(1200)) { fogString = Translator.Get("weather-menu.expectedFog"); } if (CurrentFog.WeatherBeginTime > SDVTime.CurrentTime && Current.GenerateEveningFog) { fogString = Translator.Get("weather-menu.fogFuture", new { fogTime = CurrentFog.WeatherBeginTime.ToString(), endFog = CurrentFog.WeatherExpirationTime.ToString() }); } //Current Conditions. string currentMenu; if (Current.HasWeather(CurrentWeather.Rain) && Current.IsVariableRain) { currentMenu = "weather-menu.currentRainfall"; } else { currentMenu = "weather-menu.current"; } text += Translator.Get(currentMenu, new { todayCondition = Current.HasWeather(CurrentWeather.Fog) ? Translator.Get("weather-menu.fog", new { condition = GetBasicWeather(Current), fogTime = CurrentFog.IsWeatherVisible ? CurrentFog.WeatherExpirationTime.ToString() : "" }) : GetBasicWeather(Current), tempString = GetTemperatureString(Current.GetCurrentTemperature(Game1.timeOfDay)), todayHigh = GetTemperatureString(Current.TodayHigh), todayLow = GetTemperatureString(Current.TodayLow), currentRainfall = WeatherUtilities.GetRainfallAmt(Current.AmtOfRainDrops).ToString("N2"), fogString }) + Environment.NewLine; //Tomorrow weather text += Translator.Get("weather-menu.tomorrow", new { tomorrowCondition = GetBasicWeather(Game1.weatherForTomorrow), tomorrowLow = GetTemperatureString(Current.TomorrowLow), tomorrowHigh = GetTemperatureString(Current.TomorrowHigh) }) + Environment.NewLine; //now, night time if (!String.IsNullOrEmpty(NightTime)) { text += NightTime + Environment.NewLine; } if (ClimatesOfFerngill.UseLunarDisturbancesApi) { if (ClimatesOfFerngill.MoonAPI.IsMoonUp(Game1.timeOfDay)) { text += Translator.Get("weather-menu.desc-moonNotUp", new { moonPhase = ClimatesOfFerngill.MoonAPI.GetCurrentMoonPhase(), moonRise = ClimatesOfFerngill.MoonAPI.GetMoonRise(), moonSet = ClimatesOfFerngill.MoonAPI.GetMoonSet() }); } else { text += Translator.Get("weather-menu.desc-moonUp", new { moonPhase = ClimatesOfFerngill.MoonAPI.GetCurrentMoonPhase(), moonSet = ClimatesOfFerngill.MoonAPI.GetMoonSet() }); } } //new line replacer text.Replace("[NLK]", Environment.NewLine); return(text); }
internal static void ProcessHazardousCropWeather(WeatherConditions curr, int timeOfDay, MersenneTwister Dice) { //frost works at night, heatwave works during the day if (timeOfDay == 1700) { if (curr.HasWeather(CurrentWeather.Heatwave) || curr.HasWeather(CurrentWeather.Sandstorm)) { ClimatesOfFerngill.Logger.Log("Beginning Heatwave code"); ExpireTime = 2000; Farm f = Game1.getFarm(); int count = 0, maxCrops = (int)Math.Floor(SDVUtilities.CropCountInFarm(f) * ClimatesOfFerngill.WeatherOpt.DeadCropPercentage); foreach (KeyValuePair <Vector2, TerrainFeature> tf in f.terrainFeatures.Pairs) { if (count >= maxCrops) { break; } if (tf.Value is HoeDirt dirt && dirt.crop != null) { if (Dice.NextDouble() <= ClimatesOfFerngill.WeatherOpt.CropResistance) { if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"Dewatering crop at {tf.Key}. Crop is {dirt.crop.indexOfHarvest}"); } CropList.Add(tf.Key); dirt.state.Value = HoeDirt.dry; count++; } } } if (CropList.Count > 0) { if (ClimatesOfFerngill.WeatherOpt.AllowCropDeath) { if (curr.HasWeather(CurrentWeather.Heatwave) && !curr.HasWeather(CurrentWeather.Sandstorm)) { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_heatwave_kill", new { crops = count }), 3); } if (curr.HasWeather(CurrentWeather.Sandstorm)) { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_sandstorm_kill", new { crops = count }), 3); } } else { if (curr.HasWeather(CurrentWeather.Heatwave) && !curr.HasWeather(CurrentWeather.Sandstorm)) { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_heatwave_dry", new { crops = count }), 3); } if (curr.HasWeather(CurrentWeather.Sandstorm)) { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_sandstorm_dry", new { crops = count }), 3); } } } else { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_heatwave"), 3); } } } if (Game1.timeOfDay == ExpireTime && ClimatesOfFerngill.WeatherOpt.AllowCropDeath) { ClimatesOfFerngill.Logger.Log("Beginning Crop Death code"); //if it's still de watered - kill it. Farm f = Game1.getFarm(); bool cDead = false; foreach (Vector2 v in CropList) { HoeDirt hd = (HoeDirt)f.terrainFeatures[v]; if (hd.state.Value == HoeDirt.dry) { if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"Killing crop at {v}. Crop is {hd.crop.indexOfHarvest}"); } hd.crop.dead.Value = true; cDead = true; } } CropList.Clear(); //clear the list if (cDead) { SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_heatwave_cropdeath"), 3); } } }
internal static bool TestForSpecialWeather(WeatherConditions curr, FerngillClimateTimeSpan ClimateForDay) { bool specialWeatherTriggered = false; // Conditions: Blizzard - occurs in weather_snow in "winter" // Dry Lightning - occurs if it's sunny in any season if temps exceed 25C. // Frost and Heatwave check against the configuration. // Thundersnow - as Blizzard, but really rare. Will not happen in fog, may happen in Blizzard/WhiteOut // Sandstorm - windy, with no precip for several days. Spring-Fall only, highest chance in summer. // Fog - per climate, although night fog in winter is double normal chance curr.GenerateEveningFog = (ClimatesOfFerngill.Dice.NextDouble() < ClimateForDay.EveningFogChance * ClimateForDay.RetrieveOdds(ClimatesOfFerngill.Dice, "fog", Game1.dayOfMonth)) && !curr.GetCurrentConditions().HasFlag(CurrentWeather.Wind); bool blockFog = ClimatesOfFerngill.MoonAPI != null && ClimatesOfFerngill.MoonAPI.IsSolarEclipse(); if (blockFog || ClimatesOfFerngill.WeatherOpt.DisableAllFog) { curr.GenerateEveningFog = false; } double fogRoll = (ClimatesOfFerngill.WeatherOpt.DisableAllFog ? 1.1 : ClimatesOfFerngill.Dice.NextDoublePositive()); if (fogRoll < ClimateForDay.RetrieveOdds(ClimatesOfFerngill.Dice, "fog", Game1.dayOfMonth) && !curr.GetCurrentConditions().HasFlag(CurrentWeather.Wind) && !blockFog) { curr.CreateWeather("Fog"); if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"{curr.FogDescription(fogRoll, ClimateForDay.RetrieveOdds(ClimatesOfFerngill.Dice, "fog", Game1.dayOfMonth))}"); } specialWeatherTriggered = true; } //set special temps before we check for the results of them if (ClimatesOfFerngill.Dice.NextDouble() < ClimateForDay.HeatwaveChance) { SetHotwave(); } else if (ClimatesOfFerngill.Dice.NextDouble() < ClimateForDay.ChillwaveChance) { SetChillWave(); } //do these here //20190626 - Thanks to Crops Anywhere, I have to add this if ((curr.TodayLow < ClimatesOfFerngill.WeatherOpt.TooColdOutside && !Game1.IsWinter) || (curr.TodayLow < ClimatesOfFerngill.WeatherOpt.TooColdOutside && Game1.IsWinter && ClimatesOfFerngill.WeatherOpt.ApplyFrostsInWinter)) { if (ClimatesOfFerngill.WeatherOpt.HazardousWeather) { curr.AddWeather(CurrentWeather.Frost); specialWeatherTriggered = true; } } //test for spring conversion if (curr.HasWeather(CurrentWeather.Rain) && curr.HasWeather(CurrentWeather.Frost) && (Game1.currentSeason == "spring" || Game1.currentSeason == "fall") && ClimatesOfFerngill.Dice.NextDoublePositive() <= ClimatesOfFerngill.WeatherOpt.RainToSnowConversion) { curr.RemoveWeather(CurrentWeather.Rain); curr.AddWeather(CurrentWeather.Snow); Game1.isRaining = false; Game1.isSnowing = true; specialWeatherTriggered = true; } if (curr.HasWeather(CurrentWeather.Snow)) { double blizRoll = ClimatesOfFerngill.Dice.NextDoublePositive(); double blizOdds = ClimateForDay.RetrieveOdds(ClimatesOfFerngill.Dice, "blizzard", Game1.dayOfMonth); if (blizRoll <= blizOdds) { curr.CreateWeather("Blizzard"); if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"With roll {blizRoll:N3} against {blizOdds}, there will be blizzards today"); } if (ClimatesOfFerngill.Dice.NextDoublePositive() < ClimatesOfFerngill.WeatherOpt.WhiteOutChances && ClimatesOfFerngill.WeatherOpt.HazardousWeather) { curr.CreateWeather("WhiteOut"); } } specialWeatherTriggered = true; } //Dry Lightning is also here for such like the dry and arid climates // which have so low rain chances they may never storm. if (curr.HasWeather(CurrentWeather.Snow)) { double oddsRoll = ClimatesOfFerngill.Dice.NextDoublePositive(); double thunderSnowOdds = ClimateForDay.RetrieveOdds(ClimatesOfFerngill.Dice, "storm", Game1.dayOfMonth); if (oddsRoll <= thunderSnowOdds && !curr.HasWeather(CurrentWeather.Fog)) { curr.AddWeather(CurrentWeather.Lightning); if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"With roll {oddsRoll:N3} against {thunderSnowOdds}, there will be thundersnow today"); } specialWeatherTriggered = true; } } if (!(curr.HasPrecip())) { double oddsRoll = ClimatesOfFerngill.Dice.NextDoublePositive(); if (oddsRoll <= ClimatesOfFerngill.WeatherOpt.DryLightning && curr.TodayHigh >= ClimatesOfFerngill.WeatherOpt.DryLightningMinTemp && !curr.HasWeather(CurrentWeather.Frost)) { curr.AddWeather(CurrentWeather.Lightning); if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"With roll {oddsRoll:N3} against {ClimatesOfFerngill.WeatherOpt.DryLightning}, there will be dry lightning today."); } specialWeatherTriggered = true; } if (curr.TodayHigh > ClimatesOfFerngill.WeatherOpt.TooHotOutside && ClimatesOfFerngill.WeatherOpt.HazardousWeather) { curr.AddWeather(CurrentWeather.Heatwave); specialWeatherTriggered = true; } double sandstormOdds = .18; if (Game1.currentSeason == "summer") { sandstormOdds *= 1.2; } if (oddsRoll < sandstormOdds && ClimatesOfFerngill.WeatherOpt.HazardousWeather && Game1.isDebrisWeather) { curr.AddWeather(CurrentWeather.Sandstorm); specialWeatherTriggered = true; curr.CreateWeather("Sandstorm"); } } //and finally, test for thunder frenzy if (curr.HasWeather(CurrentWeather.Lightning) && curr.HasWeather(CurrentWeather.Rain) && ClimatesOfFerngill.WeatherOpt.HazardousWeather) { double oddsRoll = ClimatesOfFerngill.Dice.NextDouble(); if (oddsRoll < ClimatesOfFerngill.WeatherOpt.ThunderFrenzyOdds) { curr.AddWeather(CurrentWeather.ThunderFrenzy); specialWeatherTriggered = true; if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"With roll {oddsRoll:N3} against {ClimatesOfFerngill.WeatherOpt.ThunderFrenzyOdds}, there will be a thunder frenzy today"); } curr.CreateWeather("ThunderFrenzy"); } } return(specialWeatherTriggered); }
/// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { RWeatherIcon = new Rectangle(); WeatherOpt = helper.ReadConfig <WeatherConfig>(); Logger = Monitor; Translator = Helper.Translation; Reflection = Helper.Reflection; MPHandler = Helper.Multiplayer; Dice = new MersenneTwister(); OurIcons = new Sprites.Icons(Helper.Content); WeatherProcessing.Init(); Conditions = new WeatherConditions(); DescriptionEngine = new Descriptions(WeatherOpt, Helper.Translation); queuedMsg = null; SummitRebornLoaded = false; if (WeatherOpt.Verbose) { Monitor.Log($"Loading climate type: {WeatherOpt.ClimateType} from file", LogLevel.Trace); } var path = Path.Combine("assets", "climates", WeatherOpt.ClimateType + ".json"); GameClimate = helper.Data.ReadJsonFile <FerngillClimate>(path); if (GameClimate is null) { this.Monitor.Log($"The required '{path}' file is missing. Try reinstalling the mod to fix that.", LogLevel.Error); this.Monitor.Log("This mod will now disable itself.", LogLevel.Error); this.Disabled = true; } if (Disabled) { return; } var harmony = HarmonyInstance.Create("koihimenakamura.climatesofferngill"); harmony.PatchAll(Assembly.GetExecutingAssembly()); ConsoleCommands.Init(); MethodInfo GameLocationDAAFL = AccessTools.Method(typeof(GameLocation), "drawAboveAlwaysFrontLayer"); HarmonyMethod DAAFLTranspiler = new HarmonyMethod(AccessTools.Method(typeof(GameLocationPatches), "DAAFLTranspiler")); Monitor.Log($"Patching {GameLocationDAAFL} with Transpiler: {DAAFLTranspiler}", LogLevel.Trace);; harmony.Patch(GameLocationDAAFL, transpiler: DAAFLTranspiler); MethodInfo GameDrawW = AccessTools.Method(typeof(Game1), "drawWeather"); HarmonyMethod DrawWeatherPrefix = new HarmonyMethod(AccessTools.Method(typeof(Game1Patches), "DrawWeatherPrefix")); Monitor.Log($"Patching {GameDrawW} with Prefix: {DrawWeatherPrefix}", LogLevel.Trace);; harmony.Patch(GameDrawW, prefix: DrawWeatherPrefix); Type t = AccessTools.TypeByName("StardewModdingAPI.Framework.SGame"); MethodInfo SGameDrawImpl = AccessTools.Method(t, "DrawImpl"); HarmonyMethod DrawTrans = new HarmonyMethod(AccessTools.Method(typeof(SGamePatches), "DrawImplTranspiler")); Monitor.Log($"Patching {SGameDrawImpl} with Transpiler: {DrawTrans}", LogLevel.Trace); harmony.Patch(SGameDrawImpl, transpiler: DrawTrans); t = AccessTools.TypeByName("StardewValley.WeatherDebris"); var DebrisConstructor = AccessTools.Constructor(t, new[] { typeof(Vector2), typeof(int), typeof(float), typeof(float), typeof(float) }); HarmonyMethod CtorPatch = new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "CtorPostfix")); Monitor.Log($"Patching {DebrisConstructor} with Postfix: {CtorPatch}", LogLevel.Trace); harmony.Patch(DebrisConstructor, postfix: CtorPatch); MethodInfo DebrisDraw = AccessTools.Method(typeof(WeatherDebris), "draw"); HarmonyMethod DebrisPatch = new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "DrawPrefix")); Monitor.Log($"Patching {DebrisDraw} with Prefix: {DebrisDraw}", LogLevel.Trace); harmony.Patch(DebrisDraw, prefix: DebrisPatch); MethodInfo DebrisUpdate = AccessTools.Method(typeof(WeatherDebris), "update", new[] { typeof(bool) }); HarmonyMethod DebrisUpdatePatch = new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "UpdatePrefix")); Monitor.Log($"Patching {DebrisUpdate} with Prefix: {DebrisUpdatePatch}", LogLevel.Trace); harmony.Patch(DebrisUpdate, prefix: DebrisUpdatePatch); //INSERT DNT CHECKS HERE var modManifest = Helper.ModRegistry.Get("knakamura.dynamicnighttime"); if (modManifest != null) { if (modManifest.Manifest.Version.IsOlderThan("1.2.11")) { Monitor.Log("WARNING: Overcast weather may not work correctly unless you are running Dynamic Night Time 1.2.11 or later", LogLevel.Alert); } } else { //Normal Climates patch goes here. MethodInfo UpdateGameClock = helper.Reflection.GetMethod(SDVUtilities.GetSDVType("Game1"), "UpdateGameClock").MethodInfo; MethodInfo postfixClock = helper.Reflection.GetMethod(typeof(Patches.GameClockPatch), "Postfix").MethodInfo; Monitor.Log($"Postfixing {UpdateGameClock} with {postfixClock}", LogLevel.Trace); harmony.Patch(UpdateGameClock, null, new HarmonyMethod(postfixClock)); } SanityCheckConfigOptions(); //subscribe to events var events = helper.Events; events.GameLoop.DayStarted += OnDayStarted; events.GameLoop.Saving += OnSaving; events.GameLoop.TimeChanged += OnTimeChanged; events.Display.MenuChanged += OnMenuChanged; events.GameLoop.UpdateTicked += OnUpdateTicked; events.GameLoop.GameLaunched += OnGameLaunched; events.GameLoop.OneSecondUpdateTicked += OnOneSecondUpdateTicked; events.GameLoop.ReturnedToTitle += OnReturnedToTitle; events.GameLoop.SaveLoaded += OnSaveLoaded; events.Display.RenderingHud += OnRenderingHud; events.Display.RenderedHud += OnRenderedHud; events.Input.ButtonPressed += OnButtonPressed; events.Multiplayer.ModMessageReceived += OnModMessageRecieved; // events.GameLoop.UpdateTicking += GameLoop_UpdateTicking; //console commands helper.ConsoleCommands .Add("world_tmrwweather", helper.Translation.Get("console-text.desc_tmrweather"), ConsoleCommands.TomorrowWeatherChangeFromConsole) .Add("world_setweather", helper.Translation.Get("console-text.desc_setweather"), ConsoleCommands.WeatherChangeFromConsole) .Add("debug_clearspecial", "debug command to clear special weathers", ConsoleCommands.ClearSpecial) .Add("debug_weatherstatus", "!", ConsoleCommands.OutputWeather) .Add("debug_sswa", "Show Special Weather", ConsoleCommands.ShowSpecialWeather) .Add("debug_vrainc", "Set Rain Amt.", ConsoleCommands.SetRainAmt) .Add("debug_raintotal", "Get Rain Total", ConsoleCommands.DisplayRainTotal) .Add("debug_printClimate", "Print Climate Tracker Data", ConsoleCommands.DisplayClimateTrackerData); }
internal static void DynamicRainOnNewDay(WeatherConditions curr, MersenneTwister Dice) { if (!curr.HasWeather(CurrentWeather.Rain)) { return; } curr.SetRainAmt(70); //Rain chances. This will also affect storms (in that storms still can have variable rain) . //only roll this if it's actually raining. :| double roll = Dice.NextDouble(); if (roll <= ClimatesOfFerngill.WeatherOpt.VariableRainChance && Game1.isRaining) { ClimatesOfFerngill.Logger.Log($"With {roll}, we are setting for variable rain against {ClimatesOfFerngill.WeatherOpt.VariableRainChance}"); curr.SetVariableRain(true); //check for overcast chance first. if (Dice.NextDouble() < ClimatesOfFerngill.WeatherOpt.OvercastChance && !Game1.isLightning) { WeatherUtilities.SetWeatherOvercast(true); SDVUtilities.AlterWaterStatusOfCrops(water: false); SDVUtilities.ShowMessage(ClimatesOfFerngill.Translator.Get("hud-text.desc_overcast"), 0); } //now that we've done that base check, we need to change the rainfall... //... after we calc rainfall to see if it's watered. Essentially, every time this is called, //... it'll check to see if it should flip the tiles. //Variable Rain may set the starting rain at 0300 to be something else than normal, and as such, StartingRain should // only be checked if IsVariableRain is true. // Odds are fixed: Normal (default) is 72%, Light is 16%, Heavy is 6%, Sunshower is 5%, Severe is 1% double startingRainRoll = Dice.NextDouble(); if (startingRainRoll <= .72) { curr.StartingRain = RainLevels.Normal; } else if (startingRainRoll > .72 && startingRainRoll <= .88) { curr.StartingRain = RainLevels.Light; } else if (startingRainRoll > .88 && startingRainRoll <= .94) { curr.StartingRain = RainLevels.Heavy; } else if (startingRainRoll > .94 && startingRainRoll <= .99) { curr.StartingRain = RainLevels.Sunshower; } else if (startingRainRoll > .99) { curr.StartingRain = RainLevels.Severe; } if (Game1.isLightning && !(curr.StartingRain == RainLevels.Light || curr.StartingRain == RainLevels.Sunshower || curr.StartingRain == RainLevels.Normal)) { curr.StartingRain = RainLevels.Heavy; } curr.SetRainAmt(WeatherUtilities.GetRainCategoryMidPoint(curr.StartingRain)); curr.TodayRain = curr.AmtOfRainDrops; //now run this for 0300 to 0600. for (int i = 0; i < 17; i++) { curr.SetRainAmt(GetNewRainAmount(curr.AmtOfRainDrops, ClimatesOfFerngill.Translator)); curr.TodayRain += curr.AmtOfRainDrops; } //set starting amount at 6am curr.RefreshRainAmt(); } }
/// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { RWeatherIcon = new Rectangle(); WeatherOpt = helper.ReadConfig <WeatherConfig>(); Logger = Monitor; Translator = Helper.Translation; Reflection = Helper.Reflection; MPHandler = Helper.Multiplayer; Dice = new Xoshiro.PRNG64.XoShiRo256starstar(); OurIcons = new Sprites.Icons(Helper.Content); WeatherProcessing.Init(); Conditions = new WeatherConditions(); DescriptionEngine = new Descriptions(WeatherOpt, Helper.Translation); queuedMsg = null; SummitRebornLoaded = false; if (WeatherOpt.Verbose) { Monitor.Log($"Loading climate type: {WeatherOpt.ClimateType} from file", LogLevel.Trace); } var path = Path.Combine("assets", "climates", WeatherOpt.ClimateType + ".json"); GameClimate = helper.Data.ReadJsonFile <FerngillClimate>(path); if (GameClimate is null) { this.Monitor.Log($"The required '{path}' file is missing. Try reinstalling the mod to fix that.", LogLevel.Error); this.Monitor.Log("This mod will now disable itself.", LogLevel.Error); this.Disabled = true; } if (Disabled) { return; } var harmony = new Harmony("koihimenakamura.climatesofferngill"); harmony.Patch( original: AccessTools.Method(typeof(GameLocation), "drawAboveAlwaysFrontLayer"), transpiler: new HarmonyMethod(AccessTools.Method(typeof(GameLocationPatches), "DAAFLTranspiler"))); Monitor.Log("Patching GameLocation::drawAboveAlwaysFrontLayer with a Transpiler.", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(Game1), "drawWeather"), prefix: new HarmonyMethod(AccessTools.Method(typeof(Game1Patches), "DrawWeatherPrefix"))); Monitor.Log("Patching Game1::drawWeather with a prefix method.", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(Game1), "updateWeather"), prefix: new HarmonyMethod(AccessTools.Method(typeof(Game1Patches), "UpdateWeatherPrefix"))); Monitor.Log("Patching Game1::updateWeather with a prefix method.", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(AccessTools.TypeByName("StardewModdingAPI.Framework.SGame"), "DrawImpl"), transpiler: new HarmonyMethod(AccessTools.Method(typeof(SGamePatches), "DrawImplTranspiler"))); Monitor.Log("Patching SMAPI (SGame::DrawImpl) with a transpiler.", LogLevel.Trace); harmony.Patch( original: AccessTools.Constructor(AccessTools.TypeByName("StardewValley.WeatherDebris"), new[] { typeof(Vector2), typeof(int), typeof(float), typeof(float), typeof(float) }), postfix: new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "CtorPostfix"))); Monitor.Log("Patching WeatherDebris's constructor method with a postfix method.", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(WeatherDebris), "draw"), prefix: new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "DrawPrefix"))); Monitor.Log("Patching WeatherDebris::draw with a prefix method.", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(WeatherDebris), "update", new[] { typeof(bool) }), prefix: new HarmonyMethod(AccessTools.Method(typeof(WeatherDebrisPatches), "UpdatePrefix"))); Monitor.Log("Patching WeatherDebris::draw with a prefix method.", LogLevel.Trace); //INSERT DNT CHECKS HERE var modManifest = Helper.ModRegistry.Get("knakamura.dynamicnighttime"); if (modManifest != null) { if (modManifest.Manifest.Version.IsOlderThan("1.2.11")) { Monitor.Log("WARNING: Overcast weather may not work correctly unless you are running Dynamic Night Time 1.2.11 or later", LogLevel.Alert); } } else { harmony.Patch( original: AccessTools.Method(typeof(Game1), "UpdateGameClock"), postfix: new HarmonyMethod(AccessTools.Method(typeof(GameClockPatch), "Postfix"))); Monitor.Log("Patching Game1::UpdateGameClock with a Postfix method. (Used only when Climates is installed and DNT is not.)", LogLevel.Trace); } ConsoleCommands.Init(); SanityCheckConfigOptions(); //subscribe to events var events = helper.Events; events.GameLoop.DayStarted += OnDayStarted; events.GameLoop.Saving += OnSaving; events.GameLoop.TimeChanged += OnTimeChanged; events.Display.MenuChanged += OnMenuChanged; events.GameLoop.UpdateTicked += OnUpdateTicked; events.GameLoop.GameLaunched += OnGameLaunched; events.GameLoop.OneSecondUpdateTicked += OnOneSecondUpdateTicked; events.GameLoop.ReturnedToTitle += OnReturnedToTitle; events.GameLoop.SaveLoaded += OnSaveLoaded; events.Display.RenderedWorld += Display_RenderedWorld; //events.Display.RenderingHud += OnRenderingHud; events.Display.RenderedHud += OnRenderedHud; events.Input.ButtonPressed += OnButtonPressed; events.Multiplayer.ModMessageReceived += OnModMessageRecieved; //console commands helper.ConsoleCommands .Add("world_tmrwweather", helper.Translation.Get("console-text.desc_tmrweather"), ConsoleCommands.TomorrowWeatherChangeFromConsole) .Add("world_setweather", helper.Translation.Get("console-text.desc_setweather"), ConsoleCommands.WeatherChangeFromConsole) .Add("debug_clearspecial", "debug command to clear special weathers", ConsoleCommands.ClearSpecial) .Add("debug_weatherstatus", "!", ConsoleCommands.OutputWeather) .Add("debug_sswa", "Show Special Weather", ConsoleCommands.ShowSpecialWeather) .Add("debug_vrainc", "Set Rain Amt.", ConsoleCommands.SetRainAmt) .Add("debug_raindef", "Set Rain Deflection.", ConsoleCommands.SetRainDef) /* * .Add("debug_setwindchance", "Set Wind Chance", ConsoleCommands.SetWindChance) * .Add("debug_setwindtresh", "Set Wind Threshold", ConsoleCommands.SetWindThreshold) * .Add("debug_setwindrange", "Set Wind Range", ConsoleCommands.SetWindRange) * .Add("debug_raintotal", "Get Rain Total", ConsoleCommands.DisplayRainTotal) * .Add("debug_getcurrentwind", "Show wind values", ConsoleCommands.ShowWind) * .Add("debug_resetwind", "Reset Global Wind", ConsoleCommands.ResetGlobalWind) */ .Add("debug_printClimate", "Print Climate Tracker Data", ConsoleCommands.DisplayClimateTrackerData); }
internal string GenerateMenuPopup(WeatherConditions Current, string MoonPhase = "", string NightTime = "") { string text = ""; if (SDate.Now().Season == "spring" && SDate.Now().Day == 1) { text = Helper.Get("weather-menu.openingS1D1", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } else if (SDate.Now().Season == "winter" && SDate.Now().Day == 28) { text = Helper.Get("weather-menu.openingS4D28", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } else { text = Helper.Get("weather-menu.opening", new { descDay = Helper.Get($"date{UpperSeason(SDate.Now().Season)}{SDate.Now().Day}") }) + Environment.NewLine + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.Heatwave)) { text += Helper.Get("weather-menu.condition.heatwave") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.Frost)) { text += Helper.Get("weather-menu.condition.frost") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.WhiteOut)) { text += Helper.Get("weather-menu.condition.whiteOut") + Environment.NewLine; } if (Current.ContainsCondition(CurrentWeather.ThunderFrenzy)) { text += Helper.Get("weather-menu.condition.thunderFrenzy") + Environment.NewLine; } if (MoonPhase == "Blood Moon") { text += Helper.Get("weather-menu.condition.bloodmoon") + Environment.NewLine; } ISDVWeather CurrentFog = Current.GetWeatherMatchingType("Fog").First(); string fogString = ""; // If the fog is visible, we don't need to display fog information. However, if it's in the morning, // and we know evening fog is likely, we should display the message it's expected // That said, if it's not, we need to pull the fog information down, assuming it's been reset. This checks that the fog end // time is *before* now. To avoid nested trinary statements.. if (SDVTime.CurrentTime < CurrentFog.WeatherExpirationTime && Current.GenerateEveningFog && CurrentFog.WeatherBeginTime < new SDVTime(1200)) { fogString = Helper.Get("weather-menu.expectedFog"); } if (CurrentFog.WeatherBeginTime > SDVTime.CurrentTime && Current.GenerateEveningFog) { fogString = Helper.Get("weather-menu.fogFuture", new { fogTime = CurrentFog.WeatherBeginTime.ToString(), endFog = CurrentFog.WeatherExpirationTime.ToString() }); } //Current Conditions. text += Helper.Get("weather-menu.current", new { todayCondition = Current.HasWeather(CurrentWeather.Fog) ? Helper.Get("weather-menu.fog", new { condition = GetBasicWeather(Current, Game1.currentSeason), fogTime = CurrentFog.IsWeatherVisible ? CurrentFog.WeatherExpirationTime.ToString() : "" }) : GetBasicWeather(Current, Game1.currentSeason), todayHigh = GetTemperatureString(Current.TodayHigh), todayLow = GetTemperatureString(Current.TodayLow), fogString }) + Environment.NewLine; //Tomorrow weather text += Helper.Get("weather-menu.tomorrow", new { tomorrowCondition = GetBasicWeather(Game1.weatherForTomorrow, Game1.currentSeason), tomorrowLow = GetTemperatureString(Current.TomorrowLow), tomorrowHigh = GetTemperatureString(Current.TomorrowHigh) }) + Environment.NewLine; //now, night time if (NightTime != "") { text += Environment.NewLine; text += NightTime + Environment.NewLine; } return(text); }
internal static int GetNewRainAmount(int prevRain, ITranslationHelper Translation, bool showRain = true) { int currRain = prevRain; double ChanceOfRainChange = ClimatesOfFerngill.WeatherOpt.VRChangeChance; bool massiveChange = false; //do some rain chance pre pumping if (currRain == 0) { ChanceOfRainChange += .20; } if (currRain > WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Torrential)) { ChanceOfRainChange += .10; } if (WeatherUtilities.GetRainCategory(currRain) == RainLevels.NoahsFlood) { ChanceOfRainChange += .15; } double FlipChance = .5; //so, lower: decrease, higher: increase if (WeatherUtilities.IsSevereRainFall(currRain)) { FlipChance += .2; } if (WeatherUtilities.GetRainCategory(currRain) == RainLevels.Torrential || WeatherUtilities.GetRainCategory(currRain) == RainLevels.Typhoon || WeatherUtilities.GetRainCategory(currRain) == RainLevels.NoahsFlood) { FlipChance += .15; //15% chance remaining of increasing. } if (WeatherUtilities.GetRainCategory(currRain) == RainLevels.Typhoon || WeatherUtilities.GetRainCategory(currRain) == RainLevels.NoahsFlood) { FlipChance += .1456; //.44% chance remaning of increasing. } if (WeatherUtilities.GetRainCategory(currRain) == RainLevels.NoahsFlood) { FlipChance += .0018; //.26% chance remaning of increasing. } if (currRain == ClimatesOfFerngill.WeatherOpt.MaxRainFall) { FlipChance = 1; //you must go ddown. } if (currRain <= WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Light)) { FlipChance -= .2; //70% chance of increasing } if (currRain <= WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Sunshower)) { FlipChance -= .1; //80% chance of increasing } if (currRain == 0) { FlipChance -= .15; //95% chance of increasing } if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log($"Rain is {prevRain}, current chance for rain change is {ChanceOfRainChange}."); ClimatesOfFerngill.Logger.Log($"Calculated chance for rain decreasing: {WeatherUtilities.GetStepChance(currRain, increase: false).ToString("N3")}, rain increasing: {WeatherUtilities.GetStepChance(currRain, increase: true).ToString("N3")}. Flip chance is {FlipChance.ToString("N3")} "); } // I just spent nine minutes typing out an invalid explanation for this. :| // So, i'm renaming the variables. // And redoing this entirely. It's a lot of duplicated effort. //Greater than flip chance is increase, lesser is decrease if (ClimatesOfFerngill.Dice.NextDouble() < ChanceOfRainChange) { // Handle rain changes. // first check for a massive change 145% to 245% double stepRoll = ClimatesOfFerngill.Dice.NextDouble(); if (ClimatesOfFerngill.Dice.NextDouble() > FlipChance) { if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log("Increasing rain!"); } if (stepRoll <= WeatherUtilities.GetStepChance(currRain, increase: true)) { //get the multiplier. This should be between 145% and 245% int mult = Math.Max(1, (int)(Math.Floor(ClimatesOfFerngill.Dice.NextDouble() + .68))); if (currRain == 0) { currRain = 15 * mult; } else { currRain = (int)(Math.Floor(currRain * mult * 1.0)); } massiveChange = true; } } else { if (stepRoll <= WeatherUtilities.GetStepChance(currRain, increase: false)) { ClimatesOfFerngill.Logger.Log("Increasing rain!"); currRain = (int)(Math.Floor(currRain / (ClimatesOfFerngill.Dice.NextDouble() + 1.45))); massiveChange = true; } } if (!massiveChange) { double mult = (1 + (ClimatesOfFerngill.Dice.NextDouble() * 1.3) - .55); if (currRain == 0) { currRain = 4; } if (currRain < WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Light)) { mult += 4.5; } currRain = (int)(Math.Floor(currRain * mult)); } } if (!ClimatesOfFerngill.WeatherOpt.HazardousWeather) { if (ClimatesOfFerngill.WeatherOpt.Verbose) { ClimatesOfFerngill.Logger.Log("Triggering Hazardous Weather Failsafe"); } currRain = WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Severe); } if (WeatherConditions.PreventGoingOutside(currRain)) { if (Game1.timeOfDay >= 2300) { //drop the rain to at least allow the person to return home if they aren't. currRain = WeatherUtilities.GetRainCategoryMidPoint(RainLevels.Severe); } } if (currRain > ClimatesOfFerngill.WeatherOpt.MaxRainFall) { currRain = ClimatesOfFerngill.WeatherOpt.MaxRainFall; } if (currRain < 0) { currRain = 0; } if (currRain != prevRain && Game1.timeOfDay != 600 && showRain && !(Game1.currentLocation is Desert)) { if (WeatherUtilities.GetRainCategory(currRain) == RainLevels.None) { Game1.addHUDMessage(new HUDMessage(Translation.Get("hud-text.NearlyNoRain"))); return(currRain); } else if (currRain > prevRain) { if (WeatherUtilities.GetRainCategory(currRain) != WeatherUtilities.GetRainCategory(prevRain)) { Game1.addHUDMessage(new HUDMessage(Translation.Get("hud-text.CateIncrease", new { currRain, category = WeatherUtilities.DescRainCategory(currRain) }))); return(currRain); } else if (Math.Abs(currRain / prevRain) >= ClimatesOfFerngill.WeatherOpt.VRainNotifThreshold || ClimatesOfFerngill.WeatherOpt.Verbose) { Game1.addHUDMessage(new HUDMessage(Translation.Get("hud-text.Increase", new { currRain }))); return(currRain); } } else { if (WeatherUtilities.GetRainCategory(currRain) != WeatherUtilities.GetRainCategory(prevRain)) { Game1.addHUDMessage(new HUDMessage(Translation.Get("hud-text.CateDecrease", new { currRain, category = WeatherUtilities.DescRainCategory(currRain) }))); return(currRain); } else if (Math.Abs(currRain / prevRain) >= ClimatesOfFerngill.WeatherOpt.VRainNotifThreshold || ClimatesOfFerngill.WeatherOpt.Verbose) { Game1.addHUDMessage(new HUDMessage(Translation.Get("hud-text.Decrease", new { currRain }))); return(currRain); } } } return(currRain); }
internal string GenerateTVForecast(WeatherConditions Current, string MoonPhase = "") { //assemble params var talkParams = new Dictionary <string, string> { { "location", GetRandomLocation() }, { "descWeather", GetWeather(Current, Game1.dayOfMonth, Game1.currentSeason) }, { "festival", SDVUtilities.GetFestivalName(SDate.Now()) }, { "festivalTomorrow", SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) }, { "fogTime", Current.GetFogTime().ToString() }, { "todayHigh", GetTemperatureString(Current.TodayHigh) }, { "todayLow", GetTemperatureString(Current.TodayLow) }, { "tomorrowWeather", GetWeather(Game1.weatherForTomorrow, Game1.dayOfMonth, Game1.currentSeason, true) }, { "tomorrowHigh", GetTemperatureString(Current.TomorrowHigh) }, { "tomorrowLow", GetTemperatureString(Current.TomorrowLow) }, { "condWarning", GetCondWarning(Current) }, { "condString", GetCondWarning(Current) }, { "eveningFog", GetEveningFog(Current) } }; //select the weather string for the TV. SDVTimePeriods CurrentPeriod = SDVTime.CurrentTimePeriod; //get the current time period int nRandom = OurDice.Next(2); //blood moon checks if ((Game1.player.spouse != null && Game1.player.isEngaged() && Game1.player.friendshipData[Game1.player.spouse].CountdownToWedding == 1) && MoonPhase == "Blood Moon") { talkParams["tomrrowWeather"] = Helper.Get($"weat-{Game1.currentSeason}.sunny.{nRandom}"); return(Helper.Get("weat-wedTomorrow.BM.0", talkParams)); } //festival tomorrow else if (SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) != "" && MoonPhase == "Blood Moon") { return(Helper.Get("weat-fesTomorrow.BM.0", talkParams)); } else if (MoonPhase == "Blood Moon") { return(Helper.Get("weat-gen.bloodmoon.0", talkParams)); } //first, check for special conditions -fog, festival, wedding else if (Current.HasWeather(CurrentWeather.Fog)) { return(Helper.Get($"weat-loc.fog.{nRandom}", talkParams)); } //festival today else if (Current.HasWeather(CurrentWeather.Festival)) { return(Helper.Get("weat-fesToday.0", talkParams)); } //festival tomorrow else if (SDVUtilities.GetFestivalName(SDate.Now().AddDays(1)) != "") { return(Helper.Get("weat-fesTomorrow.0", talkParams)); } //wedding today else if (Current.HasWeather(CurrentWeather.Wedding)) { return(Helper.Get("weat-wedToday.0", talkParams)); } //wedding tomrrow else if (Game1.player.spouse != null && Game1.player.isEngaged() && Game1.player.friendshipData[Game1.player.spouse].CountdownToWedding == 1) { talkParams["tomrrowWeather"] = Helper.Get($"weat-{Game1.currentSeason}.sunny.{nRandom}"); return(Helper.Get("weat-wedTomorrow.0", talkParams)); } if (OurDice.NextDoublePositive() > .45) { if (CurrentPeriod == SDVTimePeriods.Morning) { return(Helper.Get($"weat-morn.{nRandom}", talkParams)); } else if (CurrentPeriod == SDVTimePeriods.Afternoon) { return(Helper.Get($"weat-afternoon.{nRandom}", talkParams)); } else if (CurrentPeriod == SDVTimePeriods.Evening) { return(Helper.Get($"weat-evening.{nRandom}", talkParams)); } else if (CurrentPeriod == SDVTimePeriods.Night) { return(Helper.Get($"weat-night.{nRandom}", talkParams)); } else if (CurrentPeriod == SDVTimePeriods.Midnight) { return(Helper.Get($"weat-midnight.{nRandom}", talkParams)); } else if (CurrentPeriod == SDVTimePeriods.LateNight) { return(Helper.Get($"weat-latenight.{nRandom}", talkParams)); } } else { //ye olde generic! return(Helper.Get($"weat-loc.{nRandom}", talkParams)); } return(""); }
public ClimatesOfFerngillAPI(WeatherConditions cond, WeatherConfig Opt) { LoadData(cond, Opt); }
public int TenMinuteTick(WeatherConditions conditions, int ticksOutside, int ticksTotal, MersenneTwister Dice) { double amtOutside = ticksOutside / (double)ticksTotal, totalMulti = 0; int staminaAffect = 0; int sickReason = 0; var condList = new List <string>(); /* if (Config.Verbose) * Monitor.Log($"Ticks: {ticksOutside}/{ticksTotal} with percentage {amtOutside.ToString("N3")} against" + * $" target {Config.AffectedOutside}"); */ //Logic: At all times, if the today danger is not null, we should consider processing. //However: If it's frost, only at night. If it's a heatwave, only during the day. //So this means: if it's storming, you can get sick. If it's a blizzard or thundersnow.. you can get sick //If it's frost or heatwave during the appropriate time.. you can get sick //First, update the sick status bool farmerCaughtCold = false; double sickOdds = Config.ChanceOfGettingSick - Game1.dailyLuck; //weee. if (Game1.player.hat?.which == 28 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Lightning)) { sickOdds -= (Dice.NextDoublePositive() / 5.0) - .1; } if (Game1.player.hat?.which == 25 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard)) { sickOdds -= .22; } if (Game1.player.hat?.which == 4 && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight) { sickOdds -= .11; } farmerCaughtCold = (Dice.NextDoublePositive() <= sickOdds); if (amtOutside >= Config.AffectedOutside && farmerCaughtCold || this.FarmerSick) { //check if it's a valid condition if (FarmerCanGetSick()) { if (conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Blizzard | CurrentWeather.Lightning) || (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) | (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)) { if ((conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)) { sickReason = HEATWAVE; } else if (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) { sickReason = FROST; } this.MakeSick(sickReason); } } //test status /*if (Config.Verbose) * Monitor.Log($"Status update. Farmer Sick: {FarmerSick} and Valid Conditions: {conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Blizzard | CurrentWeather.Lightning) || (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) | (conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight)}"); */ //now that we've done that, go through the various conditions if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Lightning)) { totalMulti += 1; condList.Add("Lightning or Thundersnow"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Fog)) { totalMulti += .5; condList.Add("Fog"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Fog) && SDVTime.IsNight) { totalMulti += .25; condList.Add("Night Fog"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && !conditions.GetCurrentConditions().HasFlag(CurrentWeather.WhiteOut)) { totalMulti += 1.25; condList.Add("Blizzard"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && conditions.GetCurrentConditions().HasFlag(CurrentWeather.WhiteOut)) { totalMulti += 2.25; condList.Add("White Out"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Frost) && SDVTime.IsNight) { totalMulti += 1.25; condList.Add("Night Frost"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasAllFlags(CurrentWeather.Lightning | CurrentWeather.Snow) && SDVTime.IsNight) { totalMulti += .5; condList.Add("Night Thundersnow"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Blizzard) && SDVTime.IsNight) { totalMulti += .5; condList.Add("Night Blizzard"); } if (this.FarmerSick && conditions.GetCurrentConditions().HasFlag(CurrentWeather.Heatwave) && !SDVTime.IsNight) { totalMulti += 1.25; condList.Add("Day Heatwave"); } } staminaAffect -= (int)Math.Floor(Config.StaminaDrain * totalMulti); if (Config.Verbose && this.FarmerSick) { string condString = "[ "; for (int i = 0; i < condList.Count; i++) { if (i != condList.Count - 1) { condString += condList[i] + ", "; } else { condString += condList[i]; } } condString += " ]"; /* * Monitor.Log($"[{Game1.timeOfDay}] Conditions for the drain are {condString} for a total multipler of {totalMulti} for a total drain of {staminaAffect}"); */ } return(staminaAffect); }
/// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { RWeatherIcon = new Rectangle(); WeatherOpt = helper.ReadConfig <WeatherConfig>(); Dice = new MersenneTwister(); OurIcons = new Sprites.Icons(Helper.Content); CropList = new List <Vector2>(); Conditions = new WeatherConditions(OurIcons, Dice, Helper.Translation, Monitor, WeatherOpt); DescriptionEngine = new Descriptions(Helper.Translation, Dice, WeatherOpt, Monitor); queuedMsg = null; ExpireTime = 0; if (WeatherOpt.Verbose) { Monitor.Log($"Loading climate type: {WeatherOpt.ClimateType} from file", LogLevel.Trace); } var path = Path.Combine("data", "weather", WeatherOpt.ClimateType + ".json"); GameClimate = helper.Data.ReadJsonFile <FerngillClimate>(path); if (GameClimate is null) { this.Monitor.Log($"The required '{path}' file is missing. Try reinstalling the mod to fix that.", LogLevel.Error); this.Monitor.Log("This mod will now disable itself.", LogLevel.Error); this.Disabled = true; } if (Disabled) { return; } var harmony = HarmonyInstance.Create("koihimenakamura.climatesofferngill"); harmony.PatchAll(Assembly.GetExecutingAssembly()); //patch SGame::DarkImpl //patch GameLocation::drawAboveAlwaysFrontLayer MethodInfo GameLocationDAAFL = AccessTools.Method(typeof(StardewValley.GameLocation), "drawAboveAlwaysFrontLayer"); HarmonyMethod DAAFLTranspiler = new HarmonyMethod(AccessTools.Method(typeof(GameLocationPatches), "Transpiler")); Monitor.Log($"Patching {GameLocationDAAFL} with Transpiler: {DAAFLTranspiler}", LogLevel.Trace);; harmony.Patch(GameLocationDAAFL, transpiler: DAAFLTranspiler); Type t = AccessTools.TypeByName("StardewModdingAPI.Framework.SGame"); MethodInfo SGameDrawImpl = AccessTools.Method(t, "DrawImpl"); HarmonyMethod DrawTrans = new HarmonyMethod(AccessTools.Method(typeof(SGamePatches), "Transpiler")); Monitor.Log($"Patching {SGameDrawImpl} with Transpiler: {DrawTrans}", LogLevel.Trace); harmony.Patch(SGameDrawImpl, transpiler: DrawTrans); //subscribe to events var events = helper.Events; events.GameLoop.DayStarted += OnDayStarted; events.GameLoop.Saving += OnSaving; events.GameLoop.TimeChanged += OnTimeChanged; events.Display.MenuChanged += OnMenuChanged; events.GameLoop.UpdateTicked += OnUpdateTicked; events.GameLoop.GameLaunched += OnGameLaunched; events.GameLoop.OneSecondUpdateTicked += OnOneSecondUpdateTicked; events.GameLoop.ReturnedToTitle += OnReturnedToTitle; events.GameLoop.SaveLoaded += OnSaveLoaded; events.Display.RenderingHud += OnRenderingHud; events.Display.RenderedHud += OnRenderedHud; events.Player.Warped += OnWarped; events.Input.ButtonPressed += OnButtonPressed; //console commands helper.ConsoleCommands .Add("world_tmrwweather", helper.Translation.Get("console-text.desc_tmrweather"), TomorrowWeatherChangeFromConsole) .Add("world_setweather", helper.Translation.Get("console-text.desc_setweather"), WeatherChangeFromConsole) .Add("debug_clearspecial", "debug command to clear special weathers", ClearSpecial) .Add("debug_weatherstatus", "!", OutputWeather); }
public void LoadData(WeatherConditions cond, WeatherConfig opt) { CurrentConditions = cond; Options = opt; }
public void LoadData(WeatherConditions Cond, WeatherConfig Opt) { CurrentConditions = Cond; Options = Opt; }
private void UpdateWeatherOnNewDay() { if (!Context.IsMainPlayer) { return; } if (Game1.dayOfMonth == 0) //do not run on day 0. { return; } int loopCount = 0; //Set Temperature for today and tommorow. Get today's conditions. // If tomorrow is set, move it to today, and autoregen tomorrow. // *201711 Due to changes in the object, it auto attempts to update today from tomorrow. if (!Conditions.IsTodayTempSet) { if (!Conditions.IsTomorrowTempSet) { Conditions.SetTodayTemps(GameClimate.GetTemperatures(SDate.Now(), Dice)); if (Game1.weatherForTomorrow == Game1.weather_snow) { while (!WeatherConditions.IsValidWeatherForSnow(Conditions.GetTodayTemps()) && loopCount <= 1000) { Conditions.SetTodayTemps(GameClimate.GetTemperatures(SDate.Now(), Dice)); loopCount++; } } } else { Conditions.SetTodayTempsFromTomorrow(); } Conditions.SetTomorrowTemps(GameClimate.GetTemperatures(SDate.Now().AddDays(1), Dice)); } if (WeatherOpt.Verbose) { Monitor.Log($"Updated the temperature for tommorow and today. Setting weather for today... ", LogLevel.Trace); } //if today is a festival or wedding, do not go further. if (Conditions.GetCurrentConditions().HasAnyFlags(CurrentWeather.Festival | CurrentWeather.Wedding)) { if (WeatherOpt.Verbose) { Monitor.Log("It is a wedding or festival today. Not attempting to run special weather or fog."); } return; } //variable rain conditions WeatherProcessing.DynamicRainOnNewDay(Conditions, Dice); if (!Conditions.IsVariableRain) { WeatherProcessing.CheckForStaticRainChanges(Conditions, Dice, GameClimate.ChanceForNonNormalRain); } if (WeatherProcessing.TestForSpecialWeather(Conditions, GameClimate.GetClimateForDate(SDate.Now()))) { if (WeatherOpt.Verbose) { Monitor.Log("Special weather created!"); } Conditions.UpdateClimateTracker(); } }