From 2a0a7191a7b943a50e30077b5cdd36eb11aa5dd1 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Oct 2021 23:37:48 -0400 Subject: fix barn/coop map edits resetting the exit warp --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 49 +++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 8bf7a32b..b176185b 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -184,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 GetWarpSet(GameLocation location) @@ -196,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)); @@ -906,9 +908,10 @@ namespace StardewModdingAPI.Metadata } /// Reload the map for a location. - /// The location whose map to reload. - private void ReloadMap(GameLocation location) + /// The location whose map to reload. + private void ReloadMap(LocationInfo locationInfo) { + GameLocation location = locationInfo.Location; Vector2? playerPos = Game1.player?.Position; if (this.AggressiveMemoryOptimizations) @@ -929,6 +932,7 @@ 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 @@ -1212,6 +1216,13 @@ namespace StardewModdingAPI.Metadata /// Get all locations in the game. /// Whether to also get the interior locations for constructable buildings. private IEnumerable GetLocations(bool buildingInteriors = true) + { + return this.GetLocationsWithInfo(buildingInteriors).Select(info => info.Location); + } + + /// Get all locations in the game. + /// Whether to also get the interior locations for constructable buildings. + private IEnumerable GetLocationsWithInfo(bool buildingInteriors = true) { // get available root locations IEnumerable rootLocations = Game1.locations; @@ -1221,7 +1232,7 @@ namespace StardewModdingAPI.Metadata // yield root + child locations foreach (GameLocation location in rootLocations) { - yield return location; + yield return new(location, null); if (buildingInteriors && location is BuildableGameLocation buildableLocation) { @@ -1229,7 +1240,7 @@ namespace StardewModdingAPI.Metadata { GameLocation indoors = building.indoors.Value; if (indoors != null) - yield return indoors; + yield return new(indoors, building); } } } @@ -1317,5 +1328,31 @@ namespace StardewModdingAPI.Metadata // remove key from cache return BuildingPainter.paintMaskLookup.Remove(key); } + + /// Metadata about a location used in asset propagation. + private readonly struct LocationInfo + { + /********* + ** Accessors + *********/ + /// The location instance. + public GameLocation Location { get; } + + /// The building which contains the location, if any. + public Building ParentBuilding { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The location instance. + /// The building which contains the location, if any. + public LocationInfo(GameLocation location, Building parentBuilding) + { + this.Location = location; + this.ParentBuilding = parentBuilding; + } + } } } -- cgit