From 04b9a810dde93ff790e356f0af3510c7d20bebfc Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 8 Dec 2019 11:27:23 -0500 Subject: add asset propagation for grass textures --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 35 ++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 1c0a04f0..985e4e1b 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -474,10 +474,14 @@ namespace StardewModdingAPI.Metadata /**** ** Content\TerrainFeatures ****/ - case "terrainfeatures\\flooring": // Flooring + case "terrainfeatures\\flooring": // from Flooring Flooring.floorsTexture = content.Load(key); return true; + case "terrainfeatures\\grass": // from Grass + this.ReloadGrassTextures(content, key); + return true; + case "terrainfeatures\\hoedirt": // from HoeDirt HoeDirt.lightTexture = content.Load(key); return true; @@ -694,6 +698,35 @@ namespace StardewModdingAPI.Metadata return true; } + /// Reload tree textures. + /// The content manager through which to reload the asset. + /// The asset key to reload. + /// Returns whether any textures were reloaded. + private bool ReloadGrassTextures(LocalizedContentManager content, string key) + { + Grass[] grasses = + ( + from location in Game1.locations + from grass in location.terrainFeatures.Values.OfType() + let textureName = this.NormalizeAssetNameIgnoringEmpty( + this.Reflection.GetMethod(grass, "textureName").Invoke() + ) + where textureName == key + select grass + ) + .ToArray(); + + if (grasses.Any()) + { + Lazy texture = new Lazy(() => content.Load(key)); + foreach (Grass grass in grasses) + this.Reflection.GetField>(grass, "texture").SetValue(texture); + return true; + } + + return false; + } + /// Reload the disposition data for matching NPCs. /// The content manager through which to reload the asset. /// The asset key to reload. -- cgit From 194b96a79c335fa098a6cf55c2be75c7f2e9c6ad Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 8 Dec 2019 11:31:20 -0500 Subject: use GetLocations logic more consistently in asset propagation --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 985e4e1b..8b00d893 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -611,7 +611,7 @@ namespace StardewModdingAPI.Metadata { // get buildings string type = Path.GetFileName(key); - Building[] buildings = Game1.locations + Building[] buildings = this.GetLocations(buildingInteriors: false) .OfType() .SelectMany(p => p.buildings) .Where(p => p.buildingType.Value == type) @@ -706,7 +706,7 @@ namespace StardewModdingAPI.Metadata { Grass[] grasses = ( - from location in Game1.locations + from location in this.GetLocations() from grass in location.terrainFeatures.Values.OfType() let textureName = this.NormalizeAssetNameIgnoringEmpty( this.Reflection.GetMethod(grass, "textureName").Invoke() @@ -804,7 +804,7 @@ namespace StardewModdingAPI.Metadata /// Returns whether any textures were reloaded. private bool ReloadTreeTextures(LocalizedContentManager content, string key, int type) { - Tree[] trees = Game1.locations + Tree[] trees = this.GetLocations() .SelectMany(p => p.terrainFeatures.Values.OfType()) .Where(tree => tree.treeType.Value == type) .ToArray(); @@ -909,7 +909,8 @@ namespace StardewModdingAPI.Metadata } /// Get all locations in the game. - private IEnumerable GetLocations() + /// Whether to also get the interior locations for constructable buildings. + private IEnumerable GetLocations(bool buildingInteriors = true) { // get available root locations IEnumerable rootLocations = Game1.locations; @@ -921,7 +922,7 @@ namespace StardewModdingAPI.Metadata { yield return location; - if (location is BuildableGameLocation buildableLocation) + if (buildingInteriors && location is BuildableGameLocation buildableLocation) { foreach (Building building in buildableLocation.buildings) { -- cgit From 16f986c51b9c87c2253a39fd771dcc24f7c43db4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 14 Dec 2019 21:31:34 -0500 Subject: refactor cache invalidation & propagation to allow for future optimizations --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 67 +++++++++++++++++-------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 8b00d893..84102828 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -65,8 +65,8 @@ namespace StardewModdingAPI.Metadata /// Reload one of the game's core assets (if applicable). /// The content manager through which to reload the asset. /// The asset keys and types to reload. - /// Returns the number of reloaded assets. - public int Propagate(LocalizedContentManager content, IDictionary assets) + /// Returns a lookup of asset names to whether they've been propagated. + public IDictionary Propagate(LocalizedContentManager content, IDictionary assets) { // group into optimized lists var buckets = assets.GroupBy(p => @@ -81,25 +81,26 @@ namespace StardewModdingAPI.Metadata }); // reload assets - int reloaded = 0; + IDictionary 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; } @@ -750,51 +751,57 @@ namespace StardewModdingAPI.Metadata /// Reload the sprites for matching NPCs. /// The content manager through which to reload the asset. /// The asset keys to reload. - /// Returns the number of reloaded assets. - private int ReloadNpcSprites(LocalizedContentManager content, IEnumerable keys) + /// The asset keys which have been propagated. + private void ReloadNpcSprites(LocalizedContentManager content, IEnumerable keys, IDictionary propagated) { // get NPCs HashSet lookup = new HashSet(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(npc.Sprite.textureName.Value)); - reloaded++; + this.SetSpriteTexture(target.Npc.Sprite, content.Load(target.Key)); + propagated[target.Key] = true; } - - return reloaded; } /// Reload the portraits for matching NPCs. /// The content manager through which to reload the asset. /// The asset key to reload. - /// Returns the number of reloaded assets. - private int ReloadNpcPortraits(LocalizedContentManager content, IEnumerable keys) + /// The asset keys which have been propagated. + private void ReloadNpcPortraits(LocalizedContentManager content, IEnumerable keys, IDictionary propagated) { // get NPCs HashSet lookup = new HashSet(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(npc.Portrait.Name); - reloaded++; + target.Npc.Portrait = content.Load(target.Key); + propagated[target.Key] = true; } - return reloaded; } /// Reload tree textures. -- cgit From 5ea5932661316e2504833951188eae4118f460f3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 14 Dec 2019 22:11:25 -0500 Subject: add asset propagation for bundles --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 84102828..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; @@ -227,6 +229,29 @@ namespace StardewModdingAPI.Metadata Game1.bigCraftablesInformation = content.Load>(key); return true; + case "data\\bundles": // NetWorldState constructor + { + var bundles = this.Reflection.GetField(Game1.netWorldState.Value, "bundles").GetValue(); + var rewards = this.Reflection.GetField>(Game1.netWorldState.Value, "bundleRewards").GetValue(); + foreach (var pair in content.Load>(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>(key); return true; -- cgit From 18a5b07c5ba277e4ea424228a9148e498e0361fa Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 15 Dec 2019 00:04:00 -0500 Subject: fix overeager asset propagation for bundles --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 97093636..a684b473 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -239,11 +239,13 @@ namespace StardewModdingAPI.Metadata int rewardsCount = pair.Value.Split('/')[2].Split(' ').Length; // add bundles - if (bundles.TryGetValue(bundleKey, out bool[] values)) + if (!bundles.TryGetValue(bundleKey, out bool[] values) || values.Length < rewardsCount) + { + values ??= new bool[0]; + bundles.Remove(bundleKey); - else - values = new bool[0]; - bundles[bundleKey] = values.Concat(Enumerable.Repeat(false, rewardsCount - values.Length)).ToArray(); + bundles[bundleKey] = values.Concat(Enumerable.Repeat(false, rewardsCount - values.Length)).ToArray(); + } // add bundle rewards if (!rewards.ContainsKey(bundleKey)) -- cgit From 0a00c70397d85777499dcf7877cef08727a2dbae Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 20 Dec 2019 20:27:21 -0500 Subject: add console warning in paranoid mode --- src/SMAPI/Metadata/InstructionMetadata.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 95482708..eee5c235 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -60,6 +60,7 @@ namespace StardewModdingAPI.Metadata if (paranoidMode) { // filesystem access + yield return new TypeFinder(typeof(System.Console).FullName, InstructionHandleResult.DetectedConsoleAccess); yield return new TypeFinder(typeof(System.IO.File).FullName, InstructionHandleResult.DetectedFilesystemAccess); yield return new TypeFinder(typeof(System.IO.FileStream).FullName, InstructionHandleResult.DetectedFilesystemAccess); yield return new TypeFinder(typeof(System.IO.FileInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess); -- cgit From 9dc6054479da664ea82ec366215ba79c36bfca2c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 20 Dec 2019 20:29:02 -0500 Subject: fix typo in asset propagation --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index a684b473..b828ec00 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -196,7 +196,7 @@ namespace StardewModdingAPI.Metadata return true; case "characters\\farmer\\farmer_girl_base": // Farmer - case "characters\\farmer\\farmer_girl_bald": + case "characters\\farmer\\farmer_girl_base_bald": if (Game1.player == null || Game1.player.IsMale) return false; Game1.player.FarmerRenderer = new FarmerRenderer(key, Game1.player); -- cgit From d6901ed49626dac27e9ebf80d2ac86223a6064ca Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 22 Dec 2019 12:52:34 -0500 Subject: add asset propagation for winter flooring (#679) --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index b828ec00..b86a6790 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -506,6 +506,10 @@ namespace StardewModdingAPI.Metadata Flooring.floorsTexture = content.Load(key); return true; + case "terrainfeatures\\flooring_winter": // from Flooring + Flooring.floorsTextureWinter = content.Load(key); + return true; + case "terrainfeatures\\grass": // from Grass this.ReloadGrassTextures(content, key); return true; -- cgit