• Forge论坛

导航页

  • 主页
  • 向文档做出贡献
  • 入门
    • 概述
    • 模组文件
    • 规划你的模组结构
    • 版本号
  • 核心概念
    • 注册表
    • 端位(Sides)
    • 事件
    • 模组生命周期
    • 资源
    • 国际化与本地化
  • 方块
    • 概述
    • 方块状态
  • 物品
    • 概述
    • BlockEntityWithoutLevelRenderer
  • 网络
    • 概述
    • SimpleImpl
    • 实体的同步
  • 方块实体
    • 概述
    • BlockEntityRenderer
  • 游戏特效
    • 粒子效果
    • 音效
  • 数据储存
    • Capabilities
    • Saved Data
    • 编解码器(Codecs)
  • 图形用户界面
    • 菜单(Menus)
    • 屏幕(Screens)
  • 渲染
    • 模型扩展
      • 概述
      • 根变换
      • 渲染类型
      • 部分可见度
      • 面数据
    • 模型加载器
      • 概述
      • 烘焙模型
      • 变换
      • 物品重载
  • 资源
    • 客户端资源(Assets)
      • 概述
      • 模型
        • 概述
        • 纹理色调
        • 物品属性
    • 服务端数据(Data)
      • 概述
      • 配方
        • 概述
        • 自定义配方
        • 原料
        • 非数据包配方
      • 战利品表
      • 全局战利品修改器
      • 标签
      • 进度
      • 条件性加载数据
        • 实现
        • 条件
        • 创建自定义条件
  • 数据生成
    • 概述
    • 客户端资源(Assets)
      • 模型提供者
      • 语言提供者
      • 音效提供者
    • 服务端数据(Data)
      • 配方提供者
      • 战利品表提供者
      • 标签提供者
      • 进度提供者
      • 全局战利品修改器提供者
      • 数据包注册表对象提供者
  • 杂项功能
    • 配置
    • 键盘布局
    • 游戏测试
    • Forge更新检查器
    • 调试分析器
  • 进阶主题
    • 访问转换器
  • 向Forge做出贡献
    • 概述
    • Pull Request准则
  • 旧版本
    • 概述
    • 移植到当前版本

条件性加载数据

有时,模组开发者可能希望包括一些使用来自另一个模组的信息的数据驱动的对象,而不必明确地使该模组成为依赖项。其他情况可能是,当某些对象存在时,将其与其他模组编写的条目交换。这可以通过条件子系统来完成。

实现

目前,条件加载已针对配方和进度实现。对于任何有条件的配方或进度,都会加载一个条件到数据对的列表。如果为列表中的某个数据指定的条件为true,则返回该数据。否则,将丢弃该数据。

{
  // 需要为配方指定类型,因为它们可以具有自定义序列化器
  // 进度不需要这种类型
  "type": "forge:conditional",

  "recipes": [ // 或'advancements'(对于进度)
    {
      // 要检查的条件
      "conditions": [
        // 该列表中的条件用逻辑和(AND)相连
        {
          // 条件1
        },
        {
          // 条件2
        }
      ],
      "recipe": { // 或'advancement'(对于进度)
        // 如果所有条件都成功,则使用的配方
      }
    },
    {
      // 如果上一个条件失败,则接下来要检查的条件
    },
  ]
}

通过ConditionalRecipe$Builder和ConditionalAdvancement$Builder,条件加载的数据还具有用于数据生成的包装。

条件

条件是通过将type设置为IConditionSerializer#getID指定的条件名称来指定的。

True和False

布尔条件不包含任何数据,并返回条件的期望值。它们用forge:true和forge:false来表示。

// 对于某个条件
{
  // 将始终返回true(或为'forge:false'时始终返回false)
  "type": "forge:true"
}

Not、And和Or

布尔运算符条件由正在操作的条件组成,并应用以下逻辑。它们用forge:not、forge:and和forge:or表示。

// 对于某个条件
{
  // 反转存储条件的结果
  "type": "forge:not",
  "value": {
    // 一个条件
  }
}
// 对于某个条件
{
  // 将存储条件用逻辑和(AND)相连(或为'forge:or'时将存储条件用逻辑或(OR)相连)
  "type": "forge:and",
  "values": [
    {
      // 第一个条件
    },
    {
      // 第二个要用逻辑和(AND)连接的条件(或为'forge:or'时用逻辑或(OR)连接)
    }
  ]
}

模组被加载

只要在当前应用程序中加载了具有给定id的指定模组,ModLoadedCondition就会返回true。其由forge:mod_loaded表示。

// 对于某个条件
{
  "type": "forge:mod_loaded",
   // 如果'examplemod'已被加载,则返回true
  "modid": "examplemod"
}

物品存在

只要给定物品已在当前应用程序中注册,ItemExistsCondition就会返回true。其由forge:item_exists表示。

// 对于某个条件
{
  "type": "forge:item_exists",
   // 如果'examplemod:example_item'已被注册,则返回true
  "item": "examplemod:example_item"
}

标签为空

只要给定的物品标签中没有物品,TagEmptyCondition就会返回true。其由forge:tag_empty表示。

// 对于某个条件
{
  "type": "forge:tag_empty",
   // 如果'examplemod:example_tag'是一个没有条目的物品标签,则返回true
  "tag": "examplemod:example_tag"
}

创建自定义条件

可以通过实现ICondition及与其关联的IConditionSerializer来创建自定义条件。

ICondition

任何条件只需要实现两种方法:

方法 描述
getID 该条件的注册表名称。必须等效于IConditionSerializer#getID。仅用于数据生成。
test 当条件满足时返回true。

注意

每个#test都可以访问一些代表游戏状态的IContext。目前,从注册表中只能获取标签。

IConditionSerializer

序列化器需要实现三种方法:

方法 描述
getID 该条件的注册表名称。必须等效于ICondition#getID。
read 从JSON中读取条件数据。
write 将给定的条件数据写入JSON。

注意

条件序列化器不负责写入或读取序列化器的类型,类似于Minecraft中的其他序列化器实现。

之后,应声明一个静态实例来保存初始化的序列化器,然后在RecipeSerializer的RegisterEvent期间或在FMLCommonSetupEvent期间使用CraftingHelper#register进行注册。

// 在某个序列化器类中
public static final ExampleConditionSerializer INSTANCE = new ExampleConditionSerializer();

// 在某个处理器类中
public void registerSerializers(RegisterEvent event) {
  event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS,
    helper -> CraftingHelper.register(INSTANCE)
  );
}

重要

如果使用FMLCommonSetupEvent注册条件序列化器,则必须通过 FMLCommonSetupEvent#enqueueWork将其排入同步工作队列,因为CraftingHelper#register不是线程安全的。

Built with MkDocs using a custom theme. Hosted by Read the Docs.
Enable Dark Theme