From a71aeb5147399233f675eb82d7a00c6dce7c609a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 29 Jul 2017 19:59:16 -0400 Subject: [PATCH] refactor NightOwl This commit formats/documents/simplifies code, standardises naming conventions, removes redundant code, etc. --- GeneralMods/NightOwl/Class1.cs | 584 ++++++++++++----------------- GeneralMods/NightOwl/manifest.json | 2 +- 2 files changed, 233 insertions(+), 353 deletions(-) diff --git a/GeneralMods/NightOwl/Class1.cs b/GeneralMods/NightOwl/Class1.cs index 15350ea7..8c9d33c5 100644 --- a/GeneralMods/NightOwl/Class1.cs +++ b/GeneralMods/NightOwl/Class1.cs @@ -1,13 +1,13 @@ using System; -using System.Collections.Generic; using System.IO; +using System.Linq; +using Microsoft.Xna.Framework; using Newtonsoft.Json; using StardewModdingAPI; +using StardewModdingAPI.Events; using StardewValley; /*TODO: -*/ -/* Issues: -Mail can't be wiped without destroying all mail. -Lighting transition does not work if it is raining. @@ -15,431 +15,311 @@ Issues: -transition still doesnt work. However atleast it is dark now. -Known glitched - */ - - - namespace Omegasis.NightOwl { + /// The mod entry point. public class Class1 : Mod { - int player_x; - int player_y; - string prior_map; + /********* + ** Properties + *********/ + /**** + ** Context + ****/ + /// Whether the player loaded a save. + private bool IsGameLoaded; - bool reset_check; - bool was_raining; - bool time_reset; - int prior_money; - int post_money; - float pre_stam; - int pre_health; + /// Whether the player stayed up all night. + private bool IsUpLate; - bool lighting_transition; //if true transition happens. If false, game starts out bright at 2AM. Good to remove that awkward change from dark to bright. - bool warp; - bool stay_up; + /// Whether the player should be reset to their pre-collapse details for the morning transition on the next update. + private bool ShouldResetPlayerAfterCollapseNow; - bool wipe_mail; - bool protect_money; - bool persistant_health; - bool persistant_stamina; + /// Whether the player just started a new day. + private bool JustStartedNewDay; - bool game_loaded; + /// Whether the player just collapsed for the morning transition. + private bool JustCollapsed; - bool once; - bool up_late; + /**** + ** Pre-collapse state + ****/ + /// The player's location name before they collapsed. + private string PreCollapseMap; - bool first_check; + /// The player's tile position before they collapsed. + private Point PreCollapseTile; - bool warped_check; + /// The player's money before they collapsed. + private int PreCollapseMoney; - bool super_map_warping_check; + /// The player's stamina before they collapsed. + private float PreCollapseStamina; - + /// The player's health before they collapsed. + private int PreCollapseHealth; - public static string ModPath; - public static string Error_Path; + /**** + ** 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; + + + /********* + ** Public methods + *********/ + /// The mod entry point, called after the mod is first loaded. + /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - StardewModdingAPI.Events.TimeEvents.TimeOfDayChanged += TimeEvents_TimeOfDayChanged; - StardewModdingAPI.Events.TimeEvents.DayOfMonthChanged += TimeEvents_DayOfMonthChanged; - StardewModdingAPI.Events.SaveEvents.AfterLoad += PlayerEvents_LoadedGame; - StardewModdingAPI.Events.GameEvents.FourthUpdateTick += GameEvents_FourthUpdateTick; - ModPath =Helper.DirectoryPath; - Error_Path = Path.Combine(ModPath, "Error_Logs"); + TimeEvents.TimeOfDayChanged += this.TimeEvents_TimeOfDayChanged; + TimeEvents.DayOfMonthChanged += this.TimeEvents_DayOfMonthChanged; + SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; + GameEvents.FourthUpdateTick += this.GameEvents_FourthUpdateTick; } + /********* + ** Private methods + *********/ + /// The method invoked every fourth game update (roughly 15 times per second). + /// The event sender. + /// The event data. public void GameEvents_FourthUpdateTick(object sender, EventArgs e) { - /* - IMPLEMENT TRY CATCH SYSTEM HERE; - - */ try { - - if (Game1.eventUp == true) return; - if (game_loaded == false) return; - - if (Game1.timeOfDay == 600) - { - if (once==true) + // reset position after collapse + if (!Game1.eventUp && this.IsGameLoaded && this.JustStartedNewDay && this.KeepPositionAfterCollapse) { - // Log.AsyncM("NEW MONEY" + Game1.player.money); - // Game1.player.money = Game1.player.money + post_money; - once = false; - } - - } - if (warped_check == false) - { - if (warp == true) - { - Monitor.Log("Warping!!!"); - if (prior_map == null) - { - warped_check = true; - super_map_warping_check = true; - return; - } - Game1.warpFarmer(prior_map, player_x, player_y, false); - warped_check = true; - super_map_warping_check = true; - prior_map = null; - } + if (this.PreCollapseMap != null) + Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); + this.PreCollapseMap = null; + this.JustStartedNewDay = false; + this.JustCollapsed = false; } } catch (Exception ex) { - try - { - Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; - serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All; - serializer.Formatting = Newtonsoft.Json.Formatting.Indented; - serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - using (StreamWriter sw = new StreamWriter(Path.Combine(Error_Path, "Mod_State.json"))) - { - using (Newtonsoft.Json.JsonWriter writer2 = new Newtonsoft.Json.JsonTextWriter(sw)) - { - serializer.Serialize(writer2, this); - } - } - } - catch (Exception exc) - { - Monitor.Log(exc.ToString()); - } + this.Monitor.Log(ex.ToString(), LogLevel.Error); + this.WriteErrorLog(); } } - public void PlayerEvents_LoadedGame(object sender, EventArgs e) + /// The method invoked after the player loads a save. + /// The event sender. + /// The event data. + public void SaveEvents_AfterLoad(object sender, EventArgs e) { - DataLoader(); - MyWritter(); - game_loaded = true; - once = false; - up_late = false; - first_check = false; - warped_check = true; - super_map_warping_check = true; + this.LoadConfig(); + this.WriteConfig(); + this.IsGameLoaded = true; + this.IsUpLate = false; + this.JustStartedNewDay = false; + this.JustCollapsed = false; } - public void TimeEvents_DayOfMonthChanged(object sender, StardewModdingAPI.Events.EventArgsIntChanged e) + /// The method invoked when changes. + /// The event sender. + /// The event data. + public void TimeEvents_DayOfMonthChanged(object sender, EventArgsIntChanged e) { - /* - IMPLEMENT TRY CATCH SYSTEM HERE - - */ - try { - - if (game_loaded == false) return; - if (first_check == false) - { - first_check = true; - Monitor.Log("first"); + if (!this.IsGameLoaded) return; - } - else + + try { - first_check = false; - Monitor.Log("Second"); - } - if(Game1.farmerShouldPassOut== true) Game1.farmerShouldPassOut = false; //make the farmer collapse. - - reset_check = false; - //Game1.farmerShouldPassOut = false; //make the farmer collapse. - DataLoader(); - MyWritter(); - //List newmail = new List(); - Queue newmail = new Queue(); - - up_late = false; - - if (time_reset == true) - { - was_raining = false; - if (persistant_stamina==true) Game1.player.stamina = pre_stam; //reset health and stam upon collapsing - if (persistant_health == true) Game1.player.health = pre_health; - //post_money = Game1.player.money; - if (protect_money == true) { + // reset data + this.LoadConfig(); + this.WriteConfig(); + this.IsUpLate = false; + Game1.farmerShouldPassOut = false; - Game1.player.money += post_money; - once = true; - - - } //add the money back from colapsing. - time_reset = false; //reset my bool. - if(warp==true)Game1.warpFarmer(prior_map, player_x, player_y, false); - // very_old_money = (safety_cash - Game1.player.money); - //Game1.player.money += very_old_money; - } - - if (wipe_mail == true) - { - foreach (var i in Game1.mailbox) //delete those annoying charge messages. If only I could do this with mail IRL. - { - Monitor.Log(i); - - if (i.Contains("passedOut")) - { - Monitor.Log("Found bad mail"); - } - else { - newmail.Enqueue(i); - } - } - Game1.mailbox.Clear(); - foreach (string mail in newmail) + // transition to the next day + if (this.ShouldResetPlayerAfterCollapseNow) { - Game1.mailbox.Enqueue(mail); + this.ShouldResetPlayerAfterCollapseNow = false; + + if (this.KeepStaminaAfterCollapse) + Game1.player.stamina = this.PreCollapseStamina; + if (this.KeepHealthAfterCollapse) + Game1.player.health = this.PreCollapseHealth; + if (this.KeepMoneyAfterCollapse) + Game1.player.money = this.PreCollapseMoney; + if (this.KeepPositionAfterCollapse) + Game1.warpFarmer(this.PreCollapseMap, this.PreCollapseTile.X, this.PreCollapseTile.Y, false); } - } - warped_check = false; - //prior_map==null; //prevents multiple warping when sleeping + + // delete annoying charge messages (if only I could do this with mail IRL) + if (this.SkipCollapseMail) + { + string[] validMail = Game1.mailbox + .Where(p => !p.Contains("passedOut")) + .ToArray(); + + Game1.mailbox.Clear(); + foreach (string mail in validMail) + Game1.mailbox.Enqueue(mail); + } + + this.JustStartedNewDay = true; } catch (Exception ex) { - try - { - Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; - serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All; - serializer.Formatting = Newtonsoft.Json.Formatting.Indented; - serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - using (StreamWriter sw = new StreamWriter(Path.Combine(Error_Path, "Mod_State.json"))) - { - using (Newtonsoft.Json.JsonWriter writer2 = new Newtonsoft.Json.JsonTextWriter(sw)) - { - serializer.Serialize(writer2, this); - } - } - } - catch (Exception exc) - { - Monitor.Log(exc.ToString()); - } + this.Monitor.Log(ex.ToString(), LogLevel.Error); + this.WriteErrorLog(); } } - - public void TimeEvents_TimeOfDayChanged(object sender, StardewModdingAPI.Events.EventArgsIntChanged e) + /// The method invoked when changes. + /// The event sender. + /// The event data. + private void TimeEvents_TimeOfDayChanged(object sender, EventArgsIntChanged e) { - /* - Implement try catch system here. + if (!this.IsGameLoaded) + return; - */ - try { - if (game_loaded == false) return; - float color_mod; - //transition the lighting for more "realistic" lighting from 2am to 11am. There is an awkward screen shuffle that happens because of this update. - - if (lighting_transition == true) + try { - if (Game1.timeOfDay > 400 && Game1.timeOfDay < 600) + // transition morning light more realistically + if (this.MorningLightTransition && Game1.timeOfDay > 400 && Game1.timeOfDay < 600) { - color_mod = (1300 - Game1.timeOfDay) / 1000f; //.7f - Game1.outdoorLight = Game1.ambientLight * color_mod; - + float colorMod = (1300 - Game1.timeOfDay) / 1000f; + Game1.outdoorLight = Game1.ambientLight * colorMod; } - } - - if (stay_up == true) - { - if (Game1.timeOfDay == 2550) + // transition to next morning + if (this.StayUp && Game1.timeOfDay == 2550) { - if (StardewValley.Game1.isRaining == true) - { - was_raining = true; - StardewValley.Game1.isRaining = false; //regardless make sure I change the weather. Otherwise lighting gets screwy. - } - StardewValley.Game1.updateWeatherIcon(); + Game1.isRaining = false; // remove rain, otherwise lighting gets screwy + Game1.updateWeatherIcon(); Game1.timeOfDay = 150; //change it from 1:50 am late, to 1:50 am early } - } - - if (Game1.timeOfDay == 550) //if the game time is 5:50 AM - { - up_late = true; - } - - if (Game1.timeOfDay == 600) //when time is 6:00 AM after staying up - { - - if (up_late == false) + // collapse player at 6am to save & reset + if (Game1.timeOfDay == 550) + this.IsUpLate = true; + if (this.IsUpLate && Game1.timeOfDay == 600 && !this.JustCollapsed) { - return; + this.JustCollapsed = true; + + this.ShouldResetPlayerAfterCollapseNow = true; + this.PreCollapseTile = new Point(Game1.player.getTileX(), Game1.player.getTileY()); + this.PreCollapseMap = Game1.player.currentLocation.name; + this.PreCollapseStamina = Game1.player.stamina; + this.PreCollapseHealth = Game1.player.health; + this.PreCollapseMoney = Game1.player.money; + + if (Game1.currentMinigame != null) + Game1.currentMinigame = null; + Game1.farmerShouldPassOut = true; } - - - if (super_map_warping_check == true) - { - if (Game1.currentMinigame != null) Game1.currentMinigame = null; - //if (time_reset == false) return; - time_reset = true; - player_x = Game1.player.getTileX(); - player_y = Game1.player.getTileY(); - prior_map = Game1.player.currentLocation.name; - - Monitor.Log(prior_map); - Monitor.Log(player_x.ToString()); - Monitor.Log(player_y.ToString()); - super_map_warping_check = false; - - - Game1.farmerShouldPassOut = true; //make the farmer collapse. - - pre_stam = Game1.player.stamina; - pre_health = Game1.player.health; - prior_money = Game1.player.money; - - if (Game1.player.money <= 10000) - { - post_money = prior_money / 10; - } - else - { - post_money = 1000; - } - } - } } catch (Exception ex) { - try - { - Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; - serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All; - serializer.Formatting = Newtonsoft.Json.Formatting.Indented; - serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - using (StreamWriter sw = new StreamWriter(Path.Combine(Error_Path, "Mod_State.json"))) - { - using (Newtonsoft.Json.JsonWriter writer2 = new Newtonsoft.Json.JsonTextWriter(sw)) - { - serializer.Serialize(writer2, this); - } - } - } - catch (Exception exc) - { - Monitor.Log(exc.ToString()); - } + this.Monitor.Log(ex.ToString(), LogLevel.Error); + this.WriteErrorLog(); } } - - void MyWritter() + /// Save the configuration settings. + private void WriteConfig() { - //saves the BuildEndurance_data at the end of a new day; - string myname = Game1.player.name; - string mylocation = Path.Combine(Helper.DirectoryPath, "Night_Owl_Config_"); - //string mylocation2 = mylocation + myname; - string mylocation3 = mylocation + ".txt"; - string[] mystring3 = new string[20]; - if (!File.Exists(mylocation3)) - { - Monitor.Log("The data file for Night Owl wasn't found. Time to create it!"); - mystring3[0] = "Player: Night Owl Config. Feel free to edit."; - mystring3[1] = "===================================================================================="; - mystring3[2] = "Stay up to 6 AM?: Do you wan't to stay up till 6 AM the next morning?"; - mystring3[3] = stay_up.ToString(); - mystring3[4] = "Custom Lighting Transition?: Do you want to have a lighting transition from 2AM to 5:50 AM? Setting this to false will keep the world dark until the player passes out or goes to bed."; - mystring3[5] = lighting_transition.ToString(); - mystring3[6] = "Warp to collapse position?: True: Stay in the same place. False: Warp back home."; - mystring3[7] = warp.ToString(); - mystring3[8] = "Keep Money?: True: Don't be charged for passing out."; - mystring3[9] = protect_money.ToString(); - mystring3[10] = "Keep stamina when staying up? When the farmer passes out at 6, should their stamina be their stamina before collapsing?"; - mystring3[11] = persistant_stamina.ToString(); - mystring3[12] = "Keep health when staying up? When the farmer passes out at 6, should their health be their health before collapsing?"; - mystring3[13] = persistant_health.ToString(); - mystring3[14] = "Clean out charges mail?: Get rid of the annoying We charged X gold for your health fees, etc."; - mystring3[15] = wipe_mail.ToString(); - File.WriteAllLines(mylocation3, mystring3); - } + 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)) //if not data.json exists, initialize the data variables to the ModConfig data. I.E. starting out. + { + this.Monitor.Log("Loading Night_Owl_Config"); + this.MorningLightTransition = true; + this.KeepPositionAfterCollapse = true; + this.StayUp = true; + + this.KeepHealthAfterCollapse = true; + this.KeepStaminaAfterCollapse = true; + this.SkipCollapseMail = true; + this.KeepMoneyAfterCollapse = true; + } else { - // Console.WriteLine("HEY IM SAVING DATA"); - //write out the info to a text file at the end of a day. - mystring3[0] = "Player: Night Owl Config. Feel free to edit."; - mystring3[1] = "===================================================================================="; - mystring3[2] = "Stay up to 6 AM?: Do you wan't to stay up till 6 AM the next morning?"; - mystring3[3] = stay_up.ToString(); - mystring3[4] = "Custom Lighting Transition?: Do you want to have a lighting transition from 2AM to 5:50 AM? Setting this to false will keep the world dark until the player passes out or goes to bed."; - mystring3[5] = lighting_transition.ToString(); - mystring3[6] = "Warp to collapse position?: True: Stay in the same place. False: Warp back home."; - mystring3[7] = warp.ToString(); - mystring3[8] = "Keep Money?: True: Don't be charged for passing out."; - mystring3[9] = protect_money.ToString(); - mystring3[10] = "Keep stamina when staying up? When the farmer passes out at 6, should their stamina be their stamina before collapsing?"; - mystring3[11] = persistant_stamina.ToString(); - mystring3[12] = "Keep health when staying up? When the farmer passes out at 6, should their health be their health before collapsing?"; - mystring3[13] = persistant_health.ToString(); - mystring3[14] = "Clean out charges mail?: Get rid of the annoying We charged X gold for your health fees, etc."; - mystring3[15] = wipe_mail.ToString(); - - File.WriteAllLines(mylocation3, mystring3); + 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]); } } - void DataLoader() + + /// Write the current mod state to the error log file. + private void WriteErrorLog() { - //loads the data to the variables upon loading the game. - string myname = StardewValley.Game1.player.name; - string mylocation = Path.Combine(Helper.DirectoryPath, "Night_Owl_Config_"); - //string mylocation2 = mylocation + myname; - string mylocation3 = mylocation + ".txt"; - if (!File.Exists(mylocation3)) //if not data.json exists, initialize the data variables to the ModConfig data. I.E. starting out. + try { - Monitor.Log("Loading Night_Owl_Config"); - lighting_transition = true; - warp = true; - stay_up = true; - - persistant_health = true; - persistant_stamina = true; - wipe_mail = true; - protect_money = true; - + 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); + } } - - else + catch (Exception ex) { - string[] readtext = File.ReadAllLines(mylocation3); - stay_up = Convert.ToBoolean(readtext[3]);//will the player stay up? - lighting_transition = Convert.ToBoolean(readtext[5]); //does the lighting transition occur? - warp = Convert.ToBoolean(readtext[7]); //does the player warp back to the spot they passed out at? - protect_money = Convert.ToBoolean(readtext[9]); //Is their money safe from stealing? - persistant_stamina = Convert.ToBoolean(readtext[11]); //Does the player have the same stam when collapsing? - persistant_health = Convert.ToBoolean(readtext[13]); //Ditto but with health. - if (readtext[15] == "") wipe_mail = true; - else wipe_mail = Convert.ToBoolean(readtext[15]); //will I clean out their mailbox? + this.Monitor.Log(ex.ToString(), LogLevel.Error); } } } diff --git a/GeneralMods/NightOwl/manifest.json b/GeneralMods/NightOwl/manifest.json index 3e65ed53..81037820 100644 --- a/GeneralMods/NightOwl/manifest.json +++ b/GeneralMods/NightOwl/manifest.json @@ -11,4 +11,4 @@ "UniqueID": "Stardew_NightOwl", "PerSaveConfigs": false, "EntryDll": "NightOwl.dll" -} \ No newline at end of file +}