summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-07-01 19:39:04 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-07-01 19:39:04 -0400
commit3b6adf3c2676fa8f73997f9c1f8ec5f727f73690 (patch)
treee4314a49d68e8f040ade273c58c2cf730eb7dec7
parent4568f2259ba6a0808658229122daa6ff6335a4fe (diff)
downloadSMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.tar.gz
SMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.tar.bz2
SMAPI-3b6adf3c2676fa8f73997f9c1f8ec5f727f73690.zip
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.
-rw-r--r--src/StardewModdingAPI/Framework/ContentHelper.cs6
-rw-r--r--src/StardewModdingAPI/Framework/SContentManager.cs59
-rw-r--r--src/StardewModdingAPI/Program.cs16
3 files changed, 79 insertions, 2 deletions
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
*********/
+ /// <summary>The observable implementation of <see cref="AssetEditors"/>.</summary>
+ internal ObservableCollection<IAssetEditor> ObservableAssetEditors { get; } = new ObservableCollection<IAssetEditor>();
+
/// <summary>Editors which change content assets after they're loaded.</summary>
- internal IList<IAssetEditor> AssetEditors { get; } = new List<IAssetEditor>();
+ internal IList<IAssetEditor> 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<T>(string assetName, T value)
{
assetName = this.NormaliseAssetName(assetName);
+
this.Cache[assetName] = value;
}
@@ -139,6 +148,56 @@ namespace StardewModdingAPI.Framework
return this.GetKeyLocale.Invoke<string>();
}
+ /// <summary>Reset the asset cache and reload the game's static assets.</summary>
+ /// <remarks>This implementation is derived from <see cref="Game1.LoadContent"/>.</remarks>
+ public void Reset()
+ {
+ this.Monitor.Log("Resetting asset cache...", LogLevel.Trace);
+ this.Cache.Clear();
+
+ // from Game1.LoadContent
+ Game1.daybg = this.Load<Texture2D>("LooseSprites\\daybg");
+ Game1.nightbg = this.Load<Texture2D>("LooseSprites\\nightbg");
+ Game1.menuTexture = this.Load<Texture2D>("Maps\\MenuTiles");
+ Game1.lantern = this.Load<Texture2D>("LooseSprites\\Lighting\\lantern");
+ Game1.windowLight = this.Load<Texture2D>("LooseSprites\\Lighting\\windowLight");
+ Game1.sconceLight = this.Load<Texture2D>("LooseSprites\\Lighting\\sconceLight");
+ Game1.cauldronLight = this.Load<Texture2D>("LooseSprites\\Lighting\\greenLight");
+ Game1.indoorWindowLight = this.Load<Texture2D>("LooseSprites\\Lighting\\indoorWindowLight");
+ Game1.shadowTexture = this.Load<Texture2D>("LooseSprites\\shadow");
+ Game1.mouseCursors = this.Load<Texture2D>("LooseSprites\\Cursors");
+ Game1.controllerMaps = this.Load<Texture2D>("LooseSprites\\ControllerMaps");
+ Game1.animations = this.Load<Texture2D>("TileSheets\\animations");
+ Game1.achievements = this.Load<Dictionary<int, string>>("Data\\Achievements");
+ Game1.NPCGiftTastes = this.Load<Dictionary<string, string>>("Data\\NPCGiftTastes");
+ Game1.dialogueFont = this.Load<SpriteFont>("Fonts\\SpriteFont1");
+ Game1.smallFont = this.Load<SpriteFont>("Fonts\\SmallFont");
+ Game1.tinyFont = this.Load<SpriteFont>("Fonts\\tinyFont");
+ Game1.tinyFontBorder = this.Load<SpriteFont>("Fonts\\tinyFontBorder");
+ Game1.objectSpriteSheet = this.Load<Texture2D>("Maps\\springobjects");
+ Game1.cropSpriteSheet = this.Load<Texture2D>("TileSheets\\crops");
+ Game1.emoteSpriteSheet = this.Load<Texture2D>("TileSheets\\emotes");
+ Game1.debrisSpriteSheet = this.Load<Texture2D>("TileSheets\\debris");
+ Game1.bigCraftableSpriteSheet = this.Load<Texture2D>("TileSheets\\Craftables");
+ Game1.rainTexture = this.Load<Texture2D>("TileSheets\\rain");
+ Game1.buffsIcons = this.Load<Texture2D>("TileSheets\\BuffsIcons");
+ Game1.objectInformation = this.Load<Dictionary<int, string>>("Data\\ObjectInformation");
+ Game1.bigCraftablesInformation = this.Load<Dictionary<int, string>>("Data\\BigCraftablesInformation");
+ FarmerRenderer.hairStylesTexture = this.Load<Texture2D>("Characters\\Farmer\\hairstyles");
+ FarmerRenderer.shirtsTexture = this.Load<Texture2D>("Characters\\Farmer\\shirts");
+ FarmerRenderer.hatsTexture = this.Load<Texture2D>("Characters\\Farmer\\hats");
+ FarmerRenderer.accessoriesTexture = this.Load<Texture2D>("Characters\\Farmer\\accessories");
+ Furniture.furnitureTexture = this.Load<Texture2D>("TileSheets\\furniture");
+ SpriteText.spriteTexture = this.Load<Texture2D>("LooseSprites\\font_bold");
+ SpriteText.coloredTexture = this.Load<Texture2D>("LooseSprites\\font_colored");
+ Tool.weaponsTexture = this.Load<Texture2D>("TileSheets\\weapons");
+ Projectile.projectileSheet = this.Load<Texture2D>("TileSheets\\Projectiles");
+
+ // from Farmer constructor
+ if (Game1.player != null)
+ Game1.player.FarmerRenderer = new FarmerRenderer(this.Load<Texture2D>($"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();
}
/// <summary>Reload translations for all mods.</summary>