diff options
Diffstat (limited to 'src/SMAPI/Metadata')
| -rw-r--r-- | src/SMAPI/Metadata/CoreAssetPropagator.cs | 92 |
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> |
