We couldn't parse that file, but you can still share the link.
-
Error details: @Model.ParsedLog.Error
+
Error details: @Model.ParsedLog.Error
Raw log
-
@Model.ParsedLog.RawText
+
@Model.ParsedLog.RawText
}
From 51368b8afb0c2064a70ed09f41570ca8fac5fdfa Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Fri, 23 Mar 2018 20:18:23 -0400
Subject: [PATCH 15/29] update tree textures when changeed through the content
API (#459)
---
docs/release-notes.md | 3 +
src/SMAPI/Metadata/CoreAssetPropagator.cs | 120 ++++++++++++++++------
2 files changed, 91 insertions(+), 32 deletions(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 059105c35..05a37ea87 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -16,6 +16,9 @@
-->
## 2.5.4
+* For modders:
+ * Added automatic texture update for trees when changed through the content API.
+
* For the [log parser][]:
* Fixed error when log text contains certain tokens.
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 850217271..21aaeb6c4 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI.Framework.Reflection;
@@ -45,7 +46,10 @@ public CoreAssetPropagator(Func getNormalisedPath, Reflector ref
/// Returns whether an asset was reloaded.
public bool Propagate(LocalizedContentManager content, string key)
{
- return this.PropagateImpl(content, key) != null;
+ object result = this.PropagateImpl(content, key);
+ if (result is bool b)
+ return b;
+ return result != null;
}
@@ -55,7 +59,7 @@ public bool Propagate(LocalizedContentManager content, string key)
/// Reload one of the game's core assets (if applicable).
/// The content manager through which to reload the asset.
/// The asset key to reload.
- /// Returns any non-null value to indicate an asset was loaded..
+ /// Returns any non-null value to indicate an asset was loaded.
private object PropagateImpl(LocalizedContentManager content, string key)
{
Reflector reflection = this.Reflection;
@@ -72,7 +76,7 @@ private object PropagateImpl(LocalizedContentManager content, string key)
{
Farm farm = Game1.getFarm();
if (farm == null)
- return null;
+ return false;
return farm.houseTextures = content.Load(key);
}
#endif
@@ -85,7 +89,7 @@ private object PropagateImpl(LocalizedContentManager content, string key)
case "characters\\farmer\\farmer_base": // Farmer
if (Game1.player == null || !Game1.player.isMale)
- return null;
+ return false;
#if STARDEW_VALLEY_1_3
return Game1.player.FarmerRenderer = new FarmerRenderer(key);
#else
@@ -94,7 +98,7 @@ private object PropagateImpl(LocalizedContentManager content, string key)
case "characters\\farmer\\farmer_girl_base": // Farmer
if (Game1.player == null || Game1.player.isMale)
- return null;
+ return false;
#if STARDEW_VALLEY_1_3
return Game1.player.FarmerRenderer = new FarmerRenderer(key);
#else
@@ -240,8 +244,7 @@ private object PropagateImpl(LocalizedContentManager content, string key)
reflection.GetField(Game1.activeClickableMenu, "cloudsTexture").SetValue(content.Load(key));
return true;
}
-
- return null;
+ return false;
case "minigames\\titlebuttons": // TitleMenu
if (Game1.activeClickableMenu is TitleMenu titleMenu)
@@ -256,8 +259,7 @@ private object PropagateImpl(LocalizedContentManager content, string key)
#endif
return true;
}
-
- return null;
+ return false;
/****
** Content\TileSheets
@@ -291,48 +293,102 @@ private object PropagateImpl(LocalizedContentManager content, string key)
case "terrainfeatures\\hoedirt": // from HoeDirt
return HoeDirt.lightTexture = content.Load(key);
- case "Terrainfeatures\\hoedirtdark": // from HoeDirt
+ case "terrainfeatures\\hoedirtdark": // from HoeDirt
return HoeDirt.darkTexture = content.Load(key);
- case "Terrainfeatures\\hoedirtsnow": // from HoeDirt
+ case "terrainfeatures\\hoedirtsnow": // from HoeDirt
return HoeDirt.snowTexture = content.Load(key);
+
+ case "terrainfeatures\\mushroom_tree": // from Tree
+ return this.ReloadTreeTextures(content, key, Tree.mushroomTree);
+
+ case "terrainfeatures\\tree_palm": // from Tree
+ return this.ReloadTreeTextures(content, key, Tree.palmTree);
+
+ case "terrainfeatures\\tree1_fall": // from Tree
+ case "terrainfeatures\\tree1_spring": // from Tree
+ case "terrainfeatures\\tree1_summer": // from Tree
+ case "terrainfeatures\\tree1_winter": // from Tree
+ return this.ReloadTreeTextures(content, key, Tree.bushyTree);
+
+ case "terrainfeatures\\tree2_fall": // from Tree
+ case "terrainfeatures\\tree2_spring": // from Tree
+ case "terrainfeatures\\tree2_summer": // from Tree
+ case "terrainfeatures\\tree2_winter": // from Tree
+ return this.ReloadTreeTextures(content, key, Tree.leafyTree);
+
+ case "terrainfeatures\\tree3_fall": // from Tree
+ case "terrainfeatures\\tree3_spring": // from Tree
+ case "terrainfeatures\\tree3_winter": // from Tree
+ return this.ReloadTreeTextures(content, key, Tree.pineTree);
}
// building textures
if (key.StartsWith(this.GetNormalisedPath("Buildings\\"), StringComparison.InvariantCultureIgnoreCase))
{
- Building[] buildings = this.GetAllBuildings().Where(p => key.Equals(this.GetNormalisedPath($"Buildings\\{p.buildingType?.ToLower()}"), StringComparison.InvariantCultureIgnoreCase)).ToArray();
- if (buildings.Any())
- {
-#if STARDEW_VALLEY_1_3
- foreach (Building building in buildings)
- building.texture = new Lazy(() => content.Load(key));
-#else
- Texture2D texture = content.Load(key);
- foreach (Building building in buildings)
- building.texture = texture;
-#endif
-
- return true;
- }
- return null;
+ string type = Path.GetFileName(key);
+ return this.ReloadBuildings(content, key, type);
}
- return null;
+ return false;
}
/*********
** Private methods
*********/
- /// Get all player-constructed buildings in the world.
- private IEnumerable GetAllBuildings()
+ /// Reload building textures.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// The type to reload.
+ /// Returns whether any textures were reloaded.
+ private bool ReloadBuildings(LocalizedContentManager content, string key, string type)
+ {
+ Building[] buildings = Game1.locations
+ .OfType()
+ .SelectMany(p => p.buildings)
+ .Where(p => p.buildingType == type)
+ .ToArray();
+
+ if (buildings.Any())
+ {
+ Lazy texture = new Lazy(() => content.Load(key));
+ foreach (Building building in buildings)
+#if STARDEW_VALLEY_1_3
+ building.texture = texture;
+#else
+ building.texture = texture.Value;
+#endif
+ return true;
+ }
+ return false;
+ }
+
+ /// Reload tree textures.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// The type to reload.
+ /// Returns whether any textures were reloaded.
+ private bool ReloadTreeTextures(LocalizedContentManager content, string key, int type)
{
- foreach (BuildableGameLocation location in Game1.locations.OfType())
+ Tree[] trees = Game1.locations
+ .SelectMany(p => p.terrainFeatures.Values.OfType())
+ .Where(tree => tree.treeType == type)
+ .ToArray();
+
+ if (trees.Any())
{
- foreach (Building building in location.buildings)
- yield return building;
+ Lazy texture = new Lazy(() => content.Load(key));
+ foreach (Tree tree in trees)
+#if STARDEW_VALLEY_1_3
+ this.Reflection.GetField>(tree, "texture").SetValue(texture);
+#else
+ this.Reflection.GetField(tree, "texture").SetValue(texture.Value);
+#endif
+ return true;
}
+
+ return false;
}
}
}
From fad47ff74f6d03652951230eb1c394b896578c48 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Fri, 23 Mar 2018 22:30:49 -0400
Subject: [PATCH 16/29] fix image overlay bugs on Linux/Mac (#461)
---
docs/release-notes.md | 5 +++--
src/SMAPI/Framework/Content/AssetDataForImage.cs | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 05a37ea87..c40e41be6 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -16,8 +16,9 @@
-->
## 2.5.4
-* For modders:
- * Added automatic texture update for trees when changed through the content API.
+* For players:
+ * Fixed tree textures not updated when changed through the content API.
+ * Fixed display bugs on Linux/Mac when mods overlay images through the content API.
* For the [log parser][]:
* Fixed error when log text contains certain tokens.
diff --git a/src/SMAPI/Framework/Content/AssetDataForImage.cs b/src/SMAPI/Framework/Content/AssetDataForImage.cs
index c665484fb..fc653bcfc 100644
--- a/src/SMAPI/Framework/Content/AssetDataForImage.cs
+++ b/src/SMAPI/Framework/Content/AssetDataForImage.cs
@@ -58,7 +58,7 @@ public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle
for (int i = 0; i < sourceData.Length; i++)
{
Color pixel = sourceData[i];
- if (pixel.A != 0) // not transparent
+ if (pixel.A > 2) // not transparent (note: on Linux/Mac, fully transparent pixels may have an alpha up to 2 for some reason)
newData[i] = pixel;
}
sourceData = newData;
From 5126d56b3992acd3193aaae35f178bb5e9da1cae Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Fri, 23 Mar 2018 22:41:15 -0400
Subject: [PATCH 17/29] fix error when a mod removes an asset editor/loader
(#460)
---
docs/release-notes.md | 3 ++-
src/SMAPI/Program.cs | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index c40e41be6..33e66a147 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -18,7 +18,8 @@
## 2.5.4
* For players:
* Fixed tree textures not updated when changed through the content API.
- * Fixed display bugs on Linux/Mac when mods overlay images through the content API.
+ * Fixed visual bug on Linux/Mac when mods overlay images through the content API.
+ * Fixed error when a mod removes an asset editor/loader.
* For the [log parser][]:
* Fixed error when log text contains certain tokens.
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index 8c1ea2386..1b8cb2ba9 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -953,7 +953,7 @@ IContentPack CreateTransitionalContentPack(string packDirPath, IManifest packMan
{
helper.ObservableAssetEditors.CollectionChanged += (sender, e) =>
{
- if (e.NewItems.Count > 0)
+ if (e.NewItems?.Count > 0)
{
this.Monitor.Log("Invalidating cache entries for new asset editors...", LogLevel.Trace);
this.ContentCore.InvalidateCacheFor(e.NewItems.Cast().ToArray(), new IAssetLoader[0]);
@@ -961,7 +961,7 @@ IContentPack CreateTransitionalContentPack(string packDirPath, IManifest packMan
};
helper.ObservableAssetLoaders.CollectionChanged += (sender, e) =>
{
- if (e.NewItems.Count > 0)
+ if (e.NewItems?.Count > 0)
{
this.Monitor.Log("Invalidating cache entries for new asset loaders...", LogLevel.Trace);
this.ContentCore.InvalidateCacheFor(new IAssetEditor[0], e.NewItems.Cast().ToArray());
From 34346d8b0911ec949832c037bfd83d4ab706d37a Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sat, 24 Mar 2018 19:06:13 -0400
Subject: [PATCH 18/29] tweak transparency threshold (#461)
---
src/SMAPI/Framework/Content/AssetDataForImage.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/SMAPI/Framework/Content/AssetDataForImage.cs b/src/SMAPI/Framework/Content/AssetDataForImage.cs
index fc653bcfc..1eef2afb3 100644
--- a/src/SMAPI/Framework/Content/AssetDataForImage.cs
+++ b/src/SMAPI/Framework/Content/AssetDataForImage.cs
@@ -58,7 +58,7 @@ public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle
for (int i = 0; i < sourceData.Length; i++)
{
Color pixel = sourceData[i];
- if (pixel.A > 2) // not transparent (note: on Linux/Mac, fully transparent pixels may have an alpha up to 2 for some reason)
+ if (pixel.A > 4) // not transparent (note: on Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason)
newData[i] = pixel;
}
sourceData = newData;
From 20b778390051569aa34a9ac42f03cd9b9a051df7 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sat, 24 Mar 2018 20:26:33 -0400
Subject: [PATCH 19/29] update NPC textures when changed through the content
API (#459)
---
src/SMAPI/Metadata/CoreAssetPropagator.cs | 122 ++++++++++++++++++++--
1 file changed, 115 insertions(+), 7 deletions(-)
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 21aaeb6c4..4a1d60971 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -323,12 +323,18 @@ private object PropagateImpl(LocalizedContentManager content, string key)
return this.ReloadTreeTextures(content, key, Tree.pineTree);
}
- // building textures
+ // dynamic textures
if (key.StartsWith(this.GetNormalisedPath("Buildings\\"), StringComparison.InvariantCultureIgnoreCase))
- {
- string type = Path.GetFileName(key);
- return this.ReloadBuildings(content, key, type);
- }
+ return this.ReloadBuildings(content, key);
+
+ if (key.StartsWith(this.GetNormalisedPath("Characters\\")) && this.CountSegments(key) == 2) // ignore Characters/Dialogue/*, etc
+ return this.ReloadNpcSprites(content, key, monster: false);
+
+ if (key.StartsWith(this.GetNormalisedPath("Characters\\Monsters\\")))
+ return this.ReloadNpcSprites(content, key, monster: true);
+
+ if (key.StartsWith(this.GetNormalisedPath("Portraits\\")))
+ return this.ReloadNpcPortraits(content, key);
return false;
}
@@ -340,16 +346,18 @@ private object PropagateImpl(LocalizedContentManager content, string key)
/// Reload building textures.
/// The content manager through which to reload the asset.
/// The asset key to reload.
- /// The type to reload.
/// Returns whether any textures were reloaded.
- private bool ReloadBuildings(LocalizedContentManager content, string key, string type)
+ private bool ReloadBuildings(LocalizedContentManager content, string key)
{
+ // get buildings
+ string type = Path.GetFileName(key);
Building[] buildings = Game1.locations
.OfType()
.SelectMany(p => p.buildings)
.Where(p => p.buildingType == type)
.ToArray();
+ // reload buildings
if (buildings.Any())
{
Lazy texture = new Lazy(() => content.Load(key));
@@ -364,6 +372,61 @@ private bool ReloadBuildings(LocalizedContentManager content, string key, string
return false;
}
+ /// Reload the sprites for matching NPCs.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// Whether to match monsters (true) or non-monsters (false).
+ /// Returns whether any textures were reloaded.
+ private bool ReloadNpcSprites(LocalizedContentManager content, string key, bool monster)
+ {
+ // get NPCs
+ string name = this.GetNpcNameFromFileName(Path.GetFileName(key));
+ NPC[] characters =
+ (
+ from location in this.GetLocations()
+ from npc in location.characters
+ where npc.name == name && npc.IsMonster == monster
+ select npc
+ )
+ .Distinct()
+ .ToArray();
+ if (!characters.Any())
+ return false;
+
+ // update portrait
+ Texture2D texture = content.Load(key);
+ foreach (NPC character in characters)
+ character.Sprite.Texture = texture;
+ return true;
+ }
+
+ /// Reload the portraits for matching NPCs.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// Returns whether any textures were reloaded.
+ private bool ReloadNpcPortraits(LocalizedContentManager content, string key)
+ {
+ // get NPCs
+ string name = this.GetNpcNameFromFileName(Path.GetFileName(key));
+ NPC[] villagers =
+ (
+ from location in this.GetLocations()
+ from npc in location.characters
+ where npc.name == name && npc.isVillager()
+ select npc
+ )
+ .Distinct()
+ .ToArray();
+ if (!villagers.Any())
+ return false;
+
+ // update portrait
+ Texture2D texture = content.Load(key);
+ foreach (NPC villager in villagers)
+ villager.Portrait = texture;
+ return true;
+ }
+
/// Reload tree textures.
/// The content manager through which to reload the asset.
/// The asset key to reload.
@@ -390,5 +453,50 @@ private bool ReloadTreeTextures(LocalizedContentManager content, string key, int
return false;
}
+
+ /// Get an NPC name from the name of their file under Content/Characters.
+ /// The file name.
+ /// Derived from .
+ private string GetNpcNameFromFileName(string name)
+ {
+ switch (name)
+ {
+ case "Mariner":
+ return "Old Mariner";
+ case "DwarfKing":
+ return "Dwarf King";
+ case "MrQi":
+ return "Mister Qi";
+ default:
+ return name;
+ }
+ }
+
+ /// Get all locations in the game.
+ private IEnumerable GetLocations()
+ {
+ foreach (GameLocation location in Game1.locations)
+ {
+ yield return location;
+
+ if (location is BuildableGameLocation buildableLocation)
+ {
+ foreach (Building building in buildableLocation.buildings)
+ {
+ if (building.indoors != null)
+ yield return building.indoors;
+ }
+ }
+ }
+ }
+
+ /// Count the number of segments in a path (e.g. 'a/b' is 2).
+ /// The path to check.
+ private int CountSegments(string path)
+ {
+ if (path == null)
+ return 0;
+ return path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Length;
+ }
}
}
From d0b96ed3c068f8b94a53a156a7c5e668f53aa2fc Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sat, 24 Mar 2018 20:33:59 -0400
Subject: [PATCH 20/29] update release notes (#459)
---
docs/release-notes.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 33e66a147..e0e209a1d 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -17,7 +17,7 @@
## 2.5.4
* For players:
- * Fixed tree textures not updated when changed through the content API.
+ * Fixed NPC and tree textures not updated when changed through the content API.
* Fixed visual bug on Linux/Mac when mods overlay images through the content API.
* Fixed error when a mod removes an asset editor/loader.
From 5a0e49827be92d19dfdda7bb15ca15fa8f269ecb Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 00:52:37 -0400
Subject: [PATCH 21/29] update fence textures when changed through the content
API (#459)
---
docs/release-notes.md | 3 +-
src/SMAPI/Metadata/CoreAssetPropagator.cs | 44 +++++++++++++++++++++--
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index e0e209a1d..2a134d13d 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -17,9 +17,10 @@
## 2.5.4
* For players:
- * Fixed NPC and tree textures not updated when changed through the content API.
+ * Fixed fence, NPC, and tree textures not updated when a mod changes them through the content API.
* Fixed visual bug on Linux/Mac when mods overlay images through the content API.
* Fixed error when a mod removes an asset editor/loader.
+ * Fixed minimum game version incorrectly changed from 1.2.30 to 1.2.33 in SMAPI 2.5.3.
* For the [log parser][]:
* Fixed error when log text contains certain tokens.
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 4a1d60971..1702ee265 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -333,6 +333,9 @@ private object PropagateImpl(LocalizedContentManager content, string key)
if (key.StartsWith(this.GetNormalisedPath("Characters\\Monsters\\")))
return this.ReloadNpcSprites(content, key, monster: true);
+ if (key.StartsWith(this.GetNormalisedPath("LooseSprites\\Fence")))
+ return this.ReloadFenceTextures(content, key);
+
if (key.StartsWith(this.GetNormalisedPath("Portraits\\")))
return this.ReloadNpcPortraits(content, key);
@@ -372,6 +375,34 @@ private bool ReloadBuildings(LocalizedContentManager content, string key)
return false;
}
+ /// Reload the sprites for a fence type.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// Returns whether any textures were reloaded.
+ private bool ReloadFenceTextures(LocalizedContentManager content, string key)
+ {
+ // get fence type
+ if (!int.TryParse(this.GetSegments(key)[1].Substring("Fence".Length), out int fenceType))
+ return false;
+
+ // get fences
+ Fence[] fences =
+ (
+ from location in this.GetLocations()
+ from fence in location.Objects.Values.OfType()
+ where fenceType == 1
+ ? fence.isGate
+ : fence.whichType == fenceType
+ select fence
+ )
+ .ToArray();
+
+ // update fence textures
+ foreach (Fence fence in fences)
+ fence.reloadSprite();
+ return true;
+ }
+
/// Reload the sprites for matching NPCs.
/// The content manager through which to reload the asset.
/// The asset key to reload.
@@ -490,13 +521,20 @@ private IEnumerable GetLocations()
}
}
+ /// Get the segments in a path (e.g. 'a/b' is 'a' and 'b').
+ /// The path to check.
+ private string[] GetSegments(string path)
+ {
+ if (path == null)
+ return new string[0];
+ return path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ }
+
/// Count the number of segments in a path (e.g. 'a/b' is 2).
/// The path to check.
private int CountSegments(string path)
{
- if (path == null)
- return 0;
- return path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Length;
+ return this.GetSegments(path).Length;
}
}
}
From b1cc6c1d9995db2eccead2a2c99f8f64ddb1da81 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 11:41:56 -0400
Subject: [PATCH 22/29] update new asset update logic for Stardew Valley 1.3
(#453)
---
src/SMAPI/Metadata/CoreAssetPropagator.cs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 1702ee265..277da5250 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -195,8 +195,10 @@ private object PropagateImpl(LocalizedContentManager content, string key)
/****
** Content\Critters
****/
+#if !STARDEW_VALLEY_1_3
case "tilesheets\\critters": // Criter.InitShared
return Critter.critterTexture = content.Load(key);
+#endif
case "tilesheets\\crops": // Game1.loadContent
return Game1.cropSpriteSheet = content.Load(key);
@@ -427,7 +429,11 @@ select npc
// update portrait
Texture2D texture = content.Load(key);
foreach (NPC character in characters)
+#if STARDEW_VALLEY_1_3
+ this.Reflection.GetField(character.Sprite, "spriteTexture").SetValue(texture);
+#else
character.Sprite.Texture = texture;
+#endif
return true;
}
From 5681c0f98170d5830e7f2ab58c77b92216aa9a60 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 12:01:19 -0400
Subject: [PATCH 23/29] update mod build config package
---
docs/mod-build-config.md | 10 ++++++++++
src/SMAPI.ModBuildConfig/package.nuspec | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/docs/mod-build-config.md b/docs/mod-build-config.md
index 2616d8a59..0d72e4d9c 100644
--- a/docs/mod-build-config.md
+++ b/docs/mod-build-config.md
@@ -140,6 +140,16 @@ That error means the package couldn't find your game. You can specify the game p
_[Game path](#game-path)_ above.
## Release notes
+### 2.0.3 alpha
+* Added support for Stardew Valley 1.3.
+* Added support for unit test projects.
+
+### 2.0.2
+* Fixed compatibility issue on Linux.
+
+### 2.0.1
+* Fixed mod deploy failing to create subfolders if they don't already exist.
+
### 2.0
* Added: mods are now copied into the `Mods` folder automatically (configurable).
* Added: release zips are now created automatically in your build output folder (configurable).
diff --git a/src/SMAPI.ModBuildConfig/package.nuspec b/src/SMAPI.ModBuildConfig/package.nuspec
index 6af8fefe9..d24e15bec 100644
--- a/src/SMAPI.ModBuildConfig/package.nuspec
+++ b/src/SMAPI.ModBuildConfig/package.nuspec
@@ -2,7 +2,7 @@
Pathoschild.Stardew.ModBuildConfig
- 2.0.3-alpha20180321
+ 2.0.3-alpha20180325Build package for SMAPI modsPathoschildPathoschild
From 4d668eb7022819391a6c1834e1351c9b4fc52104 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 12:17:58 -0400
Subject: [PATCH 24/29] update API packages
---
src/SMAPI.Web/StardewModdingAPI.Web.csproj | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj
index 19198503c..e2eee8a8b 100644
--- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj
+++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj
@@ -10,13 +10,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
From 04e299aeaa4f9291c15f49d8093831cae93e8329 Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 12:32:16 -0400
Subject: [PATCH 25/29] update Json.NET package
---
.../StardewModdingAPI.Mods.ConsoleCommands.csproj | 4 ++--
src/SMAPI.Mods.ConsoleCommands/packages.config | 2 +-
src/SMAPI/StardewModdingAPI.csproj | 3 ++-
src/SMAPI/packages.config | 2 +-
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj
index a5b89a336..d1f72c6c6 100644
--- a/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj
+++ b/src/SMAPI.Mods.ConsoleCommands/StardewModdingAPI.Mods.ConsoleCommands.csproj
@@ -37,8 +37,8 @@
- ..\packages\Newtonsoft.Json.11.0.1-beta3\lib\net45\Newtonsoft.Json.dll
- False
+ ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
+ True
diff --git a/src/SMAPI.Mods.ConsoleCommands/packages.config b/src/SMAPI.Mods.ConsoleCommands/packages.config
index a0f76c34a..c8b3ae63a 100644
--- a/src/SMAPI.Mods.ConsoleCommands/packages.config
+++ b/src/SMAPI.Mods.ConsoleCommands/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj
index 82a5602de..edddbd2aa 100644
--- a/src/SMAPI/StardewModdingAPI.csproj
+++ b/src/SMAPI/StardewModdingAPI.csproj
@@ -66,7 +66,8 @@
True
- ..\packages\Newtonsoft.Json.11.0.1-beta3\lib\net45\Newtonsoft.Json.dll
+ ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll
+ True
diff --git a/src/SMAPI/packages.config b/src/SMAPI/packages.config
index 1a0b78fa9..3e8769224 100644
--- a/src/SMAPI/packages.config
+++ b/src/SMAPI/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
From 0bcc1f6be95af4a309ff9bb31750f29b4b8338df Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 13:28:38 -0400
Subject: [PATCH 26/29] standardise folder checks when reloading assets (#459)
---
src/SMAPI/Metadata/CoreAssetPropagator.cs | 27 ++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 277da5250..38b205a57 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -326,19 +326,19 @@ private object PropagateImpl(LocalizedContentManager content, string key)
}
// dynamic textures
- if (key.StartsWith(this.GetNormalisedPath("Buildings\\"), StringComparison.InvariantCultureIgnoreCase))
+ if (this.IsInFolder(key, "Buildings"))
return this.ReloadBuildings(content, key);
- if (key.StartsWith(this.GetNormalisedPath("Characters\\")) && this.CountSegments(key) == 2) // ignore Characters/Dialogue/*, etc
+ if (this.IsInFolder(key, "Characters"))
return this.ReloadNpcSprites(content, key, monster: false);
- if (key.StartsWith(this.GetNormalisedPath("Characters\\Monsters\\")))
+ if (this.IsInFolder(key, "Characters\\Monsters"))
return this.ReloadNpcSprites(content, key, monster: true);
- if (key.StartsWith(this.GetNormalisedPath("LooseSprites\\Fence")))
+ if (key.StartsWith(this.GetNormalisedPath("LooseSprites\\Fence"), StringComparison.InvariantCultureIgnoreCase))
return this.ReloadFenceTextures(content, key);
- if (key.StartsWith(this.GetNormalisedPath("Portraits\\")))
+ if (this.IsInFolder(key, "Portraits"))
return this.ReloadNpcPortraits(content, key);
return false;
@@ -348,6 +348,9 @@ private object PropagateImpl(LocalizedContentManager content, string key)
/*********
** Private methods
*********/
+ /****
+ ** Reload methods
+ ****/
/// Reload building textures.
/// The content manager through which to reload the asset.
/// The asset key to reload.
@@ -491,6 +494,9 @@ private bool ReloadTreeTextures(LocalizedContentManager content, string key, int
return false;
}
+ /****
+ ** Helpers
+ ****/
/// Get an NPC name from the name of their file under Content/Characters.
/// The file name.
/// Derived from .
@@ -527,6 +533,17 @@ private IEnumerable GetLocations()
}
}
+ /// Get whether a normalised asset key is in the given folder.
+ /// The normalised asset key (like Animals/cat).
+ /// The key folder (like Animals); doesn't need to be normalised.
+ /// Whether to return true if the key is inside a subfolder of the .
+ private bool IsInFolder(string key, string folder, bool allowSubfolders = false)
+ {
+ return
+ key.StartsWith(this.GetNormalisedPath($"{folder}\\"), StringComparison.InvariantCultureIgnoreCase)
+ && (allowSubfolders || this.CountSegments(key) == this.CountSegments(folder) + 1);
+ }
+
/// Get the segments in a path (e.g. 'a/b' is 'a' and 'b').
/// The path to check.
private string[] GetSegments(string path)
From 60fc4a64886d92e70475af5bbfeb29b2e3ef26cd Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Sun, 25 Mar 2018 14:59:06 -0400
Subject: [PATCH 27/29] update animal textures when changed through the content
API (#459)
---
docs/release-notes.md | 4 +-
src/SMAPI/Metadata/CoreAssetPropagator.cs | 125 ++++++++++++++++++----
2 files changed, 104 insertions(+), 25 deletions(-)
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 2a134d13d..c30d3a3b6 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -17,8 +17,8 @@
## 2.5.4
* For players:
- * Fixed fence, NPC, and tree textures not updated when a mod changes them through the content API.
- * Fixed visual bug on Linux/Mac when mods overlay images through the content API.
+ * Fixed some textures not updated when a mod changes them (notably animals, fences, NPCs, and trees).
+ * Fixed visual bug on Linux/Mac when mods overlay textures.
* Fixed error when a mod removes an asset editor/loader.
* Fixed minimum game version incorrectly changed from 1.2.30 to 1.2.33 in SMAPI 2.5.3.
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 38b205a57..e54e02866 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -7,6 +7,7 @@
using StardewValley;
using StardewValley.BellsAndWhistles;
using StardewValley.Buildings;
+using StardewValley.Characters;
using StardewValley.Locations;
using StardewValley.Menus;
using StardewValley.Objects;
@@ -65,6 +66,16 @@ private object PropagateImpl(LocalizedContentManager content, string key)
Reflector reflection = this.Reflection;
switch (key.ToLower().Replace("/", "\\")) // normalised key so we can compare statically
{
+ /****
+ ** Animals
+ ****/
+ case "animals\\cat":
+ return this.ReloadPetOrHorseSprites(content, key);
+ case "animals\\dog":
+ return this.ReloadPetOrHorseSprites(content, key);
+ case "animals\\horse":
+ return this.ReloadPetOrHorseSprites(content, key);
+
/****
** Buildings
****/
@@ -326,6 +337,9 @@ private object PropagateImpl(LocalizedContentManager content, string key)
}
// dynamic textures
+ if (this.IsInFolder(key, "Animals"))
+ return this.ReloadFarmAnimalSprites(content, key);
+
if (this.IsInFolder(key, "Buildings"))
return this.ReloadBuildings(content, key);
@@ -351,6 +365,57 @@ private object PropagateImpl(LocalizedContentManager content, string key)
/****
** Reload methods
****/
+ /// Reload the sprites for matching pets or horses.
+ /// The animal type.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// Returns whether any textures were reloaded.
+ private bool ReloadPetOrHorseSprites(LocalizedContentManager content, string key)
+ where TAnimal : NPC
+ {
+ // find matches
+ TAnimal[] animals = this.GetCharacters().OfType().ToArray();
+ if (!animals.Any())
+ return false;
+
+ // update sprites
+ Texture2D texture = content.Load(key);
+ foreach (TAnimal animal in animals)
+ this.SetSpriteTexture(animal.sprite, texture);
+ return true;
+ }
+
+ /// Reload the sprites for matching farm animals.
+ /// The content manager through which to reload the asset.
+ /// The asset key to reload.
+ /// Returns whether any textures were reloaded.
+ /// Derived from .
+ private bool ReloadFarmAnimalSprites(LocalizedContentManager content, string key)
+ {
+ // find matches
+ FarmAnimal[] animals = this.GetFarmAnimals().ToArray();
+ if (!animals.Any())
+ return false;
+
+ // update sprites
+ Lazy texture = new Lazy(() => content.Load(key));
+ foreach (FarmAnimal animal in animals)
+ {
+ // get expected key
+ string expectedKey = animal.age < animal.ageWhenMature
+ ? $"Baby{(animal.type == "Duck" ? "White Chicken" : animal.type)}"
+ : animal.type;
+ if (animal.showDifferentTextureWhenReadyForHarvest && animal.currentProduce <= 0)
+ expectedKey = $"Sheared{expectedKey}";
+ expectedKey = $"Animals\\{expectedKey}";
+
+ // reload asset
+ if (expectedKey == key)
+ this.SetSpriteTexture(animal.sprite, texture.Value);
+ }
+ return texture.IsValueCreated;
+ }
+
/// Reload building textures.
/// The content manager through which to reload the asset.
/// The asset key to reload.
@@ -417,26 +482,14 @@ private bool ReloadNpcSprites(LocalizedContentManager content, string key, bool
{
// get NPCs
string name = this.GetNpcNameFromFileName(Path.GetFileName(key));
- NPC[] characters =
- (
- from location in this.GetLocations()
- from npc in location.characters
- where npc.name == name && npc.IsMonster == monster
- select npc
- )
- .Distinct()
- .ToArray();
+ NPC[] characters = this.GetCharacters().Where(npc => npc.name == name && npc.IsMonster == monster).ToArray();
if (!characters.Any())
return false;
// update portrait
Texture2D texture = content.Load(key);
foreach (NPC character in characters)
-#if STARDEW_VALLEY_1_3
- this.Reflection.GetField(character.Sprite, "spriteTexture").SetValue(texture);
-#else
- character.Sprite.Texture = texture;
-#endif
+ this.SetSpriteTexture(character.Sprite, texture);
return true;
}
@@ -448,15 +501,7 @@ private bool ReloadNpcPortraits(LocalizedContentManager content, string key)
{
// get NPCs
string name = this.GetNpcNameFromFileName(Path.GetFileName(key));
- NPC[] villagers =
- (
- from location in this.GetLocations()
- from npc in location.characters
- where npc.name == name && npc.isVillager()
- select npc
- )
- .Distinct()
- .ToArray();
+ NPC[] villagers = this.GetCharacters().Where(npc => npc.name == name && npc.isVillager()).ToArray();
if (!villagers.Any())
return false;
@@ -497,6 +542,18 @@ private bool ReloadTreeTextures(LocalizedContentManager content, string key, int
/****
** Helpers
****/
+ /// Reload the texture for an animated sprite.
+ /// The animated sprite to update.
+ /// The texture to set.
+ private void SetSpriteTexture(AnimatedSprite sprite, Texture2D texture)
+ {
+#if STARDEW_VALLEY_1_3
+ this.Reflection.GetField(sprite, "spriteTexture").SetValue(texture);
+#else
+ sprite.Texture = texture;
+#endif
+ }
+
/// Get an NPC name from the name of their file under Content/Characters.
/// The file name.
/// Derived from .
@@ -515,6 +572,28 @@ private string GetNpcNameFromFileName(string name)
}
}
+ /// Get all NPCs in the game (excluding farm animals).
+ private IEnumerable GetCharacters()
+ {
+ return this.GetLocations().SelectMany(p => p.characters);
+ }
+
+ /// Get all farm animals in the game.
+ private IEnumerable GetFarmAnimals()
+ {
+ foreach (GameLocation location in this.GetLocations())
+ {
+ if (location is Farm farm)
+ {
+ foreach (FarmAnimal animal in farm.animals.Values)
+ yield return animal;
+ }
+ else if (location is AnimalHouse animalHouse)
+ foreach (FarmAnimal animal in animalHouse.animals.Values)
+ yield return animal;
+ }
+ }
+
/// Get all locations in the game.
private IEnumerable GetLocations()
{
From 56288e1d0ec072d35040b7954fc7c0f8b086663e Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Mon, 26 Mar 2018 09:22:45 -0400
Subject: [PATCH 28/29] fix log parser timestamp not rendered
---
src/SMAPI.Web/Views/LogParser/Index.cshtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml
index 9c21c8c08..7213e2863 100644
--- a/src/SMAPI.Web/Views/LogParser/Index.cshtml
+++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml
@@ -70,7 +70,7 @@
Log started:
-
@Model.ParsedLog.Timestamp.UtcDateTime.ToString("yyyy-MM-dd HH:mm") UTC ({{localTimeStarted}} your time)
+
@Model.ParsedLog.Timestamp.UtcDateTime.ToString("yyyy-MM-dd HH:mm") UTC ({{localTimeStarted}} your time)
From 4d68ef3514de7deb357a0042d1af7ccf241ab5ff Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard
Date: Mon, 26 Mar 2018 09:34:45 -0400
Subject: [PATCH 29/29] update for 2.5.4 release
---
build/GlobalAssemblyInfo.cs | 4 ++--
docs/release-notes.md | 12 +++++++++---
src/SMAPI.Mods.ConsoleCommands/manifest.json | 2 +-
src/SMAPI/Constants.cs | 2 +-
4 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/build/GlobalAssemblyInfo.cs b/build/GlobalAssemblyInfo.cs
index e9236498a..d2cf8fe76 100644
--- a/build/GlobalAssemblyInfo.cs
+++ b/build/GlobalAssemblyInfo.cs
@@ -1,5 +1,5 @@
using System.Reflection;
[assembly: AssemblyProduct("SMAPI")]
-[assembly: AssemblyVersion("2.5.3")]
-[assembly: AssemblyFileVersion("2.5.3")]
+[assembly: AssemblyVersion("2.5.4")]
+[assembly: AssemblyFileVersion("2.5.4")]
diff --git a/docs/release-notes.md b/docs/release-notes.md
index c30d3a3b6..b33008008 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -17,14 +17,20 @@
## 2.5.4
* For players:
- * Fixed some textures not updated when a mod changes them (notably animals, fences, NPCs, and trees).
+ * Fixed some textures not updated when a mod changes them.
* Fixed visual bug on Linux/Mac when mods overlay textures.
- * Fixed error when a mod removes an asset editor/loader.
- * Fixed minimum game version incorrectly changed from 1.2.30 to 1.2.33 in SMAPI 2.5.3.
+ * Fixed error when mods remove an asset editor/loader.
+ * Fixed minimum game version incorrectly increased in SMAPI 2.5.3.
* For the [log parser][]:
* Fixed error when log text contains certain tokens.
+* For modders:
+ * Updated to Json.NET 11.0.2.
+
+* For SMAPI developers:
+ * Added support for beta update track to support upcoming Stardew Valley 1.3 beta.
+
## 2.5.3
* For players:
* Simplified and improved skipped-mod messages.
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index 785af01aa..a56cf66d8 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,7 +1,7 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "2.5.3",
+ "Version": "2.5.4",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll"
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index 1279f8e1a..6270186a7 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -41,7 +41,7 @@ public static class Constants
#if STARDEW_VALLEY_1_3
new SemanticVersion($"2.6-alpha.{DateTime.UtcNow:yyyyMMddHHmm}");
#else
- new SemanticVersion($"2.5.3");
+ new SemanticVersion("2.5.4");
#endif
/// The minimum supported version of Stardew Valley.