From 602227eae8da421db759e45595812d9978ca8238 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 18 Jan 2017 22:14:50 -0500 Subject: [PATCH] fix some world events being fired during game startup (#217) --- release-notes.md | 1 + src/StardewModdingAPI/Inheritance/SGame.cs | 220 +++++++++++---------- 2 files changed, 115 insertions(+), 106 deletions(-) diff --git a/release-notes.md b/release-notes.md index 4e91ee2e..c870bbb5 100644 --- a/release-notes.md +++ b/release-notes.md @@ -5,6 +5,7 @@ See [log](https://github.com/Pathoschild/SMAPI/compare/1.6...1.7). For mod developers: * Fixed `PlayerEvents.LoadedGame` and `SaveEvents.AfterLoad` being fired before the world finishes initialising. +* Fixed some `LocationEvents`, `PlayerEvents`, and `TimeEvents` being fired during game startup. ## 1.6 See [log](https://github.com/Pathoschild/SMAPI/compare/1.5...1.6). diff --git a/src/StardewModdingAPI/Inheritance/SGame.cs b/src/StardewModdingAPI/Inheritance/SGame.cs index 28c2aa42..f23f3212 100644 --- a/src/StardewModdingAPI/Inheritance/SGame.cs +++ b/src/StardewModdingAPI/Inheritance/SGame.cs @@ -28,6 +28,9 @@ namespace StardewModdingAPI.Inheritance /// Skipping a few frames ensures the game finishes initialising the world before mods try to change it. private int AfterLoadTimer = 5; + /// Whether the player has loaded a save and the world has finished initialising. + private bool IsWorldReady => this.AfterLoadTimer < 0; + /// The debug messages to add to the next debug output. internal static Queue DebugMessageQueue { get; private set; } @@ -861,57 +864,71 @@ namespace StardewModdingAPI.Inheritance /// Detect changes since the last update ticket and trigger mod events. private void UpdateEventCalls() { - // get latest state - this.KStateNow = Keyboard.GetState(); - this.MStateNow = Mouse.GetState(); - this.MPositionNow = new Point(Game1.getMouseX(), Game1.getMouseY()); - - // raise key pressed - foreach (var key in this.FramePressedKeys) - ControlEvents.InvokeKeyPressed(this.Monitor, key); - - // raise key released - foreach (var key in this.FrameReleasedKeys) - ControlEvents.InvokeKeyReleased(this.Monitor, key); - - // raise controller button pressed - for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + // save loaded event + if (Game1.hasLoadedGame && this.AfterLoadTimer >= 0) { - var buttons = this.GetFramePressedButtons(i); - foreach (var button in buttons) + if (this.AfterLoadTimer == 0) { - if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger) - ControlEvents.InvokeTriggerPressed(this.Monitor, i, button, button == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); - else - ControlEvents.InvokeButtonPressed(this.Monitor, i, button); + SaveEvents.InvokeAfterLoad(this.Monitor); + PlayerEvents.InvokeLoadedGame(this.Monitor, new EventArgsLoadedGameChanged(Game1.hasLoadedGame)); + } + this.AfterLoadTimer--; + } + + // input events + { + // get latest state + this.KStateNow = Keyboard.GetState(); + this.MStateNow = Mouse.GetState(); + this.MPositionNow = new Point(Game1.getMouseX(), Game1.getMouseY()); + + // raise key pressed + foreach (var key in this.FramePressedKeys) + ControlEvents.InvokeKeyPressed(this.Monitor, key); + + // raise key released + foreach (var key in this.FrameReleasedKeys) + ControlEvents.InvokeKeyReleased(this.Monitor, key); + + // raise controller button pressed + for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + { + var buttons = this.GetFramePressedButtons(i); + foreach (var button in buttons) + { + if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger) + ControlEvents.InvokeTriggerPressed(this.Monitor, i, button, button == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + else + ControlEvents.InvokeButtonPressed(this.Monitor, i, button); + } + } + + // raise controller button released + for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + { + foreach (var button in this.GetFrameReleasedButtons(i)) + { + if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger) + ControlEvents.InvokeTriggerReleased(this.Monitor, i, button, button == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + else + ControlEvents.InvokeButtonReleased(this.Monitor, i, button); + } + } + + // raise keyboard state changed + if (this.KStateNow != this.KStatePrior) + ControlEvents.InvokeKeyboardChanged(this.Monitor, this.KStatePrior, this.KStateNow); + + // raise mouse state changed + if (this.MStateNow != this.MStatePrior) + { + ControlEvents.InvokeMouseChanged(this.Monitor, this.MStatePrior, this.MStateNow, this.MPositionPrior, this.MPositionNow); + this.MStatePrior = this.MStateNow; + this.MPositionPrior = this.MPositionPrior; } } - // raise controller button released - for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) - { - foreach (var button in this.GetFrameReleasedButtons(i)) - { - if (button == Buttons.LeftTrigger || button == Buttons.RightTrigger) - ControlEvents.InvokeTriggerReleased(this.Monitor, i, button, button == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); - else - ControlEvents.InvokeButtonReleased(this.Monitor, i, button); - } - } - - // raise keyboard state changed - if (this.KStateNow != this.KStatePrior) - ControlEvents.InvokeKeyboardChanged(this.Monitor, this.KStatePrior, this.KStateNow); - - // raise mouse state changed - if (this.MStateNow != this.MStatePrior) - { - ControlEvents.InvokeMouseChanged(this.Monitor, this.MStatePrior, this.MStateNow, this.MPositionPrior, this.MPositionNow); - this.MStatePrior = this.MStateNow; - this.MPositionPrior = this.MPositionPrior; - } - - // raise menu changed + // menu events if (Game1.activeClickableMenu != this.PreviousActiveMenu) { IClickableMenu previousMenu = this.PreviousActiveMenu; @@ -934,23 +951,23 @@ namespace StardewModdingAPI.Inheritance this.PreviousActiveMenu = newMenu; } - // raise location list changed - if (this.GetHash(Game1.locations) != this.PreviousGameLocations) + // world & player events + if (this.IsWorldReady) { - LocationEvents.InvokeLocationsChanged(this.Monitor, Game1.locations); - this.PreviousGameLocations = this.GetHash(Game1.locations); - } + // raise location list changed + if (this.GetHash(Game1.locations) != this.PreviousGameLocations) + { + LocationEvents.InvokeLocationsChanged(this.Monitor, Game1.locations); + this.PreviousGameLocations = this.GetHash(Game1.locations); + } - // raise current location changed - if (Game1.currentLocation != this.PreviousGameLocation) - { - LocationEvents.InvokeCurrentLocationChanged(this.Monitor, this.PreviousGameLocation, Game1.currentLocation); - this.PreviousGameLocation = Game1.currentLocation; - } + // raise current location changed + if (Game1.currentLocation != this.PreviousGameLocation) + { + LocationEvents.InvokeCurrentLocationChanged(this.Monitor, this.PreviousGameLocation, Game1.currentLocation); + this.PreviousGameLocation = Game1.currentLocation; + } - // player events - if (Game1.player != null) - { // raise player changed if (Game1.player != this.PreviousFarmer) { @@ -997,57 +1014,48 @@ namespace StardewModdingAPI.Inheritance PlayerEvents.InvokeInventoryChanged(this.Monitor, Game1.player.items, changedItems); this.PreviousItems = Game1.player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack); } - } - // raise current location's object list changed - int? objectHash = Game1.currentLocation?.objects != null ? this.GetHash(Game1.currentLocation.objects) : (int?)null; - if (objectHash != null && this.PreviousLocationObjects != objectHash) - { - LocationEvents.InvokeOnNewLocationObject(this.Monitor, Game1.currentLocation.objects); - this.PreviousLocationObjects = objectHash.Value; - } - - // raise time changed - if (Game1.timeOfDay != this.PreviousTimeOfDay) - { - TimeEvents.InvokeTimeOfDayChanged(this.Monitor, this.PreviousTimeOfDay, Game1.timeOfDay); - this.PreviousTimeOfDay = Game1.timeOfDay; - } - if (Game1.dayOfMonth != this.PreviousDayOfMonth) - { - TimeEvents.InvokeDayOfMonthChanged(this.Monitor, this.PreviousDayOfMonth, Game1.dayOfMonth); - this.PreviousDayOfMonth = Game1.dayOfMonth; - } - if (Game1.currentSeason != this.PreviousSeasonOfYear) - { - TimeEvents.InvokeSeasonOfYearChanged(this.Monitor, this.PreviousSeasonOfYear, Game1.currentSeason); - this.PreviousSeasonOfYear = Game1.currentSeason; - } - if (Game1.year != this.PreviousYearOfGame) - { - TimeEvents.InvokeYearOfGameChanged(this.Monitor, this.PreviousYearOfGame, Game1.year); - this.PreviousYearOfGame = Game1.year; - } - - // raise save loaded - if (Game1.hasLoadedGame && this.AfterLoadTimer >= 0) - { - if (this.AfterLoadTimer == 0) + // raise current location's object list changed { - SaveEvents.InvokeAfterLoad(this.Monitor); - PlayerEvents.InvokeLoadedGame(this.Monitor, new EventArgsLoadedGameChanged(Game1.hasLoadedGame)); + int? objectHash = Game1.currentLocation?.objects != null ? this.GetHash(Game1.currentLocation.objects) : (int?)null; + if (objectHash != null && this.PreviousLocationObjects != objectHash) + { + LocationEvents.InvokeOnNewLocationObject(this.Monitor, Game1.currentLocation.objects); + this.PreviousLocationObjects = objectHash.Value; + } + } + + // raise time changed + if (Game1.timeOfDay != this.PreviousTimeOfDay) + { + TimeEvents.InvokeTimeOfDayChanged(this.Monitor, this.PreviousTimeOfDay, Game1.timeOfDay); + this.PreviousTimeOfDay = Game1.timeOfDay; + } + if (Game1.dayOfMonth != this.PreviousDayOfMonth) + { + TimeEvents.InvokeDayOfMonthChanged(this.Monitor, this.PreviousDayOfMonth, Game1.dayOfMonth); + this.PreviousDayOfMonth = Game1.dayOfMonth; + } + if (Game1.currentSeason != this.PreviousSeasonOfYear) + { + TimeEvents.InvokeSeasonOfYearChanged(this.Monitor, this.PreviousSeasonOfYear, Game1.currentSeason); + this.PreviousSeasonOfYear = Game1.currentSeason; + } + if (Game1.year != this.PreviousYearOfGame) + { + TimeEvents.InvokeYearOfGameChanged(this.Monitor, this.PreviousYearOfGame, Game1.year); + this.PreviousYearOfGame = Game1.year; + } + + // raise mine level changed + if (Game1.mine != null && Game1.mine.mineLevel != this.PreviousMineLevel) + { + MineEvents.InvokeMineLevelChanged(this.Monitor, this.PreviousMineLevel, Game1.mine.mineLevel); + this.PreviousMineLevel = Game1.mine.mineLevel; } - this.AfterLoadTimer--; } - // raise mine level changed - if (Game1.mine != null && Game1.mine.mineLevel != this.PreviousMineLevel) - { - MineEvents.InvokeMineLevelChanged(this.Monitor, this.PreviousMineLevel, Game1.mine.mineLevel); - this.PreviousMineLevel = Game1.mine.mineLevel; - } - - // raise game transitioning to new day + // raise game day transition event (obsolete) if (Game1.newDay != this.PreviousIsNewDay) { TimeEvents.InvokeOnNewDay(this.Monitor, this.PreviousDayOfMonth, Game1.dayOfMonth, Game1.newDay);