CraftTweaker 脚本接口

基本信息

属性 值
所属 Eternal Singularity(modid eternalsingularity)
ZenScript 类 mods.eternalsingularity(EternalRecipeTweaker.java:17)
启用条件 Loader.isModLoaded("MineTweaker3"),在 preInit(CommonProxy.java:56)
注册方式 MineTweakerAPI.registerClass(EternalRecipeTweaker.class)(行 23)

提供的脚本方法

ZenScript 签名 行为
add add(IItemStack input) 把物品加入永恒奇点聚合配方的输入
remove remove(IItemStack input) 从聚合配方输入中移除物品

两者都通过 wanion.lib.common.MineTweakerHelper.toStack(...) 把脚本物品栈转成 ItemStack,并判空后才 apply(行 28-29、34-35): itemStack != null && itemStack.getItem() != null。

ZenScript 用法

mods.eternalsingularity.add(<物品>);
mods.eternalsingularity.remove(<物品>);

底层全部作用在 CommonProxy.getEternalSingularityRecipe().getInput() 这个 ShapelessOreRecipe 的输入列表上。

可撤销性

两个动作都实现 IUndoableAction:

动作 canUndo undo
Add 恒 true getInput().remove(itemStack)
Remove itemStack != null getInput().add(itemStack)

Add.describe() 输出 Adding <名字> into Eternal Singularity Recipe., Remove.describe() 反之(行 62-69、108-115)。

getOverrideKey() 两个动作都返回 null(行 72-74、118-120), 即不参与 override key 去重。

Remove 的查找方式

Remove 的构造函数(EternalRecipeTweaker.java:81-90)就遍历输入列表, 用 ((ItemStack) input).isItemEqual(itemStackToRemove) 找第一个匹配项:

特性 说明
匹配方式 isItemEqual —— 比较物品 + 数量 + meta,不含 NBT
找到数量 仅 1 个(循环条件 itemStack == null),同种物品有多个只删一个
找不到 this.itemStack 为 null;apply() 执行 remove(null),canUndo() 返回 false

与 add 不同,remove 不判空就构造 Remove(行 35 只判了 itemStackToRemove 本身非空)。

已知源码问题

  • preInit 早退导致 NPE:EternalRecipeTweaker.init() 在 preInit 无条件注册 (CommonProxy.java:56,只判 MineTweaker3 是否加载), 但 eternalSingularityRecipe 到 postInit 才赋值(行 98)。 若 postInit 因 classSet.isEmpty() || craftingOnly 早退 (CommonProxy.java:67-70),该字段保持 null, 脚本的 add/remove 在 apply 时对 null 调 getInput() 抛 NPE。 EternalRecipeTweaker 内无任何判空(行 48、58、94、104)。
  • getOverrideKey() 返回 null:两个动作都不提供 override key, 与 MineTweaker 的 override 机制不兼容,重复 apply 同一动作无法被识别。
  • 异常被包装后重抛:CommonProxy 无 try/catch,但若 Avaritia 的 ExtremeCraftingManager 未就绪,postInit 的配方挂载(行 123)失败会直接抛出。
  • isItemEqual 不含 NBT:带 NBT 的变体奇点无法用 remove 精确删除。

相关条目