remove deprecated APIs (#606)

This commit is contained in:
Jesse Plamondon-Willard 2019-02-24 19:56:08 -05:00
parent 5dddb0cf1f
commit 87afd4fbf8
No known key found for this signature in database
GPG Key ID: 7D7C8097B62033CE
53 changed files with 65 additions and 2681 deletions

View File

@ -8,6 +8,7 @@ These changes have not been released yet.
* For modders: * For modders:
* Added `IContentPack.HasFile` method. * Added `IContentPack.HasFile` method.
* Dropped support for all deprecated APIs.
* Updated to Json.NET 12.0.1. * Updated to Json.NET 12.0.1.
## 2.11.1 ## 2.11.1

View File

@ -106,7 +106,6 @@ SMAPI uses a small number of conditional compilation constants, which you can se
flag | purpose flag | purpose
---- | ------- ---- | -------
`SMAPI_FOR_WINDOWS` | Whether 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 # SMAPI web services
## Overview ## Overview

View File

@ -44,32 +44,10 @@ namespace StardewModdingAPI
public static string SavesPath { get; } = Path.Combine(Constants.DataPath, "Saves"); public static string SavesPath { get; } = Path.Combine(Constants.DataPath, "Saves");
/// <summary>The name of the current save folder (if save info is available, regardless of whether the save file exists yet).</summary> /// <summary>The name of the current save folder (if save info is available, regardless of whether the save file exists yet).</summary>
public static string SaveFolderName public static string SaveFolderName => Constants.GetSaveFolderName();
{
get
{
return Constants.GetSaveFolderName()
#if SMAPI_3_0_STRICT
;
#else
?? "";
#endif
}
}
/// <summary>The absolute path to the current save folder (if save info is available and the save file exists).</summary> /// <summary>The absolute path to the current save folder (if save info is available and the save file exists).</summary>
public static string CurrentSavePath public static string CurrentSavePath => Constants.GetSaveFolderPathIfExists();
{
get
{
return Constants.GetSaveFolderPathIfExists()
#if SMAPI_3_0_STRICT
;
#else
?? "";
#endif
}
}
/**** /****
** Internal ** Internal

View File

@ -1,45 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the game loads content.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class ContentEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the content language changes.</summary>
public static event EventHandler<EventArgsValueChanged<string>> AfterLocaleChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ContentEvents.EventManager.Legacy_LocaleChanged.Add(value);
}
remove => ContentEvents.EventManager.Legacy_LocaleChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
ContentEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,123 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player uses a controller, keyboard, or mouse.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class ControlEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the <see cref="KeyboardState"/> changes. That happens when the player presses or releases a key.</summary>
public static event EventHandler<EventArgsKeyboardStateChanged> KeyboardChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyboardChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyboardChanged.Remove(value);
}
/// <summary>Raised after the player presses a keyboard key.</summary>
public static event EventHandler<EventArgsKeyPressed> KeyPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyPressed.Remove(value);
}
/// <summary>Raised after the player releases a keyboard key.</summary>
public static event EventHandler<EventArgsKeyPressed> KeyReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyReleased.Remove(value);
}
/// <summary>Raised when the <see cref="MouseState"/> changes. That happens when the player moves the mouse, scrolls the mouse wheel, or presses/releases a button.</summary>
public static event EventHandler<EventArgsMouseStateChanged> MouseChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_MouseChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_MouseChanged.Remove(value);
}
/// <summary>The player pressed a controller button. This event isn't raised for trigger buttons.</summary>
public static event EventHandler<EventArgsControllerButtonPressed> ControllerButtonPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonPressed.Remove(value);
}
/// <summary>The player released a controller button. This event isn't raised for trigger buttons.</summary>
public static event EventHandler<EventArgsControllerButtonReleased> ControllerButtonReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonReleased.Remove(value);
}
/// <summary>The player pressed a controller trigger button.</summary>
public static event EventHandler<EventArgsControllerTriggerPressed> ControllerTriggerPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Remove(value);
}
/// <summary>The player released a controller trigger button.</summary>
public static event EventHandler<EventArgsControllerTriggerReleased> ControllerTriggerReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
ControlEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,33 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MenuEvents.MenuChanged"/> event.</summary>
public class EventArgsClickableMenuChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous menu.</summary>
public IClickableMenu NewMenu { get; }
/// <summary>The current menu.</summary>
public IClickableMenu PriorMenu { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorMenu">The previous menu.</param>
/// <param name="newMenu">The current menu.</param>
public EventArgsClickableMenuChanged(IClickableMenu priorMenu, IClickableMenu newMenu)
{
this.NewMenu = newMenu;
this.PriorMenu = priorMenu;
}
}
}
#endif

View File

@ -1,28 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MenuEvents.MenuClosed"/> event.</summary>
public class EventArgsClickableMenuClosed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The menu that was closed.</summary>
public IClickableMenu PriorMenu { get; }
/*********
** Accessors
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorMenu">The menu that was closed.</param>
public EventArgsClickableMenuClosed(IClickableMenu priorMenu)
{
this.PriorMenu = priorMenu;
}
}
}
#endif

View File

@ -1,34 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerButtonPressed"/> event.</summary>
public class EventArgsControllerButtonPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonPressed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the button.</param>
/// <param name="button">The controller button that was pressed.</param>
public EventArgsControllerButtonPressed(PlayerIndex playerIndex, Buttons button)
{
this.PlayerIndex = playerIndex;
this.ButtonPressed = button;
}
}
}
#endif

View File

@ -1,34 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerButtonReleased"/> event.</summary>
public class EventArgsControllerButtonReleased : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonReleased { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the button.</param>
/// <param name="button">The controller button that was released.</param>
public EventArgsControllerButtonReleased(PlayerIndex playerIndex, Buttons button)
{
this.PlayerIndex = playerIndex;
this.ButtonReleased = button;
}
}
}
#endif

View File

@ -1,39 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerTriggerPressed"/> event.</summary>
public class EventArgsControllerTriggerPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonPressed { get; }
/// <summary>The current trigger value.</summary>
public float Value { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the trigger button.</param>
/// <param name="button">The trigger button that was pressed.</param>
/// <param name="value">The current trigger value.</param>
public EventArgsControllerTriggerPressed(PlayerIndex playerIndex, Buttons button, float value)
{
this.PlayerIndex = playerIndex;
this.ButtonPressed = button;
this.Value = value;
}
}
}
#endif

View File

@ -1,39 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerTriggerReleased"/> event.</summary>
public class EventArgsControllerTriggerReleased : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was released.</summary>
public Buttons ButtonReleased { get; }
/// <summary>The current trigger value.</summary>
public float Value { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the trigger button.</param>
/// <param name="button">The trigger button that was released.</param>
/// <param name="value">The current trigger value.</param>
public EventArgsControllerTriggerReleased(PlayerIndex playerIndex, Buttons button, float value)
{
this.PlayerIndex = playerIndex;
this.ButtonReleased = button;
this.Value = value;
}
}
}
#endif

View File

@ -1,64 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when a button is pressed or released.</summary>
public class EventArgsInput : EventArgs
{
/*********
** Fields
*********/
/// <summary>The buttons to suppress.</summary>
private readonly HashSet<SButton> SuppressButtons;
/*********
** Accessors
*********/
/// <summary>The button on the controller, keyboard, or mouse.</summary>
public SButton Button { get; }
/// <summary>The current cursor position.</summary>
public ICursorPosition Cursor { get; }
/// <summary>Whether the input should trigger actions on the affected tile.</summary>
public bool IsActionButton => this.Button.IsActionButton();
/// <summary>Whether the input should use tools on the affected tile.</summary>
public bool IsUseToolButton => this.Button.IsUseToolButton();
/// <summary>Whether a mod has indicated the key was already handled.</summary>
public bool IsSuppressed => this.SuppressButtons.Contains(this.Button);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="button">The button on the controller, keyboard, or mouse.</param>
/// <param name="cursor">The cursor position.</param>
/// <param name="suppressButtons">The buttons to suppress.</param>
public EventArgsInput(SButton button, ICursorPosition cursor, HashSet<SButton> suppressButtons)
{
this.Button = button;
this.Cursor = cursor;
this.SuppressButtons = suppressButtons;
}
/// <summary>Prevent the game from handling the current button press. This doesn't prevent other mods from receiving the event.</summary>
public void SuppressButton()
{
this.SuppressButton(this.Button);
}
/// <summary>Prevent the game from handling a button press. This doesn't prevent other mods from receiving the event.</summary>
/// <param name="button">The button to suppress.</param>
public void SuppressButton(SButton button)
{
this.SuppressButtons.Add(button);
}
}
}
#endif

View File

@ -1,32 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an integer field that changed value.</summary>
public class EventArgsIntChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous value.</summary>
public int PriorInt { get; }
/// <summary>The current value.</summary>
public int NewInt { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorInt">The previous value.</param>
/// <param name="newInt">The current value.</param>
public EventArgsIntChanged(int priorInt, int newInt)
{
this.PriorInt = priorInt;
this.NewInt = newInt;
}
}
}
#endif

View File

@ -1,43 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.InventoryChanged"/> event.</summary>
public class EventArgsInventoryChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player's inventory.</summary>
public IList<Item> Inventory { get; }
/// <summary>The added items.</summary>
public List<ItemStackChange> Added { get; }
/// <summary>The removed items.</summary>
public List<ItemStackChange> Removed { get; }
/// <summary>The items whose stack sizes changed.</summary>
public List<ItemStackChange> QuantityChanged { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="inventory">The player's inventory.</param>
/// <param name="changedItems">The inventory changes.</param>
public EventArgsInventoryChanged(IList<Item> inventory, ItemStackChange[] changedItems)
{
this.Inventory = inventory;
this.Added = changedItems.Where(n => n.ChangeType == ChangeType.Added).ToList();
this.Removed = changedItems.Where(n => n.ChangeType == ChangeType.Removed).ToList();
this.QuantityChanged = changedItems.Where(n => n.ChangeType == ChangeType.StackChange).ToList();
}
}
}
#endif

View File

@ -1,28 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.KeyboardChanged"/> event.</summary>
public class EventArgsKeyPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The keyboard button that was pressed.</summary>
public Keys KeyPressed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="key">The keyboard button that was pressed.</param>
public EventArgsKeyPressed(Keys key)
{
this.KeyPressed = key;
}
}
}
#endif

View File

@ -1,33 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.KeyboardChanged"/> event.</summary>
public class EventArgsKeyboardStateChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous keyboard state.</summary>
public KeyboardState NewState { get; }
/// <summary>The current keyboard state.</summary>
public KeyboardState PriorState { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorState">The previous keyboard state.</param>
/// <param name="newState">The current keyboard state.</param>
public EventArgsKeyboardStateChanged(KeyboardState priorState, KeyboardState newState)
{
this.PriorState = priorState;
this.NewState = newState;
}
}
}
#endif

View File

@ -1,55 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Enums;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.LeveledUp"/> event.</summary>
public class EventArgsLevelUp : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player skill that leveled up.</summary>
public LevelType Type { get; }
/// <summary>The new skill level.</summary>
public int NewLevel { get; }
/// <summary>The player skill types.</summary>
public enum LevelType
{
/// <summary>The combat skill.</summary>
Combat = SkillType.Combat,
/// <summary>The farming skill.</summary>
Farming = SkillType.Farming,
/// <summary>The fishing skill.</summary>
Fishing = SkillType.Fishing,
/// <summary>The foraging skill.</summary>
Foraging = SkillType.Foraging,
/// <summary>The mining skill.</summary>
Mining = SkillType.Mining,
/// <summary>The luck skill.</summary>
Luck = SkillType.Luck
}
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="type">The player skill that leveled up.</param>
/// <param name="newLevel">The new skill level.</param>
public EventArgsLevelUp(LevelType type, int newLevel)
{
this.Type = type;
this.NewLevel = newLevel;
}
}
}
#endif

View File

