Example #1
0
        private SDate dayToSDate(int day)
        {
            int initialYearStart = (initialDate.Year - 1) * 112 + 1;
            int initialDay       = initialDate.DaysSinceStart - initialYearStart;
            int offset           = (day < initialDay) ? 112 : 0;

            return(SDate.FromDaysSinceStart(initialYearStart + day + offset));
        }
Example #2
0
 // Finds the next Garbage Hat to be available on or after the given date.
 public static Prediction?FindGarbageHat(SDate fromDate)
 {
     for (int days = fromDate.DaysSinceStart;
          days < fromDate.DaysSinceStart + Utilities.MaxHorizon;
          ++days)
     {
         List <Prediction> predictions =
             ListLootForDate(SDate.FromDaysSinceStart(days), true)
             .Where((p) => p.loot is Hat).ToList();
         if (predictions.Count > 0)
         {
             return(predictions[0]);
         }
     }
     return(null);
 }
Example #3
0
        // Lists the next several trains to arrive on or after the given date,
        // up to the given limit.
        public static List <Prediction> ListNextTrainsFromDate(SDate fromDate, uint limit)
        {
            Utilities.CheckWorldReady();
            if (!IsAvailable)
            {
                throw new UnavailableException("trains");
            }

            // Logic from StardewValley.Locations.Railroad.DayUpdate()
            // as implemented in Stardew Predictor by MouseyPounds.

            List <Prediction> predictions = new ();

            for (int days = Math.Max(fromDate.DaysSinceStart, 31);
                 predictions.Count < limit &&
                 days < fromDate.DaysSinceStart + Utilities.MaxHorizon;
                 ++days)
            {
                Random rng = new (((int)Game1.uniqueIDForThisGame / 2) + days);
                if (!(rng.NextDouble() < 0.2))
                {
                    continue;
                }

                int time = rng.Next(900, 1800);
                time -= time % 10;
                if (time % 100 >= 60)
                {
                    continue;
                }

                // No train on the first day after loading the game.
                SDate date = SDate.FromDaysSinceStart(days);
                if (date == Utilities.LoadDate)
                {
                    continue;
                }

                predictions.Add(new Prediction {
                    date = date, time = time
                });
            }

            return(predictions);
        }
        /// <summary>Print the UV value (no scaling) and UV index high for a specific date (int days since start).</summary>
        /// <param name="_command">The name of the command invoked.</param>
        /// <param name="_args">The arguments received by the command. Each word after the command name is a separate argument.</param>
        private static void getUV(string _command, string[] _args)
        {
            try
            {
                int days;
                int dailyMaxUV;
                int uvIndex;

                if (_args.Length > 0)
                {
                    days = int.Parse(_args[0]);
                    SDate date = SDate.FromDaysSinceStart(days);

                    if (date == SDate.Now().AddDays(1)) //date is tomorrow, can be more accurate with weather
                    {
                        dailyMaxUV = UVIndex.DailyMaxUV(days, Game1.weatherForTomorrow);
                        uvIndex    = Convert.ToInt32((double)dailyMaxUV / 25);
                        Monitor.Log($"Tomorrow's max UV value: {dailyMaxUV} | UV Index: {uvIndex}", LogLevel.Debug);
                        return;
                    }
                    else if (date != SDate.Now()) //any other day except today
                    {
                        dailyMaxUV = UVIndex.DailyMaxUV(days);
                        uvIndex    = Convert.ToInt32((double)dailyMaxUV / 25);
                        Monitor.Log($"Forecasted max UV value (if sunny): {dailyMaxUV} | UV Index: {uvIndex}", LogLevel.Debug);
                        return;
                    }
                }
                //No date argument provided OR day provided is today
                days       = SDate.Now().DaysSinceStart;
                dailyMaxUV = UVIndex.DailyMaxUV(days, UVIndex.GetTodaysWeather());
                uvIndex    = Convert.ToInt32((double)dailyMaxUV / 25);
                Monitor.Log($"Today's max UV value: {dailyMaxUV} | UV Index: {uvIndex}", LogLevel.Debug);
            }
            catch (Exception ex)
            {
                Monitor.Log($"Command getUV failed:\n{ex}", LogLevel.Warn);
            }
        }
Example #5
0
        // Finds the next Garbage Hat to be available on or after the given date.
        public static Prediction?FindGarbageHat(SDate fromDate)
        {
            Utilities.CheckWorldReady();
            if (!IsAvailable)
            {
                throw new UnavailableException("garbage");
            }

            for (int days = fromDate.DaysSinceStart;
                 days < fromDate.DaysSinceStart + Utilities.MaxHorizon;
                 ++days)
            {
                List <Prediction> predictions =
                    ListLootForDate(SDate.FromDaysSinceStart(days), true)
                    .Where((p) => p.loot is Hat).ToList();
                if (predictions.Count > 0)
                {
                    return(predictions[0]);
                }
            }
            return(null);
        }
