summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/common.targets2
-rw-r--r--docs/release-notes.md10
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json4
-rw-r--r--src/SMAPI.Mods.SaveBackup/manifest.json4
-rw-r--r--src/SMAPI.Toolkit/SemanticVersion.cs80
-rw-r--r--src/SMAPI.sln4
-rw-r--r--src/SMAPI/Constants.cs4
-rw-r--r--src/SMAPI/Framework/SCore.cs1
-rw-r--r--src/SMAPI/Framework/SGame.cs12
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs66
10 files changed, 115 insertions, 72 deletions
diff --git a/build/common.targets b/build/common.targets
index c7af8630..3d39be23 100644
--- a/build/common.targets
+++ b/build/common.targets
@@ -4,7 +4,7 @@
<!--set properties -->
<PropertyGroup>
- <Version>3.8.3</Version>
+ <Version>3.8.4</Version>
<Product>SMAPI</Product>
<LangVersion>latest</LangVersion>
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 6a6b07a2..a2ac8b35 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -7,6 +7,16 @@
* Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info).
-->
+## 3.8.4
+Released 15 January 2021 for Stardew Valley 1.5.3 or later.
+
+* For players:
+ * Updated for Stardew Valley 1.5.3.
+ * Fixed issue where title screen music didn't stop after loading a save.
+
+* For modders:
+ * Fixed `SemanticVersion` comparisons returning wrong value in rare cases.
+
## 3.8.3
Released 08 January 2021 for Stardew Valley 1.5.2 or later.
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index 1a021485..a7daf62b 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "3.8.3",
+ "Version": "3.8.4",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
- "MinimumApiVersion": "3.8.3"
+ "MinimumApiVersion": "3.8.4"
}
diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json
index 17ca5991..0fd202da 100644
--- a/src/SMAPI.Mods.SaveBackup/manifest.json
+++ b/src/SMAPI.Mods.SaveBackup/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
- "Version": "3.8.3",
+ "Version": "3.8.4",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
- "MinimumApiVersion": "3.8.3"
+ "MinimumApiVersion": "3.8.4"
}
diff --git a/src/SMAPI.Toolkit/SemanticVersion.cs b/src/SMAPI.Toolkit/SemanticVersion.cs
index 0f341665..d58dce0c 100644
--- a/src/SMAPI.Toolkit/SemanticVersion.cs
+++ b/src/SMAPI.Toolkit/SemanticVersion.cs
@@ -230,38 +230,49 @@ namespace StardewModdingAPI.Toolkit
const int curNewer = 1;
const int curOlder = -1;
- // compare stable versions
- if (this.MajorVersion != otherMajor)
- return this.MajorVersion.CompareTo(otherMajor);
- if (this.MinorVersion != otherMinor)
- return this.MinorVersion.CompareTo(otherMinor);
- if (this.PatchVersion != otherPatch)
- return this.PatchVersion.CompareTo(otherPatch);
- if (this.PlatformRelease != otherPlatformRelease)
- return this.PlatformRelease.CompareTo(otherPlatformRelease);
- if (this.PrereleaseTag == otherTag)
- return same;
-
- // stable supersedes prerelease
- bool curIsStable = string.IsNullOrWhiteSpace(this.PrereleaseTag);
- bool otherIsStable = string.IsNullOrWhiteSpace(otherTag);
- if (curIsStable)
- return curNewer;
- if (otherIsStable)
- return curOlder;
-
- // compare two prerelease tag values
- string[] curParts = this.PrereleaseTag.Split('.', '-');
- string[] otherParts = otherTag.Split('.', '-');
- for (int i = 0; i < curParts.Length; i++)
+ int CompareToRaw()
{
- // longer prerelease tag supersedes if otherwise equal
- if (otherParts.Length <= i)
+ // compare stable versions
+ if (this.MajorVersion != otherMajor)
+ return this.MajorVersion.CompareTo(otherMajor);
+ if (this.MinorVersion != otherMinor)
+ return this.MinorVersion.CompareTo(otherMinor);
+ if (this.PatchVersion != otherPatch)
+ return this.PatchVersion.CompareTo(otherPatch);
+ if (this.PlatformRelease != otherPlatformRelease)
+ return this.PlatformRelease.CompareTo(otherPlatformRelease);
+ if (this.PrereleaseTag == otherTag)
+ return same;
+
+ // stable supersedes prerelease
+ bool curIsStable = string.IsNullOrWhiteSpace(this.PrereleaseTag);
+ bool otherIsStable = string.IsNullOrWhiteSpace(otherTag);
+ if (curIsStable)
return curNewer;
-
- // compare if different
- if (curParts[i] != otherParts[i])
+ if (otherIsStable)
+ return curOlder;
+
+ // compare two prerelease tag values
+ string[] curParts = this.PrereleaseTag.Split('.', '-');
+ string[] otherParts = otherTag.Split('.', '-');
+ int length = Math.Max(curParts.Length, otherParts.Length);
+ for (int i = 0; i < length; i++)
{
+ // longer prerelease tag supersedes if otherwise equal
+ if (curParts.Length <= i)
+ return curOlder;
+ if (otherParts.Length <= i)
+ return curNewer;
+
+ // skip if same value, unless we've reached the end
+ if (curParts[i] == otherParts[i])
+ {
+ if (i == length - 1)
+ return same;
+
+ continue;
+ }
+
// unofficial is always lower-precedence
if (otherParts[i].Equals("unofficial", StringComparison.OrdinalIgnoreCase))
return curNewer;
@@ -277,10 +288,17 @@ namespace StardewModdingAPI.Toolkit
// else compare lexically
return string.Compare(curParts[i], otherParts[i], StringComparison.OrdinalIgnoreCase);
}
+
+ // fallback (this should never happen)
+ return string.Compare(this.ToString(), new SemanticVersion(otherMajor, otherMinor, otherPatch, otherPlatformRelease, otherTag).ToString(), StringComparison.OrdinalIgnoreCase);
}
- // fallback (this should never happen)
- return string.Compare(this.ToString(), new SemanticVersion(otherMajor, otherMinor, otherPatch, otherPlatformRelease, otherTag).ToString(), StringComparison.OrdinalIgnoreCase);
+ return CompareToRaw() switch
+ {
+ (< 0) => curOlder,
+ (> 0) => curNewer,
+ _ => same
+ };
}
/// <summary>Assert that the current version is valid.</summary>
diff --git a/src/SMAPI.sln b/src/SMAPI.sln
index bc74e6b9..b7a84fe4 100644
--- a/src/SMAPI.sln
+++ b/src/SMAPI.sln
@@ -48,6 +48,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "technical", "technical", "{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mods", "Mods", "{AE9A4D46-E910-4293-8BC4-673F85FFF6A5}"
+EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SMAPI.Internal", "SMAPI.Internal\SMAPI.Internal.shproj", "{85208F8D-6FD1-4531-BE05-7142490F59FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SMAPI.ModBuildConfig.Analyzer.Tests", "SMAPI.ModBuildConfig.Analyzer.Tests\SMAPI.ModBuildConfig.Analyzer.Tests.csproj", "{680B2641-81EA-467C-86A5-0E81CDC57ED0}"
@@ -148,6 +150,8 @@ Global
{85208F8D-6FD1-4531-BE05-7142490F59FE} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}
{680B2641-81EA-467C-86A5-0E81CDC57ED0} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}
{AA95884B-7097-476E-92C8-D0500DE9D6D1} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}
+ {0634EA4C-3B8F-42DB-AEA6-CA9E4EF6E92F} = {AE9A4D46-E910-4293-8BC4-673F85FFF6A5}
+ {CD53AD6F-97F4-4872-A212-50C2A0FD3601} = {AE9A4D46-E910-4293-8BC4-673F85FFF6A5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {70143042-A862-47A8-A677-7C819DDC90DC}
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index 2c0b85b7..b72471ca 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -54,10 +54,10 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
- public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.8.3");
+ public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.8.4");
/// <summary>The minimum supported version of Stardew Valley.</summary>
- public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.2");
+ public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.3");
/// <summary>The maximum supported version of Stardew Valley.</summary>
public static ISemanticVersion MaximumGameVersion { get; } = null;
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 3a51b418..f9a36593 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -619,6 +619,7 @@ namespace StardewModdingAPI.Framework
if (Game1.currentLoader != null)
{
this.Monitor.Log("Game loader synchronizing...");
+ this.Reflection.GetMethod(Game1.game1, "UpdateTitleScreen").Invoke(Game1.currentGameTime); // run game logic to change music on load, etc
while (Game1.currentLoader?.MoveNext() == true)
{
// raise load stage changed
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 2ede40ae..42a712ee 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -740,16 +740,20 @@ namespace StardewModdingAPI.Framework
Game1.spriteBatch.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle(startingX, (int)y, Game1.graphics.GraphicsDevice.Viewport.Width, 1), Microsoft.Xna.Framework.Color.Red * 0.5f);
}
}
+ if (Game1.ShouldShowOnscreenUsernames() && Game1.currentLocation != null)
+ {
+ Game1.currentLocation.DrawFarmerUsernames(Game1.spriteBatch);
+ }
if (Game1.currentBillboard != 0 && !this.takingMapScreenshot)
{
this.drawBillboard();
}
if (!Game1.eventUp && Game1.farmEvent == null && Game1.currentBillboard == 0 && Game1.gameMode == 3 && !this.takingMapScreenshot && Game1.isOutdoorMapSmallerThanViewport())
{
- Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, -Math.Min(Game1.viewport.X, 4096), Game1.graphics.GraphicsDevice.Viewport.Height), Microsoft.Xna.Framework.Color.Black);
- Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64, 0, Math.Min(4096, Game1.graphics.GraphicsDevice.Viewport.Width - (-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64)), Game1.graphics.GraphicsDevice.Viewport.Height), Microsoft.Xna.Framework.Color.Black);
- Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.graphics.GraphicsDevice.Viewport.Width, -Math.Min(Game1.viewport.Y, 4096)), Microsoft.Xna.Framework.Color.Black);
- Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, -Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64, Game1.graphics.GraphicsDevice.Viewport.Width, Math.Min(4096, Game1.graphics.GraphicsDevice.Viewport.Height - (-Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64))), Microsoft.Xna.Framework.Color.Black);
+ Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, -Math.Min(Game1.viewport.X, GameRunner.MaxTextureSize), Game1.graphics.GraphicsDevice.Viewport.Height), Microsoft.Xna.Framework.Color.Black);
+ Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64, 0, Math.Min(GameRunner.MaxTextureSize, Game1.graphics.GraphicsDevice.Viewport.Width - (-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64)), Game1.graphics.GraphicsDevice.Viewport.Height), Microsoft.Xna.Framework.Color.Black);
+ Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.graphics.GraphicsDevice.Viewport.Width, -Math.Min(Game1.viewport.Y, GameRunner.MaxTextureSize)), Microsoft.Xna.Framework.Color.Black);
+ Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, -Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64, Game1.graphics.GraphicsDevice.Viewport.Width, Math.Min(GameRunner.MaxTextureSize, Game1.graphics.GraphicsDevice.Viewport.Height - (-Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64))), Microsoft.Xna.Framework.Color.Black);
}
Game1.spriteBatch.End();
Game1.PushUIMode();
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index b82dedfd..bd1cc50e 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -138,36 +138,7 @@ namespace StardewModdingAPI.Metadata
{
if (!string.IsNullOrWhiteSpace(location.mapPath.Value) && this.NormalizeAssetNameIgnoringEmpty(location.mapPath.Value) == key)
{
- // reset patch caches
- switch (location)
- {
- case Town _:
- this.Reflection.GetField<bool>(location, "ccRefurbished").SetValue(false);
- this.Reflection.GetField<bool>(location, "isShowingDestroyedJoja").SetValue(false);
- this.Reflection.GetField<bool>(location, "isShowingUpgradedPamHouse").SetValue(false);
- break;
-
- case Beach _:
- case BeachNightMarket _:
- case Forest _:
- this.Reflection.GetField<bool>(location, "hasShownCCUpgrade").SetValue(false);
- break;
- }
-
- // general updates
- location.reloadMap();
- location.updateSeasonalTileSheets();
- location.updateWarps();
-
- // update interior doors
- location.interiorDoors.Clear();
- foreach (var entry in new InteriorDoorDictionary(location))
- location.interiorDoors.Add(entry);
-
- // update doors
- location.doors.Clear();
- location.updateDoors();
-
+ this.ReloadMap(location);
anyChanged = true;
}
}
@@ -803,6 +774,41 @@ namespace StardewModdingAPI.Metadata
return true;
}
+ /// <summary>Reload the map for a location.</summary>
+ /// <param name="location">The location whose map to reload.</param>
+ private void ReloadMap(GameLocation location)
+ {
+ // reset patch caches
+ switch (location)
+ {
+ case Town _:
+ this.Reflection.GetField<bool>(location, "ccRefurbished").SetValue(false);
+ this.Reflection.GetField<bool>(location, "isShowingDestroyedJoja").SetValue(false);
+ this.Reflection.GetField<bool>(location, "isShowingUpgradedPamHouse").SetValue(false);
+ break;
+
+ case Beach _:
+ case BeachNightMarket _:
+ case Forest _:
+ this.Reflection.GetField<bool>(location, "hasShownCCUpgrade").SetValue(false);
+ break;
+ }
+
+ // general updates
+ location.reloadMap();
+ location.updateSeasonalTileSheets();
+ location.updateWarps();
+
+ // update interior doors
+ location.interiorDoors.Clear();
+ foreach (var entry in new InteriorDoorDictionary(location))
+ location.interiorDoors.Add(entry);
+
+ // update doors
+ location.doors.Clear();
+ location.updateDoors();
+ }
+
/// <summary>Reload the disposition data for matching NPCs.</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="key">The asset key to reload.</param>