@ -1,41 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
using StardewValley.Buildings;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.BuildingsChanged"/> event.</summary>
public class EventArgsLocationBuildingsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The buildings added to the location.</summary>
public IEnumerable<Building> Added { get; }
/// <summary>The buildings removed from the location.</summary>
public IEnumerable<Building> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The buildings added to the location.</param>
/// <param name="removed">The buildings removed from the location.</param>
public EventArgsLocationBuildingsChanged(GameLocation location, IEnumerable<Building> added, IEnumerable<Building> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -1,42 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using StardewValley;
using SObject = StardewValley.Object;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.ObjectsChanged"/> event.</summary>
public class EventArgsLocationObjectsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The objects added to the location.</summary>
public IEnumerable<KeyValuePair<Vector2, SObject>> Added { get; }
/// <summary>The objects removed from the location.</summary>
public IEnumerable<KeyValuePair<Vector2, SObject>> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The objects added to the location.</param>
/// <param name="removed">The objects removed from the location.</param>
public EventArgsLocationObjectsChanged(GameLocation location, IEnumerable<KeyValuePair<Vector2, SObject>> added, IEnumerable<KeyValuePair<Vector2, SObject>> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -1,35 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.LocationsChanged"/> event.</summary>
public class EventArgsLocationsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The added locations.</summary>
public IEnumerable<GameLocation> Added { get; }
/// <summary>The removed locations.</summary>
public IEnumerable<GameLocation> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="added">The added locations.</param>
/// <param name="removed">The removed locations.</param>
public EventArgsLocationsChanged(IEnumerable<GameLocation> added, IEnumerable<GameLocation> removed)
{
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -1,32 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MineEvents.MineLevelChanged"/> event.</summary>
public class EventArgsMineLevelChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous mine level.</summary>
public int PreviousMineLevel { get; }
/// <summary>The current mine level.</summary>
public int CurrentMineLevel { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="previousMineLevel">The previous mine level.</param>
/// <param name="currentMineLevel">The current mine level.</param>
public EventArgsMineLevelChanged(int previousMineLevel, int currentMineLevel)
{
this.PreviousMineLevel = previousMineLevel;
this.CurrentMineLevel = currentMineLevel;
}
}
}
#endif

View File

@ -1,44 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.MouseChanged"/> event.</summary>
public class EventArgsMouseStateChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous mouse state.</summary>
public MouseState PriorState { get; }
/// <summary>The current mouse state.</summary>
public MouseState NewState { get; }
/// <summary>The previous mouse position on the screen adjusted for the zoom level.</summary>
public Point PriorPosition { get; }
/// <summary>The current mouse position on the screen adjusted for the zoom level.</summary>
public Point NewPosition { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorState">The previous mouse state.</param>
/// <param name="newState">The current mouse state.</param>
/// <param name="priorPosition">The previous mouse position on the screen adjusted for the zoom level.</param>
/// <param name="newPosition">The current mouse position on the screen adjusted for the zoom level.</param>
public EventArgsMouseStateChanged(MouseState priorState, MouseState newState, Point priorPosition, Point newPosition)
{
this.PriorState = priorState;
this.NewState = newState;
this.PriorPosition = priorPosition;
this.NewPosition = newPosition;
}
}
}
#endif

View File

@ -1,34 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.Warped"/> event.</summary>
public class EventArgsPlayerWarped : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player's previous location.</summary>
public GameLocation PriorLocation { get; }
/// <summary>The player's current location.</summary>
public GameLocation NewLocation { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorLocation">The player's previous location.</param>
/// <param name="newLocation">The player's current location.</param>
public EventArgsPlayerWarped(GameLocation priorLocation, GameLocation newLocation)
{
this.NewLocation = newLocation;
this.PriorLocation = priorLocation;
}
}
}
#endif

View File

@ -1,33 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a field that changed value.</summary>
/// <typeparam name="T">The value type.</typeparam>
public class EventArgsValueChanged<T> : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous value.</summary>
public T PriorValue { get; }
/// <summary>The current value.</summary>
public T NewValue { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorValue">The previous value.</param>
/// <param name="newValue">The current value.</param>
public EventArgsValueChanged(T priorValue, T newValue)
{
this.PriorValue = priorValue;
this.NewValue = newValue;
}
}
}
#endif

View File

@ -1,122 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the game changes state.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class GameEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the game updates its state (≈60 times per second).</summary>
public static event EventHandler UpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_UpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_UpdateTick.Remove(value);
}
/// <summary>Raised every other tick (≈30 times per second).</summary>
public static event EventHandler SecondUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_SecondUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_SecondUpdateTick.Remove(value);
}
/// <summary>Raised every fourth tick (≈15 times per second).</summary>
public static event EventHandler FourthUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FourthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FourthUpdateTick.Remove(value);
}
/// <summary>Raised every eighth tick (≈8 times per second).</summary>
public static event EventHandler EighthUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_EighthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_EighthUpdateTick.Remove(value);
}
/// <summary>Raised every 15th tick (≈4 times per second).</summary>
public static event EventHandler QuarterSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_QuarterSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_QuarterSecondTick.Remove(value);
}
/// <summary>Raised every 30th tick (≈twice per second).</summary>
public static event EventHandler HalfSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_HalfSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_HalfSecondTick.Remove(value);
}
/// <summary>Raised every 60th tick (≈once per second).</summary>
public static event EventHandler OneSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_OneSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_OneSecondTick.Remove(value);
}
/// <summary>Raised once after the game initialises and all <see cref="IMod.Entry"/> methods have been called.</summary>
public static event EventHandler FirstUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FirstUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FirstUpdateTick.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
GameEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,120 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised during the game's draw loop, when the game is rendering content to the window.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class GraphicsEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the game window is resized.</summary>
public static event EventHandler Resize
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_Resize.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_Resize.Remove(value);
}
/****
** Main render events
****/
/// <summary>Raised before drawing the world to the screen.</summary>
public static event EventHandler OnPreRenderEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Remove(value);
}
/// <summary>Raised after drawing the world to the screen.</summary>
public static event EventHandler OnPostRenderEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Remove(value);
}
/****
** HUD events
****/
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public static event EventHandler OnPreRenderHudEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Remove(value);
}
/// <summary>Raised after drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public static event EventHandler OnPostRenderHudEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Remove(value);
}
/****
** GUI events
****/
/// <summary>Raised before drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public static event EventHandler OnPreRenderGuiEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Remove(value);
}
/// <summary>Raised after drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public static event EventHandler OnPostRenderGuiEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
GraphicsEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,56 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player uses a controller, keyboard, or mouse button.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class InputEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the player presses a button on the keyboard, controller, or mouse.</summary>
public static event EventHandler<EventArgsInput> ButtonPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonPressed.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonPressed.Remove(value);
}
/// <summary>Raised when the player releases a keyboard key on the keyboard, controller, or mouse.</summary>
public static event EventHandler<EventArgsInput> ButtonReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonReleased.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonReleased.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
InputEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,67 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player transitions between game locations, a location is added or removed, or the objects in the current location change.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class LocationEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after a game location is added or removed.</summary>
public static event EventHandler<EventArgsLocationsChanged> LocationsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_LocationsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_LocationsChanged.Remove(value);
}
/// <summary>Raised after buildings are added or removed in a location.</summary>
public static event EventHandler<EventArgsLocationBuildingsChanged> BuildingsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_BuildingsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_BuildingsChanged.Remove(value);
}
/// <summary>Raised after objects are added or removed in a location.</summary>
public static event EventHandler<EventArgsLocationObjectsChanged> ObjectsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_ObjectsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_ObjectsChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
LocationEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,56 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when a game menu is opened or closed (including internal menus like the title screen).</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MenuEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after a game menu is opened or replaced with another menu. This event is not invoked when a menu is closed.</summary>
public static event EventHandler<EventArgsClickableMenuChanged> MenuChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuChanged.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuChanged.Remove(value);
}
/// <summary>Raised after a game menu is closed.</summary>
public static event EventHandler<EventArgsClickableMenuClosed> MenuClosed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuClosed.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuClosed.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MenuEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,45 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when something happens in the mines.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MineEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the player warps to a new level of the mine.</summary>
public static event EventHandler<EventArgsMineLevelChanged> MineLevelChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MineEvents.EventManager.Legacy_MineLevelChanged.Add(value);
}
remove => MineEvents.EventManager.Legacy_MineLevelChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MineEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,78 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised during the multiplayer sync process.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MultiplayerEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised before the game syncs changes from other players.</summary>
public static event EventHandler BeforeMainSync
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Remove(value);
}
/// <summary>Raised after the game syncs changes from other players.</summary>
public static event EventHandler AfterMainSync
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainSync.Remove(value);
}
/// <summary>Raised before the game broadcasts changes to other players.</summary>
public static event EventHandler BeforeMainBroadcast
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Remove(value);
}
/// <summary>Raised after the game broadcasts changes to other players.</summary>
public static event EventHandler AfterMainBroadcast
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MultiplayerEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,68 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player data changes.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class PlayerEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the player's inventory changes in any way (added or removed item, sorted, etc).</summary>
public static event EventHandler<EventArgsInventoryChanged> InventoryChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_InventoryChanged.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_InventoryChanged.Remove(value);
}
/// <summary>Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
public static event EventHandler<EventArgsLevelUp> LeveledUp
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_LeveledUp.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_LeveledUp.Remove(value);
}
/// <summary>Raised after the player warps to a new location.</summary>
public static event EventHandler<EventArgsPlayerWarped> Warped
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_PlayerWarped.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_PlayerWarped.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
PlayerEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,100 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised before and after the player saves/loads the game.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class SaveEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised before the game creates the save file.</summary>
public static event EventHandler BeforeCreate
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeCreateSave.Remove(value);
}
/// <summary>Raised after the game finishes creating the save file.</summary>
public static event EventHandler AfterCreate
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterCreateSave.Remove(value);
}
/// <summary>Raised before the game begins writes data to the save file.</summary>
public static event EventHandler BeforeSave
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeSave.Remove(value);
}
/// <summary>Raised after the game finishes writing data to the save file.</summary>
public static event EventHandler AfterSave
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterSave.Remove(value);
}
/// <summary>Raised after the player loads a save slot.</summary>
public static event EventHandler AfterLoad
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterLoad.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterLoad.Remove(value);
}
/// <summary>Raised after the game returns to the title screen.</summary>
public static event EventHandler AfterReturnToTitle
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterReturnToTitle.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterReturnToTitle.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
SaveEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,45 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class SpecialisedEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the game updates its state (≈60 times per second), regardless of normal SMAPI validation. This event is not thread-safe and may be invoked while game logic is running asynchronously. Changes to game state in this method may crash the game or corrupt an in-progress save. Do not use this event unless you're fully aware of the context in which your code will be run. Mods using this method will trigger a stability warning in the SMAPI console.</summary>
public static event EventHandler UnvalidatedUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Add(value);
}
remove => SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
SpecialisedEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,56 +0,0 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the in-game date or time changes.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class TimeEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the game begins a new day, including when loading a save.</summary>
public static event EventHandler AfterDayStarted
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_AfterDayStarted.Add(value);
}
remove => TimeEvents.EventManager.Legacy_AfterDayStarted.Remove(value);
}
/// <summary>Raised after the in-game clock changes.</summary>
public static event EventHandler<EventArgsIntChanged> TimeOfDayChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_TimeOfDayChanged.Add(value);
}
remove => TimeEvents.EventManager.Legacy_TimeOfDayChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
TimeEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace StardewModdingAPI.Framework.Content namespace StardewModdingAPI.Framework.Content
{ {
@ -18,37 +17,5 @@ namespace StardewModdingAPI.Framework.Content
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param> /// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
public AssetDataForDictionary(string locale, string assetName, IDictionary<TKey, TValue> data, Func<string, string> getNormalisedPath, Action<IDictionary<TKey, TValue>> onDataReplaced) public AssetDataForDictionary(string locale, string assetName, IDictionary<TKey, TValue> data, Func<string, string> getNormalisedPath, Action<IDictionary<TKey, TValue>> onDataReplaced)
: base(locale, assetName, data, getNormalisedPath, onDataReplaced) { } : base(locale, assetName, data, getNormalisedPath, onDataReplaced) { }
#if !SMAPI_3_0_STRICT
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">The entry value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
public void Set(TKey key, TValue value)
{
SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval);
this.Data[key] = value;
}
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">A callback which accepts the current value and returns the new value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
public void Set(TKey key, Func<TValue, TValue> value)
{
SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval);
this.Data[key] = value(this.Data[key]);
}
/// <summary>Dynamically replace values in the dictionary.</summary>
/// <param name="replacer">A lambda which takes the current key and value for an entry, and returns the new value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
public void Set(Func<TKey, TValue, TValue> replacer)
{
SCore.DeprecationManager.Warn($"AssetDataForDictionary.{nameof(Set)}", "2.10", DeprecationLevel.PendingRemoval);
foreach (var pair in this.Data.ToArray())
this.Data[pair.Key] = replacer(pair.Key, pair.Value);
}
#endif
} }
} }

View File

