From fb253941dfdd370d3081c6e46707424d993b300a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 25 Nov 2018 00:07:26 -0500 Subject: add support for propagating map asset changes --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 8487b6be..841e6d64 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -13,6 +13,7 @@ using StardewValley.Menus; using StardewValley.Objects; using StardewValley.Projectiles; using StardewValley.TerrainFeatures; +using xTile; using xTile.Tiles; namespace StardewModdingAPI.Metadata @@ -45,10 +46,11 @@ namespace StardewModdingAPI.Metadata /// Reload one of the game's core assets (if applicable). /// The content manager through which to reload the asset. /// The asset key to reload. + /// The asset type to reload. /// Returns whether an asset was reloaded. - public bool Propagate(LocalizedContentManager content, string key) + public bool Propagate(LocalizedContentManager content, string key, Type type) { - object result = this.PropagateImpl(content, key); + object result = this.PropagateImpl(content, key, type); if (result is bool b) return b; return result != null; @@ -61,9 +63,12 @@ namespace StardewModdingAPI.Metadata /// Reload one of the game's core assets (if applicable). /// The content manager through which to reload the asset. /// The asset key to reload. - /// Returns any non-null value to indicate an asset was loaded. - private object PropagateImpl(LocalizedContentManager content, string key) + /// The asset type to reload. + /// Returns whether an asset was loaded. The return value may be true or false, or a non-null value for true. + private object PropagateImpl(LocalizedContentManager content, string key, Type type) { + key = this.GetNormalisedPath(key); + /**** ** Special case: current map tilesheet ** We only need to do this for the current location, since tilesheets are reloaded when you enter a location. @@ -78,6 +83,23 @@ namespace StardewModdingAPI.Metadata } } + /**** + ** Propagate map changes + ****/ + if (type == typeof(Map)) + { + bool anyChanged = false; + foreach (GameLocation location in this.GetLocations()) + { + if (this.GetNormalisedPath(location.mapPath.Value) == key) + { + this.Reflection.GetMethod(location, "reloadMap").Invoke(); + anyChanged = true; + } + } + return anyChanged; + } + /**** ** Propagate by key ****/ -- cgit From 924c3a5d3fe6bfad483834112883156bdf202b57 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 25 Nov 2018 15:19:12 -0500 Subject: add support for propagating NPCDisposition asset changes --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 841e6d64..8083b4b1 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Reflection; using StardewValley; @@ -163,6 +164,9 @@ namespace StardewModdingAPI.Metadata case "data\\craftingrecipes": // CraftingRecipe.InitShared return CraftingRecipe.craftingRecipes = content.Load>(key); + case "data\\npcdispositions": // NPC constructor + return this.ReloadNpcDispositions(content, key); + case "data\\npcgifttastes": // Game1.loadContent return Game1.NPCGiftTastes = content.Load>(key); @@ -482,6 +486,35 @@ namespace StardewModdingAPI.Metadata return true; } + /// Reload the disposition data for matching NPCs. + /// The content manager through which to reload the asset. + /// The asset key to reload. + /// Returns whether any NPCs were affected. + private bool ReloadNpcDispositions(LocalizedContentManager content, string key) + { + IDictionary dispositions = content.Load>(key); + foreach (NPC character in this.GetCharacters()) + { + if (!character.isVillager() || !dispositions.ContainsKey(character.Name)) + continue; + + NPC clone = new NPC(null, Vector2.Zero, 0, character.Name); + character.Age = clone.Age; + character.Manners = clone.Manners; + character.SocialAnxiety = clone.SocialAnxiety; + character.Optimism = clone.Optimism; + character.Gender = clone.Gender; + character.datable.Value = clone.datable.Value; + character.homeRegion = clone.homeRegion; + character.Birthday_Season = clone.Birthday_Season; + character.Birthday_Day = clone.Birthday_Day; + character.id = clone.id; + character.displayName = clone.displayName; + } + + return true; + } + /// Reload the sprites for matching NPCs. /// The content manager through which to reload the asset. /// The asset key to reload. -- cgit From 3744e2f1e5505c9d15fb3bc985ad147a33621048 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 3 Dec 2018 02:39:20 -0500 Subject: add SMAPI 3.0 compatibility strict mode (#606) --- src/SMAPI/Metadata/InstructionMetadata.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index ff8d54e3..c4ddf807 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -52,7 +52,10 @@ namespace StardewModdingAPI.Metadata new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.serializer), InstructionHandleResult.DetectedSaveSerialiser), new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.farmerSerializer), InstructionHandleResult.DetectedSaveSerialiser), new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.locationSerializer), InstructionHandleResult.DetectedSaveSerialiser), + new TypeFinder(typeof(ISpecialisedEvents).FullName, InstructionHandleResult.DetectedUnvalidatedUpdateTick), +#if !SMAPI_3_0_STRICT new EventFinder(typeof(SpecialisedEvents).FullName, nameof(SpecialisedEvents.UnvalidatedUpdateTick), InstructionHandleResult.DetectedUnvalidatedUpdateTick), +#endif /**** ** detect paranoid issues -- cgit From 2b97b9f701452bbcdc7bfb5c433b9906c595b195 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 6 Dec 2018 18:27:44 -0500 Subject: disable paranoid detection if paranoid warnings are disabled --- src/SMAPI/Metadata/InstructionMetadata.cs | 79 ++++++++++++++++--------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index c4ddf807..7c840b2f 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -24,54 +24,55 @@ namespace StardewModdingAPI.Metadata ** Public methods *********/ /// Get rewriters which detect or fix incompatible CIL instructions in mod assemblies. - public IEnumerable GetHandlers() + /// Whether to detect paranoid mode issues. + public IEnumerable GetHandlers(bool paranoidMode) { - return new IInstructionHandler[] - { - /**** - ** rewrite CIL to fix incompatible code - ****/ - // rewrite for crossplatform compatibility - new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchMethods), onlyIfPlatformChanged: true), + /**** + ** rewrite CIL to fix incompatible code + ****/ + // rewrite for crossplatform compatibility + yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchMethods), onlyIfPlatformChanged: true); - // rewrite for Stardew Valley 1.3 - new StaticFieldToConstantRewriter(typeof(Game1), "tileSize", Game1.tileSize), + // rewrite for Stardew Valley 1.3 + yield return new StaticFieldToConstantRewriter(typeof(Game1), "tileSize", Game1.tileSize); - /**** - ** detect mod issues - ****/ - // detect broken code - new ReferenceToMissingMemberFinder(this.ValidateReferencesToAssemblies), - new ReferenceToMemberWithUnexpectedTypeFinder(this.ValidateReferencesToAssemblies), + /**** + ** detect mod issues + ****/ + // detect broken code + yield return new ReferenceToMissingMemberFinder(this.ValidateReferencesToAssemblies); + yield return new ReferenceToMemberWithUnexpectedTypeFinder(this.ValidateReferencesToAssemblies); - /**** - ** detect code which may impact game stability - ****/ - new TypeFinder("Harmony.HarmonyInstance", InstructionHandleResult.DetectedGamePatch), - new TypeFinder("System.Runtime.CompilerServices.CallSite", InstructionHandleResult.DetectedDynamic), - new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.serializer), InstructionHandleResult.DetectedSaveSerialiser), - new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.farmerSerializer), InstructionHandleResult.DetectedSaveSerialiser), - new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.locationSerializer), InstructionHandleResult.DetectedSaveSerialiser), - new TypeFinder(typeof(ISpecialisedEvents).FullName, InstructionHandleResult.DetectedUnvalidatedUpdateTick), + /**** + ** detect code which may impact game stability + ****/ + yield return new TypeFinder("Harmony.HarmonyInstance", InstructionHandleResult.DetectedGamePatch); + yield return new TypeFinder("System.Runtime.CompilerServices.CallSite", InstructionHandleResult.DetectedDynamic); + yield return new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.serializer), InstructionHandleResult.DetectedSaveSerialiser); + yield return new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.farmerSerializer), InstructionHandleResult.DetectedSaveSerialiser); + yield return new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.locationSerializer), InstructionHandleResult.DetectedSaveSerialiser); + yield return new TypeFinder(typeof(ISpecialisedEvents).FullName, InstructionHandleResult.DetectedUnvalidatedUpdateTick); #if !SMAPI_3_0_STRICT - new EventFinder(typeof(SpecialisedEvents).FullName, nameof(SpecialisedEvents.UnvalidatedUpdateTick), InstructionHandleResult.DetectedUnvalidatedUpdateTick), + yield return new EventFinder(typeof(SpecialisedEvents).FullName, nameof(SpecialisedEvents.UnvalidatedUpdateTick), InstructionHandleResult.DetectedUnvalidatedUpdateTick); #endif - - /**** - ** detect paranoid issues - ****/ + + /**** + ** detect paranoid issues + ****/ + if (paranoidMode) + { // filesystem access - new TypeFinder(typeof(System.IO.File).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.FileStream).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.FileInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.Directory).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.DirectoryInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.DriveInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess), - new TypeFinder(typeof(System.IO.FileSystemWatcher).FullName, InstructionHandleResult.DetectedFilesystemAccess), + 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); + yield return new TypeFinder(typeof(System.IO.Directory).FullName, InstructionHandleResult.DetectedFilesystemAccess); + yield return new TypeFinder(typeof(System.IO.DirectoryInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess); + yield return new TypeFinder(typeof(System.IO.DriveInfo).FullName, InstructionHandleResult.DetectedFilesystemAccess); + yield return new TypeFinder(typeof(System.IO.FileSystemWatcher).FullName, InstructionHandleResult.DetectedFilesystemAccess); // shell access - new TypeFinder(typeof(System.Diagnostics.Process).FullName, InstructionHandleResult.DetectedShellAccess) - }; + yield return new TypeFinder(typeof(System.Diagnostics.Process).FullName, InstructionHandleResult.DetectedShellAccess); + } } } } -- cgit From b823d126d2fabac0cb8e0af3f4d7ab8594ee1aed Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 7 Dec 2018 13:39:58 -0500 Subject: fix location warps when propagating map changes (#608) --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 8083b4b1..d273c251 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -95,6 +95,7 @@ namespace StardewModdingAPI.Metadata if (this.GetNormalisedPath(location.mapPath.Value) == key) { this.Reflection.GetMethod(location, "reloadMap").Invoke(); + this.Reflection.GetMethod(location, "updateWarps").Invoke(); anyChanged = true; } } @@ -641,24 +642,6 @@ namespace StardewModdingAPI.Metadata this.Reflection.GetField(sprite, "spriteTexture").SetValue(texture); } - /// Get an NPC name from the name of their file under Content/Characters. - /// The file name. - /// Derived from . - private string GetNpcNameFromFileName(string name) - { - switch (name) - { - case "Mariner": - return "Old Mariner"; - case "DwarfKing": - return "Dwarf King"; - case "MrQi": - return "Mister Qi"; - default: - return name; - } - } - /// Get all NPCs in the game (excluding farm animals). private IEnumerable GetCharacters() { -- cgit