diff --git a/GeneralMods/AutoSpeed/AutoSpeed.cs b/GeneralMods/AutoSpeed/AutoSpeed.cs index 17cf4857..ec6bb545 100644 --- a/GeneralMods/AutoSpeed/AutoSpeed.cs +++ b/GeneralMods/AutoSpeed/AutoSpeed.cs @@ -1,5 +1,5 @@ using System; -using System.IO; +using Omegasis.AutoSpeed.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -12,8 +12,8 @@ namespace Omegasis.AutoSpeed /********* ** Properties *********/ - /// The speed multiplier. - private int Speed = 5; + /// The mod configuration. + private ModConfig Config; /********* @@ -24,13 +24,7 @@ namespace Omegasis.AutoSpeed public override void Entry(IModHelper helper) { GameEvents.UpdateTick += this.GameEvents_UpdateTick; - - string configLocation = Path.Combine(helper.DirectoryPath, "AutoSpeed_Data.txt"); - if (!File.Exists(configLocation)) - this.Speed = 1; - - this.LoadConfig(); - this.Monitor.Log("AutoSpeed Initialization Completed", LogLevel.Info); + this.Config = helper.ReadConfig(); } @@ -43,32 +37,7 @@ namespace Omegasis.AutoSpeed private void GameEvents_UpdateTick(object sender, EventArgs e) { if (Context.IsPlayerFree) - Game1.player.addedSpeed = this.Speed; - } - - /// Load the configuration settings. - private void LoadConfig() - { - string path = Path.Combine(this.Helper.DirectoryPath, "AutoSpeed_data.txt"); - if (!File.Exists(path)) - this.WriteConfig(); - else - { - string[] text = File.ReadAllLines(path); - this.Speed = Convert.ToInt32(text[3]); - } - } - - /// Save the configuration settings. - void WriteConfig() - { - string path = Path.Combine(this.Helper.DirectoryPath, "AutoSpeed_data.txt"); - string[] text = new string[20]; - text[0] = "Player: AutoSpeed Config:"; - text[1] = "===================================================================================="; - text[2] = "Player Added Speed:"; - text[3] = Speed.ToString(); - File.WriteAllLines(path, text); + Game1.player.addedSpeed = this.Config.Speed; } } } diff --git a/GeneralMods/AutoSpeed/AutoSpeed.csproj b/GeneralMods/AutoSpeed/AutoSpeed.csproj index 1c9aac56..7fce89f1 100644 --- a/GeneralMods/AutoSpeed/AutoSpeed.csproj +++ b/GeneralMods/AutoSpeed/AutoSpeed.csproj @@ -38,6 +38,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/AutoSpeed/Framework/ModConfig.cs b/GeneralMods/AutoSpeed/Framework/ModConfig.cs new file mode 100644 index 00000000..e4f0c68f --- /dev/null +++ b/GeneralMods/AutoSpeed/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.AutoSpeed.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The added speed. + public int Speed { get; set; } = 1; + } +} diff --git a/GeneralMods/AutoSpeed/README.md b/GeneralMods/AutoSpeed/README.md index 7527d5ac..1d101d35 100644 --- a/GeneralMods/AutoSpeed/README.md +++ b/GeneralMods/AutoSpeed/README.md @@ -9,8 +9,8 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 3. Run the game using SMAPI. ## Usage -Launch the game with the mod installed to generate the config file, then edit the -`AutoSpeed_data.txt` to set the speed you want (higher values are faster). +Launch the game with the mod installed to generate the config file, then edit the `config.json` to +set the speed you want (higher values are faster). ## Versions 1.0 @@ -23,4 +23,5 @@ Launch the game with the mod installed to generate the config file, then edit th * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.4: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs b/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs index a4610ef4..50480d7b 100644 --- a/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs +++ b/GeneralMods/BillboardAnywhere/BillboardAnywhere.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using Omegasis.BillboardAnywhere.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -13,8 +12,8 @@ namespace Omegasis.BillboardAnywhere /********* ** Properties *********/ - /// The key which shows the billboard menu. - private string KeyBinding = "B"; + /// The mod configuration. + private ModConfig Config; /********* @@ -24,7 +23,8 @@ namespace Omegasis.BillboardAnywhere /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + this.Config = helper.ReadConfig(); + ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; } @@ -32,50 +32,14 @@ namespace Omegasis.BillboardAnywhere /********* ** Private methods *********/ - /// The method invoked after the player loads a save. - /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) - { - this.LoadConfig(); - } - /// The method invoked when the presses a keyboard button. /// The event sender. /// The event data. public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) { // load menu if key pressed - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.KeyBinding) + if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) Game1.activeClickableMenu = new Billboard(); } - - /// Load the configuration settings. - void LoadConfig() - { - string path = Path.Combine(this.Helper.DirectoryPath, "Billboard_Anywhere_Config.txt"); - if (!File.Exists(path)) - { - this.KeyBinding = "B"; - this.WriteConfig(); - } - else - { - string[] text = File.ReadAllLines(path); - this.KeyBinding = Convert.ToString(text[3]); - } - } - - /// Save the configuration settings. - void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Billboard_Anywhere_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: Billboard_Anywhere. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - text[2] = "Key binding for opening the billboard anywhere. Press this key to do so"; - text[3] = this.KeyBinding; - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/BillboardAnywhere/BillboardAnywhere.csproj b/GeneralMods/BillboardAnywhere/BillboardAnywhere.csproj index 4023451c..f05db33b 100644 --- a/GeneralMods/BillboardAnywhere/BillboardAnywhere.csproj +++ b/GeneralMods/BillboardAnywhere/BillboardAnywhere.csproj @@ -38,6 +38,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs b/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs new file mode 100644 index 00000000..e57f51ce --- /dev/null +++ b/GeneralMods/BillboardAnywhere/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.BillboardAnywhere.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the billboard menu. + public string KeyBinding { get; set; } = "B"; + } +} diff --git a/GeneralMods/BillboardAnywhere/README.md b/GeneralMods/BillboardAnywhere/README.md index 4817c5e7..f4f4a1b9 100644 --- a/GeneralMods/BillboardAnywhere/README.md +++ b/GeneralMods/BillboardAnywhere/README.md @@ -9,8 +9,7 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 3. Run the game using SMAPI. ## Usage -Press `B` while in-game to show the billboard menu. Edit the `Billboard_Anywhere_Config.txt` file -to change the key. +Press `B` while in-game to show the billboard menu. Edit the `config.json` file to change the key. ## Versions 1.0 @@ -23,4 +22,5 @@ to change the key. * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.4: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/BuildEndurance/BuildEndurance.cs b/GeneralMods/BuildEndurance/BuildEndurance.cs index 0a87f1f6..82cca4b7 100644 --- a/GeneralMods/BuildEndurance/BuildEndurance.cs +++ b/GeneralMods/BuildEndurance/BuildEndurance.cs @@ -1,7 +1,6 @@ using System; using System.IO; -using System.Text; -using Newtonsoft.Json; +using System.Linq; using Omegasis.BuildEndurance.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -15,45 +14,30 @@ namespace Omegasis.BuildEndurance /********* ** Properties *********/ - /// The mod settings and player data. + /// The relative path for the current player's data file. + private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); + + /// The absolute path for the current player's legacy data file. + private string LegacyDataFilePath => Path.Combine(this.Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.name}.txt"); + + /// The mod settings. private ModConfig Config; + /// The data for the current player. + private PlayerData PlayerData; + /// Whether the player has been exhausted today. private bool WasExhausted; /// Whether the player has collapsed today. private bool WasCollapsed; - /// The XP points needed to reach the next endurance level. - private double ExpToNextLevel = 20; - - /// The player's current endurance XP points. - private double CurrentExp; - - /// The player's current endurance level. - private int CurrentLevel; - - /// The stamina points to add to the player's base stamina due to their current endurance level. - private int CurrentLevelStaminaBonus; - - /// The initial stamina bonus to apply regardless of the player's endurance level, from the config file. - private int BaseStaminaBonus; - - /// Whether to reset all changes by the mod to the default values (i.e. start over). - private bool ClearModEffects; - - /// The player's original stamina value, excluding mod effects. - private int OriginalStamina; - /// Whether the player recently gained XP for tool use. private bool HasRecentToolExp; /// Whether the player was eating last time we checked. private bool WasEating; - /// The player's stamina last time they slept. - private int NightlyStamina; - /********* ** Public methods @@ -62,46 +46,22 @@ namespace Omegasis.BuildEndurance /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.Config = helper.ReadConfig(); + GameEvents.UpdateTick += this.GameEvents_UpdateTick; GameEvents.OneSecondTick += this.GameEvents_OneSecondTick; SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; - TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; - - string configPath = Path.Combine(helper.DirectoryPath, "BuildEnduranceConfig.json"); - if (!File.Exists(configPath)) - { - this.Monitor.Log("Initial configuration file setup."); - this.Config = new ModConfig - { - CurrentLevel = 0, - MaxLevel = 100, - StaminaIncreasePerLevel = 1, - CurrentExp = 0, - ExpToNextLevel = 20, - ExpCurve = 1.15, - ExpForEating = 2, - ExpForSleeping = 10, - ExpForToolUse = 1, - BaseStaminaBonus = 0, - CurrentLevelStaminaBonus = 0, - ExpForExhaustion = 25, - ExpForCollapsing = 50 - }; - File.WriteAllBytes(configPath, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this.Config))); - } - else - { - this.Config = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(File.ReadAllBytes(configPath))); - this.Monitor.Log("Found BuildEndurance config file."); - } - - this.Monitor.Log("BuildEndurance Initialization Completed"); + SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; } + + /********* + ** Private methods + *********/ /// The method invoked once per second during a game update. /// The event sender. /// The event data. - public void GameEvents_OneSecondTick(object sender, EventArgs e) + private void GameEvents_OneSecondTick(object sender, EventArgs e) { // nerf how quickly tool xp is gained (I hope) if (this.HasRecentToolExp) @@ -111,28 +71,31 @@ namespace Omegasis.BuildEndurance /// The method invoked when the game updates (roughly 60 times per second). /// The event sender. /// The event data. - public void GameEvents_UpdateTick(object sender, EventArgs e) + private void GameEvents_UpdateTick(object sender, EventArgs e) { + if (!Context.IsWorldReady) + return; + // give XP when player finishes eating if (Game1.isEating) this.WasEating = true; else if (this.WasEating) { - this.CurrentExp += this.Config.ExpForEating; + this.PlayerData.CurrentExp += this.Config.ExpForEating; this.WasEating = false; } // give XP when player uses tool if (!this.HasRecentToolExp && Game1.player.usingTool) { - this.CurrentExp += this.Config.ExpForToolUse; + this.PlayerData.CurrentExp += this.Config.ExpForToolUse; this.HasRecentToolExp = true; } // give XP when exhausted if (!this.WasExhausted && Game1.player.exhausted) { - this.CurrentExp += this.Config.ExpForExhaustion; + this.PlayerData.CurrentExp += this.Config.ExpForExhaustion; this.WasExhausted = true; this.Monitor.Log("The player is exhausted"); } @@ -140,7 +103,7 @@ namespace Omegasis.BuildEndurance // give XP when player stays up too late or collapses if (!this.WasCollapsed && Game1.farmerShouldPassOut) { - this.CurrentExp += this.Config.ExpForCollapsing; + this.PlayerData.CurrentExp += this.Config.ExpForCollapsing; this.WasCollapsed = true; this.Monitor.Log("The player has collapsed!"); } @@ -149,195 +112,100 @@ namespace Omegasis.BuildEndurance /// The method invoked after the player loads a save. /// The event sender. /// The event data. - public void SaveEvents_AfterLoad(object sender, EventArgs e) + private void SaveEvents_AfterLoad(object sender, EventArgs e) { - // initialise - this.LoadConfig(); - this.WriteConfig(); - - // grab initial stamina - var player = Game1.player; - if (this.OriginalStamina == 0) - this.OriginalStamina = player.MaxStamina; - - // set nightly stamina - player.MaxStamina = this.NightlyStamina; - if (this.NightlyStamina == 0) - player.MaxStamina = this.BaseStaminaBonus + this.CurrentLevelStaminaBonus + this.OriginalStamina; + // load player data + this.MigrateLegacyData(); + this.PlayerData = this.Helper.ReadJsonFile(this.DataFilePath) ?? new PlayerData(); + if (this.PlayerData.OriginalMaxStamina == 0) + this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina; // reset if needed - if (this.ClearModEffects) - player.MaxStamina = this.OriginalStamina; + if (this.PlayerData.ClearModEffects) + { + Game1.player.MaxStamina = this.PlayerData.OriginalMaxStamina; + this.PlayerData.ExpToNextLevel = this.Config.ExpToNextLevel; + this.PlayerData.CurrentExp = this.Config.CurrentExp; + this.PlayerData.CurrentLevelStaminaBonus = 0; + this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina; + this.PlayerData.BaseStaminaBonus = 0; + this.PlayerData.CurrentLevel = 0; + this.PlayerData.ClearModEffects = false; + } - // save config - this.LoadConfig(); - this.WriteConfig(); + // else apply stamina + else + { + Game1.player.MaxStamina = this.PlayerData.NightlyStamina <= 0 + ? this.PlayerData.BaseStaminaBonus + this.PlayerData.CurrentLevelStaminaBonus + this.PlayerData.OriginalMaxStamina + : this.PlayerData.NightlyStamina; + } } - /// The method invoked when a new day starts. + /// The method invoked just before the game is saved. /// The event sender. /// The event data. - public void TimeEvents_AfterDayStarted(object sender, EventArgs e) + private void SaveEvents_BeforeSave(object sender, EventArgs e) { // reset data this.WasExhausted = false; this.WasCollapsed = false; - // update settings - this.Monitor.Log(this.CurrentExp.ToString()); - this.UpdateClearSetting(); - this.Monitor.Log(this.ClearModEffects.ToString()); + // update player data + this.PlayerData.CurrentExp += this.Config.ExpForSleeping; + if (this.PlayerData.OriginalMaxStamina == 0) + this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina; //grab the initial stamina value - var player = Game1.player; - this.CurrentExp += this.Config.ExpForSleeping; - if (this.OriginalStamina == 0) - this.OriginalStamina = player.MaxStamina; //grab the initial stamina value - - if (this.ClearModEffects) + if (this.PlayerData.CurrentLevel < this.Config.MaxLevel) { - this.LoadClearSettings(); - player.MaxStamina = this.OriginalStamina; - this.ExpToNextLevel = this.Config.ExpToNextLevel; - this.CurrentExp = this.Config.CurrentExp; - this.CurrentLevelStaminaBonus = 0; - this.OriginalStamina = player.MaxStamina; - this.BaseStaminaBonus = 0; - this.CurrentLevel = 0; - } - - if (!this.ClearModEffects && this.CurrentLevel < this.Config.MaxLevel) - { - while (this.CurrentExp >= this.ExpToNextLevel) + while (this.PlayerData.CurrentExp >= this.PlayerData.ExpToNextLevel) { - this.CurrentLevel += 1; - this.CurrentExp = this.CurrentExp - this.ExpToNextLevel; - this.ExpToNextLevel = (this.Config.ExpCurve * this.ExpToNextLevel); - player.MaxStamina += this.Config.StaminaIncreasePerLevel; - this.CurrentLevelStaminaBonus += this.Config.StaminaIncreasePerLevel; - + this.PlayerData.CurrentLevel += 1; + this.PlayerData.CurrentExp = this.PlayerData.CurrentExp - this.PlayerData.ExpToNextLevel; + this.PlayerData.ExpToNextLevel = (this.Config.ExpCurve * this.PlayerData.ExpToNextLevel); + Game1.player.MaxStamina += this.Config.StaminaIncreasePerLevel; + this.PlayerData.CurrentLevelStaminaBonus += this.Config.StaminaIncreasePerLevel; } } - this.ClearModEffects = false; - this.NightlyStamina = Game1.player.maxStamina; - this.WriteConfig(); + this.PlayerData.ClearModEffects = false; + this.PlayerData.NightlyStamina = Game1.player.maxStamina; + + // save data + this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData); } - /// Update the settings needed for from the latest config file on disk. - void LoadClearSettings() + /// Migrate the legacy settings for the current player. + private void MigrateLegacyData() { - this.LoadConfig(); - this.WriteConfig(); + // skip if no legacy data or new data already exists + if (!File.Exists(this.LegacyDataFilePath) || File.Exists(this.DataFilePath)) + return; - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.name}.txt"); - if (!File.Exists(path)) + // migrate to new file + try { - this.Monitor.Log("Clear Data Loaded could not find the correct file.")); + string[] text = File.ReadAllLines(this.LegacyDataFilePath); + this.Helper.WriteJsonFile(this.DataFilePath, new PlayerData + { + CurrentLevel = Convert.ToInt32(text[3]), + CurrentExp = Convert.ToDouble(text[5]), + ExpToNextLevel = Convert.ToDouble(text[7]), + BaseStaminaBonus = Convert.ToInt32(text[9]), + CurrentLevelStaminaBonus = Convert.ToInt32(text[11]), + ClearModEffects = Convert.ToBoolean(text[14]), + OriginalMaxStamina = Convert.ToInt32(text[16]), + NightlyStamina = Convert.ToInt32(text[18]) + }); - this.ClearModEffects = false; - this.OriginalStamina = 0; - this.BaseStaminaBonus = 0; + FileInfo file = new FileInfo(this.LegacyDataFilePath); + file.Delete(); + if (!file.Directory.EnumerateFiles().Any()) + file.Directory.Delete(); } - else + catch (Exception ex) { - string[] text = File.ReadAllLines(path); - this.BaseStaminaBonus = Convert.ToInt32(text[9]); - this.ClearModEffects = Convert.ToBoolean(text[14]); - this.OriginalStamina = Convert.ToInt32(text[16]); + this.Monitor.Log($"Error migrating data from the legacy 'PlayerData' folder for the current player. Technical details:\n {ex}", LogLevel.Error); } } - - /// Update based on the latest config file on disk. - private void UpdateClearSetting() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.name}.txt"); - if (!File.Exists(path)) - { - this.Monitor.Log("Clear Data Loaded could not find the correct file."); - - this.ClearModEffects = false; - this.OriginalStamina = 0; - this.BaseStaminaBonus = 0; - } - else - { - string[] text = File.ReadAllLines(path); - this.ClearModEffects = Convert.ToBoolean(text[14]); - } - } - - /// Load the configuration settings. - void LoadConfig() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.name}.txt"); - if (!File.Exists(path)) - { - this.ExpToNextLevel = this.Config.ExpToNextLevel; - this.CurrentExp = this.Config.CurrentExp; - this.CurrentLevel = this.Config.CurrentLevel; - this.BaseStaminaBonus = this.Config.BaseStaminaBonus; - this.CurrentLevelStaminaBonus = this.Config.CurrentLevelStaminaBonus; - this.ClearModEffects = false; - this.OriginalStamina = 0; - } - else - { - string[] text = File.ReadAllLines(path); - this.CurrentLevel = Convert.ToInt32(text[3]); - this.ExpToNextLevel = Convert.ToDouble(text[7]); - this.CurrentExp = Convert.ToDouble(text[5]); - this.BaseStaminaBonus = Convert.ToInt32(text[9]); - this.CurrentLevelStaminaBonus = Convert.ToInt32(text[11]); - this.ClearModEffects = Convert.ToBoolean(text[14]); - this.OriginalStamina = Convert.ToInt32(text[16]); - this.NightlyStamina = Convert.ToInt32(text[18]); - } - } - - /// Save the configuration settings. - void WriteConfig() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.name}.txt"); - string[] text = new string[20]; - text[0] = "Player: Build Endurance Data. Modification can cause errors. Edit at your own risk."; - text[1] = "===================================================================================="; - - text[2] = "Player Current Level:"; - text[3] = this.CurrentLevel.ToString(); - - text[4] = "Player Current XP:"; - text[5] = this.CurrentExp.ToString(); - - text[6] = "Xp to next Level:"; - text[7] = this.ExpToNextLevel.ToString(); - - text[8] = "Initial Stam Bonus:"; - text[9] = this.BaseStaminaBonus.ToString(); - - text[10] = "Additional Stam Bonus:"; - text[11] = this.CurrentLevelStaminaBonus.ToString(); - - text[12] = "======================================================================================="; - text[13] = "RESET ALL MOD EFFECTS? This will effective start you back at square 1. Also good if you want to remove this mod."; - text[14] = this.ClearModEffects.ToString(); - text[15] = "OLD STAMINA AMOUNT: This is the initial value of the Player's Stamina before this mod took over."; - text[16] = this.OriginalStamina.ToString(); - - text[17] = "Nightly Stamina Value: This is the value of the player's stamina that was saved when the player slept."; - text[18] = this.NightlyStamina.ToString(); - - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/BuildEndurance/BuildEndurance.csproj b/GeneralMods/BuildEndurance/BuildEndurance.csproj index 16ff6c1a..611d9fba 100644 --- a/GeneralMods/BuildEndurance/BuildEndurance.csproj +++ b/GeneralMods/BuildEndurance/BuildEndurance.csproj @@ -30,10 +30,6 @@ 4 - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - False - @@ -43,6 +39,7 @@ + diff --git a/GeneralMods/BuildEndurance/Framework/ModConfig.cs b/GeneralMods/BuildEndurance/Framework/ModConfig.cs index f2a12060..477ca87f 100644 --- a/GeneralMods/BuildEndurance/Framework/ModConfig.cs +++ b/GeneralMods/BuildEndurance/Framework/ModConfig.cs @@ -4,7 +4,7 @@ namespace Omegasis.BuildEndurance.Framework internal class ModConfig { /// The XP points needed to reach the next endurance level. - public double ExpToNextLevel { get; set; } + public double ExpToNextLevel { get; set; } = 20; /// The player's current endurance XP points. public double CurrentExp { get; set; } @@ -19,27 +19,27 @@ namespace Omegasis.BuildEndurance.Framework public int CurrentLevelStaminaBonus { get; set; } /// The multiplier for the experience points to need to reach an endurance level relative to the previous one. - public double ExpCurve { get; set; } + public double ExpCurve { get; set; } = 1.15; /// The maximum endurance level the player can reach. - public int MaxLevel { get; set; } + public int MaxLevel { get; set; } = 100; /// The amount of stamina the player should gain for each endurance level. - public int StaminaIncreasePerLevel { get; set; } + public int StaminaIncreasePerLevel { get; set; } = 1; /// The experience points to gain for using a tool. - public int ExpForToolUse { get; set; } + public int ExpForToolUse { get; set; } = 1; /// The experience points to gain for eating or drinking. - public int ExpForEating { get; set; } + public int ExpForEating { get; set; } = 2; /// The experience points to gain for sleeping. - public int ExpForSleeping { get; set; } + public int ExpForSleeping { get; set; } = 10; /// The experience points to gain for reaching a state of exhaustion for the day. - public int ExpForExhaustion { get; set; } + public int ExpForExhaustion { get; set; } = 25; /// The experience points to gain for collapsing for the day. - public int ExpForCollapsing { get; set; } + public int ExpForCollapsing { get; set; } = 50; } } diff --git a/GeneralMods/BuildEndurance/Framework/PlayerData.cs b/GeneralMods/BuildEndurance/Framework/PlayerData.cs new file mode 100644 index 00000000..de2a36c8 --- /dev/null +++ b/GeneralMods/BuildEndurance/Framework/PlayerData.cs @@ -0,0 +1,30 @@ +namespace Omegasis.BuildEndurance.Framework +{ + /// The data for the current player. + internal class PlayerData + { + /// The player's current endurance level. + public int CurrentLevel { get; set; } + + /// The player's current endurance XP points. + public double CurrentExp { get; set; } + + /// The XP points needed to reach the next endurance level. + public double ExpToNextLevel { get; set; } = 20; + + /// The initial stamina bonus to apply regardless of the player's endurance level, from the config file. + public int BaseStaminaBonus { get; set; } + + /// The stamina points to add to the player's base stamina due to their current endurance level. + public int CurrentLevelStaminaBonus { get; set; } + + /// Whether to reset all changes by the mod to the default values (i.e. start over). + public bool ClearModEffects { get; set; } + + /// The player's original max stamina value, excluding mod effects. + public int OriginalMaxStamina { get; set; } + + /// The player's stamina last time they slept. + public int NightlyStamina { get; set; } + } +} diff --git a/GeneralMods/BuildEndurance/README.md b/GeneralMods/BuildEndurance/README.md index 9c3a0674..6dbaa5d6 100644 --- a/GeneralMods/BuildEndurance/README.md +++ b/GeneralMods/BuildEndurance/README.md @@ -8,8 +8,8 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 2. Install [this mod from Nexus mods](http://www.nexusmods.com/stardewvalley/mods/445). 3. Run the game using SMAPI. -**NOTE:** to undo the mod's changes to your player, edit the `PlayerData\BuildEndurance_data_*.txt` -file and change the "RESET ALL MOD EFFECTS?" field to `True`. +**NOTE:** to undo the mod's changes to your player, edit the `data\*.json` file for your save and +change the "ClearModEffects" field to `true`. ## Usage You'll automatically get XP for... @@ -22,7 +22,7 @@ You'll automatically get XP for... Get enough XP, and your endurance will level up. -Edit `BuildEnduranceConfig.json` to configure the mod settings. +Edit `config.json` to configure the mod settings. ## Versions 1.0 @@ -36,4 +36,6 @@ Edit `BuildEnduranceConfig.json` to configure the mod settings. 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config & data files. +* Fixed issue where saves with the same name would overwrite each other's endurance level data. * Internal refactoring. diff --git a/GeneralMods/BuildEndurance/packages.config b/GeneralMods/BuildEndurance/packages.config index 31bc8030..058d0838 100644 --- a/GeneralMods/BuildEndurance/packages.config +++ b/GeneralMods/BuildEndurance/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/GeneralMods/BuildHealth/BuildHealth.cs b/GeneralMods/BuildHealth/BuildHealth.cs index ea234699..c35cc067 100644 --- a/GeneralMods/BuildHealth/BuildHealth.cs +++ b/GeneralMods/BuildHealth/BuildHealth.cs @@ -1,7 +1,6 @@ using System; using System.IO; -using System.Text; -using Newtonsoft.Json; +using System.Linq; using Omegasis.BuildHealth.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -15,29 +14,17 @@ namespace Omegasis.BuildHealth /********* ** Properties *********/ + /// The relative path for the current player's data file. + private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); + + /// The absolute path for the current player's legacy data file. + private string LegacyDataFilePath => Path.Combine(this.Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.name}.txt"); + /// The mod settings and player data. private ModConfig Config; - /// The XP points needed to reach the next level. - private double ExpToNextLevel = 20; - - /// The player's current XP points. - private double CurrentExp; - - /// The player's current level. - private int CurrentLevel; - - /// The health points to add to the player's base health due to their current level. - private int CurrentLevelHealthBonus; - - /// The initial health bonus to apply regardless of the player's level, from the config file. - private int BaseHealthBonus; - - /// Whether to reset all changes by the mod to the default values (i.e. start over). - private bool ClearModEffects; - - /// The player's original max health value, excluding mod effects. - private int OriginalMaxHealth; + /// The data for the current player. + private PlayerData PlayerData; /// Whether the player recently gained XP for tool use. private bool HasRecentToolExp; @@ -61,42 +48,20 @@ namespace Omegasis.BuildHealth { GameEvents.UpdateTick += this.GameEvents_UpdateTick; GameEvents.OneSecondTick += this.GameEvents_OneSecondTick; - - TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; + TimeEvents.AfterDayStarted += this.SaveEvents_BeforeSave; SaveEvents.AfterLoad += this.SaveEvents_AfterLoaded; - var configPath = Path.Combine(helper.DirectoryPath, "BuildHealthConfig.json"); - if (!File.Exists(configPath)) - { - this.Config = new ModConfig - { - CurrentLevel = 0, - MaxLevel = 100, - HealthIncreasePerLevel = 1, - CurrentExp = 0, - ExpToNextLevel = 20, - ExpCurve = 1.15, - ExpForEating = 2, - ExpForSleeping = 10, - ExpForToolUse = 1, - BaseHealthBonus = 0, - CurrentLevelHealthBonus = 0 - }; - File.WriteAllBytes(configPath, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this.Config))); - } - else - { - this.Config = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(File.ReadAllBytes(configPath))); - this.Monitor.Log("Found BuildHealth config file."); - } - - this.Monitor.Log("BuildHealth Initialization Completed"); + this.Config = helper.ReadConfig(); } + + /********* + ** Private methods + *********/ /// The method invoked once per second during a game update. /// The event sender. /// The event data. - public void GameEvents_OneSecondTick(object sender, EventArgs e) + private void GameEvents_OneSecondTick(object sender, EventArgs e) { // nerf how quickly tool xp is gained (I hope) if (this.HasRecentToolExp) @@ -106,21 +71,24 @@ namespace Omegasis.BuildHealth /// The method invoked when the game updates (roughly 60 times per second). /// The event sender. /// The event data. - public void GameEvents_UpdateTick(object sender, EventArgs e) + private void GameEvents_UpdateTick(object sender, EventArgs e) { + if (!Context.IsWorldReady) + return; + // give XP when player finishes eating if (Game1.isEating) this.WasEating = true; else if (this.WasEating) { - this.CurrentExp += this.Config.ExpForEating; + this.PlayerData.CurrentExp += this.Config.ExpForEating; this.WasEating = false; } // give XP when player uses tool if (!this.HasRecentToolExp && Game1.player.usingTool) { - this.CurrentExp += this.Config.ExpForToolUse; + this.PlayerData.CurrentExp += this.Config.ExpForToolUse; this.HasRecentToolExp = true; } @@ -128,7 +96,7 @@ namespace Omegasis.BuildHealth var player = Game1.player; if (this.LastHealth > player.health) { - this.CurrentExp += this.LastHealth - player.health; + this.PlayerData.CurrentExp += this.LastHealth - player.health; this.LastHealth = player.health; } else if (this.LastHealth < player.health) @@ -137,195 +105,107 @@ namespace Omegasis.BuildHealth // give XP when player stays up too late or collapses if (!this.WasCollapsed && Game1.farmerShouldPassOut) { - this.CurrentExp += this.Config.ExpForCollapsing; + this.PlayerData.CurrentExp += this.Config.ExpForCollapsing; this.WasCollapsed = true; this.Monitor.Log("The player has collapsed!"); } } - /// The method invoked after a new day starts. + /// The method invoked after the player loads a save. /// The event sender. /// The event data. - public void TimeEvents_AfterDayStarted(object sender, EventArgs e) + private void SaveEvents_AfterLoaded(object sender, EventArgs e) + { + // load player data + this.MigrateLegacyData(); + this.PlayerData = this.Helper.ReadJsonFile(this.DataFilePath) ?? new PlayerData(); + if (this.PlayerData.OriginalMaxHealth == 0) + this.PlayerData.OriginalMaxHealth = Game1.player.maxHealth; + + // reset if needed + if (this.PlayerData.ClearModEffects) + { + Game1.player.maxHealth = this.PlayerData.OriginalMaxHealth; + this.PlayerData.ExpToNextLevel = this.Config.ExpToNextLevel; + this.PlayerData.CurrentExp = this.Config.CurrentExp; + this.PlayerData.CurrentLevelHealthBonus = 0; + this.PlayerData.OriginalMaxHealth = Game1.player.maxHealth; + this.PlayerData.BaseHealthBonus = 0; + this.PlayerData.CurrentLevel = 0; + this.PlayerData.ClearModEffects = false; + } + + // else apply health + else + { + Game1.player.maxHealth = this.PlayerData.BaseHealthBonus + this.PlayerData.CurrentLevelHealthBonus + this.PlayerData.OriginalMaxHealth; + this.LastHealth = Game1.player.health; + } + } + + /// The method invoked just before the game saves. + /// The event sender. + /// The event data. + private void SaveEvents_BeforeSave(object sender, EventArgs e) { // reset data this.LastHealth = Game1.player.maxHealth; this.WasCollapsed = false; // update settings - this.UpdateClearSetting(); - var player = Game1.player; - this.CurrentExp += this.Config.ExpForSleeping; - if (this.OriginalMaxHealth == 0) - this.OriginalMaxHealth = player.maxHealth; //grab the initial Health value + this.PlayerData.CurrentExp += this.Config.ExpForSleeping; + if (this.PlayerData.OriginalMaxHealth == 0) + this.PlayerData.OriginalMaxHealth = player.maxHealth; //grab the initial Health value - if (this.ClearModEffects) + if (this.PlayerData.CurrentLevel < this.Config.MaxLevel) { - this.LoadClearSettings(); - //This will run when the character goes to sleep. It will increase their sleeping skill. - player.maxHealth = this.OriginalMaxHealth; - this.ExpToNextLevel = this.Config.ExpToNextLevel; - this.CurrentExp = this.Config.CurrentExp; - this.CurrentLevelHealthBonus = 0; - this.OriginalMaxHealth = player.maxHealth; - this.BaseHealthBonus = 0; - this.CurrentLevel = 0; - this.Monitor.Log("BuildHealth Reset!"); - } - - if (!this.ClearModEffects && this.CurrentLevel < this.Config.MaxLevel) - { - while (this.CurrentExp >= this.ExpToNextLevel) + while (this.PlayerData.CurrentExp >= this.PlayerData.ExpToNextLevel) { - this.CurrentLevel += 1; - this.CurrentExp = this.CurrentExp - this.ExpToNextLevel; - this.ExpToNextLevel = - (this.Config.ExpCurve * this.ExpToNextLevel); + this.PlayerData.CurrentLevel += 1; + this.PlayerData.CurrentExp = this.PlayerData.CurrentExp - this.PlayerData.ExpToNextLevel; + this.PlayerData.ExpToNextLevel = + (this.Config.ExpCurve * this.PlayerData.ExpToNextLevel); player.maxHealth += this.Config.HealthIncreasePerLevel; - this.CurrentLevelHealthBonus += this.Config.HealthIncreasePerLevel; + this.PlayerData.CurrentLevelHealthBonus += this.Config.HealthIncreasePerLevel; } } - this.ClearModEffects = false; - this.WriteConfig(); + // save data + this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData); } - /// The method invoked after the player loads a save. - /// The event sender. - /// The event data. - public void SaveEvents_AfterLoaded(object sender, EventArgs e) + /// Migrate the legacy settings for the current player. + private void MigrateLegacyData() { - // initialise - this.LoadConfig(); - this.WriteConfig(); + // skip if no legacy data or new data already exists + if (!File.Exists(this.LegacyDataFilePath) || File.Exists(this.DataFilePath)) + return; - // grab initial health - var player = Game1.player; - if (this.OriginalMaxHealth == 0) - this.OriginalMaxHealth = player.maxHealth; - - // set max health - player.maxHealth = this.BaseHealthBonus + this.CurrentLevelHealthBonus + this.OriginalMaxHealth; - - // reset if needed - if (this.ClearModEffects) + // migrate to new file + try { - player.maxHealth = this.OriginalMaxHealth; - this.Monitor.Log("BuildHealth Reset!"); + string[] text = File.ReadAllLines(this.LegacyDataFilePath); + this.Helper.WriteJsonFile(this.DataFilePath, new PlayerData + { + CurrentLevel = Convert.ToInt32(text[3]), + CurrentExp = Convert.ToDouble(text[5]), + ExpToNextLevel = Convert.ToDouble(text[7]), + BaseHealthBonus = Convert.ToInt32(text[9]), + CurrentLevelHealthBonus = Convert.ToInt32(text[11]), + ClearModEffects = Convert.ToBoolean(text[14]), + OriginalMaxHealth = Convert.ToInt32(text[16]) + }); + + FileInfo file = new FileInfo(this.LegacyDataFilePath); + file.Delete(); + if (!file.Directory.EnumerateFiles().Any()) + file.Directory.Delete(); } - - // save config - this.LastHealth = Game1.player.maxHealth; - this.LoadConfig(); - this.WriteConfig(); - } - - /// Update the settings needed for from the latest config file on disk. - void LoadClearSettings() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.name}.txt"); - if (!File.Exists(path)) + catch (Exception ex) { - this.ClearModEffects = false; - this.OriginalMaxHealth = 0; - this.BaseHealthBonus = 0; + this.Monitor.Log($"Error migrating data from the legacy 'PlayerData' folder for the current player. Technical details:\n {ex}", LogLevel.Error); } - else - { - string[] text = File.ReadAllLines(path); - this.BaseHealthBonus = Convert.ToInt32(text[9]); - this.ClearModEffects = Convert.ToBoolean(text[14]); - this.OriginalMaxHealth = Convert.ToInt32(text[16]); - } - } - - /// Update based on the latest config file on disk. - private void UpdateClearSetting() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.name}.txt"); - if (!File.Exists(path)) - { - this.ClearModEffects = false; - this.OriginalMaxHealth = 0; - this.BaseHealthBonus = 0; - } - else - { - string[] text = File.ReadAllLines(path); - this.ClearModEffects = Convert.ToBoolean(text[14]); - } - } - - /// Load the configuration settings. - private void LoadConfig() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.name}.txr"); - if (!File.Exists(path)) - { - this.ExpToNextLevel = this.Config.ExpToNextLevel; - this.CurrentExp = this.Config.CurrentExp; - this.CurrentLevel = this.Config.CurrentLevel; - this.BaseHealthBonus = this.Config.BaseHealthBonus; - this.CurrentLevelHealthBonus = this.Config.CurrentLevelHealthBonus; - this.ClearModEffects = false; - this.OriginalMaxHealth = 0; - } - else - { - string[] text = File.ReadAllLines(path); - this.CurrentLevel = Convert.ToInt32(text[3]); - this.ExpToNextLevel = Convert.ToDouble(text[7]); - this.CurrentExp = Convert.ToDouble(text[5]); - this.BaseHealthBonus = Convert.ToInt32(text[9]); - this.CurrentLevelHealthBonus = Convert.ToInt32(text[11]); - this.ClearModEffects = Convert.ToBoolean(text[14]); - this.OriginalMaxHealth = Convert.ToInt32(text[16]); - } - } - - /// Save the configuration settings. - private void WriteConfig() - { - if (!Directory.Exists(Path.Combine(Helper.DirectoryPath, "PlayerData"))) - Directory.CreateDirectory(Path.Combine(Helper.DirectoryPath, "PlayerData")); - - string path = Path.Combine(Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.name}.txt"); - string[] text = new string[20]; - text[0] = "Player: Build Health Data. Modification can cause errors. Edit at your own risk."; - text[1] = "===================================================================================="; - - text[2] = "Player Current Level:"; - text[3] = this.CurrentLevel.ToString(); - - text[4] = "Player Current XP:"; - text[5] = this.CurrentExp.ToString(); - - text[6] = "Xp to next Level:"; - text[7] = this.ExpToNextLevel.ToString(); - - text[8] = "Initial Health Bonus:"; - text[9] = this.BaseHealthBonus.ToString(); - - text[10] = "Additional Health Bonus:"; - text[11] = this.CurrentLevelHealthBonus.ToString(); - - text[12] = "======================================================================================="; - text[13] = "RESET ALL MOD EFFECTS? This will effective start you back at square 1. Also good if you want to remove this mod."; - text[14] = this.ClearModEffects.ToString(); - text[15] = "OLD Health AMOUNT: This is the initial value of the Player's Health before this mod took over."; - text[16] = this.OriginalMaxHealth.ToString(); - - File.WriteAllLines(path, text); } } } diff --git a/GeneralMods/BuildHealth/BuildHealth.csproj b/GeneralMods/BuildHealth/BuildHealth.csproj index 40c8afd8..2cd434dc 100644 --- a/GeneralMods/BuildHealth/BuildHealth.csproj +++ b/GeneralMods/BuildHealth/BuildHealth.csproj @@ -30,10 +30,6 @@ 4 - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - False - @@ -43,6 +39,7 @@ + diff --git a/GeneralMods/BuildHealth/Framework/ModConfig.cs b/GeneralMods/BuildHealth/Framework/ModConfig.cs index 7fb1cf14..e0849f74 100644 --- a/GeneralMods/BuildHealth/Framework/ModConfig.cs +++ b/GeneralMods/BuildHealth/Framework/ModConfig.cs @@ -4,7 +4,7 @@ internal class ModConfig { /// The XP points needed to reach the next level. - public double ExpToNextLevel { get; set; } + public double ExpToNextLevel { get; set; } = 20; /// The player's current XP points. public double CurrentExp { get; set; } @@ -19,22 +19,22 @@ public int CurrentLevelHealthBonus { get; set; } /// The multiplier for the experience points to need to reach an endurance level relative to the previous one. - public double ExpCurve { get; set; } + public double ExpCurve { get; set; } = 1.15; /// The maximum endurance level the player can reach. - public int MaxLevel { get; set; } + public int MaxLevel { get; set; } = 100; /// The amount of stamina the player should gain for each endurance level. - public int HealthIncreasePerLevel { get; set; } + public int HealthIncreasePerLevel { get; set; } = 1; /// The experience points to gain for using a tool. - public int ExpForToolUse { get; set; } + public int ExpForToolUse { get; set; } = 1; /// The experience points to gain for eating or drinking. - public int ExpForEating { get; set; } + public int ExpForEating { get; set; } = 2; /// The experience points to gain for sleeping. - public int ExpForSleeping { get; set; } + public int ExpForSleeping { get; set; } = 10; /// The experience points to gain for collapsing for the day. public int ExpForCollapsing { get; set; } diff --git a/GeneralMods/BuildHealth/Framework/PlayerData.cs b/GeneralMods/BuildHealth/Framework/PlayerData.cs new file mode 100644 index 00000000..1e9cbb8e --- /dev/null +++ b/GeneralMods/BuildHealth/Framework/PlayerData.cs @@ -0,0 +1,27 @@ +namespace Omegasis.BuildHealth.Framework +{ + /// The data for the current player. + internal class PlayerData + { + /// The player's current endurance level. + public int CurrentLevel { get; set; } + + /// The player's current endurance XP points. + public double CurrentExp { get; set; } + + /// The XP points needed to reach the next endurance level. + public double ExpToNextLevel { get; set; } = 20; + + /// The initial health bonus to apply regardless of the player's endurance level, from the config file. + public int BaseHealthBonus { get; set; } + + /// The health points to add to the player's base health due to their current endurance level. + public int CurrentLevelHealthBonus { get; set; } + + /// Whether to reset all changes by the mod to the default values (i.e. start over). + public bool ClearModEffects { get; set; } + + /// The player's original maximum health value, excluding mod effects. + public int OriginalMaxHealth { get; set; } + } +} diff --git a/GeneralMods/BuildHealth/ReadMe.md b/GeneralMods/BuildHealth/ReadMe.md index aaed1534..6da29210 100644 --- a/GeneralMods/BuildHealth/ReadMe.md +++ b/GeneralMods/BuildHealth/ReadMe.md @@ -8,8 +8,8 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 2. Install [this mod from Nexus mods](http://www.nexusmods.com/stardewvalley/mods/445). 3. Run the game using SMAPI. -**NOTE:** to undo the mod's changes to your player, edit the `PlayerData\BuildEndurance_data_*.txt` -file and change the "RESET ALL MOD EFFECTS?" field to `True`. +**NOTE:** to undo the mod's changes to your player, edit the `data\*.json` file for your save and +change the "ClearModEffects" field to `true`. ## Usage You'll automatically get XP for... @@ -23,7 +23,7 @@ You'll automatically get XP for... Get enough XP, and your health will level up. -Edit `BuildHealthConfig.json` to configure the mod settings. +Edit `config.json` to configure the mod settings. ## Versions 1.0 @@ -37,4 +37,6 @@ Edit `BuildHealthConfig.json` to configure the mod settings. 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config & data files. +* Fixed issue where saves with the same name would overwrite each other's endurance level data. * Internal refactoring. diff --git a/GeneralMods/BuildHealth/packages.config b/GeneralMods/BuildHealth/packages.config index 31bc8030..058d0838 100644 --- a/GeneralMods/BuildHealth/packages.config +++ b/GeneralMods/BuildHealth/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs b/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs index 98074b93..91d89a06 100644 --- a/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs +++ b/GeneralMods/BuyBackCollectables/BuyBackCollectables.cs @@ -1,6 +1,4 @@ -using System; -using System.IO; -using Omegasis.BuyBackCollectables.Framework; +using Omegasis.BuyBackCollectables.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -13,11 +11,8 @@ namespace Omegasis.BuyBackCollectables /********* ** Properties *********/ - /// The key which shows the menu. - private string KeyBinding = "B"; - - /// The multiplier applied to the cost of buying back a collectable. - private double CostMultiplier = 3.0; + /// The mod configuration. + private ModConfig Config; /********* @@ -27,7 +22,8 @@ namespace Omegasis.BuyBackCollectables /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + this.Config = helper.ReadConfig(); + ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; } @@ -35,55 +31,13 @@ namespace Omegasis.BuyBackCollectables /********* ** Private methods *********/ - /// The method invoked after the player loads a save. - /// The event sender. - /// The event data. - public void SaveEvents_AfterLoad(object sender, EventArgs e) - { - this.LoadConfig(); - this.WriteConfig(); - } - /// The method invoked when the presses a keyboard button. /// The event sender. /// The event data. public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) { - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.KeyBinding) - Game1.activeClickableMenu = new BuyBackMenu(this.CostMultiplier); - } - - /// Load the configuration settings. - private void LoadConfig() - { - //loads the data to the variables upon loading the game. - string path = Path.Combine(Helper.DirectoryPath, "BuyBack_Config.txt"); - if (!File.Exists(path)) - { - this.KeyBinding = "B"; - this.CostMultiplier = 3.0; - } - else - { - string[] text = File.ReadAllLines(path); - this.KeyBinding = Convert.ToString(text[3]); - this.CostMultiplier = Convert.ToDouble(text[5]); - } - } - - /// Save the configuration settings. - private void WriteConfig() - { - //write all of my info to a text file. - string path = Path.Combine(Helper.DirectoryPath, "BuyBack_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: Buy Back Collections. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - text[2] = "Key binding"; - text[3] = this.KeyBinding; - text[4] = "Collectables Multiplier Cost: Sell Value * value listed below"; - text[5] = this.CostMultiplier.ToString(); - File.WriteAllLines(path, text); + if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) + Game1.activeClickableMenu = new BuyBackMenu(this.Config.CostMultiplier); } } } diff --git a/GeneralMods/BuyBackCollectables/BuyBackCollectables.csproj b/GeneralMods/BuyBackCollectables/BuyBackCollectables.csproj index 9832f159..9564b090 100644 --- a/GeneralMods/BuyBackCollectables/BuyBackCollectables.csproj +++ b/GeneralMods/BuyBackCollectables/BuyBackCollectables.csproj @@ -38,6 +38,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs b/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs new file mode 100644 index 00000000..deee9c28 --- /dev/null +++ b/GeneralMods/BuyBackCollectables/Framework/ModConfig.cs @@ -0,0 +1,12 @@ +namespace Omegasis.BuyBackCollectables.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the menu. + public string KeyBinding { get; set; } = "B"; + + /// The multiplier applied to the cost of buying back a collectable. + public double CostMultiplier { get; set; } = 3.0; + } +} diff --git a/GeneralMods/BuyBackCollectables/README.md b/GeneralMods/BuyBackCollectables/README.md index 9d736462..b563b853 100644 --- a/GeneralMods/BuyBackCollectables/README.md +++ b/GeneralMods/BuyBackCollectables/README.md @@ -9,8 +9,8 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 3. Run the game using SMAPI. ## Usage -Press `B` to open the buy-collectibles menu. Edit `BuildHealthConfig.json` to change the key or the -price markup. +Press `B` to open the buy-collectibles menu. Edit `config.json` to change the key or the price +markup. ## Versions 1.0: @@ -31,4 +31,5 @@ price markup. * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.4: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/CustomShopsRedux/CustomShopsRedux.cs b/GeneralMods/CustomShopsRedux/CustomShopsRedux.cs index 03a52693..f010c7d7 100644 --- a/GeneralMods/CustomShopsRedux/CustomShopsRedux.cs +++ b/GeneralMods/CustomShopsRedux/CustomShopsRedux.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.Xna.Framework; +using Omegasis.CustomShopsRedux.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -31,17 +32,17 @@ namespace Omegasis.CustomShopsRedux /********* ** Properties *********/ + /// The mod configuration. + private ModConfig Config; + /// The prices for the items to list. private readonly Dictionary ListPrices = new Dictionary(); - /// The folder path containing shop data files. - private string DataPath; - /// The configured shop options. private readonly List Options = new List(); - /// The key which shows the menu. - private string KeyBinding = "U"; + /// The folder path containing shop data files. + private string DataPath => Path.Combine(this.Helper.DirectoryPath, "Custom_Shops"); /********* @@ -51,7 +52,8 @@ namespace Omegasis.CustomShopsRedux /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterDayStarted; + this.Config = helper.ReadConfig(); + ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; } @@ -59,58 +61,20 @@ namespace Omegasis.CustomShopsRedux /********* ** Private methods *********/ - /// The method invoked after a new day starts. - /// The event sender. - /// The event data. - private void SaveEvents_AfterDayStarted(object sender, EventArgs e) - { - this.LoadConfig(); - this.WriteConfig(); - } - /// The method invoked when the presses a keyboard button. /// The event sender. /// The event data. private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) { - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.KeyBinding) + if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) this.OpenSelectFileMenu(); } - /// Load the configuration settings. - private void LoadConfig() - { - this.DataPath = Path.Combine(this.Helper.DirectoryPath, "Custom_Shops"); - Directory.CreateDirectory(this.DataPath); - - string path = Path.Combine(this.Helper.DirectoryPath, "Custom_Shop_Redux_Config.txt"); - if (!File.Exists(path)) - this.KeyBinding = "U"; - else - { - string[] text = File.ReadAllLines(path); - this.KeyBinding = Convert.ToString(text[3]); - } - } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(this.Helper.DirectoryPath, "Custom_Shop_Redux_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: Custom_Shop_Redux. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - - text[2] = "Key binding for saving anywhere. Press this key to save anywhere!"; - text[3] = this.KeyBinding; - - File.WriteAllLines(path, text); - } - /// Open the menu which lets the player choose a file. private void OpenSelectFileMenu() { // get mod folder + Directory.CreateDirectory(this.DataPath); DirectoryInfo modFolder = new DirectoryInfo(this.DataPath); this.Monitor.Log(modFolder.FullName); diff --git a/GeneralMods/CustomShopsRedux/CustomShopsRedux.csproj b/GeneralMods/CustomShopsRedux/CustomShopsRedux.csproj index 0c6e63ed..4e752f99 100644 --- a/GeneralMods/CustomShopsRedux/CustomShopsRedux.csproj +++ b/GeneralMods/CustomShopsRedux/CustomShopsRedux.csproj @@ -38,6 +38,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/CustomShopsRedux/Framework/ModConfig.cs b/GeneralMods/CustomShopsRedux/Framework/ModConfig.cs new file mode 100644 index 00000000..6c98157f --- /dev/null +++ b/GeneralMods/CustomShopsRedux/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.CustomShopsRedux.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the menu. + public string KeyBinding { get; set; } = "U"; + } +} diff --git a/GeneralMods/CustomShopsRedux/ReadMe.md b/GeneralMods/CustomShopsRedux/ReadMe.md index 44c5d022..f1053728 100644 --- a/GeneralMods/CustomShopsRedux/ReadMe.md +++ b/GeneralMods/CustomShopsRedux/ReadMe.md @@ -13,7 +13,7 @@ Make a custom shop by copying & editing one of the included custom shop template [Custom Shops Creation Tool](https://myscccd-my.sharepoint.com/personal/0703280_my_scccd_edu/_layouts/15/guestaccess.aspx?guestaccesstoken=ZYxG9Cs8S0q%2bxCVV3fEnc8MI4SfVfe07919rhFUhRiA%3d&docid=0e51dae1da2eb43988f77f5c54ec3ee58) (see [demo video](https://youtu.be/bSvNTZmgeZE)). -You can access the custom shops by pressing `U` in-game (configurable via `Custom_Shop_Redux_Config.txt`). +You can access the custom shops by pressing `U` in-game (configurable via `config.json`). Supported item types: @@ -60,4 +60,5 @@ Supported item types: 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs index 3b215154..0ec7bbda 100644 --- a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs +++ b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using Omegasis.DailyQuestAnywhere.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -13,8 +12,8 @@ namespace Omegasis.DailyQuestAnywhere /********* ** Properties *********/ - /// The key which shows the menu. - private string KeyBinding = "H"; + /// The mod configuration. + private ModConfig Config; /********* @@ -24,7 +23,8 @@ namespace Omegasis.DailyQuestAnywhere /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + this.Config = helper.ReadConfig(); + ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; } @@ -32,49 +32,13 @@ namespace Omegasis.DailyQuestAnywhere /********* ** Private methods *********/ - /// The method invoked after the player loads a save. - /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) - { - this.LoadConfig(); - this.WriteConfig(); - } - /// The method invoked when the presses a keyboard button. /// The event sender. /// The event data. private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) { - if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.KeyBinding) + if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding) Game1.activeClickableMenu = new Billboard(true); } - - /// Load the configuration settings. - void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "DailyQuest_Anywhere_Config.txt"); - if (!File.Exists(path)) - this.KeyBinding = "H"; - else - { - string[] text = File.ReadAllLines(path); - this.KeyBinding = Convert.ToString(text[3]); - } - } - - /// Save the configuration settings. - void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "DailyQuest_Anywhere_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: DailyQuest_Anywhere Info. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - - text[2] = "Key binding for opening the billboard for quests anywhere. Press this key to do so"; - text[3] = this.KeyBinding; - - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.csproj b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.csproj index 65963a04..90e083b7 100644 --- a/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.csproj +++ b/GeneralMods/DailyQuestAnywhere/DailyQuestAnywhere.csproj @@ -38,6 +38,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs new file mode 100644 index 00000000..8f1a2f0c --- /dev/null +++ b/GeneralMods/DailyQuestAnywhere/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.DailyQuestAnywhere.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the menu. + public string KeyBinding { get; set; } = "H"; + } +} diff --git a/GeneralMods/DailyQuestAnywhere/README.md b/GeneralMods/DailyQuestAnywhere/README.md index bd4e5393..349e0b4e 100644 --- a/GeneralMods/DailyQuestAnywhere/README.md +++ b/GeneralMods/DailyQuestAnywhere/README.md @@ -9,7 +9,7 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 3. Run the game using SMAPI. ## Usage -Press `H` to open the daily quest menu. Edit `DailyQuest_Anywhere_Config.txt` to change the key. +Press `H` to open the daily quest menu. Edit `config.json` to change the key. ## Versions 1.0: @@ -22,4 +22,5 @@ Press `H` to open the daily quest menu. Edit `DailyQuest_Anywhere_Config.txt` to * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.4: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/HappyBirthday/Framework/ModConfig.cs b/GeneralMods/HappyBirthday/Framework/ModConfig.cs new file mode 100644 index 00000000..db05d90f --- /dev/null +++ b/GeneralMods/HappyBirthday/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.HappyBirthday.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the menu. + public string KeyBinding { get; set; } = "O"; + } +} diff --git a/GeneralMods/HappyBirthday/Framework/PlayerData.cs b/GeneralMods/HappyBirthday/Framework/PlayerData.cs new file mode 100644 index 00000000..449f747c --- /dev/null +++ b/GeneralMods/HappyBirthday/Framework/PlayerData.cs @@ -0,0 +1,12 @@ +namespace Omegasis.HappyBirthday.Framework +{ + /// The data for the current player. + internal class PlayerData + { + /// The player's current birthday day. + public int BirthdayDay; + + /// The player's current birthday season. + public string BirthdaySeason; + } +} diff --git a/GeneralMods/HappyBirthday/HappyBirthday.cs b/GeneralMods/HappyBirthday/HappyBirthday.cs index 12363835..5ec3723c 100644 --- a/GeneralMods/HappyBirthday/HappyBirthday.cs +++ b/GeneralMods/HappyBirthday/HappyBirthday.cs @@ -18,11 +18,20 @@ namespace Omegasis.HappyBirthday /********* ** Properties *********/ - /// The key which shows the menu. - private string KeyBinding = "O"; + /// The relative path for the current player's data file. + private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json"); + + /// The absolute path for the current player's legacy data file. + private string LegacyDataFilePath => Path.Combine(this.Helper.DirectoryPath, "Player_Birthdays", $"HappyBirthday_{Game1.player.name}.txt"); + + /// The mod configuration. + private ModConfig Config; + + /// The data for the current player. + private PlayerData PlayerData; /// Whether the player has chosen a birthday. - private bool HasChosenBirthday; + private bool HasChosenBirthday => !string.IsNullOrEmpty(this.PlayerData.BirthdaySeason) && this.PlayerData.BirthdayDay != 0; /// The queue of villagers who haven't given a gift yet. private List VillagerQueue; @@ -38,18 +47,6 @@ namespace Omegasis.HappyBirthday //private Dictionary Dialogue; //private bool SeenEvent; - /// The name of the folder containing birthday data files. - private readonly string FolderName = "Player_Birthdays"; - - /// The full path to the folder containing birthday data files. - private string BirthdayFolderPath; - - /// The player's current birthday day. - public int BirthdayDay; - - /// The player's current birthday season. - public string BirthdaySeason; - /********* ** Public methods @@ -58,17 +55,16 @@ namespace Omegasis.HappyBirthday /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.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; this.VillagerQueue = new List(); this.PossibleBirthdayGifts = new List(); - this.BirthdayFolderPath = Path.Combine(Helper.DirectoryPath, this.FolderName); - - if (!Directory.Exists(this.BirthdayFolderPath)) - Directory.CreateDirectory(this.BirthdayFolderPath); } @@ -80,9 +76,6 @@ namespace Omegasis.HappyBirthday /// The event data. private void TimeEvents_AfterDayStarted(object sender, EventArgs e) { - if (this.HasChosenBirthday) - this.WriteBirthday(); - this.WriteConfig(); this.CheckedForBirthday = false; } @@ -92,8 +85,8 @@ namespace Omegasis.HappyBirthday private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e) { // show birthday selection menu - if (Context.IsPlayerFree && !this.HasChosenBirthday && e.KeyPressed.ToString() == this.KeyBinding) - Game1.activeClickableMenu = new BirthdayMenu(this.BirthdaySeason, this.BirthdayDay, this.SetBirthday); + if (Context.IsPlayerFree && !this.HasChosenBirthday && e.KeyPressed.ToString() == this.Config.KeyBinding) + Game1.activeClickableMenu = new BirthdayMenu(this.PlayerData.BirthdaySeason, this.PlayerData.BirthdayDay, this.SetBirthday); } /// The method invoked after the player loads a save. @@ -101,12 +94,21 @@ namespace Omegasis.HappyBirthday /// The event data. private void SaveEvents_AfterLoad(object sender, EventArgs e) { - this.LoadBirthday(); - this.LoadConfig(); + this.MigrateLegacyData(); + this.PlayerData = this.Helper.ReadJsonFile(this.DataFilePath) ?? new PlayerData(); //this.SeenEvent = false; //this.Dialogue = new Dictionary(); } + /// The method invoked just before the game updates the saves. + /// The event sender. + /// The event data. + private void SaveEvents_BeforeSave(object sender, EventArgs e) + { + if (this.HasChosenBirthday) + this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData); + } + /// The method invoked when the game updates (roughly 60 times per second). /// The event sender. /// The event data. @@ -159,9 +161,9 @@ namespace Omegasis.HappyBirthday } // ask for birthday date - if (string.IsNullOrEmpty(this.BirthdaySeason) || this.BirthdayDay == 0) + if (!this.HasChosenBirthday) { - Game1.activeClickableMenu = new BirthdayMenu(this.BirthdaySeason, this.BirthdayDay, this.SetBirthday); + Game1.activeClickableMenu = new BirthdayMenu(this.PlayerData.BirthdaySeason, this.PlayerData.BirthdayDay, this.SetBirthday); this.CheckedForBirthday = false; } } @@ -223,14 +225,6 @@ namespace Omegasis.HappyBirthday Game1.player.addItemByMenuIfNecessaryElseHoldUp(this.BirthdayGiftToReceive); this.BirthdayGiftToReceive = null; } - - // update settings - if (!this.HasChosenBirthday && !string.IsNullOrEmpty(this.BirthdaySeason) && this.BirthdayDay != 0) - { - this.WriteConfig(); - this.WriteBirthday(); - this.HasChosenBirthday = true; - } } /// Set the player's birtday/ @@ -238,8 +232,8 @@ namespace Omegasis.HappyBirthday /// The birthday day. private void SetBirthday(string season, int day) { - this.BirthdaySeason = season; - this.BirthdayDay = day; + this.PlayerData.BirthdaySeason = season; + this.PlayerData.BirthdayDay = day; } /// Reset the queue of villager names. @@ -495,63 +489,36 @@ namespace Omegasis.HappyBirthday private bool IsBirthday() { return - this.BirthdayDay == Game1.dayOfMonth - && this.BirthdaySeason == Game1.currentSeason; + this.PlayerData.BirthdayDay == Game1.dayOfMonth + && this.PlayerData.BirthdaySeason == Game1.currentSeason; } - /// Load the configuration settings. - private void LoadConfig() + /// Migrate the legacy settings for the current player. + private void MigrateLegacyData() { - string path = Path.Combine(Helper.DirectoryPath, "HappyBirthday_Config.txt"); - if (!File.Exists(path)) - this.KeyBinding = "O"; - else + // skip if no legacy data or new data already exists + if (!File.Exists(this.LegacyDataFilePath) || File.Exists(this.DataFilePath)) + return; + + // migrate to new file + try { - string[] text = File.ReadAllLines(path); - this.KeyBinding = Convert.ToString(text[3]); + string[] text = File.ReadAllLines(this.LegacyDataFilePath); + this.Helper.WriteJsonFile(this.DataFilePath, new PlayerData + { + BirthdaySeason = text[3], + BirthdayDay = Convert.ToInt32(text[5]) + }); + + FileInfo file = new FileInfo(this.LegacyDataFilePath); + file.Delete(); + if (!file.Directory.EnumerateFiles().Any()) + file.Directory.Delete(); } - } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "HappyBirthday_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: HappyBirthday Info. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - - text[2] = "Key binding for opening the birthday menu. Press this key to do so."; - text[3] = this.KeyBinding; - - File.WriteAllLines(path, text); - } - - /// Load the player's birthday from the config file. - private void LoadBirthday() - { - string path = Path.Combine(this.BirthdayFolderPath, $"HappyBirthday_{Game1.player.name}.txt"); - if (File.Exists(path)) + catch (Exception ex) { - string[] text = File.ReadAllLines(path); - this.BirthdaySeason = Convert.ToString(text[3]); - this.BirthdayDay = Convert.ToInt32(text[5]); + this.Monitor.Log($"Error migrating data from the legacy 'Player_Birthdays' folder for the current player. Technical details:\n {ex}", LogLevel.Error); } } - - /// Write the player's birthday to the config file. - private void WriteBirthday() - { - string path = Path.Combine(this.BirthdayFolderPath, $"HappyBirthday_{Game1.player.name}.txt"); - string[] text = new string[20]; - text[0] = "Player Info: Modifying these values could be considered cheating or an exploit. Edit at your own risk."; - text[1] = "===================================================================================="; - - text[2] = "Player's Birthday Season"; - text[3] = this.BirthdaySeason; - text[4] = "Player's Birthday Date"; - text[5] = this.BirthdayDay.ToString(); - - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/HappyBirthday/HappyBirthday.csproj b/GeneralMods/HappyBirthday/HappyBirthday.csproj index d62fdc25..a12d0621 100644 --- a/GeneralMods/HappyBirthday/HappyBirthday.csproj +++ b/GeneralMods/HappyBirthday/HappyBirthday.csproj @@ -40,6 +40,8 @@ Properties\GlobalAssemblyInfo.cs + + diff --git a/GeneralMods/HappyBirthday/README.md b/GeneralMods/HappyBirthday/README.md index 474d26e5..53f51b89 100644 --- a/GeneralMods/HappyBirthday/README.md +++ b/GeneralMods/HappyBirthday/README.md @@ -54,4 +54,6 @@ change based on your friendship with them. Check your mailbox for letters from y 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config & data files. +* Fixed issue where saves with the same name would overwrite each other's birthdays. * Internal refactoring. diff --git a/GeneralMods/MoreRain/Framework/ModConfig.cs b/GeneralMods/MoreRain/Framework/ModConfig.cs new file mode 100644 index 00000000..ce34e80f --- /dev/null +++ b/GeneralMods/MoreRain/Framework/ModConfig.cs @@ -0,0 +1,30 @@ +namespace Omegasis.MoreRain.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The chance out of 100 that it will rain tomorrow if it's spring. + public int SpringRainChance { get; set; } = 15; + + /// The chance out of 100 that it will storm tomorrow if it's spring. + public int SpringThunderChance { get; set; } = 5; + + /// The chance out of 100 that it will rain tomorrow if it's summer. + public int SummerRainChance { get; set; } = 5; + + /// The chance out of 100 that it will storm tomorrow if it's summer. + public int SummerThunderChance { get; set; } = 10; + + /// The chance out of 100 that it will rain tomorrow if it's fall. + public int FallRainChance { get; set; } = 15; + + /// The chance out of 100 that it will storm tomorrow if it's fall. + public int FallThunderChance { get; set; } = 5; + + /// The chance out of 100 that it will snow tomorrow if it's winter. + public int WinterSnowChance { get; set; } = 15; + + /// Whether to suppress verbose logging. + public bool SuppressLog { get; set; } = true; + } +} diff --git a/GeneralMods/MoreRain/MoreRain.cs b/GeneralMods/MoreRain/MoreRain.cs index 7cd5d313..f7613ce7 100644 --- a/GeneralMods/MoreRain/MoreRain.cs +++ b/GeneralMods/MoreRain/MoreRain.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.IO; +using Omegasis.MoreRain.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -16,29 +16,8 @@ namespace Omegasis.MoreRain /// 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 }; - /// The chance out of 100 that it will rain tomorrow if it's spring. - private int SpringRainChance; - - /// The chance out of 100 that it will storm tomorrow if it's spring. - private int SpringThunderChance; - - /// The chance out of 100 that it will rain tomorrow if it's summer. - private int SummerRainChance; - - /// The chance out of 100 that it will storm tomorrow if it's summer. - private int SummerThunderChance; - - /// The chance out of 100 that it will rain tomorrow if it's fall. - private int FallRainChance; - - /// The chance out of 100 that it will storm tomorrow if it's fall. - private int FallThunderChance; - - /// The chance out of 100 that it will snow tomorrow if it's winter. - private int WinterSnowChance; - - /// Whether to suppress verbose logging. - private bool SuppressLog; + /// The mod configuration. + private ModConfig Config; /********* @@ -48,9 +27,10 @@ namespace Omegasis.MoreRain /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.Config = helper.ReadConfig(); + SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; SaveEvents.BeforeSave += this.SaveEvents_BeforeSave; - this.LoadConfig(); } @@ -95,7 +75,7 @@ namespace Omegasis.MoreRain { case "spring": // set rain - if (chance <= this.SpringRainChance) + if (chance <= this.Config.SpringRainChance) { Game1.weatherForTomorrow = Game1.weather_rain; this.VerboseLog("It will rain tomorrow."); @@ -109,7 +89,7 @@ namespace Omegasis.MoreRain // set storm if (Game1.weatherForTomorrow == Game1.weather_rain) { - if (chance <= this.SpringThunderChance) + if (chance <= this.Config.SpringThunderChance) { Game1.weatherForTomorrow = Game1.weather_lightning; this.VerboseLog("It will be stormy tomorrow."); @@ -124,7 +104,7 @@ namespace Omegasis.MoreRain case "summer": // set rain - if (chance <= this.SummerRainChance) + if (chance <= this.Config.SummerRainChance) { Game1.weatherForTomorrow = Game1.weather_rain; this.VerboseLog("It will rain tomorrow."); @@ -138,7 +118,7 @@ namespace Omegasis.MoreRain // set storm if (Game1.weatherForTomorrow == Game1.weather_rain) { - if (chance <= this.SummerThunderChance) + if (chance <= this.Config.SummerThunderChance) { Game1.weatherForTomorrow = Game1.weather_lightning; this.VerboseLog("It will be stormy tomorrow."); @@ -154,7 +134,7 @@ namespace Omegasis.MoreRain case "fall": case "autumn": // set rain - if (chance <= this.FallRainChance) + if (chance <= this.Config.FallRainChance) { Game1.weatherForTomorrow = Game1.weather_rain; this.VerboseLog("It will rain tomorrow."); @@ -168,7 +148,7 @@ namespace Omegasis.MoreRain // set storm if (Game1.weatherForTomorrow == Game1.weather_rain) { - if (chance <= this.FallThunderChance) + if (chance <= this.Config.FallThunderChance) { Game1.weatherForTomorrow = Game1.weather_lightning; this.VerboseLog("It will be stormy tomorrow."); @@ -183,7 +163,7 @@ namespace Omegasis.MoreRain case "winter": // set snow - if (chance <= this.WinterSnowChance) + if (chance <= this.Config.WinterSnowChance) { Game1.weatherForTomorrow = Game1.weather_snow; this.VerboseLog("It will snow tomorrow."); @@ -197,91 +177,11 @@ namespace Omegasis.MoreRain } } - /// Save the configuration settings. - private void SaveConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "More_Rain_Config.txt"); - string[] text = new string[20]; - text[0] = "Player: More Rain Config. Feel free to edit."; - text[1] = "===================================================================================="; - text[2] = "Spring Rain chance: The chance out of 100 that it will rain tomorrow."; - text[3] = this.SpringRainChance.ToString(); - text[4] = "Spring Storm chance: The chance out of 100 that it will be stormy tomorrow."; - text[5] = this.SpringThunderChance.ToString(); - - text[6] = "Summer Rain chance: The chance out of 100 that it will rain tomorrow."; - text[7] = this.SummerRainChance.ToString(); - text[8] = "Summer Storm chance: The chance out of 100 that it will be stormy tomorrow."; - text[9] = this.SummerThunderChance.ToString(); - - text[10] = "Fall Rain chance: The chance out of 100 that it will rain tomorrow."; - text[11] = this.FallRainChance.ToString(); - text[12] = "Fall Storm chance: The chance out of 100 that it will be stormy tomorrow."; - text[13] = this.FallThunderChance.ToString(); - - text[14] = "Winter Snow chance: The chance out of 100 that it will rain tomorrow."; - text[15] = this.WinterSnowChance.ToString(); - - text[16] = "Supress Log: If true, the mod won't output any messages to the console."; - text[17] = this.SuppressLog.ToString(); - - File.WriteAllLines(path, text); - } - - /// Load the configuration settings. - private void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, $"More_Rain_Config.txt"); - if (!File.Exists(path)) - { - this.SpringRainChance = 15; - this.SummerRainChance = 5; - this.FallRainChance = 15; - this.WinterSnowChance = 15; - - this.SpringThunderChance = 5; - this.SummerThunderChance = 10; - this.FallThunderChance = 5; - - this.SuppressLog = true; - this.SaveConfig(); - } - else - { - try - { - string[] text = File.ReadAllLines(path); - this.SpringRainChance = Convert.ToInt32(text[3]); - this.SpringThunderChance = Convert.ToInt32(text[5]); - this.SummerRainChance = Convert.ToInt32(text[7]); - this.SummerThunderChance = Convert.ToInt32(text[9]); - this.FallRainChance = Convert.ToInt32(text[11]); - this.FallThunderChance = Convert.ToInt32(text[13]); - this.WinterSnowChance = Convert.ToInt32(text[15]); - this.SuppressLog = Convert.ToBoolean(text[17]); - } - catch (Exception) //something dun goofed - { - this.SpringRainChance = 15; - this.SummerRainChance = 5; - this.FallRainChance = 15; - this.WinterSnowChance = 15; - - this.SpringThunderChance = 5; - this.SummerThunderChance = 10; - this.FallThunderChance = 5; - - this.SuppressLog = true; - this.SaveConfig(); - } - } - } - /// Log a message if is false. /// The message to log. private void VerboseLog(string message) { - if (!this.SuppressLog) + if (!this.Config.SuppressLog) this.Monitor.Log(message); } } diff --git a/GeneralMods/MoreRain/MoreRain.csproj b/GeneralMods/MoreRain/MoreRain.csproj index 96853537..cf14ef9e 100644 --- a/GeneralMods/MoreRain/MoreRain.csproj +++ b/GeneralMods/MoreRain/MoreRain.csproj @@ -37,6 +37,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/MoreRain/README.md b/GeneralMods/MoreRain/README.md index f1677bae..a6fc798d 100644 --- a/GeneralMods/MoreRain/README.md +++ b/GeneralMods/MoreRain/README.md @@ -9,8 +9,8 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. 3. Run the game using SMAPI. ## Usage -Edit `More_Rain_Config.txt` to change the chance of rain, storms, or snow. Each value is a -percentage (0 to 100). +Edit `config.json` to change the chance of rain, storms, or snow. Each value is a percentage (0 +to 100). It won't rain on days where a wedding or a festival would take place. @@ -29,4 +29,5 @@ It won't rain on days where a wedding or a festival would take place. 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/MuseumRearranger/Framework/ModConfig.cs b/GeneralMods/MuseumRearranger/Framework/ModConfig.cs new file mode 100644 index 00000000..f14ea7ad --- /dev/null +++ b/GeneralMods/MuseumRearranger/Framework/ModConfig.cs @@ -0,0 +1,12 @@ +namespace Omegasis.MuseumRearranger.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The key which shows the museum rearranging menu. + public string ShowMenuKey { get; set; } = "R"; + + /// The key which toggles the inventory box when the menu is open. + public string ToggleInventoryKey { get; set; } = "T"; + } +} diff --git a/GeneralMods/MuseumRearranger/MuseumRearranger.cs b/GeneralMods/MuseumRearranger/MuseumRearranger.cs index 1685d6a1..98df59ee 100644 --- a/GeneralMods/MuseumRearranger/MuseumRearranger.cs +++ b/GeneralMods/MuseumRearranger/MuseumRearranger.cs @@ -1,6 +1,4 @@ -using System; -using System.IO; -using Omegasis.MuseumRearranger.Framework; +using Omegasis.MuseumRearranger.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -14,11 +12,8 @@ namespace Omegasis.MuseumRearranger /********* ** Properties *********/ - /// The key which shows the museum rearranging menu. - private string ShowMenuKey = "R"; - - /// The key which toggles the inventory box when the menu is open. - private string ToggleInventoryKey = "T"; + /// The mod configuration. + private ModConfig Config; /// The open museum menu (if any). private NewMuseumMenu OpenMenu; @@ -31,7 +26,8 @@ namespace Omegasis.MuseumRearranger /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + this.Config = helper.ReadConfig(); + ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; } @@ -48,7 +44,7 @@ namespace Omegasis.MuseumRearranger return; // open menu - if (e.KeyPressed.ToString() == this.ShowMenuKey) + if (e.KeyPressed.ToString() == this.Config.ShowMenuKey) { if (Game1.activeClickableMenu != null) return; @@ -59,48 +55,8 @@ namespace Omegasis.MuseumRearranger } // toggle inventory box - if (e.KeyPressed.ToString() == this.ToggleInventoryKey) + if (e.KeyPressed.ToString() == this.Config.ToggleInventoryKey) this.OpenMenu?.ToggleInventory(); } - - /// The method invoked after the player loads a save. - /// The event sender. - /// The event data. - private void SaveEvents_AfterLoad(object sender, EventArgs e) - { - this.LoadConfig(); - this.WriteConfig(); - } - - /// Load the configuration settings. - private void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Museum_Rearrange_Config.txt"); - if (!File.Exists(path)) - { - this.ShowMenuKey = "R"; - this.ToggleInventoryKey = "T"; - } - else - { - string[] text = File.ReadAllLines(path); - this.ShowMenuKey = Convert.ToString(text[3]); - this.ToggleInventoryKey = Convert.ToString(text[5]); - } - } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Museum_Rearrange_Config.txt"); - string[] text = new string[20]; - text[0] = "Config: Museum_Rearranger. Feel free to mess with these settings."; - text[1] = "===================================================================================="; - text[2] = "Key binding for rearranging the museum."; - text[3] = this.ShowMenuKey; - text[4] = "Key binding for showing the menu when rearranging the museum."; - text[5] = this.ToggleInventoryKey; - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/MuseumRearranger/MuseumRearranger.csproj b/GeneralMods/MuseumRearranger/MuseumRearranger.csproj index d551b058..ecaee172 100644 --- a/GeneralMods/MuseumRearranger/MuseumRearranger.csproj +++ b/GeneralMods/MuseumRearranger/MuseumRearranger.csproj @@ -39,6 +39,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/MuseumRearranger/ReadMe.md b/GeneralMods/MuseumRearranger/ReadMe.md index 6b6556a9..7d2bc0bc 100644 --- a/GeneralMods/MuseumRearranger/ReadMe.md +++ b/GeneralMods/MuseumRearranger/ReadMe.md @@ -10,7 +10,7 @@ Compatible with Stardew Valley 1.2+ on Linux, Mac, and Windows. ## Usage Press `R` while in the museum to open the rearranging menu. Press `T` while the menu is open to -toggle the inventory box. Edit `Museum_Rearrange_Config.txt` to change the keys. +toggle the inventory box. Edit `config.json` to change the keys. ## Versions 1.0: @@ -28,4 +28,5 @@ toggle the inventory box. Edit `Museum_Rearrange_Config.txt` to change the keys. * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.4: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/NightOwl/Framework/ModConfig.cs b/GeneralMods/NightOwl/Framework/ModConfig.cs new file mode 100644 index 00000000..d161c911 --- /dev/null +++ b/GeneralMods/NightOwl/Framework/ModConfig.cs @@ -0,0 +1,27 @@ +namespace Omegasis.NightOwl.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// Whether lighting should transition to day from 2am to 6am. If false, the world will stay dark until the player passes out or goes to bed. + public bool MorningLightTransition { get; set; } = true; + + /// Whether the player can stay up until 6am. + public bool StayUp { get; set; } = true; + + /// Whether to remove the mail received for collapsing like 'we charged X gold for your health fees'. + public bool SkipCollapseMail { get; set; } = true; + + /// Whether to restore the player's position after they collapse. + public bool KeepPositionAfterCollapse { get; set; } = true; + + /// Whether to restore the player's money after they collapse (i.e. prevent the automatic deduction). + public bool KeepMoneyAfterCollapse { get; set; } = true; + + /// Whether to keep stamina as-is after the player collapses. + public bool KeepHealthAfterCollapse { get; set; } = true; + + /// Whether to keep stamina as-is after the player collapses. + public bool KeepStaminaAfterCollapse { get; set; } = true; + } +} diff --git a/GeneralMods/NightOwl/NightOwl.cs b/GeneralMods/NightOwl/NightOwl.cs index 00927544..abc51c44 100644 --- a/GeneralMods/NightOwl/NightOwl.cs +++ b/GeneralMods/NightOwl/NightOwl.cs @@ -2,7 +2,7 @@ using System.IO; using System.Linq; using Microsoft.Xna.Framework; -using Newtonsoft.Json; +using Omegasis.NightOwl.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -24,6 +24,9 @@ namespace Omegasis.NightOwl /********* ** Properties *********/ + /// The mod configuration. + private ModConfig Config; + /**** ** Context ****/ @@ -57,29 +60,6 @@ namespace Omegasis.NightOwl /// The player's health before they collapsed. private int PreCollapseHealth; - /**** - ** Settings - ****/ - /// Whether lighting should transition to day from 2am to 6am. If false, the world will stay dark until the player passes out or goes to bed. - private bool MorningLightTransition; - - /// Whether the player can stay up until 6am. - private bool StayUp; - - /// Whether to remove the mail received for collapsing like 'we charged X gold for your health fees'. - private bool SkipCollapseMail; - - /// Whether to restore the player's position after they collapse. - private bool KeepPositionAfterCollapse; - - /// Whether to restore the player's money after they collapse (i.e. prevent the automatic deduction). - private bool KeepMoneyAfterCollapse; - - /// Whether to keep stamina as-is after the player collapses. - private bool KeepHealthAfterCollapse; - - /// Whether to keep stamina as-is after the player collapses. - private bool KeepStaminaAfterCollapse; /********* @@ -89,6 +69,8 @@ namespace Omegasis.NightOwl /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.Config = helper.ReadConfig(); + TimeEvents.TimeOfDayChanged += this.TimeEvents_TimeOfDayChanged; TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; @@ -107,7 +89,7 @@ namespace Omegasis.NightOwl try { // reset position after collapse - if (Context.IsWorldReady && this.JustStartedNewDay && this.KeepPositionAfterCollapse) + if (Context.IsWorldReady && this.JustStartedNewDay && this.Config.KeepPositionAfterCollapse) { if (this.PreCollapseMap != null) Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); @@ -129,8 +111,6 @@ namespace Omegasis.NightOwl /// The event data. public void SaveEvents_AfterLoad(object sender, EventArgs e) { - this.LoadConfig(); - this.WriteConfig(); this.IsUpLate = false; this.JustStartedNewDay = false; this.JustCollapsed = false; @@ -144,8 +124,6 @@ namespace Omegasis.NightOwl try { // reset data - this.LoadConfig(); - this.WriteConfig(); this.IsUpLate = false; Game1.farmerShouldPassOut = false; @@ -154,18 +132,18 @@ namespace Omegasis.NightOwl { this.ShouldResetPlayerAfterCollapseNow = false; - if (this.KeepStaminaAfterCollapse) + if (this.Config.KeepStaminaAfterCollapse) Game1.player.stamina = this.PreCollapseStamina; - if (this.KeepHealthAfterCollapse) + if (this.Config.KeepHealthAfterCollapse) Game1.player.health = this.PreCollapseHealth; - if (this.KeepMoneyAfterCollapse) + if (this.Config.KeepMoneyAfterCollapse) Game1.player.money = this.PreCollapseMoney; - if (this.KeepPositionAfterCollapse) + if (this.Config.KeepPositionAfterCollapse) Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); } // delete annoying charge messages (if only I could do this with mail IRL) - if (this.SkipCollapseMail) + if (this.Config.SkipCollapseMail) { string[] validMail = Game1.mailbox .Where(p => !p.Contains("passedOut")) @@ -196,14 +174,14 @@ namespace Omegasis.NightOwl try { // transition morning light more realistically - if (this.MorningLightTransition && Game1.timeOfDay > 400 && Game1.timeOfDay < 600) + if (this.Config.MorningLightTransition && Game1.timeOfDay > 400 && Game1.timeOfDay < 600) { float colorMod = (1300 - Game1.timeOfDay) / 1000f; Game1.outdoorLight = Game1.ambientLight * colorMod; } // transition to next morning - if (this.StayUp && Game1.timeOfDay == 2550) + if (this.Config.StayUp && Game1.timeOfDay == 2550) { Game1.isRaining = false; // remove rain, otherwise lighting gets screwy Game1.updateWeatherIcon(); @@ -236,83 +214,24 @@ namespace Omegasis.NightOwl } } - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Night_Owl_Config_.txt"); - string[] text = new string[20]; - - text[0] = "Player: Night Owl Config. Feel free to edit."; - text[1] = "===================================================================================="; - text[2] = "Whether you can stay up until 6am."; - text[3] = this.StayUp.ToString(); - text[4] = "Whether the lighting should transition to daytime from 2am to 6am. Setting this to false will keep the world dark until the player passes out or goes to bed."; - text[5] = this.MorningLightTransition.ToString(); - text[6] = "Whether to keep your position as-is after you collapse at 6am. If false, you'll warp back home."; - text[7] = this.KeepPositionAfterCollapse.ToString(); - text[8] = "Whether to prevent money from being deducted after you collapse at 6am."; - text[9] = this.KeepMoneyAfterCollapse.ToString(); - text[10] = "Whether to keep your stamina as-is after you collapse at 6am."; - text[11] = this.KeepStaminaAfterCollapse.ToString(); - text[12] = "Whether to keep your health as-is after you collapse at 6am."; - text[13] = this.KeepHealthAfterCollapse.ToString(); - text[14] = "Whether to remove the mail you receive for collapsing like 'we charged X gold for your health fees'."; - text[15] = this.SkipCollapseMail.ToString(); - - File.WriteAllLines(path, text); - } - - /// Load the configuration settings. - private void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Night_Owl_Config_.txt"); - if (!File.Exists(path)) - { - this.MorningLightTransition = true; - this.KeepPositionAfterCollapse = true; - this.StayUp = true; - - this.KeepHealthAfterCollapse = true; - this.KeepStaminaAfterCollapse = true; - this.SkipCollapseMail = true; - this.KeepMoneyAfterCollapse = true; - } - else - { - string[] text = File.ReadAllLines(path); - this.StayUp = Convert.ToBoolean(text[3]); - this.MorningLightTransition = Convert.ToBoolean(text[5]); - this.KeepPositionAfterCollapse = Convert.ToBoolean(text[7]); - this.KeepMoneyAfterCollapse = Convert.ToBoolean(text[9]); - this.KeepStaminaAfterCollapse = Convert.ToBoolean(text[11]); - this.KeepHealthAfterCollapse = Convert.ToBoolean(text[13]); - this.SkipCollapseMail = text[15] == "" || Convert.ToBoolean(text[15]); - } - } - /// Write the current mod state to the error log file. private void WriteErrorLog() { - try + var state = new { - JsonSerializer serializer = new JsonSerializer - { - NullValueHandling = NullValueHandling.Ignore, - TypeNameHandling = TypeNameHandling.All, - Formatting = Formatting.Indented, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore - }; - string path = Path.Combine(this.Helper.DirectoryPath, "Error_Logs", "Mod_State.json"); - using (StreamWriter sw = new StreamWriter(path)) - { - using (JsonWriter writer2 = new JsonTextWriter(sw)) - serializer.Serialize(writer2, this); - } - } - catch (Exception ex) - { - this.Monitor.Log(ex.ToString(), LogLevel.Error); - } + this.Config, + this.IsUpLate, + this.ShouldResetPlayerAfterCollapseNow, + this.JustStartedNewDay, + this.JustCollapsed, + this.PreCollapseMap, + this.PreCollapseTile, + this.PreCollapseMoney, + this.PreCollapseStamina, + this.PreCollapseHealth + }; + string path = Path.Combine(this.Helper.DirectoryPath, "Error_Logs", "Mod_State.json"); + this.Helper.WriteJsonFile(path, state); } } } diff --git a/GeneralMods/NightOwl/NightOwl.csproj b/GeneralMods/NightOwl/NightOwl.csproj index 0c6927b2..828a89a9 100644 --- a/GeneralMods/NightOwl/NightOwl.csproj +++ b/GeneralMods/NightOwl/NightOwl.csproj @@ -30,10 +30,6 @@ 4 - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - False - @@ -41,6 +37,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/NightOwl/README.md b/GeneralMods/NightOwl/README.md index c1b25ba6..ebbe9259 100644 --- a/GeneralMods/NightOwl/README.md +++ b/GeneralMods/NightOwl/README.md @@ -14,7 +14,7 @@ Simply stay up past 2am, and you won't collapse. The lighting will gradually bri rises. At 6am you'll temporarily collapse so the game can save, but you won't lose anything and you'll stay where you are. -Edit the `Night_Owl_Config_.txt` to change the mod settings. +Edit the `config.json` to change the mod settings. ## Versions 1.0: @@ -25,4 +25,5 @@ Edit the `Night_Owl_Config_.txt` to change the mod settings. 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/NightOwl/packages.config b/GeneralMods/NightOwl/packages.config index 31bc8030..058d0838 100644 --- a/GeneralMods/NightOwl/packages.config +++ b/GeneralMods/NightOwl/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/GeneralMods/SaveAnywhere/SaveAnywhere.cs b/GeneralMods/SaveAnywhere/SaveAnywhere.cs index 39e70368..3e21f552 100644 --- a/GeneralMods/SaveAnywhere/SaveAnywhere.cs +++ b/GeneralMods/SaveAnywhere/SaveAnywhere.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using Omegasis.SaveAnywhere.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; diff --git a/GeneralMods/SaveBackup/Framework/ModConfig.cs b/GeneralMods/SaveBackup/Framework/ModConfig.cs new file mode 100644 index 00000000..1612c9f8 --- /dev/null +++ b/GeneralMods/SaveBackup/Framework/ModConfig.cs @@ -0,0 +1,9 @@ +namespace Omegasis.SaveBackup.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The number of save backups to keep for each type. + public int SaveCount { get; set; } = 30; + } +} diff --git a/GeneralMods/SaveBackup/ReadMe.md b/GeneralMods/SaveBackup/ReadMe.md index a3477e59..4236f1c1 100644 --- a/GeneralMods/SaveBackup/ReadMe.md +++ b/GeneralMods/SaveBackup/ReadMe.md @@ -24,4 +24,5 @@ configure that. 1.3: * Updated for SMAPI 2.0. +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/SaveBackup/SaveBackup.cs b/GeneralMods/SaveBackup/SaveBackup.cs index d8e44999..b10f0878 100644 --- a/GeneralMods/SaveBackup/SaveBackup.cs +++ b/GeneralMods/SaveBackup/SaveBackup.cs @@ -2,6 +2,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using Omegasis.SaveBackup.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -25,8 +26,8 @@ namespace Omegasis.SaveBackup /// The folder path containing nightly backups of the save. private static readonly string NightlyBackupsPath = Path.Combine(SaveBackup.AppDataPath, "Backed_Up_Saves", "Nightly_InGame_Saves"); - /// The number of save backups to keep for each type. - private int SaveCount = 30; + /// The mod configuration. + private ModConfig Config; /********* @@ -36,8 +37,7 @@ namespace Omegasis.SaveBackup /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - this.LoadConfig(); - this.WriteConfig(); + this.Config = helper.ReadConfig(); this.BackupSaves(SaveBackup.PrePlayBackupsPath); @@ -68,33 +68,9 @@ namespace Omegasis.SaveBackup new DirectoryInfo(folderPath) .EnumerateFiles() .OrderByDescending(f => f.CreationTime) - .Skip(this.SaveCount) + .Skip(this.Config.SaveCount) .ToList() .ForEach(file => file.Delete()); } - - /// Load the configuration settings. - private void LoadConfig() - { - var path = Path.Combine(Helper.DirectoryPath, "AutoBackup_data.txt"); - if (File.Exists(path)) - { - string[] text = File.ReadAllLines(path); - this.SaveCount = Convert.ToInt32(text[3]); - } - } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "AutoBackup_data.txt"); - string[] text = new string[20]; - text[0] = "Player: AutoBackup Config:"; - text[1] = "===================================================================================="; - text[2] = "Number of Backups to Keep:"; - text[3] = this.SaveCount.ToString(); - - File.WriteAllLines(path, text); - } } } diff --git a/GeneralMods/SaveBackup/SaveBackup.csproj b/GeneralMods/SaveBackup/SaveBackup.csproj index c9ddd410..4989f701 100644 --- a/GeneralMods/SaveBackup/SaveBackup.csproj +++ b/GeneralMods/SaveBackup/SaveBackup.csproj @@ -39,6 +39,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/StardewSymphony/Framework/ModConfig.cs b/GeneralMods/StardewSymphony/Framework/ModConfig.cs new file mode 100644 index 00000000..e72b39d3 --- /dev/null +++ b/GeneralMods/StardewSymphony/Framework/ModConfig.cs @@ -0,0 +1,18 @@ +namespace Omegasis.StardewSymphony.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// The minimum delay (in milliseconds) to pass before playing the next song, or 0 for no delay. + public int MinSongDelay { get; set; } = 10000; + + /// The maximum delay (in milliseconds) to pass before playing the next song, or 0 for no delay. + public int MaxSongDelay { get; set; } = 30000; + + /// Whether to disable ambient rain audio when music is playing. If false, plays ambient rain audio alongside whatever songs are set in rain music. + public bool SilentRain { get; set; } + + /// Whether to play seasonal music from the music packs, instead of defaulting to the Stardew Valley Soundtrack. + public bool PlaySeasonalMusic { get; set; } = true; + } +} diff --git a/GeneralMods/StardewSymphony/README.md b/GeneralMods/StardewSymphony/README.md index 29e804da..103b9766 100644 --- a/GeneralMods/StardewSymphony/README.md +++ b/GeneralMods/StardewSymphony/README.md @@ -34,4 +34,5 @@ This won't mute the music for in-game events or festivals. 1.4: * Updated for SMAPI 2.0. +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/StardewSymphony/StardewSymphony.cs b/GeneralMods/StardewSymphony/StardewSymphony.cs index a2152ed7..8d1a83e8 100644 --- a/GeneralMods/StardewSymphony/StardewSymphony.cs +++ b/GeneralMods/StardewSymphony/StardewSymphony.cs @@ -25,6 +25,9 @@ namespace Omegasis.StardewSymphony /********* ** Properties *********/ + /// The mod configuration. + private ModConfig Config; + /// All of the music/soundbanks and their locations. private IList MasterList = new List(); @@ -60,21 +63,6 @@ namespace Omegasis.StardewSymphony /// A timer used to create random pauses between songs. private Timer SongDelayTimer = new Timer(); - /**** - ** Config - ****/ - /// The minimum delay (in milliseconds) to pass before playing the next song, or 0 for no delay. - private int MinSongDelay; - - /// The maximum delay (in milliseconds) to pass before playing the next song, or 0 for no delay. - private int MaxSongDelay; - - /// Whether to disable ambient rain audio when music is playing. If false, plays ambient rain audio alongside whatever songs are set in rain music. - private bool SilentRain; - - /// Whether to play seasonal music from the music packs, instead of defaulting to the Stardew Valley Soundtrack. - private bool PlaySeasonalMusic; - /********* ** Public methods @@ -83,6 +71,7 @@ namespace Omegasis.StardewSymphony /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.Config = helper.ReadConfig(); this.HexProcessor = new MusicHexProcessor(this.MasterList, this.Reset); SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; @@ -122,7 +111,7 @@ namespace Omegasis.StardewSymphony return; // replace with festival if (Game1.eventUp) return; // replace with event music - if (Game1.isRaining && !this.SilentRain) + if (Game1.isRaining && !this.Config.SilentRain) return; // play the rain ambience soundtrack Game1.currentSong.Stop(AudioStopOptions.Immediate); //stop the normal songs from playing over the new songs @@ -135,9 +124,6 @@ namespace Omegasis.StardewSymphony private void TimeEvents_AfterDayStarted(object sender, EventArgs e) { this.StopSound(); //if my music player is called and I forget to clean up sound before hand, kill the old sound. - this.LoadConfig(); - this.WriteConfig(); - this.SelectMusic(); } @@ -146,10 +132,6 @@ namespace Omegasis.StardewSymphony /// The event data. private void SaveEvents_AfterLoad(object sender, EventArgs e) { - // init config - this.LoadConfig(); - this.WriteConfig(); - // init context this.Random = new Random(); this.MasterList = new List(); @@ -192,7 +174,7 @@ namespace Omegasis.StardewSymphony { // reset timer this.SongDelayTimer.Dispose(); - this.SongDelayTimer = new Timer(this.Random.Next(this.MinSongDelay, this.MaxSongDelay)); + this.SongDelayTimer = new Timer(this.Random.Next(this.Config.MinSongDelay, this.Config.MaxSongDelay)); // start timer this.SongDelayTimer.Elapsed += (sender, args) => @@ -364,7 +346,7 @@ namespace Omegasis.StardewSymphony if (this.HasNoMusic) //if there is valid music playing { - if (!this.PlaySeasonalMusic) + if (!this.Config.PlaySeasonalMusic) return; if (this.CurrentSong != null && this.CurrentSong.IsPlaying) @@ -1185,49 +1167,5 @@ namespace Omegasis.StardewSymphony Game1.waveBank = this.DefaultWavebank; Game1.soundBank = this.DefaultSoundbank; } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Music_Expansion_Config.txt"); - string[] text = new string[20]; - text[0] = "Player: Stardew Valley Music Expansion Config. Feel free to edit."; - text[1] = "===================================================================================="; - - text[2] = "Minimum delay time: This is the minimal amout of time(in miliseconds!!!) that will pass before another song will play. 0 means a song will play immediately, 1000 means a second will pass, etc. Used in RNG to determine a random delay between songs."; - text[3] = this.MinSongDelay.ToString(); - - text[4] = "Maximum delay time: This is the maximum amout of time(in miliseconds!!!) that will pass before another song will play. 0 means a song will play immediately, 1000 means a second will pass, etc. Used in RNG to determine a random delay between songs."; - text[5] = this.MaxSongDelay.ToString(); - - text[6] = "Silent rain? Setting this value to false plays the default ambient rain music along side whatever songs are set in rain music. Setting this to true will disable the ambient rain music. It's up to the soundpack creators wither or not they want to mix their music with rain prior to loading it in here."; - text[7] = this.SilentRain.ToString(); - - text[8] = "Seasonal_Music? Setting this value to true will play the seasonal music from the music packs instead of defaulting to the Stardew Valley Soundtrack."; - text[9] = this.PlaySeasonalMusic.ToString(); - - File.WriteAllLines(path, text); - } - - /// Load the configuration settings. - void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "Music_Expansion_Config.txt"); - if (!File.Exists(path)) - { - this.MinSongDelay = 10000; - this.MaxSongDelay = 30000; - this.SilentRain = false; - this.PlaySeasonalMusic = true; - } - else - { - string[] text = File.ReadAllLines(path); - this.MinSongDelay = Convert.ToInt32(text[3]); - this.MaxSongDelay = Convert.ToInt32(text[5]); - this.SilentRain = Convert.ToBoolean(text[7]); - this.PlaySeasonalMusic = Convert.ToBoolean(text[9]); - } - } } } diff --git a/GeneralMods/StardewSymphony/StardewSymphony.csproj b/GeneralMods/StardewSymphony/StardewSymphony.csproj index 14be478a..b91e0ba4 100644 --- a/GeneralMods/StardewSymphony/StardewSymphony.csproj +++ b/GeneralMods/StardewSymphony/StardewSymphony.csproj @@ -37,6 +37,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/GeneralMods/TimeFreeze/Framework/ModConfig.cs b/GeneralMods/TimeFreeze/Framework/ModConfig.cs new file mode 100644 index 00000000..4b3cdde3 --- /dev/null +++ b/GeneralMods/TimeFreeze/Framework/ModConfig.cs @@ -0,0 +1,12 @@ +namespace Omegasis.TimeFreeze.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /// Whether time should be unfrozen while the player is swimming. + public bool PassTimeWhileSwimming { get; set; } = true; + + /// Whether time should be unfrozen while the player is swimming in the vanilla bathhouse. + public bool PassTimeWhileSwimmingInBathhouse { get; set; } = true; + } +} diff --git a/GeneralMods/TimeFreeze/README.md b/GeneralMods/TimeFreeze/README.md index e2c8ca9a..41052070 100644 --- a/GeneralMods/TimeFreeze/README.md +++ b/GeneralMods/TimeFreeze/README.md @@ -20,4 +20,5 @@ but you can edit `ModConfig.txt` to change that. * Updated to Stardew Valley 1.2 and SMAPI 1.12. 1.2: +* Switched to standard JSON config file. * Internal refactoring. diff --git a/GeneralMods/TimeFreeze/TimeFreeze.cs b/GeneralMods/TimeFreeze/TimeFreeze.cs index 454ad299..049fac91 100644 --- a/GeneralMods/TimeFreeze/TimeFreeze.cs +++ b/GeneralMods/TimeFreeze/TimeFreeze.cs @@ -1,5 +1,5 @@ using System; -using System.IO; +using Omegasis.TimeFreeze.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley; @@ -13,11 +13,8 @@ namespace Omegasis.TimeFreeze /********* ** Properties *********/ - /// Whether time should be unfrozen while the player is swimming. - private bool PassTimeWhileSwimming = true; - - /// Whether time should be unfrozen while the player is swimming in the vanilla bathhouse. - private bool PassTimeWhileSwimmingInBathhouse = true; + /// The mod configuration. + private ModConfig Config; /********* @@ -27,8 +24,9 @@ namespace Omegasis.TimeFreeze /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + this.Config = helper.ReadConfig(); + GameEvents.UpdateTick += this.GameEvents_UpdateTick; - this.LoadConfig(); } /********* @@ -55,44 +53,12 @@ namespace Omegasis.TimeFreeze return false; if (player.swimming) { - if (this.PassTimeWhileSwimmingInBathhouse && location is BathHousePool) + if (this.Config.PassTimeWhileSwimmingInBathhouse && location is BathHousePool) return false; - if (this.PassTimeWhileSwimming) + if (this.Config.PassTimeWhileSwimming) return false; } return true; } - - /// Save the configuration settings. - private void WriteConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "ModConfig.txt"); - string[] text = new string[6]; - text[0] = "Player: TimeFreeze Config"; - text[1] = "===================================================================================="; - text[2] = "Whether to unfreeze time while swimming in the vanilla bathhouse."; - text[3] = this.PassTimeWhileSwimmingInBathhouse.ToString(); - text[4] = "Whether to unfreeze time while swimming anywhere."; - text[5] = this.PassTimeWhileSwimming.ToString(); - File.WriteAllLines(path, text); - } - - /// Load the configuration settings. - private void LoadConfig() - { - string path = Path.Combine(Helper.DirectoryPath, "ModConfig.txt"); - if (!File.Exists(path)) - { - this.PassTimeWhileSwimming = true; - this.PassTimeWhileSwimmingInBathhouse = true; - this.WriteConfig(); - } - else - { - string[] text = File.ReadAllLines(path); - this.PassTimeWhileSwimming = Convert.ToBoolean(text[3]); - this.PassTimeWhileSwimmingInBathhouse = Convert.ToBoolean(text[5]); - } - } } } diff --git a/GeneralMods/TimeFreeze/TimeFreeze.csproj b/GeneralMods/TimeFreeze/TimeFreeze.csproj index 56f71209..f8bd1977 100644 --- a/GeneralMods/TimeFreeze/TimeFreeze.csproj +++ b/GeneralMods/TimeFreeze/TimeFreeze.csproj @@ -37,6 +37,7 @@ Properties\GlobalAssemblyInfo.cs +