维护提醒

BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。

全站通知:

模组:制作指南/APIs/Content Packs

来自星露谷物语维基
跳到导航 跳到搜索

模组:目录

内容包(content pack)是一种特殊的模组,它不直接由 SMAPI 运行,但包含您的模组可以读取的文件。

内容包格式

内容包是一个文件夹,它包含一个 manifest.json 文件,该文件的 ContentPackFor 列出了需要读取该内容包的模组(参见[[../Manifest|清单文件]])。除此之外的格式由您自定定义。例如,Content Patcher 需要一个 content.json 文件,但 SMAPI 并不会直接验证它。与之相对地,SMAPI 会提供一个接口,以让您从内容包中读取所需的其他文件。

参见模组:内容包以获取关于内容包的更多信息。

内容包接口

获取拥有的内容包

可以按如下方式获取针对您模组的、已安装的内容包(其中 Manifest 字段包含了内容包的完整清单信息):

foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
{
   this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
}

内容包会按照加载顺序列出,因此已经按照依赖关系排序。例如,如果内容包B 依赖于内容包A,则会按照 A → B 的顺序列出。

注意,您可以早在 ModEntry 中调用此方法,但是模组经常在 GameLoad 或 SaveLoaded 事件中调用此方法。

检查文件是否存在

您可以使用 HasFile 来检查内容包中是否存在某文件。可以使用相对路径,例如 data/content.json

if (!contentPack.HasFile("content.json"))
{
   // show 'required file missing' error
}

在部署时,如果有文件缺失,建议您提醒玩家(和使用您模组的开发者)。

读取 JSON 文件

您可以使用 ReadJsonFile 来把 JSON 文件读入数据模型(在下面的例子中,为 YourDataModel)。您可以使用相对路径,例如 data/content.json。如果文件不存在,则返回 null

YourDataModel data = contentPack.ReadJsonFile<YourDataFile>("content.json");

写入 JSON 文件

您可以使用 WriteJsonFile 来把数据模型(在下面的例子中,为 YourDataModel)中的数据写入到 JSON 文件。您可以使用相对路径,例如 data/content.json(如果需要,会自动创建子目录)。若文件不存在,则会创建相应文件;若存在,则会覆写。

注意:这最好用于生成文件。不建议覆写文件,因为如果您的模组存在漏洞,则可能永久损坏内容包,使得玩家不得不重新安装。

YourDataModel data = new YourDataModel();
contentPack.WriteJsonFile("content.json", data);

读取内容素材

您可以使用 LoadAsset 从内容包文件夹中读取 内容素材。您可以指定相对路径以从子文件夹中读取。

Texture2D image = contentPack.ModContent.Load<Texture2D>("image.png");

如果您需要将某个素材名称传入游戏代码,您可以使用 GetActualAssetKey 方法:

tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png");

获取翻译

您可以从内容包的 i18n 文件夹读取翻译。这与翻译接口相同,不同点在于调用的是 contentPack.Translations

string text = contentPack.Translation.Get("item-type.label");

创建伪内容包

在某些特殊情况下,您可以在指定文件路径下创建临时内容包:

// create with random manifest data
IContentPack contentPack = this.Helper.ContentPacks.CreateFake(
   directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
);

// create with given manifest fields
IContentPack contentPack = this.Helper.ContentPacks.CreateTemporary(
   directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
   id: Guid.NewGuid().ToString("N"),
   name: "temporary content pack",
   description: "...",
   author: "...",
   version: new SemanticVersion(1, 0, 0)
);