本篇教程由作者设定未经允许禁止转载。
模块化机械:社区版 从入门到入土 —— Part.3.1 高级配方运用
本篇教程皆在展示模块化机械:社区版的 CrT 的高级可用 API。
本教程主要使用的模组为模块化机械:社区版 - 1.11.1-r33、CraftTweaker。
注意:本教程内容可能随时都有变化,请仔细对照本教程使用的模组版本,以免引起模组更新导致莫名其妙的报错问题。
教程目录:
Part.3.1 高级配方运用(当前)
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 和模块化机械本体且已启动游戏,你可以跳过此段描述。
要创建配方,你需要使用 CraftTweaker(任意版本)。
要查看创建的配方,你需要使用 JEI(任意版本)。
高级 API
高级 API 允许你使用 CraftTweaker 来创建更丰富的机械机制和功能。
RecipeModifierBuilder
RecipeModifierBuilder 可以用来构建 RecipeModifier,而 RecipeModifier 是用来动态修改配方输入输出的关键。
导包:
import mods.modularmachinery.RecipeModifierBuilder;
RecipeModifierBuilder 提供了两种用法:
RecipeModifierBuilder.newBuilder()
//type = 要应用 RecipeModifier 的类型
//ioTypeStr = RecipeModifier 会应用到输入还是输出?("input" 为输入,"output" 为输出)
//value = RecipeModifier 的数值 (类型为 float)
//operation = RecipeModifier 数值会用哪种方法计算?(0 为加,1 为乘,默认 0)
//affectChance = RecipeModifier 是否应用到概率上?(true 为应用,false 为不应用,默认 false)
RecipeModifierBuilder.create(String type, String ioTypeStr, float value, int operation, boolean affectChance)
两种方法最终创建的内容都相同。
RecipeModifierBuilder 用例:
//Builder 模式
RecipeModifierBuilder.newBuilder()
# 定义要应用 RecipeModifier 的类型
.setRequirementType("modularmachinery:energy")
# 这个 RecipeModifier 会应用到输入还是输出?("input" 为输入,"output" 为输出)
.setIOType("input")
# RecipeModifier 数值会用哪种方法计算?(0 为加,1 为乘,默认 0)
.setOperation(1)
# 定义 RecipeModifier 的数值 (类型为 float)
.setValue(0.1)
# RecipeModifier 是否应用到概率上?(true 为应用,false 为不应用,默认 false)
.isAffectChance(false)
# 构建 RecipeModifier,同时检查上方参数的合法性
.build();
//快速构建模式
RecipeModifierBuilder.create("modularmachinery:energy", "input", 0.1, 1, false).setValue(0).build();
^
//create() 后方也可以调用上方方法内容
IMachineController
IMachineController 是 MMCE 专门为 CraftTweaker 提供的接口,它提供了大量直接对控制器进行操作的功能。
IMachineController 可以通过绝大部分机械事件获取。
接口方法列表:
ZenGetter:
//获取控制器所在的世界。
IWorld world
//获取控制器方块状态。
IBlockState blockState
//获取控制器方块的位置。
IBlockPos pos
//获取机械在当前世界运行的时间(非世界时间,进入退出世界会被重置)
int ticksExisted
//获取控制器正在运行的配方列表,始终会返回一个数组(不会返回 null)。
//普通机械始终会返回一个大小为 1 的数组(但是内容有可能是 null),工厂则会返回任意大小的数组且所有内容非 null(可能会返回空数组)。
ActiveMachineRecipe[] activeRecipeList
//机器是否在运行,如果运行返回 true,反之 false。
boolean isWorking
//控制器形成的机械结构注册名(例如:"modularmachinery:machine_1"),如果为形成结构则返回 null。
//注意:是 "modularmachinery:machine_1" 而不是 "machine_1"!
String formedMachineName
//获取自定义数据,ZenScript 可以用来存储数据,且数据在游戏关闭时会被保存在 NBT 内。
IData customData
//获取控制器绑定的所有智能数据接口数据
//此方法会返回一组智能数据接口的内部数据,如果没有则为空数组,但绝不会为 null
SmartInterfaceData[] smartInterfaceDataList
//获取控制器找到的机械升级
//注:返回的是一组字符串数组,内容为机械升级的注册名。
String[] foundModifiers
ZenSetter:
//保存自定义数据,当获取的自定义数据被更改时需要调用此方法。
IData customData
//覆盖控制器当前的状态消息
String statusMessage
ZenMethod:
//向控制器添加一个自定义名称的 RecipeModifier,并且会被同步到正在运行的配方上。高级 CrT 配方方法大全
void addModifier(String key, RecipeModifier modifier);
//向控制器删除对应名称的 RecipeModifier。
void removeModifier(String key);
//检查控制器是否已存在对应名称的 RecipeModifier,true 为存在,反之 false。
boolean hasModifier(String key);
//获取控制器绑定的指定智能数据接口数据。
//返回值可能为 null。
SmartInterfaceData getSmartInterfaceData(String type);
//获取机械中是否已找到指定的注册名的机械升级。
boolean hasModifierReplacement(String modifierName);
杂项:
//设置配方预览时显示的 NBT,不影响配方 NBT 匹配
setPreViewNBT(IData nbt)
# 例
addItemInput(<botania:terrapick>).setPreViewNBT({mana: 100000})
//为配方添加 JEI 提示
addRecipeTooltip(String... tooltips)
# 例(支持一次性传入多个提示)(注:不支持未本地化名,如需要本地化,请自行处理未本地化名)
addRecipeTooltip("输出有概率翻倍。", "有概率不消耗能量。")
催化剂:
催化剂是一种特殊的物品输入,它可以在检查配方并符合要求时给目标配方添加一组半永久性的 RecipeModifier,并且是可选输入。
//添加催化剂输入
//tooltips = JEI 鼠标提示,为数组,可以传入多个
//modifiers = 配方修改器,为数组,可以传入多个
addCatalystInput(IIngredient input, String[] tooltips, RecipeModifierBuilder[] modifiers)
# 例
addCatalystInput(<avaritia:resource:5>, ["无尽催化剂作为催化剂输入时,能量消耗降低 90%"], [RecipeModifierBuilder.create("modularmachinery:energy", "input", 0.1, 1, false)]);
自定义 NBT 检查器:
自定义 NBT 检查器允许你通过 ZenScript 来检查物品是否匹配相应的 NBT。
用法:
//设置自定义 NBT 检查器(仅限物品类型输入)
setNBTChecker(IMachineController controller, AdvancedItemNBTChecker checker)
# 例
import crafttweaker.item.IItemStack;
import mods.modularmachinery.IMachineController;
addItemInput(<botania:terrapick>).setNBTChecker(function(ctrl as IMachineController, item as IItemStack) {
val nbt = item.tag.asMap();
if (nbt["mana"].asInt() > 1919810) {
# 返回 true 即为匹配
return true;
} else {
# 返回 false 即为不匹配
return false;
}
})
自定义物品修改器:
自定义物品修改器允许你通过 ZenScript 来修改物品的输入输出内容。
//设置自定义物品修改器(仅限物品类型输入输出)
addItemModifier(IMachineController controller, AdvancedItemModifier modifier)
# 例
import crafttweaker.item.IItemStack;
import mods.modularmachinery.IMachineController;
addItemInput(<botania:manaresource:4>).addItemModifier(function(ctrl as IMachineController, oldItem as IItemStack) as IItemStack {
if (oldItem.amount >= 2) {
# 返回新的物品
return <botania:manaresource:4> * 4;
} else {
# 返回新的物品
return <botania:manaresource:4> * 2;
}
})