Example #6
0
        // Lists the next several night events to occur on or after the given
        // date, up to the given limit, optionally of a given type.
        public static List <Prediction> ListNextEventsFromDate
            (SDate fromDate, uint limit, Event?onlyType = null)
        {
            Utilities.CheckWorldReady();

            // Logic from StardewValley.Utility.<>c.<pickFarmEvent>b__146_0()
            // as implemented in Stardew Predictor by MouseyPounds.

            List <Prediction> predictions =
                new List <Prediction> ();

            for (int days = fromDate.DaysSinceStart;
                 predictions.Count < limit &&
                 days < fromDate.DaysSinceStart + Utilities.MaxHorizon;
                 ++days)
            {
                SDate tonight  = SDate.FromDaysSinceStart(days);
                SDate tomorrow = SDate.FromDaysSinceStart(days + 1);

                // No event if there is a wedding tomorrow.
                foreach (Farmer farmer in Game1.getAllFarmers())
                {
                    Friendship spouse = farmer.GetSpouseFriendship();
                    if (spouse != null &&
                        spouse.WeddingDate == tomorrow.ToWorldDate())
                    {
                        continue;
                    }
                }

                Event  @event = Event.None;
                Random rng    = new Random(((int)Game1.uniqueIDForThisGame / 2) +
                                           days + 1);
                if (days == 29)
                {
                    @event = Event.Earthquake;
                }
                // Ignoring the possibility of bundle completion here.
                else if (rng.NextDouble() < 0.01 && tomorrow.Season != "winter")
                {
                    @event = Event.Fairy;
                }
                else if (rng.NextDouble() < 0.01)
                {
                    @event = Event.Witch;
                }
                else if (rng.NextDouble() < 0.01)
                {
                    @event = Event.Meteorite;
                }
                else if (rng.NextDouble() < 0.01 && tomorrow.Year > 1)
                {
                    @event = Event.StrangeCapsule;
                }
                else if (rng.NextDouble() < 0.01)
                {
                    @event = Event.StoneOwl;
                }

                if (@event == Event.None ||
                    (onlyType != null && @event != onlyType))
                {
                    continue;
                }

                predictions.Add(new Prediction
                {
                    date = tonight, @event = @event
                });
            }

            return(predictions);
        }
Example #7
0
        // Lists the next several night events to occur on or after the given
        // date, up to the given limit, optionally of a given type.
        public static List <Prediction> ListNextEventsFromDate(SDate fromDate,
                                                               uint limit, Event?onlyType = null)
        {
            Utilities.CheckWorldReady();
            if (!IsAvailable)
            {
                throw new UnavailableException("night events");
            }

            // Logic from StardewValley.Utility.pickFarmEvent
            // as implemented in Stardew Predictor by MouseyPounds.

            List <Prediction> predictions = new ();

            for (int days = fromDate.DaysSinceStart;
                 predictions.Count < limit &&
                 days < fromDate.DaysSinceStart + Utilities.MaxHorizon;
                 ++days)
            {
                SDate tonight  = SDate.FromDaysSinceStart(days);
                SDate tomorrow = SDate.FromDaysSinceStart(days + 1);

                // No event if there is a wedding tomorrow.
                foreach (Farmer farmer in Game1.getAllFarmers())
                {
                    Friendship spouse = farmer.GetSpouseFriendship();
                    if (spouse != null &&
                        spouse.WeddingDate == tomorrow.ToWorldDate())
                    {
                        continue;
                    }
                }

                Event  @event = Event.None;
                Random rng    = new (((int)Game1.uniqueIDForThisGame / 2) + days + 1);
                if (days == 29)
                {
                    @event = Event.Earthquake;
                }
                // Ignoring the possibility of a WorldChangeEvent here.
                else if (rng.NextDouble() < 0.01 && tomorrow.Season != "winter")
                {
                    @event = Event.Fairy;
                }
                else if (rng.NextDouble() < 0.01)
                {
                    @event = Event.Witch;
                }
                else if (rng.NextDouble() < 0.01)
                {
                    @event = Event.Meteorite;
                }
                else if (rng.NextDouble() < 0.005)
                {
                    @event = Event.StoneOwl;
                }
                else if (rng.NextDouble() < 0.008 && tomorrow.Year > 1 &&
                         !Utility.doesMasterPlayerHaveMailReceivedButNotMailForTomorrow("Got_Capsule"))
                {
                    @event = Event.StrangeCapsule;
                }

                if (@event == Event.None ||
                    (onlyType != null && @event != onlyType))
                {
                    continue;
                }

                predictions.Add(new Prediction {
                    date = tonight, @event = @event
                });
            }

            return(predictions);
        }
Example #8
0
 public string FromDaysSinceStart(int daysSinceStart)
 {
     // act
     return(SDate.FromDaysSinceStart(daysSinceStart).ToString());
 }
Example #9
0
 public void FromDaysSinceStart_RejectsInvalidValues(int daysSinceStart)
 {
     // act & assert
     Assert.Throws <ArgumentException>(() => _ = SDate.FromDaysSinceStart(daysSinceStart), "Passing the invalid number of days didn't throw the expected exception.");
 }