@ -14,11 +14,7 @@ namespace StardewModdingAPI.Framework
private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
/// <summary>Encapsulates monitoring and logging for a given module.</summary> /// <summary>Encapsulates monitoring and logging for a given module.</summary>
#if !SMAPI_3_0_STRICT
private readonly Monitor Monitor;
#else
private readonly IMonitor Monitor; private readonly IMonitor Monitor;
#endif
/// <summary>Tracks the installed mods.</summary> /// <summary>Tracks the installed mods.</summary>
private readonly ModRegistry ModRegistry; private readonly ModRegistry ModRegistry;
@ -26,11 +22,6 @@ namespace StardewModdingAPI.Framework
/// <summary>The queued deprecation warnings to display.</summary> /// <summary>The queued deprecation warnings to display.</summary>
private readonly IList<DeprecationWarning> QueuedWarnings = new List<DeprecationWarning>(); private readonly IList<DeprecationWarning> QueuedWarnings = new List<DeprecationWarning>();
#if !SMAPI_3_0_STRICT
/// <summary>Whether the one-time deprecation message has been shown.</summary>
private bool DeprecationHeaderShown = false;
#endif
/********* /*********
** Public methods ** Public methods
@ -38,11 +29,7 @@ namespace StardewModdingAPI.Framework
/// <summary>Construct an instance.</summary> /// <summary>Construct an instance.</summary>
/// <param name="monitor">Encapsulates monitoring and logging for a given module.</param> /// <param name="monitor">Encapsulates monitoring and logging for a given module.</param>
/// <param name="modRegistry">Tracks the installed mods.</param> /// <param name="modRegistry">Tracks the installed mods.</param>
#if !SMAPI_3_0_STRICT
public DeprecationManager(Monitor monitor, ModRegistry modRegistry)
#else
public DeprecationManager(IMonitor monitor, ModRegistry modRegistry) public DeprecationManager(IMonitor monitor, ModRegistry modRegistry)
#endif
{ {
this.Monitor = monitor; this.Monitor = monitor;
this.ModRegistry = modRegistry; this.ModRegistry = modRegistry;
@ -81,26 +68,10 @@ namespace StardewModdingAPI.Framework
/// <summary>Print any queued messages.</summary> /// <summary>Print any queued messages.</summary>
public void PrintQueued() public void PrintQueued()
{ {
#if !SMAPI_3_0_STRICT
if (!this.DeprecationHeaderShown && this.QueuedWarnings.Any())
{
this.Monitor.Newline();
this.Monitor.Log("Some of your mods will break in the upcoming SMAPI 3.0. Please update your mods now, or notify the author if no update is available. See https://mods.smapi.io for links to the latest versions.", LogLevel.Warn);
this.Monitor.Newline();
this.DeprecationHeaderShown = true;
}
#endif
foreach (DeprecationWarning warning in this.QueuedWarnings.OrderBy(p => p.ModName).ThenBy(p => p.NounPhrase)) foreach (DeprecationWarning warning in this.QueuedWarnings.OrderBy(p => p.ModName).ThenBy(p => p.NounPhrase))
{ {
// build message // build message
#if SMAPI_3_0_STRICT
string message = $"{warning.ModName} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version})."; string message = $"{warning.ModName} uses deprecated code ({warning.NounPhrase} is deprecated since SMAPI {warning.Version}).";
#else
string message = warning.NounPhrase == "legacy events"
? $"{warning.ModName ?? "An unknown mod"} will break in the upcoming SMAPI 3.0 (legacy events are deprecated since SMAPI {warning.Version})."
: $"{warning.ModName ?? "An unknown mod"} will break in the upcoming SMAPI 3.0 ({warning.NounPhrase} is deprecated since SMAPI {warning.Version}).";
#endif
// get log level // get log level
LogLevel level; LogLevel level;

View File

@ -1,7 +1,4 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
#if !SMAPI_3_0_STRICT
using Microsoft.Xna.Framework.Input;
#endif
using StardewModdingAPI.Events; using StardewModdingAPI.Events;
namespace StardewModdingAPI.Framework.Events namespace StardewModdingAPI.Framework.Events
@ -167,196 +164,6 @@ namespace StardewModdingAPI.Framework.Events
public readonly ManagedEvent<UnvalidatedUpdateTickedEventArgs> UnvalidatedUpdateTicked; public readonly ManagedEvent<UnvalidatedUpdateTickedEventArgs> UnvalidatedUpdateTicked;
#if !SMAPI_3_0_STRICT
/*********
** Events (old)
*********/
/****
** ContentEvents
****/
/// <summary>Raised after the content language changes.</summary>
public readonly ManagedEvent<EventArgsValueChanged<string>> Legacy_LocaleChanged;
/****
** ControlEvents
****/
/// <summary>Raised when the <see cref="KeyboardState"/> changes. That happens when the player presses or releases a key.</summary>
public readonly ManagedEvent<EventArgsKeyboardStateChanged> Legacy_KeyboardChanged;
/// <summary>Raised after the player presses a keyboard key.</summary>
public readonly ManagedEvent<EventArgsKeyPressed> Legacy_KeyPressed;
/// <summary>Raised after the player releases a keyboard key.</summary>
public readonly ManagedEvent<EventArgsKeyPressed> Legacy_KeyReleased;
/// <summary>Raised when the <see cref="MouseState"/> changes. That happens when the player moves the mouse, scrolls the mouse wheel, or presses/releases a button.</summary>
public readonly ManagedEvent<EventArgsMouseStateChanged> Legacy_MouseChanged;
/// <summary>The player pressed a controller button. This event isn't raised for trigger buttons.</summary>
public readonly ManagedEvent<EventArgsControllerButtonPressed> Legacy_ControllerButtonPressed;
/// <summary>The player released a controller button. This event isn't raised for trigger buttons.</summary>
public readonly ManagedEvent<EventArgsControllerButtonReleased> Legacy_ControllerButtonReleased;
/// <summary>The player pressed a controller trigger button.</summary>
public readonly ManagedEvent<EventArgsControllerTriggerPressed> Legacy_ControllerTriggerPressed;
/// <summary>The player released a controller trigger button.</summary>
public readonly ManagedEvent<EventArgsControllerTriggerReleased> Legacy_ControllerTriggerReleased;
/****
** GameEvents
****/
/// <summary>Raised once after the game initialises and all <see cref="IMod.Entry"/> methods have been called.</summary>
public readonly ManagedEvent Legacy_FirstUpdateTick;
/// <summary>Raised when the game updates its state (≈60 times per second).</summary>
public readonly ManagedEvent Legacy_UpdateTick;
/// <summary>Raised every other tick (≈30 times per second).</summary>
public readonly ManagedEvent Legacy_SecondUpdateTick;
/// <summary>Raised every fourth tick (≈15 times per second).</summary>
public readonly ManagedEvent Legacy_FourthUpdateTick;
/// <summary>Raised every eighth tick (≈8 times per second).</summary>
public readonly ManagedEvent Legacy_EighthUpdateTick;
/// <summary>Raised every 15th tick (≈4 times per second).</summary>
public readonly ManagedEvent Legacy_QuarterSecondTick;
/// <summary>Raised every 30th tick (≈twice per second).</summary>
public readonly ManagedEvent Legacy_HalfSecondTick;
/// <summary>Raised every 60th tick (≈once per second).</summary>
public readonly ManagedEvent Legacy_OneSecondTick;
/****
** GraphicsEvents
****/
/// <summary>Raised after the game window is resized.</summary>
public readonly ManagedEvent Legacy_Resize;
/// <summary>Raised before drawing the world to the screen.</summary>
public readonly ManagedEvent Legacy_OnPreRenderEvent;
/// <summary>Raised after drawing the world to the screen.</summary>
public readonly ManagedEvent Legacy_OnPostRenderEvent;
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public readonly ManagedEvent Legacy_OnPreRenderHudEvent;
/// <summary>Raised after drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public readonly ManagedEvent Legacy_OnPostRenderHudEvent;
/// <summary>Raised before drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public readonly ManagedEvent Legacy_OnPreRenderGuiEvent;
/// <summary>Raised after drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public readonly ManagedEvent Legacy_OnPostRenderGuiEvent;
/****
** InputEvents
****/
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
public readonly ManagedEvent<EventArgsInput> Legacy_ButtonPressed;
/// <summary>Raised after the player releases a keyboard key on the keyboard, controller, or mouse.</summary>
public readonly ManagedEvent<EventArgsInput> Legacy_ButtonReleased;
/****
** LocationEvents
****/
/// <summary>Raised after a game location is added or removed.</summary>
public readonly ManagedEvent<EventArgsLocationsChanged> Legacy_LocationsChanged;
/// <summary>Raised after buildings are added or removed in a location.</summary>
public readonly ManagedEvent<EventArgsLocationBuildingsChanged> Legacy_BuildingsChanged;
/// <summary>Raised after objects are added or removed in a location.</summary>
public readonly ManagedEvent<EventArgsLocationObjectsChanged> Legacy_ObjectsChanged;
/****
** MenuEvents
****/
/// <summary>Raised after a game menu is opened or replaced with another menu. This event is not invoked when a menu is closed.</summary>
public readonly ManagedEvent<EventArgsClickableMenuChanged> Legacy_MenuChanged;
/// <summary>Raised after a game menu is closed.</summary>
public readonly ManagedEvent<EventArgsClickableMenuClosed> Legacy_MenuClosed;
/****
** MultiplayerEvents
****/
/// <summary>Raised before the game syncs changes from other players.</summary>
public readonly ManagedEvent Legacy_BeforeMainSync;
/// <summary>Raised after the game syncs changes from other players.</summary>
public readonly ManagedEvent Legacy_AfterMainSync;
/// <summary>Raised before the game broadcasts changes to other players.</summary>
public readonly ManagedEvent Legacy_BeforeMainBroadcast;
/// <summary>Raised after the game broadcasts changes to other players.</summary>
public readonly ManagedEvent Legacy_AfterMainBroadcast;
/****
** MineEvents
****/
/// <summary>Raised after the player warps to a new level of the mine.</summary>
public readonly ManagedEvent<EventArgsMineLevelChanged> Legacy_MineLevelChanged;
/****
** PlayerEvents
****/
/// <summary>Raised after the player's inventory changes in any way (added or removed item, sorted, etc).</summary>
public readonly ManagedEvent<EventArgsInventoryChanged> Legacy_InventoryChanged;
/// <summary> Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
public readonly ManagedEvent<EventArgsLevelUp> Legacy_LeveledUp;
/// <summary>Raised after the player warps to a new location.</summary>
public readonly ManagedEvent<EventArgsPlayerWarped> Legacy_PlayerWarped;
/****
** SaveEvents
****/
/// <summary>Raised before the game creates the save file.</summary>
public readonly ManagedEvent Legacy_BeforeCreateSave;
/// <summary>Raised after the game finishes creating the save file.</summary>
public readonly ManagedEvent Legacy_AfterCreateSave;
/// <summary>Raised before the game begins writes data to the save file.</summary>
public readonly ManagedEvent Legacy_BeforeSave;
/// <summary>Raised after the game finishes writing data to the save file.</summary>
public readonly ManagedEvent Legacy_AfterSave;
/// <summary>Raised after the player loads a save slot.</summary>
public readonly ManagedEvent Legacy_AfterLoad;
/// <summary>Raised after the game returns to the title screen.</summary>
public readonly ManagedEvent Legacy_AfterReturnToTitle;
/****
** SpecialisedEvents
****/
/// <summary>Raised when the game updates its state (≈60 times per second), regardless of normal SMAPI validation. This event is not thread-safe and may be invoked while game logic is running asynchronously. Changes to game state in this method may crash the game or corrupt an in-progress save. Do not use this event unless you're fully aware of the context in which your code will be run. Mods using this method will trigger a stability warning in the SMAPI console.</summary>
public readonly ManagedEvent Legacy_UnvalidatedUpdateTick;
/****
** TimeEvents
****/
/// <summary>Raised after the game begins a new day, including when loading a save.</summary>
public readonly ManagedEvent Legacy_AfterDayStarted;
/// <summary>Raised after the in-game clock changes.</summary>
public readonly ManagedEvent<EventArgsIntChanged> Legacy_TimeOfDayChanged;
#endif
/********* /*********
** Public methods ** Public methods
*********/ *********/
@ -367,9 +174,6 @@ namespace StardewModdingAPI.Framework.Events
{ {
// create shortcut initialisers // create shortcut initialisers
ManagedEvent<TEventArgs> ManageEventOf<TEventArgs>(string typeName, string eventName) => new ManagedEvent<TEventArgs>($"{typeName}.{eventName}", monitor, modRegistry); ManagedEvent<TEventArgs> ManageEventOf<TEventArgs>(string typeName, string eventName) => new ManagedEvent<TEventArgs>($"{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) // init events (new)
this.MenuChanged = ManageEventOf<MenuChangedEventArgs>(nameof(IModEvents.Display), nameof(IDisplayEvents.MenuChanged)); this.MenuChanged = ManageEventOf<MenuChangedEventArgs>(nameof(IModEvents.Display), nameof(IDisplayEvents.MenuChanged));
@ -422,70 +226,6 @@ namespace StardewModdingAPI.Framework.Events
this.LoadStageChanged = ManageEventOf<LoadStageChangedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.LoadStageChanged)); this.LoadStageChanged = ManageEventOf<LoadStageChangedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.LoadStageChanged));
this.UnvalidatedUpdateTicking = ManageEventOf<UnvalidatedUpdateTickingEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicking)); this.UnvalidatedUpdateTicking = ManageEventOf<UnvalidatedUpdateTickingEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicking));
this.UnvalidatedUpdateTicked = ManageEventOf<UnvalidatedUpdateTickedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicked)); this.UnvalidatedUpdateTicked = ManageEventOf<UnvalidatedUpdateTickedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicked));
#if !SMAPI_3_0_STRICT
// init events (old)
this.Legacy_LocaleChanged = ManageEventOf<EventArgsValueChanged<string>>(nameof(ContentEvents), nameof(ContentEvents.AfterLocaleChanged));
this.Legacy_ControllerButtonPressed = ManageEventOf<EventArgsControllerButtonPressed>(nameof(ControlEvents), nameof(ControlEvents.ControllerButtonPressed));
this.Legacy_ControllerButtonReleased = ManageEventOf<EventArgsControllerButtonReleased>(nameof(ControlEvents), nameof(ControlEvents.ControllerButtonReleased));
this.Legacy_ControllerTriggerPressed = ManageEventOf<EventArgsControllerTriggerPressed>(nameof(ControlEvents), nameof(ControlEvents.ControllerTriggerPressed));
this.Legacy_ControllerTriggerReleased = ManageEventOf<EventArgsControllerTriggerReleased>(nameof(ControlEvents), nameof(ControlEvents.ControllerTriggerReleased));
this.Legacy_KeyboardChanged = ManageEventOf<EventArgsKeyboardStateChanged>(nameof(ControlEvents), nameof(ControlEvents.KeyboardChanged));
this.Legacy_KeyPressed = ManageEventOf<EventArgsKeyPressed>(nameof(ControlEvents), nameof(ControlEvents.KeyPressed));
this.Legacy_KeyReleased = ManageEventOf<EventArgsKeyPressed>(nameof(ControlEvents), nameof(ControlEvents.KeyReleased));
this.Legacy_MouseChanged = ManageEventOf<EventArgsMouseStateChanged>(nameof(ControlEvents), nameof(ControlEvents.MouseChanged));
this.Legacy_FirstUpdateTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.FirstUpdateTick));
this.Legacy_UpdateTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.UpdateTick));
this.Legacy_SecondUpdateTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.SecondUpdateTick));
this.Legacy_FourthUpdateTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.FourthUpdateTick));
this.Legacy_EighthUpdateTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.EighthUpdateTick));
this.Legacy_QuarterSecondTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.QuarterSecondTick));
this.Legacy_HalfSecondTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.HalfSecondTick));
this.Legacy_OneSecondTick = ManageEvent(nameof(GameEvents), nameof(GameEvents.OneSecondTick));
this.Legacy_Resize = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.Resize));
this.Legacy_OnPreRenderEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPreRenderEvent));
this.Legacy_OnPostRenderEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPostRenderEvent));
this.Legacy_OnPreRenderHudEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPreRenderHudEvent));
this.Legacy_OnPostRenderHudEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPostRenderHudEvent));
this.Legacy_OnPreRenderGuiEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPreRenderGuiEvent));
this.Legacy_OnPostRenderGuiEvent = ManageEvent(nameof(GraphicsEvents), nameof(GraphicsEvents.OnPostRenderGuiEvent));
this.Legacy_ButtonPressed = ManageEventOf<EventArgsInput>(nameof(InputEvents), nameof(InputEvents.ButtonPressed));
this.Legacy_ButtonReleased = ManageEventOf<EventArgsInput>(nameof(InputEvents), nameof(InputEvents.ButtonReleased));
this.Legacy_LocationsChanged = ManageEventOf<EventArgsLocationsChanged>(nameof(LocationEvents), nameof(LocationEvents.LocationsChanged));
this.Legacy_BuildingsChanged = ManageEventOf<EventArgsLocationBuildingsChanged>(nameof(LocationEvents), nameof(LocationEvents.BuildingsChanged));
this.Legacy_ObjectsChanged = ManageEventOf<EventArgsLocationObjectsChanged>(nameof(LocationEvents), nameof(LocationEvents.ObjectsChanged));
this.Legacy_MenuChanged = ManageEventOf<EventArgsClickableMenuChanged>(nameof(MenuEvents), nameof(MenuEvents.MenuChanged));
this.Legacy_MenuClosed = ManageEventOf<EventArgsClickableMenuClosed>(nameof(MenuEvents), nameof(MenuEvents.MenuClosed));
this.Legacy_BeforeMainBroadcast = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.BeforeMainBroadcast));
this.Legacy_AfterMainBroadcast = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.AfterMainBroadcast));
this.Legacy_BeforeMainSync = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.BeforeMainSync));
this.Legacy_AfterMainSync = ManageEvent(nameof(MultiplayerEvents), nameof(MultiplayerEvents.AfterMainSync));
this.Legacy_MineLevelChanged = ManageEventOf<EventArgsMineLevelChanged>(nameof(MineEvents), nameof(MineEvents.MineLevelChanged));
this.Legacy_InventoryChanged = ManageEventOf<EventArgsInventoryChanged>(nameof(PlayerEvents), nameof(PlayerEvents.InventoryChanged));
this.Legacy_LeveledUp = ManageEventOf<EventArgsLevelUp>(nameof(PlayerEvents), nameof(PlayerEvents.LeveledUp));
this.Legacy_PlayerWarped = ManageEventOf<EventArgsPlayerWarped>(nameof(PlayerEvents), nameof(PlayerEvents.Warped));
this.Legacy_BeforeCreateSave = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.BeforeCreate));
this.Legacy_AfterCreateSave = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.AfterCreate));
this.Legacy_BeforeSave = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.BeforeSave));
this.Legacy_AfterSave = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.AfterSave));
this.Legacy_AfterLoad = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.AfterLoad));
this.Legacy_AfterReturnToTitle = ManageEvent(nameof(SaveEvents), nameof(SaveEvents.AfterReturnToTitle));
this.Legacy_UnvalidatedUpdateTick = ManageEvent(nameof(SpecialisedEvents), nameof(SpecialisedEvents.UnvalidatedUpdateTick));
this.Legacy_AfterDayStarted = ManageEvent(nameof(TimeEvents), nameof(TimeEvents.AfterDayStarted));
this.Legacy_TimeOfDayChanged = ManageEventOf<EventArgsIntChanged>(nameof(TimeEvents), nameof(TimeEvents.TimeOfDayChanged));
#endif
} }
} }
} }

