Remove SMAPI folder

This commit is contained in:
Chris 2019-05-24 03:26:45 -04:00
parent a73e416e32
commit 6c33ddacd9
282 changed files with 0 additions and 24775 deletions

View File

@ -1,238 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using StardewModdingAPI.Enums;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Internal;
using StardewValley;
namespace StardewModdingAPI
{
/// <summary>Contains SMAPI's constants and assumptions.</summary>
public static class Constants
{
/*********
** Accessors
*********/
/****
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("2.11.2");
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.3.36");
/// <summary>The maximum supported version of Stardew Valley.</summary>
public static ISemanticVersion MaximumGameVersion { get; } = new GameVersion("1.3.36");
/// <summary>The target game platform.</summary>
public static GamePlatform TargetPlatform => (GamePlatform)Constants.Platform;
/// <summary>The path to the game folder.</summary>
public static string ExecutionPath { get; } = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "StardewValley");
/// <summary>The directory path containing Stardew Valley's app data.</summary>
public static string DataPath { get; } = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "StardewValley");
/// <summary>The directory path in which error logs should be stored.</summary>
public static string LogDir { get; } = Path.Combine(Constants.DataPath, "ErrorLogs");
/// <summary>The directory path where all saves are stored.</summary>
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>
public static string SaveFolderName
{
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>
public static string CurrentSavePath
{
get
{
return Constants.GetSaveFolderPathIfExists()
#if SMAPI_3_0_STRICT
;
#else
?? "";
#endif
}
}
/****
** Internal
****/
/// <summary>The URL of the SMAPI home page.</summary>
internal const string HomePageUrl = "https://smapi.io";
/// <summary>The absolute path to the folder containing SMAPI's internal files.</summary>
internal static readonly string InternalFilesPath = Program.DllSearchPath;
/// <summary>The file path for the SMAPI configuration file.</summary>
internal static string ApiConfigPath => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.config.json");
/// <summary>The file path for the SMAPI metadata file.</summary>
internal static string ApiMetadataPath => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.metadata.json");
/// <summary>The filename prefix used for all SMAPI logs.</summary>
internal static string LogNamePrefix { get; } = "SMAPI-";
/// <summary>The filename for SMAPI's main log, excluding the <see cref="LogExtension"/>.</summary>
internal static string LogFilename { get; } = $"{Constants.LogNamePrefix}latest";
/// <summary>The filename extension for SMAPI log files.</summary>
internal static string LogExtension { get; } = "txt";
/// <summary>The file path for the log containing the previous fatal crash, if any.</summary>
internal static string FatalCrashLog => Path.Combine(Constants.LogDir, "SMAPI-crash.txt");
/// <summary>The file path which stores a fatal crash message for the next run.</summary>
internal static string FatalCrashMarker => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.crash.marker");
/// <summary>The file path which stores the detected update version for the next run.</summary>
internal static string UpdateMarker => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.update.marker");
/// <summary>The default full path to search for mods.</summary>
internal static string DefaultModsPath { get; } = Path.Combine(Constants.ExecutionPath, "Mods");
/// <summary>The actual full path to search for mods.</summary>
internal static string ModsPath { get; set; }
/// <summary>The game's current semantic version.</summary>
internal static ISemanticVersion GameVersion { get; } = new GameVersion("1.3.36");
/// <summary>The target game platform.</summary>
internal static Platform Platform { get; } = EnvironmentUtility.DetectPlatform();
/// <summary>The game's assembly name.</summary>
internal static string GameAssemblyName => Constants.Platform == Platform.Windows ? "Stardew Valley" : "StardewValley";
/*********
** Internal methods
*********/
/// <summary>Get the SMAPI version to recommend for an older game version, if any.</summary>
/// <param name="version">The game version to search.</param>
/// <returns>Returns the compatible SMAPI version, or <c>null</c> if none was found.</returns>
internal static ISemanticVersion GetCompatibleApiVersion(ISemanticVersion version)
{
switch (version.ToString())
{
case "1.3.28":
return new SemanticVersion(2, 7, 0);
case "1.2.30":
case "1.2.31":
case "1.2.32":
case "1.2.33":
return new SemanticVersion(2, 5, 5);
}
return null;
}
/// <summary>Get metadata for mapping assemblies to the current platform.</summary>
/// <param name="targetPlatform">The target game platform.</param>
internal static PlatformAssemblyMap GetAssemblyMap(Platform targetPlatform)
{
// get assembly changes needed for platform
string[] removeAssemblyReferences;
Assembly[] targetAssemblies;
switch (targetPlatform)
{
case Platform.Linux:
case Platform.Mac:
removeAssemblyReferences = new[]
{
"Netcode",
"Stardew Valley",
"Microsoft.Xna.Framework",
"Microsoft.Xna.Framework.Game",
"Microsoft.Xna.Framework.Graphics",
"Microsoft.Xna.Framework.Xact"
};
targetAssemblies = new[]
{
typeof(StardewValley.Game1).Assembly, // note: includes Netcode types on Linux/Mac
typeof(Microsoft.Xna.Framework.Vector2).Assembly
};
break;
case Platform.Windows:
removeAssemblyReferences = new[]
{
"StardewValley",
"MonoGame.Framework"
};
targetAssemblies = new[]
{
typeof(Netcode.NetBool).Assembly,
typeof(StardewValley.Game1).Assembly,
typeof(Microsoft.Xna.Framework.Vector2).Assembly,
typeof(Microsoft.Xna.Framework.Game).Assembly,
typeof(Microsoft.Xna.Framework.Graphics.SpriteBatch).Assembly
};
break;
default:
throw new InvalidOperationException($"Unknown target platform '{targetPlatform}'.");
}
return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences, targetAssemblies);
}
/*********
** Private methods
*********/
/// <summary>Get the name of the save folder, if any.</summary>
internal static string GetSaveFolderName()
{
// save not available
if (Context.LoadStage == LoadStage.None)
return null;
// get basic info
string playerName;
ulong saveID;
if (Context.LoadStage == LoadStage.SaveParsed)
{
playerName = SaveGame.loaded.player.Name;
saveID = SaveGame.loaded.uniqueIDForThisGame;
}
else
{
playerName = Game1.player.Name;
saveID = Game1.uniqueIDForThisGame;
}
// build folder name
return $"{new string(playerName.Where(char.IsLetterOrDigit).ToArray())}_{saveID}";
}
/// <summary>Get the path to the current save folder, if any.</summary>
internal static string GetSaveFolderPathIfExists()
{
string folderName = Constants.GetSaveFolderName();
if (folderName == null)
return null;
string path = Path.Combine(Constants.SavesPath, folderName);
return Directory.Exists(path)
? path
: null;
}
}
}

View File

@ -1,12 +0,0 @@
namespace StardewModdingAPI
{
/// <summary>Specifies a source containing content that can be loaded.</summary>
public enum ContentSource
{
/// <summary>Assets in the game's content manager (i.e. XNBs in the game's content folder).</summary>
GameContent,
/// <summary>XNB files in the current mod's folder.</summary>
ModFolder
}
}

View File

