Skip to content

Commit 7dae07a

Browse files
committed
Merge branch 'develop' into stable
2 parents 0db8eb9 + d0c7856 commit 7dae07a

7 files changed

Lines changed: 39 additions & 26 deletions

File tree

build/common.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ repo. It imports the other MSBuild files as needed.
77
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
88
<PropertyGroup>
99
<!--set general build properties -->
10-
<Version>4.2.0</Version>
10+
<Version>4.2.1</Version>
1111
<Product>SMAPI</Product>
1212
<LangVersion>latest</LangVersion>
1313
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>

docs/release-notes.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
[README](README.md)
22

33
# Release notes
4+
## Upcoming release
5+
Released 25 March 2025 for Stardew Valley 1.6.14 or later.
6+
7+
* For players:
8+
* Fixed crash when some mods' custom tiles are on-screen.
9+
10+
* For mod authors:
11+
* Reverted the fix for the game's `Data/ChairTiles` logic not handling unique string IDs like `Maps/Author.ModName` correctly.
12+
_The fix caused crashes loading map tiles in some cases. This will be fixed in the next game update instead._
13+
414
## 4.2.0
515
Released 24 March 2025 for Stardew Valley 1.6.14 or later. See [release highlights](https://www.patreon.com/posts/125017679).
616

@@ -13,7 +23,8 @@ Released 24 March 2025 for Stardew Valley 1.6.14 or later. See [release highligh
1323
* For mod authors:
1424
* Mod events are now raised on the shipping menu (except when it's actually saving).
1525
* Added translation API methods to query translation keys (`ContainsKey` and `GetKeys`).
16-
* Fixed the game's `Data/ChairTiles` logic not handling unique string IDs like `Maps/Author.ModName` correctly.
26+
* ~~Fixed the game's `Data/ChairTiles` logic not handling unique string IDs like `Maps/Author.ModName` correctly.~~
27+
_Reverted in 4.2.1._
1728
* Fixed exception thrown if `modRegistry.GetApi<T>` can't proxy the API to the given interface. It now logs an error and returns null as intended.
1829

1930
* For external tools:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"Name": "Console Commands",
33
"Author": "SMAPI",
4-
"Version": "4.2.0",
4+
"Version": "4.2.1",
55
"Description": "Adds SMAPI console commands that let you manipulate the game.",
66
"UniqueId": "SMAPI.ConsoleCommands",
77
"EntryDll": "ConsoleCommands.dll",
8-
"MinimumApiVersion": "4.2.0"
8+
"MinimumApiVersion": "4.2.1"
99
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"Name": "Save Backup",
33
"Author": "SMAPI",
4-
"Version": "4.2.0",
4+
"Version": "4.2.1",
55
"Description": "Automatically backs up all your saves once per day into its folder.",
66
"UniqueId": "SMAPI.SaveBackup",
77
"EntryDll": "SaveBackup.dll",
8-
"MinimumApiVersion": "4.2.0"
8+
"MinimumApiVersion": "4.2.1"
99
}

src/SMAPI.Web/wwwroot/schemas/content-patcher.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
"title": "Format version",
1515
"description": "The format version. You should always use the latest version to enable the latest features, avoid obsolete behavior, and reduce load times.",
1616
"type": "string",
17-
"pattern": "^2\\.5\\.[0-9]+$",
17+
"pattern": "^2\\.6\\.[0-9]+$",
1818
"@errorMessages": {
19-
"pattern": "Incorrect value '@value'. You should always use the latest format version (currently 2.5.0) to enable the latest features, avoid obsolete behavior, and reduce load times."
19+
"pattern": "Incorrect value '@value'. You should always use the latest format version (currently 2.6.0) to enable the latest features, avoid obsolete behavior, and reduce load times."
2020
}
2121
},
2222
"ConfigSchema": {
@@ -355,7 +355,19 @@
355355
"type": "string",
356356
"pattern": " *-?\\d+ -?\\d+ [A-Za-z0-9_\\.]+ -?\\d+ -?\\d+ *$",
357357
"@errorMessages": {
358-
"pattern": "Each warp must match the exact format recognized by the game's Warp map property (i.e. 'fromX fromY targetMap targetX targetY', like '10 10 Town 0 30'."
358+
"pattern": "Each warp must match the exact format recognized by the game's Warp map property (i.e. 'fromX fromY targetMap targetX targetY', like '10 10 Town 0 30')."
359+
}
360+
}
361+
},
362+
"AddNpcWarps": {
363+
"title": "Add NPC-only warps",
364+
"description": "The NPC-only warp values to add to the location, in the format recognized by the game's NPCWarp map property.",
365+
"type": "array",
366+
"items": {
367+
"type": "string",
368+
"pattern": " *-?\\d+ -?\\d+ [A-Za-z0-9_\\.]+ -?\\d+ -?\\d+ *$",
369+
"@errorMessages": {
370+
"pattern": "Each warp must match the exact format recognized by the game's NPCWarp map property (i.e. 'fromX fromY targetMap targetX targetY', like '10 10 Town 0 30')."
359371
}
360372
}
361373
},
@@ -560,6 +572,7 @@
560572
"When",
561573

