From 3b6adf3c2676fa8f73997f9c1f8ec5f727f73690 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 1 Jul 2017 19:39:04 -0400 Subject: reset asset cache when a new interceptor is added (#255) This lets new interceptors edit assets loaded before they were added, particularly assets loaded before mods are initialised. --- src/StardewModdingAPI/Framework/ContentHelper.cs | 6 ++- src/StardewModdingAPI/Framework/SContentManager.cs | 59 ++++++++++++++++++++++ src/StardewModdingAPI/Program.cs | 16 +++++- 3 files changed, 79 insertions(+), 2 deletions(-) (limited to 'src/StardewModdingAPI') diff --git a/src/StardewModdingAPI/Framework/ContentHelper.cs b/src/StardewModdingAPI/Framework/ContentHelper.cs index f4b541e9..b7773d6a 100644 --- a/src/StardewModdingAPI/Framework/ContentHelper.cs +++ b/src/StardewModdingAPI/Framework/ContentHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; @@ -36,8 +37,11 @@ namespace StardewModdingAPI.Framework /********* ** Accessors *********/ + /// The observable implementation of . + internal ObservableCollection ObservableAssetEditors { get; } = new ObservableCollection(); + /// Editors which change content assets after they're loaded. - internal IList AssetEditors { get; } = new List(); + internal IList AssetEditors => this.ObservableAssetEditors; /********* diff --git a/src/StardewModdingAPI/Framework/SContentManager.cs b/src/StardewModdingAPI/Framework/SContentManager.cs index d269cafa..24585963 100644 --- a/src/StardewModdingAPI/Framework/SContentManager.cs +++ b/src/StardewModdingAPI/Framework/SContentManager.cs @@ -5,10 +5,14 @@ using System.IO; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.AssemblyRewriters; using StardewModdingAPI.Framework.Content; using StardewModdingAPI.Framework.Reflection; using StardewValley; +using StardewValley.BellsAndWhistles; +using StardewValley.Objects; +using StardewValley.Projectiles; namespace StardewModdingAPI.Framework { @@ -59,6 +63,10 @@ namespace StardewModdingAPI.Framework public SContentManager(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, string languageCodeOverride, IMonitor monitor) : base(serviceProvider, rootDirectory, currentCulture, languageCodeOverride) { + // validate + if (monitor == null) + throw new ArgumentNullException(nameof(monitor)); + // initialise IReflectionHelper reflection = new ReflectionHelper(); this.Monitor = monitor; @@ -130,6 +138,7 @@ namespace StardewModdingAPI.Framework public void Inject(string assetName, T value) { assetName = this.NormaliseAssetName(assetName); + this.Cache[assetName] = value; } @@ -139,6 +148,56 @@ namespace StardewModdingAPI.Framework return this.GetKeyLocale.Invoke(); } + /// Reset the asset cache and reload the game's static assets. + /// This implementation is derived from . + public void Reset() + { + this.Monitor.Log("Resetting asset cache...", LogLevel.Trace); + this.Cache.Clear(); + + // from Game1.LoadContent + Game1.daybg = this.Load("LooseSprites\\daybg"); + Game1.nightbg = this.Load("LooseSprites\\nightbg"); + Game1.menuTexture = this.Load("Maps\\MenuTiles"); + Game1.lantern = this.Load("LooseSprites\\Lighting\\lantern"); + Game1.windowLight = this.Load("LooseSprites\\Lighting\\windowLight"); + Game1.sconceLight = this.Load("LooseSprites\\Lighting\\sconceLight"); + Game1.cauldronLight = this.Load("LooseSprites\\Lighting\\greenLight"); + Game1.indoorWindowLight = this.Load("LooseSprites\\Lighting\\indoorWindowLight"); + Game1.shadowTexture = this.Load("LooseSprites\\shadow"); + Game1.mouseCursors = this.Load("LooseSprites\\Cursors"); + Game1.controllerMaps = this.Load("LooseSprites\\ControllerMaps"); + Game1.animations = this.Load("TileSheets\\animations"); + Game1.achievements = this.Load>("Data\\Achievements"); + Game1.NPCGiftTastes = this.Load>("Data\\NPCGiftTastes"); + Game1.dialogueFont = this.Load("Fonts\\SpriteFont1"); + Game1.smallFont = this.Load("Fonts\\SmallFont"); + Game1.tinyFont = this.Load("Fonts\\tinyFont"); + Game1.tinyFontBorder = this.Load("Fonts\\tinyFontBorder"); + Game1.objectSpriteSheet = this.Load("Maps\\springobjects"); + Game1.cropSpriteSheet = this.Load("TileSheets\\crops"); + Game1.emoteSpriteSheet = this.Load("TileSheets\\emotes"); + Game1.debrisSpriteSheet = this.Load("TileSheets\\debris"); + Game1.bigCraftableSpriteSheet = this.Load("TileSheets\\Craftables"); + Game1.rainTexture = this.Load("TileSheets\\rain"); + Game1.buffsIcons = this.Load("TileSheets\\BuffsIcons"); + Game1.objectInformation = this.Load>("Data\\ObjectInformation"); + Game1.bigCraftablesInformation = this.Load>("Data\\BigCraftablesInformation"); + FarmerRenderer.hairStylesTexture = this.Load("Characters\\Farmer\\hairstyles"); + FarmerRenderer.shirtsTexture = this.Load("Characters\\Farmer\\shirts"); + FarmerRenderer.hatsTexture = this.Load("Characters\\Farmer\\hats"); + FarmerRenderer.accessoriesTexture = this.Load("Characters\\Farmer\\accessories"); + Furniture.furnitureTexture = this.Load("TileSheets\\furniture"); + SpriteText.spriteTexture = this.Load("LooseSprites\\font_bold"); + SpriteText.coloredTexture = this.Load("LooseSprites\\font_colored"); + Tool.weaponsTexture = this.Load("TileSheets\\weapons"); + Projectile.projectileSheet = this.Load("TileSheets\\Projectiles"); + + // from Farmer constructor + if (Game1.player != null) + Game1.player.FarmerRenderer = new FarmerRenderer(this.Load($"Characters\\Farmer\\farmer_" + (Game1.player.isMale ? "" : "girl_") + "base")); + } + /********* ** Private methods *********/ diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 98de4608..53efe1e3 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -708,7 +708,7 @@ namespace StardewModdingAPI { // add interceptors if (metadata.Mod.Helper.Content is ContentHelper helper) - this.ContentManager.Editors[metadata] = helper.AssetEditors; + this.ContentManager.Editors[metadata] = helper.ObservableAssetEditors; // call entry method try @@ -727,6 +727,20 @@ namespace StardewModdingAPI } } + // reset cache when needed + // only register listeners after Entry to avoid repeatedly reloading assets during load + foreach (IModMetadata metadata in loadedMods) + { + if (metadata.Mod.Helper.Content is ContentHelper helper) + { + helper.ObservableAssetEditors.CollectionChanged += (sender, e) => + { + if (e.NewItems.Count > 0) + this.ContentManager.Reset(); + }; + } + } + this.ContentManager.Reset(); } /// Reload translations for all mods. -- cgit