View File

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace StardewModdingAPI.Framework.Events namespace StardewModdingAPI.Framework.Events
{ {
/// <summary>An event wrapper which intercepts and logs errors in handler code.</summary> /// <summary>An event wrapper which intercepts and logs errors in handler code.</summary>
/// <typeparam name="TEventArgs">The event arguments type.</typeparam> /// <typeparam name="TEventArgs">The event arguments type.</typeparam>
internal class ManagedEvent<TEventArgs> : ManagedEventBase<EventHandler<TEventArgs>> internal class ManagedEvent<TEventArgs>
{ {
/********* /*********
** Fields ** Fields
@ -13,6 +14,21 @@ namespace StardewModdingAPI.Framework.Events
/// <summary>The underlying event.</summary> /// <summary>The underlying event.</summary>
private event EventHandler<TEventArgs> Event; private event EventHandler<TEventArgs> Event;
/// <summary>A human-readable name for the event.</summary>
private readonly string EventName;
/// <summary>Writes messages to the log.</summary>
private readonly IMonitor Monitor;
/// <summary>The mod registry with which to identify mods.</summary>
protected readonly ModRegistry ModRegistry;
/// <summary>The display names for the mods which added each delegate.</summary>
private readonly IDictionary<EventHandler<TEventArgs>, IModMetadata> SourceMods = new Dictionary<EventHandler<TEventArgs>, IModMetadata>();
/// <summary>The cached invocation list.</summary>
private EventHandler<TEventArgs>[] CachedInvocationList;
/********* /*********
** Public methods ** Public methods
@ -22,7 +38,17 @@ namespace StardewModdingAPI.Framework.Events
/// <param name="monitor">Writes messages to the log.</param> /// <param name="monitor">Writes messages to the log.</param>
/// <param name="modRegistry">The mod registry with which to identify mods.</param> /// <param name="modRegistry">The mod registry with which to identify mods.</param>
public ManagedEvent(string eventName, IMonitor monitor, ModRegistry modRegistry) public ManagedEvent(string eventName, IMonitor monitor, ModRegistry modRegistry)
: base(eventName, monitor, modRegistry) { } {
this.EventName = eventName;
this.Monitor = monitor;
this.ModRegistry = modRegistry;
}
/// <summary>Get whether anything is listening to the event.</summary>
public bool HasListeners()
{
return this.CachedInvocationList?.Length > 0;
}
/// <summary>Add an event handler.</summary> /// <summary>Add an event handler.</summary>
/// <param name="handler">The event handler.</param> /// <param name="handler">The event handler.</param>
@ -91,71 +117,50 @@ namespace StardewModdingAPI.Framework.Events
} }
} }
} }
}
#if !SMAPI_3_0_STRICT
/// <summary>An event wrapper which intercepts and logs errors in handler code.</summary>
internal class ManagedEvent : ManagedEventBase<EventHandler>
{
/*********
** Fields
*********/
/// <summary>The underlying event.</summary>
private event EventHandler Event;
/********* /*********
** Public methods ** Private methods
*********/ *********/
/// <summary>Construct an instance.</summary> /// <summary>Track an event handler.</summary>
/// <param name="eventName">A human-readable name for the event.</param> /// <param name="mod">The mod which added the handler.</param>
/// <param name="monitor">Writes messages to the log.</param>
/// <param name="modRegistry">The mod registry with which to identify mods.</param>
public ManagedEvent(string eventName, IMonitor monitor, ModRegistry modRegistry)
: base(eventName, monitor, modRegistry) { }
/// <summary>Add an event handler.</summary>
/// <param name="handler">The event handler.</param> /// <param name="handler">The event handler.</param>
public void Add(EventHandler handler) /// <param name="invocationList">The updated event invocation list.</param>
protected void AddTracking(IModMetadata mod, EventHandler<TEventArgs> handler, IEnumerable<EventHandler<TEventArgs>> invocationList)
{ {
this.Add(handler, this.ModRegistry.GetFromStack()); this.SourceMods[handler] = mod;
this.CachedInvocationList = invocationList?.ToArray() ?? new EventHandler<TEventArgs>[0];
} }
/// <summary>Add an event handler.</summary> /// <summary>Remove tracking for an event handler.</summary>
/// <param name="handler">The event handler.</param> /// <param name="handler">The event handler.</param>
/// <param name="mod">The mod which added the event handler.</param> /// <param name="invocationList">The updated event invocation list.</param>
public void Add(EventHandler handler, IModMetadata mod) protected void RemoveTracking(EventHandler<TEventArgs> handler, IEnumerable<EventHandler<TEventArgs>> invocationList)
{ {
this.Event += handler; this.CachedInvocationList = invocationList?.ToArray() ?? new EventHandler<TEventArgs>[0];
this.AddTracking(mod, handler, this.Event?.GetInvocationList().Cast<EventHandler>()); if (!this.CachedInvocationList.Contains(handler)) // don't remove if there's still a reference to the removed handler (e.g. it was added twice and removed once)
this.SourceMods.Remove(handler);
} }
/// <summary>Remove an event handler.</summary> /// <summary>Get the mod which registered the given event handler, if available.</summary>
/// <param name="handler">The event handler.</param> /// <param name="handler">The event handler.</param>
public void Remove(EventHandler handler) protected IModMetadata GetSourceMod(EventHandler<TEventArgs> handler)
{ {
this.Event -= handler; return this.SourceMods.TryGetValue(handler, out IModMetadata mod)
this.RemoveTracking(handler, this.Event?.GetInvocationList().Cast<EventHandler>()); ? mod
: null;
} }
/// <summary>Raise the event and notify all handlers.</summary> /// <summary>Log an exception from an event handler.</summary>
public void Raise() /// <param name="handler">The event handler instance.</param>
/// <param name="ex">The exception that was raised.</param>
protected void LogError(EventHandler<TEventArgs> handler, Exception ex)
{ {
if (this.Event == null) IModMetadata mod = this.GetSourceMod(handler);
return; if (mod != null)
mod.LogAsMod($"This mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
foreach (EventHandler handler in this.CachedInvocationList) else
{ this.Monitor.Log($"A mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
try
{
handler.Invoke(null, EventArgs.Empty);
}
catch (Exception ex)
{
this.LogError(handler, ex);
}
}
} }
} }
#endif
} }

View File

@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace StardewModdingAPI.Framework.Events
{
/// <summary>The base implementation for an event wrapper which intercepts and logs errors in handler code.</summary>
internal abstract class ManagedEventBase<TEventHandler>
{
/*********
** Fields
*********/
/// <summary>A human-readable name for the event.</summary>
private readonly string EventName;
/// <summary>Writes messages to the log.</summary>
private readonly IMonitor Monitor;
/// <summary>The mod registry with which to identify mods.</summary>
protected readonly ModRegistry ModRegistry;
/// <summary>The display names for the mods which added each delegate.</summary>
private readonly IDictionary<TEventHandler, IModMetadata> SourceMods = new Dictionary<TEventHandler, IModMetadata>();
/// <summary>The cached invocation list.</summary>
protected TEventHandler[] CachedInvocationList { get; private set; }
/*********
** Public methods
*********/
/// <summary>Get whether anything is listening to the event.</summary>
public bool HasListeners()
{
return this.CachedInvocationList?.Length > 0;
}
/*********
** Protected methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="eventName">A human-readable name for the event.</param>
/// <param name="monitor">Writes messages to the log.</param>
/// <param name="modRegistry">The mod registry with which to identify mods.</param>
protected ManagedEventBase(string eventName, IMonitor monitor, ModRegistry modRegistry)
{
this.EventName = eventName;
this.Monitor = monitor;
this.ModRegistry = modRegistry;
}
/// <summary>Track an event handler.</summary>
/// <param name="mod">The mod which added the handler.</param>
/// <param name="handler">The event handler.</param>
/// <param name="invocationList">The updated event invocation list.</param>
protected void AddTracking(IModMetadata mod, TEventHandler handler, IEnumerable<TEventHandler> invocationList)
{
this.SourceMods[handler] = mod;
this.CachedInvocationList = invocationList?.ToArray() ?? new TEventHandler[0];
}
/// <summary>Remove tracking for an event handler.</summary>
/// <param name="handler">The event handler.</param>
/// <param name="invocationList">The updated event invocation list.</param>
protected void RemoveTracking(TEventHandler handler, IEnumerable<TEventHandler> invocationList)
{
this.CachedInvocationList = invocationList?.ToArray() ?? new TEventHandler[0];
if (!this.CachedInvocationList.Contains(handler)) // don't remove if there's still a reference to the removed handler (e.g. it was added twice and removed once)
this.SourceMods.Remove(handler);
}
/// <summary>Get the mod which registered the given event handler, if available.</summary>
/// <param name="handler">The event handler.</param>
protected IModMetadata GetSourceMod(TEventHandler handler)
{
return this.SourceMods.TryGetValue(handler, out IModMetadata mod)
? mod
: null;
}
/// <summary>Log an exception from an event handler.</summary>
/// <param name="handler">The event handler instance.</param>
/// <param name="ex">The exception that was raised.</param>
protected void LogError(TEventHandler handler, Exception ex)
{
IModMetadata mod = this.GetSourceMod(handler);
if (mod != null)
mod.LogAsMod($"This mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
else
this.Monitor.Log($"A mod failed in the {this.EventName} event. Technical details: \n{ex.GetLogSummary()}", LogLevel.Error);
}
}
}

View File

@ -1,11 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using StardewModdingAPI.Events; using StardewModdingAPI.Events;
using StardewModdingAPI.Framework.Input; using StardewModdingAPI.Framework.Input;
using StardewModdingAPI.Toolkit.Serialisation; using StardewModdingAPI.Toolkit.Serialisation;
using StardewModdingAPI.Toolkit.Serialisation.Models;
using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Framework.ModHelpers namespace StardewModdingAPI.Framework.ModHelpers
{ {
@ -18,11 +15,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The full path to the mod's folder.</summary> /// <summary>The full path to the mod's folder.</summary>
public string DirectoryPath { get; } public string DirectoryPath { get; }
#if !SMAPI_3_0_STRICT
/// <summary>Encapsulates SMAPI's JSON file parsing.</summary>
private readonly JsonHelper JsonHelper;
#endif
/// <summary>Manages access to events raised by SMAPI, which let your mod react when something happens in the game.</summary> /// <summary>Manages access to events raised by SMAPI, which let your mod react when something happens in the game.</summary>
public IModEvents Events { get; } public IModEvents Events { get; }
@ -60,7 +52,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>Construct an instance.</summary> /// <summary>Construct an instance.</summary>
/// <param name="modID">The mod's unique ID.</param> /// <param name="modID">The mod's unique ID.</param>
/// <param name="modDirectory">The full path to the mod's folder.</param> /// <param name="modDirectory">The full path to the mod's folder.</param>
/// <param name="jsonHelper">Encapsulate SMAPI's JSON parsing.</param>
/// <param name="inputState">Manages the game's input state.</param> /// <param name="inputState">Manages the game's input state.</param>
/// <param name="events">Manages access to events raised by SMAPI.</param> /// <param name="events">Manages access to events raised by SMAPI.</param>
/// <param name="contentHelper">An API for loading content assets.</param> /// <param name="contentHelper">An API for loading content assets.</param>
@ -73,7 +64,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="translationHelper">An API for reading translations stored in the mod's <c>i18n</c> folder.</param> /// <param name="translationHelper">An API for reading translations stored in the mod's <c>i18n</c> folder.</param>
/// <exception cref="ArgumentNullException">An argument is null or empty.</exception> /// <exception cref="ArgumentNullException">An argument is null or empty.</exception>
/// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception> /// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception>
public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper) public ModHelper(string modID, string modDirectory, SInputState inputState, IModEvents events, IContentHelper contentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper)
: base(modID) : base(modID)
{ {
// validate directory // validate directory
@ -94,9 +85,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
this.Multiplayer = multiplayer ?? throw new ArgumentNullException(nameof(multiplayer)); this.Multiplayer = multiplayer ?? throw new ArgumentNullException(nameof(multiplayer));
this.Translation = translationHelper ?? throw new ArgumentNullException(nameof(translationHelper)); this.Translation = translationHelper ?? throw new ArgumentNullException(nameof(translationHelper));
this.Events = events; this.Events = events;
#if !SMAPI_3_0_STRICT
this.JsonHelper = jsonHelper ?? throw new ArgumentNullException(nameof(jsonHelper));
#endif
} }
/**** /****
@ -121,63 +109,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
this.Data.WriteJsonFile("config.json", config); this.Data.WriteJsonFile("config.json", config);
} }
#if !SMAPI_3_0_STRICT
/****
** Generic JSON files
****/
/// <summary>Read a JSON file.</summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <param name="path">The file path relative to the mod directory.</param>
/// <returns>Returns the deserialised model, or <c>null</c> if the file doesn't exist or is empty.</returns>
[Obsolete("Use " + nameof(ModHelper.Data) + "." + nameof(IDataHelper.ReadJsonFile) + " instead")]
public TModel ReadJsonFile<TModel>(string path)
where TModel : class
{
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalisePathSeparators(path));
return this.JsonHelper.ReadJsonFileIfExists(path, out TModel data)
? data
: null;
}
/// <summary>Save to a JSON file.</summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <param name="path">The file path relative to the mod directory.</param>
/// <param name="model">The model to save.</param>
[Obsolete("Use " + nameof(ModHelper.Data) + "." + nameof(IDataHelper.WriteJsonFile) + " instead")]
public void WriteJsonFile<TModel>(string path, TModel model)
where TModel : class
{
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalisePathSeparators(path));
this.JsonHelper.WriteJsonFile(path, model);
}
#endif
/****
** Content packs
****/
#if !SMAPI_3_0_STRICT
/// <summary>Manually create a transitional content pack to support pre-SMAPI content packs. This provides a way to access legacy content packs using the SMAPI content pack APIs, but the content pack will not be visible in the log or validated by SMAPI.</summary>
/// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
/// <param name="id">The content pack's unique ID.</param>
/// <param name="name">The content pack name.</param>
/// <param name="description">The content pack description.</param>
/// <param name="author">The content pack author's name.</param>
/// <param name="version">The content pack version.</param>
[Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.CreateTemporary) + " instead")]
public IContentPack CreateTransitionalContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version)
{
SCore.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.PendingRemoval);
return this.ContentPacks.CreateTemporary(directoryPath, id, name, description, author, version);
}
/// <summary>Get all content packs loaded for this mod.</summary>
[Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.GetOwned) + " instead")]
public IEnumerable<IContentPack> GetContentPacks()
{
return this.ContentPacks.GetOwned();
}
#endif
/**** /****
** Disposal ** Disposal
****/ ****/

