BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。
模组:制作指南/APIs/Utilities
← 模组:目录
SMAPI 提供了一些 C# 对象用于简化代码。
元数据
模组路径
在处理模组路径前,请注意:
- 模组文件夹路径并不是一成不变的:游戏可以被安装在不同的文件夹,Nexus 模组经常默认解压到 Mods/Your Mod Name 1.27.5-541-1-27-5-1598664794/YourModFolder 这样的模组,而且玩家可以自行配置模组文件,例如 Mods/For single-player/YourModFolder。
- Linux/Mac/Android 的路径格式与 Windows 并不相同。
但是,当您使用 SMAPI 时无需担心这些,因为 SMAPI 允许使用相对路径,且会根据实际情况调整路径格式:
var data = this.Helper.Data.ReadJsonFile<SomeDataModel>("assets/data.json");
如果您的确需要绝对路径,您应当使用 this.Helper.DirectoryPath 和 Path.Combine 来获取它:
string path = Path.Combine(this.Helper.DirectoryPath, "assets", "data.json"); // "assets/data.json" in the current mod's folder
var file = new FileInfo(path);
参见 Constants 以获取某些绝对路径,例如游戏文件夹路径。
Constants
Constants 类提供了关于 SMAPI 和游戏的元数据。
值 | 含义 |
---|---|
Constants.ApiVersion | 正在运行的 SMAPI 实例的版本。 |
Constants.MinimumGameVersion Constants.MaximumGameVersion |
正在运行的 SMAPI 实例支持的游戏版本。 |
Constants.TargetPlatform | 当前操作系统(取 Android、Linux、Mac 或 Windows 之一)。 |
Constants.GameFramework | 运行该游戏的游戏框架(Xna 或 MonoGame)。 |
Constants.GamePath | Stardew Valley 文件夹的绝对路径。 |
Constants.ContentPath | 游戏的 Content 文件夹的绝对路径。 |
Constants.DataPath | 游戏的数据文件夹(即,容纳存档文件夹的文件夹)的绝对路径。 |
Constants.LogDir | 游戏和SMAPI的日志文件夹的绝对路径。 |
Constants.SavesPath | 存档文件夹的绝对路径。 |
Constants.CurrentSavePath | 如果已经加载了存档,则此字段为当前存档所在文件夹的绝对路径。 |
Constants.SaveFolderName | 如果已经加载了存档,则此字段为当前存档文件夹的名称(例如 Name_012345789)。 |
Context
Context 类提供了有关游戏状态和玩家控制的信息。
- 游戏/玩家状态:
值 含义 Context.IsGameLaunched 游戏是否已启动和初始化。它会在游戏第一次刷新后立即变为 true。 Context.IsWorldReady 玩家是否已加载了存档且世界初始化完成。主要用于在存档加载完成前忽略事件。 Context.IsPlayerFree Context.IsWorldReady 且玩家能够在世界上自由活动(即,未显示任何菜单、没有任何正在播放的过场动画等)。 Context.CanPlayerMove Context.IsPlayerFree 且玩家可以自由移动(例如,玩家当前未在使用工具)。 Context.IsInDrawLoop 游戏当前是否在运行绘制循环。大多数模组都用不到它,因为大多数模组都应当使用显示事件来向屏幕绘图。
- 多人游戏:
值 含义 Context.IsMultiplayer Context.IsWorldReady 且世界已在多人游戏中被加载(无论其他玩家是否已连接)或正处于分屏模式。 Context.IsSplitScreen Context.IsMultiplayer 且 本地玩家正在使用分屏模式。不适用于远程玩家。 Context.HasRemotePlayers Context.IsMultiplayer 且 存在一个远程玩家。 Context.IsMainPlayer Context.IsWorldReady 且 当前玩家是房主。在单人游戏中此字段恒为 true。 Context.IsOnHostComputer 当前玩家是否在房主的计算机上。相当于 Context.IsMainPlayer 或 当前玩家为分屏模式的农场帮手。 Context.ScreenId 分屏模式下,当前分屏玩家的唯一 ID。主玩家的 ID 总是 0。新打开的分屏总会获得新的 ID(因此退出并重进的玩家也会获得新的 ID)。
辅助类
SDate
可以使用 SDate 以计算游戏内的日期。首先,您需要实例化一个日期:
var date = SDate.Now(); // current date
var date = new SDate(28, "spring"); // date in the current year
var date = new SDate(28, "spring", 2); // date in the given year
var date = SDate.From(Game1.Date); // from a game date
然后您就可以计算从任何日期开始的偏移:
// add days
new SDate(28, "spring", 1).AddDays(370); // 06 fall in year 4
// subtract days
new SDate(01, "spring", 2).AddDays(-1); // 28 winter in year 1
比较日期:
var a = new SDate(01, "spring");
var b = new SDate(02, "spring");
if (a < b) // true
...
获得翻译后的日期字符串:
var date = new SDate(15, "summer");
string message = $"See you on {date.ToLocaleString(withYear: false)}!"; // See you on Summer 15!
注意 SDate 不能创建无效日期:
// ArgumentException: Invalid day '30', must be a value from 1 to 28.
new SDate(30, "spring");
// ArithmeticException: Adding -1 days to 01 spring Y1 would result in invalid date 28 winter Y0.
new SDate(01, "spring", 1).AddDays(-1);
创建日期后,您可以使用如下属性:
属性 | 含义 |
---|---|
Day | 当月的第几天。 |
Season | 标准化的季节名称。 |
SeasonIndex | 从 0 计起的季节索引,用于 Utility.getSeasonNameFromNumber 等游戏方法。 |
Year | 年数。 |
DayOfWeek | 星期几(例如 Monday)。 |
DaysSinceStart | 从游戏第一天记起的天数,其中第 1 年春 1 日为 1。 |
PathUtilities
PathUtilities 提供了处理文件路径和素材名称的工具方法,以作为 .NET 的 Path 类的补充:
方法 | 使用方法 |
---|---|
GetSegments
|
将路径按分隔符切分为数组,例如 /usr/bin/example → usr 、bin 、example 。 使用示例:
string[] segments = PathUtilities.GetSegments(Constants.ExecutionPath);
|
IsSafeRelativePath
|
判断一个路径是否为相对路径且不包含目录攀升(../ ),以此确认路径确实是在父文件夹中。
|
IsSlug
|
判断字符串是否可以可以用作 slug,也就是仅包含基础字符且可安全用于所有上下文(例如文件名、URL、SMAPI ID 等)。 |
NormalizePath
|
将文件路径或素材名称标准化为当前操作系统的路径格式。例如:
string path = PathUtilities.NormalizePathSeparators(@"Characters\Dialogue//Abigail");
// Linux/Mac: "Characters/Dialogue/Abigail"
// Windows: "Characters\Dialogue\Abigail"
|
PerScreen
SMAPI 的 PerScreen<T>
工具类主要用于在分屏模式下为每个分屏玩家提供独立的变量。参见多人游戏接口的 PerScreen<T>以了解更多细节。
SemanticVersion
使用 SemanticVersion 以根据 Semantic Versioning 2.0 标准 来操作和比较版本。使用示例:
// build version from parts
ISemanticVersion version = new SemanticVersion(5, 1, 0, "beta");
// build version from string
ISemanticVersion version = new SemanticVersion("5.1.0-beta");
// compare versions (also works with SemanticVersion instances instead of strings)
new SemanticVersion("5.2").IsOlderThan("5.10"); // true
new SemanticVersion("5.10").IsNewerThan("5.10-beta"); // true
new SemanticVersion("5.1").IsBetween("5.0", "5.2"); // true
注意,1.2.0 以前的游戏版本号和某些模组版本号是非标准的(例如,星露谷物语 1.11 发布于 1.2 之前)。所有的 SMAPI 版本号都是标准的。
SButton
SMAPI 的 SButton 常量能够分别表示手柄、键盘、鼠标按键的按下或点击。参见 [[../Input|Input]] 输入接口以了解更多信息。