This commit is contained in:
Chris 2019-05-24 03:23:57 -04:00 committed by ZaneYork
parent 465ab19d42
commit 89f8be10b1
295 changed files with 30627 additions and 1 deletions

View File

@ -57,6 +57,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SMAPI.Mods.VirtualKeyboard"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Loader", "Loader\Loader.csproj", "{45D7D2FB-6B70-45D1-A595-6E289D6A3468}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI", "StardewModdingAPI\StardewModdingAPI.csproj", "{9898B56E-51EB-40CF-8B1F-ACEB4B6397A7}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
SMAPI.Internal\SMAPI.Internal.projitems*{85208f8d-6fd1-4531-be05-7142490f59fe}*SharedItemsImports = 13

View File

@ -160,7 +160,7 @@ namespace StardewModdingAPI
internal static string ModsPath { get; set; }
/// <summary>The game's current semantic version.</summary>
internal static ISemanticVersion GameVersion { get; } = new GameVersion(Game1.version);
internal static ISemanticVersion GameVersion { get; } = new GameVersion("1.3.36");
/// <summary>The target game platform as a SMAPI toolkit constant.</summary>
internal static Platform Platform { get; } = (Platform)Constants.TargetPlatform;

View File

@ -0,0 +1,78 @@
using System;
using Mono.Cecil;
using Mono.Cecil.Cil;
using StardewModdingAPI.Framework.ModLoading.Finders;
namespace StardewModdingAPI.Framework.ModLoading.Rewriters
{
/// <summary>Rewrites field references into property references.</summary>
internal class TypeFieldToTypeFieldRewriter : FieldFinder
{
/*********
** Fields
*********/
/// <summary>The type whose field to which references should be rewritten.</summary>
private readonly Type Type;
/// <summary>The type whose field to which references should be rewritten to.</summary>
private readonly Type ToType;
/// <summary>The property name.</summary>
private readonly string PropertyName;
private readonly IMonitor Monitor;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="type">The type whose field to which references should be rewritten.</param>
/// <param name="fieldName">The field name to rewrite.</param>
/// <param name="propertyName">The property name (if different).</param>
public TypeFieldToTypeFieldRewriter(Type type, Type toType, string fieldName, string propertyName, IMonitor monitor)
: base(type.FullName, fieldName, InstructionHandleResult.None)
{
this.Monitor = monitor;
this.Type = type;
this.ToType = toType;
this.PropertyName = propertyName;
}
/// <summary>Construct an instance.</summary>
/// <param name="type">The type whose field to which references should be rewritten.</param>
/// <param name="fieldName">The field name to rewrite.</param>
public TypeFieldToTypeFieldRewriter(Type type, Type toType, string fieldName, IMonitor monitor)
: this(type, toType, fieldName, fieldName, monitor) { }
/// <summary>Perform the predefined logic for an instruction if applicable.</summary>
/// <param name="module">The assembly module containing the instruction.</param>
/// <param name="cil">The CIL processor.</param>
/// <param name="instruction">The instruction to handle.</param>
/// <param name="assemblyMap">Metadata for mapping assemblies to the current platform.</param>
/// <param name="platformChanged">Whether the mod was compiled on a different platform.</param>
public override InstructionHandleResult Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction, PlatformAssemblyMap assemblyMap, bool platformChanged)
{
if (!this.IsMatch(instruction))
return InstructionHandleResult.None;
//Instruction: IL_0025: ldsfld StardewValley.GameLocation StardewValley.Game1::currentLocation
string methodPrefix = instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldfld ? "get" : "set";
try
{
//MethodReference propertyRef = module.ImportReference(this.ToType.GetMethod($"{methodPrefix}_{this.PropertyName}"));
MethodReference method = module.ImportReference(this.ToType.GetMethod($"{methodPrefix}_{this.PropertyName}"));
this.Monitor.Log("Method Ref: " + method.ToString());
cil.Replace(instruction, cil.Create(OpCodes.Call, method));
}
catch (Exception e)
{
this.Monitor.Log(e.Message);
}
return InstructionHandleResult.Rewritten;
}
}
}

