全站通知:

模组:制作指南/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]] 输入接口以了解更多信息。