diff options
Diffstat (limited to 'src/SMAPI/Framework')
15 files changed, 110 insertions, 52 deletions
diff --git a/src/SMAPI/Framework/StateTracking/ChestTracker.cs b/src/SMAPI/Framework/StateTracking/ChestTracker.cs index c33a7498..2796ad54 100644 --- a/src/SMAPI/Framework/StateTracking/ChestTracker.cs +++ b/src/SMAPI/Framework/StateTracking/ChestTracker.cs @@ -39,11 +39,12 @@ namespace StardewModdingAPI.Framework.StateTracking ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="chest">The chest being tracked.</param> - public ChestTracker(Chest chest) + public ChestTracker(string name, Chest chest) { this.Chest = chest; - this.InventoryWatcher = WatcherFactory.ForNetList(chest.items); + this.InventoryWatcher = WatcherFactory.ForNetList($"{name}.{nameof(chest.items)}", chest.items); this.StackSizes = this.Chest.items .Where(n => n != null) diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs index 3d178a36..0b13434a 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs @@ -27,6 +27,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0; /// <inheritdoc /> @@ -40,10 +43,12 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="values">The collection to watch.</param> /// <param name="comparer">The equality comparer which indicates whether two values are the same.</param> - public ComparableListWatcher(ICollection<TValue> values, IEqualityComparer<TValue> comparer) + public ComparableListWatcher(string name, ICollection<TValue> values, IEqualityComparer<TValue> comparer) { + this.Name = name; this.CurrentValues = values; this.LastValues = new HashSet<TValue>(comparer); } diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs index e51c46c1..e2f6c7fd 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs @@ -21,6 +21,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public TValue PreviousValue { get; private set; } /// <inheritdoc /> @@ -34,10 +37,12 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="getValue">Get the current value.</param> /// <param name="comparer">The equality comparer which indicates whether two values are the same.</param> - public ComparableWatcher(Func<TValue> getValue, IEqualityComparer<TValue> comparer) + public ComparableWatcher(string name, Func<TValue> getValue, IEqualityComparer<TValue> comparer) { + this.Name = name; this.GetValue = getValue; this.Comparer = comparer; this.CurrentValue = getValue(); diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs index b46e0b24..9c2ba9bc 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs @@ -14,6 +14,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers public static ImmutableCollectionWatcher<TValue> Instance { get; } = new(); /// <inheritdoc /> + public string Name => nameof(ImmutableCollectionWatcher<TValue>); + + /// <inheritdoc /> public bool IsChanged { get; } = false; /// <inheritdoc /> diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs index e278fa99..1d5e4851 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs @@ -25,6 +25,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0; /// <inheritdoc /> @@ -38,9 +41,11 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The field to watch.</param> - public NetCollectionWatcher(NetCollection<TValue> field) + public NetCollectionWatcher(string name, NetCollection<TValue> field) { + this.Name = name; this.Field = field; field.OnValueAdded += this.OnValueAdded; field.OnValueRemoved += this.OnValueRemoved; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs index a0fcc236..3bd8e09d 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs @@ -32,6 +32,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.PairsAdded.Count > 0 || this.PairsRemoved.Count > 0; /// <inheritdoc /> @@ -45,9 +48,11 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The field to watch.</param> - public NetDictionaryWatcher(NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> field) + public NetDictionaryWatcher(string name, NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> field) { + this.Name = name; this.Field = field; field.OnValueAdded += this.OnValueAdded; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetListWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetListWatcher.cs index 3badb533..5b6a3e1f 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetListWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetListWatcher.cs @@ -26,6 +26,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0; /// <inheritdoc /> @@ -39,9 +42,11 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The field to watch.</param> - public NetListWatcher(NetList<TValue, NetRef<TValue>> field) + public NetListWatcher(string name, NetList<TValue, NetRef<TValue>> field) { + this.Name = name; this.Field = field; field.OnElementChanged += this.OnElementChanged; field.OnArrayReplaced += this.OnArrayReplaced; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs index d00f4582..e4219dda 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetValueWatcher.cs @@ -18,6 +18,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged { get; private set; } /// <inheritdoc /> @@ -31,9 +34,11 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The field to watch.</param> - public NetValueWatcher(NetFieldBase<TValue, TNetField> field) + public NetValueWatcher(string name, NetFieldBase<TValue, TNetField> field) { + this.Name = name; this.Field = field; this.PreviousValue = field.Value; this.CurrentValue = field.Value; diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs index f503c47f..1f95ac89 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs @@ -29,6 +29,9 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0; /// <inheritdoc /> @@ -42,9 +45,11 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Public methods *********/ /// <summary>Construct an instance.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The field to watch.</param> - public ObservableCollectionWatcher(ObservableCollection<TValue> field) + public ObservableCollectionWatcher(string name, ObservableCollection<TValue> field) { + this.Name = name; this.Field = field; field.CollectionChanged += this.OnCollectionChanged; } diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs index c4a4d0b9..c31be1fc 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs @@ -17,37 +17,41 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ****/ /// <summary>Get a watcher which compares values using their <see cref="object.Equals(object)"/> method. This method should only be used when <see cref="ForEquatable{T}"/> won't work, since this doesn't validate whether they're comparable.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="getValue">Get the current value.</param> - public static IValueWatcher<T> ForGenericEquality<T>(Func<T> getValue) + public static IValueWatcher<T> ForGenericEquality<T>(string name, Func<T> getValue) where T : struct { - return new ComparableWatcher<T>(getValue, new GenericEqualsComparer<T>()); + return new ComparableWatcher<T>(name, getValue, new GenericEqualsComparer<T>()); } /// <summary>Get a watcher for an <see cref="IEquatable{T}"/> value.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="getValue">Get the current value.</param> - public static IValueWatcher<T> ForEquatable<T>(Func<T> getValue) + public static IValueWatcher<T> ForEquatable<T>(string name, Func<T> getValue) where T : IEquatable<T> { - return new ComparableWatcher<T>(getValue, new EquatableComparer<T>()); + return new ComparableWatcher<T>(name, getValue, new EquatableComparer<T>()); } /// <summary>Get a watcher which detects when an object reference changes.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="getValue">Get the current value.</param> - public static IValueWatcher<T> ForReference<T>(Func<T> getValue) + public static IValueWatcher<T> ForReference<T>(string name, Func<T> getValue) { - return new ComparableWatcher<T>(getValue, new ObjectReferenceComparer<T>()); + return new ComparableWatcher<T>(name, getValue, new ObjectReferenceComparer<T>()); } /// <summary>Get a watcher for a net collection.</summary> /// <typeparam name="T">The value type.</typeparam> /// <typeparam name="TSelf">The net field instance type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="field">The net collection.</param> - public static IValueWatcher<T> ForNetValue<T, TSelf>(NetFieldBase<T, TSelf> field) where TSelf : NetFieldBase<T, TSelf> + public static IValueWatcher<T> ForNetValue<T, TSelf>(string name, NetFieldBase<T, TSelf> field) where TSelf : NetFieldBase<T, TSelf> { - return new NetValueWatcher<T, TSelf>(field); + return new NetValueWatcher<T, TSelf>(name, field); } /**** @@ -55,18 +59,20 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ****/ /// <summary>Get a watcher which detects when an object reference in a collection changes.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="collection">The observable collection.</param> - public static ICollectionWatcher<T> ForReferenceList<T>(ICollection<T> collection) + public static ICollectionWatcher<T> ForReferenceList<T>(string name, ICollection<T> collection) { - return new ComparableListWatcher<T>(collection, new ObjectReferenceComparer<T>()); + return new ComparableListWatcher<T>(name, collection, new ObjectReferenceComparer<T>()); } /// <summary>Get a watcher for an observable collection.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="collection">The observable collection.</param> - public static ICollectionWatcher<T> ForObservableCollection<T>(ObservableCollection<T> collection) + public static ICollectionWatcher<T> ForObservableCollection<T>(string name, ObservableCollection<T> collection) { - return new ObservableCollectionWatcher<T>(collection); + return new ObservableCollectionWatcher<T>(name, collection); } /// <summary>Get a watcher for a collection that never changes.</summary> @@ -78,36 +84,39 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher for a net collection.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="collection">The net collection.</param> - public static ICollectionWatcher<T> ForNetCollection<T>(NetCollection<T> collection) + public static ICollectionWatcher<T> ForNetCollection<T>(string name, NetCollection<T> collection) where T : class, INetObject<INetSerializable> { - return new NetCollectionWatcher<T>(collection); + return new NetCollectionWatcher<T>(name, collection); } /// <summary>Get a watcher for a net list.</summary> /// <typeparam name="T">The value type.</typeparam> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <param name="collection">The net list.</param> - public static ICollectionWatcher<T> ForNetList<T>(NetList<T, NetRef<T>> collection) + public static ICollectionWatcher<T> ForNetList<T>(string name, NetList<T, NetRef<T>> collection) where T : class, INetObject<INetSerializable> { - return new NetListWatcher<T>(collection); + return new NetListWatcher<T>(name, collection); } /// <summary>Get a watcher for a net dictionary.</summary> + /// <param name="name">A name which identifies what the watcher is watching, used for troubleshooting.</param> /// <typeparam name="TKey">The dictionary key type.</typeparam> /// <typeparam name="TValue">The dictionary value type.</typeparam> /// <typeparam name="TField">The net type equivalent to <typeparamref name="TValue"/>.</typeparam> /// <typeparam name="TSerialDict">The serializable dictionary type that can store the keys and values.</typeparam> /// <typeparam name="TSelf">The net field instance type.</typeparam> /// <param name="field">The net field.</param> - public static NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf> ForNetDictionary<TKey, TValue, TField, TSerialDict, TSelf>(NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> field) + public static NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf> ForNetDictionary<TKey, TValue, TField, TSerialDict, TSelf>(string name, NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> field) where TKey : notnull where TField : class, INetObject<INetSerializable>, new() where TSerialDict : IDictionary<TKey, TValue>, new() where TSelf : NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> { - return new NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf>(field); + return new NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf>(name, field); } } } diff --git a/src/SMAPI/Framework/StateTracking/IWatcher.cs b/src/SMAPI/Framework/StateTracking/IWatcher.cs index 8c7fa51c..4a0e3998 100644 --- a/src/SMAPI/Framework/StateTracking/IWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/IWatcher.cs @@ -8,6 +8,9 @@ namespace StardewModdingAPI.Framework.StateTracking /********* ** Accessors *********/ + /// <summary>A name which identifies what the watcher is watching, used for troubleshooting.</summary> + string Name { get; } + /// <summary>Whether the value changed since the last reset.</summary> bool IsChanged { get; } diff --git a/src/SMAPI/Framework/StateTracking/LocationTracker.cs b/src/SMAPI/Framework/StateTracking/LocationTracker.cs index 036ed73a..790c71dd 100644 --- a/src/SMAPI/Framework/StateTracking/LocationTracker.cs +++ b/src/SMAPI/Framework/StateTracking/LocationTracker.cs @@ -26,6 +26,9 @@ namespace StardewModdingAPI.Framework.StateTracking ** Accessors *********/ /// <inheritdoc /> + public string Name { get; } + + /// <inheritdoc /> public bool IsChanged => this.Watchers.Any(p => p.IsChanged); /// <summary>The tracked location.</summary> @@ -63,16 +66,17 @@ namespace StardewModdingAPI.Framework.StateTracking /// <param name="location">The location to track.</param> public LocationTracker(GameLocation location) { + this.Name = $"Locations.{location.NameOrUniqueName}"; this.Location = location; // init watchers - this.BuildingsWatcher = location is BuildableGameLocation buildableLocation ? WatcherFactory.ForNetCollection(buildableLocation.buildings) : WatcherFactory.ForImmutableCollection<Building>(); - this.DebrisWatcher = WatcherFactory.ForNetCollection(location.debris); - this.LargeTerrainFeaturesWatcher = WatcherFactory.ForNetCollection(location.largeTerrainFeatures); - this.NpcsWatcher = WatcherFactory.ForNetCollection(location.characters); - this.ObjectsWatcher = WatcherFactory.ForNetDictionary(location.netObjects); - this.TerrainFeaturesWatcher = WatcherFactory.ForNetDictionary(location.terrainFeatures); - this.FurnitureWatcher = WatcherFactory.ForNetCollection(location.furniture); + this.BuildingsWatcher = location is BuildableGameLocation buildableLocation ? WatcherFactory.ForNetCollection($"{this.Name}.{nameof(buildableLocation.buildings)}", buildableLocation.buildings) : WatcherFactory.ForImmutableCollection<Building>(); + this.DebrisWatcher = WatcherFactory.ForNetCollection($"{this.Name}.{nameof(location.debris)}", location.debris); + this.LargeTerrainFeaturesWatcher = WatcherFactory.ForNetCollection($"{this.Name}.{nameof(location.largeTerrainFeatures)}", location.largeTerrainFeatures); + this.NpcsWatcher = WatcherFactory.ForNetCollection($"{this.Name}.{nameof(location.characters)}", location.characters); + this.ObjectsWatcher = WatcherFactory.ForNetDictionary($"{this.Name}.{nameof(location.netObjects)}", location.netObjects); + this.TerrainFeaturesWatcher = WatcherFactory.ForNetDictionary($"{this.Name}.{nameof(location.terrainFeatures)}", location.terrainFeatures); + this.FurnitureWatcher = WatcherFactory.ForNetCollection($"{this.Name}.{nameof(location.furniture)}", location.furniture); this.Watchers.AddRange(new IWatcher[] { @@ -143,7 +147,7 @@ namespace StardewModdingAPI.Framework.StateTracking foreach ((Vector2 tile, SObject? obj) in added) { if (obj is Chest chest && !this.ChestWatchers.ContainsKey(tile)) - this.ChestWatchers.Add(tile, new ChestTracker(chest)); + this.ChestWatchers.Add(tile, new ChestTracker($"{this.Name}.chest({tile})", chest)); } } } diff --git a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs index 5433ac8e..fae90678 100644 --- a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs +++ b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs @@ -54,15 +54,15 @@ namespace StardewModdingAPI.Framework.StateTracking this.PreviousInventory = new Dictionary<Item, int>(this.CurrentInventory); // init trackers - this.LocationWatcher = WatcherFactory.ForReference(this.GetCurrentLocation); + this.LocationWatcher = WatcherFactory.ForReference($"player.{nameof(player.currentLocation)}", this.GetCurrentLocation); this.SkillWatchers = new Dictionary<SkillType, IValueWatcher<int>> { - [SkillType.Combat] = WatcherFactory.ForNetValue(player.combatLevel), - [SkillType.Farming] = WatcherFactory.ForNetValue(player.farmingLevel), - [SkillType.Fishing] = WatcherFactory.ForNetValue(player.fishingLevel), - [SkillType.Foraging] = WatcherFactory.ForNetValue(player.foragingLevel), - [SkillType.Luck] = WatcherFactory.ForNetValue(player.luckLevel), - [SkillType.Mining] = WatcherFactory.ForNetValue(player.miningLevel) + [SkillType.Combat] = WatcherFactory.ForNetValue($"player.{nameof(player.combatLevel)}", player.combatLevel), + [SkillType.Farming] = WatcherFactory.ForNetValue($"player.{nameof(player.farmingLevel)}", player.farmingLevel), + [SkillType.Fishing] = WatcherFactory.ForNetValue($"player.{nameof(player.fishingLevel)}", player.fishingLevel), + [SkillType.Foraging] = WatcherFactory.ForNetValue($"player.{nameof(player.foragingLevel)}", player.foragingLevel), + [SkillType.Luck] = WatcherFactory.ForNetValue($"player.{nameof(player.luckLevel)}", player.luckLevel), + [SkillType.Mining] = WatcherFactory.ForNetValue($"player.{nameof(player.miningLevel)}", player.miningLevel) }; // track watchers for convenience diff --git a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs index f328d659..ca6988ad 100644 --- a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs +++ b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs @@ -34,6 +34,9 @@ namespace StardewModdingAPI.Framework.StateTracking /********* ** Accessors *********/ + /// <inheritdoc /> + public string Name => nameof(WorldLocationsTracker); + /// <summary>Whether locations were added or removed since the last reset.</summary> public bool IsLocationListChanged => this.Added.Any() || this.Removed.Any(); @@ -59,9 +62,9 @@ namespace StardewModdingAPI.Framework.StateTracking /// <param name="activeVolcanoLocations">The game's list of active volcano locations.</param> public WorldLocationsTracker(ObservableCollection<GameLocation> locations, IList<MineShaft> activeMineLocations, IList<VolcanoDungeon> activeVolcanoLocations) { - this.LocationListWatcher = WatcherFactory.ForObservableCollection(locations); - this.MineLocationListWatcher = WatcherFactory.ForReferenceList(activeMineLocations); - this.VolcanoLocationListWatcher = WatcherFactory.ForReferenceList(activeVolcanoLocations); + this.LocationListWatcher = WatcherFactory.ForObservableCollection($"{this.Name}.{nameof(locations)}", locations); + this.MineLocationListWatcher = WatcherFactory.ForReferenceList($"{this.Name}.{nameof(activeMineLocations)}", activeMineLocations); + this.VolcanoLocationListWatcher = WatcherFactory.ForReferenceList($"{this.Name}.{nameof(activeVolcanoLocations)}", activeVolcanoLocations); } /// <inheritdoc /> diff --git a/src/SMAPI/Framework/WatcherCore.cs b/src/SMAPI/Framework/WatcherCore.cs index 5e20ac7b..35f27cc7 100644 --- a/src/SMAPI/Framework/WatcherCore.cs +++ b/src/SMAPI/Framework/WatcherCore.cs @@ -60,14 +60,14 @@ namespace StardewModdingAPI.Framework public WatcherCore(SInputState inputState, ObservableCollection<GameLocation> gameLocations) { // init watchers - this.CursorWatcher = WatcherFactory.ForEquatable(() => inputState.CursorPosition); - this.MouseWheelScrollWatcher = WatcherFactory.ForEquatable(() => inputState.MouseState.ScrollWheelValue); - this.SaveIdWatcher = WatcherFactory.ForEquatable(() => Game1.hasLoadedGame ? Game1.uniqueIDForThisGame : 0); - this.WindowSizeWatcher = WatcherFactory.ForEquatable(() => new Point(Game1.viewport.Width, Game1.viewport.Height)); - this.TimeWatcher = WatcherFactory.ForEquatable(() => Game1.timeOfDay); - this.ActiveMenuWatcher = WatcherFactory.ForReference(() => Game1.activeClickableMenu); + this.CursorWatcher = WatcherFactory.ForEquatable(nameof(inputState.CursorPosition), () => inputState.CursorPosition); + this.MouseWheelScrollWatcher = WatcherFactory.ForEquatable(nameof(inputState.MouseState.ScrollWheelValue), () => inputState.MouseState.ScrollWheelValue); + this.SaveIdWatcher = WatcherFactory.ForEquatable(nameof(Game1.uniqueIDForThisGame), () => Game1.hasLoadedGame ? Game1.uniqueIDForThisGame : 0); + this.WindowSizeWatcher = WatcherFactory.ForEquatable(nameof(Game1.viewport), () => new Point(Game1.viewport.Width, Game1.viewport.Height)); + this.TimeWatcher = WatcherFactory.ForEquatable(nameof(Game1.timeOfDay), () => Game1.timeOfDay); + this.ActiveMenuWatcher = WatcherFactory.ForReference(nameof(Game1.activeClickableMenu), () => Game1.activeClickableMenu); this.LocationsWatcher = new WorldLocationsTracker(gameLocations, MineShaft.activeMines, VolcanoDungeon.activeLevels); - this.LocaleWatcher = WatcherFactory.ForGenericEquality(() => LocalizedContentManager.CurrentLanguageCode); + this.LocaleWatcher = WatcherFactory.ForGenericEquality(nameof(LocalizedContentManager.CurrentLanguageCode), () => LocalizedContentManager.CurrentLanguageCode); this.Watchers.AddRange(new IWatcher[] { this.CursorWatcher, |