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