@ -1,47 +0,0 @@
using StardewModdingAPI.Enums;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI
{
/// <summary>Provides information about the current game state.</summary>
public static class Context
{
/*********
** Accessors
*********/
/****
** Public
****/
/// <summary>Whether the player has loaded a save and the world has finished initialising.</summary>
public static bool IsWorldReady { get; internal set; }
/// <summary>Whether <see cref="IsWorldReady"/> is true and the player is free to act in the world (no menu is displayed, no cutscene is in progress, etc).</summary>
public static bool IsPlayerFree => Context.IsWorldReady && Game1.currentLocation != null && Game1.activeClickableMenu == null && !Game1.dialogueUp && (!Game1.eventUp || Game1.isFestival());
/// <summary>Whether <see cref="IsPlayerFree"/> is true and the player is free to move (e.g. not using a tool).</summary>
public static bool CanPlayerMove => Context.IsPlayerFree && Game1.player.CanMove;
/// <summary>Whether the game is currently running the draw loop. This isn't relevant to most mods, since you should use <see cref="IDisplayEvents"/> events to draw to the screen.</summary>
public static bool IsInDrawLoop { get; internal set; }
/// <summary>Whether <see cref="IsWorldReady"/> and the player loaded the save in multiplayer mode (regardless of whether any other players are connected).</summary>
public static bool IsMultiplayer => Context.IsWorldReady && Game1.multiplayerMode != Game1.singlePlayer;
/// <summary>Whether <see cref="IsWorldReady"/> and the current player is the main player. This is always true in single-player, and true when hosting in multiplayer.</summary>
public static bool IsMainPlayer => Context.IsWorldReady && Game1.IsMasterGame;
/****
** Internal
****/
/// <summary>Whether a player save has been loaded.</summary>
internal static bool IsSaveLoaded => Game1.hasLoadedGame && !(Game1.activeClickableMenu is TitleMenu);
/// <summary>Whether the game is currently writing to the save file.</summary>
internal static bool IsSaving => Game1.activeClickableMenu is SaveGameMenu || Game1.activeClickableMenu is ShippingMenu; // saving is performed by SaveGameMenu, but it's wrapped by ShippingMenu on days when the player shipping something
/// <summary>The current stage in the game's loading process.</summary>
internal static LoadStage LoadStage { get; set; }
}
}

View File

@ -1,36 +0,0 @@
namespace StardewModdingAPI.Enums
{
/// <summary>A low-level stage in the game's loading process.</summary>
public enum LoadStage
{
/// <summary>A save is not loaded or loading.</summary>
None,
/// <summary>The game is creating a new save slot, and has initialised the basic save info.</summary>
CreatedBasicInfo,
/// <summary>The game is creating a new save slot, and has initialised the in-game locations.</summary>
CreatedLocations,
/// <summary>The game is creating a new save slot, and has created the physical save files.</summary>
CreatedSaveFile,
/// <summary>The game is loading a save slot, and has read the raw save data into <see cref="StardewValley.SaveGame.loaded"/>. Not applicable when connecting to a multiplayer host. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 20.</summary>
SaveParsed,
/// <summary>The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialised at this point. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 36.</summary>
SaveLoadedBasicInfo,
/// <summary>The game is loading a save slot, and has applied the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 50.</summary>
SaveLoadedLocations,
/// <summary>The final metadata has been loaded from the save file. This happens before the game applies problem fixes, checks for achievements, starts music, etc. Not applicable when connecting to a multiplayer host.</summary>
Preloaded,
/// <summary>The save is fully loaded, but the world may not be fully initialised yet.</summary>
Loaded,
/// <summary>The save is fully loaded, the world has been initialised, and <see cref="Context.IsWorldReady"/> is now true.</summary>
Ready
}
}

View File

