diff --git a/src/SMAPI/Framework/StateTracking/ChestTracker.cs b/src/SMAPI/Framework/StateTracking/ChestTracker.cs new file mode 100644 index 00000000..4440bf4b --- /dev/null +++ b/src/SMAPI/Framework/StateTracking/ChestTracker.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using StardewModdingAPI.Enums; +using StardewModdingAPI.Events; +using StardewModdingAPI.Framework.StateTracking.FieldWatchers; +using StardewValley; +using ChangeType = StardewModdingAPI.Events.ChangeType; +using Chest = StardewValley.Objects.Chest; + +namespace StardewModdingAPI.Framework.StateTracking +{ + internal class ChestTracker + { + /********* + ** Fields + *********/ + /// The chest's inventory as of the last reset. + private IDictionary PreviousInventory; + + /// The chest's inventory change as of the last update. + private IDictionary CurrentInventory; + + /********* + ** Accessors + *********/ + /// The chest being tracked + public Chest Chest { get; } + + /********* + ** Public methods + *********/ + public ChestTracker(Chest chest) + { + this.Chest = chest; + this.PreviousInventory = this.GetInventory(); + } + + public void Update() + { + this.CurrentInventory = this.GetInventory(); + } + + + public void Reset() + { + this.PreviousInventory = this.CurrentInventory; + } + + public IEnumerable GetInventoryChanges() + { + IDictionary previous = this.PreviousInventory; + Console.WriteLine(previous.Count); + IDictionary current = this.GetInventory(); + Console.WriteLine(current.Count); + foreach (Item item in previous.Keys.Union(current.Keys)) + { + if (!previous.TryGetValue(item, out int prevStack)) + yield return new ItemStackChange { Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added }; + else if (!current.TryGetValue(item, out int newStack)) + yield return new ItemStackChange { Item = item, StackChange = -item.Stack, ChangeType = ChangeType.Removed }; + else if (prevStack != newStack) + yield return new ItemStackChange { Item = item, StackChange = newStack - prevStack, ChangeType = ChangeType.StackChange }; + } + } + + /********* + ** Private methods + *********/ + + private IDictionary GetInventory() + { + return this.Chest.items + .Where(n => n != null) + .Distinct() + .ToDictionary(n => n, n => n.Stack); + } + } +} diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs index 73ed2d8f..ed8001d6 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs @@ -43,7 +43,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots foreach (LocationTracker locationWatcher in watcher.Locations) { if (!this.LocationsDict.TryGetValue(locationWatcher.Location, out LocationSnapshot snapshot)) - this.LocationsDict[locationWatcher.Location] = snapshot = new LocationSnapshot(locationWatcher.Location); + this.LocationsDict[locationWatcher.Location] = snapshot = new LocationSnapshot(locationWatcher); snapshot.Update(locationWatcher); }