diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-10-17 19:53:40 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-10-17 19:53:40 -0400 |
commit | d578345cfd53df8a91ae8e0e1346b711332a999a (patch) | |
tree | fa9a2e6c855a532dbd99910c7cdac1dc468010da /src/SMAPI/Metadata | |
parent | ebe41180c41f544919c03fb3bf6029437a7d65a4 (diff) | |
parent | f8c9a2929bb42ef7f71fa3a2d258c5566960aa69 (diff) | |
download | SMAPI-d578345cfd53df8a91ae8e0e1346b711332a999a.tar.gz SMAPI-d578345cfd53df8a91ae8e0e1346b711332a999a.tar.bz2 SMAPI-d578345cfd53df8a91ae8e0e1346b711332a999a.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Metadata')
-rw-r--r-- | src/SMAPI/Metadata/CoreAssetPropagator.cs | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 35ae26b3..7efd99a0 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.ContentManagers; using StardewModdingAPI.Framework.Reflection; @@ -183,8 +184,10 @@ namespace StardewModdingAPI.Metadata if (!ignoreWorld) { - foreach (GameLocation location in this.GetLocations()) + foreach (LocationInfo info in this.GetLocationsWithInfo()) { + GameLocation location = info.Location; + if (!string.IsNullOrWhiteSpace(location.mapPath.Value) && this.NormalizeAssetNameIgnoringEmpty(location.mapPath.Value) == key) { static ISet<string> GetWarpSet(GameLocation location) @@ -195,7 +198,7 @@ namespace StardewModdingAPI.Metadata } var oldWarps = GetWarpSet(location); - this.ReloadMap(location); + this.ReloadMap(info); var newWarps = GetWarpSet(location); changedWarps = changedWarps || oldWarps.Count != newWarps.Count || oldWarps.Any(p => !newWarps.Contains(p)); @@ -905,9 +908,12 @@ namespace StardewModdingAPI.Metadata } /// <summary>Reload the map for a location.</summary> - /// <param name="location">The location whose map to reload.</param> - private void ReloadMap(GameLocation location) + /// <param name="locationInfo">The location whose map to reload.</param> + private void ReloadMap(LocationInfo locationInfo) { + GameLocation location = locationInfo.Location; + Vector2? playerPos = Game1.player?.Position; + if (this.AggressiveMemoryOptimizations) location.map.DisposeTileSheets(Game1.mapDisplayDevice); @@ -926,6 +932,15 @@ namespace StardewModdingAPI.Metadata // update for changes location.updateWarps(); location.updateDoors(); + locationInfo.ParentBuilding?.updateInteriorWarps(); + + // reset player position + // The game may move the player as part of the map changes, even if they're not in that + // location. That's not needed in this case, and it can have weird effects like players + // warping onto the wrong tile (or even off-screen) if a patch changes the farmhouse + // map on location change. + if (playerPos.HasValue) + Game1.player.Position = playerPos.Value; } /// <summary>Reload the disposition data for matching NPCs.</summary> @@ -1202,6 +1217,13 @@ namespace StardewModdingAPI.Metadata /// <param name="buildingInteriors">Whether to also get the interior locations for constructable buildings.</param> private IEnumerable<GameLocation> GetLocations(bool buildingInteriors = true) { + return this.GetLocationsWithInfo(buildingInteriors).Select(info => info.Location); + } + + /// <summary>Get all locations in the game.</summary> + /// <param name="buildingInteriors">Whether to also get the interior locations for constructable buildings.</param> + private IEnumerable<LocationInfo> GetLocationsWithInfo(bool buildingInteriors = true) + { // get available root locations IEnumerable<GameLocation> rootLocations = Game1.locations; if (SaveGame.loaded?.locations != null) @@ -1210,7 +1232,7 @@ namespace StardewModdingAPI.Metadata // yield root + child locations foreach (GameLocation location in rootLocations) { - yield return location; + yield return new LocationInfo(location, null); if (buildingInteriors && location is BuildableGameLocation buildableLocation) { @@ -1218,7 +1240,7 @@ namespace StardewModdingAPI.Metadata { GameLocation indoors = building.indoors.Value; if (indoors != null) - yield return indoors; + yield return new LocationInfo(indoors, building); } } } @@ -1306,5 +1328,31 @@ namespace StardewModdingAPI.Metadata // remove key from cache return BuildingPainter.paintMaskLookup.Remove(key); } + + /// <summary>Metadata about a location used in asset propagation.</summary> + private readonly struct LocationInfo + { + /********* + ** Accessors + *********/ + /// <summary>The location instance.</summary> + public GameLocation Location { get; } + + /// <summary>The building which contains the location, if any.</summary> + public Building ParentBuilding { get; } + + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="location">The location instance.</param> + /// <param name="parentBuilding">The building which contains the location, if any.</param> + public LocationInfo(GameLocation location, Building parentBuilding) + { + this.Location = location; + this.ParentBuilding = parentBuilding; + } + } } } |