@ -1,26 +0,0 @@
using StardewValley;
namespace StardewModdingAPI.Enums
{
/// <summary>The player skill types.</summary>
public enum SkillType
{
/// <summary>The combat skill.</summary>
Combat = Farmer.combatSkill,
/// <summary>The farming skill.</summary>
Farming = Farmer.farmingSkill,
/// <summary>The fishing skill.</summary>
Fishing = Farmer.fishingSkill,
/// <summary>The foraging skill.</summary>
Foraging = Farmer.foragingSkill,
/// <summary>The mining skill.</summary>
Mining = Farmer.miningSkill,
/// <summary>The luck skill.</summary>
Luck = Farmer.luckSkill
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
using StardewValley.Buildings;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.BuildingListChanged"/> event.</summary>
public class BuildingListChangedEventArgs : 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; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** 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>
internal BuildingListChangedEventArgs(GameLocation location, IEnumerable<Building> added, IEnumerable<Building> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,60 +0,0 @@
using System;
using StardewModdingAPI.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when a button is pressed.</summary>
public class ButtonPressedEventArgs : EventArgs
{
/*********
** Fields
*********/
/// <summary>The game's current input state.</summary>
private readonly SInputState InputState;
/*********
** 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; }
/*********
** 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="inputState">The game's current input state.</param>
internal ButtonPressedEventArgs(SButton button, ICursorPosition cursor, SInputState inputState)
{
this.Button = button;
this.Cursor = cursor;
this.InputState = inputState;
}
/// <summary>Whether a mod has indicated the key was already handled, so the game should handle it.</summary>
public bool IsSuppressed()
{
return this.IsSuppressed(this.Button);
}
/// <summary>Whether a mod has indicated the key was already handled, so the game should handle it.</summary>
/// <param name="button">The button to check.</param>
public bool IsSuppressed(SButton button)
{
return this.InputState.SuppressButtons.Contains(button);
}
/// <summary>Get whether a given button was pressed or held.</summary>
/// <param name="button">The button to check.</param>
public bool IsDown(SButton button)
{
return this.InputState.IsDown(button);
}
}
}

View File

@ -1,60 +0,0 @@
using System;
using StardewModdingAPI.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when a button is released.</summary>
public class ButtonReleasedEventArgs : EventArgs
{
/*********
** Fields
*********/
/// <summary>The game's current input state.</summary>
private readonly SInputState InputState;
/*********
** 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; }
/*********
** 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="inputState">The game's current input state.</param>
internal ButtonReleasedEventArgs(SButton button, ICursorPosition cursor, SInputState inputState)
{
this.Button = button;
this.Cursor = cursor;
this.InputState = inputState;
}
/// <summary>Whether a mod has indicated the key was already handled, so the game should handle it.</summary>
public bool IsSuppressed()
{
return this.IsSuppressed(this.Button);
}
/// <summary>Whether a mod has indicated the key was already handled, so the game should handle it.</summary>
/// <param name="button">The button to check.</param>
public bool IsSuppressed(SButton button)
{
return this.InputState.SuppressButtons.Contains(button);
}
/// <summary>Get whether a given button was pressed or held.</summary>
/// <param name="button">The button to check.</param>
public bool IsDown(SButton button)
{
return this.InputState.IsDown(button);
}
}
}

View File

@ -1,15 +0,0 @@
namespace StardewModdingAPI.Events
{
/// <summary>Indicates how an inventory item changed.</summary>
public enum ChangeType
{
/// <summary>The entire stack was removed.</summary>
Removed,
/// <summary>The entire stack was added.</summary>
Added,
/// <summary>The stack size changed.</summary>
StackChange
}
}

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,30 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when the in-game cursor is moved.</summary>
public class CursorMovedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous cursor position.</summary>
public ICursorPosition OldPosition { get; }
/// <summary>The current cursor position.</summary>
public ICursorPosition NewPosition { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldPosition">The previous cursor position.</param>
/// <param name="newPosition">The new cursor position.</param>
internal CursorMovedEventArgs(ICursorPosition oldPosition, ICursorPosition newPosition)
{
this.OldPosition = oldPosition;
this.NewPosition = newPosition;
}
}
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.DayEnding"/> event.</summary>
public class DayEndingEventArgs : EventArgs { }
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.DayStarted"/> event.</summary>
public class DayStartedEventArgs : EventArgs { }
}

View File

@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.DebrisListChanged"/> event.</summary>
public class DebrisListChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The debris added to the location.</summary>
public IEnumerable<Debris> Added { get; }
/// <summary>The debris removed from the location.</summary>
public IEnumerable<Debris> Removed { get; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The debris added to the location.</param>
/// <param name="removed">The debris removed from the location.</param>
internal DebrisListChangedEventArgs(GameLocation location, IEnumerable<Debris> added, IEnumerable<Debris> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

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,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.GameLaunched"/> event.</summary>
public class GameLaunchedEventArgs : EventArgs { }
}

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,39 +0,0 @@
using System;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Events related to UI and drawing to the screen.</summary>
public interface IDisplayEvents
{
/// <summary>Raised after a game menu is opened, closed, or replaced.</summary>
event EventHandler<MenuChangedEventArgs> MenuChanged;
/// <summary>Raised before the game draws anything to the screen in a draw tick, as soon as the sprite batch is opened. The sprite batch may be closed and reopened multiple times after this event is called, but it's only raised once per draw tick. This event isn't useful for drawing to the screen, since the game will draw over it.</summary>
event EventHandler<RenderingEventArgs> Rendering;
/// <summary>Raised after the game draws to the sprite patch in a draw tick, just before the final sprite batch is rendered to the screen. Since the game may open/close the sprite batch multiple times in a draw tick, the sprite batch may not contain everything being drawn and some things may already be rendered to the screen. Content drawn to the sprite batch at this point will be drawn over all vanilla content (including menus, HUD, and cursor).</summary>
event EventHandler<RenderedEventArgs> Rendered;
/// <summary>Raised before the game world is drawn to the screen. This event isn't useful for drawing to the screen, since the game will draw over it.</summary>
event EventHandler<RenderingWorldEventArgs> RenderingWorld;
/// <summary>Raised after the game world is drawn to the sprite patch, before it's rendered to the screen. Content drawn to the sprite batch at this point will be drawn over the world, but under any active menu, HUD elements, or cursor.</summary>
event EventHandler<RenderedWorldEventArgs> RenderedWorld;
/// <summary>When a menu is open (<see cref="Game1.activeClickableMenu"/> isn't null), raised before that menu is drawn to the screen. This includes the game's internal menus like the title screen. Content drawn to the sprite batch at this point will appear under the menu.</summary>
event EventHandler<RenderingActiveMenuEventArgs> RenderingActiveMenu;
/// <summary>When a menu is open (<see cref="Game1.activeClickableMenu"/> isn't null), raised after that menu is drawn to the sprite batch but before it's rendered to the screen. Content drawn to the sprite batch at this point will appear over the menu and menu cursor.</summary>
event EventHandler<RenderedActiveMenuEventArgs> RenderedActiveMenu;
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The vanilla HUD may be hidden at this point (e.g. because a menu is open). Content drawn to the sprite batch at this point will appear under the HUD.</summary>
event EventHandler<RenderingHudEventArgs> RenderingHud;
/// <summary>Raised after drawing the HUD (item toolbar, clock, etc) to the sprite batch, but before it's rendered to the screen. The vanilla HUD may be hidden at this point (e.g. because a menu is open). Content drawn to the sprite batch at this point will appear over the HUD.</summary>
event EventHandler<RenderedHudEventArgs> RenderedHud;
/// <summary>Raised after the game window is resized.</summary>
event EventHandler<WindowResizedEventArgs> WindowResized;
}
}

View File

@ -1,50 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events linked to the game's update loop. The update loop runs roughly ≈60 times/second to run game logic like state changes, action handling, etc. These can be useful, but you should consider more semantic events like <see cref="IInputEvents"/> if possible.</summary>
public interface IGameLoopEvents
{
/// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations.</summary>
event EventHandler<GameLaunchedEventArgs> GameLaunched;
/// <summary>Raised before the game state is updated (≈60 times per second).</summary>
event EventHandler<UpdateTickingEventArgs> UpdateTicking;
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
event EventHandler<UpdateTickedEventArgs> UpdateTicked;
/// <summary>Raised once per second before the game state is updated.</summary>
event EventHandler<OneSecondUpdateTickingEventArgs> OneSecondUpdateTicking;
/// <summary>Raised once per second after the game state is updated.</summary>
event EventHandler<OneSecondUpdateTickedEventArgs> OneSecondUpdateTicked;
/// <summary>Raised before the game creates a new save file.</summary>
event EventHandler<SaveCreatingEventArgs> SaveCreating;
/// <summary>Raised after the game finishes creating the save file.</summary>
event EventHandler<SaveCreatedEventArgs> SaveCreated;
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
event EventHandler<SavingEventArgs> Saving;
/// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary>
event EventHandler<SavedEventArgs> Saved;
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
event EventHandler<SaveLoadedEventArgs> SaveLoaded;
/// <summary>Raised after the game begins a new day (including when the player loads a save).</summary>
event EventHandler<DayStartedEventArgs> DayStarted;
/// <summary>Raised before the game ends the current day. This happens before it starts setting up the next day and before <see cref="Saving"/>.</summary>
event EventHandler<DayEndingEventArgs> DayEnding;
/// <summary>Raised after the in-game clock time changes.</summary>
event EventHandler<TimeChangedEventArgs> TimeChanged;
/// <summary>Raised after the game returns to the title screen.</summary>
event EventHandler<ReturnedToTitleEventArgs> ReturnedToTitle;
}
}

View File

@ -1,20 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player provides input using a controller, keyboard, or mouse.</summary>
public interface IInputEvents
{
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
event EventHandler<ButtonPressedEventArgs> ButtonPressed;
/// <summary>Raised after the player releases a button on the keyboard, controller, or mouse.</summary>
event EventHandler<ButtonReleasedEventArgs> ButtonReleased;
/// <summary>Raised after the player moves the in-game cursor.</summary>
event EventHandler<CursorMovedEventArgs> CursorMoved;
/// <summary>Raised after the player scrolls the mouse wheel.</summary>
event EventHandler<MouseWheelScrolledEventArgs> MouseWheelScrolled;
}
}

View File

@ -1,27 +0,0 @@
namespace StardewModdingAPI.Events
{
/// <summary>Manages access to events raised by SMAPI.</summary>
public interface IModEvents
{
/// <summary>Events related to UI and drawing to the screen.</summary>
IDisplayEvents Display { get; }
/// <summary>Events linked to the game's update loop. The update loop runs roughly ≈60 times/second to run game logic like state changes, action handling, etc. These can be useful, but you should consider more semantic events like <see cref="Input"/> if possible.</summary>
IGameLoopEvents GameLoop { get; }
/// <summary>Events raised when the player provides input using a controller, keyboard, or mouse.</summary>
IInputEvents Input { get; }
/// <summary>Events raised for multiplayer messages and connections.</summary>
IMultiplayerEvents Multiplayer { get; }
/// <summary>Events raised when the player data changes.</summary>
IPlayerEvents Player { get; }
/// <summary>Events raised when something changes in the world.</summary>
IWorldEvents World { get; }
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
ISpecialisedEvents Specialised { get; }
}
}

View File

@ -1,17 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised for multiplayer messages and connections.</summary>
public interface IMultiplayerEvents
{
/// <summary>Raised after the mod context for a peer is received. This happens before the game approves the connection, so the player doesn't yet exist in the game. This is the earliest point where messages can be sent to the peer via SMAPI.</summary>
event EventHandler<PeerContextReceivedEventArgs> PeerContextReceived;
/// <summary>Raised after a mod message is received over the network.</summary>
event EventHandler<ModMessageReceivedEventArgs> ModMessageReceived;
/// <summary>Raised after the connection with a peer is severed.</summary>
event EventHandler<PeerDisconnectedEventArgs> PeerDisconnected;
}
}

View File

@ -1,17 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player data changes.</summary>
public interface IPlayerEvents
{
/// <summary>Raised after items are added or removed to a player's inventory. NOTE: this event is currently only raised for the current player.</summary>
event EventHandler<InventoryChangedEventArgs> InventoryChanged;
/// <summary>Raised after a player skill level changes. This happens as soon as they level up, not when the game notifies the player after their character goes to bed. NOTE: this event is currently only raised for the current player.</summary>
event EventHandler<LevelChangedEventArgs> LevelChanged;
/// <summary>Raised after a player warps to a new location. NOTE: this event is currently only raised for the current player.</summary>
event EventHandler<WarpedEventArgs> Warped;
}
}

View File

@ -1,17 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
public interface ISpecialisedEvents
{
/// <summary>Raised when the low-level stage in the game's loading process has changed. This is an advanced event for mods which need to run code at specific points in the loading process. The available stages or when they happen might change without warning in future versions (e.g. due to changes in the game's load process), so mods using this event are more likely to break or have bugs. Most mods should use <see cref="IGameLoopEvents"/> instead.</summary>
event EventHandler<LoadStageChangedEventArgs> LoadStageChanged;
/// <summary>Raised before the game state is updated (≈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 event will trigger a stability warning in the SMAPI console.</summary>
event EventHandler<UnvalidatedUpdateTickingEventArgs> UnvalidatedUpdateTicking;
/// <summary>Raised after the game state is updated (≈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 event will trigger a stability warning in the SMAPI console.</summary>
event EventHandler<UnvalidatedUpdateTickedEventArgs> UnvalidatedUpdateTicked;
}
}

View File

@ -1,29 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when something changes in the world.</summary>
public interface IWorldEvents
{
/// <summary>Raised after a game location is added or removed.</summary>
event EventHandler<LocationListChangedEventArgs> LocationListChanged;
/// <summary>Raised after buildings are added or removed in a location.</summary>
event EventHandler<BuildingListChangedEventArgs> BuildingListChanged;
/// <summary>Raised after debris are added or removed in a location.</summary>
event EventHandler<DebrisListChangedEventArgs> DebrisListChanged;
/// <summary>Raised after large terrain features (like bushes) are added or removed in a location.</summary>
event EventHandler<LargeTerrainFeatureListChangedEventArgs> LargeTerrainFeatureListChanged;
/// <summary>Raised after NPCs are added or removed in a location.</summary>
event EventHandler<NpcListChangedEventArgs> NpcListChanged;
/// <summary>Raised after objects are added or removed in a location.</summary>
event EventHandler<ObjectListChangedEventArgs> ObjectListChanged;
/// <summary>Raised after terrain features (like floors and trees) are added or removed in a location.</summary>
event EventHandler<TerrainFeatureListChangedEventArgs> TerrainFeatureListChanged;
}
}

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,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IPlayerEvents.InventoryChanged"/> event.</summary>
public class InventoryChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player whose inventory changed.</summary>
public Farmer Player { get; }
/// <summary>The added items.</summary>
public IEnumerable<Item> Added { get; }
/// <summary>The removed items.</summary>
public IEnumerable<Item> Removed { get; }
/// <summary>The items whose stack sizes changed, with the relative change.</summary>
public IEnumerable<ItemStackSizeChange> QuantityChanged { get; }
/// <summary>Whether the affected player is the local one.</summary>
public bool IsLocalPlayer => this.Player.IsLocalPlayer;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="player">The player whose inventory changed.</param>
/// <param name="changedItems">The inventory changes.</param>
internal InventoryChangedEventArgs(Farmer player, ItemStackChange[] changedItems)
{
this.Player = player;
this.Added = changedItems
.Where(n => n.ChangeType == ChangeType.Added)
.Select(p => p.Item)
.ToArray();
this.Removed = changedItems
.Where(n => n.ChangeType == ChangeType.Removed)
.Select(p => p.Item)
.ToArray();
this.QuantityChanged = changedItems
.Where(n => n.ChangeType == ChangeType.StackChange)
.Select(change => new ItemStackSizeChange(
item: change.Item,
oldSize: change.Item.Stack - change.StackChange,
newSize: change.Item.Stack
))
.ToArray();
}
}
}

View File

@ -1,20 +0,0 @@
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Represents an inventory slot that changed.</summary>
public class ItemStackChange
{
/*********
** Accessors
*********/
/// <summary>The item in the slot.</summary>
public Item Item { get; set; }
/// <summary>The amount by which the item's stack size changed.</summary>
public int StackChange { get; set; }
/// <summary>How the inventory slot changed.</summary>
public ChangeType ChangeType { get; set; }
}
}

View File

@ -1,35 +0,0 @@
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>An inventory item stack size change.</summary>
public class ItemStackSizeChange
{
/*********
** Accessors
*********/
/// <summary>The item whose stack size changed.</summary>
public Item Item { get; }
/// <summary>The previous stack size.</summary>
public int OldSize { get; }
/// <summary>The new stack size.</summary>
public int NewSize { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="item">The item whose stack size changed.</param>
/// <param name="oldSize">The previous stack size.</param>
/// <param name="newSize">The new stack size.</param>
public ItemStackSizeChange(Item item, int oldSize, int newSize)
{
this.Item = item;
this.OldSize = oldSize;
this.NewSize = newSize;
}
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
using StardewValley.TerrainFeatures;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.LargeTerrainFeatureListChanged"/> event.</summary>
public class LargeTerrainFeatureListChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The large terrain features added to the location.</summary>
public IEnumerable<LargeTerrainFeature> Added { get; }
/// <summary>The large terrain features removed from the location.</summary>
public IEnumerable<LargeTerrainFeature> Removed { get; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The large terrain features added to the location.</param>
/// <param name="removed">The large terrain features removed from the location.</param>
internal LargeTerrainFeatureListChangedEventArgs(GameLocation location, IEnumerable<LargeTerrainFeature> added, IEnumerable<LargeTerrainFeature> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,45 +0,0 @@
using System;
using StardewModdingAPI.Enums;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IPlayerEvents.LevelChanged"/> event.</summary>
public class LevelChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player whose skill level changed.</summary>
public Farmer Player { get; }
/// <summary>The skill whose level changed.</summary>
public SkillType Skill { get; }
/// <summary>The previous skill level.</summary>
public int OldLevel { get; }
/// <summary>The new skill level.</summary>
public int NewLevel { get; }
/// <summary>Whether the affected player is the local one.</summary>
public bool IsLocalPlayer => this.Player.IsLocalPlayer;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="player">The player whose skill level changed.</param>
/// <param name="skill">The skill whose level changed.</param>
/// <param name="oldLevel">The previous skill level.</param>
/// <param name="newLevel">The new skill level.</param>
internal LevelChangedEventArgs(Farmer player, SkillType skill, int oldLevel, int newLevel)
{
this.Player = player;
this.Skill = skill;
this.OldLevel = oldLevel;
this.NewLevel = newLevel;
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using StardewModdingAPI.Enums;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.LoadStageChanged"/> event.</summary>
public class LoadStageChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous load stage.</summary>
public LoadStage OldStage { get; }
/// <summary>The new load stage.</summary>
public LoadStage NewStage { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="old">The previous load stage.</param>
/// <param name="current">The new load stage.</param>
public LoadStageChangedEventArgs(LoadStage old, LoadStage current)
{
this.OldStage = old;
this.NewStage = current;
}
}
}

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,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.LocationListChanged"/> event.</summary>
public class LocationListChangedEventArgs : 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>
internal LocationListChangedEventArgs(IEnumerable<GameLocation> added, IEnumerable<GameLocation> removed)
{
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.MenuChanged"/> event.</summary>
public class MenuChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous menu.</summary>
public IClickableMenu OldMenu { get; }
/// <summary>The current menu.</summary>
public IClickableMenu NewMenu { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldMenu">The previous menu.</param>
/// <param name="newMenu">The current menu.</param>
internal MenuChangedEventArgs(IClickableMenu oldMenu, IClickableMenu newMenu)
{
this.OldMenu = oldMenu;
this.NewMenu = newMenu;
}
}
}

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,46 +0,0 @@
using System;
using StardewModdingAPI.Framework.Networking;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IMultiplayerEvents.ModMessageReceived"/> event.</summary>
public class ModMessageReceivedEventArgs : EventArgs
{
/*********
** Fields
*********/
/// <summary>The underlying message model.</summary>
private readonly ModMessageModel Message;
/*********
** Accessors
*********/
/// <summary>The unique ID of the player from whose computer the message was sent.</summary>
public long FromPlayerID => this.Message.FromPlayerID;
/// <summary>The unique ID of the mod which sent the message.</summary>
public string FromModID => this.Message.FromModID;
/// <summary>A message type which can be used to decide whether it's the one you want to handle, like <c>SetPlayerLocation</c>. This doesn't need to be globally unique, so mods should check the <see cref="FromModID"/>.</summary>
public string Type => this.Message.Type;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="message">The received message.</param>
internal ModMessageReceivedEventArgs(ModMessageModel message)
{
this.Message = message;
}
/// <summary>Read the message data into the given model type.</summary>
/// <typeparam name="TModel">The message model type.</typeparam>
public TModel ReadAs<TModel>()
{
return this.Message.Data.ToObject<TModel>();
}
}
}

View File

@ -1,38 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when the player scrolls the mouse wheel.</summary>
public class MouseWheelScrolledEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The cursor position.</summary>
public ICursorPosition Position { get; }
/// <summary>The old scroll value.</summary>
public int OldValue { get; }
/// <summary>The new scroll value.</summary>
public int NewValue { get; }
/// <summary>The amount by which the scroll value changed.</summary>
public int Delta => this.NewValue - this.OldValue;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="position">The cursor position.</param>
/// <param name="oldValue">The old scroll value.</param>
/// <param name="newValue">The new scroll value.</param>
internal MouseWheelScrolledEventArgs(ICursorPosition position, int oldValue, int newValue)
{
this.Position = position;
this.OldValue = oldValue;
this.NewValue = newValue;
}
}
}

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,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.NpcListChanged"/> event.</summary>
public class NpcListChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The NPCs added to the location.</summary>
public IEnumerable<NPC> Added { get; }
/// <summary>The NPCs removed from the location.</summary>
public IEnumerable<NPC> Removed { get; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The NPCs added to the location.</param>
/// <param name="removed">The NPCs removed from the location.</param>
internal NpcListChangedEventArgs(GameLocation location, IEnumerable<NPC> added, IEnumerable<NPC> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using StardewValley;
using Object = StardewValley.Object;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.ObjectListChanged"/> event.</summary>
public class ObjectListChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The objects added to the location.</summary>
public IEnumerable<KeyValuePair<Vector2, Object>> Added { get; }
/// <summary>The objects removed from the location.</summary>
public IEnumerable<KeyValuePair<Vector2, Object>> Removed { get; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** 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>
internal ObjectListChangedEventArgs(GameLocation location, IEnumerable<KeyValuePair<Vector2, Object>> added, IEnumerable<KeyValuePair<Vector2, Object>> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.OneSecondUpdateTicked"/> event.</summary>
public class OneSecondUpdateTickedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, including the current tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,26 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.OneSecondUpdateTicking"/> event.</summary>
public class OneSecondUpdateTickingEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, excluding the upcoming tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,25 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IMultiplayerEvents.PeerContextReceived"/> event.</summary>
public class PeerContextReceivedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The peer whose metadata was received.</summary>
public IMultiplayerPeer Peer { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="peer">The peer whose metadata was received.</param>
internal PeerContextReceivedEventArgs(IMultiplayerPeer peer)
{
this.Peer = peer;
}
}
}

View File

@ -1,25 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IMultiplayerEvents.PeerDisconnected"/> event.</summary>
public class PeerDisconnectedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The peer who disconnected.</summary>
public IMultiplayerPeer Peer { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="peer">The peer who disconnected.</param>
internal PeerDisconnectedEventArgs(IMultiplayerPeer peer)
{
this.Peer = peer;
}
}
}

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,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderedActiveMenu"/> event.</summary>
public class RenderedActiveMenuEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.Rendered"/> event.</summary>
public class RenderedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderedHud"/> event.</summary>
public class RenderedHudEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderedWorld"/> event.</summary>
public class RenderedWorldEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderingActiveMenu"/> event.</summary>
public class RenderingActiveMenuEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.Rendering"/> event.</summary>
public class RenderingEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderingHud"/> event.</summary>
public class RenderingHudEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.RenderingWorld"/> event.</summary>
public class RenderingWorldEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The sprite batch being drawn. Add anything you want to appear on-screen to this sprite batch.</summary>
public SpriteBatch SpriteBatch => Game1.spriteBatch;
}
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.ReturnedToTitle"/> event.</summary>
public class ReturnedToTitleEventArgs : EventArgs { }
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveCreated"/> event.</summary>
public class SaveCreatedEventArgs : EventArgs { }
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveCreating"/> event.</summary>
public class SaveCreatingEventArgs : EventArgs { }
}

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,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.SaveLoaded"/> event.</summary>
public class SaveLoadedEventArgs : EventArgs { }
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.Saved"/> event.</summary>
public class SavedEventArgs : EventArgs { }
}

View File

@ -1,7 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.Saving"/> event.</summary>
public class SavingEventArgs : EventArgs { }
}

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,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using StardewValley;
using StardewValley.TerrainFeatures;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="IWorldEvents.TerrainFeatureListChanged"/> event.</summary>
public class TerrainFeatureListChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The terrain features added to the location.</summary>
public IEnumerable<KeyValuePair<Vector2, TerrainFeature>> Added { get; }
/// <summary>The terrain features removed from the location.</summary>
public IEnumerable<KeyValuePair<Vector2, TerrainFeature>> Removed { get; }
/// <summary>Whether this is the location containing the local player.</summary>
public bool IsCurrentLocation => object.ReferenceEquals(this.Location, Game1.player?.currentLocation);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The terrain features added to the location.</param>
/// <param name="removed">The terrain features removed from the location.</param>
internal TerrainFeatureListChangedEventArgs(GameLocation location, IEnumerable<KeyValuePair<Vector2, TerrainFeature>> added, IEnumerable<KeyValuePair<Vector2, TerrainFeature>> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}

View File

@ -1,30 +0,0 @@
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.TimeChanged"/> event.</summary>
public class TimeChangedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous time of day in 24-hour notation (like 1600 for 4pm). The clock time resets when the player sleeps, so 2am (before sleeping) is 2600.</summary>
public int OldTime { get; }
/// <summary>The current time of day in 24-hour notation (like 1600 for 4pm). The clock time resets when the player sleeps, so 2am (before sleeping) is 2600.</summary>
public int NewTime { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldTime">The previous time of day in 24-hour notation (like 1600 for 4pm).</param>
/// <param name="newTime">The current time of day in 24-hour notation (like 1600 for 4pm).</param>
internal TimeChangedEventArgs(int oldTime, int newTime)
{
this.OldTime = oldTime;
this.NewTime = newTime;
}
}
}

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,29 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.UnvalidatedUpdateTicked"/> event.</summary>
public class UnvalidatedUpdateTickedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, including the current tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/// <summary>Whether <see cref="Ticks"/> is a multiple of 60, which happens approximately once per second.</summary>
public bool IsOneSecond => this.Ticks % 60 == 0;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,29 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.UnvalidatedUpdateTicking"/> event.</summary>
public class UnvalidatedUpdateTickingEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, excluding the upcoming tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/// <summary>Whether <see cref="Ticks"/> is a multiple of 60, which happens approximately once per second.</summary>
public bool IsOneSecond => this.Ticks % 60 == 0;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,29 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.UpdateTicked"/> event.</summary>
public class UpdateTickedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, including the current tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/// <summary>Whether <see cref="Ticks"/> is a multiple of 60, which happens approximately once per second.</summary>
public bool IsOneSecond => this.Ticks % 60 == 0;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,29 +0,0 @@
using System;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IGameLoopEvents.UpdateTicking"/> event.</summary>
public class UpdateTickingEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The number of ticks elapsed since the game started, excluding the upcoming tick.</summary>
public uint Ticks => SGame.TicksElapsed;
/// <summary>Whether <see cref="Ticks"/> is a multiple of 60, which happens approximately once per second.</summary>
public bool IsOneSecond => this.Ticks % 60 == 0;
/*********
** Public methods
*********/
/// <summary>Get whether <see cref="Ticks"/> is a multiple of the given <paramref name="number"/>. This is mainly useful if you want to run logic intermittently (e.g. <code>e.IsMultipleOf(30)</code> for every half-second).</summary>
/// <param name="number">The factor to check.</param>
public bool IsMultipleOf(uint number)
{
return this.Ticks % number == 0;
}
}
}

