fix asset propagation for child sprites (#573)

This commit is contained in:
Jesse Plamondon-Willard 2018-08-12 00:41:53 -04:00
parent 99ebac7e07
commit a6f6b9cad7
2 changed files with 25 additions and 14 deletions

View File

@ -13,7 +13,7 @@
* For modders: * For modders:
* Added support for `.json` data files in the content API (including Content Patcher). * Added support for `.json` data files in the content API (including Content Patcher).
* Added asset propagation for dialogue changes through the content API. * Fixed changes through the content API not propagating correctly for dialogue and child sprites.
* Added `--mods-path` command-line argument to allow switching between mod folders. * Added `--mods-path` command-line argument to allow switching between mod folders.
* All enums are now JSON-serialised by name, since that's more user-friendly. Previously only certain predefined enums were serialised that way. JSON files which already have integer enums will still be parsed fine. * All enums are now JSON-serialised by name, since that's more user-friendly. Previously only certain predefined enums were serialised that way. JSON files which already have integer enums will still be parsed fine.
* Fixed false compatibility error when constructing multidimensional arrays. * Fixed false compatibility error when constructing multidimensional arrays.

View File

@ -313,13 +313,10 @@ namespace StardewModdingAPI.Metadata
if (this.IsInFolder(key, "Buildings")) if (this.IsInFolder(key, "Buildings"))
return this.ReloadBuildings(content, key); return this.ReloadBuildings(content, key);
if (this.IsInFolder(key, "Characters")) if (this.IsInFolder(key, "Characters") || this.IsInFolder(key, "Characters\\Monsters"))
return this.ReloadNpcSprites(content, key, monster: false); return this.ReloadNpcSprites(content, key);
if (this.IsInFolder(key, "Characters\\Monsters")) if (this.KeyStartsWith(key, "LooseSprites\\Fence"))
return this.ReloadNpcSprites(content, key, monster: true);
if (key.StartsWith(this.GetNormalisedPath("LooseSprites\\Fence"), StringComparison.InvariantCultureIgnoreCase))
return this.ReloadFenceTextures(key); return this.ReloadFenceTextures(key);
if (this.IsInFolder(key, "Portraits")) if (this.IsInFolder(key, "Portraits"))
@ -328,6 +325,7 @@ namespace StardewModdingAPI.Metadata
// dynamic data // dynamic data
if (this.IsInFolder(key, "Characters\\Dialogue")) if (this.IsInFolder(key, "Characters\\Dialogue"))
return this.ReloadNpcDialogue(key); return this.ReloadNpcDialogue(key);
if (this.IsInFolder(key, "Characters\\schedules")) if (this.IsInFolder(key, "Characters\\schedules"))
return this.ReloadNpcSchedules(key); return this.ReloadNpcSchedules(key);
@ -447,13 +445,13 @@ namespace StardewModdingAPI.Metadata
/// <summary>Reload the sprites for matching NPCs.</summary> /// <summary>Reload the sprites for matching NPCs.</summary>
/// <param name="content">The content manager through which to reload the asset.</param> /// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="key">The asset key to reload.</param> /// <param name="key">The asset key to reload.</param>
/// <param name="monster">Whether to match monsters (<c>true</c>) or non-monsters (<c>false</c>).</param>
/// <returns>Returns whether any textures were reloaded.</returns> /// <returns>Returns whether any textures were reloaded.</returns>
private bool ReloadNpcSprites(LocalizedContentManager content, string key, bool monster) private bool ReloadNpcSprites(LocalizedContentManager content, string key)
{ {
// get NPCs // get NPCs
string name = this.GetNpcNameFromFileName(Path.GetFileName(key)); NPC[] characters = this.GetCharacters()
NPC[] characters = this.GetCharacters().Where(npc => npc.Name == name && npc.IsMonster == monster).ToArray(); .Where(npc => this.GetNormalisedPath(npc.Sprite.textureName.Value) == key)
.ToArray();
if (!characters.Any()) if (!characters.Any())
return false; return false;
@ -471,15 +469,20 @@ namespace StardewModdingAPI.Metadata
private bool ReloadNpcPortraits(LocalizedContentManager content, string key) private bool ReloadNpcPortraits(LocalizedContentManager content, string key)
{ {
// get NPCs // get NPCs
string name = this.GetNpcNameFromFileName(Path.GetFileName(key)); NPC[] villagers = this.GetCharacters()
NPC[] villagers = this.GetCharacters().Where(npc => npc.Name == name && npc.isVillager()).ToArray(); .Where(npc => npc.isVillager() && this.GetNormalisedPath($"Portraits\\{this.Reflection.GetMethod(npc, "getTextureName").Invoke<string>()}") == key)
.ToArray();
if (!villagers.Any()) if (!villagers.Any())
return false; return false;
// update portrait // update portrait
Texture2D texture = content.Load<Texture2D>(key); Texture2D texture = content.Load<Texture2D>(key);
foreach (NPC villager in villagers) foreach (NPC villager in villagers)
{
villager.resetPortrait();
villager.Portrait = texture; villager.Portrait = texture;
}
return true; return true;
} }
@ -624,6 +627,14 @@ namespace StardewModdingAPI.Metadata
} }
} }
/// <summary>Get whether a key starts with a substring after the substring is normalised.</summary>
/// <param name="key">The key to check.</param>
/// <param name="rawSubstring">The substring to normalise and find.</param>
private bool KeyStartsWith(string key, string rawSubstring)
{
return key.StartsWith(this.GetNormalisedPath(rawSubstring), StringComparison.InvariantCultureIgnoreCase);
}
/// <summary>Get whether a normalised asset key is in the given folder.</summary> /// <summary>Get whether a normalised asset key is in the given folder.</summary>
/// <param name="key">The normalised asset key (like <c>Animals/cat</c>).</param> /// <param name="key">The normalised asset key (like <c>Animals/cat</c>).</param>
/// <param name="folder">The key folder (like <c>Animals</c>); doesn't need to be normalised.</param> /// <param name="folder">The key folder (like <c>Animals</c>); doesn't need to be normalised.</param>
@ -631,7 +642,7 @@ namespace StardewModdingAPI.Metadata
private bool IsInFolder(string key, string folder, bool allowSubfolders = false) private bool IsInFolder(string key, string folder, bool allowSubfolders = false)
{ {
return return
key.StartsWith(this.GetNormalisedPath($"{folder}\\"), StringComparison.InvariantCultureIgnoreCase) this.KeyStartsWith(key, $"{folder}\\")
&& (allowSubfolders || this.CountSegments(key) == this.CountSegments(folder) + 1); && (allowSubfolders || this.CountSegments(key) == this.CountSegments(folder) + 1);
} }