View File

@ -147,12 +147,8 @@ namespace StardewModdingAPI.Framework.ModLoading
string actualFilename = new DirectoryInfo(mod.DirectoryPath).GetFiles(mod.Manifest.EntryDll).FirstOrDefault()?.Name; string actualFilename = new DirectoryInfo(mod.DirectoryPath).GetFiles(mod.Manifest.EntryDll).FirstOrDefault()?.Name;
if (actualFilename != mod.Manifest.EntryDll) if (actualFilename != mod.Manifest.EntryDll)
{ {
#if SMAPI_3_0_STRICT
mod.SetStatus(ModMetadataStatus.Failed, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalisation '{actualFilename}'. The capitalisation must match for crossplatform compatibility."); mod.SetStatus(ModMetadataStatus.Failed, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalisation '{actualFilename}'. The capitalisation must match for crossplatform compatibility.");
continue; continue;
#else
SCore.DeprecationManager.Warn(mod.DisplayName, $"{nameof(IManifest.EntryDll)} value with case-insensitive capitalisation", "2.11", DeprecationLevel.PendingRemoval);
#endif
} }
} }

View File

@ -190,24 +190,6 @@ namespace StardewModdingAPI.Framework
// initialise SMAPI // initialise SMAPI
try try
{ {
#if !SMAPI_3_0_STRICT
// hook up events
ContentEvents.Init(this.EventManager);
ControlEvents.Init(this.EventManager);
GameEvents.Init(this.EventManager);
GraphicsEvents.Init(this.EventManager);
InputEvents.Init(this.EventManager);
LocationEvents.Init(this.EventManager);
MenuEvents.Init(this.EventManager);
MineEvents.Init(this.EventManager);
MultiplayerEvents.Init(this.EventManager);
PlayerEvents.Init(this.EventManager);
SaveEvents.Init(this.EventManager);
SpecialisedEvents.Init(this.EventManager);
TimeEvents.Init(this.EventManager);
#endif
// init JSON parser
JsonConverter[] converters = { JsonConverter[] converters = {
new ColorConverter(), new ColorConverter(),
new PointConverter(), new PointConverter(),
@ -261,10 +243,6 @@ namespace StardewModdingAPI.Framework
// set window titles // set window titles
this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion}"; this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion}";
Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion}"; 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) catch (Exception ex)
{ {
@ -374,9 +352,6 @@ namespace StardewModdingAPI.Framework
private void InitialiseAfterGameStart() private void InitialiseAfterGameStart()
{ {
// add headers // 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) if (this.Settings.DeveloperMode)
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); 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) if (!this.Settings.CheckForUpdates)
@ -438,11 +413,6 @@ namespace StardewModdingAPI.Framework
int modsLoaded = this.ModRegistry.GetAll().Count(); int modsLoaded = this.ModRegistry.GetAll().Count();
this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion} with {modsLoaded} mods"; 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"; 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 // start SMAPI console
new Thread(this.RunConsoleLoop).Start(); new Thread(this.RunConsoleLoop).Start();
@ -925,14 +895,6 @@ namespace StardewModdingAPI.Framework
return false; return false;
} }
#if !SMAPI_3_0_STRICT
// add deprecation warning for old version format
{
if (mod.Manifest?.Version is Toolkit.SemanticVersion version && version.IsLegacyFormat)
SCore.DeprecationManager.Warn(mod.DisplayName, "non-string manifest version", "2.8", DeprecationLevel.PendingRemoval);
}
#endif
// validate dependencies // validate dependencies
// Although dependences are validated before mods are loaded, a dependency may have failed to load. // Although dependences are validated before mods are loaded, a dependency may have failed to load.
if (mod.Manifest.Dependencies?.Any() == true) if (mod.Manifest.Dependencies?.Any() == true)
@ -1038,7 +1000,7 @@ namespace StardewModdingAPI.Framework
return new ContentPack(packDirPath, packManifest, packContentHelper, this.Toolkit.JsonHelper); return new ContentPack(packDirPath, packManifest, packContentHelper, this.Toolkit.JsonHelper);
} }
modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.Toolkit.JsonHelper, this.GameInstance.Input, events, contentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper); modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, this.GameInstance.Input, events, contentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
} }
// init mod // init mod

View File