View File

@ -1,40 +0,0 @@
using System;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IPlayerEvents.Warped"/> event.</summary>
public class WarpedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who warped to a new location.</summary>
public Farmer Player { get; }
/// <summary>The player's previous location.</summary>
public GameLocation OldLocation { get; }
/// <summary>The player's current location.</summary>
public GameLocation NewLocation { get; }
/// <summary>Whether the affected player is the local one.</summary>
public bool IsLocalPlayer => this.Player.IsLocalPlayer;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="player">The player who warped to a new location.</param>
/// <param name="oldLocation">The player's previous location.</param>
/// <param name="newLocation">The player's current location.</param>
internal WarpedEventArgs(Farmer player, GameLocation oldLocation, GameLocation newLocation)
{
this.Player = player;
this.NewLocation = newLocation;
this.OldLocation = oldLocation;
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using Microsoft.Xna.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IDisplayEvents.WindowResized"/> event.</summary>
public class WindowResizedEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous window size.</summary>
public Point OldSize { get; }
/// <summary>The current window size.</summary>
public Point NewSize { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldSize">The previous window size.</param>
/// <param name="newSize">The current window size.</param>
internal WindowResizedEventArgs(Point oldSize, Point newSize)
{
this.OldSize = oldSize;
this.NewSize = newSize;
}
}
}

