diff --git a/docs/technical-docs.md b/docs/technical-docs.md index 5883ee00..1d69f868 100644 --- a/docs/technical-docs.md +++ b/docs/technical-docs.md @@ -105,8 +105,8 @@ SMAPI uses a small number of conditional compilation constants, which you can se flag | purpose ---- | ------- -`SMAPI_FOR_WINDOWS` | Indicates that SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`. - +`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`. +`SMAPI_3_0_STRICT` | Whether to exclude all deprecated APIs from compilation. This is useful for testing mods for SMAPI 3.0 compatibility. # SMAPI web services ## Overview diff --git a/src/SMAPI.Mods.ConsoleCommands/ModEntry.cs b/src/SMAPI.Mods.ConsoleCommands/ModEntry.cs index 7588043d..30951064 100644 --- a/src/SMAPI.Mods.ConsoleCommands/ModEntry.cs +++ b/src/SMAPI.Mods.ConsoleCommands/ModEntry.cs @@ -29,7 +29,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands helper.ConsoleCommands.Add(command.Name, command.Description, (name, args) => this.HandleCommand(command, name, args)); // hook events - GameEvents.UpdateTick += this.GameEvents_UpdateTick; + helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; } @@ -39,7 +39,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands /// The method invoked when the game updates its state. /// The event sender. /// The event arguments. - private void GameEvents_UpdateTick(object sender, EventArgs e) + private void OnUpdateTicked(object sender, EventArgs e) { if (!Context.IsWorldReady) return; diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index 1782308b..2e7719eb 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -47,7 +47,7 @@ namespace StardewModdingAPI.Tests.Utilities Assert.AreEqual(major, version.MajorVersion, "The major version doesn't match the given value."); Assert.AreEqual(minor, version.MinorVersion, "The minor version doesn't match the given value."); Assert.AreEqual(patch, version.PatchVersion, "The patch version doesn't match the given value."); - Assert.AreEqual(string.IsNullOrWhiteSpace(tag) ? null : tag.Trim(), version.Build, "The tag doesn't match the given value."); + Assert.AreEqual(string.IsNullOrWhiteSpace(tag) ? null : tag.Trim(), version.PrereleaseTag, "The tag doesn't match the given value."); return version.ToString(); } diff --git a/src/SMAPI/Context.cs b/src/SMAPI/Context.cs index c7aed81d..cd1cf1c2 100644 --- a/src/SMAPI/Context.cs +++ b/src/SMAPI/Context.cs @@ -22,7 +22,7 @@ namespace StardewModdingAPI /// Whether is true and the player is free to move (e.g. not using a tool). public static bool CanPlayerMove => Context.IsPlayerFree && Game1.player.CanMove; - /// Whether the game is currently running the draw loop. This isn't relevant to most mods, since you should use to draw to the screen. + /// Whether the game is currently running the draw loop. This isn't relevant to most mods, since you should use events to draw to the screen. public static bool IsInDrawLoop { get; internal set; } /// Whether and the player loaded the save in multiplayer mode (regardless of whether any other players are connected). diff --git a/src/SMAPI/Events/ContentEvents.cs b/src/SMAPI/Events/ContentEvents.cs index 3bf3881b..99369cae 100644 --- a/src/SMAPI/Events/ContentEvents.cs +++ b/src/SMAPI/Events/ContentEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -46,3 +47,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/ControlEvents.cs b/src/SMAPI/Events/ControlEvents.cs index c50d5bea..5626ff81 100644 --- a/src/SMAPI/Events/ControlEvents.cs +++ b/src/SMAPI/Events/ControlEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using Microsoft.Xna.Framework.Input; using StardewModdingAPI.Framework; @@ -124,3 +125,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsClickableMenuChanged.cs b/src/SMAPI/Events/EventArgsClickableMenuChanged.cs index 5e00b86d..a0b903b7 100644 --- a/src/SMAPI/Events/EventArgsClickableMenuChanged.cs +++ b/src/SMAPI/Events/EventArgsClickableMenuChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewValley.Menus; @@ -29,3 +30,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsClickableMenuClosed.cs b/src/SMAPI/Events/EventArgsClickableMenuClosed.cs index 65751da7..77db69ea 100644 --- a/src/SMAPI/Events/EventArgsClickableMenuClosed.cs +++ b/src/SMAPI/Events/EventArgsClickableMenuClosed.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewValley.Menus; @@ -24,3 +25,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsControllerButtonPressed.cs b/src/SMAPI/Events/EventArgsControllerButtonPressed.cs index 3243b80b..949446e1 100644 --- a/src/SMAPI/Events/EventArgsControllerButtonPressed.cs +++ b/src/SMAPI/Events/EventArgsControllerButtonPressed.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -30,3 +31,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsControllerButtonReleased.cs b/src/SMAPI/Events/EventArgsControllerButtonReleased.cs index e05a080b..d6d6d840 100644 --- a/src/SMAPI/Events/EventArgsControllerButtonReleased.cs +++ b/src/SMAPI/Events/EventArgsControllerButtonReleased.cs @@ -1,4 +1,5 @@ -using System; +#if !SMAPI_3_0_STRICT +using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -30,3 +31,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsControllerTriggerPressed.cs b/src/SMAPI/Events/EventArgsControllerTriggerPressed.cs index a2087733..33be2fa3 100644 --- a/src/SMAPI/Events/EventArgsControllerTriggerPressed.cs +++ b/src/SMAPI/Events/EventArgsControllerTriggerPressed.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -35,3 +36,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsControllerTriggerReleased.cs b/src/SMAPI/Events/EventArgsControllerTriggerReleased.cs index d2eecbec..e90ff712 100644 --- a/src/SMAPI/Events/EventArgsControllerTriggerReleased.cs +++ b/src/SMAPI/Events/EventArgsControllerTriggerReleased.cs @@ -1,4 +1,5 @@ -using System; +#if !SMAPI_3_0_STRICT +using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -35,3 +36,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsInput.cs b/src/SMAPI/Events/EventArgsInput.cs index 0cafdba5..837de2f8 100644 --- a/src/SMAPI/Events/EventArgsInput.cs +++ b/src/SMAPI/Events/EventArgsInput.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using System.Collections.Generic; @@ -60,3 +61,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsIntChanged.cs b/src/SMAPI/Events/EventArgsIntChanged.cs index a018695c..76ec6d08 100644 --- a/src/SMAPI/Events/EventArgsIntChanged.cs +++ b/src/SMAPI/Events/EventArgsIntChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; namespace StardewModdingAPI.Events @@ -28,3 +29,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsInventoryChanged.cs b/src/SMAPI/Events/EventArgsInventoryChanged.cs index 3a2354b6..488dd23f 100644 --- a/src/SMAPI/Events/EventArgsInventoryChanged.cs +++ b/src/SMAPI/Events/EventArgsInventoryChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using System.Collections.Generic; using System.Linq; @@ -39,3 +40,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsKeyPressed.cs b/src/SMAPI/Events/EventArgsKeyPressed.cs index d9d81e10..6204d821 100644 --- a/src/SMAPI/Events/EventArgsKeyPressed.cs +++ b/src/SMAPI/Events/EventArgsKeyPressed.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using Microsoft.Xna.Framework.Input; @@ -24,3 +25,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsKeyboardStateChanged.cs b/src/SMAPI/Events/EventArgsKeyboardStateChanged.cs index 14e397ce..2c3203b1 100644 --- a/src/SMAPI/Events/EventArgsKeyboardStateChanged.cs +++ b/src/SMAPI/Events/EventArgsKeyboardStateChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using Microsoft.Xna.Framework.Input; @@ -29,3 +30,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsLevelUp.cs b/src/SMAPI/Events/EventArgsLevelUp.cs index e9a697e7..06c70088 100644 --- a/src/SMAPI/Events/EventArgsLevelUp.cs +++ b/src/SMAPI/Events/EventArgsLevelUp.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Enums; @@ -51,3 +52,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsLocationBuildingsChanged.cs b/src/SMAPI/Events/EventArgsLocationBuildingsChanged.cs index e8184ebe..25e84722 100644 --- a/src/SMAPI/Events/EventArgsLocationBuildingsChanged.cs +++ b/src/SMAPI/Events/EventArgsLocationBuildingsChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using System.Collections.Generic; using System.Linq; @@ -37,3 +38,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs b/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs index 3bb387d5..9ca2e3e2 100644 --- a/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs +++ b/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using System.Collections.Generic; using System.Linq; @@ -38,3 +39,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsLocationsChanged.cs b/src/SMAPI/Events/EventArgsLocationsChanged.cs index 20984f45..1a59e612 100644 --- a/src/SMAPI/Events/EventArgsLocationsChanged.cs +++ b/src/SMAPI/Events/EventArgsLocationsChanged.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using System.Collections.Generic; using System.Linq; @@ -31,3 +32,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsMineLevelChanged.cs b/src/SMAPI/Events/EventArgsMineLevelChanged.cs index c82fed35..c63b04e9 100644 --- a/src/SMAPI/Events/EventArgsMineLevelChanged.cs +++ b/src/SMAPI/Events/EventArgsMineLevelChanged.cs @@ -1,4 +1,5 @@ -using System; +#if !SMAPI_3_0_STRICT +using System; namespace StardewModdingAPI.Events { @@ -28,3 +29,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsMouseStateChanged.cs b/src/SMAPI/Events/EventArgsMouseStateChanged.cs index 57298164..09f3f759 100644 --- a/src/SMAPI/Events/EventArgsMouseStateChanged.cs +++ b/src/SMAPI/Events/EventArgsMouseStateChanged.cs @@ -1,4 +1,5 @@ -using System; +#if !SMAPI_3_0_STRICT +using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -40,3 +41,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsPlayerWarped.cs b/src/SMAPI/Events/EventArgsPlayerWarped.cs index 93026aea..d1aa1588 100644 --- a/src/SMAPI/Events/EventArgsPlayerWarped.cs +++ b/src/SMAPI/Events/EventArgsPlayerWarped.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewValley; @@ -30,3 +31,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/EventArgsValueChanged.cs b/src/SMAPI/Events/EventArgsValueChanged.cs index 1d25af49..7bfac7a2 100644 --- a/src/SMAPI/Events/EventArgsValueChanged.cs +++ b/src/SMAPI/Events/EventArgsValueChanged.cs @@ -1,4 +1,5 @@ -using System; +#if !SMAPI_3_0_STRICT +using System; namespace StardewModdingAPI.Events { @@ -28,4 +29,5 @@ namespace StardewModdingAPI.Events this.NewValue = newValue; } } -} \ No newline at end of file +} +#endif diff --git a/src/SMAPI/Events/GameEvents.cs b/src/SMAPI/Events/GameEvents.cs index 13f6bfb0..39b77f99 100644 --- a/src/SMAPI/Events/GameEvents.cs +++ b/src/SMAPI/Events/GameEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -123,3 +124,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/GraphicsEvents.cs b/src/SMAPI/Events/GraphicsEvents.cs index de79e42e..be29bf11 100644 --- a/src/SMAPI/Events/GraphicsEvents.cs +++ b/src/SMAPI/Events/GraphicsEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -121,3 +122,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/InputEvents.cs b/src/SMAPI/Events/InputEvents.cs index 788dde62..255b9c8a 100644 --- a/src/SMAPI/Events/InputEvents.cs +++ b/src/SMAPI/Events/InputEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -57,3 +58,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/LocationEvents.cs b/src/SMAPI/Events/LocationEvents.cs index 4aad5387..e0bcd853 100644 --- a/src/SMAPI/Events/LocationEvents.cs +++ b/src/SMAPI/Events/LocationEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -68,3 +69,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/MenuEvents.cs b/src/SMAPI/Events/MenuEvents.cs index 502ec340..e36cb498 100644 --- a/src/SMAPI/Events/MenuEvents.cs +++ b/src/SMAPI/Events/MenuEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -57,3 +58,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/MineEvents.cs b/src/SMAPI/Events/MineEvents.cs index 617c8013..954c844a 100644 --- a/src/SMAPI/Events/MineEvents.cs +++ b/src/SMAPI/Events/MineEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -46,3 +47,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/MultiplayerEvents.cs b/src/SMAPI/Events/MultiplayerEvents.cs index 14c58031..7e8328a4 100644 --- a/src/SMAPI/Events/MultiplayerEvents.cs +++ b/src/SMAPI/Events/MultiplayerEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -79,3 +80,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/PlayerEvents.cs b/src/SMAPI/Events/PlayerEvents.cs index 4f5f4a37..1193675f 100644 --- a/src/SMAPI/Events/PlayerEvents.cs +++ b/src/SMAPI/Events/PlayerEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -69,3 +70,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/SaveEvents.cs b/src/SMAPI/Events/SaveEvents.cs index 5b83efc8..156d3047 100644 --- a/src/SMAPI/Events/SaveEvents.cs +++ b/src/SMAPI/Events/SaveEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -101,3 +102,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/SpecialisedEvents.cs b/src/SMAPI/Events/SpecialisedEvents.cs index 482ac62e..0dd726e9 100644 --- a/src/SMAPI/Events/SpecialisedEvents.cs +++ b/src/SMAPI/Events/SpecialisedEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -46,3 +47,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Events/TimeEvents.cs b/src/SMAPI/Events/TimeEvents.cs index cca6a056..61491dc8 100644 --- a/src/SMAPI/Events/TimeEvents.cs +++ b/src/SMAPI/Events/TimeEvents.cs @@ -1,3 +1,4 @@ +#if !SMAPI_3_0_STRICT using System; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -57,3 +58,4 @@ namespace StardewModdingAPI.Events } } } +#endif diff --git a/src/SMAPI/Framework/Events/EventManager.cs b/src/SMAPI/Framework/Events/EventManager.cs index b9d1c453..0ad85adf 100644 --- a/src/SMAPI/Framework/Events/EventManager.cs +++ b/src/SMAPI/Framework/Events/EventManager.cs @@ -1,5 +1,7 @@ using System.Diagnostics.CodeAnalysis; +#if !SMAPI_3_0_STRICT using Microsoft.Xna.Framework.Input; +#endif using StardewModdingAPI.Events; namespace StardewModdingAPI.Framework.Events @@ -156,6 +158,7 @@ namespace StardewModdingAPI.Framework.Events public readonly ManagedEvent UnvalidatedUpdateTicked; +#if !SMAPI_3_0_STRICT /********* ** Events (old) *********/ @@ -342,6 +345,7 @@ namespace StardewModdingAPI.Framework.Events /// Raised after the in-game clock changes. public readonly ManagedEvent Legacy_TimeOfDayChanged; +#endif /********* @@ -354,7 +358,9 @@ namespace StardewModdingAPI.Framework.Events { // create shortcut initialisers ManagedEvent ManageEventOf(string typeName, string eventName) => new ManagedEvent($"{typeName}.{eventName}", monitor, modRegistry); +#if !SMAPI_3_0_STRICT ManagedEvent ManageEvent(string typeName, string eventName) => new ManagedEvent($"{typeName}.{eventName}", monitor, modRegistry); +#endif // init events (new) this.MenuChanged = ManageEventOf(nameof(IModEvents.Display), nameof(IDisplayEvents.MenuChanged)); @@ -405,6 +411,7 @@ namespace StardewModdingAPI.Framework.Events this.UnvalidatedUpdateTicking = ManageEventOf(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicking)); this.UnvalidatedUpdateTicked = ManageEventOf(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicked)); +#if !SMAPI_3_0_STRICT // init events (old) this.Legacy_LocaleChanged = ManageEventOf>(nameof(ContentEvents), nameof(ContentEvents.AfterLocaleChanged)); @@ -466,6 +473,7 @@ namespace StardewModdingAPI.Framework.Events this.Legacy_AfterDayStarted = ManageEvent(nameof(TimeEvents), nameof(TimeEvents.AfterDayStarted)); this.Legacy_TimeOfDayChanged = ManageEventOf(nameof(TimeEvents), nameof(TimeEvents.TimeOfDayChanged)); +#endif } } } diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index 5e190e55..cd7ac8ea 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -131,6 +131,7 @@ namespace StardewModdingAPI.Framework.ModHelpers this.Data.WriteJsonFile("config.json", config); } +#if !SMAPI_3_0_STRICT /**** ** Generic JSON files ****/ @@ -199,6 +200,7 @@ namespace StardewModdingAPI.Framework.ModHelpers // create content pack return this.CreateContentPack(directoryPath, manifest); } +#endif /// Get all content packs loaded for this mod. public IEnumerable GetContentPacks() diff --git a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs index f3555c2d..6592760e 100644 --- a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs +++ b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs @@ -23,7 +23,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// The instruction is compatible, but uses the dynamic keyword which won't work on Linux/Mac. DetectedDynamic, - /// The instruction is compatible, but references which may impact stability. + /// The instruction is compatible, but references or which may impact stability. DetectedUnvalidatedUpdateTick, /// The instruction accesses the filesystem directly. diff --git a/src/SMAPI/Framework/ModLoading/ModWarning.cs b/src/SMAPI/Framework/ModLoading/ModWarning.cs index c62199b2..e643cb05 100644 --- a/src/SMAPI/Framework/ModLoading/ModWarning.cs +++ b/src/SMAPI/Framework/ModLoading/ModWarning.cs @@ -22,7 +22,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// The mod uses the dynamic keyword which won't work on Linux/Mac. UsesDynamic = 8, - /// The mod references which may impact stability. + /// The mod references or which may impact stability. UsesUnvalidatedUpdateTick = 16, /// The mod has no update keys set. diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 827ed82c..eff7cb3b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -180,6 +180,7 @@ namespace StardewModdingAPI.Framework // initialise SMAPI try { +#if !SMAPI_3_0_STRICT // hook up events ContentEvents.Init(this.EventManager, this.DeprecationManager); ControlEvents.Init(this.EventManager, this.DeprecationManager); @@ -194,6 +195,7 @@ namespace StardewModdingAPI.Framework SaveEvents.Init(this.EventManager, this.DeprecationManager); SpecialisedEvents.Init(this.EventManager, this.DeprecationManager); TimeEvents.Init(this.EventManager, this.DeprecationManager); +#endif // init JSON parser JsonConverter[] converters = { @@ -216,7 +218,7 @@ namespace StardewModdingAPI.Framework // override game SGame.ConstructorHack = new SGameConstructorHack(this.Monitor, this.Reflection, this.Toolkit.JsonHelper); - this.GameInstance = new SGame(this.Monitor, this.MonitorForGame, this.Reflection, this.EventManager, this.Toolkit.JsonHelper, this.ModRegistry, this.DeprecationManager, this.InitialiseAfterGameStart, this.Dispose); + this.GameInstance = new SGame(this.Monitor, this.MonitorForGame, this.Reflection, this.EventManager, this.Toolkit.JsonHelper, this.ModRegistry, this.DeprecationManager, this.OnLocaleChanged, this.InitialiseAfterGameStart, this.Dispose); StardewValley.Program.gamePtr = this.GameInstance; // add exit handler @@ -239,12 +241,13 @@ namespace StardewModdingAPI.Framework } }).Start(); - // hook into game events - ContentEvents.AfterLocaleChanged += (sender, e) => this.OnLocaleChanged(); - // set window titles this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion}"; Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion}"; +#if SMAPI_3_0_STRICT + this.GameInstance.Window.Title += " [SMAPI 3.0 strict mode]"; + Console.Title += " [SMAPI 3.0 strict mode]"; +#endif } catch (Exception ex) { @@ -348,8 +351,11 @@ namespace StardewModdingAPI.Framework private void InitialiseAfterGameStart() { // add headers +#if SMAPI_3_0_STRICT + this.Monitor.Log($"You're running SMAPI 3.0 strict mode, so most mods won't work correctly. If that wasn't intended, install the normal version of SMAPI from https://smapi.io instead.", LogLevel.Warn); +#endif if (this.Settings.DeveloperMode) - this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); + this.Monitor.Log($"You have SMAPI for developers, so the console will be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); if (!this.Settings.CheckForUpdates) this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn); if (!this.Monitor.WriteToConsole) @@ -409,6 +415,11 @@ namespace StardewModdingAPI.Framework int modsLoaded = this.ModRegistry.GetAll().Count(); this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion} with {modsLoaded} mods"; Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion} with {modsLoaded} mods"; +#if SMAPI_3_0_STRICT + this.GameInstance.Window.Title += " [SMAPI 3.0 strict mode]"; + Console.Title += " [SMAPI 3.0 strict mode]"; +#endif + // start SMAPI console new Thread(this.RunConsoleLoop).Start(); diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index f76245a2..d15c5c3e 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -9,7 +9,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; using Netcode; using StardewModdingAPI.Enums; using StardewModdingAPI.Events; @@ -70,12 +69,15 @@ namespace StardewModdingAPI.Framework /// Whether the after-load events were raised for this session. private bool RaisedAfterLoadEvent; - /// Whether the game is saving and SMAPI has already raised . + /// Whether the game is saving and SMAPI has already raised . private bool IsBetweenSaveEvents; - /// Whether the game is creating the save file and SMAPI has already raised . + /// Whether the game is creating the save file and SMAPI has already raised . private bool IsBetweenCreateEvents; + /// A callback to invoke after the content language changes. + private readonly Action OnLocaleChanged; + /// A callback to invoke after the game finishes initialising. private readonly Action OnGameInitialised; @@ -138,9 +140,10 @@ namespace StardewModdingAPI.Framework /// Encapsulates SMAPI's JSON file parsing. /// Tracks the installed mods. /// Manages deprecation warnings. + /// A callback to invoke after the content language changes. /// A callback to invoke after the game finishes initialising. /// A callback to invoke when the game exits. - internal SGame(IMonitor monitor, IMonitor monitorForGame, Reflector reflection, EventManager eventManager, JsonHelper jsonHelper, ModRegistry modRegistry, DeprecationManager deprecationManager, Action onGameInitialised, Action onGameExiting) + internal SGame(IMonitor monitor, IMonitor monitorForGame, Reflector reflection, EventManager eventManager, JsonHelper jsonHelper, ModRegistry modRegistry, DeprecationManager deprecationManager, Action onLocaleChanged, Action onGameInitialised, Action onGameExiting) { SGame.ConstructorHack = null; @@ -158,6 +161,7 @@ namespace StardewModdingAPI.Framework this.ModRegistry = modRegistry; this.Reflection = reflection; this.DeprecationManager = deprecationManager; + this.OnLocaleChanged = onLocaleChanged; this.OnGameInitialised = onGameInitialised; this.OnGameExiting = onGameExiting; Game1.input = new SInputState(); @@ -212,7 +216,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log("Context: returned to title", LogLevel.Trace); this.Multiplayer.Peers.Clear(); this.Events.ReturnedToTitle.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_AfterReturnToTitle.Raise(); +#endif } /// Constructor a content manager to read XNB files. @@ -296,7 +302,9 @@ namespace StardewModdingAPI.Framework this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed)); base.Update(gameTime); this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_UnvalidatedUpdateTick.Raise(); +#endif return; } @@ -343,7 +351,9 @@ namespace StardewModdingAPI.Framework // This should *always* run, even when suppressing mod events, since the game uses // this too. For example, doing this after mod event suppression would prevent the // user from doing anything on the overnight shipping screen. +#if !SMAPI_3_0_STRICT SInputState previousInputState = this.Input.Clone(); +#endif SInputState inputState = this.Input; if (this.IsActive) inputState.TrueUpdate(); @@ -364,7 +374,9 @@ namespace StardewModdingAPI.Framework this.IsBetweenCreateEvents = true; this.Monitor.Log("Context: before save creation.", LogLevel.Trace); this.Events.SaveCreating.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_BeforeCreateSave.Raise(); +#endif } // raise before-save @@ -373,14 +385,18 @@ namespace StardewModdingAPI.Framework this.IsBetweenSaveEvents = true; this.Monitor.Log("Context: before save.", LogLevel.Trace); this.Events.Saving.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_BeforeSave.Raise(); +#endif } // suppress non-save events this.Events.UnvalidatedUpdateTicking.Raise(new UnvalidatedUpdateTickingEventArgs(this.TicksElapsed)); base.Update(gameTime); this.Events.UnvalidatedUpdateTicked.Raise(new UnvalidatedUpdateTickedEventArgs(this.TicksElapsed)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_UnvalidatedUpdateTick.Raise(); +#endif return; } if (this.IsBetweenCreateEvents) @@ -389,7 +405,9 @@ namespace StardewModdingAPI.Framework this.IsBetweenCreateEvents = false; this.Monitor.Log($"Context: after save creation, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); this.Events.SaveCreated.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_AfterCreateSave.Raise(); +#endif } if (this.IsBetweenSaveEvents) { @@ -398,9 +416,10 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Context: after save, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); this.Events.Saved.RaiseEmpty(); this.Events.DayStarted.RaiseEmpty(); - +#if !SMAPI_3_0_STRICT this.Events.Legacy_AfterSave.Raise(); this.Events.Legacy_AfterDayStarted.Raise(); +#endif } /********* @@ -430,7 +449,11 @@ namespace StardewModdingAPI.Framework var now = this.Watchers.LocaleWatcher.CurrentValue; this.Monitor.Log($"Context: locale set to {now}.", LogLevel.Trace); + + this.OnLocaleChanged(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_LocaleChanged.Raise(new EventArgsValueChanged(was.ToString(), now.ToString())); +#endif this.Watchers.LocaleWatcher.Reset(); } @@ -457,9 +480,10 @@ namespace StardewModdingAPI.Framework this.RaisedAfterLoadEvent = true; this.Events.SaveLoaded.RaiseEmpty(); this.Events.DayStarted.RaiseEmpty(); - +#if !SMAPI_3_0_STRICT this.Events.Legacy_AfterLoad.Raise(); this.Events.Legacy_AfterDayStarted.Raise(); +#endif } /********* @@ -478,7 +502,9 @@ namespace StardewModdingAPI.Framework Point newSize = this.Watchers.WindowSizeWatcher.CurrentValue; this.Events.WindowResized.Raise(new WindowResizedEventArgs(oldSize, newSize)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_Resize.Raise(); +#endif this.Watchers.WindowSizeWatcher.Reset(); } @@ -527,9 +553,10 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Events: button {button} pressed.", LogLevel.Trace); this.Events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState)); - this.Events.Legacy_ButtonPressed.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); +#if !SMAPI_3_0_STRICT // legacy events + this.Events.Legacy_ButtonPressed.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); if (button.TryGetKeyboard(out Keys key)) { if (key != Keys.None) @@ -542,6 +569,7 @@ namespace StardewModdingAPI.Framework else this.Events.Legacy_ControllerButtonPressed.Raise(new EventArgsControllerButtonPressed(PlayerIndex.One, controllerButton)); } +#endif } else if (status == InputStatus.Released) { @@ -549,9 +577,10 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Events: button {button} released.", LogLevel.Trace); this.Events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState)); - this.Events.Legacy_ButtonReleased.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); +#if !SMAPI_3_0_STRICT // legacy events + this.Events.Legacy_ButtonReleased.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons)); if (button.TryGetKeyboard(out Keys key)) { if (key != Keys.None) @@ -564,14 +593,17 @@ namespace StardewModdingAPI.Framework else this.Events.Legacy_ControllerButtonReleased.Raise(new EventArgsControllerButtonReleased(PlayerIndex.One, controllerButton)); } +#endif } } +#if !SMAPI_3_0_STRICT // raise legacy state-changed events if (inputState.RealKeyboard != previousInputState.RealKeyboard) this.Events.Legacy_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(previousInputState.RealKeyboard, inputState.RealKeyboard)); if (inputState.RealMouse != previousInputState.RealMouse) this.Events.Legacy_MouseChanged.Raise(new EventArgsMouseStateChanged(previousInputState.RealMouse, inputState.RealMouse, new Point((int)previousInputState.CursorPosition.ScreenPixels.X, (int)previousInputState.CursorPosition.ScreenPixels.Y), new Point((int)inputState.CursorPosition.ScreenPixels.X, (int)inputState.CursorPosition.ScreenPixels.Y))); +#endif } } @@ -589,10 +621,12 @@ namespace StardewModdingAPI.Framework // raise menu events this.Events.MenuChanged.Raise(new MenuChangedEventArgs(was, now)); +#if !SMAPI_3_0_STRICT if (now != null) this.Events.Legacy_MenuChanged.Raise(new EventArgsClickableMenuChanged(was, now)); else this.Events.Legacy_MenuClosed.Raise(new EventArgsClickableMenuClosed(was)); +#endif } /********* @@ -620,7 +654,9 @@ namespace StardewModdingAPI.Framework } this.Events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_LocationsChanged.Raise(new EventArgsLocationsChanged(added, removed)); +#endif } // raise location contents changed @@ -637,7 +673,9 @@ namespace StardewModdingAPI.Framework watcher.BuildingsWatcher.Reset(); this.Events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, added, removed)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_BuildingsChanged.Raise(new EventArgsLocationBuildingsChanged(location, added, removed)); +#endif } // debris changed @@ -682,7 +720,9 @@ namespace StardewModdingAPI.Framework watcher.ObjectsWatcher.Reset(); this.Events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, added, removed)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed)); +#endif } // terrain features changed @@ -712,7 +752,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Events: time changed from {was} to {now}.", LogLevel.Trace); this.Events.TimeChanged.Raise(new TimeChangedEventArgs(was, now)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_TimeOfDayChanged.Raise(new EventArgsIntChanged(was, now)); +#endif } else this.Watchers.TimeWatcher.Reset(); @@ -730,7 +772,9 @@ namespace StardewModdingAPI.Framework GameLocation oldLocation = playerTracker.LocationWatcher.PreviousValue; this.Events.Warped.Raise(new WarpedEventArgs(playerTracker.Player, oldLocation, newLocation)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_PlayerWarped.Raise(new EventArgsPlayerWarped(oldLocation, newLocation)); +#endif } // raise player leveled up a skill @@ -740,7 +784,9 @@ namespace StardewModdingAPI.Framework this.Monitor.Log($"Events: player skill '{pair.Key}' changed from {pair.Value.PreviousValue} to {pair.Value.CurrentValue}.", LogLevel.Trace); this.Events.LevelChanged.Raise(new LevelChangedEventArgs(playerTracker.Player, pair.Key, pair.Value.PreviousValue, pair.Value.CurrentValue)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_LeveledUp.Raise(new EventArgsLevelUp((EventArgsLevelUp.LevelType)pair.Key, pair.Value.CurrentValue)); +#endif } // raise player inventory changed @@ -750,7 +796,9 @@ namespace StardewModdingAPI.Framework if (this.Monitor.IsVerbose) this.Monitor.Log("Events: player inventory changed.", LogLevel.Trace); this.Events.InventoryChanged.Raise(new InventoryChangedEventArgs(playerTracker.Player, changedItems)); +#if !SMAPI_3_0_STRICT this.Events.Legacy_InventoryChanged.Raise(new EventArgsInventoryChanged(Game1.player.Items, changedItems)); +#endif } // raise mine level changed @@ -758,7 +806,9 @@ namespace StardewModdingAPI.Framework { if (this.Monitor.IsVerbose) this.Monitor.Log($"Context: mine level changed to {mineLevel}.", LogLevel.Trace); +#if !SMAPI_3_0_STRICT this.Events.Legacy_MineLevelChanged.Raise(new EventArgsMineLevelChanged(playerTracker.MineLevelWatcher.PreviousValue, mineLevel)); +#endif } } this.Watchers.CurrentPlayerTracker?.Reset(); @@ -790,6 +840,7 @@ namespace StardewModdingAPI.Framework /********* ** Update events *********/ +#if !SMAPI_3_0_STRICT this.Events.Legacy_UnvalidatedUpdateTick.Raise(); if (this.TicksElapsed == 1) this.Events.Legacy_FirstUpdateTick.Raise(); @@ -806,6 +857,7 @@ namespace StardewModdingAPI.Framework this.Events.Legacy_HalfSecondTick.Raise(); if (this.CurrentUpdateTick % 60 == 0) this.Events.Legacy_OneSecondTick.Raise(); +#endif this.CurrentUpdateTick += 1; if (this.CurrentUpdateTick >= 60) this.CurrentUpdateTick = 0; @@ -895,10 +947,14 @@ namespace StardewModdingAPI.Framework try { this.Events.RenderingActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderGuiEvent.Raise(); +#endif activeClickableMenu.draw(Game1.spriteBatch); this.Events.RenderedActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderGuiEvent.Raise(); +#endif } catch (Exception ex) { @@ -906,7 +962,9 @@ namespace StardewModdingAPI.Framework activeClickableMenu.exitThisMenu(); } this.Events.Rendered.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderEvent.Raise(); +#endif Game1.spriteBatch.End(); } @@ -930,10 +988,14 @@ namespace StardewModdingAPI.Framework { Game1.activeClickableMenu.drawBackground(Game1.spriteBatch); this.Events.RenderingActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderGuiEvent.Raise(); +#endif Game1.activeClickableMenu.draw(Game1.spriteBatch); this.Events.RenderedActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderGuiEvent.Raise(); +#endif } catch (Exception ex) { @@ -941,7 +1003,9 @@ namespace StardewModdingAPI.Framework Game1.activeClickableMenu.exitThisMenu(); } this.Events.Rendered.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderEvent.Raise(); +#endif Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); if ((double)Game1.options.zoomLevel != 1.0) @@ -966,7 +1030,9 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.content.LoadString("Strings\\StringsFromCSFiles:Game1.cs.3686"), new Vector2(16f, 32f), new Color(0, (int)byte.MaxValue, 0)); Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.parseText(Game1.errorMessage, Game1.dialogueFont, Game1.graphics.GraphicsDevice.Viewport.Width), new Vector2(16f, 48f), Color.White); this.Events.Rendered.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderEvent.Raise(); +#endif Game1.spriteBatch.End(); } else if (Game1.currentMinigame != null) @@ -979,7 +1045,9 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); +#if !SMAPI_3_0_STRICT this.RaisePostRender(needsNewBatch: true); +#endif if ((double)Game1.options.zoomLevel == 1.0) return; this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); @@ -997,10 +1065,14 @@ namespace StardewModdingAPI.Framework try { this.Events.RenderingActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderGuiEvent.Raise(); +#endif Game1.activeClickableMenu.draw(Game1.spriteBatch); this.Events.RenderedActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderGuiEvent.Raise(); +#endif } catch (Exception ex) { @@ -1090,7 +1162,9 @@ namespace StardewModdingAPI.Framework if (++batchOpens == 1) this.Events.Rendering.RaiseEmpty(); this.Events.RenderingWorld.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderEvent.Raise(); +#endif if (Game1.background != null) Game1.background.draw(Game1.spriteBatch); Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch); @@ -1403,10 +1477,14 @@ namespace StardewModdingAPI.Framework if ((Game1.displayHUD || Game1.eventUp) && (Game1.currentBillboard == 0 && Game1.gameMode == (byte)3) && (!Game1.freezeControls && !Game1.panMode && !Game1.HostPaused)) { this.Events.RenderingHud.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderHudEvent.Raise(); +#endif this.drawHUD(); this.Events.RenderedHud.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderHudEvent.Raise(); +#endif } else if (Game1.activeClickableMenu == null && Game1.farmEvent == null) Game1.spriteBatch.Draw(Game1.mouseCursors, new Vector2((float)Game1.getOldMouseX(), (float)Game1.getOldMouseY()), new Microsoft.Xna.Framework.Rectangle?(Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, 0, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)(4.0 + (double)Game1.dialogueButtonScale / 150.0), SpriteEffects.None, 1f); @@ -1515,10 +1593,14 @@ namespace StardewModdingAPI.Framework try { this.Events.RenderingActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPreRenderGuiEvent.Raise(); +#endif Game1.activeClickableMenu.draw(Game1.spriteBatch); this.Events.RenderedActiveMenu.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderGuiEvent.Raise(); +#endif } catch (Exception ex) { @@ -1535,7 +1617,9 @@ namespace StardewModdingAPI.Framework } this.Events.Rendered.RaiseEmpty(); +#if !SMAPI_3_0_STRICT this.Events.Legacy_OnPostRenderEvent.Raise(); +#endif Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); this.renderScreenBuffer(); @@ -1555,6 +1639,7 @@ namespace StardewModdingAPI.Framework this.RaisedAfterLoadEvent = false; } +#if !SMAPI_3_0_STRICT /// Raise the if there are any listeners. /// Whether to create a new sprite batch. private void RaisePostRender(bool needsNewBatch = false) @@ -1568,5 +1653,6 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.End(); } } +#endif } } diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs index 629fce1d..12cd2d46 100644 --- a/src/SMAPI/Framework/SMultiplayer.cs +++ b/src/SMAPI/Framework/SMultiplayer.cs @@ -82,6 +82,7 @@ namespace StardewModdingAPI.Framework this.OnModMessageReceived = onModMessageReceived; } +#if !SMAPI_3_0_STRICT /// Handle sync messages from other players and perform other initial sync logic. public override void UpdateEarly() { @@ -97,6 +98,7 @@ namespace StardewModdingAPI.Framework base.UpdateLate(forceSync); this.EventManager.Legacy_AfterMainBroadcast.Raise(); } +#endif /// Initialise a client before the game connects to a remote server. /// The client to initialise. diff --git a/src/SMAPI/IModHelper.cs b/src/SMAPI/IModHelper.cs index 7e82e0d0..678339dc 100644 --- a/src/SMAPI/IModHelper.cs +++ b/src/SMAPI/IModHelper.cs @@ -56,6 +56,7 @@ namespace StardewModdingAPI /// The config settings to save. void WriteConfig(TConfig config) where TConfig : class, new(); +#if !SMAPI_3_0_STRICT /**** ** Generic JSON files ****/ @@ -88,5 +89,6 @@ namespace StardewModdingAPI /// Get all content packs loaded for this mod. IEnumerable GetContentPacks(); +#endif } } 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 diff --git a/src/SMAPI/SemanticVersion.cs b/src/SMAPI/SemanticVersion.cs index 401f62c2..f75105df 100644 --- a/src/SMAPI/SemanticVersion.cs +++ b/src/SMAPI/SemanticVersion.cs @@ -29,6 +29,7 @@ namespace StardewModdingAPI /// The patch version for backwards-compatible bug fixes. public int PatchVersion => this.Version.PatchVersion; +#if !SMAPI_3_0_STRICT /// An optional build tag. [Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")] public string Build @@ -39,6 +40,7 @@ namespace StardewModdingAPI return this.Version.PrereleaseTag; } } +#endif /// An optional prerelease tag. public string PrereleaseTag => this.Version.PrereleaseTag; diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 5a098b8a..3696b54d 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -32,7 +32,7 @@ x86 false - DEBUG;TRACE + DEBUG;TRACE;SMAPI_3_0_STRICT true false $(SolutionDir)\..\bin\Debug\SMAPI diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/ISemanticVersion.cs b/src/StardewModdingAPI.Toolkit.CoreInterfaces/ISemanticVersion.cs index 6631b01d..0a6e5758 100644 --- a/src/StardewModdingAPI.Toolkit.CoreInterfaces/ISemanticVersion.cs +++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/ISemanticVersion.cs @@ -17,9 +17,11 @@ namespace StardewModdingAPI /// The patch version for backwards-compatible bug fixes. int PatchVersion { get; } +#if !SMAPI_3_0_STRICT /// An optional build tag. [Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")] string Build { get; } +#endif /// An optional prerelease tag. string PrereleaseTag { get; } diff --git a/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj b/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj index 525931e5..539cb5d8 100644 --- a/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj +++ b/src/StardewModdingAPI.Toolkit.CoreInterfaces/StardewModdingAPI.Toolkit.CoreInterfaces.csproj @@ -8,6 +8,10 @@ ..\..\bin\$(Configuration)\SMAPI.Toolkit.CoreInterfaces\$(TargetFramework)\StardewModdingAPI.Toolkit.CoreInterfaces.xml + + $(DefineConstants);SMAPI_3_0_STRICT + + diff --git a/src/StardewModdingAPI.Toolkit/SemanticVersion.cs b/src/StardewModdingAPI.Toolkit/SemanticVersion.cs index a7990d13..2d0bc033 100644 --- a/src/StardewModdingAPI.Toolkit/SemanticVersion.cs +++ b/src/StardewModdingAPI.Toolkit/SemanticVersion.cs @@ -39,9 +39,11 @@ namespace StardewModdingAPI.Toolkit /// The patch version for backwards-compatible bug fixes. public int PatchVersion { get; } +#if !SMAPI_3_0_STRICT /// An optional prerelease tag. [Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")] public string Build => this.PrereleaseTag; +#endif /// An optional prerelease tag. public string PrereleaseTag { get; } @@ -114,7 +116,7 @@ namespace StardewModdingAPI.Toolkit { if (other == null) throw new ArgumentNullException(nameof(other)); - return this.CompareTo(other.MajorVersion, other.MinorVersion, other.PatchVersion, other.Build); + return this.CompareTo(other.MajorVersion, other.MinorVersion, other.PatchVersion, other.PrereleaseTag); } /// Indicates whether the current object is equal to another object of the same type. @@ -128,7 +130,7 @@ namespace StardewModdingAPI.Toolkit /// Whether this is a pre-release version. public bool IsPrerelease() { - return !string.IsNullOrWhiteSpace(this.Build); + return !string.IsNullOrWhiteSpace(this.PrereleaseTag); } /// Get whether this version is older than the specified version. @@ -187,7 +189,7 @@ namespace StardewModdingAPI.Toolkit : $"{this.MajorVersion}.{this.MinorVersion}"; // tag - string tag = this.Build; + string tag = this.PrereleaseTag; if (tag != null) result += $"-{tag}"; return result; @@ -241,11 +243,11 @@ namespace StardewModdingAPI.Toolkit return this.MinorVersion.CompareTo(otherMinor); if (this.PatchVersion != otherPatch) return this.PatchVersion.CompareTo(otherPatch); - if (this.Build == otherTag) + if (this.PrereleaseTag == otherTag) return same; // stable supercedes pre-release - bool curIsStable = string.IsNullOrWhiteSpace(this.Build); + bool curIsStable = string.IsNullOrWhiteSpace(this.PrereleaseTag); bool otherIsStable = string.IsNullOrWhiteSpace(otherTag); if (curIsStable) return curNewer; @@ -253,7 +255,7 @@ namespace StardewModdingAPI.Toolkit return curOlder; // compare two pre-release tag values - string[] curParts = this.Build.Split('.', '-'); + string[] curParts = this.PrereleaseTag.Split('.', '-'); string[] otherParts = otherTag.Split('.', '-'); for (int i = 0; i < curParts.Length; i++) { @@ -292,11 +294,11 @@ namespace StardewModdingAPI.Toolkit throw new FormatException($"{this} isn't a valid semantic version. The major, minor, and patch numbers can't be negative."); if (this.MajorVersion == 0 && this.MinorVersion == 0 && this.PatchVersion == 0) throw new FormatException($"{this} isn't a valid semantic version. At least one of the major, minor, and patch numbers must be more than zero."); - if (this.Build != null) + if (this.PrereleaseTag != null) { - if (this.Build.Trim() == "") + if (this.PrereleaseTag.Trim() == "") throw new FormatException($"{this} isn't a valid semantic version. The tag cannot be a blank string (but may be omitted)."); - if (!Regex.IsMatch(this.Build, $"^{SemanticVersion.TagPattern}$", RegexOptions.IgnoreCase)) + if (!Regex.IsMatch(this.PrereleaseTag, $"^{SemanticVersion.TagPattern}$", RegexOptions.IgnoreCase)) throw new FormatException($"{this} isn't a valid semantic version. The tag is invalid."); } } diff --git a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj index 3fa28d19..29667b1e 100644 --- a/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj +++ b/src/StardewModdingAPI.Toolkit/StardewModdingAPI.Toolkit.csproj @@ -7,6 +7,10 @@ ..\..\bin\$(Configuration)\SMAPI.Toolkit\$(TargetFramework)\StardewModdingAPI.Toolkit.xml + + $(DefineConstants);SMAPI_3_0_STRICT + +