@ -9,9 +9,6 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
#if !SMAPI_3_0_STRICT
using Microsoft.Xna.Framework.Input;
#endif
using Netcode; using Netcode;
using StardewModdingAPI.Enums; using StardewModdingAPI.Enums;
using StardewModdingAPI.Events; using StardewModdingAPI.Events;
@ -228,12 +225,7 @@ namespace StardewModdingAPI.Framework
// raise events // raise events
this.Events.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage)); this.Events.LoadStageChanged.Raise(new LoadStageChangedEventArgs(oldStage, newStage));
if (newStage == LoadStage.None) if (newStage == LoadStage.None)
{
this.Events.ReturnedToTitle.RaiseEmpty(); this.Events.ReturnedToTitle.RaiseEmpty();
#if !SMAPI_3_0_STRICT
this.Events.Legacy_AfterReturnToTitle.Raise();
#endif
}
} }
/// <summary>Constructor a content manager to read XNB files.</summary> /// <summary>Constructor a content manager to read XNB files.</summary>
@ -344,9 +336,6 @@ namespace StardewModdingAPI.Framework
SGame.TicksElapsed++; SGame.TicksElapsed++;
base.Update(gameTime); base.Update(gameTime);
events.UnvalidatedUpdateTicked.RaiseEmpty(); events.UnvalidatedUpdateTicked.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_UnvalidatedUpdateTick.Raise();
#endif
return; return;
} }
@ -393,9 +382,6 @@ namespace StardewModdingAPI.Framework
// This should *always* run, even when suppressing mod events, since the game uses // 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 // this too. For example, doing this after mod event suppression would prevent the
// user from doing anything on the overnight shipping screen. // user from doing anything on the overnight shipping screen.
#if !SMAPI_3_0_STRICT
SInputState previousInputState = this.Input.Clone();
#endif
SInputState inputState = this.Input; SInputState inputState = this.Input;
if (this.IsActive) if (this.IsActive)
inputState.TrueUpdate(); inputState.TrueUpdate();
@ -416,9 +402,6 @@ namespace StardewModdingAPI.Framework
this.IsBetweenCreateEvents = true; this.IsBetweenCreateEvents = true;
this.Monitor.Log("Context: before save creation.", LogLevel.Trace); this.Monitor.Log("Context: before save creation.", LogLevel.Trace);
events.SaveCreating.RaiseEmpty(); events.SaveCreating.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_BeforeCreateSave.Raise();
#endif
} }
// raise before-save // raise before-save
@ -427,9 +410,6 @@ namespace StardewModdingAPI.Framework
this.IsBetweenSaveEvents = true; this.IsBetweenSaveEvents = true;
this.Monitor.Log("Context: before save.", LogLevel.Trace); this.Monitor.Log("Context: before save.", LogLevel.Trace);
events.Saving.RaiseEmpty(); events.Saving.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_BeforeSave.Raise();
#endif
} }
// suppress non-save events // suppress non-save events
@ -437,9 +417,6 @@ namespace StardewModdingAPI.Framework
SGame.TicksElapsed++; SGame.TicksElapsed++;
base.Update(gameTime); base.Update(gameTime);
events.UnvalidatedUpdateTicked.RaiseEmpty(); events.UnvalidatedUpdateTicked.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_UnvalidatedUpdateTick.Raise();
#endif
return; return;
} }
if (this.IsBetweenCreateEvents) if (this.IsBetweenCreateEvents)
@ -449,9 +426,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Context: after save creation, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); this.Monitor.Log($"Context: after save creation, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace);
this.OnLoadStageChanged(LoadStage.CreatedSaveFile); this.OnLoadStageChanged(LoadStage.CreatedSaveFile);
events.SaveCreated.RaiseEmpty(); events.SaveCreated.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_AfterCreateSave.Raise();
#endif
} }
if (this.IsBetweenSaveEvents) if (this.IsBetweenSaveEvents)
{ {
@ -460,10 +434,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Context: after save, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); this.Monitor.Log($"Context: after save, starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace);
events.Saved.RaiseEmpty(); events.Saved.RaiseEmpty();
events.DayStarted.RaiseEmpty(); events.DayStarted.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_AfterSave.Raise();
events.Legacy_AfterDayStarted.Raise();
#endif
} }
/********* /*********
@ -492,15 +462,8 @@ namespace StardewModdingAPI.Framework
*********/ *********/
if (this.Watchers.LocaleWatcher.IsChanged) if (this.Watchers.LocaleWatcher.IsChanged)
{ {
var was = this.Watchers.LocaleWatcher.PreviousValue; this.Monitor.Log($"Context: locale set to {this.Watchers.LocaleWatcher.CurrentValue}.", LogLevel.Trace);
var now = this.Watchers.LocaleWatcher.CurrentValue;
this.Monitor.Log($"Context: locale set to {now}.", LogLevel.Trace);
this.OnLocaleChanged(); this.OnLocaleChanged();
#if !SMAPI_3_0_STRICT
events.Legacy_LocaleChanged.Raise(new EventArgsValueChanged<string>(was.ToString(), now.ToString()));
#endif
this.Watchers.LocaleWatcher.Reset(); this.Watchers.LocaleWatcher.Reset();
} }
@ -527,10 +490,6 @@ namespace StardewModdingAPI.Framework
this.OnLoadStageChanged(LoadStage.Ready); this.OnLoadStageChanged(LoadStage.Ready);
events.SaveLoaded.RaiseEmpty(); events.SaveLoaded.RaiseEmpty();
events.DayStarted.RaiseEmpty(); events.DayStarted.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_AfterLoad.Raise();
events.Legacy_AfterDayStarted.Raise();
#endif
} }
/********* /*********
@ -549,9 +508,6 @@ namespace StardewModdingAPI.Framework
Point newSize = this.Watchers.WindowSizeWatcher.CurrentValue; Point newSize = this.Watchers.WindowSizeWatcher.CurrentValue;
events.WindowResized.Raise(new WindowResizedEventArgs(oldSize, newSize)); events.WindowResized.Raise(new WindowResizedEventArgs(oldSize, newSize));
#if !SMAPI_3_0_STRICT
events.Legacy_Resize.Raise();
#endif
this.Watchers.WindowSizeWatcher.Reset(); this.Watchers.WindowSizeWatcher.Reset();
} }
@ -610,23 +566,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Events: button {button} pressed.", LogLevel.Trace); this.Monitor.Log($"Events: button {button} pressed.", LogLevel.Trace);
events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState)); events.ButtonPressed.Raise(new ButtonPressedEventArgs(button, cursor, inputState));
#if !SMAPI_3_0_STRICT
// legacy events
events.Legacy_ButtonPressed.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons));
if (button.TryGetKeyboard(out Keys key))
{
if (key != Keys.None)
events.Legacy_KeyPressed.Raise(new EventArgsKeyPressed(key));
}
else if (button.TryGetController(out Buttons controllerButton))
{
if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
events.Legacy_ControllerTriggerPressed.Raise(new EventArgsControllerTriggerPressed(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right));
else
events.Legacy_ControllerButtonPressed.Raise(new EventArgsControllerButtonPressed(PlayerIndex.One, controllerButton));
}
#endif
} }
else if (status == InputStatus.Released) else if (status == InputStatus.Released)
{ {
@ -634,33 +573,8 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Events: button {button} released.", LogLevel.Trace); this.Monitor.Log($"Events: button {button} released.", LogLevel.Trace);
events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState)); events.ButtonReleased.Raise(new ButtonReleasedEventArgs(button, cursor, inputState));
#if !SMAPI_3_0_STRICT
// legacy events
events.Legacy_ButtonReleased.Raise(new EventArgsInput(button, cursor, inputState.SuppressButtons));
if (button.TryGetKeyboard(out Keys key))
{
if (key != Keys.None)
events.Legacy_KeyReleased.Raise(new EventArgsKeyPressed(key));
}
else if (button.TryGetController(out Buttons controllerButton))
{
if (controllerButton == Buttons.LeftTrigger || controllerButton == Buttons.RightTrigger)
events.Legacy_ControllerTriggerReleased.Raise(new EventArgsControllerTriggerReleased(PlayerIndex.One, controllerButton, controllerButton == Buttons.LeftTrigger ? inputState.RealController.Triggers.Left : inputState.RealController.Triggers.Right));
else
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)
events.Legacy_KeyboardChanged.Raise(new EventArgsKeyboardStateChanged(previousInputState.RealKeyboard, inputState.RealKeyboard));
if (inputState.RealMouse != previousInputState.RealMouse)
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
} }
} }
@ -678,12 +592,6 @@ namespace StardewModdingAPI.Framework
// raise menu events // raise menu events
events.MenuChanged.Raise(new MenuChangedEventArgs(was, now)); events.MenuChanged.Raise(new MenuChangedEventArgs(was, now));
#if !SMAPI_3_0_STRICT
if (now != null)
events.Legacy_MenuChanged.Raise(new EventArgsClickableMenuChanged(was, now));
else
events.Legacy_MenuClosed.Raise(new EventArgsClickableMenuClosed(was));
#endif
} }
/********* /*********
@ -711,9 +619,6 @@ namespace StardewModdingAPI.Framework
} }
events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed)); events.LocationListChanged.Raise(new LocationListChangedEventArgs(added, removed));
#if !SMAPI_3_0_STRICT
events.Legacy_LocationsChanged.Raise(new EventArgsLocationsChanged(added, removed));
#endif
} }
// raise location contents changed // raise location contents changed
@ -730,9 +635,6 @@ namespace StardewModdingAPI.Framework
watcher.BuildingsWatcher.Reset(); watcher.BuildingsWatcher.Reset();
events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, added, removed)); events.BuildingListChanged.Raise(new BuildingListChangedEventArgs(location, added, removed));
#if !SMAPI_3_0_STRICT
events.Legacy_BuildingsChanged.Raise(new EventArgsLocationBuildingsChanged(location, added, removed));
#endif
} }
// debris changed // debris changed
@ -777,9 +679,6 @@ namespace StardewModdingAPI.Framework
watcher.ObjectsWatcher.Reset(); watcher.ObjectsWatcher.Reset();
events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, added, removed)); events.ObjectListChanged.Raise(new ObjectListChangedEventArgs(location, added, removed));
#if !SMAPI_3_0_STRICT
events.Legacy_ObjectsChanged.Raise(new EventArgsLocationObjectsChanged(location, added, removed));
#endif
} }
// terrain features changed // terrain features changed
@ -809,9 +708,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Events: time changed from {was} to {now}.", LogLevel.Trace); this.Monitor.Log($"Events: time changed from {was} to {now}.", LogLevel.Trace);
events.TimeChanged.Raise(new TimeChangedEventArgs(was, now)); events.TimeChanged.Raise(new TimeChangedEventArgs(was, now));
#if !SMAPI_3_0_STRICT
events.Legacy_TimeOfDayChanged.Raise(new EventArgsIntChanged(was, now));
#endif
} }
else else
this.Watchers.TimeWatcher.Reset(); this.Watchers.TimeWatcher.Reset();
@ -829,9 +725,6 @@ namespace StardewModdingAPI.Framework
GameLocation oldLocation = playerTracker.LocationWatcher.PreviousValue; GameLocation oldLocation = playerTracker.LocationWatcher.PreviousValue;
events.Warped.Raise(new WarpedEventArgs(playerTracker.Player, oldLocation, newLocation)); events.Warped.Raise(new WarpedEventArgs(playerTracker.Player, oldLocation, newLocation));
#if !SMAPI_3_0_STRICT
events.Legacy_PlayerWarped.Raise(new EventArgsPlayerWarped(oldLocation, newLocation));
#endif
} }
// raise player leveled up a skill // raise player leveled up a skill
@ -841,9 +734,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log($"Events: player skill '{pair.Key}' changed from {pair.Value.PreviousValue} to {pair.Value.CurrentValue}.", LogLevel.Trace); this.Monitor.Log($"Events: player skill '{pair.Key}' changed from {pair.Value.PreviousValue} to {pair.Value.CurrentValue}.", LogLevel.Trace);
events.LevelChanged.Raise(new LevelChangedEventArgs(playerTracker.Player, pair.Key, pair.Value.PreviousValue, pair.Value.CurrentValue)); events.LevelChanged.Raise(new LevelChangedEventArgs(playerTracker.Player, pair.Key, pair.Value.PreviousValue, pair.Value.CurrentValue));
#if !SMAPI_3_0_STRICT
events.Legacy_LeveledUp.Raise(new EventArgsLevelUp((EventArgsLevelUp.LevelType)pair.Key, pair.Value.CurrentValue));
#endif
} }
// raise player inventory changed // raise player inventory changed
@ -853,9 +743,6 @@ namespace StardewModdingAPI.Framework
if (this.Monitor.IsVerbose) if (this.Monitor.IsVerbose)
this.Monitor.Log("Events: player inventory changed.", LogLevel.Trace); this.Monitor.Log("Events: player inventory changed.", LogLevel.Trace);
events.InventoryChanged.Raise(new InventoryChangedEventArgs(playerTracker.Player, changedItems)); events.InventoryChanged.Raise(new InventoryChangedEventArgs(playerTracker.Player, changedItems));
#if !SMAPI_3_0_STRICT
events.Legacy_InventoryChanged.Raise(new EventArgsInventoryChanged(Game1.player.Items, changedItems));
#endif
} }
// raise mine level changed // raise mine level changed
@ -863,9 +750,6 @@ namespace StardewModdingAPI.Framework
{ {
if (this.Monitor.IsVerbose) if (this.Monitor.IsVerbose)
this.Monitor.Log($"Context: mine level changed to {mineLevel}.", LogLevel.Trace); this.Monitor.Log($"Context: mine level changed to {mineLevel}.", LogLevel.Trace);
#if !SMAPI_3_0_STRICT
events.Legacy_MineLevelChanged.Raise(new EventArgsMineLevelChanged(playerTracker.MineLevelWatcher.PreviousValue, mineLevel));
#endif
} }
} }
this.Watchers.CurrentPlayerTracker?.Reset(); this.Watchers.CurrentPlayerTracker?.Reset();
@ -910,25 +794,6 @@ namespace StardewModdingAPI.Framework
/********* /*********
** Update events ** Update events
*********/ *********/
#if !SMAPI_3_0_STRICT
events.Legacy_UnvalidatedUpdateTick.Raise();
if (isFirstTick)
events.Legacy_FirstUpdateTick.Raise();
events.Legacy_UpdateTick.Raise();
if (SGame.TicksElapsed % 2 == 0)
events.Legacy_SecondUpdateTick.Raise();
if (SGame.TicksElapsed % 4 == 0)
events.Legacy_FourthUpdateTick.Raise();
if (SGame.TicksElapsed % 8 == 0)
events.Legacy_EighthUpdateTick.Raise();
if (SGame.TicksElapsed % 15 == 0)
events.Legacy_QuarterSecondTick.Raise();
if (SGame.TicksElapsed % 30 == 0)
events.Legacy_HalfSecondTick.Raise();
if (SGame.TicksElapsed % 60 == 0)
events.Legacy_OneSecondTick.Raise();
#endif
this.UpdateCrashTimer.Reset(); this.UpdateCrashTimer.Reset();
} }
catch (Exception ex) catch (Exception ex)
@ -1014,14 +879,8 @@ namespace StardewModdingAPI.Framework
try try
{ {
events.RenderingActiveMenu.RaiseEmpty(); events.RenderingActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderGuiEvent.Raise();
#endif
activeClickableMenu.draw(Game1.spriteBatch); activeClickableMenu.draw(Game1.spriteBatch);
events.RenderedActiveMenu.RaiseEmpty(); events.RenderedActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderGuiEvent.Raise();
#endif
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1029,10 +888,6 @@ namespace StardewModdingAPI.Framework
activeClickableMenu.exitThisMenu(); activeClickableMenu.exitThisMenu();
} }
events.Rendered.RaiseEmpty(); events.Rendered.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderEvent.Raise();
#endif
Game1.spriteBatch.End(); Game1.spriteBatch.End();
} }
if (Game1.overlayMenu != null) if (Game1.overlayMenu != null)
@ -1055,14 +910,8 @@ namespace StardewModdingAPI.Framework
{ {
Game1.activeClickableMenu.drawBackground(Game1.spriteBatch); Game1.activeClickableMenu.drawBackground(Game1.spriteBatch);
events.RenderingActiveMenu.RaiseEmpty(); events.RenderingActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderGuiEvent.Raise();
#endif
Game1.activeClickableMenu.draw(Game1.spriteBatch); Game1.activeClickableMenu.draw(Game1.spriteBatch);
events.RenderedActiveMenu.RaiseEmpty(); events.RenderedActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderGuiEvent.Raise();
#endif
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1070,9 +919,6 @@ namespace StardewModdingAPI.Framework
Game1.activeClickableMenu.exitThisMenu(); Game1.activeClickableMenu.exitThisMenu();
} }
events.Rendered.RaiseEmpty(); events.Rendered.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderEvent.Raise();
#endif
Game1.spriteBatch.End(); Game1.spriteBatch.End();
this.drawOverlays(Game1.spriteBatch); this.drawOverlays(Game1.spriteBatch);
if ((double)Game1.options.zoomLevel != 1.0) if ((double)Game1.options.zoomLevel != 1.0)
@ -1097,9 +943,6 @@ 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.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); Game1.spriteBatch.DrawString(Game1.dialogueFont, Game1.parseText(Game1.errorMessage, Game1.dialogueFont, Game1.graphics.GraphicsDevice.Viewport.Width), new Vector2(16f, 48f), Color.White);
events.Rendered.RaiseEmpty(); events.Rendered.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderEvent.Raise();
#endif
Game1.spriteBatch.End(); Game1.spriteBatch.End();
} }
else if (Game1.currentMinigame != null) else if (Game1.currentMinigame != null)
@ -1112,9 +955,6 @@ namespace StardewModdingAPI.Framework
Game1.spriteBatch.End(); Game1.spriteBatch.End();
} }
this.drawOverlays(Game1.spriteBatch); this.drawOverlays(Game1.spriteBatch);
#if !SMAPI_3_0_STRICT
this.RaisePostRender(needsNewBatch: true);
#endif
if ((double)Game1.options.zoomLevel == 1.0) if ((double)Game1.options.zoomLevel == 1.0)
return; return;
this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null);
@ -1132,14 +972,8 @@ namespace StardewModdingAPI.Framework
try try
{ {
events.RenderingActiveMenu.RaiseEmpty(); events.RenderingActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderGuiEvent.Raise();
#endif
Game1.activeClickableMenu.draw(Game1.spriteBatch); Game1.activeClickableMenu.draw(Game1.spriteBatch);
events.RenderedActiveMenu.RaiseEmpty(); events.RenderedActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderGuiEvent.Raise();
#endif
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1229,9 +1063,6 @@ namespace StardewModdingAPI.Framework
if (++batchOpens == 1) if (++batchOpens == 1)
events.Rendering.RaiseEmpty(); events.Rendering.RaiseEmpty();
events.RenderingWorld.RaiseEmpty(); events.RenderingWorld.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderEvent.Raise();
#endif
if (Game1.background != null) if (Game1.background != null)
Game1.background.draw(Game1.spriteBatch); Game1.background.draw(Game1.spriteBatch);
Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch); Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch);
@ -1389,7 +1220,7 @@ namespace StardewModdingAPI.Framework
} }
Game1.drawPlayerHeldObject(Game1.player); Game1.drawPlayerHeldObject(Game1.player);
} }
label_129: label_129:
if ((Game1.player.UsingTool || Game1.pickingTool) && Game1.player.CurrentTool != null && ((!Game1.player.CurrentTool.Name.Equals("Seeds") || Game1.pickingTool) && (Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), (int)Game1.player.Position.Y - 38), Game1.viewport.Size) != null && Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), Game1.player.getStandingY()), Game1.viewport.Size) == null))) if ((Game1.player.UsingTool || Game1.pickingTool) && Game1.player.CurrentTool != null && ((!Game1.player.CurrentTool.Name.Equals("Seeds") || Game1.pickingTool) && (Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), (int)Game1.player.Position.Y - 38), Game1.viewport.Size) != null && Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), Game1.player.getStandingY()), Game1.viewport.Size) == null)))
Game1.drawTool(Game1.player); Game1.drawTool(Game1.player);
if (Game1.currentLocation.Map.GetLayer("AlwaysFront") != null) if (Game1.currentLocation.Map.GetLayer("AlwaysFront") != null)
@ -1544,14 +1375,8 @@ namespace StardewModdingAPI.Framework
if ((Game1.displayHUD || Game1.eventUp) && (Game1.currentBillboard == 0 && Game1.gameMode == (byte)3) && (!Game1.freezeControls && !Game1.panMode && !Game1.HostPaused)) if ((Game1.displayHUD || Game1.eventUp) && (Game1.currentBillboard == 0 && Game1.gameMode == (byte)3) && (!Game1.freezeControls && !Game1.panMode && !Game1.HostPaused))
{ {
events.RenderingHud.RaiseEmpty(); events.RenderingHud.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderHudEvent.Raise();
#endif
this.drawHUD(); this.drawHUD();
events.RenderedHud.RaiseEmpty(); events.RenderedHud.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderHudEvent.Raise();
#endif
} }
else if (Game1.activeClickableMenu == null && Game1.farmEvent == null) 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); 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);
@ -1660,14 +1485,8 @@ namespace StardewModdingAPI.Framework
try try
{ {
events.RenderingActiveMenu.RaiseEmpty(); events.RenderingActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPreRenderGuiEvent.Raise();
#endif
Game1.activeClickableMenu.draw(Game1.spriteBatch); Game1.activeClickableMenu.draw(Game1.spriteBatch);
events.RenderedActiveMenu.RaiseEmpty(); events.RenderedActiveMenu.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderGuiEvent.Raise();
#endif
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1684,9 +1503,6 @@ namespace StardewModdingAPI.Framework
} }
events.Rendered.RaiseEmpty(); events.Rendered.RaiseEmpty();
#if !SMAPI_3_0_STRICT
events.Legacy_OnPostRenderEvent.Raise();
#endif
Game1.spriteBatch.End(); Game1.spriteBatch.End();
this.drawOverlays(Game1.spriteBatch); this.drawOverlays(Game1.spriteBatch);
this.renderScreenBuffer(); this.renderScreenBuffer();
@ -1694,24 +1510,5 @@ namespace StardewModdingAPI.Framework
} }
} }
} }
/****
** Methods
****/
#if !SMAPI_3_0_STRICT
/// <summary>Raise the <see cref="GraphicsEvents.OnPostRenderEvent"/> if there are any listeners.</summary>
/// <param name="needsNewBatch">Whether to create a new sprite batch.</param>
private void RaisePostRender(bool needsNewBatch = false)
{
if (this.Events.Legacy_OnPostRenderEvent.HasListeners())
{
if (needsNewBatch)
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
this.Events.Legacy_OnPostRenderEvent.Raise();
if (needsNewBatch)
Game1.spriteBatch.End();
}
}
#endif
} }
} }