View File

@ -1,40 +0,0 @@
using System;
namespace StardewModdingAPI.Framework
{
/// <summary>A command that can be submitted through the SMAPI console to interact with SMAPI.</summary>
internal class Command
{
/*********
** Accessor
*********/
/// <summary>The mod that registered the command (or <c>null</c> if registered by SMAPI).</summary>
public IModMetadata Mod { get; }
/// <summary>The command name, which the user must type to trigger it.</summary>
public string Name { get; }
/// <summary>The human-readable documentation shown when the player runs the built-in 'help' command.</summary>
public string Documentation { get; }
/// <summary>The method to invoke when the command is triggered. This method is passed the command name and arguments submitted by the user.</summary>
public Action<string, string[]> Callback { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="mod">The mod that registered the command (or <c>null</c> if registered by SMAPI).</param>
/// <param name="name">The command name, which the user must type to trigger it.</param>
/// <param name="documentation">The human-readable documentation shown when the player runs the built-in 'help' command.</param>
/// <param name="callback">The method to invoke when the command is triggered. This method is passed the command name and arguments submitted by the user.</param>
public Command(IModMetadata mod, string name, string documentation, Action<string, string[]> callback)
{
this.Mod = mod;
this.Name = name;
this.Documentation = documentation;
this.Callback = callback;
}
}
}

View File

@ -1,153 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StardewModdingAPI.Framework
{
/// <summary>Manages console commands.</summary>
internal class CommandManager
{
/*********
** Fields
*********/
/// <summary>The commands registered with SMAPI.</summary>
private readonly IDictionary<string, Command> Commands = new Dictionary<string, Command>(StringComparer.InvariantCultureIgnoreCase);
/*********
** Public methods
*********/
/// <summary>Add a console command.</summary>
/// <param name="mod">The mod adding the command (or <c>null</c> for a SMAPI command).</param>
/// <param name="name">The command name, which the user must type to trigger it.</param>
/// <param name="documentation">The human-readable documentation shown when the player runs the built-in 'help' command.</param>
/// <param name="callback">The method to invoke when the command is triggered. This method is passed the command name and arguments submitted by the user.</param>
/// <param name="allowNullCallback">Whether to allow a null <paramref name="callback"/> argument; this should only used for backwards compatibility.</param>
/// <exception cref="ArgumentNullException">The <paramref name="name"/> or <paramref name="callback"/> is null or empty.</exception>
/// <exception cref="FormatException">The <paramref name="name"/> is not a valid format.</exception>
/// <exception cref="ArgumentException">There's already a command with that name.</exception>
public void Add(IModMetadata mod, string name, string documentation, Action<string, string[]> callback, bool allowNullCallback = false)
{
name = this.GetNormalisedName(name);
// validate format
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name), "Can't register a command with no name.");
if (name.Any(char.IsWhiteSpace))
throw new FormatException($"Can't register the '{name}' command because the name can't contain whitespace.");
if (callback == null && !allowNullCallback)
throw new ArgumentNullException(nameof(callback), $"Can't register the '{name}' command because without a callback.");
// ensure uniqueness
if (this.Commands.ContainsKey(name))
throw new ArgumentException(nameof(callback), $"Can't register the '{name}' command because there's already a command with that name.");
// add command
this.Commands.Add(name, new Command(mod, name, documentation, callback));
}
/// <summary>Get a command by its unique name.</summary>
/// <param name="name">The command name.</param>
/// <returns>Returns the matching command, or <c>null</c> if not found.</returns>
public Command Get(string name)
{
name = this.GetNormalisedName(name);
this.Commands.TryGetValue(name, out Command command);
return command;
}
/// <summary>Get all registered commands.</summary>
public IEnumerable<Command> GetAll()
{
return this.Commands
.Values
.OrderBy(p => p.Name);
}
/// <summary>Try to parse a raw line of user input into an executable command.</summary>
/// <param name="input">The raw user input.</param>
/// <param name="name">The parsed command name.</param>
/// <param name="args">The parsed command arguments.</param>
/// <param name="command">The command which can handle the input.</param>
/// <returns>Returns true if the input was successfully parsed and matched to a command; else false.</returns>
public bool TryParse(string input, out string name, out string[] args, out Command command)
{
// ignore if blank
if (string.IsNullOrWhiteSpace(input))
{
name = null;
args = null;
command = null;
return false;
}
// parse input
args = this.ParseArgs(input);
name = this.GetNormalisedName(args[0]);
args = args.Skip(1).ToArray();
// get command
return this.Commands.TryGetValue(name, out command);
}
/// <summary>Trigger a command.</summary>
/// <param name="name">The command name.</param>
/// <param name="arguments">The command arguments.</param>
/// <returns>Returns whether a matching command was triggered.</returns>
public bool Trigger(string name, string[] arguments)
{
// get normalised name
name = this.GetNormalisedName(name);
if (name == null)
return false;
// get command
if (this.Commands.TryGetValue(name, out Command command))
{
command.Callback.Invoke(name, arguments);
return true;
}
return false;
}
/*********
** Private methods
*********/
/// <summary>Parse a string into command arguments.</summary>
/// <param name="input">The string to parse.</param>
private string[] ParseArgs(string input)
{
bool inQuotes = false;
IList<string> args = new List<string>();
StringBuilder currentArg = new StringBuilder();
foreach (char ch in input)
{
if (ch == '"')
inQuotes = !inQuotes;
else if (!inQuotes && char.IsWhiteSpace(ch))
{
args.Add(currentArg.ToString());
currentArg.Clear();
}
else
currentArg.Append(ch);
}
args.Add(currentArg.ToString());
return args.Where(item => !string.IsNullOrWhiteSpace(item)).ToArray();
}
/// <summary>Get a normalised command name.</summary>
/// <param name="name">The command name.</param>
private string GetNormalisedName(string name)
{
name = name?.Trim().ToLower();
return !string.IsNullOrWhiteSpace(name)
? name
: null;
}
}
}