562574
"AddWarps",
575+
"AddNPCWarps",
563576
"FromArea",
564577
"MapProperties",
565578
"MapTiles",

src/SMAPI/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal static class EarlyConstants
4949
internal static int? LogScreenId { get; set; }
5050

5151
/// <summary>SMAPI's current raw semantic version.</summary>
52-
internal static string RawApiVersion = "4.2.0";
52+
internal static string RawApiVersion = "4.2.1";
5353
}
5454

5555
/// <summary>Contains SMAPI's constants and assumptions.</summary>

src/SMAPI/Framework/ContentManagers/ModContentManager.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -419,21 +419,15 @@ private void FixTilesheetPaths(Map map, string relativeMapPath, bool fixEagerPat
419419
// load best match
420420
try
421421
{
422-
if (!this.TryGetTilesheetAssetName(relativeMapFolder, imageSource, out IAssetName? assetName, out bool isInternalAssetKey, out string? error))
422+
if (!this.TryGetTilesheetAssetName(relativeMapFolder, imageSource, out IAssetName? assetName, out string? error))
423423
throw new SContentLoadException(ContentLoadErrorType.InvalidData, $"{errorPrefix} {error}");
424424

425425
if (assetName is not null)
426426
{
427-
// Some game code is hardcoded to expect a file extension, which results in issues like the
428-
// `Data/ChairTiles` key for `Author.ModName_Tilesheet` being `Author`.
429-
string newImageSource = !isInternalAssetKey && Path.GetExtension(assetName.Name).ToLowerInvariant() is not (".xnb" or ".png")
430-
? assetName.Name + ".xnb"
431-
: assetName.Name;
432-
433-
// set path
434-
if (this.Monitor.IsVerbose && PathUtilities.NormalizeAssetName(tilesheet.ImageSource) != PathUtilities.NormalizePath(newImageSource))
427+
if (!assetName.IsEquivalentTo(tilesheet.ImageSource))
435428
this.Monitor.VerboseLog($" Mapped tilesheet '{tilesheet.ImageSource}' to '{assetName}'.");
436-
tilesheet.ImageSource = newImageSource;
429+
430+
tilesheet.ImageSource = assetName.Name;
437431
}
438432
}
439433
catch (Exception ex)
@@ -450,19 +444,17 @@ private void FixTilesheetPaths(Map map, string relativeMapPath, bool fixEagerPat
450444
/// <param name="modRelativeMapFolder">The folder path containing the map, relative to the mod folder.</param>
451445
/// <param name="relativePath">The tilesheet path to load.</param>
452446
/// <param name="assetName">The found asset name.</param>
453-
/// <param name="isInternalAssetKey">Whether the <paramref name="assetName"/> is an internal asset key which points to a file in the mod folder, rather than an asset name in the game's normal content pipeline.</param>
454447
/// <param name="error">A message indicating why the file couldn't be loaded.</param>
455448
/// <returns>Returns whether the asset name was found.</returns>
456449
/// <remarks>See remarks on <see cref="FixTilesheetPaths"/>.</remarks>
457-
private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relativePath, out IAssetName? assetName, out bool isInternalAssetKey, out string? error)
450+
private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relativePath, out IAssetName? assetName, out string? error)
458451
{
459452
error = null;
460453

461454
// nothing to do
462455
if (string.IsNullOrWhiteSpace(relativePath))
463456
{
464457
assetName = null;
465-
isInternalAssetKey = false;
466458
return true;
467459
}
468460

@@ -481,7 +473,6 @@ private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relati
481473
if (this.GetModFile<Texture2D>(localKey).Exists)
482474
{
483475
assetName = this.GetInternalAssetKey(localKey);
484-
isInternalAssetKey = true;
485476
return true;
486477
}
487478
}
@@ -492,7 +483,6 @@ private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relati
492483
{
493484
this.GameContentManager.LoadLocalized<Texture2D>(contentKey, this.GameContentManager.Language, useCache: true); // no need to bypass cache here, since we're not storing the asset
494485
assetName = contentKey;
495-
isInternalAssetKey = false;
496486
return true;
497487
}
498488
catch
@@ -510,7 +500,6 @@ private bool TryGetTilesheetAssetName(string modRelativeMapFolder, string relati
510500

511501
// not found
512502
assetName = null;
513-
isInternalAssetKey = false;
514503
error = "The tilesheet couldn't be found relative to either the map file or the game's content folder.";
515504
return false;
516505
}

0 commit comments

Comments
 (0)