summaryrefslogtreecommitdiff
path: root/src/SMAPI/Metadata
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Metadata')
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs92
1 files changed, 62 insertions, 30 deletions
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 8b00d893..97093636 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework.Graphics;
+using Netcode;
using StardewModdingAPI.Framework.Reflection;
using StardewValley;
using StardewValley.BellsAndWhistles;
@@ -11,6 +12,7 @@ using StardewValley.Characters;
using StardewValley.GameData.Movies;
using StardewValley.Locations;
using StardewValley.Menus;
+using StardewValley.Network;
using StardewValley.Objects;
using StardewValley.Projectiles;
using StardewValley.TerrainFeatures;
@@ -65,8 +67,8 @@ namespace StardewModdingAPI.Metadata
/// <summary>Reload one of the game's core assets (if applicable).</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="assets">The asset keys and types to reload.</param>
- /// <returns>Returns the number of reloaded assets.</returns>
- public int Propagate(LocalizedContentManager content, IDictionary<string, Type> assets)
+ /// <returns>Returns a lookup of asset names to whether they've been propagated.</returns>
+ public IDictionary<string, bool> Propagate(LocalizedContentManager content, IDictionary<string, Type> assets)
{
// group into optimized lists
var buckets = assets.GroupBy(p =>
@@ -81,25 +83,26 @@ namespace StardewModdingAPI.Metadata
});
// reload assets
- int reloaded = 0;
+ IDictionary<string, bool> propagated = assets.ToDictionary(p => p.Key, p => false, StringComparer.InvariantCultureIgnoreCase);
foreach (var bucket in buckets)
{
switch (bucket.Key)
{
case AssetBucket.Sprite:
- reloaded += this.ReloadNpcSprites(content, bucket.Select(p => p.Key));
+ this.ReloadNpcSprites(content, bucket.Select(p => p.Key), propagated);
break;
case AssetBucket.Portrait:
- reloaded += this.ReloadNpcPortraits(content, bucket.Select(p => p.Key));
+ this.ReloadNpcPortraits(content, bucket.Select(p => p.Key), propagated);
break;
default:
- reloaded += bucket.Count(p => this.PropagateOther(content, p.Key, p.Value));
+ foreach (var entry in bucket)
+ propagated[entry.Key] = this.PropagateOther(content, entry.Key, entry.Value);
break;
}
}
- return reloaded;
+ return propagated;
}
@@ -226,6 +229,29 @@ namespace StardewModdingAPI.Metadata
Game1.bigCraftablesInformation = content.Load<Dictionary<int, string>>(key);
return true;
+ case "data\\bundles": // NetWorldState constructor
+ {
+ var bundles = this.Reflection.GetField<NetBundles>(Game1.netWorldState.Value, "bundles").GetValue();
+ var rewards = this.Reflection.GetField<NetIntDictionary<bool, NetBool>>(Game1.netWorldState.Value, "bundleRewards").GetValue();
+ foreach (var pair in content.Load<Dictionary<string, string>>(key))
+ {
+ int bundleKey = int.Parse(pair.Key.Split('/')[1]);
+ int rewardsCount = pair.Value.Split('/')[2].Split(' ').Length;
+
+ // add bundles
+ if (bundles.TryGetValue(bundleKey, out bool[] values))
+ bundles.Remove(bundleKey);
+ else
+ values = new bool[0];
+ bundles[bundleKey] = values.Concat(Enumerable.Repeat(false, rewardsCount - values.Length)).ToArray();
+
+ // add bundle rewards
+ if (!rewards.ContainsKey(bundleKey))
+ rewards[bundleKey] = false;
+ }
+ }
+ break;
+
case "data\\clothinginformation": // Game1.LoadContent
Game1.clothingInformation = content.Load<Dictionary<int, string>>(key);
return true;
@@ -750,51 +776,57 @@ namespace StardewModdingAPI.Metadata
/// <summary>Reload the sprites for matching NPCs.</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="keys">The asset keys to reload.</param>
- /// <returns>Returns the number of reloaded assets.</returns>
- private int ReloadNpcSprites(LocalizedContentManager content, IEnumerable<string> keys)
+ /// <param name="propagated">The asset keys which have been propagated.</param>
+ private void ReloadNpcSprites(LocalizedContentManager content, IEnumerable<string> keys, IDictionary<string, bool> propagated)
{
// get NPCs
HashSet<string> lookup = new HashSet<string>(keys, StringComparer.InvariantCultureIgnoreCase);
- NPC[] characters = this.GetCharacters()
- .Where(npc => npc.Sprite != null && lookup.Contains(this.NormalizeAssetNameIgnoringEmpty(npc.Sprite?.Texture?.Name)))
+ var characters =
+ (
+ from npc in this.GetCharacters()
+ let key = this.NormalizeAssetNameIgnoringEmpty(npc.Sprite?.Texture?.Name)
+ where key != null && lookup.Contains(key)
+ select new { Npc = npc, Key = key }
+ )
.ToArray();
if (!characters.Any())
- return 0;
+ return;
// update sprite
- int reloaded = 0;
- foreach (NPC npc in characters)
+ foreach (var target in characters)
{
- this.SetSpriteTexture(npc.Sprite, content.Load<Texture2D>(npc.Sprite.textureName.Value));
- reloaded++;
+ this.SetSpriteTexture(target.Npc.Sprite, content.Load<Texture2D>(target.Key));
+ propagated[target.Key] = true;
}
-
- return reloaded;
}
/// <summary>Reload the portraits for matching NPCs.</summary>
/// <param name="content">The content manager through which to reload the asset.</param>
/// <param name="keys">The asset key to reload.</param>
- /// <returns>Returns the number of reloaded assets.</returns>
- private int ReloadNpcPortraits(LocalizedContentManager content, IEnumerable<string> keys)
+ /// <param name="propagated">The asset keys which have been propagated.</param>
+ private void ReloadNpcPortraits(LocalizedContentManager content, IEnumerable<string> keys, IDictionary<string, bool> propagated)
{
// get NPCs
HashSet<string> lookup = new HashSet<string>(keys, StringComparer.InvariantCultureIgnoreCase);
- var villagers = this
- .GetCharacters()
- .Where(npc => npc.isVillager() && lookup.Contains(this.NormalizeAssetNameIgnoringEmpty(npc.Portrait?.Name)))
+ var characters =
+ (
+ from npc in this.GetCharacters()
+ where npc.isVillager()
+
+ let key = this.NormalizeAssetNameIgnoringEmpty(npc.Portrait?.Name)
+ where key != null && lookup.Contains(key)
+ select new { Npc = npc, Key = key }
+ )
.ToArray();
- if (!villagers.Any())
- return 0;
+ if (!characters.Any())
+ return;
// update portrait
- int reloaded = 0;
- foreach (NPC npc in villagers)
+ foreach (var target in characters)
{
- npc.Portrait = content.Load<Texture2D>(npc.Portrait.Name);
- reloaded++;
+ target.Npc.Portrait = content.Load<Texture2D>(target.Key);
+ propagated[target.Key] = true;
}
- return reloaded;
}
/// <summary>Reload tree textures.</summary>