rewrite location events for multiplayer
This commit is contained in:
parent
a65a49a622
commit
b8fd3aedfe
|
@ -12,7 +12,11 @@
|
|||
|
||||
* For modders:
|
||||
* Added code analysis to mod build config package to flag common issues as warnings.
|
||||
* Added `LocationEvents.ObjectsChanged`, raised when an object is added/removed in any location.
|
||||
* Replaced `LocationEvents` with a more powerful set of events for multiplayer:
|
||||
* now raised for all locations;
|
||||
* now includes added/removed building interiors;
|
||||
* each event now provides a list of added/removed values;
|
||||
* added buildings-changed event.
|
||||
* Added `Context.IsMultiplayer` and `Context.IsMainPlayer` flags.
|
||||
* Added `Constants.TargetPlatform` which says whether the game is running on Linux, Mac, or Windows.
|
||||
* Added `semanticVersion.IsPrerelease()` method.
|
||||
|
@ -21,8 +25,10 @@
|
|||
* Fixed assets not reloaded consistently when the player switches language.
|
||||
* Fixed console command input not saved to the log.
|
||||
* Fixed `helper.ModRegistry.GetApi` interface validation errors not mentioning which interface caused the issue.
|
||||
* **Breaking change**: dropped some deprecated APIs.
|
||||
* **Breaking change**: mods can't intercept chatbox input, including the game's hotkeys to toggle the chatbox (default `T` and `?`).
|
||||
* **Breaking changes** (see [migration guide](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.3)):
|
||||
* dropped some deprecated APIs;
|
||||
* `LocationEvents` have been rewritten (see above);
|
||||
* mods can't intercept chatbox input, including the game's hotkeys to toggle the chatbox (default `T` and `?`).
|
||||
|
||||
* In console commands:
|
||||
* Added `player_add name`, which lets you add items to your inventory by name instead of ID.
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.LocationsChanged"/> event.</summary>
|
||||
public class EventArgsGameLocationsChanged : EventArgs
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The current list of game locations.</summary>
|
||||
public IList<GameLocation> NewLocations { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="newLocations">The current list of game locations.</param>
|
||||
public EventArgsGameLocationsChanged(IList<GameLocation> newLocations)
|
||||
{
|
||||
this.NewLocations = newLocations;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
|
@ -14,6 +14,7 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>The current value.</summary>
|
||||
public int NewInt { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using StardewValley;
|
||||
using StardewValley.Buildings;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.BuildingsChanged"/> event.</summary>
|
||||
public class EventArgsLocationBuildingsChanged : EventArgs
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The location which changed.</summary>
|
||||
public GameLocation Location { get; }
|
||||
|
||||
/// <summary>The buildings added to the location.</summary>
|
||||
public IEnumerable<Building> Added { get; }
|
||||
|
||||
/// <summary>The buildings removed from the location.</summary>
|
||||
public IEnumerable<Building> Removed { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="location">The location which changed.</param>
|
||||
/// <param name="added">The buildings added to the location.</param>
|
||||
/// <param name="removed">The buildings removed from the location.</param>
|
||||
public EventArgsLocationBuildingsChanged(GameLocation location, IEnumerable<Building> added, IEnumerable<Building> removed)
|
||||
{
|
||||
this.Location = location;
|
||||
this.Added = added.ToArray();
|
||||
this.Removed = removed.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ using SObject = StardewValley.Object;
|
|||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.LocationObjectsChanged"/> or <see cref="LocationEvents.ObjectsChanged"/> event.</summary>
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.ObjectsChanged"/> event.</summary>
|
||||
public class EventArgsLocationObjectsChanged : EventArgs
|
||||
{
|
||||
/*********
|
||||
|
@ -17,31 +17,25 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>The location which changed.</summary>
|
||||
public GameLocation Location { get; }
|
||||
|
||||
/// <summary>The objects added to the list.</summary>
|
||||
/// <summary>The objects added to the location.</summary>
|
||||
public IEnumerable<KeyValuePair<Vector2, SObject>> Added { get; }
|
||||
|
||||
/// <summary>The objects removed from the list.</summary>
|
||||
/// <summary>The objects removed from the location.</summary>
|
||||
public IEnumerable<KeyValuePair<Vector2, SObject>> Removed { get; }
|
||||
|
||||
/// <summary>The current list of objects in the current location.</summary>
|
||||
[Obsolete("Use " + nameof(EventArgsLocationObjectsChanged.Added))]
|
||||
public IDictionary<Vector2, NetRef<SObject>> NewObjects { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="location">The location which changed.</param>
|
||||
/// <param name="added">The objects added to the list.</param>
|
||||
/// <param name="removed">The objects removed from the list.</param>
|
||||
/// <param name="newObjects">The current list of objects in the current location.</param>
|
||||
public EventArgsLocationObjectsChanged(GameLocation location, IEnumerable<KeyValuePair<Vector2, SObject>> added, IEnumerable<KeyValuePair<Vector2, SObject>> removed, IDictionary<Vector2, NetRef<SObject>> newObjects)
|
||||
/// <param name="added">The objects added to the location.</param>
|
||||
/// <param name="removed">The objects removed from the location.</param>
|
||||
public EventArgsLocationObjectsChanged(GameLocation location, IEnumerable<KeyValuePair<Vector2, SObject>> added, IEnumerable<KeyValuePair<Vector2, SObject>> removed)
|
||||
{
|
||||
this.Location = location;
|
||||
this.Added = added.ToArray();
|
||||
this.Removed = removed.ToArray();
|
||||
this.NewObjects = newObjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.LocationsChanged"/> event.</summary>
|
||||
public class EventArgsLocationsChanged : EventArgs
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The added locations.</summary>
|
||||
public IEnumerable<GameLocation> Added { get; }
|
||||
|
||||
/// <summary>The removed locations.</summary>
|
||||
public IEnumerable<GameLocation> Removed { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="added">The added locations.</param>
|
||||
/// <param name="removed">The removed locations.</param>
|
||||
public EventArgsLocationsChanged(IEnumerable<GameLocation> added, IEnumerable<GameLocation> removed)
|
||||
{
|
||||
this.Added = added.ToArray();
|
||||
this.Removed = removed.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,20 @@
|
|||
using System;
|
||||
using System;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for a <see cref="LocationEvents.CurrentLocationChanged"/> event.</summary>
|
||||
public class EventArgsCurrentLocationChanged : EventArgs
|
||||
/// <summary>Event arguments for a <see cref="PlayerEvents.Warped"/> event.</summary>
|
||||
public class EventArgsPlayerWarped : EventArgs
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The player's previous location.</summary>
|
||||
public GameLocation PriorLocation { get; }
|
||||
|
||||
/// <summary>The player's current location.</summary>
|
||||
public GameLocation NewLocation { get; }
|
||||
|
||||
/// <summary>The player's previous location.</summary>
|
||||
public GameLocation PriorLocation { get; }
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -22,7 +23,7 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="priorLocation">The player's previous location.</param>
|
||||
/// <param name="newLocation">The player's current location.</param>
|
||||
public EventArgsCurrentLocationChanged(GameLocation priorLocation, GameLocation newLocation)
|
||||
public EventArgsPlayerWarped(GameLocation priorLocation, GameLocation newLocation)
|
||||
{
|
||||
this.NewLocation = newLocation;
|
||||
this.PriorLocation = priorLocation;
|
|
@ -16,29 +16,21 @@ namespace StardewModdingAPI.Events
|
|||
/*********
|
||||
** Events
|
||||
*********/
|
||||
/// <summary>Raised after the player warps to a new location.</summary>
|
||||
public static event EventHandler<EventArgsCurrentLocationChanged> CurrentLocationChanged
|
||||
{
|
||||
add => LocationEvents.EventManager.Location_CurrentLocationChanged.Add(value);
|
||||
remove => LocationEvents.EventManager.Location_CurrentLocationChanged.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>Raised after a game location is added or removed.</summary>
|
||||
public static event EventHandler<EventArgsGameLocationsChanged> LocationsChanged
|
||||
public static event EventHandler<EventArgsLocationsChanged> LocationsChanged
|
||||
{
|
||||
add => LocationEvents.EventManager.Location_LocationsChanged.Add(value);
|
||||
remove => LocationEvents.EventManager.Location_LocationsChanged.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>Raised after the list of objects in the current location changes (e.g. an object is added or removed).</summary>
|
||||
[Obsolete("Use " + nameof(LocationEvents) + "." + nameof(LocationEvents.ObjectsChanged) + " instead")]
|
||||
public static event EventHandler<EventArgsLocationObjectsChanged> LocationObjectsChanged
|
||||
/// <summary>Raised after buildings are added or removed in a location.</summary>
|
||||
public static event EventHandler<EventArgsLocationBuildingsChanged> BuildingsChanged
|
||||
{
|
||||
add => LocationEvents.EventManager.Location_LocationObjectsChanged.Add(value);
|
||||
remove => LocationEvents.EventManager.Location_LocationObjectsChanged.Remove(value);
|
||||
add => LocationEvents.EventManager.Location_BuildingsChanged.Add(value);
|
||||
remove => LocationEvents.EventManager.Location_BuildingsChanged.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>Raised after the list of objects in a location changes (e.g. an object is added or removed).</summary>
|
||||
/// <summary>Raised after objects are added or removed in a location.</summary>
|
||||
public static event EventHandler<EventArgsLocationObjectsChanged> ObjectsChanged
|
||||
{
|
||||
add => LocationEvents.EventManager.Location_ObjectsChanged.Add(value);
|
||||
|
|
|
@ -23,13 +23,21 @@ namespace StardewModdingAPI.Events
|
|||
remove => PlayerEvents.EventManager.Player_InventoryChanged.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary> Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
|
||||
/// <summary>Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
|
||||
public static event EventHandler<EventArgsLevelUp> LeveledUp
|
||||
{
|
||||
add => PlayerEvents.EventManager.Player_LeveledUp.Add(value);
|
||||
remove => PlayerEvents.EventManager.Player_LeveledUp.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>Raised after the player warps to a new location.</summary>
|
||||
public static event EventHandler<EventArgsPlayerWarped> Warped
|
||||
{
|
||||
add => PlayerEvents.EventManager.Player_Warped.Add(value);
|
||||
remove => PlayerEvents.EventManager.Player_Warped.Remove(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
|
|
|
@ -108,17 +108,13 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/****
|
||||
** LocationEvents
|
||||
****/
|
||||
/// <summary>Raised after the player warps to a new location.</summary>
|
||||
public readonly ManagedEvent<EventArgsCurrentLocationChanged> Location_CurrentLocationChanged;
|
||||
|
||||
/// <summary>Raised after a game location is added or removed.</summary>
|
||||
public readonly ManagedEvent<EventArgsGameLocationsChanged> Location_LocationsChanged;
|
||||
public readonly ManagedEvent<EventArgsLocationsChanged> Location_LocationsChanged;
|
||||
|
||||
/// <summary>Raised after the list of objects in the current location changes (e.g. an object is added or removed).</summary>
|
||||
[Obsolete]
|
||||
public readonly ManagedEvent<EventArgsLocationObjectsChanged> Location_LocationObjectsChanged;
|
||||
/// <summary>Raised after buildings are added or removed in a location.</summary>
|
||||
public readonly ManagedEvent<EventArgsLocationBuildingsChanged> Location_BuildingsChanged;
|
||||
|
||||
/// <summary>Raised after the list of objects in a location changes (e.g. an object is added or removed).</summary>
|
||||
/// <summary>Raised after objects are added or removed in a location.</summary>
|
||||
public readonly ManagedEvent<EventArgsLocationObjectsChanged> Location_ObjectsChanged;
|
||||
|
||||
/****
|
||||
|
@ -160,6 +156,10 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/// <summary> Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
|
||||
public readonly ManagedEvent<EventArgsLevelUp> Player_LeveledUp;
|
||||
|
||||
/// <summary>Raised after the player warps to a new location.</summary>
|
||||
public readonly ManagedEvent<EventArgsPlayerWarped> Player_Warped;
|
||||
|
||||
|
||||
/****
|
||||
** SaveEvents
|
||||
****/
|
||||
|
@ -241,9 +241,8 @@ namespace StardewModdingAPI.Framework.Events
|
|||
this.Input_ButtonPressed = ManageEventOf<EventArgsInput>(nameof(InputEvents), nameof(InputEvents.ButtonPressed));
|
||||
this.Input_ButtonReleased = ManageEventOf<EventArgsInput>(nameof(InputEvents), nameof(InputEvents.ButtonReleased));
|
||||
|
||||
this.Location_CurrentLocationChanged = ManageEventOf<EventArgsCurrentLocationChanged>(nameof(LocationEvents), nameof(LocationEvents.CurrentLocationChanged));
|
||||
this.Location_LocationsChanged = ManageEventOf<EventArgsGameLocationsChanged>(nameof(LocationEvents), nameof(LocationEvents.LocationsChanged));
|
||||
this.Location_LocationObjectsChanged = ManageEventOf<EventArgsLocationObjectsChanged>(nameof(LocationEvents), nameof(LocationEvents.LocationObjectsChanged));
|
||||
this.Location_LocationsChanged = ManageEventOf<EventArgsLocationsChanged>(nameof(LocationEvents), nameof(LocationEvents.LocationsChanged));
|
||||
this.Location_BuildingsChanged = ManageEventOf<EventArgsLocationBuildingsChanged>(nameof(LocationEvents), nameof(LocationEvents.BuildingsChanged));
|
||||
this.Location_ObjectsChanged = ManageEventOf<EventArgsLocationObjectsChanged>(nameof(LocationEvents), nameof(LocationEvents.ObjectsChanged));
|
||||
|
||||
this.Menu_Changed = ManageEventOf<EventArgsClickableMenuChanged>(nameof(MenuEvents), nameof(MenuEvents.MenuChanged));
|
||||
|
@ -258,6 +257,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
|
||||
this.Player_InventoryChanged = ManageEventOf<EventArgsInventoryChanged>(nameof(PlayerEvents), nameof(PlayerEvents.InventoryChanged));
|
||||
this.Player_LeveledUp = ManageEventOf<EventArgsLevelUp>(nameof(PlayerEvents), nameof(PlayerEvents.LeveledUp));
|
||||
this.Player_Warped = ManageEventOf<EventArgsPlayerWarped>(nameof(PlayerEvents), nameof(PlayerEvents.Warped));
|
||||
|
||||
this.Save_BeforeCreate = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.BeforeCreate));
|
||||
this.Save_AfterCreate = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.AfterCreate));
|
||||
|
|
|
@ -23,7 +23,6 @@ using StardewValley.Menus;
|
|||
using StardewValley.Tools;
|
||||
using xTile.Dimensions;
|
||||
using xTile.Layers;
|
||||
using SObject = StardewValley.Object;
|
||||
|
||||
namespace StardewModdingAPI.Framework
|
||||
{
|
||||
|
@ -92,11 +91,8 @@ namespace StardewModdingAPI.Framework
|
|||
/// <summary>Tracks changes to the save ID.</summary>
|
||||
private readonly IValueWatcher<ulong> SaveIdWatcher;
|
||||
|
||||
/// <summary>Tracks changes to the location list.</summary>
|
||||
private readonly ICollectionWatcher<GameLocation> LocationListWatcher;
|
||||
|
||||
/// <summary>Tracks changes to each location.</summary>
|
||||
private readonly IDictionary<GameLocation, LocationTracker> LocationWatchers = new Dictionary<GameLocation, LocationTracker>();
|
||||
/// <summary>Tracks changes to the game's locations.</summary>
|
||||
private readonly WorldLocationsTracker LocationsWatcher;
|
||||
|
||||
/// <summary>Tracks changes to <see cref="Game1.activeClickableMenu"/>.</summary>
|
||||
private readonly IValueWatcher<IClickableMenu> ActiveMenuWatcher;
|
||||
|
@ -165,14 +161,14 @@ namespace StardewModdingAPI.Framework
|
|||
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.LocationListWatcher = WatcherFactory.ForObservableCollection((ObservableCollection<GameLocation>)Game1.locations);
|
||||
this.LocationsWatcher = new WorldLocationsTracker((ObservableCollection<GameLocation>)Game1.locations);
|
||||
this.Watchers.AddRange(new IWatcher[]
|
||||
{
|
||||
this.SaveIdWatcher,
|
||||
this.WindowSizeWatcher,
|
||||
this.TimeWatcher,
|
||||
this.ActiveMenuWatcher,
|
||||
this.LocationListWatcher
|
||||
this.LocationsWatcher
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -351,22 +347,7 @@ namespace StardewModdingAPI.Framework
|
|||
foreach (IWatcher watcher in this.Watchers)
|
||||
watcher.Update();
|
||||
this.CurrentPlayerTracker?.Update();
|
||||
|
||||
// update location watchers
|
||||
if (this.LocationListWatcher.IsChanged)
|
||||
{
|
||||
foreach (GameLocation location in this.LocationListWatcher.Removed.Union(this.LocationListWatcher.Added))
|
||||
{
|
||||
if (this.LocationWatchers.TryGetValue(location, out LocationTracker watcher))
|
||||
{
|
||||
this.Watchers.Remove(watcher);
|
||||
this.LocationWatchers.Remove(location);
|
||||
watcher.Dispose();
|
||||
}
|
||||
}
|
||||
foreach (GameLocation location in this.LocationListWatcher.Added)
|
||||
this.LocationWatchers[location] = new LocationTracker(location);
|
||||
}
|
||||
this.LocationsWatcher.Update();
|
||||
|
||||
/*********
|
||||
** Locale changed events
|
||||
|
@ -516,45 +497,86 @@ namespace StardewModdingAPI.Framework
|
|||
*********/
|
||||
if (Context.IsWorldReady)
|
||||
{
|
||||
// update player info
|
||||
PlayerTracker curPlayer = this.CurrentPlayerTracker;
|
||||
bool raiseWorldEvents = !this.SaveIdWatcher.IsChanged; // don't report changes from unloaded => loaded
|
||||
|
||||
// raise current location changed
|
||||
if (curPlayer.TryGetNewLocation(out GameLocation newLocation))
|
||||
// raise location changes
|
||||
if (this.LocationsWatcher.IsChanged)
|
||||
{
|
||||
if (this.VerboseLogging)
|
||||
this.Monitor.Log($"Context: set location to {newLocation.Name}.", LogLevel.Trace);
|
||||
this.Events.Location_CurrentLocationChanged.Raise(new EventArgsCurrentLocationChanged(curPlayer.LocationWatcher.PreviousValue, newLocation));
|
||||
}
|
||||
|
||||
// raise location list changed
|
||||
if (this.LocationListWatcher.IsChanged)
|
||||
{
|
||||
if (this.VerboseLogging)
|
||||
// location list changes
|
||||
if (this.LocationsWatcher.IsLocationListChanged)
|
||||
{
|
||||
string added = this.LocationListWatcher.Added.Any() ? string.Join(", ", this.LocationListWatcher.Added.Select(p => p.Name)) : "none";
|
||||
string removed = this.LocationListWatcher.Removed.Any() ? string.Join(", ", this.LocationListWatcher.Removed.Select(p => p.Name)) : "none";
|
||||
this.Monitor.Log($"Context: location list changed (added {added}; removed {removed}).", LogLevel.Trace);
|
||||
GameLocation[] added = this.LocationsWatcher.Added.ToArray();
|
||||
GameLocation[] removed = this.LocationsWatcher.Removed.ToArray();
|
||||
this.LocationsWatcher.ResetLocationList();
|
||||
|
||||
if (this.VerboseLogging)
|
||||
{
|
||||
string addedText = this.LocationsWatcher.Added.Any() ? string.Join(", ", added.Select(p => p.Name)) : "none";
|
||||
string removedText = this.LocationsWatcher.Removed.Any() ? string.Join(", ", removed.Select(p => p.Name)) : "none";
|
||||
this.Monitor.Log($"Context: location list changed (added {addedText}; removed {removedText}).", LogLevel.Trace);
|
||||
}
|
||||
|
||||
this.Events.Location_LocationsChanged.Raise(new EventArgsLocationsChanged(added, removed));
|
||||
}
|
||||
|
||||
this.Events.Location_LocationsChanged.Raise(new EventArgsGameLocationsChanged(Game1.locations));
|
||||
// raise location contents changed
|
||||
if (raiseWorldEvents)
|
||||
{
|
||||
foreach (LocationTracker watcher in this.LocationsWatcher.Locations)
|
||||
{
|
||||
// objects changed
|
||||
if (watcher.ObjectsWatcher.IsChanged)
|
||||
{
|
||||
GameLocation location = watcher.Location;
|
||||
var added = watcher.ObjectsWatcher.Added;
|
||||
var removed = watcher.ObjectsWatcher.Removed;
|
||||
watcher.ObjectsWatcher.Reset();
|
||||
|
||||
this.Events.Location_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed));
|
||||
}
|
||||
|
||||
// buildings changed
|
||||
if (watcher.BuildingsWatcher.IsChanged)
|
||||
{
|
||||
GameLocation location = watcher.Location;
|
||||
var added = watcher.BuildingsWatcher.Added;
|
||||
var removed = watcher.BuildingsWatcher.Removed;
|
||||
watcher.BuildingsWatcher.Reset();
|
||||
|
||||
this.Events.Location_BuildingsChanged.Raise(new EventArgsLocationBuildingsChanged(location, added, removed));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this.LocationsWatcher.Reset();
|
||||
}
|
||||
|
||||
// raise events that shouldn't be triggered on initial load
|
||||
if (!this.SaveIdWatcher.IsChanged)
|
||||
// raise time changed
|
||||
if (raiseWorldEvents && this.TimeWatcher.IsChanged)
|
||||
{
|
||||
// raise location objects changed
|
||||
foreach (LocationTracker watcher in this.LocationWatchers.Values)
|
||||
{
|
||||
if (watcher.LocationObjectsWatcher.IsChanged)
|
||||
{
|
||||
GameLocation location = watcher.Location;
|
||||
var added = watcher.LocationObjectsWatcher.Added;
|
||||
var removed = watcher.LocationObjectsWatcher.Removed;
|
||||
watcher.Reset();
|
||||
int was = this.TimeWatcher.PreviousValue;
|
||||
int now = this.TimeWatcher.CurrentValue;
|
||||
this.TimeWatcher.Reset();
|
||||
|
||||
this.Events.Location_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed, watcher.Location.netObjects.FieldDict));
|
||||
}
|
||||
if (this.VerboseLogging)
|
||||
this.Monitor.Log($"Context: time changed from {was} to {now}.", LogLevel.Trace);
|
||||
|
||||
this.Events.Time_TimeOfDayChanged.Raise(new EventArgsIntChanged(was, now));
|
||||
}
|
||||
else
|
||||
this.TimeWatcher.Reset();
|
||||
|
||||
// raise player events
|
||||
if (raiseWorldEvents)
|
||||
{
|
||||
PlayerTracker curPlayer = this.CurrentPlayerTracker;
|
||||
|
||||
// raise current location changed
|
||||
if (curPlayer.TryGetNewLocation(out GameLocation newLocation))
|
||||
{
|
||||
if (this.VerboseLogging)
|
||||
this.Monitor.Log($"Context: set location to {newLocation.Name}.", LogLevel.Trace);
|
||||
this.Events.Player_Warped.Raise(new EventArgsPlayerWarped(curPlayer.LocationWatcher.PreviousValue, newLocation));
|
||||
}
|
||||
|
||||
// raise player leveled up a skill
|
||||
|
@ -574,27 +596,6 @@ namespace StardewModdingAPI.Framework
|
|||
this.Events.Player_InventoryChanged.Raise(new EventArgsInventoryChanged(Game1.player.Items, changedItems.ToList()));
|
||||
}
|
||||
|
||||
// raise current location's object list changed
|
||||
{
|
||||
if (curPlayer.TryGetLocationChanges(out IDictionaryWatcher<Vector2, SObject> watcher))
|
||||
{
|
||||
if (this.VerboseLogging)
|
||||
this.Monitor.Log("Context: current location objects changed.", LogLevel.Trace);
|
||||
|
||||
GameLocation location = curPlayer.GetCurrentLocation();
|
||||
|
||||
this.Events.Location_LocationObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, watcher.Added, watcher.Removed, location.netObjects.FieldDict));
|
||||
}
|
||||
}
|
||||
|
||||
// raise time changed
|
||||
if (this.TimeWatcher.IsChanged)
|
||||
{
|
||||
if (this.VerboseLogging)
|
||||
this.Monitor.Log($"Context: time changed from {this.TimeWatcher.PreviousValue} to {this.TimeWatcher.CurrentValue}.", LogLevel.Trace);
|
||||
this.Events.Time_TimeOfDayChanged.Raise(new EventArgsIntChanged(this.TimeWatcher.PreviousValue, this.TimeWatcher.CurrentValue));
|
||||
}
|
||||
|
||||
// raise mine level changed
|
||||
if (curPlayer.TryGetNewMineLevel(out int mineLevel))
|
||||
{
|
||||
|
@ -603,18 +604,11 @@ namespace StardewModdingAPI.Framework
|
|||
this.Events.Mine_LevelChanged.Raise(new EventArgsMineLevelChanged(curPlayer.MineLevelWatcher.PreviousValue, mineLevel));
|
||||
}
|
||||
}
|
||||
this.CurrentPlayerTracker?.Reset();
|
||||
}
|
||||
|
||||
// update state
|
||||
this.CurrentPlayerTracker?.Reset();
|
||||
this.LocationListWatcher.Reset();
|
||||
// update save ID watcher
|
||||
this.SaveIdWatcher.Reset();
|
||||
this.TimeWatcher.Reset();
|
||||
if (!Context.IsWorldReady)
|
||||
{
|
||||
foreach (LocationTracker watcher in this.LocationWatchers.Values)
|
||||
watcher.Reset();
|
||||
}
|
||||
|
||||
/*********
|
||||
** Game update
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
using System.Collections.Generic;
|
||||
using Netcode;
|
||||
|
||||
namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers
|
||||
{
|
||||
/// <summary>A watcher which detects changes to a Netcode collection.</summary>
|
||||
internal class NetCollectionWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue>
|
||||
where TValue : INetObject<INetSerializable>
|
||||
{
|
||||
/*********
|
||||
** Properties
|
||||
*********/
|
||||
/// <summary>The field being watched.</summary>
|
||||
private readonly NetCollection<TValue> Field;
|
||||
|
||||
/// <summary>The pairs added since the last reset.</summary>
|
||||
private readonly List<TValue> AddedImpl = new List<TValue>();
|
||||
|
||||
/// <summary>The pairs demoved since the last reset.</summary>
|
||||
private readonly List<TValue> RemovedImpl = new List<TValue>();
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>Whether the collection changed since the last reset.</summary>
|
||||
public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0;
|
||||
|
||||
/// <summary>The values added since the last reset.</summary>
|
||||
public IEnumerable<TValue> Added => this.AddedImpl;
|
||||
|
||||
/// <summary>The values removed since the last reset.</summary>
|
||||
public IEnumerable<TValue> Removed => this.RemovedImpl;
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="field">The field to watch.</param>
|
||||
public NetCollectionWatcher(NetCollection<TValue> field)
|
||||
{
|
||||
this.Field = field;
|
||||
field.OnValueAdded += this.OnValueAdded;
|
||||
field.OnValueRemoved += this.OnValueRemoved;
|
||||
}
|
||||
|
||||
/// <summary>Update the current value if needed.</summary>
|
||||
public void Update()
|
||||
{
|
||||
this.AssertNotDisposed();
|
||||
}
|
||||
|
||||
/// <summary>Set the current value as the baseline.</summary>
|
||||
public void Reset()
|
||||
{
|
||||
this.AssertNotDisposed();
|
||||
|
||||
this.AddedImpl.Clear();
|
||||
this.RemovedImpl.Clear();
|
||||
}
|
||||
|
||||
/// <summary>Stop watching the field and release all references.</summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
if (!this.IsDisposed)
|
||||
{
|
||||
this.Field.OnValueAdded -= this.OnValueAdded;
|
||||
this.Field.OnValueRemoved -= this.OnValueRemoved;
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>A callback invoked when an entry is added to the collection.</summary>
|
||||
/// <param name="value">The added value.</param>
|
||||
private void OnValueAdded(TValue value)
|
||||
{
|
||||
this.AddedImpl.Add(value);
|
||||
}
|
||||
|
||||
/// <summary>A callback invoked when an entry is removed from the collection.</summary>
|
||||
/// <param name="value">The added value.</param>
|
||||
private void OnValueRemoved(TValue value)
|
||||
{
|
||||
this.RemovedImpl.Add(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,14 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers
|
|||
return new ObservableCollectionWatcher<T>(collection);
|
||||
}
|
||||
|
||||
/// <summary>Get a watcher for a net collection.</summary>
|
||||
/// <typeparam name="T">The value type.</typeparam>
|
||||
/// <param name="collection">The net collection.</param>
|
||||
public static NetCollectionWatcher<T> ForNetCollection<T>(NetCollection<T> collection) where T : INetObject<INetSerializable>
|
||||
{
|
||||
return new NetCollectionWatcher<T>(collection);
|
||||
}
|
||||
|
||||
/// <summary>Get a watcher for a net dictionary.</summary>
|
||||
/// <typeparam name="TKey">The dictionary key type.</typeparam>
|
||||
/// <typeparam name="TValue">The dictionary value type.</typeparam>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using StardewModdingAPI.Framework.StateTracking.FieldWatchers;
|
||||
using StardewValley;
|
||||
using StardewValley.Buildings;
|
||||
using StardewValley.Locations;
|
||||
using Object = StardewValley.Object;
|
||||
|
||||
namespace StardewModdingAPI.Framework.StateTracking
|
||||
|
@ -26,8 +29,11 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
/// <summary>The tracked location.</summary>
|
||||
public GameLocation Location { get; }
|
||||
|
||||
/// <summary>Tracks changes to the current location's objects.</summary>
|
||||
public IDictionaryWatcher<Vector2, Object> LocationObjectsWatcher { get; }
|
||||
/// <summary>Tracks changes to the location's buildings.</summary>
|
||||
public ICollectionWatcher<Building> BuildingsWatcher { get; }
|
||||
|
||||
/// <summary>Tracks changes to the location's objects.</summary>
|
||||
public IDictionaryWatcher<Vector2, Object> ObjectsWatcher { get; }
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -40,10 +46,15 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
this.Location = location;
|
||||
|
||||
// init watchers
|
||||
this.LocationObjectsWatcher = WatcherFactory.ForNetDictionary(location.netObjects);
|
||||
this.Watchers.AddRange(new[]
|
||||
this.ObjectsWatcher = WatcherFactory.ForNetDictionary(location.netObjects);
|
||||
this.BuildingsWatcher = location is BuildableGameLocation buildableLocation
|
||||
? WatcherFactory.ForNetCollection(buildableLocation.buildings)
|
||||
: (ICollectionWatcher<Building>)WatcherFactory.ForObservableCollection(new ObservableCollection<Building>());
|
||||
|
||||
this.Watchers.AddRange(new IWatcher[]
|
||||
{
|
||||
this.LocationObjectsWatcher
|
||||
this.BuildingsWatcher,
|
||||
this.ObjectsWatcher
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.StateTracking.FieldWatchers;
|
||||
using StardewValley;
|
||||
using StardewValley.Locations;
|
||||
using SObject = StardewValley.Object;
|
||||
|
||||
namespace StardewModdingAPI.Framework.StateTracking
|
||||
{
|
||||
|
@ -38,9 +36,6 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
/// <summary>The player's current location.</summary>
|
||||
public IValueWatcher<GameLocation> LocationWatcher { get; }
|
||||
|
||||
/// <summary>Tracks changes to the player's current location's objects.</summary>
|
||||
public IDictionaryWatcher<Vector2, SObject> LocationObjectsWatcher { get; private set; }
|
||||
|
||||
/// <summary>The player's current mine level.</summary>
|
||||
public IValueWatcher<int> MineLevelWatcher { get; }
|
||||
|
||||
|
@ -61,7 +56,6 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
|
||||
// init trackers
|
||||
this.LocationWatcher = WatcherFactory.ForReference(this.GetCurrentLocation);
|
||||
this.LocationObjectsWatcher = WatcherFactory.ForNetDictionary(this.GetCurrentLocation().netObjects);
|
||||
this.MineLevelWatcher = WatcherFactory.ForEquatable(() => this.LastValidLocation is MineShaft mine ? mine.mineLevel : 0);
|
||||
this.SkillWatchers = new Dictionary<EventArgsLevelUp.LevelType, IValueWatcher<int>>
|
||||
{
|
||||
|
@ -77,7 +71,6 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
this.Watchers.AddRange(new IWatcher[]
|
||||
{
|
||||
this.LocationWatcher,
|
||||
this.LocationObjectsWatcher,
|
||||
this.MineLevelWatcher
|
||||
});
|
||||
this.Watchers.AddRange(this.SkillWatchers.Values);
|
||||
|
@ -93,16 +86,6 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
foreach (IWatcher watcher in this.Watchers)
|
||||
watcher.Update();
|
||||
|
||||
// replace location objects watcher
|
||||
if (this.LocationWatcher.IsChanged)
|
||||
{
|
||||
this.Watchers.Remove(this.LocationObjectsWatcher);
|
||||
this.LocationObjectsWatcher.Dispose();
|
||||
|
||||
this.LocationObjectsWatcher = WatcherFactory.ForNetDictionary(this.GetCurrentLocation().netObjects);
|
||||
this.Watchers.Add(this.LocationObjectsWatcher);
|
||||
}
|
||||
|
||||
// update inventory
|
||||
this.CurrentInventory = this.GetInventory();
|
||||
}
|
||||
|
@ -154,21 +137,6 @@ namespace StardewModdingAPI.Framework.StateTracking
|
|||
return this.LocationWatcher.IsChanged;
|
||||
}
|
||||
|
||||
/// <summary>Get object changes to the player's current location if they there as of the last reset.</summary>
|
||||
/// <param name="watcher">The object change watcher.</param>
|
||||
/// <returns>Returns whether it changed.</returns>
|
||||
public bool TryGetLocationChanges(out IDictionaryWatcher<Vector2, SObject> watcher)
|
||||
{
|
||||
if (this.LocationWatcher.IsChanged)
|
||||
{
|
||||
watcher = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
watcher = this.LocationObjectsWatcher;
|
||||
return watcher.IsChanged;
|
||||
}
|
||||
|
||||
/// <summary>Get the player's new mine level if it changed.</summary>
|
||||
/// <param name="mineLevel">The player's current mine level.</param>
|
||||
/// <returns>Returns whether it changed.</returns>
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using StardewModdingAPI.Framework.StateTracking.FieldWatchers;
|
||||
using StardewValley;
|
||||
using StardewValley.Buildings;
|
||||
using StardewValley.Locations;
|
||||
|
||||
namespace StardewModdingAPI.Framework.StateTracking
|
||||
{
|
||||
/// <summary>Detects changes to the game's locations.</summary>
|
||||
internal class WorldLocationsTracker : IWatcher
|
||||
{
|
||||
/*********
|
||||
** Properties
|
||||
*********/
|
||||
/// <summary>Tracks changes to the location list.</summary>
|
||||
private readonly ICollectionWatcher<GameLocation> LocationListWatcher;
|
||||
|
||||
/// <summary>A lookup of the tracked locations.</summary>
|
||||
private IDictionary<GameLocation, LocationTracker> LocationDict { get; } = new Dictionary<GameLocation, LocationTracker>();
|
||||
|
||||
/// <summary>A lookup of registered buildings and their indoor location.</summary>
|
||||
private readonly IDictionary<Building, GameLocation> BuildingIndoors = new Dictionary<Building, GameLocation>();
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>Whether locations were added or removed since the last reset.</summary>
|
||||
public bool IsLocationListChanged => this.Added.Any() || this.Removed.Any();
|
||||
|
||||
/// <summary>Whether any tracked location data changed since the last reset.</summary>
|
||||
public bool IsChanged => this.IsLocationListChanged || this.Locations.Any(p => p.IsChanged);
|
||||
|
||||
/// <summary>The tracked locations.</summary>
|
||||
public IEnumerable<LocationTracker> Locations => this.LocationDict.Values;
|
||||
|
||||
/// <summary>The locations removed since the last update.</summary>
|
||||
public ICollection<GameLocation> Added { get; } = new HashSet<GameLocation>();
|
||||
|
||||
/// <summary>The locations added since the last update.</summary>
|
||||
public ICollection<GameLocation> Removed { get; } = new HashSet<GameLocation>();
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locations">The game's list of locations.</param>
|
||||
public WorldLocationsTracker(ObservableCollection<GameLocation> locations)
|
||||
{
|
||||
this.LocationListWatcher = WatcherFactory.ForObservableCollection(locations);
|
||||
}
|
||||
|
||||
/// <summary>Update the current value if needed.</summary>
|
||||
public void Update()
|
||||
{
|
||||
// detect location changes
|
||||
if (this.LocationListWatcher.IsChanged)
|
||||
{
|
||||
this.Remove(this.LocationListWatcher.Removed);
|
||||
this.Add(this.LocationListWatcher.Added);
|
||||
}
|
||||
|
||||
// detect building changes
|
||||
foreach (LocationTracker watcher in this.Locations.ToArray())
|
||||
{
|
||||
if (watcher.BuildingsWatcher.IsChanged)
|
||||
{
|
||||
this.Remove(watcher.BuildingsWatcher.Removed);
|
||||
this.Add(watcher.BuildingsWatcher.Added);
|
||||
}
|
||||
}
|
||||
|
||||
// detect building interior changed (e.g. construction completed)
|
||||
foreach (KeyValuePair<Building, GameLocation> pair in this.BuildingIndoors.Where(p => !object.Equals(p.Key.indoors.Value, p.Value)))
|
||||
{
|
||||
GameLocation oldIndoors = pair.Value;
|
||||
GameLocation newIndoors = pair.Key.indoors.Value;
|
||||
|
||||
if (oldIndoors != null)
|
||||
this.Added.Add(oldIndoors);
|
||||
if (newIndoors != null)
|
||||
this.Removed.Add(newIndoors);
|
||||
}
|
||||
|
||||
// update watchers
|
||||
foreach (IWatcher watcher in this.Locations)
|
||||
watcher.Update();
|
||||
}
|
||||
|
||||
/// <summary>Set the current location list as the baseline.</summary>
|
||||
public void ResetLocationList()
|
||||
{
|
||||
this.Removed.Clear();
|
||||
this.Added.Clear();
|
||||
this.LocationListWatcher.Reset();
|
||||
}
|
||||
|
||||
/// <summary>Set the current value as the baseline.</summary>
|
||||
public void Reset()
|
||||
{
|
||||
this.ResetLocationList();
|
||||
foreach (IWatcher watcher in this.Locations)
|
||||
watcher.Reset();
|
||||
}
|
||||
|
||||
/// <summary>Stop watching the player fields and release all references.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.LocationListWatcher.Dispose();
|
||||
foreach (IWatcher watcher in this.Locations)
|
||||
watcher.Dispose();
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/****
|
||||
** Enumerable wrappers
|
||||
****/
|
||||
/// <summary>Add the given buildings.</summary>
|
||||
/// <param name="buildings">The buildings to add.</param>
|
||||
public void Add(IEnumerable<Building> buildings)
|
||||
{
|
||||
foreach (Building building in buildings)
|
||||
this.Add(building);
|
||||
}
|
||||
|
||||
/// <summary>Add the given locations.</summary>
|
||||
/// <param name="locations">The locations to add.</param>
|
||||
public void Add(IEnumerable<GameLocation> locations)
|
||||
{
|
||||
foreach (GameLocation location in locations)
|
||||
this.Add(location);
|
||||
}
|
||||
|
||||
/// <summary>Remove the given buildings.</summary>
|
||||
/// <param name="buildings">The buildings to remove.</param>
|
||||
public void Remove(IEnumerable<Building> buildings)
|
||||
{
|
||||
foreach (Building building in buildings)
|
||||
this.Remove(building);
|
||||
}
|
||||
|
||||
/// <summary>Remove the given locations.</summary>
|
||||
/// <param name="locations">The locations to remove.</param>
|
||||
public void Remove(IEnumerable<GameLocation> locations)
|
||||
{
|
||||
foreach (GameLocation location in locations)
|
||||
this.Remove(location);
|
||||
}
|
||||
|
||||
/****
|
||||
** Main add/remove logic
|
||||
****/
|
||||
/// <summary>Add the given building.</summary>
|
||||
/// <param name="building">The building to add.</param>
|
||||
public void Add(Building building)
|
||||
{
|
||||
if (building == null)
|
||||
return;
|
||||
|
||||
GameLocation indoors = building.indoors.Value;
|
||||
this.BuildingIndoors[building] = indoors;
|
||||
this.Add(indoors);
|
||||
}
|
||||
|
||||
/// <summary>Add the given location.</summary>
|
||||
/// <param name="location">The location to add.</param>
|
||||
public void Add(GameLocation location)
|
||||
{
|
||||
if (location == null)
|
||||
return;
|
||||
|
||||
// remove old location if needed
|
||||
this.Remove(location);
|
||||
|
||||
// track change
|
||||
this.Added.Add(location);
|
||||
|
||||
// add
|
||||
this.LocationDict[location] = new LocationTracker(location);
|
||||
if (location is BuildableGameLocation buildableLocation)
|
||||
this.Add(buildableLocation.buildings);
|
||||
}
|
||||
|
||||
/// <summary>Remove the given building.</summary>
|
||||
/// <param name="building">The building to remove.</param>
|
||||
public void Remove(Building building)
|
||||
{
|
||||
if (building == null)
|
||||
return;
|
||||
|
||||
this.BuildingIndoors.Remove(building);
|
||||
this.Remove(building.indoors.Value);
|
||||
}
|
||||
|
||||
/// <summary>Remove the given location.</summary>
|
||||
/// <param name="location">The location to remove.</param>
|
||||
public void Remove(GameLocation location)
|
||||
{
|
||||
if (location == null)
|
||||
return;
|
||||
|
||||
if (this.LocationDict.TryGetValue(location, out LocationTracker watcher))
|
||||
{
|
||||
// track change
|
||||
this.Removed.Add(location);
|
||||
|
||||
// remove
|
||||
this.LocationDict.Remove(location);
|
||||
watcher.Dispose();
|
||||
if (location is BuildableGameLocation buildableLocation)
|
||||
this.Remove(buildableLocation.buildings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,6 +85,7 @@
|
|||
<Compile Include="..\..\build\GlobalAssemblyInfo.cs">
|
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Events\EventArgsLocationBuildingsChanged.cs" />
|
||||
<Compile Include="Events\MultiplayerEvents.cs" />
|
||||
<Compile Include="Framework\Events\EventManager.cs" />
|
||||
<Compile Include="Framework\Events\ManagedEvent.cs" />
|
||||
|
@ -142,12 +143,14 @@
|
|||
<Compile Include="Framework\StateTracking\FieldWatchers\ComparableWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\FieldWatchers\NetDictionaryWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\FieldWatchers\NetValueWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\FieldWatchers\NetCollectionWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\FieldWatchers\ObservableCollectionWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\FieldWatchers\WatcherFactory.cs" />
|
||||
<Compile Include="Framework\StateTracking\ICollectionWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\IDictionaryWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\IValueWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\IWatcher.cs" />
|
||||
<Compile Include="Framework\StateTracking\WorldLocationsTracker.cs" />
|
||||
<Compile Include="Framework\StateTracking\LocationTracker.cs" />
|
||||
<Compile Include="Framework\StateTracking\PlayerTracker.cs" />
|
||||
<Compile Include="Framework\Utilities\ContextHash.cs" />
|
||||
|
@ -175,8 +178,8 @@
|
|||
<Compile Include="Events\EventArgsControllerButtonReleased.cs" />
|
||||
<Compile Include="Events\EventArgsControllerTriggerPressed.cs" />
|
||||
<Compile Include="Events\EventArgsControllerTriggerReleased.cs" />
|
||||
<Compile Include="Events\EventArgsCurrentLocationChanged.cs" />
|
||||
<Compile Include="Events\EventArgsGameLocationsChanged.cs" />
|
||||
<Compile Include="Events\EventArgsPlayerWarped.cs" />
|
||||
<Compile Include="Events\EventArgsLocationsChanged.cs" />
|
||||
<Compile Include="Events\EventArgsIntChanged.cs" />
|
||||
<Compile Include="Events\EventArgsInventoryChanged.cs" />
|
||||
<Compile Include="Events\EventArgsKeyboardStateChanged.cs" />
|
||||
|
|
Loading…
Reference in New Issue