diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c6e4a75
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+/.git/
+/.idea/
+/assets/
+/Stardew Valley/
+/packages/
+/obj/
+/bin/
\ No newline at end of file
diff --git a/ForecasterText.csproj b/ForecasterText.csproj
new file mode 100644
index 0000000..efbb889
--- /dev/null
+++ b/ForecasterText.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {DB67424C-151C-4F2B-9EE7-02594AEBE089}
+ Library
+ Properties
+ ForecasterText
+ ForecasterText
+ v4.7.2
+ 512
+ true
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f331cd4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Gregory Stefanowich
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/ModEntry.cs b/ModEntry.cs
new file mode 100644
index 0000000..2a53b90
--- /dev/null
+++ b/ModEntry.cs
@@ -0,0 +1,50 @@
+/*
+ * This software is licensed under the MIT License
+ * https://github.com/GStefanowich/SDV-Forecaster
+ *
+ * Copyright (c) 2019 Gregory Stefanowich
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+using StardewModdingAPI;
+using StardewValley;
+
+namespace ForecasterText {
+ public class ModEntry : Mod {
+ public static IMonitor MONITOR;
+ public static string MOD_ID;
+ public static IModHelper MOD_HELPER;
+
+ /*
+ * Mod Initializer
+ */
+ public override void Entry(IModHelper helper) {
+ // Initialize the Harmony Override Console
+ ModEntry.MOD_ID = this.ModManifest.UniqueID;
+ ModEntry.MOD_HELPER = this.Helper;
+ ModEntry.MONITOR = this.Monitor;
+
+ ModEntry.MOD_HELPER.Events.GameLoop.DayStarted += ModEvents.OnDayStart;
+ }
+
+ public static bool PlayerHasRecipe(string recipe) => Game1.player.cookingRecipes.ContainsKey(recipe);
+ public static bool PlayerBeenToIsland() => Game1.player.hasOrWillReceiveMail("Visited_Island");
+ }
+}
diff --git a/ModEvents.cs b/ModEvents.cs
new file mode 100644
index 0000000..2d55a7d
--- /dev/null
+++ b/ModEvents.cs
@@ -0,0 +1,164 @@
+/*
+ * This software is licensed under the MIT License
+ * https://github.com/GStefanowich/SDV-Forecaster
+ *
+ * Copyright (c) 2019 Gregory Stefanowich
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+using System;
+using System.Collections.Generic;
+using StardewModdingAPI;
+using StardewModdingAPI.Events;
+using StardewValley;
+
+namespace ForecasterText {
+ public static class ModEvents {
+ private static readonly VirtualTV TELEVISION = new VirtualTV();
+
+ public static void OnDayStart(object sender, DayStartedEventArgs e) {
+ if (!Context.IsWorldReady)
+ return;
+
+ // Send messages for each event
+ ModEvents.SendChatMessage(new [] {
+ ModEvents.GetTownForecast(),
+ ModEvents.GetIslandForecast(),
+ ModEvents.GetDailyLuck(),
+ ModEvents.GetQueenOfSauce()
+ });
+ }
+
+ /*
+ * Show messages in chat
+ */
+
+ private static void SendChatMessage( IEnumerable messages ) {
+ foreach (string message in messages) ModEvents.SendChatMessage(message);
+ }
+ private static void SendChatMessage( string message ) {
+ if (message != null) Game1.chatBox.addInfoMessage($"TV: {message}");
+ }
+
+ /*
+ * Weather
+ */
+
+ private static string GetTownForecast() {
+ WorldDate date = new WorldDate(Game1.Date);
+ ++date.TotalDays;
+ return ModEvents.GetWeatherInformation("Pelican Town forecast", !Game1.IsMasterGame ? Game1.getWeatherModificationsForDate(date, Game1.netWorldState.Value.WeatherForTomorrow) : Game1.getWeatherModificationsForDate(date, Game1.weatherForTomorrow));
+ }
+
+ private static string GetIslandForecast() {
+ if (!ModEntry.PlayerBeenToIsland())
+ return null;
+ return ModEvents.GetWeatherInformation("Ginger Island forecast", Game1.netWorldState.Value.GetWeatherForLocation(
+ Game1.getLocationFromName("IslandSouth").GetLocationContext()
+ ).weatherForTomorrow.Value);
+ }
+
+ private static string GetWeatherInformation( string prefix, int num ) {
+ switch (num) {
+ case 0:
+ case 4:
+ case 6:
+ return $"{prefix} [99]";
+ case 1:
+ return $"{prefix} [101][100]";
+ case 2:
+ if (Game1.currentSeason.Equals("winter"))
+ return $"{prefix} [103]";
+ return $"{prefix} [99]";
+ case 3:
+ return $"{prefix} [102][100]";
+ case 5:
+ return $"{prefix} [103]";
+ }
+ return $"{prefix}: ???";
+ }
+
+ /*
+ * Luck
+ */
+
+ private static string GetDailyLuck() {
+ Farmer who = Game1.player;
+ if (who.team.sharedDailyLuck.Value == -0.12)
+ return "[119]are[15]today"; // Furious (TV.cs.13191)
+ if (who.DailyLuck == 0.0)
+ return "[119]are[16]today"; // Neutral (TV.cs.13201)
+ if (who.DailyLuck >= -0.07 && who.DailyLuck < -0.02) {
+ Random random = new Random((int) Game1.stats.DaysPlayed + (int) Game1.uniqueIDForThisGame / 2);
+ if (random.NextDouble() < 0.5)
+ return "[119]are[18]today"; // Somewhat Annoyed (TV.cs.13193)
+ return "[119]are[11]today"; // Mildly Perturbed (TV.cs.13195)
+ }
+ if (who.DailyLuck >= -0.07 && who.team.sharedDailyLuck.Value != 0.12) {
+ if (who.DailyLuck > 0.07)
+ return "[119]are[43]today"; // Very Happy (TV.cs.13198)
+ if (who.DailyLuck <= 0.02)
+ return "[119]are[16]today"; // Neutral (TV.cs.13200)
+ return "[119]are[2]today"; // Good Humor (TV.cs.13199)
+ }
+ if (who.DailyLuck >= -0.07)
+ return "[119]are[1]today"; // Joyous (TV.cs.13197)
+ return "[119]are[14]today"; // Very Displeased (TV.cs.13192)
+ }
+
+ /*
+ * Recipes
+ */
+
+ private static string GetQueenOfSauce() {
+ int num = (int)(Game1.stats.DaysPlayed % 224U / 7U);
+ if (Game1.stats.DaysPlayed % 224U == 0U)
+ num = 32;
+ FarmerTeam team = Game1.player.team;
+ switch (Game1.dayOfMonth % 7) {
+ case 0: // Sunday
+ break;
+ case 3: // Wednesday
+ if (team.lastDayQueenOfSauceRerunUpdated.Value != Game1.Date.TotalDays) {
+ team.lastDayQueenOfSauceRerunUpdated.Set(Game1.Date.TotalDays);
+ team.queenOfSauceRerunWeek.Set(ModEvents.TELEVISION.GetRerunWeek());
+ }
+ num = team.queenOfSauceRerunWeek.Value;
+ break;
+ default: return null;
+ }
+
+ // Dictionary of recipes
+ Dictionary dictionary = Game1.temporaryContent.Load>("Data\\TV\\CookingChannel");
+ if (!dictionary.TryGetValue($"{num}", out string translation))
+ return null;
+
+ // Split the translation info
+ string[] recipeInfo = translation.Split('/');
+ if (recipeInfo.Length <= 0)
+ return null;
+
+ // Get the recipe name
+ string recipeName = recipeInfo[0];
+ return $"[{(ModEntry.PlayerHasRecipe(recipeName) ? "135" : "132")}]Learn to make \"{recipeName}\"";
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..212e622
--- /dev/null
+++ b/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ForecasterText")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ForecasterText")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("db67424c-151c-4f2b-9ee7-02594aebe089")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c4949b1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+# Forecaster Texts
+**Forecaster Texts** is a **[Stardew Valley](https://www.stardewvalley.net/)** mod that uses the [Stardew Modding API](https://www.nexusmods.com/stardewvalley/mods/2400).
+
+- See the mod on [Nexus](https://www.nexusmods.com/stardewvalley/mods/7541/).
\ No newline at end of file
diff --git a/VirtualTV.cs b/VirtualTV.cs
new file mode 100644
index 0000000..5b3127f
--- /dev/null
+++ b/VirtualTV.cs
@@ -0,0 +1,13 @@
+using StardewValley.Objects;
+
+namespace ForecasterText {
+ public class VirtualTV : TV {
+
+ public VirtualTV() : base() {}
+
+ public int GetRerunWeek() {
+ return base.getRerunWeek();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..1192d4e
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,12 @@
+{
+ "Name": "Forecaster Text",
+ "Author": "TheElm",
+ "Version": "1.0.0",
+ "Description": "Receive messages from the News station every day",
+ "UniqueID": "TheElm.ForecasterText",
+ "EntryDll": "ForecasterText.dll",
+ "MinimumApiVersion": "3.8.0",
+ "UpdateKeys": [
+ "Nexus:7541"
+ ]
+}
\ No newline at end of file
diff --git a/packages.config b/packages.config
new file mode 100644
index 0000000..54fe9bb
--- /dev/null
+++ b/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file