View File

@ -89,24 +89,6 @@ namespace StardewModdingAPI.Framework
this.HostPeer = null; this.HostPeer = null;
} }
#if !SMAPI_3_0_STRICT
/// <summary>Handle sync messages from other players and perform other initial sync logic.</summary>
public override void UpdateEarly()
{
this.EventManager.Legacy_BeforeMainSync.Raise();
base.UpdateEarly();
this.EventManager.Legacy_AfterMainSync.Raise();
}
/// <summary>Broadcast sync messages to other players and perform other final sync logic.</summary>
public override void UpdateLate(bool forceSync = false)
{
this.EventManager.Legacy_BeforeMainBroadcast.Raise();
base.UpdateLate(forceSync);
this.EventManager.Legacy_AfterMainBroadcast.Raise();
}
#endif
/// <summary>Initialise a client before the game connects to a remote server.</summary> /// <summary>Initialise a client before the game connects to a remote server.</summary>
/// <param name="client">The client to initialise.</param> /// <param name="client">The client to initialise.</param>
public override Client InitClient(Client client) public override Client InitClient(Client client)

View File

@ -1,32 +1,7 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using StardewModdingAPI.Framework.Content;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
/// <summary>Encapsulates access and changes to dictionary content being read from a data file.</summary> /// <summary>Encapsulates access and changes to dictionary content being read from a data file.</summary>
public interface IAssetDataForDictionary<TKey, TValue> : IAssetData<IDictionary<TKey, TValue>> public interface IAssetDataForDictionary<TKey, TValue> : IAssetData<IDictionary<TKey, TValue>> { }
{
#if !SMAPI_3_0_STRICT
/*********
** Public methods
*********/
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">The entry value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(TKey key, TValue value);
/// <summary>Add or replace an entry in the dictionary.</summary>
/// <param name="key">The entry key.</param>
/// <param name="value">A callback which accepts the current value and returns the new value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(TKey key, Func<TValue, TValue> value);
/// <summary>Dynamically replace values in the dictionary.</summary>
/// <param name="replacer">A lambda which takes the current key and value for an entry, and returns the new value.</param>
[Obsolete("Access " + nameof(AssetData<IDictionary<TKey, TValue>>.Data) + "field directly.")]
void Set(Func<TKey, TValue, TValue> replacer);
#endif
}
} }

View File

@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using StardewModdingAPI.Events; using StardewModdingAPI.Events;
namespace StardewModdingAPI namespace StardewModdingAPI
@ -58,41 +56,5 @@ namespace StardewModdingAPI
/// <typeparam name="TConfig">The config class type.</typeparam> /// <typeparam name="TConfig">The config class type.</typeparam>
/// <param name="config">The config settings to save.</param> /// <param name="config">The config settings to save.</param>
void WriteConfig<TConfig>(TConfig config) where TConfig : class, new(); void WriteConfig<TConfig>(TConfig config) where TConfig : class, new();
#if !SMAPI_3_0_STRICT
/****
** Generic JSON files
****/
/// <summary>Read a JSON file.</summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <param name="path">The file path relative to the mod directory.</param>
/// <returns>Returns the deserialised model, or <c>null</c> if the file doesn't exist or is empty.</returns>
[Obsolete("Use " + nameof(IModHelper.Data) + "." + nameof(IDataHelper.ReadJsonFile) + " instead")]
TModel ReadJsonFile<TModel>(string path) where TModel : class;
/// <summary>Save to a JSON file.</summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <param name="path">The file path relative to the mod directory.</param>
/// <param name="model">The model to save.</param>
[Obsolete("Use " + nameof(IModHelper.Data) + "." + nameof(IDataHelper.WriteJsonFile) + " instead")]
void WriteJsonFile<TModel>(string path, TModel model) where TModel : class;
/****
** Content packs
****/
/// <summary>Manually create a transitional content pack to support pre-SMAPI content packs. This provides a way to access legacy content packs using the SMAPI content pack APIs, but the content pack will not be visible in the log or validated by SMAPI.</summary>
/// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
/// <param name="id">The content pack's unique ID.</param>
/// <param name="name">The content pack name.</param>
/// <param name="description">The content pack description.</param>
/// <param name="author">The content pack author's name.</param>
/// <param name="version">The content pack version.</param>
[Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.CreateTemporary) + " instead")]
IContentPack CreateTransitionalContentPack(string directoryPath, string id, string name, string description, string author, ISemanticVersion version);
/// <summary>Get all content packs loaded for this mod.</summary>
[Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ContentPacks) + "." + nameof(IContentPackHelper.GetOwned) + " instead")]
IEnumerable<IContentPack> GetContentPacks();
#endif
} }
} }

View File

