diff --git a/GeneralMods/AdvancedSaveBackup/SaveBackup.cs b/GeneralMods/AdvancedSaveBackup/SaveBackup.cs index fb19a21e..592b6b35 100644 --- a/GeneralMods/AdvancedSaveBackup/SaveBackup.cs +++ b/GeneralMods/AdvancedSaveBackup/SaveBackup.cs @@ -12,7 +12,7 @@ namespace Omegasis.SaveBackup public class SaveBackup : Mod { /********* - ** Properties + ** Fields *********/ /// The folder path containing the game's app data. private static readonly string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley"); @@ -41,17 +41,17 @@ namespace Omegasis.SaveBackup this.BackupSaves(SaveBackup.PrePlayBackupsPath); - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; + helper.Events.GameLoop.Saving += this.OnSaving; } /********* ** Private methods *********/ - /// The method invoked before the save is updated. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + private void OnSaving(object sender, SavingEventArgs e) { this.BackupSaves(SaveBackup.NightlyBackupsPath); } diff --git a/GeneralMods/AdvancedSaveBackup/manifest.json b/GeneralMods/AdvancedSaveBackup/manifest.json index 8db3680c..bb113ace 100644 --- a/GeneralMods/AdvancedSaveBackup/manifest.json +++ b/GeneralMods/AdvancedSaveBackup/manifest.json @@ -5,6 +5,6 @@ "Description": "Backs up your save files when loading SMAPI and every in game night when saving.", "UniqueID": "Omegasis.AdvancedSaveBackup", "EntryDll": "AdvancedSaveBackup.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:435" ] } diff --git a/GeneralMods/AutoSpeed/AutoSpeed.cs b/GeneralMods/AutoSpeed/AutoSpeed.cs index 80d44cdb..d4859a35 100644 --- a/GeneralMods/AutoSpeed/AutoSpeed.cs +++ b/GeneralMods/AutoSpeed/AutoSpeed.cs @@ -1,4 +1,3 @@ -using System; using Omegasis.AutoSpeed.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -10,7 +9,7 @@ namespace Omegasis.AutoSpeed public class AutoSpeed : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -23,7 +22,7 @@ namespace Omegasis.AutoSpeed /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - GameEvents.UpdateTick += this.GameEvents_UpdateTick; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; this.Config = helper.ReadConfig(); } @@ -31,10 +30,10 @@ namespace Omegasis.AutoSpeed /********* ** Private methods *********/ - /// The method invoked when the game updates (roughly 60 times per second). + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (Context.IsPlayerFree) Game1.player.addedSpeed = this.Config.Speed; diff --git a/GeneralMods/AutoSpeed/manifest.json b/GeneralMods/AutoSpeed/manifest.json index 39a0695d..acc444d5 100644 --- a/GeneralMods/AutoSpeed/manifest.json +++ b/GeneralMods/AutoSpeed/manifest.json @@ -5,6 +5,6 @@ "Description": "Got to go fast!", "UniqueID": "Omegasis.AutoSpeed", "EntryDll": "AutoSpeed.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:443" ] } diff --git a/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs b/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs index e09dadda..494db12c 100644 --- a/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs +++ b/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs @@ -10,7 +10,7 @@ namespace Omegasis.BillboardAnywhere public class BillboardAnywhere : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -25,20 +25,20 @@ namespace Omegasis.BillboardAnywhere { this.Config = helper.ReadConfig(); - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; } /********* ** Private methods *********/ - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + public void OnButtonPressed(object sender, ButtonPressedEventArgs e) { // load menu if key pressed - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) + if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding) Game1.activeClickableMenu = new Billboard(); } } diff --git a/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs b/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs index ec6f3b5c..8f16e667 100644 --- a/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs +++ b/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs @@ -1,9 +1,11 @@ +using StardewModdingAPI; + namespace Omegasis.BillboardAnywhere.Framework { /// The mod configuration. internal class ModConfig { /// The key which shows the billboard menu. - public string KeyBinding { get; set; } = "B"; + public SButton KeyBinding { get; set; } = SButton.B; } } diff --git a/GeneralMods/BillboardAnywhere/manifest.json b/GeneralMods/BillboardAnywhere/manifest.json index c35ec23e..5685e1ec 100644 --- a/GeneralMods/BillboardAnywhere/manifest.json +++ b/GeneralMods/BillboardAnywhere/manifest.json @@ -5,6 +5,6 @@ "Description": "Lets you view the billboard from anywhere.", "UniqueID": "Omegasis.BillboardAnywhere", "EntryDll": "BillboardAnywhere.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:492" ] } diff --git a/GeneralMods/BuildEndurance/BuildEndurance.cs b/GeneralMods/BuildEndurance/BuildEndurance.cs index d826fbc4..4c8f5a6e 100644 --- a/GeneralMods/BuildEndurance/BuildEndurance.cs +++ b/GeneralMods/BuildEndurance/BuildEndurance.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Omegasis.BuildEndurance.Framework; using StardewModdingAPI; @@ -11,10 +10,10 @@ namespace Omegasis.BuildEndurance public class BuildEndurance : Mod { /********* - ** Properties + ** Fields *********/ /// The relative path for the current player's data file. - private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); + private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); /// The mod settings. private ModConfig Config; @@ -47,10 +46,9 @@ namespace Omegasis.BuildEndurance { this.Config = helper.ReadConfig(); - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - GameEvents.OneSecondTick += this.GameEvents_OneSecondTick; - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saving += this.OnSaving; this.ModHelper = this.Helper; this.ModMonitor = this.Monitor; @@ -60,24 +58,18 @@ namespace Omegasis.BuildEndurance /********* ** Private methods *********/ - /// The method invoked once per second during a game update. + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_OneSecondTick(object sender, EventArgs e) - { - // nerf how quickly tool xp is gained (I hope) - if (this.HasRecentToolExp) - this.HasRecentToolExp = false; - } - - /// The method invoked when the game updates (roughly 60 times per second). - /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (!Context.IsWorldReady) return; + // nerf how quickly tool xp is gained (I hope) + if (e.IsOneSecond && this.HasRecentToolExp) + this.HasRecentToolExp = false; + // give XP when player finishes eating if (Game1.player.isEating) this.WasEating = true; @@ -112,10 +104,10 @@ namespace Omegasis.BuildEndurance } } - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { // reset state this.WasExhausted = false; @@ -124,7 +116,7 @@ namespace Omegasis.BuildEndurance this.WasEating = false; // load player data - this.PlayerData = this.Helper.ReadJsonFile(this.DataFilePath) ?? new PlayerData(); + this.PlayerData = this.Helper.Data.ReadJsonFile(this.RelativeDataPath) ?? new PlayerData(); if (this.PlayerData.OriginalMaxStamina == 0) this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina; @@ -150,10 +142,10 @@ namespace Omegasis.BuildEndurance } } - /// The method invoked just before the game is saved. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + private void OnSaving(object sender, SavingEventArgs e) { // reset data this.WasExhausted = false; @@ -179,7 +171,7 @@ namespace Omegasis.BuildEndurance this.PlayerData.NightlyStamina = Game1.player.MaxStamina; // save data - this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData); + this.Helper.Data.WriteJsonFile(this.RelativeDataPath, this.PlayerData); } /// Try and emulate the old Game1.shouldFarmerPassout logic. diff --git a/GeneralMods/BuildEndurance/manifest.json b/GeneralMods/BuildEndurance/manifest.json index 3b75abd3..965d6449 100644 --- a/GeneralMods/BuildEndurance/manifest.json +++ b/GeneralMods/BuildEndurance/manifest.json @@ -5,6 +5,6 @@ "Description": "Increase your health as you play.", "UniqueID": "Omegasis.BuildEndurance", "EntryDll": "BuildEndurance.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:445" ] } diff --git a/GeneralMods/BuildHealth/BuildHealth.cs b/GeneralMods/BuildHealth/BuildHealth.cs index bbdee068..c27a2185 100644 --- a/GeneralMods/BuildHealth/BuildHealth.cs +++ b/GeneralMods/BuildHealth/BuildHealth.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Omegasis.BuildHealth.Framework; using StardewModdingAPI; @@ -11,10 +10,10 @@ namespace Omegasis.BuildHealth public class BuildHealth : Mod { /********* - ** Properties + ** Fields *********/ /// The relative path for the current player's data file. - private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); + private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); /// The mod settings and player data. private ModConfig Config; @@ -42,10 +41,9 @@ namespace Omegasis.BuildHealth /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - GameEvents.OneSecondTick += this.GameEvents_OneSecondTick; - TimeEvents.AfterDayStarted += this.SaveEvents_BeforeSave; - SaveEvents.AfterLoad += this.SaveEvents_AfterLoaded; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.GameLoop.DayStarted += this.OnDayStarted; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; this.Config = helper.ReadConfig(); } @@ -54,24 +52,18 @@ namespace Omegasis.BuildHealth /********* ** Private methods *********/ - /// The method invoked once per second during a game update. + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_OneSecondTick(object sender, EventArgs e) - { - // nerf how quickly tool xp is gained (I hope) - if (this.HasRecentToolExp) - this.HasRecentToolExp = false; - } - - /// The method invoked when the game updates (roughly 60 times per second). - /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (!Context.IsWorldReady) return; + // nerf how quickly tool xp is gained (I hope) + if (e.IsOneSecond && this.HasRecentToolExp) + this.HasRecentToolExp = false; + // give XP when player finishes eating if (Game1.player.isEating) this.WasEating = true; @@ -106,10 +98,10 @@ namespace Omegasis.BuildHealth } } - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterLoaded(object sender, EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { // reset state this.HasRecentToolExp = false; @@ -118,7 +110,7 @@ namespace Omegasis.BuildHealth this.WasCollapsed = false; // load player data - this.PlayerData = this.Helper.ReadJsonFile(this.DataFilePath) ?? new PlayerData(); + this.PlayerData = this.Helper.Data.ReadJsonFile(this.RelativeDataPath) ?? new PlayerData(); if (this.PlayerData.OriginalMaxHealth == 0) this.PlayerData.OriginalMaxHealth = Game1.player.maxHealth; @@ -140,10 +132,10 @@ namespace Omegasis.BuildHealth Game1.player.maxHealth = this.PlayerData.BaseHealthBonus + this.PlayerData.CurrentLevelHealthBonus + this.PlayerData.OriginalMaxHealth; } - /// The method invoked just before the game saves. + /// Raised after the game begins a new day (including when the player loads a save). /// The event sender. - /// The event data. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + private void OnDayStarted(object sender, DayStartedEventArgs e) { // reset data this.LastHealth = Game1.player.maxHealth; @@ -169,7 +161,7 @@ namespace Omegasis.BuildHealth } // save data - this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData); + this.Helper.Data.WriteJsonFile(this.RelativeDataPath, this.PlayerData); } public bool shouldFarmerPassout() diff --git a/GeneralMods/BuildHealth/manifest.json b/GeneralMods/BuildHealth/manifest.json index 808dd39d..f68687dd 100644 --- a/GeneralMods/BuildHealth/manifest.json +++ b/GeneralMods/BuildHealth/manifest.json @@ -5,6 +5,6 @@ "Description": "Increase your health as you play.", "UniqueID": "Omegasis.BuildHealth", "EntryDll": "BuildHealth.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:446" ] } diff --git a/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs b/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs index 2493af01..30817b29 100644 --- a/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs +++ b/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs @@ -9,7 +9,7 @@ namespace Omegasis.BuyBackCollectables public class BuyBackCollectables : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -24,19 +24,19 @@ namespace Omegasis.BuyBackCollectables { this.Config = helper.ReadConfig(); - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; } /********* ** Private methods *********/ - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) + if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding) Game1.activeClickableMenu = new BuyBackMenu(this.Config.CostMultiplier); } } diff --git a/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs b/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs index 24bfcbf4..85efc9bd 100644 --- a/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs +++ b/GeneralMods/BuyBackCollectables/Framework/BuyBackMenu.cs @@ -13,7 +13,7 @@ namespace Omegasis.BuyBackCollectables.Framework internal class BuyBackMenu : IClickableMenu { /********* - ** Properties + ** Fields *********/ /// The organics tab ID. private const int OrganicsTab = 0; diff --git a/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs b/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs index c1299949..27288986 100644 --- a/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs +++ b/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs @@ -1,10 +1,12 @@ +using StardewModdingAPI; + namespace Omegasis.BuyBackCollectables.Framework { /// The mod configuration. internal class ModConfig { /// The key which shows the menu. - public string KeyBinding { get; set; } = "B"; + public SButton KeyBinding { get; set; } = SButton.B; /// The multiplier applied to the cost of buying back a collectable. public double CostMultiplier { get; set; } = 3.0; diff --git a/GeneralMods/BuyBackCollectables/manifest.json b/GeneralMods/BuyBackCollectables/manifest.json index a420d9ca..c4349ae3 100644 --- a/GeneralMods/BuyBackCollectables/manifest.json +++ b/GeneralMods/BuyBackCollectables/manifest.json @@ -5,6 +5,6 @@ "Description": "Lets you buy back any obtained collectable.", "UniqueID": "Omegasis.BuyBackCollectables", "EntryDll": "BuyBackCollectables.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:507" ] } diff --git a/GeneralMods/CustomNPCFramework/Class1.cs b/GeneralMods/CustomNPCFramework/Class1.cs index 49ea38ef..bbb7091e 100644 --- a/GeneralMods/CustomNPCFramework/Class1.cs +++ b/GeneralMods/CustomNPCFramework/Class1.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using CustomNPCFramework.Framework.Enums; using CustomNPCFramework.Framework.Graphics; using CustomNPCFramework.Framework.ModularNpcs.ColorCollections; @@ -8,6 +9,7 @@ using CustomNPCFramework.Framework.NPCS; using CustomNPCFramework.Framework.Utilities; using Microsoft.Xna.Framework; using StardewModdingAPI; +using StardewModdingAPI.Events; using StardewValley; namespace CustomNPCFramework @@ -63,13 +65,10 @@ namespace CustomNPCFramework ModMonitor = this.Monitor; Manifest = this.ModManifest; - StardewModdingAPI.Events.SaveEvents.AfterLoad += this.SaveEvents_LoadChar; - - StardewModdingAPI.Events.SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; - StardewModdingAPI.Events.SaveEvents.AfterSave += this.SaveEvents_AfterSave; - - StardewModdingAPI.Events.PlayerEvents.Warped += this.LocationEvents_CurrentLocationChanged; - StardewModdingAPI.Events.GameEvents.UpdateTick += this.GameEvents_UpdateTick; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saving += this.OnSaving; + helper.Events.GameLoop.Saved += this.OnSaved; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; npcTracker = new NpcTracker(); assetPool = new AssetPool(); var assetManager = new AssetManager(); @@ -82,31 +81,34 @@ namespace CustomNPCFramework /// Initialize the asset pool with some test variables. public void initializeAssetPool() { - string path = Path.Combine(ModHelper.DirectoryPath, "Content", "Graphics", "NPCS"); - assetPool.getAssetManager("testNPC").addPathCreateDirectory(new KeyValuePair("characters", path)); + string relativePath = Path.Combine("Content", "Graphics", "NPCS"); + assetPool.getAssetManager("testNPC").addPathCreateDirectory(new KeyValuePair("characters", relativePath)); } - /// A function that is called when the game finishes saving. + /// Raised after the game finishes writing data to the save file (except the initial save creation). /// The event sender. /// The event arguments. - private void SaveEvents_AfterSave(object sender, EventArgs e) + private void OnSaved(object sender, SavedEventArgs e) { npcTracker.afterSave(); } - /// A function that is called when the game is about to load. Used to clean up all the npcs from the game world to prevent it from crashing. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. /// The event arguments. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + private void OnSaving(object sender, SavingEventArgs e) { + // clean up all the npcs from the game world to prevent it from crashing npcTracker.cleanUpBeforeSave(); } - /// Called upon 60 times a second. For testing purposes only. Will remove in future release. + /// Raised after the game state is updated (≈60 times per second). /// The event sender. /// The event arguments. - private void GameEvents_UpdateTick(object sender, EventArgs e) + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { + // TODO For testing purposes only. Will remove in future release. + /* if (Game1.player.currentLocation == null) return; if (Game1.activeClickableMenu != null) return; @@ -123,16 +125,13 @@ namespace CustomNPCFramework */ } - /// Called when the player's location changes. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. /// The event arguments. - private void LocationEvents_CurrentLocationChanged(object sender, StardewModdingAPI.Events.EventArgsPlayerWarped e) { } - - /// Used to spawn a custom npc just as an example. Don't keep this code. GENERATE NPC AND CALL THE CODE - /// The event sender. - /// The event arguments. - private void SaveEvents_LoadChar(object sender, EventArgs e) + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { + // TODO Used to spawn a custom npc just as an example. Don't keep this code. GENERATE NPC AND CALL THE CODE + ExtendedNpc myNpc3 = assetPool.generateNPC(Genders.female, 0, 1, new StandardColorCollection(null, null, Color.Blue, null, Color.Yellow, null)); MerchantNpc merch = new MerchantNpc(new List() { @@ -145,52 +144,40 @@ namespace CustomNPCFramework public void initializeExamples() { return; - string dirPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Templates"); + string relativeDirPath = Path.Combine("Content", "Templates"); var aManager = assetPool.getAssetManager("testNPC"); - aManager.addPathCreateDirectory(new KeyValuePair("templates", dirPath)); - string filePath = Path.Combine(dirPath, "Example.json"); - if (!File.Exists(filePath)) - { - string getRelativePath = getShortenedDirectory(filePath); - ModMonitor.Log("THIS IS THE PATH::: " + getRelativePath); - AssetInfo info = new AssetInfo("MyExample", new NamePairings("StandingExampleL", "StandingExampleR", "StandingExampleU", "StandingExampleD"), new NamePairings("MovingExampleL", "MovingExampleR", "MovingExampleU", "MovingExampleD"), new NamePairings("SwimmingExampleL", "SwimmingExampleR", "SwimmingExampleU", "SwimmingExampleD"), new NamePairings("SittingExampleL", "SittingExampleR", "SittingExampleU", "SittingExampleD"), new Vector2(16, 16), false); - info.writeToJson(filePath); + aManager.addPathCreateDirectory(new KeyValuePair("templates", relativeDirPath)); - } - string filePath2 = Path.Combine(dirPath, "AdvancedExample.json"); - if (!File.Exists(filePath2)) + // write example { + string relativeFilePath = Path.Combine(relativeDirPath, "Example.json"); + if (!File.Exists(Path.Combine(this.Helper.DirectoryPath, relativeFilePath))) + { + ModMonitor.Log("THIS IS THE PATH::: " + relativeFilePath); + AssetInfo info = new AssetInfo("MyExample", new NamePairings("StandingExampleL", "StandingExampleR", "StandingExampleU", "StandingExampleD"), new NamePairings("MovingExampleL", "MovingExampleR", "MovingExampleU", "MovingExampleD"), new NamePairings("SwimmingExampleL", "SwimmingExampleR", "SwimmingExampleU", "SwimmingExampleD"), new NamePairings("SittingExampleL", "SittingExampleR", "SittingExampleU", "SittingExampleD"), new Vector2(16, 16), false); + info.writeToJson(relativeFilePath); - ExtendedAssetInfo info2 = new ExtendedAssetInfo("AdvancedExample", new NamePairings("AdvancedStandingExampleL", "AdvancedStandingExampleR", "AdvancedStandingExampleU", "AdvancedStandingExampleD"), new NamePairings("AdvancedMovingExampleL", "AdvancedMovingExampleR", "AdvancedMovingExampleU", "AdvancedMovingExampleD"), new NamePairings("AdvancedSwimmingExampleL", "AdvancedSwimmingExampleR", "AdvancedSwimmingExampleU", "AdvancedSwimmingExampleD"), new NamePairings("AdvancedSittingExampleL", "AdvancedSittingExampleR", "AdvancedSittingExampleU", "AdvancedSittingExampleD"), new Vector2(16, 16), false, Genders.female, new List() - { - Seasons.spring, - Seasons.summer - }, PartType.hair - ); - info2.writeToJson(filePath2); + } } - } - /// Used to splice the mod directory to get relative paths. - public static string getShortenedDirectory(string path) - { - string lol = (string)path.Clone(); - string[] spliter = lol.Split(new string[] { ModHelper.DirectoryPath }, StringSplitOptions.None); - try + // write advanced example { - return spliter[1]; - } - catch - { - return spliter[0]; + string relativeFilePath = Path.Combine(relativeDirPath, "AdvancedExample.json"); + if (!File.Exists(Path.Combine(this.Helper.DirectoryPath, relativeFilePath))) + { + ExtendedAssetInfo info2 = new ExtendedAssetInfo("AdvancedExample", new NamePairings("AdvancedStandingExampleL", "AdvancedStandingExampleR", "AdvancedStandingExampleU", "AdvancedStandingExampleD"), new NamePairings("AdvancedMovingExampleL", "AdvancedMovingExampleR", "AdvancedMovingExampleU", "AdvancedMovingExampleD"), new NamePairings("AdvancedSwimmingExampleL", "AdvancedSwimmingExampleR", "AdvancedSwimmingExampleU", "AdvancedSwimmingExampleD"), new NamePairings("AdvancedSittingExampleL", "AdvancedSittingExampleR", "AdvancedSittingExampleU", "AdvancedSittingExampleD"), new Vector2(16, 16), false, Genders.female, new List() { Seasons.spring, Seasons.summer }, PartType.hair); + info2.writeToJson(relativeFilePath); + } } } /// Used to finish cleaning up absolute asset paths into a shortened relative path. public static string getRelativeDirectory(string path) { - string s = getShortenedDirectory(path); - return s.Remove(0, 1); + return path + .Split(new[] { ModHelper.DirectoryPath }, 2, StringSplitOptions.None) + .Last() + .TrimStart(Path.DirectorySeparatorChar); } } } diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs index 8ad12a14..ad4ab1e2 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs @@ -49,17 +49,17 @@ namespace CustomNPCFramework.Framework.Graphics } /// Save the json to a certain location. - /// The absolute path to save. - public void writeToJson(string path) + /// The relative path to save. + public void writeToJson(string relativeFilePath) { - Class1.ModHelper.WriteJsonFile(path, this); + Class1.ModHelper.Data.WriteJsonFile(relativeFilePath, this); } /// Read the json from a certain location. - /// The absolute path to save. - public static AssetInfo readFromJson(string path) + /// The relative path to save. + public static AssetInfo readFromJson(string relativePath) { - return Class1.ModHelper.ReadJsonFile(path); + return Class1.ModHelper.Data.ReadJsonFile(relativePath); } } } diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs index ef6fc18f..82a27c43 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.IO; using CustomNPCFramework.Framework.Enums; @@ -9,65 +8,48 @@ namespace CustomNPCFramework.Framework.Graphics public class AssetManager { /// A list of all of the assets held by this asset manager. - public List assets; + public List assets { get; } = new List(); - /// A list of all of the directories managed by this asset manager. - public Dictionary paths; - - /// Construct an instance. - public AssetManager() - { - this.assets = new List(); - this.paths = new Dictionary(); - } - - /// Construct an instance. - /// A list of all directories to be managed by the asset manager. Name, path is the key pair value. - public AssetManager(Dictionary assetsPathsToLoadFrom) - { - this.assets = new List(); - this.paths = assetsPathsToLoadFrom; - } + /// A list of directories managed by this asset manager, relative to the mod folder. + public Dictionary relativePaths { get; } = new Dictionary(); /// Default loading function from hardcoded paths. public void loadAssets() { - foreach (var path in this.paths) - this.ProcessDirectory(path.Value); + foreach (var relativePath in this.relativePaths) + this.ProcessDirectory(relativePath.Value); } /// Process all .json files in the given directory. If there are more nested directories, keep digging to find more .json files. Also allows us to specify a broader directory like Content/Grahphics/ModularNPC/Hair to have multiple hair styles. - /// The absolute directory path to process. + /// The relative directory path to process. /// Taken from Microsoft c# documented webpages. - private void ProcessDirectory(string targetDirectory) + private void ProcessDirectory(string relativeDirPath) { - // Process the list of files found in the directory. - string[] files = Directory.GetFiles(targetDirectory, "*.json"); - foreach (string file in files) - this.ProcessFile(file, targetDirectory); + DirectoryInfo root = new DirectoryInfo(Path.Combine(Class1.ModHelper.DirectoryPath, relativeDirPath)); + foreach (FileInfo file in root.GetFiles("*.json")) + this.ProcessFile(Path.Combine(relativeDirPath, file.Name), relativeDirPath); // Recurse into subdirectories of this directory. - string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory); - foreach (string subdirectory in subdirectoryEntries) - this.ProcessDirectory(subdirectory); + foreach (DirectoryInfo subdir in root.GetDirectories()) + this.ProcessDirectory(Path.Combine(relativeDirPath, subdir.Name)); } /// Actually load in the asset information. - /// The absolute file path to process. - /// The absolute directory path containing the file. - private void ProcessFile(string file, string path) + /// The relative path to the file to process. + /// The relative path containing the file. + private void ProcessFile(string relativeFilePath, string relativeDirPath) { try { - ExtendedAssetInfo info = ExtendedAssetInfo.readFromJson(file); - AssetSheet sheet = new AssetSheet(info, path); + ExtendedAssetInfo info = ExtendedAssetInfo.readFromJson(relativeFilePath); + AssetSheet sheet = new AssetSheet(info, relativeDirPath); this.addAsset(sheet); Class1.ModMonitor.Log("Loaded in new modular asset: " + info.assetName + " asset type: " + info.type); } catch { - AssetInfo info = AssetInfo.readFromJson(file); - AssetSheet sheet = new AssetSheet(info, path); + AssetInfo info = AssetInfo.readFromJson(relativeFilePath); + AssetSheet sheet = new AssetSheet(info, relativeDirPath); this.addAsset(sheet); } } @@ -102,16 +84,16 @@ namespace CustomNPCFramework.Framework.Graphics } /// Add a path to the dictionary. - /// The absolute path to add. + /// The relative path to add. private void addPath(KeyValuePair path) { - this.paths.Add(path.Key, path.Value); + this.relativePaths.Add(path.Key, path.Value); } /// Create appropriate directories for the path. private void createDirectoriesFromPaths() { - foreach (var v in this.paths) + foreach (var v in this.relativePaths) Directory.CreateDirectory(Path.Combine(Class1.ModHelper.DirectoryPath, v.Value)); } diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetPool.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetPool.cs index caf97e00..0361206c 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetPool.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetPool.cs @@ -351,7 +351,7 @@ namespace CustomNPCFramework.Framework.Graphics return new StandardCharacterAnimation(bodySprite, eyesSprite, hairSprite, shirtSprite, pantsSprite, shoesSprite, accessoryCollection, drawColors); } - /// Get the string for the standard character sprite to be used from this asset sheet. + /// Get the relative path for the standard character sprite to be used from this asset sheet. /// The standard asset sheet to be used. public virtual string getDefaultSpriteImage(AssetSheet imageGraphics) { diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs index d868de75..93126765 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs @@ -25,21 +25,13 @@ namespace CustomNPCFramework.Framework.Graphics /// Construct an instance. /// The asset info file to be read in or created. Holds path information. - /// The path to the assetinfo file. + /// The relative path to the assetinfo file. /// The direction to set the animation. - public AssetSheet(AssetInfo info, string path, Direction direction = Direction.down) + public AssetSheet(AssetInfo info, string relativeDirPath, Direction direction = Direction.down) { this.assetInfo = info; - this.textures = new TextureGroup(info, path, direction); - try - { - this.path = Class1.getShortenedDirectory(path); - } - catch - { - this.path = path; - } - + this.textures = new TextureGroup(info, relativeDirPath, direction); + this.path = relativeDirPath; this.index = 0; } diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/DirectionalTexture.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/DirectionalTexture.cs index 524dd53b..2834ea98 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/DirectionalTexture.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/DirectionalTexture.cs @@ -56,17 +56,12 @@ namespace CustomNPCFramework.Framework.Graphics } } - public DirectionalTexture(IModHelper helper, NamePairings info, string path, Direction direction = Direction.down) + public DirectionalTexture(IModHelper helper, NamePairings info, string relativePath, Direction direction = Direction.down) { - string leftString = Class1.getShortenedDirectory(Path.Combine(path, info.leftString + ".png")).Remove(0, 1); - string rightString = Class1.getShortenedDirectory(Path.Combine(path, info.rightString + ".png")).Remove(0, 1); - string upString = Class1.getShortenedDirectory(Path.Combine(path, info.upString + ".png")).Remove(0, 1); - string downString = Class1.getShortenedDirectory(Path.Combine(path, info.downString + ".png")).Remove(0, 1); - - this.leftTexture = new Texture2DExtended(helper, leftString); - this.rightTexture = new Texture2DExtended(helper, rightString); - this.upTexture = new Texture2DExtended(helper, upString); - this.downTexture = new Texture2DExtended(helper, downString); + this.leftTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.leftString}.png")); + this.rightTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.rightString}.png")); + this.upTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.upString}.png")); + this.downTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.downString}.png")); switch (direction) { diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/ExtendedAssetInfo.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/ExtendedAssetInfo.cs index 41745722..58d020d5 100644 --- a/GeneralMods/CustomNPCFramework/Framework/Graphics/ExtendedAssetInfo.cs +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/ExtendedAssetInfo.cs @@ -39,17 +39,17 @@ namespace CustomNPCFramework.Framework.Graphics } /// Save the json to a certain location. - /// The absolute path to write. - public new void writeToJson(string path) + /// The relative path to write. + public new void writeToJson(string relativePath) { - Class1.ModHelper.WriteJsonFile(path, this); + Class1.ModHelper.Data.WriteJsonFile(relativePath, this); } /// Read the json from a certain location. - /// The absolute path to read. - public new static ExtendedAssetInfo readFromJson(string path) + /// The relative path to read. + public new static ExtendedAssetInfo readFromJson(string relativePath) { - return Class1.ModHelper.ReadJsonFile(path); + return Class1.ModHelper.Data.ReadJsonFile(relativePath); } } } diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs index 2a02bbff..0ee288e4 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs @@ -14,17 +14,10 @@ namespace CustomNPCFramework.Framework.ModularNpcs public string relativePath; /// Construct an instance. - /// The full path to the file. - public Sprite(string path) + /// The relative path to the file. + public Sprite(string relativePath) { - try - { - this.relativePath = Class1.getShortenedDirectory(path); - } - catch - { - this.relativePath = path; - } + this.relativePath = relativePath; try { this.sprite = new AnimatedSprite(); diff --git a/GeneralMods/CustomNPCFramework/manifest.json b/GeneralMods/CustomNPCFramework/manifest.json index 0aec6403..6b916b5b 100644 --- a/GeneralMods/CustomNPCFramework/manifest.json +++ b/GeneralMods/CustomNPCFramework/manifest.json @@ -1,10 +1,13 @@ { - "Name": "CustomNPCFramework", + "Name": "Custom NPC Framework", "Author": "Alpha_Omegasis", "Version": "0.1.0", - "Description": "A system to add custom npcs to Stardew.", + "Description": "A system to add custom NPCs to Stardew.", "UniqueID": "Omegasis.CustomNPCFramework", "EntryDll": "CustomNPCFramework.dll", - "MinimumApiVersion": "2.0", - "UpdateKeys": [] + "MinimumApiVersion": "2.10.1", + "UpdateKeys": [], + "Dependencies": [ + { "UniqueID": "Omegasis.StardustCore" } + ] } diff --git a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs index e8e4fe99..058b9167 100644 --- a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs +++ b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs @@ -15,7 +15,7 @@ namespace Omegasis.DailyQuestAnywhere public class DailyQuestAnywhere : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -32,43 +32,43 @@ namespace Omegasis.DailyQuestAnywhere { this.Config = helper.ReadConfig(); - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; - SaveEvents.AfterSave += this.SaveEvents_AfterSave; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; } /********* ** Private methods *********/ - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) + if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding) + { if (!Game1.player.hasDailyQuest()) { if (this.dailyQuest == null) - { this.dailyQuest = this.generateDailyQuest(); - } Game1.questOfTheDay = this.dailyQuest; Game1.activeClickableMenu = new Billboard(true); } + } } - /// Makes my daily quest referene null so we can't just keep getting a new reference. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterSave(object sender, System.EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { - this.dailyQuest = null; //Nullify my quest reference. + // makes daily quest null so we can't just keep getting a new reference + this.dailyQuest = null; } /// Generate a daily quest for sure. public Quest generateDailyQuest() { - Random chanceRandom = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed); int chance = chanceRandom.Next(0, 101); float actualChance = chance / 100; @@ -85,15 +85,15 @@ namespace Omegasis.DailyQuestAnywhere case 1: return new FishingQuest(); case 2: - return new StardewValley.Quests.CraftingQuest(); + return new CraftingQuest(); case 3: - return new StardewValley.Quests.ItemDeliveryQuest(); + return new ItemDeliveryQuest(); case 4: - return new StardewValley.Quests.ItemHarvestQuest(); + return new ItemHarvestQuest(); case 5: - return new StardewValley.Quests.ResourceCollectionQuest(); + return new ResourceCollectionQuest(); case 6: - return new StardewValley.Quests.SlayMonsterQuest(); + return new SlayMonsterQuest(); } } return null; //This should never happen. diff --git a/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs index a88ee0fe..9190d89f 100644 --- a/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs +++ b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs @@ -1,10 +1,12 @@ +using StardewModdingAPI; + namespace Omegasis.DailyQuestAnywhere.Framework { /// The mod configuration. internal class ModConfig { /// The key which shows the menu. - public string KeyBinding { get; set; } = "H"; + public SButton KeyBinding { get; set; } = SButton.H; /// The chance for a daily quest to actually happen. public float chanceForDailyQuest { get; set; } = .75f; diff --git a/GeneralMods/DailyQuestAnywhere/manifest.json b/GeneralMods/DailyQuestAnywhere/manifest.json index 319acf00..f573351b 100644 --- a/GeneralMods/DailyQuestAnywhere/manifest.json +++ b/GeneralMods/DailyQuestAnywhere/manifest.json @@ -5,6 +5,6 @@ "Description": "Open the daily quest board from anywhere in the game.", "UniqueID": "Omegasis.DailyQuestAnywhere", "EntryDll": "DailyQuestAnywhere.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:513" ] } diff --git a/GeneralMods/Fall28SnowDay/Fall28SnowDay.cs b/GeneralMods/Fall28SnowDay/Fall28SnowDay.cs index 00b042d6..14b3e63a 100644 --- a/GeneralMods/Fall28SnowDay/Fall28SnowDay.cs +++ b/GeneralMods/Fall28SnowDay/Fall28SnowDay.cs @@ -1,4 +1,3 @@ -using System; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -15,17 +14,17 @@ namespace Omegasis.Fall28SnowDay /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; + helper.Events.GameLoop.Saving += this.OnSaving; } /********* ** Private methods *********/ - /// The method invoked just before the game saves. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - public void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + public void OnSaving(object sender, SavingEventArgs e) { if (Game1.IsFall && Game1.dayOfMonth == 27) Game1.weatherForTomorrow = Game1.weather_snow; diff --git a/GeneralMods/Fall28SnowDay/manifest.json b/GeneralMods/Fall28SnowDay/manifest.json index 5681c600..35210825 100644 --- a/GeneralMods/Fall28SnowDay/manifest.json +++ b/GeneralMods/Fall28SnowDay/manifest.json @@ -5,6 +5,6 @@ "Description": "Makes it snow on Fall 28, which makes a good explanation for all the snow on the next day.", "UniqueID": "Omegasis.Fall28SnowDay", "EntryDll": "Fall28SnowDay.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:486" ] } diff --git a/GeneralMods/FarmersMarketStall/Class1.cs b/GeneralMods/FarmersMarketStall/Class1.cs index 6d4e3138..1c08ebd9 100644 --- a/GeneralMods/FarmersMarketStall/Class1.cs +++ b/GeneralMods/FarmersMarketStall/Class1.cs @@ -3,6 +3,7 @@ using EventSystem.Framework.FunctionEvents; using FarmersMarketStall.Framework.MapEvents; using Microsoft.Xna.Framework; using StardewModdingAPI; +using StardewModdingAPI.Events; using StardewValley; namespace FarmersMarketStall @@ -29,17 +30,23 @@ namespace FarmersMarketStall ModHelper = this.Helper; ModMonitor = this.Monitor; - StardewModdingAPI.Events.SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; - StardewModdingAPI.Events.SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + helper.Events.GameLoop.Saving += this.OnSaving; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; marketStall = new Framework.MarketStall(); } - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// Raised after the player loads a save slot and the world is initialised. + /// The event sender. + /// The event arguments. + private void OnSaveLoaded(object sender, EventArgs e) { EventSystem.EventSystem.eventManager.addEvent(Game1.getLocationFromName("BusStop"), new ShopInteractionEvent("FarmersMarketStall", Game1.getLocationFromName("BusStop"), new Vector2(6, 11), new MouseButtonEvents(null, true), new MouseEntryLeaveEvent(null, null))); } - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// Raised before the game begins writes data to the save file (except the initial save creation). + /// The event sender. + /// The event arguments. + private void OnSaving(object sender, SavingEventArgs e) { if (marketStall.stock.Count > 0) { diff --git a/GeneralMods/FarmersMarketStall/manifest.json b/GeneralMods/FarmersMarketStall/manifest.json index 6cf9b432..be2231a3 100644 --- a/GeneralMods/FarmersMarketStall/manifest.json +++ b/GeneralMods/FarmersMarketStall/manifest.json @@ -1,11 +1,11 @@ { - "Name": "FarmersMarketStall", + "Name": "Farmers Market Stall", "Author": "Alpha_Omegasis", "Version": "0.1.0", "Description": "A system to add a farmers market stall to Sundrop.", "UniqueID": "SunDrop.SunDropMapEvents.FarmersMarketStall", "EntryDll": "FarmersMarketStall.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [], "Dependencies": [ { "UniqueID": "Omegasis.EventSystem" } diff --git a/GeneralMods/HappyBirthday/Framework/BirthdayMenu.cs b/GeneralMods/HappyBirthday/Framework/BirthdayMenu.cs index 8c6f8e9b..9824db59 100644 --- a/GeneralMods/HappyBirthday/Framework/BirthdayMenu.cs +++ b/GeneralMods/HappyBirthday/Framework/BirthdayMenu.cs @@ -11,7 +11,7 @@ namespace Omegasis.HappyBirthday.Framework internal class BirthdayMenu : IClickableMenu { /********* - ** Properties + ** Fields *********/ /// The labels to draw. private readonly List Labels = new List(); diff --git a/GeneralMods/HappyBirthday/Framework/ModConfig.cs b/GeneralMods/HappyBirthday/Framework/ModConfig.cs index 87d56ad5..a4d9b010 100644 --- a/GeneralMods/HappyBirthday/Framework/ModConfig.cs +++ b/GeneralMods/HappyBirthday/Framework/ModConfig.cs @@ -1,10 +1,12 @@ +using StardewModdingAPI; + namespace Omegasis.HappyBirthday.Framework { /// The mod configuration. public class ModConfig { /// The key which shows the menu. - public string KeyBinding { get; set; } = "O"; + public SButton KeyBinding { get; set; } = SButton.O; /// The minimum amount of friendship needed to get a birthday gift. public int minNeutralFriendshipGiftLevel = 3; diff --git a/GeneralMods/HappyBirthday/Framework/ObjectUtility.cs b/GeneralMods/HappyBirthday/Framework/ObjectUtility.cs index 469a0b31..84b12bc0 100644 --- a/GeneralMods/HappyBirthday/Framework/ObjectUtility.cs +++ b/GeneralMods/HappyBirthday/Framework/ObjectUtility.cs @@ -9,7 +9,7 @@ namespace Omegasis.HappyBirthday.Framework internal class ObjectUtility { /********* - ** Properties + ** Fields *********/ /// The cached object data. private static readonly Object[] ObjectList = ObjectUtility.GetAllObjects().ToArray(); diff --git a/GeneralMods/HappyBirthday/HappyBirthday.cs b/GeneralMods/HappyBirthday/HappyBirthday.cs index 628acc30..77bdf380 100644 --- a/GeneralMods/HappyBirthday/HappyBirthday.cs +++ b/GeneralMods/HappyBirthday/HappyBirthday.cs @@ -18,7 +18,7 @@ namespace Omegasis.HappyBirthday public class HappyBirthday : Mod, IAssetEditor { /********* - ** Properties + ** Fields *********/ /// The relative path for the current player's data file. private string DataFilePath; @@ -76,16 +76,15 @@ namespace Omegasis.HappyBirthday //helper.Content.AssetLoaders.Add(new PossibleGifts()); Config = helper.ReadConfig(); - TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; - MenuEvents.MenuChanged += this.MenuEvents_MenuChanged; - MenuEvents.MenuClosed += this.MenuEvents_MenuClosed; + helper.Events.GameLoop.DayStarted += this.OnDayStarted; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saving += this.OnSaving; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; + helper.Events.Display.MenuChanged += this.OnMenuChanged; - GraphicsEvents.OnPostRenderGuiEvent += this.GraphicsEvents_OnPostRenderGuiEvent; - StardewModdingAPI.Events.GraphicsEvents.OnPostRenderHudEvent += this.GraphicsEvents_OnPostRenderHudEvent; + helper.Events.Display.RenderedActiveMenu += this.OnRenderedActiveMenu; + helper.Events.Display.RenderedHud += this.OnRenderedHud; //MultiplayerSupport.initializeMultiplayerSupport(); ModHelper = this.Helper; ModMonitor = this.Monitor; @@ -113,13 +112,9 @@ namespace Omegasis.HappyBirthday /// A helper which encapsulates metadata about an asset and enables changes to it. public void Edit(IAssetData asset) { - asset - .AsDictionary() - .Set("birthdayMom", "Dear @,^ Happy birthday sweetheart. It's been amazing watching you grow into the kind, hard working person that I've always dreamed that you would become. I hope you continue to make many more fond memories with the ones you love. ^ Love, Mom ^ P.S. Here's a little something that I made for you. %item object 221 1 %%"); - - asset - .AsDictionary() - .Set("birthdayDad", "Dear @,^ Happy birthday kiddo. It's been a little quiet around here on your birthday since you aren't around, but your mother and I know that you are making both your grandpa and us proud. We both know that living on your own can be tough but we believe in you one hundred percent, just keep following your dreams.^ Love, Dad ^ P.S. Here's some spending money to help you out on the farm. Good luck! %item money 5000 5001 %%"); + IDictionary data = asset.AsDictionary().Data; + data["birthdayMom"] = "Dear @,^ Happy birthday sweetheart. It's been amazing watching you grow into the kind, hard working person that I've always dreamed that you would become. I hope you continue to make many more fond memories with the ones you love. ^ Love, Mom ^ P.S. Here's a little something that I made for you. %item object 221 1 %%"; + data["birthdayDad"] = "Dear @,^ Happy birthday kiddo. It's been a little quiet around here on your birthday since you aren't around, but your mother and I know that you are making both your grandpa and us proud. We both know that living on your own can be tough but we believe in you one hundred percent, just keep following your dreams.^ Love, Dad ^ P.S. Here's some spending money to help you out on the farm. Good luck! %item money 5000 5001 %%"; } @@ -161,33 +156,25 @@ namespace Omegasis.HappyBirthday } } - /// Used to check when a menu is closed. + /// Raised after drawing the HUD (item toolbar, clock, etc) to the sprite batch, but before it's rendered to the screen. /// The event sender. /// The event arguments. - private void MenuEvents_MenuClosed(object sender, EventArgsClickableMenuClosed e) + private void OnRenderedHud(object sender, RenderedHudEventArgs e) { - this.isDailyQuestBoard = false; - } + if (Game1.activeClickableMenu == null || this.PlayerData?.BirthdaySeason?.ToLower() != Game1.currentSeason.ToLower()) + return; - /// Used to properly display hovertext for all events happening on a calendar day. - /// The event sender. - /// The event arguments. - private void GraphicsEvents_OnPostRenderHudEvent(object sender, EventArgs e) - { - if (Game1.activeClickableMenu == null) return; - if (this.PlayerData?.BirthdaySeason == null) return; - if (this.PlayerData.BirthdaySeason.ToLower() != Game1.currentSeason.ToLower()) return; - if (Game1.activeClickableMenu is Billboard) + if (Game1.activeClickableMenu is Billboard billboard) { - if (this.isDailyQuestBoard) return; - if ((Game1.activeClickableMenu as Billboard).calendarDays == null) return; + if (this.isDailyQuestBoard || billboard.calendarDays == null) + return; //Game1.player.FarmerRenderer.drawMiniPortrat(Game1.spriteBatch, new Vector2(Game1.activeClickableMenu.xPositionOnScreen + 152 + (index - 1) % 7 * 32 * 4, Game1.activeClickableMenu.yPositionOnScreen + 230 + (index - 1) / 7 * 32 * 4), 1f, 4f, 2, Game1.player); string hoverText = ""; List texts = new List(); - foreach (var clicky in ((Billboard)Game1.activeClickableMenu).calendarDays) + foreach (var clicky in billboard.calendarDays) { if (clicky.containsPoint(Game1.getMouseX(), Game1.getMouseY())) { @@ -213,10 +200,10 @@ namespace Omegasis.HappyBirthday } } - /// Used to show the farmer's portrait on the billboard menu. + /// When a menu is open ( isn't null), raised after that menu is drawn to the sprite batch but before it's rendered to the screen. /// The event sender. /// The event arguments. - private void GraphicsEvents_OnPostRenderGuiEvent(object sender, EventArgs e) + private void OnRenderedActiveMenu(object sender, RenderedActiveMenuEventArgs e) { if (Game1.activeClickableMenu == null || this.isDailyQuestBoard) return; @@ -246,72 +233,77 @@ namespace Omegasis.HappyBirthday } } - /// Functionality to display the player's birthday on the billboard. + /// Raised after a game menu is opened, closed, or replaced. /// The event sender. /// The event arguments. - private void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged e) + private void OnMenuChanged(object sender, MenuChangedEventArgs e) { - if (Game1.activeClickableMenu == null) + switch (e.NewMenu) { - this.isDailyQuestBoard = false; - return; - } - if (Game1.activeClickableMenu is Billboard) - { - this.isDailyQuestBoard = ModHelper.Reflection.GetField((Game1.activeClickableMenu as Billboard), "dailyQuestBoard", true).GetValue(); - if (this.isDailyQuestBoard) return; + case null: + this.isDailyQuestBoard = false; + return; - Texture2D text = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); - Color[] col = new Color[1]; - col[0] = new Color(0, 0, 0, 1); - text.SetData(col); - //players birthday position rect=new .... - - if (!string.IsNullOrEmpty(this.PlayerData.BirthdaySeason)) - { - if (this.PlayerData.BirthdaySeason.ToLower() == Game1.currentSeason.ToLower()) + case Billboard billboard: { - int index = this.PlayerData.BirthdayDay; - Rectangle birthdayRect = new Rectangle(Game1.activeClickableMenu.xPositionOnScreen + 152 + (index - 1) % 7 * 32 * 4, Game1.activeClickableMenu.yPositionOnScreen + 200 + (index - 1) / 7 * 32 * 4, 124, 124); - (Game1.activeClickableMenu as Billboard).calendarDays.Add(new ClickableTextureComponent("", birthdayRect, "", Game1.player.name + "'s Birthday", text, new Rectangle(0, 0, 124, 124), 1f, false)); - } - } + this.isDailyQuestBoard = ModHelper.Reflection.GetField((Game1.activeClickableMenu as Billboard), "dailyQuestBoard", true).GetValue(); + if (this.isDailyQuestBoard) + return; - foreach (var pair in this.othersBirthdays) - { - if (pair.Value.BirthdaySeason != Game1.currentSeason.ToLower()) continue; - int index = pair.Value.BirthdayDay; - Rectangle otherBirthdayRect = new Rectangle(Game1.activeClickableMenu.xPositionOnScreen + 152 + (index - 1) % 7 * 32 * 4, Game1.activeClickableMenu.yPositionOnScreen + 200 + (index - 1) / 7 * 32 * 4, 124, 124); - (Game1.activeClickableMenu as Billboard).calendarDays.Add(new ClickableTextureComponent("", otherBirthdayRect, "", Game1.getFarmer(pair.Key).name + "'s Birthday", text, new Rectangle(0, 0, 124, 124), 1f, false)); - } + Texture2D text = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); + Color[] col = new Color[1]; + col[0] = new Color(0, 0, 0, 1); + text.SetData(col); + //players birthday position rect=new .... + + if (!string.IsNullOrEmpty(this.PlayerData.BirthdaySeason)) + { + if (this.PlayerData.BirthdaySeason.ToLower() == Game1.currentSeason.ToLower()) + { + int index = this.PlayerData.BirthdayDay; + Rectangle birthdayRect = new Rectangle(Game1.activeClickableMenu.xPositionOnScreen + 152 + (index - 1) % 7 * 32 * 4, Game1.activeClickableMenu.yPositionOnScreen + 200 + (index - 1) / 7 * 32 * 4, 124, 124); + billboard.calendarDays.Add(new ClickableTextureComponent("", birthdayRect, "", $"{Game1.player.Name}'s Birthday", text, new Rectangle(0, 0, 124, 124), 1f, false)); + } + } + + foreach (var pair in this.othersBirthdays) + { + if (pair.Value.BirthdaySeason != Game1.currentSeason.ToLower()) continue; + int index = pair.Value.BirthdayDay; + Rectangle otherBirthdayRect = new Rectangle(Game1.activeClickableMenu.xPositionOnScreen + 152 + (index - 1) % 7 * 32 * 4, Game1.activeClickableMenu.yPositionOnScreen + 200 + (index - 1) / 7 * 32 * 4, 124, 124); + billboard.calendarDays.Add(new ClickableTextureComponent("", otherBirthdayRect, "", $"{Game1.getFarmer(pair.Key).Name}'s Birthday", text, new Rectangle(0, 0, 124, 124), 1f, false)); + } + + break; + } } } - /// The method invoked after a new day starts. + /// Raised after the game begins a new day (including when the player loads a save). /// The event sender. - /// The event data. - private void TimeEvents_AfterDayStarted(object sender, EventArgs e) + /// The event arguments. + private void OnDayStarted(object sender, DayStartedEventArgs e) { this.CheckedForBirthday = false; } - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { // show birthday selection menu if (Game1.activeClickableMenu != null) return; - if (Context.IsPlayerFree && !this.HasChosenBirthday && e.KeyPressed.ToString() == Config.KeyBinding) + if (Context.IsPlayerFree && !this.HasChosenBirthday && e.Button == Config.KeyBinding) Game1.activeClickableMenu = new BirthdayMenu(this.PlayerData.BirthdaySeason, this.PlayerData.BirthdayDay, this.SetBirthday); } - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { - this.DataFilePath = Path.Combine("data", Game1.player.Name + "_" + Game1.player.UniqueMultiplayerID + ".json"); + this.DataFilePath = Path.Combine("data", $"{Game1.player.Name}_{Game1.player.UniqueMultiplayerID}.json"); // reset state this.VillagerQueue = new List(); @@ -332,19 +324,19 @@ namespace Omegasis.HappyBirthday //this.Dialogue = new Dictionary(); } - /// The method invoked just before the game updates the saves. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + private void OnSaving(object sender, SavingEventArgs e) { if (this.HasChosenBirthday) this.Helper.Data.WriteJsonFile(this.DataFilePath, this.PlayerData); } - /// The method invoked when the game updates (roughly 60 times per second). + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (!Context.IsWorldReady || Game1.eventUp || Game1.isFestival()) return; diff --git a/GeneralMods/HappyBirthday/manifest.json b/GeneralMods/HappyBirthday/manifest.json index 6241f2b8..c2a5fe2f 100644 --- a/GeneralMods/HappyBirthday/manifest.json +++ b/GeneralMods/HappyBirthday/manifest.json @@ -5,6 +5,6 @@ "Description": "Adds the farmer's birthday to the game.", "UniqueID": "Omegasis.HappyBirthday", "EntryDll": "HappyBirthday.dll", - "MinimumApiVersion": "2.9", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:520" ] } diff --git a/GeneralMods/MapEvents/EventSystem.cs b/GeneralMods/MapEvents/EventSystem.cs index 8b11646c..be7b2bfe 100644 --- a/GeneralMods/MapEvents/EventSystem.cs +++ b/GeneralMods/MapEvents/EventSystem.cs @@ -1,6 +1,6 @@ -using System; using EventSystem.Framework; using StardewModdingAPI; +using StardewModdingAPI.Events; namespace EventSystem { @@ -18,16 +18,22 @@ namespace EventSystem { ModHelper = this.Helper; ModMonitor = this.Monitor; - StardewModdingAPI.Events.GameEvents.UpdateTick += this.GameEvents_UpdateTick; - StardewModdingAPI.Events.SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; } - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// Raised after the player loads a save slot and the world is initialised. + /// The event sender. + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { eventManager = new EventManager(); } - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// Raised after the game state is updated (≈60 times per second). + /// The event sender. + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { eventManager?.update(); } diff --git a/GeneralMods/MapEvents/manifest.json b/GeneralMods/MapEvents/manifest.json index 4c72d707..d979dd05 100644 --- a/GeneralMods/MapEvents/manifest.json +++ b/GeneralMods/MapEvents/manifest.json @@ -1,10 +1,10 @@ { - "Name": "EventSystem", + "Name": "Event System", "Author": "Alpha_Omegasis", "Version": "0.1.0", "Description": "A system to manage different events that can happen on the map.", "UniqueID": "Omegasis.EventSystem", "EntryDll": "EventSystem.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [] } diff --git a/GeneralMods/MoreRain/MoreRain.cs b/GeneralMods/MoreRain/MoreRain.cs index d17e32ba..4194842a 100644 --- a/GeneralMods/MoreRain/MoreRain.cs +++ b/GeneralMods/MoreRain/MoreRain.cs @@ -11,7 +11,7 @@ namespace Omegasis.MoreRain public class MoreRain : Mod { /********* - ** Properties + ** Fields *********/ /// The weathers that can be safely overridden. private readonly HashSet NormalWeathers = new HashSet { Game1.weather_sunny, Game1.weather_rain, Game1.weather_lightning, Game1.weather_debris, Game1.weather_snow }; @@ -29,26 +29,26 @@ namespace Omegasis.MoreRain { this.Config = helper.ReadConfig(); - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saving += this.OnSaving; } /********* ** Private methods *********/ - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { this.HandleNewDay(); } - /// The method invoked before the game is saved. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - private void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + private void OnSaving(object sender, SavingEventArgs e) { this.HandleNewDay(); } diff --git a/GeneralMods/MoreRain/manifest.json b/GeneralMods/MoreRain/manifest.json index 2923d02b..8bc0f494 100644 --- a/GeneralMods/MoreRain/manifest.json +++ b/GeneralMods/MoreRain/manifest.json @@ -5,6 +5,6 @@ "Description": "Change how much it rains in the game.", "UniqueID": "Omegasis.MoreRain", "EntryDll": "MoreRain.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:441" ] } diff --git a/GeneralMods/MuseumRearranger/Framework/ModConfig.cs b/GeneralMods/MuseumRearranger/Framework/ModConfig.cs index 923c969b..e020ccb7 100644 --- a/GeneralMods/MuseumRearranger/Framework/ModConfig.cs +++ b/GeneralMods/MuseumRearranger/Framework/ModConfig.cs @@ -1,12 +1,14 @@ +using StardewModdingAPI; + namespace Omegasis.MuseumRearranger.Framework { /// The mod configuration. internal class ModConfig { /// The key which shows the museum rearranging menu. - public string ShowMenuKey { get; set; } = "R"; + public SButton ShowMenuKey { get; set; } = SButton.R; /// The key which toggles the inventory box when the menu is open. - public string ToggleInventoryKey { get; set; } = "T"; + public SButton ToggleInventoryKey { get; set; } = SButton.T; } } diff --git a/GeneralMods/MuseumRearranger/Framework/NewMuseumMenu.cs b/GeneralMods/MuseumRearranger/Framework/NewMuseumMenu.cs index a81eca27..b24f3e2b 100644 --- a/GeneralMods/MuseumRearranger/Framework/NewMuseumMenu.cs +++ b/GeneralMods/MuseumRearranger/Framework/NewMuseumMenu.cs @@ -11,7 +11,7 @@ namespace Omegasis.MuseumRearranger.Framework internal class NewMuseumMenu : MuseumMenu { /********* - ** Properties + ** Fields *********/ /// Whether to show the inventory screen. private bool ShowInventory = true; diff --git a/GeneralMods/MuseumRearranger/MuseumRearranger.cs b/GeneralMods/MuseumRearranger/MuseumRearranger.cs index 8494f4ae..f9014d3f 100644 --- a/GeneralMods/MuseumRearranger/MuseumRearranger.cs +++ b/GeneralMods/MuseumRearranger/MuseumRearranger.cs @@ -10,7 +10,7 @@ namespace Omegasis.MuseumRearranger public class MuseumRearranger : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -28,23 +28,23 @@ namespace Omegasis.MuseumRearranger { this.Config = helper.ReadConfig(); - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; } /********* ** Private methods *********/ - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { if (!Context.IsWorldReady) return; // open menu - if (e.KeyPressed.ToString() == this.Config.ShowMenuKey) + if (e.Button == this.Config.ShowMenuKey) { if (Game1.activeClickableMenu != null) return; @@ -55,7 +55,7 @@ namespace Omegasis.MuseumRearranger } // toggle inventory box - if (e.KeyPressed.ToString() == this.Config.ToggleInventoryKey) + if (e.Button == this.Config.ToggleInventoryKey) this.OpenMenu?.ToggleInventory(); } } diff --git a/GeneralMods/MuseumRearranger/manifest.json b/GeneralMods/MuseumRearranger/manifest.json index 8f28f6fe..7ed4041d 100644 --- a/GeneralMods/MuseumRearranger/manifest.json +++ b/GeneralMods/MuseumRearranger/manifest.json @@ -5,6 +5,6 @@ "Description": "Lets you rearrange the museum without needing to donate something.", "UniqueID": "Omegasis.MuseumRearranger", "EntryDll": "MuseumRearranger.dll", - "MinimumApiVersion": "2.3", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:428" ] } diff --git a/GeneralMods/NightOwl/Framework/NightFishing.cs b/GeneralMods/NightOwl/Framework/NightFishing.cs index 21b1f06c..ddb4c1a1 100644 --- a/GeneralMods/NightOwl/Framework/NightFishing.cs +++ b/GeneralMods/NightOwl/Framework/NightFishing.cs @@ -5,14 +5,18 @@ namespace Omegasis.NightOwl.Framework { class NightFishing : IAssetEditor { + /// Get whether this instance can edit the given asset. + /// Basic metadata about the asset being loaded. public bool CanEdit(IAssetInfo asset) { return asset.AssetNameEquals(@"Data\Fish"); } + /// Edit a matched asset. + /// A helper which encapsulates metadata about an asset and enables changes to it. public void Edit(IAssetData asset) { - Dictionary nightFish = new Dictionary // (T)(object) is a trick to cast anything to T if we know it's compatible + Dictionary nightFish = new Dictionary { [128] = "Pufferfish/80/floater/1/36/1200 1600/summer/sunny/690 .4 685 .1/4/.3/.5/0", [129] = "Anchovy/30/dart/1/16/600 3000/spring fall/both/682 .2/1/.25/.3/0", @@ -78,10 +82,10 @@ namespace Omegasis.NightOwl.Framework [799] = "Spook Fish/60/dart/8/25/600 3000/spring summer fall winter/both/685 .35/3/.4/.1/0", [800] = "Blobfish/75/floater/8/25/600 3000/spring summer fall winter/both/685 .35/3/.4/.1/0", }; + + IDictionary data = asset.AsDictionary().Data; foreach (KeyValuePair pair in nightFish) - { - asset.AsDictionary().Set(pair.Key, pair.Value); - } + data[pair.Key] = pair.Value; } } } diff --git a/GeneralMods/NightOwl/NightOwl.cs b/GeneralMods/NightOwl/NightOwl.cs index 41b37fbb..86aeaa71 100644 --- a/GeneralMods/NightOwl/NightOwl.cs +++ b/GeneralMods/NightOwl/NightOwl.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using Microsoft.Xna.Framework; using Netcode; @@ -22,7 +21,7 @@ namespace Omegasis.NightOwl public class NightOwl : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -91,12 +90,11 @@ namespace Omegasis.NightOwl if (this.Config.UseInternalNightFishAssetEditor) this.Helper.Content.AssetEditors.Add(new NightFishing()); - TimeEvents.TimeOfDayChanged += this.TimeEvents_TimeOfDayChanged; - TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; - GameEvents.FourthUpdateTick += this.GameEvents_FourthUpdateTick; - GameEvents.UpdateTick += this.GameEvents_UpdateTick; + helper.Events.GameLoop.TimeChanged += this.OnTimeChanged; + helper.Events.GameLoop.DayStarted += this.OnDayStarted; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saving += this.OnSaving; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; this.shouldWarpHorse = false; } @@ -104,43 +102,40 @@ namespace Omegasis.NightOwl /********* ** Private methods *********/ - /// Updates the earthquake event. + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { this.eve?.tickUpdate(Game1.currentGameTime); - } - /// The method invoked every fourth game update (roughly 15 times per second). - /// The event sender. - /// The event data. - public void GameEvents_FourthUpdateTick(object sender, EventArgs e) - { - try + if (e.IsMultipleOf(4)) // ≈15 times per second { - // reset position after collapse - if (Context.IsWorldReady && this.JustStartedNewDay && this.Config.KeepPositionAfterCollapse) + try { - if (this.PreCollapseMap != null) - Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); + // reset position after collapse + if (Context.IsWorldReady && this.JustStartedNewDay && this.Config.KeepPositionAfterCollapse) + { + if (this.PreCollapseMap != null) + Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); - this.PreCollapseMap = null; - this.JustStartedNewDay = false; - this.JustCollapsed = false; + this.PreCollapseMap = null; + this.JustStartedNewDay = false; + this.JustCollapsed = false; + } + } + catch (Exception ex) + { + this.Monitor.Log(ex.ToString(), LogLevel.Error); + this.WriteErrorLog(); } } - catch (Exception ex) - { - this.Monitor.Log(ex.ToString(), LogLevel.Error); - this.WriteErrorLog(); - } } - /// The method invoked before the game saves. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. - /// The event data. - public void SaveEvents_BeforeSave(object sender, EventArgs e) + /// The event arguments. + public void OnSaving(object sender, SavingEventArgs e) { int collapseFee = 0; string[] passOutFees = Game1.player.mailbox @@ -156,20 +151,20 @@ namespace Omegasis.NightOwl Game1.player.money += collapseFee; } - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - public void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + public void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { this.IsUpLate = false; this.JustStartedNewDay = false; this.JustCollapsed = false; } - /// The method invoked when a new day starts. + /// Raised after the game begins a new day (including when the player loads a save). /// The event sender. - /// The event data. - public void TimeEvents_AfterDayStarted(object sender, EventArgs e) + /// The event arguments. + public void OnDayStarted(object sender, DayStartedEventArgs e) { try { @@ -252,10 +247,10 @@ namespace Omegasis.NightOwl this.Helper.Reflection.GetField(mountain, "railroadBlockRect").SetValue(Rectangle.Empty); } - /// The method invoked when changes. + /// Raised after the in-game clock time changes. /// The event sender. - /// The event data. - private void TimeEvents_TimeOfDayChanged(object sender, EventArgsIntChanged e) + /// The event arguments. + private void OnTimeChanged(object sender, TimeChangedEventArgs e) { if (!Context.IsWorldReady) return; @@ -353,8 +348,7 @@ namespace Omegasis.NightOwl this.PreCollapseStamina, this.PreCollapseHealth }; - string path = Path.Combine(this.Helper.DirectoryPath, "Error_Logs", "Mod_State.json"); - this.Helper.WriteJsonFile(path, state); + this.Helper.Data.WriteJsonFile("Error_Logs/Mod_State.json", state); } /// Try and emulate the old Game1.shouldFarmerPassout logic. diff --git a/GeneralMods/NightOwl/manifest.json b/GeneralMods/NightOwl/manifest.json index 070c5081..b7a37179 100644 --- a/GeneralMods/NightOwl/manifest.json +++ b/GeneralMods/NightOwl/manifest.json @@ -5,6 +5,6 @@ "Description": "Lets you stay up all night.", "UniqueID": "Omegasis.NightOwl", "EntryDll": "NightOwl.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:433" ] } diff --git a/GeneralMods/NoMorePets/NoMorePets.cs b/GeneralMods/NoMorePets/NoMorePets.cs index 7b38c409..39a8add1 100644 --- a/GeneralMods/NoMorePets/NoMorePets.cs +++ b/GeneralMods/NoMorePets/NoMorePets.cs @@ -1,4 +1,3 @@ -using System; using System.Linq; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -17,17 +16,17 @@ namespace Omegasis.NoMorePets /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; } /********* ** Private methods *********/ - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - public void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + public void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { foreach (Pet pet in Game1.player.currentLocation.getCharacters().OfType().ToArray()) pet.currentLocation.characters.Remove(pet); diff --git a/GeneralMods/NoMorePets/manifest.json b/GeneralMods/NoMorePets/manifest.json index 4f44bd43..6c1a9aae 100644 --- a/GeneralMods/NoMorePets/manifest.json +++ b/GeneralMods/NoMorePets/manifest.json @@ -5,6 +5,6 @@ "Description": "Removes all pets from the game.", "UniqueID": "Omegasis.NoMorePets", "EntryDll": "NoMorePets.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:506" ] } diff --git a/GeneralMods/Revitalize/manifest.json b/GeneralMods/Revitalize/manifest.json index 9674ce58..8ce50f03 100644 --- a/GeneralMods/Revitalize/manifest.json +++ b/GeneralMods/Revitalize/manifest.json @@ -5,6 +5,6 @@ "Description": "A mod that attempts to add in a variety of new things to Stardew.", "UniqueID": "Omegasis.Revitalize", "EntryDll": "Revitalize.dll", - "MinimumApiVersion": "2.3", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [] } diff --git a/GeneralMods/SaveAnywhere/Framework/ModConfig.cs b/GeneralMods/SaveAnywhere/Framework/ModConfig.cs index e48269e3..a43b4f22 100644 --- a/GeneralMods/SaveAnywhere/Framework/ModConfig.cs +++ b/GeneralMods/SaveAnywhere/Framework/ModConfig.cs @@ -1,9 +1,11 @@ +using StardewModdingAPI; + namespace Omegasis.SaveAnywhere.Framework { /// The mod configuration. internal class ModConfig { /// The key which initiates a save. - public string SaveKey { get; set; } = "K"; + public SButton SaveKey { get; set; } = SButton.K; } } diff --git a/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs b/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs index 8aa2d542..d66b3681 100644 --- a/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs +++ b/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs @@ -10,7 +10,7 @@ namespace Omegasis.SaveAnywhere.Framework internal class NewShippingMenu : ShippingMenu { /********* - ** Properties + ** Fields *********/ /// The private field on the shipping menu which indicates the game has already been saved, which prevents it from saving. private readonly IReflectedField SavedYet; diff --git a/GeneralMods/SaveAnywhere/Framework/SaveManager.cs b/GeneralMods/SaveAnywhere/Framework/SaveManager.cs index 96789e17..02bab335 100644 --- a/GeneralMods/SaveAnywhere/Framework/SaveManager.cs +++ b/GeneralMods/SaveAnywhere/Framework/SaveManager.cs @@ -15,7 +15,7 @@ namespace Omegasis.SaveAnywhere.Framework public class SaveManager { /********* - ** Properties + ** Fields *********/ /// Simplifies access to game code. private readonly IReflectionHelper Reflection; @@ -26,8 +26,8 @@ namespace Omegasis.SaveAnywhere.Framework /// SMAPI's APIs for this mod. private readonly IModHelper Helper; - /// The full path to the player data file. - private string SavePath => Path.Combine(this.Helper.DirectoryPath, "data", $"{Constants.SaveFolderName}.json"); + /// The relative path to the player data file. + private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); /// Whether we should save at the next opportunity. private bool WaitingToSave; @@ -80,7 +80,7 @@ namespace Omegasis.SaveAnywhere.Framework /// Clear saved data. public void ClearData() { - File.Delete(this.SavePath); + File.Delete(Path.Combine(this.Helper.DirectoryPath, this.RelativeDataPath)); this.RemoveLegacyDataForThisPlayer(); } @@ -105,20 +105,16 @@ namespace Omegasis.SaveAnywhere.Framework } - // get data + // save data to disk PlayerData data = new PlayerData { Time = Game1.timeOfDay, Characters = this.GetPositions().ToArray(), IsCharacterSwimming = Game1.player.swimming.Value }; + this.Helper.Data.WriteJsonFile(this.RelativeDataPath, data); - // save to disk - // ReSharper disable once PossibleNullReferenceException -- not applicable - Directory.CreateDirectory(new FileInfo(this.SavePath).Directory.FullName); - this.Helper.WriteJsonFile(this.SavePath, data); - - // clear any legacy data (no longer needed as backup)1 + // clear any legacy data (no longer needed as backup) this.RemoveLegacyDataForThisPlayer(); } @@ -126,7 +122,7 @@ namespace Omegasis.SaveAnywhere.Framework public void LoadData() { // get data - PlayerData data = this.Helper.ReadJsonFile(this.SavePath); + PlayerData data = this.Helper.Data.ReadJsonFile(this.RelativeDataPath); if (data == null) return; diff --git a/GeneralMods/SaveAnywhere/SaveAnywhere.cs b/GeneralMods/SaveAnywhere/SaveAnywhere.cs index 8908de45..94010ad5 100644 --- a/GeneralMods/SaveAnywhere/SaveAnywhere.cs +++ b/GeneralMods/SaveAnywhere/SaveAnywhere.cs @@ -14,7 +14,7 @@ namespace Omegasis.SaveAnywhere public class SaveAnywhere : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; @@ -53,11 +53,11 @@ namespace Omegasis.SaveAnywhere this.SaveManager = new SaveManager(this.Helper, this.Helper.Reflection, onLoaded: () => this.ShouldResetSchedules = true); - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - SaveEvents.AfterSave += this.SaveEvents_AfterSave; - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; + helper.Events.GameLoop.Saved += this.OnSaved; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.GameLoop.DayStarted += this.OnDayStarted; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; ModHelper = helper; ModMonitor = this.Monitor; @@ -68,10 +68,10 @@ namespace Omegasis.SaveAnywhere /********* ** Private methods *********/ - /// The method invoked after the player loads a save. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { // reset state this.IsCustomSaving = false; @@ -81,10 +81,10 @@ namespace Omegasis.SaveAnywhere this.SaveManager.LoadData(); } - /// The method invoked after the player finishes saving. + /// Raised after the game finishes writing data to the save file (except the initial save creation). /// The event sender. - /// The event data. - private void SaveEvents_AfterSave(object sender, EventArgs e) + /// The event arguments. + private void OnSaved(object sender, SavedEventArgs e) { // clear custom data after a normal save (to avoid restoring old state) if (!this.IsCustomSaving) @@ -95,10 +95,10 @@ namespace Omegasis.SaveAnywhere } } - /// The method invoked when the game updates (roughly 60 times per second). + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { // let save manager run background logic if (Context.IsWorldReady) @@ -156,10 +156,10 @@ namespace Omegasis.SaveAnywhere Game1.player.currentLocation.characters.Add(monster); } - /// The method invoked after a new day starts. + /// Raised after the game begins a new day (including when the player loads a save). /// The event sender. - /// The event data. - private void TimeEvents_AfterDayStarted(object sender, EventArgs e) + /// The event arguments. + private void OnDayStarted(object sender, DayStartedEventArgs e) { // reload NPC schedules this.ShouldResetSchedules = true; @@ -173,16 +173,16 @@ namespace Omegasis.SaveAnywhere } } - /// The method invoked when the presses a keyboard button. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. - /// The event data. - private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + /// The event arguments. + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { if (!Context.IsPlayerFree) return; // initiate save (if valid context) - if (e.KeyPressed.ToString() == this.Config.SaveKey) + if (e.Button == this.Config.SaveKey) { if (Game1.client == null) { diff --git a/GeneralMods/SaveAnywhere/manifest.json b/GeneralMods/SaveAnywhere/manifest.json index 9ff92a6a..ffd84748 100644 --- a/GeneralMods/SaveAnywhere/manifest.json +++ b/GeneralMods/SaveAnywhere/manifest.json @@ -5,7 +5,7 @@ "Description": "Lets you save almost anywhere.", "UniqueID": "Omegasis.SaveAnywhere", "EntryDll": "SaveAnywhere.dll", - "MinimumApiVersion": "2.4", + "MinimumApiVersion": "2.10.1", "Dependencies": [ ] } diff --git a/GeneralMods/SimpleSoundManager/Framework/SoundManager.cs b/GeneralMods/SimpleSoundManager/Framework/SoundManager.cs index 617baa6e..7d19f501 100644 --- a/GeneralMods/SimpleSoundManager/Framework/SoundManager.cs +++ b/GeneralMods/SimpleSoundManager/Framework/SoundManager.cs @@ -36,9 +36,9 @@ namespace SimpleSoundManager.Framework } /// Constructor for wav files. - public void loadWavFile(IModHelper helper, string soundName, string pathToWav) + public void loadWavFile(IModHelper helper, string soundName, string relativePath) { - WavSound wav = new WavSound(helper, soundName, pathToWav); + WavSound wav = new WavSound(helper, soundName, relativePath); SimpleSoundManagerMod.ModMonitor.Log("Getting sound file:" + soundName); try { diff --git a/GeneralMods/SimpleSoundManager/Framework/WavSound.cs b/GeneralMods/SimpleSoundManager/Framework/WavSound.cs index 923248e4..4c31fdf2 100644 --- a/GeneralMods/SimpleSoundManager/Framework/WavSound.cs +++ b/GeneralMods/SimpleSoundManager/Framework/WavSound.cs @@ -37,9 +37,9 @@ namespace SimpleSoundManager } /// A constructor that takes a mod helper and a relative path to a wav file. - public WavSound(IModHelper modHelper, string name, string pathInModDirectory, bool loop = false) + public WavSound(IModHelper modHelper, string name, string relativePath, bool loop = false) { - string path = Path.Combine(modHelper.DirectoryPath, pathInModDirectory); + string path = Path.Combine(modHelper.DirectoryPath, relativePath); this.path = path; this.soundName = name; this.loop = loop; diff --git a/GeneralMods/SimpleSoundManager/manifest.json b/GeneralMods/SimpleSoundManager/manifest.json index a63ef698..bd16daeb 100644 --- a/GeneralMods/SimpleSoundManager/manifest.json +++ b/GeneralMods/SimpleSoundManager/manifest.json @@ -5,6 +5,6 @@ "Description": "A simple framework to play sounds from wave banks and wav files.", "UniqueID": "Omegasis.SimpleSoundManager", "EntryDll": "SimpleSoundManager.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:1410" ] } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Config.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Config.cs index 7342582c..76413128 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Config.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Config.cs @@ -1,3 +1,5 @@ +using StardewModdingAPI; + namespace StardewSymphonyRemastered { /// A class that handles all of the config files for this mod. @@ -13,7 +15,7 @@ namespace StardewSymphonyRemastered public int MaximumDelayBetweenSongsInMilliseconds { get; set; } = 60000; /// The key binding to open the menu music. - public string KeyBinding { get; set; } = "L"; + public SButton KeyBinding { get; set; } = SButton.L; /// Whether to write a JSON file for every possible option for a music pack. Use at your own risk! public bool WriteAllConfigMusicOptions { get; set; } = false; diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index 5ea907d9..d9b8238b 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI; @@ -47,19 +45,16 @@ namespace StardewSymphonyRemastered ModHelper = helper; ModMonitor = this.Monitor; Config = helper.ReadConfig(); - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - // EventArgsLocationsChanged += LocationEvents_CurrentLocationChanged; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; - PlayerEvents.Warped += this.PlayerEvents_Warped; - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; - SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; + helper.Events.Player.Warped += this.OnPlayerWarped; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; + helper.Events.Input.ButtonPressed += this.OnButtonPressed; + helper.Events.GameLoop.Saving += this.OnSaving; - MenuEvents.MenuChanged += this.MenuEvents_MenuChanged; - MenuEvents.MenuClosed += this.MenuEvents_MenuClosed; + helper.Events.Display.MenuChanged += this.OnMenuChanged; - GameEvents.FirstUpdateTick += this.GameEvents_FirstUpdateTick; - GameEvents.OneSecondTick += this.GameEvents_OneSecondTick; + helper.Events.GameLoop.GameLaunched += this.OnGameLaunched; musicManager = new MusicManager(); @@ -76,34 +71,31 @@ namespace StardewSymphonyRemastered this.LoadMusicPacks(); } - private void GameEvents_OneSecondTick(object sender, EventArgs e) - { - musicManager?.UpdateTimer(); - } - - /// Raised when the player changes locations. This should determine the next song to play. + /// Raised after a player warps to a new location. /// The event sender. /// The event arguments. - private void PlayerEvents_Warped(object sender, EventArgsPlayerWarped e) + private void OnPlayerWarped(object sender, WarpedEventArgs e) { - musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); - + if (e.IsLocalPlayer) + musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); } - /// Ran once all of teh entry methods are ran. This will ensure that all custom music from other mods has been properly loaded in. + /// Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations. /// The event sender. /// The event arguments. - private void GameEvents_FirstUpdateTick(object sender, EventArgs e) + private void OnGameLaunched(object sender, GameLaunchedEventArgs e) { + // Ran once all of the entry methods are ran. This will ensure that all custom music from other mods has been properly loaded in. + musicManager.initializeMenuMusic(); //Initialize menu music that has been added to SongSpecifics.menus from all other mods during their Entry function. musicManager.initializeFestivalMusic(); //Initialize festival music that has been added to SongSpecifics.menus from all other mods during their Entry function. musicManager.initializeEventMusic(); //Initialize event music that has been added to SongSpecifics.menus from all other mods during their Entry function. } - /// Events to occur after the game has loaded in. + /// Raised after the player loads a save slot and the world is initialised. /// The event sender. /// The event arguments. - private void SaveEvents_AfterLoad(object sender, EventArgs e) + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { //Locaion initialization MUST occur after load. Anything else can occur before. SongSpecifics.initializeLocationsList(); //Gets all Game locations once the player has loaded the game, and all buildings on the player's farm and adds them to a location list. @@ -123,67 +115,74 @@ namespace StardewSymphonyRemastered musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); } - - /// Choose new music when a menu is closed. + /// Raised after a game menu is opened, closed, or replaced. /// The event sender. /// The event arguments. - private void MenuEvents_MenuClosed(object sender, EventArgsClickableMenuClosed e) + private void OnMenuChanged(object sender, MenuChangedEventArgs e) { - if (menuChangedMusic) - musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); + // menu closed + if (e.NewMenu == null) + { + if (menuChangedMusic) + musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); + } + + // menu changed + else + musicManager.SelectMenuMusic(SongSpecifics.getCurrentConditionalString()); } - /// Choose new music when a menu is opened. + /// Raised before the game begins writes data to the save file (except the initial save creation). /// The event sender. /// The event arguments. - private void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged e) - { - //var ok = musicManager.currentMusicPack.getNameOfCurrentSong(); - musicManager.SelectMenuMusic(SongSpecifics.getCurrentConditionalString()); - } - - private void SaveEvents_BeforeSave(object sender, EventArgs e) + private void OnSaving(object sender, SavingEventArgs e) { // THIS IS WAY TO LONG to run. Better make it save individual lists when I am editing songs. foreach (var musicPack in musicManager.MusicPacks) musicPack.Value.SaveSettings(); } - /// Fires when a key is pressed to open the music selection menu. + /// Raised after the player presses a button on the keyboard, controller, or mouse. /// The event sender. /// The event arguments. - private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) + private void OnButtonPressed(object sender, ButtonPressedEventArgs e) { - if (e.KeyPressed.ToString() == Config.KeyBinding && Game1.activeClickableMenu == null) + if (e.Button == Config.KeyBinding && Game1.activeClickableMenu == null) Game1.activeClickableMenu = new Framework.Menus.MusicManagerMenu(Game1.viewport.Width, Game1.viewport.Height); } - /// Raised every frame. Mainly used just to initiate the music packs. Probably not needed. + /// Raised after the game state is updated (≈60 times per second). /// The event sender. /// The event arguments. - private void GameEvents_UpdateTick(object sender, EventArgs e) + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { - if (musicManager == null) return; + // update delay timer + if (e.IsOneSecond) + musicManager?.UpdateTimer(); - if (Config.DisableStardewMusic) + // initiate music packs + if (musicManager != null) { - if (Game1.currentSong != null) + if (Config.DisableStardewMusic) { - Game1.currentSong.Stop(AudioStopOptions.Immediate); //stop the normal songs from playing over the new songs - Game1.currentSong.Stop(AudioStopOptions.AsAuthored); - Game1.nextMusicTrack = ""; //same as above line + if (Game1.currentSong != null) + { + Game1.currentSong.Stop(AudioStopOptions.Immediate); //stop the normal songs from playing over the new songs + Game1.currentSong.Stop(AudioStopOptions.AsAuthored); + Game1.nextMusicTrack = ""; //same as above line + } } - } - else - { - if (musicManager.CurrentMusicPack == null) return; - if (Game1.currentSong != null && musicManager.CurrentMusicPack.IsPlaying()) + else { - //ModMonitor.Log("STOP THE MUSIC!!!"); - Game1.currentSong.Stop(AudioStopOptions.Immediate); //stop the normal songs from playing over the new songs - Game1.currentSong.Stop(AudioStopOptions.AsAuthored); - //Game1.nextMusicTrack = ""; //same as above line + if (musicManager.CurrentMusicPack == null) return; + if (Game1.currentSong != null && musicManager.CurrentMusicPack.IsPlaying()) + { + //ModMonitor.Log("STOP THE MUSIC!!!"); + Game1.currentSong.Stop(AudioStopOptions.Immediate); //stop the normal songs from playing over the new songs + Game1.currentSong.Stop(AudioStopOptions.AsAuthored); + //Game1.nextMusicTrack = ""; //same as above line + } } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json index 84679222..5218ccf9 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json @@ -5,7 +5,7 @@ "Description": "Adding more music to the game one beep at a time. Now with streaming!", "UniqueID": "Omegasis.StardewSymphonyRemastered", "EntryDll": "StardewSymphonyRemastered.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:425" ], "Dependencies": [ { "UniqueID": "Omegasis.StardustCore" } diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs index c2b8f057..e1ae369c 100644 --- a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs @@ -26,17 +26,5 @@ namespace StardustCore.UIUtilities.SpriteFonts.Components this.TopPadding = top; this.BottomPadding = bottom; } - - /// Save this to a .json file. - public void WriteToJson(string path) - { - StardustCore.ModCore.ModHelper.WriteJsonFile(path, this); - } - - /// Read the data from the .json file. - public static CharacterSpacing ReadFromJson(string path) - { - return StardustCore.ModCore.ModHelper.ReadJsonFile(path); - } } } diff --git a/GeneralMods/StardustCore/manifest.json b/GeneralMods/StardustCore/manifest.json index 48a12f4b..4010f9dc 100644 --- a/GeneralMods/StardustCore/manifest.json +++ b/GeneralMods/StardustCore/manifest.json @@ -5,6 +5,6 @@ "Description": "A core mod that allows for other mods of mine to be run.", "UniqueID": "Omegasis.StardustCore", "EntryDll": "StardustCore.dll", - "MinimumApiVersion": "2.3", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [] } diff --git a/GeneralMods/SundropMapEvents/Class1.cs b/GeneralMods/SundropMapEvents/Class1.cs index 65501e3a..1c700d26 100644 --- a/GeneralMods/SundropMapEvents/Class1.cs +++ b/GeneralMods/SundropMapEvents/Class1.cs @@ -1,9 +1,9 @@ -using System; using EventSystem.Framework.Events; using EventSystem.Framework.FunctionEvents; using EventSystem.Framework.Information; using Microsoft.Xna.Framework; using StardewModdingAPI; +using StardewModdingAPI.Events; using StardewValley; namespace SundropMapEvents { @@ -18,10 +18,13 @@ namespace SundropMapEvents { ModHelper = this.Helper; ModMonitor = this.Monitor; - StardewModdingAPI.Events.SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; } - private void SaveEvents_AfterLoad(object sender, EventArgs e) + /// Raised after the player loads a save slot and the world is initialised. + /// The event sender. + /// The event arguments. + private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { EventSystem.EventSystem.eventManager.addEvent(Game1.getLocationFromName("BusStop"), new WarpEvent("toRR", Game1.getLocationFromName("BusStop"), new Vector2(6, 11), new PlayerEvents(null, null), new WarpInformation("BusStop", 10, 12, 2, false))); EventSystem.EventSystem.eventManager.addEvent(Game1.getLocationFromName("BusStop"), new DialogueDisplayEvent("Hello.", Game1.getLocationFromName("BusStop"), new Vector2(10, 13), new MouseButtonEvents(null, null), new MouseEntryLeaveEvent(null, null), "Hello there!")); diff --git a/GeneralMods/SundropMapEvents/manifest.json b/GeneralMods/SundropMapEvents/manifest.json index c0e8d821..61822a3c 100644 --- a/GeneralMods/SundropMapEvents/manifest.json +++ b/GeneralMods/SundropMapEvents/manifest.json @@ -1,11 +1,11 @@ { - "Name": "SunDropMapEvents", + "Name": "SunDrop Map Events", "Author": "Alpha_Omegasis", "Version": "0.1.0", "Description": "A system to add events to the SunDropMod", "UniqueID": "SunDrop.MapEvents", "EntryDll": "SunDropMapEvents.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [], "Dependencies": [ { "UniqueID": "Omegasis.EventSystem" } diff --git a/GeneralMods/TimeFreeze/TimeFreeze.cs b/GeneralMods/TimeFreeze/TimeFreeze.cs index b712edd5..2dd9dc90 100644 --- a/GeneralMods/TimeFreeze/TimeFreeze.cs +++ b/GeneralMods/TimeFreeze/TimeFreeze.cs @@ -1,4 +1,3 @@ -using System; using Omegasis.TimeFreeze.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -11,13 +10,11 @@ namespace Omegasis.TimeFreeze public class TimeFreeze : Mod { /********* - ** Properties + ** Fields *********/ /// The mod configuration. private ModConfig Config; - public int oldInterval; - /********* ** Public methods @@ -28,18 +25,17 @@ namespace Omegasis.TimeFreeze { this.Config = helper.ReadConfig(); - GameEvents.UpdateTick += this.GameEvents_UpdateTick; - //oldInterval = 7; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; } /********* ** Private methods *********/ - /// The method invoked when the game updates (roughly 60 times per second). + /// Raised after the game state is updated (≈60 times per second). /// The event sender. - /// The event data. - private void GameEvents_UpdateTick(object sender, EventArgs e) + /// The event arguments. + private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (!Context.IsWorldReady) return; diff --git a/GeneralMods/TimeFreeze/manifest.json b/GeneralMods/TimeFreeze/manifest.json index f96a7755..e2876405 100644 --- a/GeneralMods/TimeFreeze/manifest.json +++ b/GeneralMods/TimeFreeze/manifest.json @@ -5,6 +5,6 @@ "Description": "Emulates old Harvest Moon-style games where time is frozen inside.", "UniqueID": "Omegasis.TimeFreeze", "EntryDll": "TimeFreeze.dll", - "MinimumApiVersion": "2.0", + "MinimumApiVersion": "2.10.1", "UpdateKeys": [ "Nexus:973" ] } diff --git a/GeneralMods/UpgradeLog.htm b/GeneralMods/UpgradeLog.htm deleted file mode 100644 index 2749ed45..00000000 Binary files a/GeneralMods/UpgradeLog.htm and /dev/null differ diff --git a/GeneralMods/UpgradeLog2.htm b/GeneralMods/UpgradeLog2.htm deleted file mode 100644 index 2749ed45..00000000 Binary files a/GeneralMods/UpgradeLog2.htm and /dev/null differ diff --git a/GeneralMods/Vocalization/Vocalization/Framework/AudioCues.cs b/GeneralMods/Vocalization/Vocalization/Framework/AudioCues.cs index 29ffe130..b2edff66 100644 --- a/GeneralMods/Vocalization/Vocalization/Framework/AudioCues.cs +++ b/GeneralMods/Vocalization/Vocalization/Framework/AudioCues.cs @@ -11,22 +11,19 @@ namespace Vocalization.Framework public static Dictionary> DictionaryReferences = new Dictionary>(); - public static string generateKey(string translationPath, string SpeakerName, string fileName, string dialogueKey) + public static string generateKey(LanguageName language, string SpeakerName, string fileName, string dialogueKey) { - return Vocalization.config.translationInfo.getTranslationNameFromPath(translationPath) + Seperator + SpeakerName + Seperator + fileName + Seperator + dialogueKey; + return Vocalization.config.translationInfo.getTranslationName(language) + Seperator + SpeakerName + Seperator + fileName + Seperator + dialogueKey; } - public static SortedDictionary getWavFileReferences(string translation) + public static SortedDictionary getWavFileReferences(LanguageName language) { - return DictionaryReferences[Vocalization.config.translationInfo.getTranslationNameFromPath(translation)]; + return DictionaryReferences[Vocalization.config.translationInfo.getTranslationName(language)]; } public static void initialize() { - if (!Directory.Exists(Path.Combine(Vocalization.ModHelper.DirectoryPath, "AudioCues"))) - { - Directory.CreateDirectory(Path.Combine(Vocalization.ModHelper.DirectoryPath, "AudioCues")); - } + Directory.CreateDirectory(Path.Combine(Vocalization.ModHelper.DirectoryPath, "AudioCues")); loadAudioCues(); } @@ -45,20 +42,18 @@ namespace Vocalization.Framework public static void loadAudioCues() { - foreach (string v in Vocalization.config.translationInfo.translations) + foreach (LanguageName language in Vocalization.config.translationInfo.LanguageNames) { - var loaded = Vocalization.ModHelper.ReadJsonFile>(Path.Combine(Vocalization.ModHelper.DirectoryPath, "AudioCues", "AudioCues" + Seperator + v + ".json")); - if (loaded == null) loaded = new SortedDictionary(); - DictionaryReferences.Add(v, loaded); + var loaded = Vocalization.ModHelper.Data.ReadJsonFile>($"AudioCues/AudioCues{Seperator}{language}.json") + ?? new SortedDictionary(); + DictionaryReferences.Add(Vocalization.config.translationInfo.getTranslationName(language), loaded); } } public static void saveAudioCues() { foreach (var v in DictionaryReferences) - { - Vocalization.ModHelper.WriteJsonFile>(Path.Combine(Vocalization.ModHelper.DirectoryPath, "AudioCues", "AudioCues" + Seperator + v.Key + ".json"), v.Value); - } + Vocalization.ModHelper.Data.WriteJsonFile($"AudioCues/AudioCues{Seperator}{v.Key}.json", v.Value); } } } diff --git a/GeneralMods/Vocalization/Vocalization/Framework/CharacterVoiceCue.cs b/GeneralMods/Vocalization/Vocalization/Framework/CharacterVoiceCue.cs index a1b91933..26c7150d 100644 --- a/GeneralMods/Vocalization/Vocalization/Framework/CharacterVoiceCue.cs +++ b/GeneralMods/Vocalization/Vocalization/Framework/CharacterVoiceCue.cs @@ -172,13 +172,16 @@ namespace Vocalization.Framework } /// Change all of the files to the ones that are appropriate for that translation version. - public void initializeForTranslation(string translation) + /// The translation language name. + public void initializeForTranslation(LanguageName language) { + string extension = Vocalization.config.translationInfo.getFileExtentionForTranslation(language); + for (int i = 0; i < this.dataFileNames.Count; i++) { Vocalization.ModMonitor.Log(this.dataFileNames.ElementAt(i)); string s = this.dataFileNames.ElementAt(i); - s = this.dataFileNames.ElementAt(i).Replace(".xnb", Vocalization.config.translationInfo.getFileExtentionForTranslation(translation)); + s = this.dataFileNames.ElementAt(i).Replace(".xnb", extension); this.dataFileNames[i] = s; Vocalization.ModMonitor.Log(this.dataFileNames.ElementAt(i)); } @@ -187,7 +190,7 @@ namespace Vocalization.Framework { Vocalization.ModMonitor.Log(this.dialogueFileNames.ElementAt(i)); string s = this.dialogueFileNames.ElementAt(i); - s = this.dialogueFileNames.ElementAt(i).Replace(".xnb", Vocalization.config.translationInfo.getFileExtentionForTranslation(translation)); + s = this.dialogueFileNames.ElementAt(i).Replace(".xnb", extension); this.dialogueFileNames[i] = s; Vocalization.ModMonitor.Log(this.dialogueFileNames.ElementAt(i)); } @@ -196,7 +199,7 @@ namespace Vocalization.Framework { Vocalization.ModMonitor.Log(this.stringsFileNames.ElementAt(i)); string s = this.stringsFileNames.ElementAt(i); - s = this.stringsFileNames.ElementAt(i).Replace(".xnb", Vocalization.config.translationInfo.getFileExtentionForTranslation(translation)); + s = this.stringsFileNames.ElementAt(i).Replace(".xnb", extension); this.stringsFileNames[i] = s; Vocalization.ModMonitor.Log(this.stringsFileNames.ElementAt(i)); } @@ -205,7 +208,7 @@ namespace Vocalization.Framework { Vocalization.ModMonitor.Log(this.festivalFileNames.ElementAt(i)); string s = this.festivalFileNames.ElementAt(i); - s = this.festivalFileNames.ElementAt(i).Replace(".xnb", Vocalization.config.translationInfo.getFileExtentionForTranslation(translation)); + s = this.festivalFileNames.ElementAt(i).Replace(".xnb", extension); this.festivalFileNames[i] = s; Vocalization.ModMonitor.Log(this.festivalFileNames.ElementAt(i)); } @@ -214,7 +217,7 @@ namespace Vocalization.Framework { Vocalization.ModMonitor.Log(this.eventFileNames.ElementAt(i)); string s = this.eventFileNames.ElementAt(i); - s = this.eventFileNames.ElementAt(i).Replace(".xnb", Vocalization.config.translationInfo.getFileExtentionForTranslation(translation)); + s = this.eventFileNames.ElementAt(i).Replace(".xnb", extension); this.eventFileNames[i] = s; Vocalization.ModMonitor.Log(this.eventFileNames.ElementAt(i)); } diff --git a/GeneralMods/Vocalization/Vocalization/Framework/LanguageName.cs b/GeneralMods/Vocalization/Vocalization/Framework/LanguageName.cs new file mode 100644 index 00000000..c78d42a5 --- /dev/null +++ b/GeneralMods/Vocalization/Vocalization/Framework/LanguageName.cs @@ -0,0 +1,14 @@ +namespace Vocalization.Framework +{ + /// The supported language names. + public enum LanguageName + { + English, + Spanish, + Chinese, + Japanese, + Russian, + German, + Portuguese + } +} diff --git a/GeneralMods/Vocalization/Vocalization/Framework/Menus/VocalizationMenu.cs b/GeneralMods/Vocalization/Vocalization/Framework/Menus/VocalizationMenu.cs index 38fb7ee2..ae25f24c 100644 --- a/GeneralMods/Vocalization/Vocalization/Framework/Menus/VocalizationMenu.cs +++ b/GeneralMods/Vocalization/Vocalization/Framework/Menus/VocalizationMenu.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -39,13 +40,13 @@ namespace Vocalization.Framework.Menus Rectangle sourceRect = new Rectangle(0, 0, 4, 16); this.sliderButton = new SliderButton("Slider", "Volume", new Rectangle(this.xPositionOnScreen + 100, this.yPositionOnScreen + 220, 4, 16), buttonTexture, bar, sourceRect, 2f, new SliderInformation(SliderStyle.Horizontal, (int)(Vocalization.config.voiceVolume * 100), 1), new StardustCore.Animations.Animation(sourceRect), Color.White, Color.Black, new StardustCore.UIUtilities.MenuComponents.Delegates.Functionality.ButtonFunctionality(null, null, null), false, null, true); - Button english = new Button("EnglishButton", "English", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 0, 174, 39), 1f); - Button spanish = new Button("SpanishButton", "Spanish", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 2, 174, 39), 1f); - Button portuguese = new Button("PortugueseButton", "Brazillian Portuguese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 4, 174, 39), 1f); - Button russian = new Button("RussianButton", "Russian", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 6, 174, 39), 1f); - Button chinese = new Button("ChineseButton", "Chinese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 8, 174, 39), 1f); - Button japanese = new Button("JapaneseButton", "Japanese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 10, 174, 39), 1f); - Button german = new Button("GermanButton", "German", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 12, 174, 39), 1f); + Button english = new Button(LanguageName.English.ToString(), "English", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 0, 174, 39), 1f); + Button spanish = new Button(LanguageName.Spanish.ToString(), "Spanish", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 2, 174, 39), 1f); + Button portuguese = new Button(LanguageName.Portuguese.ToString(), "Brazillian Portuguese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 4, 174, 39), 1f); + Button russian = new Button(LanguageName.Russian.ToString(), "Russian", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 6, 174, 39), 1f); + Button chinese = new Button(LanguageName.Chinese.ToString(), "Chinese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 8, 174, 39), 1f); + Button japanese = new Button(LanguageName.Japanese.ToString(), "Japanese", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 10, 174, 39), 1f); + Button german = new Button(LanguageName.German.ToString(), "German", new Rectangle(0, 0, 174, 39), new Texture2DExtended(Vocalization.ModHelper, Path.Combine("LooseSprites", "LanguageButtons.xnb"), StardewModdingAPI.ContentSource.GameContent), new Rectangle(0, 39 * 12, 174, 39), 1f); List