diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-09-02 23:58:43 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-09-02 23:58:43 -0400 |
commit | 3e820b82bccf7cab390bc43d9156fdeb4ab08cd9 (patch) | |
tree | 475824186caf48be08a54b56b4ec6a8ef1639ed7 /src/StardewModdingAPI/Framework | |
parent | dac21226d275fca4ce4880ab9e15104f7987c133 (diff) | |
download | SMAPI-3e820b82bccf7cab390bc43d9156fdeb4ab08cd9.tar.gz SMAPI-3e820b82bccf7cab390bc43d9156fdeb4ab08cd9.tar.bz2 SMAPI-3e820b82bccf7cab390bc43d9156fdeb4ab08cd9.zip |
account for game loading tilesheets from either Content or Content\Maps (#352)
Diffstat (limited to 'src/StardewModdingAPI/Framework')
-rw-r--r-- | src/StardewModdingAPI/Framework/ModHelpers/ContentHelper.cs | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/src/StardewModdingAPI/Framework/ModHelpers/ContentHelper.cs b/src/StardewModdingAPI/Framework/ModHelpers/ContentHelper.cs index d24124e0..a3beaedf 100644 --- a/src/StardewModdingAPI/Framework/ModHelpers/ContentHelper.cs +++ b/src/StardewModdingAPI/Framework/ModHelpers/ContentHelper.cs @@ -214,6 +214,18 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <param name="map">The map whose tilesheets to fix.</param> /// <param name="mapKey">The map asset key within the mod folder.</param> /// <exception cref="ContentLoadException">The map tilesheets could not be loaded.</exception> + /// <remarks> + /// The game's logic for tilesheets in <see cref="Game1.setGraphicsForSeason"/> is a bit specialised. It boils down to this: + /// * If the location is indoors or the desert, or the image source contains 'path' or 'object', it's loaded as-is relative to the <c>Content</c> folder. + /// * Else it's loaded from <c>Content\Maps</c> with a seasonal prefix. + /// + /// That logic doesn't work well in our case, mainly because we have no location metadata at this point. + /// Instead we use a more heuristic approach: check relative to the map file first, then relative to + /// <c>Content\Maps</c>, then <c>Content</c>. If the image source filename contains a seasonal prefix, we try + /// for a seasonal variation and then an exact match. + /// + /// While that doesn't exactly match the game logic, it's close enough that it's unlikely to make a difference. + /// </remarks> private void FixLocalMapTilesheets(Map map, string mapKey) { // check map info @@ -262,12 +274,13 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <param name="relativeMapFolder">The folder path containing the map, relative to the mod folder.</param> /// <param name="imageSource">The tilesheet image source to load.</param> /// <returns>Returns the loaded asset key (if it was loaded successfully).</returns> + /// <remarks>See remarks on <see cref="FixLocalMapTilesheets"/>.</remarks> private string TryLoadTilesheetImageSource(string relativeMapFolder, string imageSource) { if (imageSource == null) return null; - // check for tilesheet relative to map + // check relative to map file { string localKey = Path.Combine(relativeMapFolder, imageSource); FileInfo localFile = this.GetModFile(localKey); @@ -286,28 +299,31 @@ namespace StardewModdingAPI.Framework.ModHelpers } } - // fallback to game content + // check relative to content folder { - string contentKey = imageSource.EndsWith(".png") - ? imageSource.Substring(0, imageSource.Length - 4) - : imageSource; - - try + foreach (string candidateKey in new[] { imageSource, $@"Maps\{imageSource}" }) { - this.Load<Texture2D>(contentKey, ContentSource.GameContent); - return contentKey; - } - catch - { - // ignore file-not-found errors - // TODO: while it's useful to suppress a asset-not-found error here to avoid - // confusion, this is a pretty naive approach. Even if the file doesn't exist, - // the file may have been loaded through an IAssetLoader which failed. So even - // if the content file doesn't exist, that doesn't mean the error here is a - // content-not-found error. Unfortunately XNA doesn't provide a good way to - // detect the error type. - if (this.GetContentFolderFile(contentKey).Exists) - throw; + string contentKey = candidateKey.EndsWith(".png") + ? candidateKey.Substring(0, imageSource.Length - 4) + : candidateKey; + + try + { + this.Load<Texture2D>(contentKey, ContentSource.GameContent); + return contentKey; + } + catch + { + // ignore file-not-found errors + // TODO: while it's useful to suppress a asset-not-found error here to avoid + // confusion, this is a pretty naive approach. Even if the file doesn't exist, + // the file may have been loaded through an IAssetLoader which failed. So even + // if the content file doesn't exist, that doesn't mean the error here is a + // content-not-found error. Unfortunately XNA doesn't provide a good way to + // detect the error type. + if (this.GetContentFolderFile(contentKey).Exists) + throw; + } } } |