View File

@ -1,54 +0,0 @@
using System;
namespace StardewModdingAPI.Framework.Content
{
/// <summary>Base implementation for a content helper which encapsulates access and changes to content being read from a data file.</summary>
/// <typeparam name="TValue">The interface value type.</typeparam>
internal class AssetData<TValue> : AssetInfo, IAssetData<TValue>
{
/*********
** Fields
*********/
/// <summary>A callback to invoke when the data is replaced (if any).</summary>
private readonly Action<TValue> OnDataReplaced;
/*********
** Accessors
*********/
/// <summary>The content data being read.</summary>
public TValue Data { get; protected set; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="locale">The content's locale code, if the content is localised.</param>
/// <param name="assetName">The normalised asset name being read.</param>
/// <param name="data">The content data being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
public AssetData(string locale, string assetName, TValue data, Func<string, string> getNormalisedPath, Action<TValue> onDataReplaced)
: base(locale, assetName, data.GetType(), getNormalisedPath)
{
this.Data = data;
this.OnDataReplaced = onDataReplaced;
}
/// <summary>Replace the entire content value with the given value. This is generally not recommended, since it may break compatibility with other mods or different versions of the game.</summary>
/// <param name="value">The new content value.</param>
/// <exception cref="ArgumentNullException">The <paramref name="value"/> is null.</exception>
/// <exception cref="InvalidCastException">The <paramref name="value"/>'s type is not compatible with the loaded asset's type.</exception>
public void ReplaceWith(TValue value)
{
if (value == null)
throw new ArgumentNullException(nameof(value), "Can't set a loaded asset to a null value.");
if (!this.DataType.IsInstanceOfType(value))
throw new InvalidCastException($"Can't replace loaded asset of type {this.GetFriendlyTypeName(this.DataType)} with value of type {this.GetFriendlyTypeName(value.GetType())}. The new type must be compatible to prevent game errors.");
this.Data = value;
this.OnDataReplaced?.Invoke(value);
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace StardewModdingAPI.Framework.Content
{
/// <summary>Encapsulates access and changes to dictionary content being read from a data file.</summary>
internal class AssetDataForDictionary<TKey, TValue> : AssetData<IDictionary<TKey, TValue>>, IAssetDataForDictionary<TKey, TValue>
{
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="locale">The content's locale code, if the content is localised.</param>
/// <param name="assetName">The normalised asset name being read.</param>
/// <param name="data">The content data being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</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)
: 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

@ -1,106 +0,0 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace StardewModdingAPI.Framework.Content
{
/// <summary>Encapsulates access and changes to image content being read from a data file.</summary>
internal class AssetDataForImage : AssetData<Texture2D>, IAssetDataForImage
{
/*********
** Fields
*********/
/// <summary>The minimum value to consider non-transparent.</summary>
/// <remarks>On Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason.</remarks>
private const byte MinOpacity = 5;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="locale">The content's locale code, if the content is localised.</param>
/// <param name="assetName">The normalised asset name being read.</param>
/// <param name="data">The content data being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
public AssetDataForImage(string locale, string assetName, Texture2D data, Func<string, string> getNormalisedPath, Action<Texture2D> onDataReplaced)
: base(locale, assetName, data, getNormalisedPath, onDataReplaced) { }
/// <summary>Overwrite part of the image.</summary>
/// <param name="source">The image to patch into the content.</param>
/// <param name="sourceArea">The part of the <paramref name="source"/> to copy (or <c>null</c> to take the whole texture). This must be within the bounds of the <paramref name="source"/> texture.</param>
/// <param name="targetArea">The part of the content to patch (or <c>null</c> to patch the whole texture). The original content within this area will be erased. This must be within the bounds of the existing spritesheet.</param>
/// <param name="patchMode">Indicates how an image should be patched.</param>
/// <exception cref="ArgumentNullException">One of the arguments is null.</exception>
/// <exception cref="ArgumentOutOfRangeException">The <paramref name="targetArea"/> is outside the bounds of the spritesheet.</exception>
public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMode patchMode = PatchMode.Replace)
{
// get texture
if (source == null)
throw new ArgumentNullException(nameof(source), "Can't patch from a null source texture.");
Texture2D target = this.Data;
// get areas
sourceArea = sourceArea ?? new Rectangle(0, 0, source.Width, source.Height);
targetArea = targetArea ?? new Rectangle(0, 0, Math.Min(sourceArea.Value.Width, target.Width), Math.Min(sourceArea.Value.Height, target.Height));
// validate
if (sourceArea.Value.X < 0 || sourceArea.Value.Y < 0 || sourceArea.Value.Right > source.Width || sourceArea.Value.Bottom > source.Height)
throw new ArgumentOutOfRangeException(nameof(sourceArea), "The source area is outside the bounds of the source texture.");
if (targetArea.Value.X < 0 || targetArea.Value.Y < 0 || targetArea.Value.Right > target.Width || targetArea.Value.Bottom > target.Height)
throw new ArgumentOutOfRangeException(nameof(targetArea), "The target area is outside the bounds of the target texture.");
if (sourceArea.Value.Width != targetArea.Value.Width || sourceArea.Value.Height != targetArea.Value.Height)
throw new InvalidOperationException("The source and target areas must be the same size.");
// get source data
int pixelCount = sourceArea.Value.Width * sourceArea.Value.Height;
Color[] sourceData = new Color[pixelCount];
source.GetData(0, sourceArea, sourceData, 0, pixelCount);
// merge data in overlay mode
if (patchMode == PatchMode.Overlay)
{
// get target data
Color[] targetData = new Color[pixelCount];
target.GetData(0, targetArea, targetData, 0, pixelCount);
// merge pixels
Color[] newData = new Color[targetArea.Value.Width * targetArea.Value.Height];
target.GetData(0, targetArea, newData, 0, newData.Length);
for (int i = 0; i < sourceData.Length; i++)
{
Color above = sourceData[i];
Color below = targetData[i];
// shortcut transparency
if (above.A < AssetDataForImage.MinOpacity)
continue;
if (below.A < AssetDataForImage.MinOpacity)
{
newData[i] = above;
continue;
}
// merge pixels
// This performs a conventional alpha blend for the pixels, which are already
// premultiplied by the content pipeline. The formula is derived from
// https://blogs.msdn.microsoft.com/shawnhar/2009/11/06/premultiplied-alpha/.
// Note: don't use named arguments here since they're different between
// Linux/Mac and Windows.
float alphaBelow = 1 - (above.A / 255f);
newData[i] = new Color(
(int)(above.R + (below.R * alphaBelow)), // r
(int)(above.G + (below.G * alphaBelow)), // g
(int)(above.B + (below.B * alphaBelow)), // b
Math.Max(above.A, below.A) // a
);
}
sourceData = newData;
}
// patch target texture
target.SetData(0, targetArea, sourceData, 0, pixelCount);
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
namespace StardewModdingAPI.Framework.Content
{
/// <summary>Encapsulates access and changes to content being read from a data file.</summary>
internal class AssetDataForObject : AssetData<object>, IAssetData
{
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="locale">The content's locale code, if the content is localised.</param>
/// <param name="assetName">The normalised asset name being read.</param>
/// <param name="data">The content data being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
public AssetDataForObject(string locale, string assetName, object data, Func<string, string> getNormalisedPath)
: base(locale, assetName, data, getNormalisedPath, onDataReplaced: null) { }
/// <summary>Construct an instance.</summary>
/// <param name="info">The asset metadata.</param>
/// <param name="data">The content data being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
public AssetDataForObject(IAssetInfo info, object data, Func<string, string> getNormalisedPath)
: this(info.Locale, info.AssetName, data, getNormalisedPath) { }
/// <summary>Get a helper to manipulate the data as a dictionary.</summary>
/// <typeparam name="TKey">The expected dictionary key.</typeparam>
/// <typeparam name="TValue">The expected dictionary balue.</typeparam>
/// <exception cref="InvalidOperationException">The content being read isn't a dictionary.</exception>
public IAssetDataForDictionary<TKey, TValue> AsDictionary<TKey, TValue>()
{
return new AssetDataForDictionary<TKey, TValue>(this.Locale, this.AssetName, this.GetData<IDictionary<TKey, TValue>>(), this.GetNormalisedPath, this.ReplaceWith);
}
/// <summary>Get a helper to manipulate the data as an image.</summary>
/// <exception cref="InvalidOperationException">The content being read isn't an image.</exception>
public IAssetDataForImage AsImage()
{
return new AssetDataForImage(this.Locale, this.AssetName, this.GetData<Texture2D>(), this.GetNormalisedPath, this.ReplaceWith);
}
/// <summary>Get the data as a given type.</summary>
/// <typeparam name="TData">The expected data type.</typeparam>
/// <exception cref="InvalidCastException">The data can't be converted to <typeparamref name="TData"/>.</exception>
public TData GetData<TData>()
{
if (!(this.Data is TData))
throw new InvalidCastException($"The content data of type {this.Data.GetType().FullName} can't be converted to the requested {typeof(TData).FullName}.");
return (TData)this.Data;
}
}
}

View File

@ -1,82 +0,0 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
namespace StardewModdingAPI.Framework.Content
{
internal class AssetInfo : IAssetInfo
{
/*********
** Fields
*********/
/// <summary>Normalises an asset key to match the cache key.</summary>
protected readonly Func<string, string> GetNormalisedPath;
/*********
** Accessors
*********/
/// <summary>The content's locale code, if the content is localised.</summary>
public string Locale { get; }
/// <summary>The normalised asset name being read. The format may change between platforms; see <see cref="AssetNameEquals"/> to compare with a known path.</summary>
public string AssetName { get; }
/// <summary>The content data type.</summary>
public Type DataType { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="locale">The content's locale code, if the content is localised.</param>
/// <param name="assetName">The normalised asset name being read.</param>
/// <param name="type">The content type being read.</param>
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
public AssetInfo(string locale, string assetName, Type type, Func<string, string> getNormalisedPath)
{
this.Locale = locale;
this.AssetName = assetName;
this.DataType = type;
this.GetNormalisedPath = getNormalisedPath;
}
/// <summary>Get whether the asset name being loaded matches a given name after normalisation.</summary>
/// <param name="path">The expected asset path, relative to the game's content folder and without the .xnb extension or locale suffix (like 'Data\ObjectInformation').</param>
public bool AssetNameEquals(string path)
{
path = this.GetNormalisedPath(path);
return this.AssetName.Equals(path, StringComparison.InvariantCultureIgnoreCase);
}
/*********
** Protected methods
*********/
/// <summary>Get a human-readable type name.</summary>
/// <param name="type">The type to name.</param>
protected string GetFriendlyTypeName(Type type)
{
// dictionary
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
{
Type[] genericArgs = type.GetGenericArguments();
return $"Dictionary<{this.GetFriendlyTypeName(genericArgs[0])}, {this.GetFriendlyTypeName(genericArgs[1])}>";
}
// texture
if (type == typeof(Texture2D))
return type.Name;
// native type
if (type == typeof(int))
return "int";
if (type == typeof(string))
return "string";
// default
return type.FullName;
}
}
}

View File

@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using Microsoft.Xna.Framework;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Internal;
using StardewModdingAPI.Toolkit.Utilities;
using StardewValley;
namespace StardewModdingAPI.Framework.Content
{
/// <summary>A low-level wrapper around the content cache which handles reading, writing, and invalidating entries in the cache. This doesn't handle any higher-level logic like localisation, loading content, etc. It assumes all keys passed in are already normalised.</summary>
internal class ContentCache
{
/*********
** Fields
*********/
/// <summary>The underlying asset cache.</summary>
private readonly IDictionary<string, object> Cache;
/// <summary>Applies platform-specific asset key normalisation so it's consistent with the underlying cache.</summary>
private readonly Func<string, string> NormaliseAssetNameForPlatform;
/*********
** Accessors
*********/
/// <summary>Get or set the value of a raw cache entry.</summary>
/// <param name="key">The cache key.</param>
public object this[string key]
{
get => this.Cache[key];
set => this.Cache[key] = value;
}
/// <summary>The current cache keys.</summary>
public IEnumerable<string> Keys => this.Cache.Keys;
/*********
** Public methods
*********/
/****
** Constructor
****/
/// <summary>Construct an instance.</summary>
/// <param name="contentManager">The underlying content manager whose cache to manage.</param>
/// <param name="reflection">Simplifies access to private game code.</param>
public ContentCache(LocalizedContentManager contentManager, Reflector reflection)
{
// init
this.Cache = reflection.GetField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
// get key normalisation logic
if (Constants.Platform == Platform.Windows)
{
IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath");
this.NormaliseAssetNameForPlatform = path => method.Invoke<string>(path);
}
else
this.NormaliseAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load<T> logic
}
/****
** Fetch
****/
/// <summary>Get whether the cache contains a given key.</summary>
/// <param name="key">The cache key.</param>
public bool ContainsKey(string key)
{
return this.Cache.ContainsKey(key);
}
/****
** Normalise
****/
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="NormaliseKey"/> instead.</summary>
/// <param name="path">The file path to normalise.</param>
[Pure]
public string NormalisePathSeparators(string path)
{
return PathUtilities.NormalisePathSeparators(path);
}
/// <summary>Normalise a cache key so it's consistent with the underlying cache.</summary>
/// <param name="key">The asset key.</param>
[Pure]
public string NormaliseKey(string key)
{
key = this.NormalisePathSeparators(key);
return key.EndsWith(".xnb", StringComparison.InvariantCultureIgnoreCase)
? key.Substring(0, key.Length - 4)
: this.NormaliseAssetNameForPlatform(key);
}
/****
** Remove
****/
/// <summary>Remove an asset with the given key.</summary>
/// <param name="key">The cache key.</param>
/// <param name="dispose">Whether to dispose the entry value, if applicable.</param>
/// <returns>Returns the removed key (if any).</returns>
public bool Remove(string key, bool dispose)
{
// get entry
if (!this.Cache.TryGetValue(key, out object value))
return false;
// dispose & remove entry
if (dispose && value is IDisposable disposable)
disposable.Dispose();
return this.Cache.Remove(key);
}
/// <summary>Purge matched assets from the cache.</summary>
/// <param name="predicate">Matches the asset keys to invalidate.</param>
/// <param name="dispose">Whether to dispose invalidated assets. This should only be <c>true</c> when they're being invalidated as part of a dispose, to avoid crashing the game.</param>
/// <returns>Returns the removed keys (if any).</returns>
public IEnumerable<string> Remove(Func<string, Type, bool> predicate, bool dispose = false)
{
List<string> removed = new List<string>();
foreach (string key in this.Cache.Keys.ToArray())
{
Type type = this.Cache[key].GetType();
if (predicate(key, type))
{
this.Remove(key, dispose);
removed.Add(key);
}
}
return removed;
}
}
}

Some files were not shown because too many files have changed in this diff Show More