View File

@ -0,0 +1,21 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
class FarmerMethods : Farmer
{
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public new bool couldInventoryAcceptThisItem(Item item)
{
return base.couldInventoryAcceptThisItem(item, true);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public new bool addItemToInventoryBool(Item item)
{
return base.addItemToInventoryBool(item, false);
}
}
}

View File

@ -0,0 +1,16 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class FarmerRendererMethods : FarmerRenderer
{
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public new void drawMiniPortrat(SpriteBatch b, Vector2 position, float layerDepth, float scale, int facingDirection, Farmer who)
{
base.drawMiniPortrat(b, position, layerDepth, scale, facingDirection, who);
}
}
}

View File

@ -0,0 +1,32 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class Game1Methods : Game1
{
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new string parseText(string text, SpriteFont whichFont, int width)
{
return parseText(text, whichFont, width, 1);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void warpFarmer(LocationRequest locationRequest, int tileX, int tileY, int facingDirectionAfterWarp)
{
warpFarmer(locationRequest, tileX, tileY, facingDirectionAfterWarp, true, false);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void warpFarmer(string locationName, int tileX, int tileY, bool flip)
{
warpFarmer(locationName, tileX, tileY, flip ? ((player.FacingDirection + 2) % 4) : player.FacingDirection);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void warpFarmer(string locationName, int tileX, int tileY, int facingDirectionAfterWarp)
{
warpFarmer(locationName, tileX, tileY, facingDirectionAfterWarp, false, true, false);
}
}
}

View File

@ -0,0 +1,17 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class HUDMessageMethods : HUDMessage
{
public HUDMessageMethods(string message, int whatType)
: base(message, whatType, -1)
{
}
}
}

View File

@ -0,0 +1,33 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class IClickableMenuMethods : IClickableMenu
{
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void drawHoverText(SpriteBatch b, string text, SpriteFont font, int xOffset = 0, int yOffset = 0, int moneyAmounttoDisplayAtBottom = -1, string boldTitleText = null, int healAmountToDisplay = -1, string[] buffIconsToDsiplay = null, Item hoveredItem = null, int currencySymbol = 0, int extraItemToShowIndex = -1, int extraItemToShowAmount = -1, int overideX = -1, int overrideY = -1, float alpha = 1, CraftingRecipe craftingIngrediants = null)
{
drawHoverText(b, text, font, xOffset, yOffset, moneyAmounttoDisplayAtBottom, boldTitleText, healAmountToDisplay, buffIconsToDsiplay, hoveredItem, currencySymbol, extraItemToShowIndex, extraItemToShowAmount, overideX, overrideY, alpha, craftingIngrediants, -1, 80, -1);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void drawTextureBox(SpriteBatch b, Texture2D texture, Microsoft.Xna.Framework.Rectangle sourceRect, int x, int y, int width, int height, Color color)
{
drawTextureBox(b, texture, sourceRect, x, y, width, height, color, 1, true, false);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void drawTextureBox(SpriteBatch b, Texture2D texture, Microsoft.Xna.Framework.Rectangle sourceRect, int x, int y, int width, int height, Color color, float scale)
{
drawTextureBox(b, texture, sourceRect, x, y, width, height, color, scale, true, false);
}
[SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")]
public static new void drawTextureBox(SpriteBatch b, Texture2D texture, Microsoft.Xna.Framework.Rectangle sourceRect, int x, int y, int width, int height, Color color, float scale, bool drawShadow)
{
drawTextureBox(b, texture, sourceRect, x, y, width, height, color, scale, drawShadow, false);
}
}
}

View File

@ -0,0 +1,17 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class MapPageMethods : MapPage
{
public MapPageMethods(int x, int y, int width, int height)
: base(x, y, width, height, 1f, 1f)
{
}
}
}

View File

@ -0,0 +1,18 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Menus;
#pragma warning disable 1591 // missing documentation
namespace StardewModdingAPI.SMAPI.Framework.RewriteFacades
{
public class TextBoxMethods : TextBox
{
public TextBoxMethods(Texture2D textboxTexture, Texture2D caretTexture, SpriteFont font, Color textColor)
: base(textboxTexture, caretTexture, font, textColor, true, false)
{
}
}
}

View File

@ -0,0 +1 @@


View File

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI", "StardewModdingAPI.csproj", "{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\SMAPI.Internal\SMAPI.Internal.projitems*{f1a573b0-f436-472c-ae29-0b91ea6b9f8f}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}.Debug|Any CPU.ActiveCfg = Debug|x86
{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}.Release|Any CPU.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {82DD83B8-40C3-4BEB-82EA-84A61392732D}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,238 @@
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/smapi-internal");
/// <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

@ -0,0 +1,12 @@
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

@ -0,0 +1,47 @@
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

@ -0,0 +1,36 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,42 @@
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

@ -0,0 +1,60 @@
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

@ -0,0 +1,60 @@
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

@ -0,0 +1,15 @@
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

@ -0,0 +1,45 @@
#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

@ -0,0 +1,123 @@
#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

@ -0,0 +1,30 @@
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

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

View File

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

View File

@ -0,0 +1,41 @@
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

@ -0,0 +1,33 @@
#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

@ -0,0 +1,28 @@
#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

@ -0,0 +1,34 @@
#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

@ -0,0 +1,34 @@
#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

@ -0,0 +1,39 @@
#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

@ -0,0 +1,39 @@
#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

@ -0,0 +1,64 @@
#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

@ -0,0 +1,32 @@
#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

@ -0,0 +1,43 @@
#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

@ -0,0 +1,28 @@
#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

@ -0,0 +1,33 @@
#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

@ -0,0 +1,55 @@
#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

@ -0,0 +1,41 @@
#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

@ -0,0 +1,42 @@
#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

@ -0,0 +1,35 @@
#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

@ -0,0 +1,32 @@
#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

@ -0,0 +1,44 @@
#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

@ -0,0 +1,34 @@
#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

@ -0,0 +1,33 @@
#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

@ -0,0 +1,122 @@
#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

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

View File

@ -0,0 +1,120 @@
#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

@ -0,0 +1,39 @@
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

@ -0,0 +1,50 @@
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

@ -0,0 +1,20 @@
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

@ -0,0 +1,27 @@
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

@ -0,0 +1,17 @@
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

@ -0,0 +1,17 @@
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

@ -0,0 +1,17 @@
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

@ -0,0 +1,29 @@
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

@ -0,0 +1,56 @@
#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

@ -0,0 +1,59 @@
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

@ -0,0 +1,20 @@
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

@ -0,0 +1,35 @@
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

@ -0,0 +1,42 @@
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

@ -0,0 +1,45 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,67 @@
#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

@ -0,0 +1,33 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,56 @@
#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

@ -0,0 +1,45 @@
#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

@ -0,0 +1,46 @@
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

@ -0,0 +1,38 @@
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

@ -0,0 +1,78 @@
#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

@ -0,0 +1,41 @@
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

@ -0,0 +1,43 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,25 @@
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

@ -0,0 +1,25 @@
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

@ -0,0 +1,68 @@
#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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

@ -0,0 +1,16 @@
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

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

View File

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

View File

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

View File

@ -0,0 +1,100 @@
#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

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

View File

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

View File

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

View File

@ -0,0 +1,45 @@
#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

@ -0,0 +1,43 @@
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

@ -0,0 +1,30 @@
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

@ -0,0 +1,56 @@
#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

@ -0,0 +1,29 @@
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

@ -0,0 +1,29 @@
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;
}
}
}

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