本篇教程由作者设定未经允许禁止转载。
模块化机械:社区版 从入门到入土 —— Part.3.3 机械事件系统
本篇教程皆在展示模块化机械:社区版的 CrT 的高级可用 API。
本教程主要使用的模组为模块化机械:社区版 - 1.11.1-r33、CraftTweaker。
注意:本教程内容可能随时都有变化,请仔细对照本教程使用的模组版本,以免引起模组更新导致莫名其妙的报错问题。
教程目录:
Part 3.2 配方适配器 RecipeAdapter
Part.3.3 机械事件系统(当前)
Part.4.1 并行配方处理(未完成)
Part.4.2 工厂系统(未完成)
Part.4.3 工厂事件系统(未完成)
Part.4.4 智能数据接口(未完成)
Part.4.5 单方块 / 多方块机械升级(未完成)
Part.4.6 自定义 GUI 信息(未完成)
Part.5 配置文件解析(未完成)
环境准备
本教程强烈推荐使用 Visual Studio Code(以下简称 VSCode),可以大大减少你的魔改工作量。
使用 VSCode,你可以利用它的强大的功能来更快的完成复杂的操作,同时拥有代码提示,大大减少代码阅读难度和出错率,同时可以安装插件来扩展功能,使其更加强大。
阅读本教程即代表你已熟悉 ZenScript 的大部分高级运用,并且已经了解基本的机械创建与配方创建。
安装模组
如果你已安装 CraftTweaker 和模块化机械本体且已启动游戏,你可以跳过此段描述。
介绍
MMCE 提供的事件系统允许作者更方便的编写配方的高级机制,上手简单且易用。
截止 MMCE-R33 版本,目前共有 9 个配方事件和 4 个机械事件。
本篇教程将介绍普通机械控制器的 5 个配方事件与 4 个机械事件。
配方事件
所有的配方事件都是独立的,它们只会被指定注册名的配方触发。
配方事件共有 5 种,按照触发顺序分别为 RecipeCheckEvent(配方检查事件) -> RecipeStartEvent(配方开始事件) -> RecipePreTickEvent(配方预 Tick 事件) -> RecipePostTickEvent(配方完成 Tick 事件) -> RecipeFinishEvent(配方完成事件)。
其中 RecipePreTickEvent(配方预 Tick 事件)和 RecipePostTickEvent(配方完成 Tick 事件)会被触发多次。
这些事件只能通过 RecipePrimer(配方构建器)添加。
通用 ZenGetter
所有的配方事件都可以使用这些方法。
//获取事件对应的机械配方
ActiveMachineRecipe activeRecipe
//获取触发事件的机械控制器
IMachineController getController
RecipeCheckEvent(配方检查事件)
此事件会在机械控制器扫描配方时触发,当配方满足运行条件后触发此事件。
同时,机械完成一个配方后,会继续检查此配方,当满足运行条件时也会触发一次此事件。
示例:
//为当前配方添加一个配方检查事件监听器
addCheckHandler(IEventHandler<RecipeCheckEvent> event);
# 例
import mods.modularmachinery.RecipeCheckEvent;
addCheckHandler(function(event as RecipeCheckEvent) {
//处理事件...
})
此事件还有一个额外的 ZenMethod:
//调用此方法会将配方检查设置为失败,并且会阻止其他事件监听器继续收到此事件。
//一旦被设置为失败,配方就不会开始工作,机械会继续扫描其他配方。
//reason 为机械失败的原因(支持本地化字符串)
void setFailed(String reason)
RecipeStartEvent(配方开始事件)
此事件会在机械运行配方后触发,通常在 RecipeCheckEvent 触发后触发此事件。
示例:
//为当前配方添加一个配方开始事件监听器
addStartHandler(IEventHandler<RecipeStartEvent> event)
# 例
import mods.modularmachinery.RecipeStartEvent;
addStartHandler(function(event as RecipeStartEvent) {
//处理事件...
})
RecipePreTickEvent(配方预 Tick 事件)
此事件会在配方开始 Tick(例如:能量输入输出)前触发,每个 Tick 都会触发此事件。
示例:
RecipePreTickEvent(配方预 Tick 事件):
//为当前配方添加一个配方预 Tick 事件监听器
addPreTickHandler(IEventHandler<RecipeTickEvent> event)
# 例
import mods.modularmachinery.RecipeTickEvent;
addPreTickHandler(function(event as RecipeTickEvent) {
//处理事件...
})
此事件还有两个额外的 ZenMethod:
//阻止机器增加进度(但是依然会 Tick 并消耗能量),并设置阻止原因,原因会被输出在控制器上。
void preventProgressing(String reason)
//将运行状态设置为失败,并设置失败原因。
//当 destructRecipe 为 true 时,还会取消运行配方(吞材料),false 则不会。
void setFailed(boolean destructRecipe, String reason)
RecipePostTickEvent(配方完成 Tick 事件)
此事件会在配方完成 Tick(例如:能量已消耗或输出后)后触发,每个 Tick 都会触发此事件。
示例:
RecipePostTickEvent(配方预 Tick 事件):
//为当前配方添加一个配方预 Tick 事件监听器
addPostTickHandler(IEventHandler<RecipeTickEvent> event)
# 例
import mods.modularmachinery.RecipeTickEvent;
addPostTickHandler(function(event as RecipeTickEvent) {
//处理事件...
})
此事件还有两个额外的 ZenMethod:
//阻止机器增加进度(但是依然会 Tick 并消耗能量),并设置阻止原因,原因会被输出在控制器上。
void preventProgressing(String reason)//将运行状态设置为失败,并设置失败原因。
//当 destructRecipe 为 true 时,还会取消运行配方(吞材料),false 则不会。
void setFailed(boolean destructRecipe, String reason)
RecipeFinishEvent(配方完成事件)
此事件会在配方完成后触发,只会触发一次。
示例:
# 例
import mods.modularmachinery.RecipeFinishEvent;
addFinishHandler(function(event as RecipeFinishEvent) {
//处理事件...
})
机械事件
所有的机器事件都是独立的,它们只会被指定注册名的机器触发。
这些事件监听器可以通过 MMEvents 或 MachineBuilder 来添加。
通用 ZenGetter
所有的机械事件都可以使用这些方法。
//获取触发事件的机械控制器
IMachineController getController
MachineStructureFormedEvent(机械结构形成事件)
当机械控制器形成结构时,触发此事件。
示例:
//形成结构事件
MMEvents.onStructureFormed(String machineRegistryName, IEventHandler<MachineStructureFormedEvent> function)
# 例
MMEvents.onStructureFormed("tokmak_reactor", function(event as MachineStructureFormedEvent) {
//处理事件...
});
MachinePreTickEvent(机械预 Tick 事件)
当机械形成结构时,在机械逻辑开始前触发此事件。
示例:
//预 Tick 事件
MMEvents.onMachinePreTick(String machineRegistryName, IEventHandler<MachineTickEvent> function)
# 例
MMEvents.onMachinePreTick("tokmak_reactor", function(event as MachineTickEvent) {
//处理事件...
});
MachinePostTickEvent(机械完成 Tick 事件)
当机械形成结构时,机械逻辑执行完成后触发此事件。
示例:
//完成 Tick 事件
MMEvents.onMachinePostTick(String machineRegistryName, IEventHandler<MachineTickEvent> function)
# 例
MMEvents.onMachinePostTick("tokmak_reactor", function(event as MachineTickEvent) {
//处理事件...
});
ControllerGUIRenderEvent(控制器 GUI 渲染事件)
当客户端打开对应机械的控制器时触发此事件,允许作者向控制器添加自定义信息。
示例:
//控制器 GUI 渲染事件
MMEvents.onControllerGUIRender(String machineRegistryName, IEventHandler<ControllerGUIRenderEvent> function)
# 例
MMEvents.onControllerGUIRender("tokmak_reactor", function(event as ControllerGUIRenderEvent) {
//处理事件...
});
此事件还有一个额外的 ZenGetter 与 ZenSetter:
//获取或设置额外信息数组
String[] extraInfo
SmartInterfaceUpdateEvent(智能数据接口更新事件)
当控制器绑定的智能数据接口内部的数据更新后,触发此事件。
示例:
//智能数据接口更新事件
MMEvents.onSmartInterfaceUpdate(String machineRegistryName, IEventHandler<SmartInterfaceUpdateEvent> function)
# 例
MMEvents.onSmartInterfaceUpdate("tokmak_reactor", function(event as SmartInterfaceUpdateEvent) {
//处理事件...
});
此事件还有两个额外的 ZenGetter:
//获取触发事件的智能数据接口的位置
IBlockPos interfacePos
//获取更新的数据
SmartInterfaceData newData