@ -53,9 +53,6 @@ namespace StardewModdingAPI.Metadata
yield return new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.locationSerializer), InstructionHandleResult.DetectedSaveSerialiser); yield return new FieldFinder(typeof(SaveGame).FullName, nameof(SaveGame.locationSerializer), InstructionHandleResult.DetectedSaveSerialiser);
yield return new EventFinder(typeof(ISpecialisedEvents).FullName, nameof(ISpecialisedEvents.UnvalidatedUpdateTicked), InstructionHandleResult.DetectedUnvalidatedUpdateTick); yield return new EventFinder(typeof(ISpecialisedEvents).FullName, nameof(ISpecialisedEvents.UnvalidatedUpdateTicked), InstructionHandleResult.DetectedUnvalidatedUpdateTick);
yield return new EventFinder(typeof(ISpecialisedEvents).FullName, nameof(ISpecialisedEvents.UnvalidatedUpdateTicking), InstructionHandleResult.DetectedUnvalidatedUpdateTick); yield return new EventFinder(typeof(ISpecialisedEvents).FullName, nameof(ISpecialisedEvents.UnvalidatedUpdateTicking), InstructionHandleResult.DetectedUnvalidatedUpdateTick);
#if !SMAPI_3_0_STRICT
yield return new EventFinder(typeof(SpecialisedEvents).FullName, nameof(SpecialisedEvents.UnvalidatedUpdateTick), InstructionHandleResult.DetectedUnvalidatedUpdateTick);
#endif
/**** /****
** detect paranoid issues ** detect paranoid issues

View File

@ -1,6 +1,5 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -26,19 +25,6 @@ namespace StardewModdingAPI
/// <summary>The patch version for backwards-compatible bug fixes.</summary> /// <summary>The patch version for backwards-compatible bug fixes.</summary>
public int PatchVersion => this.Version.PatchVersion; public int PatchVersion => this.Version.PatchVersion;
#if !SMAPI_3_0_STRICT
/// <summary>An optional build tag.</summary>
[Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")]
public string Build
{
get
{
SCore.DeprecationManager?.Warn($"{nameof(ISemanticVersion)}.{nameof(ISemanticVersion.Build)}", "2.8", DeprecationLevel.PendingRemoval);
return this.Version.PrereleaseTag;
}
}
#endif
/// <summary>An optional prerelease tag.</summary> /// <summary>An optional prerelease tag.</summary>
public string PrereleaseTag => this.Version.PrereleaseTag; public string PrereleaseTag => this.Version.PrereleaseTag;

View File

@ -83,40 +83,16 @@
<Compile Include="Events\ButtonPressedEventArgs.cs" /> <Compile Include="Events\ButtonPressedEventArgs.cs" />
<Compile Include="Events\ButtonReleasedEventArgs.cs" /> <Compile Include="Events\ButtonReleasedEventArgs.cs" />
<Compile Include="Events\ChangeType.cs" /> <Compile Include="Events\ChangeType.cs" />
<Compile Include="Events\ContentEvents.cs" />
<Compile Include="Events\ControlEvents.cs" />
<Compile Include="Events\CursorMovedEventArgs.cs" /> <Compile Include="Events\CursorMovedEventArgs.cs" />
<Compile Include="Events\DayEndingEventArgs.cs" /> <Compile Include="Events\DayEndingEventArgs.cs" />
<Compile Include="Events\DayStartedEventArgs.cs" /> <Compile Include="Events\DayStartedEventArgs.cs" />
<Compile Include="Events\DebrisListChangedEventArgs.cs" /> <Compile Include="Events\DebrisListChangedEventArgs.cs" />
<Compile Include="Events\EventArgsClickableMenuChanged.cs" />
<Compile Include="Events\EventArgsClickableMenuClosed.cs" />
<Compile Include="Events\EventArgsControllerButtonPressed.cs" />
<Compile Include="Events\EventArgsControllerButtonReleased.cs" />
<Compile Include="Events\EventArgsControllerTriggerPressed.cs" />
<Compile Include="Events\EventArgsControllerTriggerReleased.cs" />
<Compile Include="Events\EventArgsInput.cs" />
<Compile Include="Events\EventArgsIntChanged.cs" />
<Compile Include="Events\EventArgsInventoryChanged.cs" />
<Compile Include="Events\EventArgsKeyboardStateChanged.cs" />
<Compile Include="Events\EventArgsKeyPressed.cs" />
<Compile Include="Events\EventArgsLevelUp.cs" />
<Compile Include="Events\EventArgsLocationBuildingsChanged.cs" />
<Compile Include="Events\EventArgsLocationObjectsChanged.cs" />
<Compile Include="Events\EventArgsLocationsChanged.cs" />
<Compile Include="Events\EventArgsMineLevelChanged.cs" />
<Compile Include="Events\EventArgsMouseStateChanged.cs" />
<Compile Include="Events\EventArgsPlayerWarped.cs" />
<Compile Include="Events\EventArgsValueChanged.cs" />
<Compile Include="Events\GameEvents.cs" />
<Compile Include="Events\GameLaunchedEventArgs.cs" /> <Compile Include="Events\GameLaunchedEventArgs.cs" />
<Compile Include="Events\GraphicsEvents.cs" />
<Compile Include="Events\IDisplayEvents.cs" /> <Compile Include="Events\IDisplayEvents.cs" />
<Compile Include="Events\IGameLoopEvents.cs" /> <Compile Include="Events\IGameLoopEvents.cs" />
<Compile Include="Events\IInputEvents.cs" /> <Compile Include="Events\IInputEvents.cs" />
<Compile Include="Events\IModEvents.cs" /> <Compile Include="Events\IModEvents.cs" />
<Compile Include="Events\IMultiplayerEvents.cs" /> <Compile Include="Events\IMultiplayerEvents.cs" />
<Compile Include="Events\InputEvents.cs" />
<Compile Include="Events\InventoryChangedEventArgs.cs" /> <Compile Include="Events\InventoryChangedEventArgs.cs" />
<Compile Include="Events\IPlayerEvents.cs" /> <Compile Include="Events\IPlayerEvents.cs" />
<Compile Include="Events\ISpecialisedEvents.cs" /> <Compile Include="Events\ISpecialisedEvents.cs" />
@ -126,21 +102,16 @@
<Compile Include="Events\LargeTerrainFeatureListChangedEventArgs.cs" /> <Compile Include="Events\LargeTerrainFeatureListChangedEventArgs.cs" />
<Compile Include="Events\LevelChangedEventArgs.cs" /> <Compile Include="Events\LevelChangedEventArgs.cs" />
<Compile Include="Events\LoadStageChangedEventArgs.cs" /> <Compile Include="Events\LoadStageChangedEventArgs.cs" />
<Compile Include="Events\LocationEvents.cs" />
<Compile Include="Events\LocationListChangedEventArgs.cs" /> <Compile Include="Events\LocationListChangedEventArgs.cs" />
<Compile Include="Events\MenuChangedEventArgs.cs" /> <Compile Include="Events\MenuChangedEventArgs.cs" />
<Compile Include="Events\MenuEvents.cs" />
<Compile Include="Events\MineEvents.cs" />
<Compile Include="Events\ModMessageReceivedEventArgs.cs" /> <Compile Include="Events\ModMessageReceivedEventArgs.cs" />
<Compile Include="Events\MouseWheelScrolledEventArgs.cs" /> <Compile Include="Events\MouseWheelScrolledEventArgs.cs" />
<Compile Include="Events\MultiplayerEvents.cs" />
<Compile Include="Events\NpcListChangedEventArgs.cs" /> <Compile Include="Events\NpcListChangedEventArgs.cs" />
<Compile Include="Events\ObjectListChangedEventArgs.cs" /> <Compile Include="Events\ObjectListChangedEventArgs.cs" />
<Compile Include="Events\OneSecondUpdateTickedEventArgs.cs" /> <Compile Include="Events\OneSecondUpdateTickedEventArgs.cs" />
<Compile Include="Events\OneSecondUpdateTickingEventArgs.cs" /> <Compile Include="Events\OneSecondUpdateTickingEventArgs.cs" />
<Compile Include="Events\PeerContextReceivedEventArgs.cs" /> <Compile Include="Events\PeerContextReceivedEventArgs.cs" />
<Compile Include="Events\PeerDisconnectedEventArgs.cs" /> <Compile Include="Events\PeerDisconnectedEventArgs.cs" />
<Compile Include="Events\PlayerEvents.cs" />
<Compile Include="Events\RenderedActiveMenuEventArgs.cs" /> <Compile Include="Events\RenderedActiveMenuEventArgs.cs" />
<Compile Include="Events\RenderedEventArgs.cs" /> <Compile Include="Events\RenderedEventArgs.cs" />
<Compile Include="Events\RenderedHudEventArgs.cs" /> <Compile Include="Events\RenderedHudEventArgs.cs" />
@ -153,13 +124,10 @@
<Compile Include="Events\SaveCreatedEventArgs.cs" /> <Compile Include="Events\SaveCreatedEventArgs.cs" />
<Compile Include="Events\SaveCreatingEventArgs.cs" /> <Compile Include="Events\SaveCreatingEventArgs.cs" />
<Compile Include="Events\SavedEventArgs.cs" /> <Compile Include="Events\SavedEventArgs.cs" />
<Compile Include="Events\SaveEvents.cs" />
<Compile Include="Events\SaveLoadedEventArgs.cs" /> <Compile Include="Events\SaveLoadedEventArgs.cs" />
<Compile Include="Events\SavingEventArgs.cs" /> <Compile Include="Events\SavingEventArgs.cs" />
<Compile Include="Events\SpecialisedEvents.cs" />
<Compile Include="Events\TerrainFeatureListChangedEventArgs.cs" /> <Compile Include="Events\TerrainFeatureListChangedEventArgs.cs" />
<Compile Include="Events\TimeChangedEventArgs.cs" /> <Compile Include="Events\TimeChangedEventArgs.cs" />
<Compile Include="Events\TimeEvents.cs" />
<Compile Include="Events\UnvalidatedUpdateTickedEventArgs.cs" /> <Compile Include="Events\UnvalidatedUpdateTickedEventArgs.cs" />
<Compile Include="Events\UnvalidatedUpdateTickingEventArgs.cs" /> <Compile Include="Events\UnvalidatedUpdateTickingEventArgs.cs" />
<Compile Include="Events\UpdateTickedEventArgs.cs" /> <Compile Include="Events\UpdateTickedEventArgs.cs" />
@ -169,7 +137,6 @@
<Compile Include="Framework\DeprecationWarning.cs" /> <Compile Include="Framework\DeprecationWarning.cs" />
<Compile Include="Framework\Events\EventManager.cs" /> <Compile Include="Framework\Events\EventManager.cs" />
<Compile Include="Framework\Events\ManagedEvent.cs" /> <Compile Include="Framework\Events\ManagedEvent.cs" />
<Compile Include="Framework\Events\ManagedEventBase.cs" />
<Compile Include="Framework\Events\ModDisplayEvents.cs" /> <Compile Include="Framework\Events\ModDisplayEvents.cs" />
<Compile Include="Framework\Events\ModEvents.cs" /> <Compile Include="Framework\Events\ModEvents.cs" />
<Compile Include="Framework\Events\ModEventsBase.cs" /> <Compile Include="Framework\Events\ModEventsBase.cs" />

View File

@ -17,12 +17,6 @@ namespace StardewModdingAPI
/// <summary>The patch version for backwards-compatible bug fixes.</summary> /// <summary>The patch version for backwards-compatible bug fixes.</summary>
int PatchVersion { get; } int PatchVersion { get; }
#if !SMAPI_3_0_STRICT
/// <summary>An optional build tag.</summary>
[Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")]
string Build { get; }
#endif
/// <summary>An optional prerelease tag.</summary> /// <summary>An optional prerelease tag.</summary>
string PrereleaseTag { get; } string PrereleaseTag { get; }

View File

@ -42,15 +42,6 @@ namespace StardewModdingAPI.Toolkit
/// <summary>An optional prerelease tag.</summary> /// <summary>An optional prerelease tag.</summary>
public string PrereleaseTag { get; } public string PrereleaseTag { get; }
#if !SMAPI_3_0_STRICT
/// <summary>An optional prerelease tag.</summary>
[Obsolete("Use " + nameof(ISemanticVersion.PrereleaseTag) + " instead")]
public string Build => this.PrereleaseTag;
/// <summary>Whether the version was parsed from the legacy object format.</summary>
public bool IsLegacyFormat { get; }
#endif
/********* /*********
** Public methods ** Public methods
@ -60,20 +51,12 @@ namespace StardewModdingAPI.Toolkit
/// <param name="minor">The minor version incremented for backwards-compatible changes.</param> /// <param name="minor">The minor version incremented for backwards-compatible changes.</param>
/// <param name="patch">The patch version for backwards-compatible fixes.</param> /// <param name="patch">The patch version for backwards-compatible fixes.</param>
/// <param name="prereleaseTag">An optional prerelease tag.</param> /// <param name="prereleaseTag">An optional prerelease tag.</param>
/// <param name="isLegacyFormat">Whether the version was parsed from the legacy object format.</param> public SemanticVersion(int major, int minor, int patch, string prereleaseTag = null)
public SemanticVersion(int major, int minor, int patch, string prereleaseTag = null
#if !SMAPI_3_0_STRICT
, bool isLegacyFormat = false
#endif
)
{ {
this.MajorVersion = major; this.MajorVersion = major;
this.MinorVersion = minor; this.MinorVersion = minor;
this.PatchVersion = patch; this.PatchVersion = patch;
this.PrereleaseTag = this.GetNormalisedTag(prereleaseTag); this.PrereleaseTag = this.GetNormalisedTag(prereleaseTag);
#if !SMAPI_3_0_STRICT
this.IsLegacyFormat = isLegacyFormat;
#endif
this.AssertValid(); this.AssertValid();
} }

View File

@ -67,20 +67,8 @@ namespace StardewModdingAPI.Toolkit.Serialisation.Converters
int minor = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.MinorVersion)); int minor = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.MinorVersion));
int patch = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.PatchVersion)); int patch = obj.ValueIgnoreCase<int>(nameof(ISemanticVersion.PatchVersion));
string prereleaseTag = obj.ValueIgnoreCase<string>(nameof(ISemanticVersion.PrereleaseTag)); string prereleaseTag = obj.ValueIgnoreCase<string>(nameof(ISemanticVersion.PrereleaseTag));
#if !SMAPI_3_0_STRICT
if (string.IsNullOrWhiteSpace(prereleaseTag))
{
prereleaseTag = obj.ValueIgnoreCase<string>("Build");
if (prereleaseTag == "0")
prereleaseTag = null; // '0' from incorrect examples in old SMAPI documentation
}
#endif
return new SemanticVersion(major, minor, patch, prereleaseTag return new SemanticVersion(major, minor, patch, prereleaseTag);
#if !SMAPI_3_0_STRICT
, isLegacyFormat: true
#endif
);
} }
/// <summary>Read a JSON string.</summary> /// <summary>Read a JSON string.</summary>