diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2018-12-29 20:09:33 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2018-12-29 20:09:33 -0500 |
commit | f046091fe637963fd6a8cc8c1324daf81b64899f (patch) | |
tree | adeffec4a5d31503548ef5dead7d67b3bff9e694 /src/SMAPI/Framework | |
parent | 82beefd8531467de318c1881afd15a258d489f37 (diff) | |
parent | ca18a2867b457fd6bfda71d9828884032ecadfb8 (diff) | |
download | SMAPI-f046091fe637963fd6a8cc8c1324daf81b64899f.tar.gz SMAPI-f046091fe637963fd6a8cc8c1324daf81b64899f.tar.bz2 SMAPI-f046091fe637963fd6a8cc8c1324daf81b64899f.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework')
75 files changed, 347 insertions, 254 deletions
diff --git a/src/SMAPI/Framework/CommandManager.cs b/src/SMAPI/Framework/CommandManager.cs index aabe99c3..fdaafff1 100644 --- a/src/SMAPI/Framework/CommandManager.cs +++ b/src/SMAPI/Framework/CommandManager.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework internal class CommandManager { /********* - ** Properties + ** Fields *********/ /// <summary>The commands registered with SMAPI.</summary> private readonly IDictionary<string, Command> Commands = new Dictionary<string, Command>(StringComparer.InvariantCultureIgnoreCase); diff --git a/src/SMAPI/Framework/Content/AssetData.cs b/src/SMAPI/Framework/Content/AssetData.cs index 0a86f54d..553404d3 100644 --- a/src/SMAPI/Framework/Content/AssetData.cs +++ b/src/SMAPI/Framework/Content/AssetData.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Content internal class AssetData<TValue> : AssetInfo, IAssetData<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>A callback to invoke when the data is replaced (if any).</summary> private readonly Action<TValue> OnDataReplaced; diff --git a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs index 9bd70711..fd3edd5d 100644 --- a/src/SMAPI/Framework/Content/AssetDataForDictionary.cs +++ b/src/SMAPI/Framework/Content/AssetDataForDictionary.cs @@ -26,7 +26,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(TKey key, TValue value) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Notice); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); this.Data[key] = value; } @@ -36,7 +36,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(TKey key, Func<TValue, TValue> value) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Notice); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); this.Data[key] = value(this.Data[key]); } @@ -45,7 +45,7 @@ namespace StardewModdingAPI.Framework.Content [Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")] public void Set(Func<TKey, TValue, TValue> replacer) { - SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Notice); + SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.Info); foreach (var pair in this.Data.ToArray()) this.Data[pair.Key] = replacer(pair.Key, pair.Value); } diff --git a/src/SMAPI/Framework/Content/AssetDataForImage.cs b/src/SMAPI/Framework/Content/AssetDataForImage.cs index f970762a..f2d21b5e 100644 --- a/src/SMAPI/Framework/Content/AssetDataForImage.cs +++ b/src/SMAPI/Framework/Content/AssetDataForImage.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Content internal class AssetDataForImage : AssetData<Texture2D>, IAssetDataForImage { /********* - ** Properties + ** Fields *********/ /// <summary>The minimum value to consider non-transparent.</summary> /// <remarks>On Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason.</remarks> diff --git a/src/SMAPI/Framework/Content/AssetInfo.cs b/src/SMAPI/Framework/Content/AssetInfo.cs index d580dc06..e5211290 100644 --- a/src/SMAPI/Framework/Content/AssetInfo.cs +++ b/src/SMAPI/Framework/Content/AssetInfo.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Content internal class AssetInfo : IAssetInfo { /********* - ** Properties + ** Fields *********/ /// <summary>Normalises an asset key to match the cache key.</summary> protected readonly Func<string, string> GetNormalisedPath; diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index a5dfac9d..55a96ed2 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.Content internal class ContentCache { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying asset cache.</summary> private readonly IDictionary<string, object> Cache; diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index 7e256939..4dd1b6e1 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -19,7 +19,7 @@ namespace StardewModdingAPI.Framework internal class ContentCoordinator : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>An asset key prefix for assets from SMAPI mod folders.</summary> private readonly string ManagedPrefix = "SMAPI"; diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index 724a6e1c..7821e454 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -18,7 +18,7 @@ namespace StardewModdingAPI.Framework.ContentManagers internal abstract class BaseContentManager : LocalizedContentManager, IContentManager { /********* - ** Properties + ** Fields *********/ /// <summary>The central coordinator which manages content managers.</summary> protected readonly ContentCoordinator Coordinator; diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 81732d3f..ee940cc7 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.ContentManagers internal class GameContentManager : BaseContentManager { /********* - ** Properties + ** Fields *********/ /// <summary>The assets currently being intercepted by <see cref="IAssetLoader"/> instances. This is used to prevent infinite loops when a loader loads a new asset.</summary> private readonly ContextHash<string> AssetsBeingLoaded = new ContextHash<string>(); diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index ed76a925..6485b3d4 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.ContentManagers internal class ModContentManager : BaseContentManager { /********* - ** Properties + ** Fields *********/ /// <summary>Encapsulates SMAPI's JSON file parsing.</summary> private readonly JsonHelper JsonHelper; diff --git a/src/SMAPI/Framework/ContentPack.cs b/src/SMAPI/Framework/ContentPack.cs index 49285388..e39d03a1 100644 --- a/src/SMAPI/Framework/ContentPack.cs +++ b/src/SMAPI/Framework/ContentPack.cs @@ -12,7 +12,7 @@ namespace StardewModdingAPI.Framework internal class ContentPack : IContentPack { /********* - ** Properties + ** Fields *********/ /// <summary>Provides an API for loading content assets.</summary> private readonly IContentHelper Content; diff --git a/src/SMAPI/Framework/DeprecationManager.cs b/src/SMAPI/Framework/DeprecationManager.cs index be564c22..76c2f616 100644 --- a/src/SMAPI/Framework/DeprecationManager.cs +++ b/src/SMAPI/Framework/DeprecationManager.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework internal class DeprecationManager { /********* - ** Properties + ** Fields *********/ /// <summary>The deprecations which have already been logged (as 'mod name::noun phrase::version').</summary> private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); @@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework /// <summary>Log a deprecation warning for the old-style events.</summary> public void WarnForOldEvents() { - this.Warn("legacy events", "2.9", DeprecationLevel.Notice); + this.Warn("legacy events", "2.9", DeprecationLevel.Info); } /// <summary>Log a deprecation warning.</summary> @@ -71,7 +71,13 @@ namespace StardewModdingAPI.Framework foreach (DeprecationWarning warning in this.QueuedWarnings.OrderBy(p => p.ModName).ThenBy(p => p.NounPhrase)) { // build message +#if SMAPI_3_0_STRICT string message = $"{warning.ModName ?? "An unknown mod"} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; +#else + string message = warning.NounPhrase == "legacy events" + ? $"{warning.ModName ?? "An unknown mod"} uses deprecated code (legacy events are deprecated since SMAPI {warning.Version})." + : $"{warning.ModName ?? "An unknown mod"} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; +#endif if (warning.ModName == null) message += $"{Environment.NewLine}{Environment.StackTrace}"; diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index 0ad85adf..13244601 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -58,6 +58,12 @@ namespace StardewModdingAPI.Framework.Events /// <summary>Raised after the game performs its overall update tick (≈60 times per second).</summary> public readonly ManagedEvent<UpdateTickedEventArgs> UpdateTicked; + /// <summary>Raised once per second before the game performs its overall update tick.</summary> + public readonly ManagedEvent<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking; + + /// <summary>Raised once per second after the game performs its overall update tick.</summary> + public readonly ManagedEvent<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked; + /// <summary>Raised before the game creates the save file.</summary> public readonly ManagedEvent<SaveCreatingEventArgs> SaveCreating; @@ -70,7 +76,7 @@ namespace StardewModdingAPI.Framework.Events /// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary> public readonly ManagedEvent<SavedEventArgs> Saved; - /// <summary>Raised after the player loads a save slot.</summary> + /// <summary>Raised after the player loads a save slot and the world is initialised.</summary> public readonly ManagedEvent<SaveLoadedEventArgs> SaveLoaded; /// <summary>Raised after the game begins a new day, including when loading a save.</summary> @@ -151,6 +157,9 @@ namespace StardewModdingAPI.Framework.Events /**** ** Specialised ****/ + /// <summary>Raised when the low-level stage in the game's loading process has changed. See notes on <see cref="ISpecialisedEvents.LoadStageChanged"/>.</summary> + public readonly ManagedEvent<LoadStageChangedEventArgs> LoadStageChanged; + /// <summary>Raised before the game performs its overall update tick (≈60 times per second). See notes on <see cref="ISpecialisedEvents.UnvalidatedUpdateTicking"/>.</summary> public readonly ManagedEvent<UnvalidatedUpdateTickingEventArgs> UnvalidatedUpdateTicking; @@ -377,6 +386,8 @@ namespace StardewModdingAPI.Framework.Events this.GameLaunched = ManageEventOf<GameLaunchedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.GameLaunched)); this.UpdateTicking = ManageEventOf<UpdateTickingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicking)); this.UpdateTicked = ManageEventOf<UpdateTickedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.UpdateTicked)); + this.OneSecondUpdateTicking = ManageEventOf<OneSecondUpdateTickingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.OneSecondUpdateTicking)); + this.OneSecondUpdateTicked = ManageEventOf<OneSecondUpdateTickedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.OneSecondUpdateTicked)); this.SaveCreating = ManageEventOf<SaveCreatingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreating)); this.SaveCreated = ManageEventOf<SaveCreatedEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.SaveCreated)); this.Saving = ManageEventOf<SavingEventArgs>(nameof(IModEvents.GameLoop), nameof(IGameLoopEvents.Saving)); @@ -408,6 +419,7 @@ namespace StardewModdingAPI.Framework.Events this.ObjectListChanged = ManageEventOf<ObjectListChangedEventArgs>(nameof(IModEvents.World), nameof(IWorldEvents.ObjectListChanged)); this.TerrainFeatureListChanged = ManageEventOf<TerrainFeatureListChangedEventArgs>(nameof(IModEvents.World), nameof(IWorldEvents.TerrainFeatureListChanged)); + this.LoadStageChanged = ManageEventOf<LoadStageChangedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.LoadStageChanged)); this.UnvalidatedUpdateTicking = ManageEventOf<UnvalidatedUpdateTickingEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicking)); this.UnvalidatedUpdateTicked = ManageEventOf<UnvalidatedUpdateTickedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicked)); diff --git a/src/SMAPI/Framework/Events/ManagedEvent.cs b/src/SMAPI/Framework/Events/ManagedEvent.cs index 65f6e38e..f9e7f6ec 100644 --- a/src/SMAPI/Framework/Events/ManagedEvent.cs +++ b/src/SMAPI/Framework/Events/ManagedEvent.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Events internal class ManagedEvent<TEventArgs> : ManagedEventBase<EventHandler<TEventArgs>> { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying event.</summary> private event EventHandler<TEventArgs> Event; @@ -93,11 +93,12 @@ namespace StardewModdingAPI.Framework.Events } } +#if !SMAPI_3_0_STRICT /// <summary>An event wrapper which intercepts and logs errors in handler code.</summary> internal class ManagedEvent : ManagedEventBase<EventHandler> { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying event.</summary> private event EventHandler Event; @@ -156,4 +157,5 @@ namespace StardewModdingAPI.Framework.Events } } } +#endif } diff --git a/src/SMAPI/Framework/Events/ManagedEventBase.cs b/src/SMAPI/Framework/Events/ManagedEventBase.cs index defd903a..c8c3516b 100644 --- a/src/SMAPI/Framework/Events/ManagedEventBase.cs +++ b/src/SMAPI/Framework/Events/ManagedEventBase.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Events internal abstract class ManagedEventBase<TEventHandler> { /********* - ** Properties + ** Fields *********/ /// <summary>A human-readable name for the event.</summary> private readonly string EventName; diff --git a/src/SMAPI/Framework/Events/ModEventsBase.cs b/src/SMAPI/Framework/Events/ModEventsBase.cs index 545c58a8..77708fc1 100644 --- a/src/SMAPI/Framework/Events/ModEventsBase.cs +++ b/src/SMAPI/Framework/Events/ModEventsBase.cs @@ -4,7 +4,7 @@ namespace StardewModdingAPI.Framework.Events internal abstract class ModEventsBase { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying event manager.</summary> protected readonly EventManager EventManager; diff --git a/src/SMAPI/Framework/Events/ModGameLoopEvents.cs b/src/SMAPI/Framework/Events/ModGameLoopEvents.cs index a5beac99..0177c22e 100644 --- a/src/SMAPI/Framework/Events/ModGameLoopEvents.cs +++ b/src/SMAPI/Framework/Events/ModGameLoopEvents.cs @@ -30,6 +30,20 @@ namespace StardewModdingAPI.Framework.Events remove => this.EventManager.UpdateTicked.Remove(value); } + /// <summary>Raised once per second before the game state is updated.</summary> + public event EventHandler<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking + { + add => this.EventManager.OneSecondUpdateTicking.Add(value); + remove => this.EventManager.OneSecondUpdateTicking.Remove(value); + } + + /// <summary>Raised once per second after the game state is updated.</summary> + public event EventHandler<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked + { + add => this.EventManager.OneSecondUpdateTicked.Add(value); + remove => this.EventManager.OneSecondUpdateTicked.Remove(value); + } + /// <summary>Raised before the game creates a new save file.</summary> public event EventHandler<SaveCreatingEventArgs> SaveCreating { @@ -58,7 +72,7 @@ namespace StardewModdingAPI.Framework.Events remove => this.EventManager.Saved.Remove(value); } - /// <summary>Raised after the player loads a save slot.</summary> + /// <summary>Raised after the player loads a save slot and the world is initialised.</summary> public event EventHandler<SaveLoadedEventArgs> SaveLoaded { add => this.EventManager.SaveLoaded.Add(value); diff --git a/src/SMAPI/Framework/Events/ModSpecialisedEvents.cs b/src/SMAPI/Framework/Events/ModSpecialisedEvents.cs index 17c32bb8..7c3e9dee 100644 --- a/src/SMAPI/Framework/Events/ModSpecialisedEvents.cs +++ b/src/SMAPI/Framework/Events/ModSpecialisedEvents.cs @@ -9,6 +9,13 @@ namespace StardewModdingAPI.Framework.Events /********* ** Accessors *********/ + /// <summary>Raised when the low-level stage in the game's loading process has changed. This is an advanced event for mods which need to run code at specific points in the loading process. The available stages or when they happen might change without warning in future versions (e.g. due to changes in the game's load process), so mods using this event are more likely to break or have bugs. Most mods should use <see cref="IGameLoopEvents"/> instead.</summary> + public event EventHandler<LoadStageChangedEventArgs> LoadStageChanged + { + add => this.EventManager.LoadStageChanged.Add(value); + remove => this.EventManager.LoadStageChanged.Remove(value); + } + /// <summary>Raised before the game state is updated (≈60 times per second), regardless of normal SMAPI validation. This event is not thread-safe and may be invoked while game logic is running asynchronously. Changes to game state in this method may crash the game or corrupt an in-progress save. Do not use this event unless you're fully aware of the context in which your code will be run. Mods using this event will trigger a stability warning in the SMAPI console.</summary> public event EventHandler<UnvalidatedUpdateTickingEventArgs> UnvalidatedUpdateTicking { diff --git a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs index 33557385..a20e1248 100644 --- a/src/SMAPI/Framework/Input/GamePadStateBuilder.cs +++ b/src/SMAPI/Framework/Input/GamePadStateBuilder.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Input internal class GamePadStateBuilder { /********* - ** Properties + ** Fields *********/ /// <summary>The current button states.</summary> private readonly IDictionary<SButton, ButtonState> ButtonStates; diff --git a/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs b/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs index c04bcd1a..ef42e536 100644 --- a/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs +++ b/src/SMAPI/Framework/Logging/ConsoleInterceptionManager.cs @@ -6,7 +6,7 @@ namespace StardewModdingAPI.Framework.Logging internal class ConsoleInterceptionManager : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>The intercepting console writer.</summary> private readonly InterceptingTextWriter Output; diff --git a/src/SMAPI/Framework/Logging/LogFileManager.cs b/src/SMAPI/Framework/Logging/LogFileManager.cs index 8cfe0527..6b5babcd 100644 --- a/src/SMAPI/Framework/Logging/LogFileManager.cs +++ b/src/SMAPI/Framework/Logging/LogFileManager.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Logging internal class LogFileManager : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying stream writer.</summary> private readonly StreamWriter Stream; diff --git a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs index a4fd21c1..e9d53d84 100644 --- a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs @@ -6,7 +6,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class CommandHelper : BaseHelper, ICommandHelper { /********* - ** Properties + ** Fields *********/ /// <summary>The mod using this instance.</summary> private readonly IModMetadata Mod; diff --git a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs index a8b24a13..dac627ba 100644 --- a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs @@ -21,7 +21,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class ContentHelper : BaseHelper, IContentHelper { /********* - ** Properties + ** Fields *********/ /// <summary>SMAPI's core content logic.</summary> private readonly ContentCoordinator ContentCore; diff --git a/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs index 26c4648c..34f24d65 100644 --- a/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ContentPackHelper.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class ContentPackHelper : BaseHelper, IContentPackHelper { /********* - ** Properties + ** Fields *********/ /// <summary>The content packs loaded for this mod.</summary> private readonly Lazy<IContentPack[]> ContentPacks; diff --git a/src/SMAPI/Framework/ModHelpers/DataHelper.cs b/src/SMAPI/Framework/ModHelpers/DataHelper.cs index e5100aed..2cb886ba 100644 --- a/src/SMAPI/Framework/ModHelpers/DataHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/DataHelper.cs @@ -11,7 +11,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class DataHelper : BaseHelper, IDataHelper { /********* - ** Properties + ** Fields *********/ /// <summary>Encapsulates SMAPI's JSON file parsing.</summary> private readonly JsonHelper JsonHelper; @@ -77,9 +77,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <exception cref="InvalidOperationException">The player hasn't loaded a save file yet or isn't the main player.</exception> public TModel ReadSaveData<TModel>(string key) where TModel : class { - if (!Context.IsSaveLoaded) + if (!Game1.hasLoadedGame) throw new InvalidOperationException($"Can't use {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.ReadSaveData)} when a save file isn't loaded."); - if (!Context.IsMainPlayer) + if (!Game1.IsMasterGame) throw new InvalidOperationException($"Can't use {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.ReadSaveData)} because this isn't the main player. (Save files are stored on the main player's computer.)"); return Game1.CustomData.TryGetValue(this.GetSaveFileKey(key), out string value) @@ -94,9 +94,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <exception cref="InvalidOperationException">The player hasn't loaded a save file yet or isn't the main player.</exception> public void WriteSaveData<TModel>(string key, TModel data) where TModel : class { - if (!Context.IsSaveLoaded) + if (!Game1.hasLoadedGame) throw new InvalidOperationException($"Can't use {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.WriteSaveData)} when a save file isn't loaded."); - if (!Context.IsMainPlayer) + if (!Game1.IsMasterGame) throw new InvalidOperationException($"Can't use {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.ReadSaveData)} because this isn't the main player. (Save files are stored on the main player's computer.)"); string internalKey = this.GetSaveFileKey(key); diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index ca872e32..18040a78 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -166,7 +166,7 @@ namespace StardewModdingAPI.Framework.ModHelpers [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.CreateTemporary) + " instead")] public IContentPack CreateTransitionalContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version) { - SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Notice); + SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Info); return this.ContentPacks.CreateTemporary(directoryPath, id, name, description, author, version); } diff --git a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs index 5cc2a20f..8330e078 100644 --- a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class ModRegistryHelper : BaseHelper, IModRegistry { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying mod registry.</summary> private readonly ModRegistry Registry; diff --git a/src/SMAPI/Framework/ModHelpers/MultiplayerHelper.cs b/src/SMAPI/Framework/ModHelpers/MultiplayerHelper.cs index eedad0bc..c62dd121 100644 --- a/src/SMAPI/Framework/ModHelpers/MultiplayerHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/MultiplayerHelper.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class MultiplayerHelper : BaseHelper, IMultiplayerHelper { /********* - ** Properties + ** Fields *********/ /// <summary>SMAPI's core multiplayer utility.</summary> private readonly SMultiplayer Multiplayer; diff --git a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs index cfe2ddbe..0ce72a9e 100644 --- a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class ReflectionHelper : BaseHelper, IReflectionHelper { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying reflection helper.</summary> private readonly Reflector Reflector; diff --git a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs index bbe3a81a..3252e047 100644 --- a/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/TranslationHelper.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModHelpers internal class TranslationHelper : BaseHelper, ITranslationHelper { /********* - ** Properties + ** Fields *********/ /// <summary>The name of the relevant mod for error messages.</summary> private readonly string ModName; diff --git a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs index 91c9e192..aefb0126 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.ModLoading internal class AssemblyDefinitionResolver : DefaultAssemblyResolver { /********* - ** Properties + ** Fields *********/ /// <summary>The known assemblies.</summary> private readonly IDictionary<string, AssemblyDefinition> Lookup = new Dictionary<string, AssemblyDefinition>(); diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 7292cf3f..5e0571a0 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -15,7 +15,7 @@ namespace StardewModdingAPI.Framework.ModLoading internal class AssemblyLoader : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>Encapsulates monitoring and logging.</summary> private readonly IMonitor Monitor; diff --git a/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs index e4beb7a9..898bafb4 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/EventFinder.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class EventFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The full type name for which to find references.</summary> private readonly string FullTypeName; diff --git a/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs index 00805815..606ca8b7 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/FieldFinder.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class FieldFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The full type name for which to find references.</summary> private readonly string FullTypeName; diff --git a/src/SMAPI/Framework/ModLoading/Finders/MethodFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/MethodFinder.cs index 5358f181..9ca246ff 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/MethodFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/MethodFinder.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class MethodFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The full type name for which to find references.</summary> private readonly string FullTypeName; diff --git a/src/SMAPI/Framework/ModLoading/Finders/PropertyFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/PropertyFinder.cs index e54c86cf..0677aa88 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/PropertyFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/PropertyFinder.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class PropertyFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The full type name for which to find references.</summary> private readonly string FullTypeName; diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs index 3a26660f..82c4920a 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class ReferenceToMemberWithUnexpectedTypeFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The assembly names to which to heuristically detect broken references.</summary> private readonly HashSet<string> ValidateReferencesToAssemblies; diff --git a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs index b95dd79c..44b531a5 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders internal class ReferenceToMissingMemberFinder : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The assembly names to which to heuristically detect broken references.</summary> private readonly HashSet<string> ValidateReferencesToAssemblies; diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index ace84054..835b0a54 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -400,7 +400,7 @@ namespace StardewModdingAPI.Framework.ModLoading ** Private models *********/ /// <summary>Represents a dependency from one mod to another.</summary> - private struct ModDependency + private readonly struct ModDependency { /********* ** Accessors diff --git a/src/SMAPI/Framework/ModLoading/RewriteHelper.cs b/src/SMAPI/Framework/ModLoading/RewriteHelper.cs index 9ff43d45..f8f10dc4 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteHelper.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteHelper.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.ModLoading internal static class RewriteHelper { /********* - ** Properties + ** Fields *********/ /// <summary>The comparer which heuristically compares type definitions.</summary> private static readonly TypeReferenceComparer TypeDefinitionComparer = new TypeReferenceComparer(); diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs index 806a074f..ff86c6e2 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldReplaceRewriter.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters internal class FieldReplaceRewriter : FieldFinder { /********* - ** Properties + ** Fields *********/ /// <summary>The new field to reference.</summary> private readonly FieldInfo ToField; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs index e6ede9e3..a43c5e9a 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters internal class FieldToPropertyRewriter : FieldFinder { /********* - ** Properties + ** Fields *********/ /// <summary>The type whose field to which references should be rewritten.</summary> private readonly Type Type; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs index 99bd9125..6b8c2de1 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters internal class MethodParentRewriter : IInstructionHandler { /********* - ** Properties + ** Fields *********/ /// <summary>The type whose methods to remap.</summary> private readonly Type FromType; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/StaticFieldToConstantRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/StaticFieldToConstantRewriter.cs index 5e12b46a..7e7c0efa 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/StaticFieldToConstantRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/StaticFieldToConstantRewriter.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters internal class StaticFieldToConstantRewriter<TValue> : FieldFinder { /********* - ** Properties + ** Fields *********/ /// <summary>The constant value to replace with.</summary> private readonly TValue Value; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index 62e15731..fade082b 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters internal class TypeReferenceRewriter : TypeFinder { /********* - ** Properties + ** Fields *********/ /// <summary>The full type name to which to find references.</summary> private readonly string FromTypeName; diff --git a/src/SMAPI/Framework/ModRegistry.cs b/src/SMAPI/Framework/ModRegistry.cs index 8ce3172c..e9ceb66e 100644 --- a/src/SMAPI/Framework/ModRegistry.cs +++ b/src/SMAPI/Framework/ModRegistry.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework internal class ModRegistry { /********* - ** Properties + ** Fields *********/ /// <summary>The registered mod data.</summary> private readonly List<IModMetadata> Mods = new List<IModMetadata>(); diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index a4d92e4b..47ebc2d7 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework internal class Monitor : IMonitor { /********* - ** Properties + ** Fields *********/ /// <summary>The name of the module which logs messages using this instance.</summary> private readonly string Source; diff --git a/src/SMAPI/Framework/Networking/MultiplayerPeer.cs b/src/SMAPI/Framework/Networking/MultiplayerPeer.cs index 44a71978..b4e39379 100644 --- a/src/SMAPI/Framework/Networking/MultiplayerPeer.cs +++ b/src/SMAPI/Framework/Networking/MultiplayerPeer.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.Networking internal class MultiplayerPeer : IMultiplayerPeer { /********* - ** Properties + ** Fields *********/ /// <summary>A method which sends a message to the peer.</summary> private readonly Action<OutgoingMessage> SendMessageImpl; diff --git a/src/SMAPI/Framework/Networking/SGalaxyNetClient.cs b/src/SMAPI/Framework/Networking/SGalaxyNetClient.cs index fddd423d..01095c66 100644 --- a/src/SMAPI/Framework/Networking/SGalaxyNetClient.cs +++ b/src/SMAPI/Framework/Networking/SGalaxyNetClient.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.Networking internal class SGalaxyNetClient : GalaxyNetClient { /********* - ** Properties + ** Fields *********/ /// <summary>A callback to raise when receiving a message. This receives the incoming message, a method to send an arbitrary message, and a callback to run the default logic.</summary> private readonly Action<IncomingMessage, Action<OutgoingMessage>, Action> OnProcessingMessage; diff --git a/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs b/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs index 82d11938..bb67f70e 100644 --- a/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs +++ b/src/SMAPI/Framework/Networking/SGalaxyNetServer.cs @@ -11,7 +11,7 @@ namespace StardewModdingAPI.Framework.Networking internal class SGalaxyNetServer : GalaxyNetServer { /********* - ** Properties + ** Fields *********/ /// <summary>A callback to raise when receiving a message. This receives the incoming message, a method to send a message, and a callback to run the default logic.</summary> private readonly Action<IncomingMessage, Action<OutgoingMessage>, Action> OnProcessingMessage; diff --git a/src/SMAPI/Framework/Networking/SLidgrenClient.cs b/src/SMAPI/Framework/Networking/SLidgrenClient.cs index 02d9d68f..39876744 100644 --- a/src/SMAPI/Framework/Networking/SLidgrenClient.cs +++ b/src/SMAPI/Framework/Networking/SLidgrenClient.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Networking internal class SLidgrenClient : LidgrenClient { /********* - ** Properties + ** Fields *********/ /// <summary>A callback to raise when receiving a message. This receives the incoming message, a method to send an arbitrary message, and a callback to run the default logic.</summary> private readonly Action<IncomingMessage, Action<OutgoingMessage>, Action> OnProcessingMessage; diff --git a/src/SMAPI/Framework/Networking/SLidgrenServer.cs b/src/SMAPI/Framework/Networking/SLidgrenServer.cs index 251e5268..1bce47fe 100644 --- a/src/SMAPI/Framework/Networking/SLidgrenServer.cs +++ b/src/SMAPI/Framework/Networking/SLidgrenServer.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.Networking internal class SLidgrenServer : LidgrenServer { /********* - ** Properties + ** Fields *********/ /// <summary>SMAPI's implementation of the game's core multiplayer logic.</summary> private readonly SMultiplayer Multiplayer; diff --git a/src/SMAPI/Framework/Patching/GamePatcher.cs b/src/SMAPI/Framework/Patching/GamePatcher.cs index 71ca8e55..f82159d0 100644 --- a/src/SMAPI/Framework/Patching/GamePatcher.cs +++ b/src/SMAPI/Framework/Patching/GamePatcher.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Patching internal class GamePatcher { /********* - ** Properties + ** Fields *********/ /// <summary>Encapsulates monitoring and logging.</summary> private readonly IMonitor Monitor; diff --git a/src/SMAPI/Framework/Reflection/CacheEntry.cs b/src/SMAPI/Framework/Reflection/CacheEntry.cs index 30faca37..912662e3 100644 --- a/src/SMAPI/Framework/Reflection/CacheEntry.cs +++ b/src/SMAPI/Framework/Reflection/CacheEntry.cs @@ -3,16 +3,16 @@ using System.Reflection; namespace StardewModdingAPI.Framework.Reflection { /// <summary>A cached member reflection result.</summary> - internal struct CacheEntry + internal readonly struct CacheEntry { /********* ** Accessors *********/ /// <summary>Whether the lookup found a valid match.</summary> - public bool IsValid; + public bool IsValid { get; } /// <summary>The reflection data for this member (or <c>null</c> if invalid).</summary> - public MemberInfo MemberInfo; + public MemberInfo MemberInfo { get; } /********* diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs index 7a2958fb..70ef81f8 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class InterfaceProxyBuilder { /********* - ** Properties + ** Fields *********/ /// <summary>The target class type.</summary> private readonly Type TargetType; diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs index e14a9f08..464367b6 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class InterfaceProxyFactory { /********* - ** Properties + ** Fields *********/ /// <summary>The CLR module in which to create proxy classes.</summary> private readonly ModuleBuilder ModuleBuilder; diff --git a/src/SMAPI/Framework/Reflection/ReflectedField.cs b/src/SMAPI/Framework/Reflection/ReflectedField.cs index 09638b1d..d771422c 100644 --- a/src/SMAPI/Framework/Reflection/ReflectedField.cs +++ b/src/SMAPI/Framework/Reflection/ReflectedField.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class ReflectedField<TValue> : IReflectedField<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>The type that has the field.</summary> private readonly Type ParentType; diff --git a/src/SMAPI/Framework/Reflection/ReflectedMethod.cs b/src/SMAPI/Framework/Reflection/ReflectedMethod.cs index 7d9072a0..039f27c3 100644 --- a/src/SMAPI/Framework/Reflection/ReflectedMethod.cs +++ b/src/SMAPI/Framework/Reflection/ReflectedMethod.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class ReflectedMethod : IReflectedMethod { /********* - ** Properties + ** Fields *********/ /// <summary>The type that has the method.</summary> private readonly Type ParentType; diff --git a/src/SMAPI/Framework/Reflection/ReflectedProperty.cs b/src/SMAPI/Framework/Reflection/ReflectedProperty.cs index d59b71ac..8a10ff9a 100644 --- a/src/SMAPI/Framework/Reflection/ReflectedProperty.cs +++ b/src/SMAPI/Framework/Reflection/ReflectedProperty.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class ReflectedProperty<TValue> : IReflectedProperty<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>The display name shown in error messages.</summary> private readonly string DisplayName; diff --git a/src/SMAPI/Framework/Reflection/Reflector.cs b/src/SMAPI/Framework/Reflection/Reflector.cs index 910e3a54..ed1a4381 100644 --- a/src/SMAPI/Framework/Reflection/Reflector.cs +++ b/src/SMAPI/Framework/Reflection/Reflector.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.Reflection internal class Reflector { /********* - ** Properties + ** Fields *********/ /// <summary>The cached fields and methods found via reflection.</summary> private readonly MemoryCache Cache = new MemoryCache(typeof(Reflector).FullName); diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 679838ba..27c0c40b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -42,7 +42,7 @@ namespace StardewModdingAPI.Framework internal class SCore : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>The log file to which to write messages.</summary> private readonly LogFileManager LogFile; @@ -181,12 +181,6 @@ namespace StardewModdingAPI.Framework return; } #endif - - // apply game patches - new GamePatcher(this.Monitor).Apply( - new DialogueErrorPatch(this.MonitorForGame, this.Reflection), - new ObjectErrorPatch() - ); } /// <summary>Launch SMAPI.</summary> @@ -237,6 +231,13 @@ namespace StardewModdingAPI.Framework this.GameInstance = new SGame(this.Monitor, this.MonitorForGame, this.Reflection, this.EventManager, this.Toolkit.JsonHelper, this.ModRegistry, SCore.DeprecationManager, this.OnLocaleChanged, this.InitialiseAfterGameStart, this.Dispose); StardewValley.Program.gamePtr = this.GameInstance; + // apply game patches + new GamePatcher(this.Monitor).Apply( + new DialogueErrorPatch(this.MonitorForGame, this.Reflection), + new ObjectErrorPatch(), + new LoadForNewGamePatch(this.Reflection, this.GameInstance.OnLoadStageChanged) + ); + // add exit handler new Thread(() => { @@ -928,7 +929,7 @@ namespace StardewModdingAPI.Framework // add deprecation warning for old version format { if (mod.Manifest?.Version is Toolkit.SemanticVersion version && version.IsLegacyFormat) - SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.Notice); + SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.Info); } #endif diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index d515d3ad..e2835a70 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -39,7 +39,7 @@ namespace StardewModdingAPI.Framework internal class SGame : Game1 { /********* - ** Properties + ** Fields *********/ /**** ** SMAPI state @@ -69,8 +69,8 @@ namespace StardewModdingAPI.Framework /// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks> private readonly Countdown AfterLoadTimer = new Countdown(5); - /// <summary>Whether the after-load events were raised for this session.</summary> - private bool RaisedAfterLoadEvent; + /// <summary>The current stage in the game's loading process.</summary> + private LoadStage LoadStage = LoadStage.None; /// <summary>Whether the game is saving and SMAPI has already raised <see cref="IGameLoopEvents.Saving"/>.</summary> private bool IsBetweenSaveEvents; @@ -96,15 +96,9 @@ namespace StardewModdingAPI.Framework /// <summary>Monitors the entire game state for changes.</summary> private WatcherCore Watchers; - /// <summary>An index incremented on every tick and reset every 60th tick (0–59).</summary> - private int CurrentUpdateTick; - /// <summary>Whether post-game-startup initialisation has been performed.</summary> private bool IsInitialised; - /// <summary>The number of update ticks which have already executed.</summary> - private uint TicksElapsed; - /// <summary>Whether the next content manager requested by the game will be for <see cref="Game1.content"/>.</summary> private bool NextContentManagerIsMain; @@ -213,15 +207,33 @@ namespace StardewModdingAPI.Framework this.Events.ModMessageReceived.RaiseForMods(new ModMessageReceivedEventArgs(message), mod => mod != null && modIDs.Contains(mod.Manifest.UniqueID)); } - /// <summary>A callback raised when the player quits a save and returns to the title screen.</summary> - private void OnReturnedToTitle() + /// <summary>A callback invoked when the game's low-level load stage changes.</summary> + /// <param name="newStage">The new load stage.</param> + internal void OnLoadStageChanged(LoadStage newStage) { - this.Monitor.Log("Context: returned to title", LogLevel.Trace); - this.Multiplayer.CleanupOnMultiplayerExit(); - this.Events.ReturnedToTitle.RaiseEmpty(); + // nothing to do + if (newStage == this.LoadStage) + return; + + // update data + LoadStage oldStage = this.LoadStage; + this.LoadStage = newStage; + if (newStage == LoadStage.None) + { + this.Monitor.Log("Context: returned to title", LogLevel.Trace); + this.Multiplayer.CleanupOnMultiplayerExit(); + } + this.Monitor.VerboseLog($"Context: load stage changed to {newStage}"); + + // raise events + this.Events.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage)); + if (newStage == LoadStage.None) + { + this.Events.ReturnedToTitle.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_AfterReturnToTitle.Raise(); + this.Events.Legacy_AfterReturnToTitle.Raise(); #endif + } } /// <summary>Constructor a content manager to read XNB files.</summary> @@ -253,6 +265,8 @@ namespace StardewModdingAPI.Framework /// <param name="gameTime">A snapshot of the game timing state.</param> protected override void Update(GameTime gameTime) { + var events = this.Events; + try { this.DeprecationManager.PrintQueued(); @@ -280,7 +294,29 @@ namespace StardewModdingAPI.Framework { this.Monitor.Log("Game loader synchronising...", LogLevel.Trace); while (Game1.currentLoader?.MoveNext() == true) - ; + { + // raise load stage changed + switch (Game1.currentLoader.Current) + { + case 20: + this.OnLoadStageChanged(LoadStage.SaveParsed); + break; + + case 36: + this.OnLoadStageChanged(LoadStage.SaveLoadedBasicInfo); + break; + + case 50: + this.OnLoadStageChanged(LoadStage.SaveLoadedLocations); + break; + + default: + if (Game1.gameMode == Game1.playingGameMode) + this.OnLoadStageChanged(LoadStage.Preloaded); + break; + } + } + Game1.currentLoader = null; this.Monitor.Log("Game loader done.", LogLevel.Trace); } @@ -302,11 +338,11 @@ namespace StardewModdingAPI.Framework // update tick are neglible and not worth the complications of bypassing Game1.Update. if (Game1._newDayTask != null || Game1.gameMode == Game1.loadingMode) { - this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed)); + events.UnvalidatedUpdateTicking.RaiseEmpty(); base.Update(gameTime); - this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed)); + events.UnvalidatedUpdateTicked.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_UnvalidatedUpdateTick.Raise(); + events.Legacy_UnvalidatedUpdateTick.Raise(); #endif return; } @@ -376,9 +412,9 @@ namespace StardewModdingAPI.Framework { this.IsBetweenCreateEvents = true; this.Monitor.Log("Context: before save creation.", LogLevel.Trace); - this.Events.SaveCreating.RaiseEmpty(); + events.SaveCreating.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_BeforeCreateSave.Raise(); + events.Legacy_BeforeCreateSave.Raise(); #endif } @@ -387,18 +423,18 @@ namespace StardewModdingAPI.Framework { this.IsBetweenSaveEvents = true; this.Monitor.Log("Context: before save.", LogLevel.Trace); - this.Events.Saving.RaiseEmpty(); + events.Saving.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_BeforeSave.Raise(); + events.Legacy_BeforeSave.Raise(); #endif } // suppress non-save events - this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed)); + events.UnvalidatedUpdateTicking.RaiseEmpty(); base.Update(gameTime); - this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed)); + events.UnvalidatedUpdateTicked.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_UnvalidatedUpdateTick.Raise(); + events.Legacy_UnvalidatedUpdateTick.Raise(); #endif return; } @@ -407,9 +443,10 @@ namespace StardewModdingAPI.Framework // raise after-create this.IsBetweenCreateEvents = false; this.Monitor.Log($"Context: after save creation, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); - this.Events.SaveCreated.RaiseEmpty(); + this.OnLoadStageChanged(LoadStage.CreatedSaveFile); + events.SaveCreated.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_AfterCreateSave.Raise(); + events.Legacy_AfterCreateSave.Raise(); #endif } if (this.IsBetweenSaveEvents) @@ -417,11 +454,11 @@ namespace StardewModdingAPI.Framework // raise after-save this.IsBetweenSaveEvents = false; this.Monitor.Log($"Context: after save, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); - this.Events.Saved.RaiseEmpty(); - this.Events.DayStarted.RaiseEmpty(); + events.Saved.RaiseEmpty(); + events.DayStarted.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_AfterSave.Raise(); - this.Events.Legacy_AfterDayStarted.Raise(); + events.Legacy_AfterSave.Raise(); + events.Legacy_AfterDayStarted.Raise(); #endif } @@ -430,7 +467,10 @@ namespace StardewModdingAPI.Framework *********/ bool wasWorldReady = Context.IsWorldReady; if ((Context.IsWorldReady && !Context.IsSaveLoaded) || Game1.exitToTitle) - this.MarkWorldNotReady(); + { + Context.IsWorldReady = false; + this.AfterLoadTimer.Reset(); + } else if (Context.IsSaveLoaded && this.AfterLoadTimer.Current > 0 && Game1.currentLocation != null) { if (Game1.dayOfMonth != 0) // wait until new-game intro finishes (world not fully initialised yet) @@ -455,7 +495,7 @@ namespace StardewModdingAPI.Framework this.OnLocaleChanged(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_LocaleChanged.Raise(new EventArgsValueChanged<string>(was.ToString(), now.ToString())); + events.Legacy_LocaleChanged.Raise(new EventArgsValueChanged<string>(was.ToString(), now.ToString())); #endif this.Watchers.LocaleWatcher.Reset(); @@ -465,8 +505,8 @@ namespace StardewModdingAPI.Framework ** Load / return-to-title events *********/ if (wasWorldReady && !Context.IsWorldReady) - this.OnReturnedToTitle(); - else if (!this.RaisedAfterLoadEvent && Context.IsWorldReady) + this.OnLoadStageChanged(LoadStage.None); + else if (Context.IsWorldReady && this.LoadStage != LoadStage.Ready) { // print context string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}."; @@ -480,12 +520,12 @@ namespace StardewModdingAPI.Framework this.Monitor.Log(context, LogLevel.Trace); // raise events - this.RaisedAfterLoadEvent = true; - this.Events.SaveLoaded.RaiseEmpty(); - this.Events.DayStarted.RaiseEmpty(); + this.OnLoadStageChanged(LoadStage.Ready); + events.SaveLoaded.RaiseEmpty(); + events.DayStarted.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_AfterLoad.Raise(); - this.Events.Legacy_AfterDayStarted.Raise(); + events.Legacy_AfterLoad.Raise(); + events.Legacy_AfterDayStarted.Raise(); #endif } @@ -504,9 +544,9 @@ namespace StardewModdingAPI.Framework Point oldSize = this.Watchers.WindowSizeWatcher.PreviousValue; Point newSize = this.Watchers.WindowSizeWatcher.CurrentValue; - this.Events.WindowResized.Raise(new WindowResizedEventArgs(oldSize, newSize)); + events.WindowResized.Raise(new WindowResizedEventArgs(oldSize, newSize)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_Resize.Raise(); + events.Legacy_Resize.Raise(); #endif this.Watchers.WindowSizeWatcher.Reset(); } @@ -525,23 +565,33 @@ namespace StardewModdingAPI.Framework // raise cursor moved event if (this.Watchers.CursorWatcher.IsChanged) { - ICursorPosition was = this.Watchers.CursorWatcher.PreviousValue; - ICursorPosition now = this.Watchers.CursorWatcher.CurrentValue; - this.Watchers.CursorWatcher.Reset(); + if (events.CursorMoved.HasListeners()) + { + ICursorPosition was = this.Watchers.CursorWatcher.PreviousValue; + ICursorPosition now = this.Watchers.CursorWatcher.CurrentValue; + this.Watchers.CursorWatcher.Reset(); - this.Events.CursorMoved.Raise(new CursorMovedEventArgs(was, now)); + events.CursorMoved.Raise(new CursorMovedEventArgs(was, now)); + } + else + this.Watchers.CursorWatcher.Reset(); } // raise mouse wheel scrolled if (this.Watchers.MouseWheelScrollWatcher.IsChanged) { - int was = this.Watchers.MouseWheelScrollWatcher.PreviousValue; - int now = this.Watchers.MouseWheelScrollWatcher.CurrentValue; - this.Watchers.MouseWheelScrollWatcher.Reset(); + if (events.MouseWheelScrolled.HasListeners() || this.Monitor.IsVerbose) + { + int was = this.Watchers.MouseWheelScrollWatcher.PreviousValue; + int now = this.Watchers.MouseWheelScrollWatcher.CurrentValue; + this.Watchers.MouseWheelScrollWatcher.Reset(); - if (this.Monitor.IsVerbose) - this.Monitor.Log($"Events: mouse wheel scrolled to {now}.", LogLevel.Trace); - this.Events.MouseWheelScrolled.Raise(new MouseWheelScrolledEventArgs(cursor, was, now)); + if (this.Monitor.IsVerbose) + this.Monitor.Log($"Events: mouse wheel scrolled to {now}.", LogLevel.Trace); + events.MouseWheelScrolled.Raise(new MouseWheelScrolledEventArgs(cursor, was, now)); + } + else + this.Watchers.MouseWheelScrollWatcher.Reset(); } // raise input button events @@ -555,22 +605,22 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log($"Events: button {button} pressed.", LogLevel.Trace); - this.Events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState)); + events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState)); #if !SMAPI_3_0_STRICT // legacy events - this.Events.Legacy_ButtonPressed.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); + events.Legacy_ButtonPressed.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); if (button.TryGetKeyboard(out Keys key)) { if (key != Keys.None) - this.Events.Legacy_KeyPressed.Raise(new EventArgsKeyPressed(key)); + events.Legacy_KeyPressed.Raise(new EventArgsKeyPressed(key)); } else if (button.TryGetController(out Buttons controllerButton)) { if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger) - this.Events.Legacy_ControllerTriggerPressed.Raise(new EventArgsControllerTriggerPressed(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right)); + events.Legacy_ControllerTriggerPressed.Raise(new EventArgsControllerTriggerPressed(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right)); else - this.Events.Legacy_ControllerButtonPressed.Raise(new EventArgsControllerButtonPressed(PlayerIndex.One, controllerButton)); + events.Legacy_ControllerButtonPressed.Raise(new EventArgsControllerButtonPressed(PlayerIndex.One, controllerButton)); } #endif } @@ -579,22 +629,22 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log($"Events: button {button} released.", LogLevel.Trace); - this.Events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState)); + events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState)); #if !SMAPI_3_0_STRICT // legacy events - this.Events.Legacy_ButtonReleased.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); + events.Legacy_ButtonReleased.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); if (button.TryGetKeyboard(out Keys key)) { if (key != Keys.None) - this.Events.Legacy_KeyReleased.Raise(new EventArgsKeyPressed(key)); + events.Legacy_KeyReleased.Raise(new EventArgsKeyPressed(key)); } else if (button.TryGetController(out Buttons controllerButton)) { if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger) - this.Events.Legacy_ControllerTriggerReleased.Raise(new EventArgsControllerTriggerReleased(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right)); + events.Legacy_ControllerTriggerReleased.Raise(new EventArgsControllerTriggerReleased(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right)); else - this.Events.Legacy_ControllerButtonReleased.Raise(new EventArgsControllerButtonReleased(PlayerIndex.One, controllerButton)); + events.Legacy_ControllerButtonReleased.Raise(new EventArgsControllerButtonReleased(PlayerIndex.One, controllerButton)); } #endif } @@ -603,9 +653,9 @@ namespace StardewModdingAPI.Framework #if !SMAPI_3_0_STRICT // raise legacy state-changed events if (inputState.RealKeyboard != previousInputState.RealKeyboard) - this.Events.Legacy_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(previousInputState.RealKeyboard, inputState.RealKeyboard)); + events.Legacy_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(previousInputState.RealKeyboard, inputState.RealKeyboard)); if (inputState.RealMouse != previousInputState.RealMouse) - this.Events.Legacy_MouseChanged.Raise(new EventArgsMouseStateChanged(previousInputState.RealMouse, inputState.RealMouse, new Point((int)previousInputState.CursorPosition.ScreenPixels.X, (int)previousInputState.CursorPosition.ScreenPixels.Y), new Point((int)inputState.CursorPosition.ScreenPixels.X, (int)inputState.CursorPosition.ScreenPixels.Y))); + events.Legacy_MouseChanged.Raise(new EventArgsMouseStateChanged(previousInputState.RealMouse, inputState.RealMouse, new Point((int)previousInputState.CursorPosition.ScreenPixels.X, (int)previousInputState.CursorPosition.ScreenPixels.Y), new Point((int)inputState.CursorPosition.ScreenPixels.X, (int)inputState.CursorPosition.ScreenPixels.Y))); #endif } } @@ -623,12 +673,12 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Context: menu changed from {was?.GetType().FullName ?? "none"} to {now?.GetType().FullName ?? "none"}.", LogLevel.Trace); // raise menu events - this.Events.MenuChanged.Raise(new MenuChangedEventArgs(was, now)); + events.MenuChanged.Raise(new MenuChangedEventArgs(was, now)); #if !SMAPI_3_0_STRICT if (now != null) - this.Events.Legacy_MenuChanged.Raise(new EventArgsClickableMenuChanged(was, now)); + events.Legacy_MenuChanged.Raise(new EventArgsClickableMenuChanged(was, now)); else - this.Events.Legacy_MenuClosed.Raise(new EventArgsClickableMenuClosed(was)); + events.Legacy_MenuClosed.Raise(new EventArgsClickableMenuClosed(was)); #endif } @@ -656,9 +706,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Context: location list changed (added {addedText}; removed {removedText}).", LogLevel.Trace); } - this.Events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed)); + events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_LocationsChanged.Raise(new EventArgsLocationsChanged(added, removed)); + events.Legacy_LocationsChanged.Raise(new EventArgsLocationsChanged(added, removed)); #endif } @@ -675,9 +725,9 @@ namespace StardewModdingAPI.Framework Building[] removed = watcher.BuildingsWatcher.Removed.ToArray(); watcher.BuildingsWatcher.Reset(); - this.Events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, added, removed)); + events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, added, removed)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_BuildingsChanged.Raise(new EventArgsLocationBuildingsChanged(location, added, removed)); + events.Legacy_BuildingsChanged.Raise(new EventArgsLocationBuildingsChanged(location, added, removed)); #endif } @@ -689,7 +739,7 @@ namespace StardewModdingAPI.Framework Debris[] removed = watcher.DebrisWatcher.Removed.ToArray(); watcher.DebrisWatcher.Reset(); - this.Events.DebrisListChanged.Raise(new DebrisListChangedEventArgs(location, added, removed)); + events.DebrisListChanged.Raise(new DebrisListChangedEventArgs(location, added, removed)); } // large terrain features changed @@ -700,7 +750,7 @@ namespace StardewModdingAPI.Framework LargeTerrainFeature[] removed = watcher.LargeTerrainFeaturesWatcher.Removed.ToArray(); watcher.LargeTerrainFeaturesWatcher.Reset(); - this.Events.LargeTerrainFeatureListChanged.Raise(new LargeTerrainFeatureListChangedEventArgs(location, added, removed)); + events.LargeTerrainFeatureListChanged.Raise(new LargeTerrainFeatureListChangedEventArgs(location, added, removed)); } // NPCs changed @@ -711,7 +761,7 @@ namespace StardewModdingAPI.Framework NPC[] removed = watcher.NpcsWatcher.Removed.ToArray(); watcher.NpcsWatcher.Reset(); - this.Events.NpcListChanged.Raise(new NpcListChangedEventArgs(location, added, removed)); + events.NpcListChanged.Raise(new NpcListChangedEventArgs(location, added, removed)); } // objects changed @@ -722,9 +772,9 @@ namespace StardewModdingAPI.Framework KeyValuePair<Vector2, SObject>[] removed = watcher.ObjectsWatcher.Removed.ToArray(); watcher.ObjectsWatcher.Reset(); - this.Events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, added, removed)); + events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, added, removed)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed)); + events.Legacy_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed)); #endif } @@ -736,7 +786,7 @@ namespace StardewModdingAPI.Framework KeyValuePair<Vector2, TerrainFeature>[] removed = watcher.TerrainFeaturesWatcher.Removed.ToArray(); watcher.TerrainFeaturesWatcher.Reset(); - this.Events.TerrainFeatureListChanged.Raise(new TerrainFeatureListChangedEventArgs(location, added, removed)); + events.TerrainFeatureListChanged.Raise(new TerrainFeatureListChangedEventArgs(location, added, removed)); } } } @@ -754,9 +804,9 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log($"Events: time changed from {was} to {now}.", LogLevel.Trace); - this.Events.TimeChanged.Raise(new TimeChangedEventArgs(was, now)); + events.TimeChanged.Raise(new TimeChangedEventArgs(was, now)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_TimeOfDayChanged.Raise(new EventArgsIntChanged(was, now)); + events.Legacy_TimeOfDayChanged.Raise(new EventArgsIntChanged(was, now)); #endif } else @@ -774,9 +824,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Context: set location to {newLocation.Name}.", LogLevel.Trace); GameLocation oldLocation = playerTracker.LocationWatcher.PreviousValue; - this.Events.Warped.Raise(new WarpedEventArgs(playerTracker.Player, oldLocation, newLocation)); + events.Warped.Raise(new WarpedEventArgs(playerTracker.Player, oldLocation, newLocation)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_PlayerWarped.Raise(new EventArgsPlayerWarped(oldLocation, newLocation)); + events.Legacy_PlayerWarped.Raise(new EventArgsPlayerWarped(oldLocation, newLocation)); #endif } @@ -786,9 +836,9 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log($"Events: player skill '{pair.Key}' changed from {pair.Value.PreviousValue} to {pair.Value.CurrentValue}.", LogLevel.Trace); - this.Events.LevelChanged.Raise(new LevelChangedEventArgs(playerTracker.Player, pair.Key, pair.Value.PreviousValue, pair.Value.CurrentValue)); + events.LevelChanged.Raise(new LevelChangedEventArgs(playerTracker.Player, pair.Key, pair.Value.PreviousValue, pair.Value.CurrentValue)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_LeveledUp.Raise(new EventArgsLevelUp((EventArgsLevelUp.LevelType)pair.Key, pair.Value.CurrentValue)); + events.Legacy_LeveledUp.Raise(new EventArgsLevelUp((EventArgsLevelUp.LevelType)pair.Key, pair.Value.CurrentValue)); #endif } @@ -798,9 +848,9 @@ namespace StardewModdingAPI.Framework { if (this.Monitor.IsVerbose) this.Monitor.Log("Events: player inventory changed.", LogLevel.Trace); - this.Events.InventoryChanged.Raise(new InventoryChangedEventArgs(playerTracker.Player, changedItems)); + events.InventoryChanged.Raise(new InventoryChangedEventArgs(playerTracker.Player, changedItems)); #if !SMAPI_3_0_STRICT - this.Events.Legacy_InventoryChanged.Raise(new EventArgsInventoryChanged(Game1.player.Items, changedItems)); + events.Legacy_InventoryChanged.Raise(new EventArgsInventoryChanged(Game1.player.Items, changedItems)); #endif } @@ -810,7 +860,7 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log($"Context: mine level changed to {mineLevel}.", LogLevel.Trace); #if !SMAPI_3_0_STRICT - this.Events.Legacy_MineLevelChanged.Raise(new EventArgsMineLevelChanged(playerTracker.MineLevelWatcher.PreviousValue, mineLevel)); + events.Legacy_MineLevelChanged.Raise(new EventArgsMineLevelChanged(playerTracker.MineLevelWatcher.PreviousValue, mineLevel)); #endif } } @@ -823,11 +873,21 @@ namespace StardewModdingAPI.Framework /********* ** Game update *********/ - this.TicksElapsed++; - if (this.TicksElapsed == 1) - this.Events.GameLaunched.Raise(new GameLaunchedEventArgs()); - this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed)); - this.Events.UpdateTicking.Raise(new UpdateTickingEventArgs(this.TicksElapsed)); + // game launched + bool isFirstTick = Game1.ticks == 0; + if (isFirstTick) + events.GameLaunched.Raise(new GameLaunchedEventArgs()); + + // preloaded + if (Context.IsSaveLoaded && this.LoadStage != LoadStage.Loaded && this.LoadStage != LoadStage.Ready) + this.OnLoadStageChanged(LoadStage.Loaded); + + // update tick + bool isOneSecond = Game1.ticks % 60 == 0; + events.UnvalidatedUpdateTicking.RaiseEmpty(); + events.UpdateTicking.RaiseEmpty(); + if (isOneSecond) + events.OneSecondUpdateTicking.RaiseEmpty(); try { this.Input.UpdateSuppression(); @@ -837,33 +897,32 @@ namespace StardewModdingAPI.Framework { this.MonitorForGame.Log($"An error occured in the base update loop: {ex.GetLogSummary()}", LogLevel.Error); } - this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed)); - this.Events.UpdateTicked.Raise(new UpdateTickedEventArgs(this.TicksElapsed)); + events.UnvalidatedUpdateTicked.RaiseEmpty(); + events.UpdateTicked.RaiseEmpty(); + if (isOneSecond) + events.OneSecondUpdateTicked.RaiseEmpty(); /********* ** Update events *********/ #if !SMAPI_3_0_STRICT - this.Events.Legacy_UnvalidatedUpdateTick.Raise(); - if (this.TicksElapsed == 1) - this.Events.Legacy_FirstUpdateTick.Raise(); - this.Events.Legacy_UpdateTick.Raise(); - if (this.CurrentUpdateTick % 2 == 0) - this.Events.Legacy_SecondUpdateTick.Raise(); - if (this.CurrentUpdateTick % 4 == 0) - this.Events.Legacy_FourthUpdateTick.Raise(); - if (this.CurrentUpdateTick % 8 == 0) - this.Events.Legacy_EighthUpdateTick.Raise(); - if (this.CurrentUpdateTick % 15 == 0) - this.Events.Legacy_QuarterSecondTick.Raise(); - if (this.CurrentUpdateTick % 30 == 0) - this.Events.Legacy_HalfSecondTick.Raise(); - if (this.CurrentUpdateTick % 60 == 0) - this.Events.Legacy_OneSecondTick.Raise(); + events.Legacy_UnvalidatedUpdateTick.Raise(); + if (isFirstTick) + events.Legacy_FirstUpdateTick.Raise(); + events.Legacy_UpdateTick.Raise(); + if (Game1.ticks % 2 == 0) + events.Legacy_SecondUpdateTick.Raise(); + if (Game1.ticks % 4 == 0) + events.Legacy_FourthUpdateTick.Raise(); + if (Game1.ticks % 8 == 0) + events.Legacy_EighthUpdateTick.Raise(); + if (Game1.ticks % 15 == 0) + events.Legacy_QuarterSecondTick.Raise(); + if (Game1.ticks % 30 == 0) + events.Legacy_HalfSecondTick.Raise(); + if (Game1.ticks % 60 == 0) + events.Legacy_OneSecondTick.Raise(); #endif - this.CurrentUpdateTick += 1; - if (this.CurrentUpdateTick >= 60) - this.CurrentUpdateTick = 0; this.UpdateCrashTimer.Reset(); } @@ -931,10 +990,10 @@ namespace StardewModdingAPI.Framework [SuppressMessage("SMAPI.CommonErrors", "AvoidImplicitNetFieldCast", Justification = "copied from game code as-is")] private void DrawImpl(GameTime gameTime) { + var events = this.Events; + if (Game1._newDayTask != null) - { this.GraphicsDevice.Clear(this.bgColor); - } else { if ((double)Game1.options.zoomLevel != 1.0) @@ -946,17 +1005,17 @@ namespace StardewModdingAPI.Framework if (activeClickableMenu != null) { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); try { - this.Events.RenderingActiveMenu.RaiseEmpty(); + events.RenderingActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderGuiEvent.Raise(); + events.Legacy_OnPreRenderGuiEvent.Raise(); #endif activeClickableMenu.draw(Game1.spriteBatch); - this.Events.RenderedActiveMenu.RaiseEmpty(); + events.RenderedActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderGuiEvent.Raise(); + events.Legacy_OnPostRenderGuiEvent.Raise(); #endif } catch (Exception ex) @@ -964,9 +1023,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"The {activeClickableMenu.GetType().FullName} menu crashed while drawing itself during save. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error); activeClickableMenu.exitThisMenu(); } - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderEvent.Raise(); + events.Legacy_OnPostRenderEvent.Raise(); #endif Game1.spriteBatch.End(); @@ -986,18 +1045,18 @@ namespace StardewModdingAPI.Framework { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); try { Game1.activeClickableMenu.drawBackground(Game1.spriteBatch); - this.Events.RenderingActiveMenu.RaiseEmpty(); + events.RenderingActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderGuiEvent.Raise(); + events.Legacy_OnPreRenderGuiEvent.Raise(); #endif Game1.activeClickableMenu.draw(Game1.spriteBatch); - this.Events.RenderedActiveMenu.RaiseEmpty(); + events.RenderedActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderGuiEvent.Raise(); + events.Legacy_OnPostRenderGuiEvent.Raise(); #endif } catch (Exception ex) @@ -1005,9 +1064,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"The {Game1.activeClickableMenu.GetType().FullName} menu crashed while drawing itself. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error); Game1.activeClickableMenu.exitThisMenu(); } - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderEvent.Raise(); + events.Legacy_OnPostRenderEvent.Raise(); #endif Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); @@ -1028,13 +1087,13 @@ namespace StardewModdingAPI.Framework else if (Game1.gameMode == (byte)11) { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.content.LoadString("Strings\\StringsFromCSFiles:Game1.cs.3685"), new Vector2(16f, 16f), Color.HotPink); Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.content.LoadString("Strings\\StringsFromCSFiles:Game1.cs.3686"), new Vector2(16f, 32f), new Color(0, (int)byte.MaxValue, 0)); Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.parseText(Game1.errorMessage, Game1.dialogueFont, Game1.graphics.GraphicsDevice.Viewport.Width), new Vector2(16f, 48f), Color.White); - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderEvent.Raise(); + events.Legacy_OnPostRenderEvent.Raise(); #endif Game1.spriteBatch.End(); } @@ -1062,19 +1121,19 @@ namespace StardewModdingAPI.Framework else if (Game1.showingEndOfNightStuff) { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); if (Game1.activeClickableMenu != null) { try { - this.Events.RenderingActiveMenu.RaiseEmpty(); + events.RenderingActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderGuiEvent.Raise(); + events.Legacy_OnPreRenderGuiEvent.Raise(); #endif Game1.activeClickableMenu.draw(Game1.spriteBatch); - this.Events.RenderedActiveMenu.RaiseEmpty(); + events.RenderedActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderGuiEvent.Raise(); + events.Legacy_OnPostRenderGuiEvent.Raise(); #endif } catch (Exception ex) @@ -1083,7 +1142,7 @@ namespace StardewModdingAPI.Framework Game1.activeClickableMenu.exitThisMenu(); } } - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); if ((double)Game1.options.zoomLevel == 1.0) @@ -1097,7 +1156,7 @@ namespace StardewModdingAPI.Framework else if (Game1.gameMode == (byte)6 || Game1.gameMode == (byte)3 && Game1.currentLocation == null) { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); string str1 = ""; for (int index = 0; (double)index < gameTime.TotalGameTime.TotalMilliseconds % 999.0 / 333.0; ++index) str1 += "."; @@ -1109,7 +1168,7 @@ namespace StardewModdingAPI.Framework int x = 64; int y = Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Bottom - height; SpriteText.drawString(Game1.spriteBatch, s, x, y, 999999, widthOfString, height, 1f, 0.88f, false, 0, str3, -1); - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); if ((double)Game1.options.zoomLevel != 1.0) @@ -1138,7 +1197,7 @@ namespace StardewModdingAPI.Framework { Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); if (++batchOpens == 1) - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); } else { @@ -1148,7 +1207,7 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.Clear(Color.White * 0.0f); Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); if (++batchOpens == 1) - this.Events.Rendering.RaiseEmpty(); + events.Rendering.RaiseEmpty(); Game1.spriteBatch.Draw(Game1.staminaRect, Game1.lightmap.Bounds, Game1.currentLocation.Name.StartsWith("UndergroundMine") ? Game1.mine.getLightingColor(gameTime) : (Game1.ambientLight.Equals(Color.White) || Game1.isRaining && (bool)((NetFieldBase<bool, NetBool>)Game1.currentLocation.isOutdoors) ? Game1.outdoorLight : Game1.ambientLight)); for (int index = 0; index < Game1.currentLightSources.Count; ++index) { @@ -1163,10 +1222,10 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.Clear(this.bgColor); Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); if (++batchOpens == 1) - this.Events.Rendering.RaiseEmpty(); - this.Events.RenderingWorld.RaiseEmpty(); + events.Rendering.RaiseEmpty(); + events.RenderingWorld.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderEvent.Raise(); + events.Legacy_OnPreRenderEvent.Raise(); #endif if (Game1.background != null) Game1.background.draw(Game1.spriteBatch); @@ -1423,7 +1482,7 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.End(); } Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); - this.Events.RenderedWorld.RaiseEmpty(); + events.RenderedWorld.RaiseEmpty(); if (Game1.drawGrid) { int num1 = -Game1.viewport.X % 64; @@ -1479,14 +1538,14 @@ namespace StardewModdingAPI.Framework this.drawBillboard(); if ((Game1.displayHUD || Game1.eventUp) && (Game1.currentBillboard == 0 && Game1.gameMode == (byte)3) && (!Game1.freezeControls && !Game1.panMode && !Game1.HostPaused)) { - this.Events.RenderingHud.RaiseEmpty(); + events.RenderingHud.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderHudEvent.Raise(); + events.Legacy_OnPreRenderHudEvent.Raise(); #endif this.drawHUD(); - this.Events.RenderedHud.RaiseEmpty(); + events.RenderedHud.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderHudEvent.Raise(); + events.Legacy_OnPostRenderHudEvent.Raise(); #endif } else if (Game1.activeClickableMenu == null && Game1.farmEvent == null) @@ -1595,14 +1654,14 @@ namespace StardewModdingAPI.Framework { try { - this.Events.RenderingActiveMenu.RaiseEmpty(); + events.RenderingActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPreRenderGuiEvent.Raise(); + events.Legacy_OnPreRenderGuiEvent.Raise(); #endif Game1.activeClickableMenu.draw(Game1.spriteBatch); - this.Events.RenderedActiveMenu.RaiseEmpty(); + events.RenderedActiveMenu.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderGuiEvent.Raise(); + events.Legacy_OnPostRenderGuiEvent.Raise(); #endif } catch (Exception ex) @@ -1619,9 +1678,9 @@ namespace StardewModdingAPI.Framework SpriteText.drawStringWithScrollBackground(Game1.spriteBatch, s, 96, 32, "", 1f, -1); } - this.Events.Rendered.RaiseEmpty(); + events.Rendered.RaiseEmpty(); #if !SMAPI_3_0_STRICT - this.Events.Legacy_OnPostRenderEvent.Raise(); + events.Legacy_OnPostRenderEvent.Raise(); #endif Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); @@ -1634,14 +1693,6 @@ namespace StardewModdingAPI.Framework /**** ** Methods ****/ - /// <summary>Perform any cleanup needed when a save is unloaded.</summary> - private void MarkWorldNotReady() - { - Context.IsWorldReady = false; - this.AfterLoadTimer.Reset(); - this.RaisedAfterLoadEvent = false; - } - #if !SMAPI_3_0_STRICT /// <summary>Raise the <see cref="GraphicsEvents.OnPostRenderEvent"/> if there are any listeners.</summary> /// <param name="needsNewBatch">Whether to create a new sprite batch.</param> diff --git a/src/SMAPI/Framework/SModHooks.cs b/src/SMAPI/Framework/SModHooks.cs index 9f0201c8..7dafc746 100644 --- a/src/SMAPI/Framework/SModHooks.cs +++ b/src/SMAPI/Framework/SModHooks.cs @@ -7,7 +7,7 @@ namespace StardewModdingAPI.Framework internal class SModHooks : ModHooks { /********* - ** Properties + ** Fields *********/ /// <summary>A callback to invoke before <see cref="Game1.newDayAfterFade"/> runs.</summary> private readonly Action BeforeNewDayAfterFade; diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs index 29d9b2b8..0241ef02 100644 --- a/src/SMAPI/Framework/SMultiplayer.cs +++ b/src/SMAPI/Framework/SMultiplayer.cs @@ -31,7 +31,7 @@ namespace StardewModdingAPI.Framework internal class SMultiplayer : Multiplayer { /********* - ** Properties + ** Fields *********/ /// <summary>Encapsulates monitoring and logging.</summary> private readonly IMonitor Monitor; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/BaseDisposableWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/BaseDisposableWatcher.cs index 40ec6c57..60006c51 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/BaseDisposableWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/BaseDisposableWatcher.cs @@ -6,7 +6,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers internal abstract class BaseDisposableWatcher : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>Whether the watcher has been disposed.</summary> protected bool IsDisposed { get; private set; } diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs index 2ea6609a..6550f950 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers internal class ComparableListWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>The collection to watch.</summary> private readonly ICollection<TValue> CurrentValues; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs index dda30a15..5ca4b9f4 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers internal class ComparableWatcher<TValue> : IValueWatcher<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>Get the current value.</summary> private readonly Func<TValue> GetValue; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs index d3022a69..21e84c47 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs @@ -9,7 +9,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers where TValue : class, INetObject<INetSerializable> { /********* - ** Properties + ** Fields *********/ /// <summary>The field being watched.</summary> private readonly NetCollection<TValue> Field; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs index 7a7ab89d..e6882f7e 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs @@ -15,7 +15,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers where TSelf : NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> { /********* - ** Properties + ** Fields *********/ /// <summary>The pairs added since the last reset.</summary> private readonly IDictionary<TKey, TValue> PairsAdded = new Dictionary<TKey, TValue>(); diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs index 85099988..48d5d681 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs @@ -8,7 +8,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers internal class NetValueWatcher<TValue, TNetField> : BaseDisposableWatcher, IValueWatcher<TValue> where TNetField : NetFieldBase<TValue, TNetField> { /********* - ** Properties + ** Fields *********/ /// <summary>The field being watched.</summary> private readonly NetFieldBase<TValue, TNetField> Field; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs index 0c65789f..883b1023 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers internal class ObservableCollectionWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue> { /********* - ** Properties + ** Fields *********/ /// <summary>The field being watched.</summary> private readonly ObservableCollection<TValue> Field; diff --git a/src/SMAPI/Framework/StateTracking/LocationTracker.cs b/src/SMAPI/Framework/StateTracking/LocationTracker.cs index 708c0716..2249e41b 100644 --- a/src/SMAPI/Framework/StateTracking/LocationTracker.cs +++ b/src/SMAPI/Framework/StateTracking/LocationTracker.cs @@ -15,7 +15,7 @@ namespace StardewModdingAPI.Framework.StateTracking internal class LocationTracker : IWatcher { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying watchers.</summary> private readonly List<IWatcher> Watchers = new List<IWatcher>(); diff --git a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs index 6a705e50..abb4fa24 100644 --- a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs +++ b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking internal class PlayerTracker : IDisposable { /********* - ** Properties + ** Fields *********/ /// <summary>The player's inventory as of the last reset.</summary> private IDictionary<Item, int> PreviousInventory; diff --git a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs index 930a8102..f09c69c1 100644 --- a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs +++ b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs @@ -13,7 +13,7 @@ namespace StardewModdingAPI.Framework.StateTracking internal class WorldLocationsTracker : IWatcher { /********* - ** Properties + ** Fields *********/ /// <summary>Tracks changes to the location list.</summary> private readonly ICollectionWatcher<GameLocation> LocationListWatcher; diff --git a/src/SMAPI/Framework/WatcherCore.cs b/src/SMAPI/Framework/WatcherCore.cs index 8d29cf18..32b7fdc6 100644 --- a/src/SMAPI/Framework/WatcherCore.cs +++ b/src/SMAPI/Framework/WatcherCore.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework internal class WatcherCore { /********* - ** Properties + ** Fields *********/ /// <summary>The underlying watchers for convenience. These are accessible individually as separate properties.</summary> private readonly List<IWatcher> Watchers = new List<IWatcher>(); |