本篇教程由作者设定未经允许禁止转载。

花了几天时间自行翻译并润色,觉得有用别忘了评论一下让我知道有人会看QAQ

贴出wiki地址:https://artisan-worktables.readthedocs.io/en/latest/

欢迎来到工匠之作Artisan Worktables

AW为整合包作者提供各种主题的工作台,由于它就是为魔改整合包准备的模组,本身并没有太多的合成表,目的是让作者们用CRT自由整活,另外同JEI和GameStages(游戏阶段)梦幻联动。

 

模组特点

工匠台添加了各种各样的功能,如此将原版工作台从过劳死中拯救出来::

1.    引入“工具合成”概念,除了合成槽,还有着额外的工具槽

2.    九宫格属实拉了,咱最高可到5*5

3.    引入“流体合成”概念,将流体输入流体槽参与合成

4.    可设置输出副产物(给玩家一些小惊喜)

5.    可设置输入次级材料参与合成(喜提折磨王)

6.    可设置合成配方时有经验要求

7.    可视化合成!可将配方复制到剪贴板(魔改人狂喜)

8.    开启自动化飞升,当然前提是你得下载Artisan Automation(已经上传了,待审核)

9.    支持CRT


注意各种名词

[名词]工匠台:即AW里所有工匠工作台的总称,防止与原版工作台相混淆,以下皆称如此。

[名词]配方(recipe):其实也就是合成表,只不过咱常把脚本里编写的合成叫做配方,JEI里显示的叫做合成表,为了避免有歧义,以下皆称如此。

[名词]设计台:用于一些与蓝图有关的合成的工匠台。

[名词]槽(slot):可以往其中放物品的格子(为什么不直接翻译成“格子”呢?试想“流体格”、“工具格”是不是会听起来很奇怪)


工具箱

默认情况下,“工具箱”和“机械工具箱”只能用来存储合成工匠台配方所使用的工具,并且拆掉之后箱子里的东西也能保存

它们都是可以更改配置的,从而使其中能存储任何物品。

跟工匠台相连后,机械工具箱可以自动替换其中用完耐久的工具。


设计蓝图

先将设计台紧挨在任何工匠台旁边,再打开工匠台,其左侧将会出现“蓝图槽”,里面包括输入和输出。

如果想使用蓝图槽,需要先把配方在工匠台里面摆好,这个合成表必须是有效的(也就是JEI可以查到并且能合成的),再在左侧的输入槽放一张空白蓝图,之后就可以从右侧输出槽中取出一个编辑好了的蓝图啦!

完成后的蓝图包含有配方名称的NBT,你可以把它作为其他配方里的合成材料。同时也能用各种方式让玩家获得这些蓝图,比如战利品(LootTables)、任务奖励等。

拿在主手Shift+右键,可以清空蓝图内容。

一张完成的蓝图,它的NBT结构如下:

<namespace:path>.withTag({

    ArtisanWorktables: {

        RecipeName: "your_recipe_name"

    }

});

注意!有一点wiki上并没有明说,是自己通过实践测试出来的:

想要设计一个蓝图,其配方必须是本模组编写的,亲手试过,原版配方并不能在游戏中设计成蓝图

但是好消息是,你仍然可以通过修改蓝图NBT里“RecipeName”的方式添加配方,这就要用到for循环了。


和其他模组联合使用(待翻译)

https://artisan-worktables.readthedocs.io/en/latest/integrations/

https://artisan-integrations.readthedocs.io/en/latest/


锁定合成槽

通过锁定合成槽,来让工匠台记住其中物品的位置。

工匠之作wiki全文(个人翻译并润色)-第1张图片

想要解锁或锁定,就点击上图图示的按钮吧。

工匠之作wiki全文(个人翻译并润色)-第2张图片

咱给它锁定了以后,会看见锁定槽出现绿色标识。

锁定合成槽有啥用呢?

工匠之作wiki全文(个人翻译并润色)-第3张图片


被锁定的地方,即便是物品被移走,工作台也仍然能记住它的位置。

如此一来,Shift+左键点击一堆物品时,就能均匀的分布上去。

也许你现在心里这样想:“就这就这就这?”

下面请看这个功能的真正用处

 

半自动化

当你给它锁定后,就可以将物品输入进合成槽中


0级工匠台

顶部输入---进入主要合成槽

侧面输入---进入主要合成槽


1级工匠台(可有流体参与合成)

顶部输入---进入次级合成槽

侧面输入--- 进入主要合成槽

流体想从哪面输入就从哪面输入

 

可惜物品不能自动输出,所以这不能算是真正意义上的自动化

 

真 · 自动化

想要自动化飞升?快去下载Artisan automation吧!

https://www.curseforge.com/minecraft/mc-mods/artisan-automation(一键飞升)


脚本速查

放在结尾


工具

AW有很多可用于参与合成的工具(有独立的工具槽)。

 工匠之作wiki全文(个人翻译并润色)-第4张图片

只有将TableMode改为创造,你才能编辑工匠台的工具槽。

具体步骤分三步走:

1.      首先,你本身必须是创造模式

2.      接下来,打开工匠台的GUI

3.      最后,点击图示按钮,将工匠台模式更改为“创造”


添加配方

切换“工匠台模式(Table Mode)”为“创造”后:

1.      工匠台将不再是合成模式,而是切换为编辑模式(添加合成表)

2.      允许你往任何槽内放置物品(合成槽放完,再放输出槽,以此指定此合成能输出什么)

3.      对输入槽内物品Shift+左键可以在其OreDict中循环选择,从而更改它的矿物词典(没看懂没关系,待会下面会单独解释)

4.      左键槽内物品就可以把它移除

5.      在输出槽放入准备让配方输出的物品后,点击“输出有序/无序”按钮即可

 

输出有序/无序配方

工匠之作wiki全文(个人翻译并润色)-第5张图片

工匠之作wiki全文(个人翻译并润色)-第6张图片

点击“输出有序/无序”按钮后,就能得到一条配方脚本,它会自动复制进剪贴板,咱直接粘贴到脚本文件即可添加合成(可视化编辑!就是方便!)

 

下列这些参与合成的东西,都能成为脚本的一部分,进到剪贴板里

1.      参与合成的流体(输入)

2.      参与合成的材料(输入)

3.      参与合成的次级材料(输入)

4.      工具槽中的工具(输入)

5.      合成得到的物品(输出)

6.      合成得到的副产物(输出)

 

选择矿物词典(OreDict)

工匠之作wiki全文(个人翻译并润色)-第7张图片

对应前面说的“对输入槽内物品Shift+点击可以在其OreDict中循环选择,从而更改它的矿物词典”

关于这些矿物词典到底是啥,看到后面就理解了

 

两种选择模式

工匠之作wiki全文(个人翻译并润色)-第8张图片

东西太多,爷不想一个一个设置它们的矿典咋办?这里提供了两种模式来助你节约生命:Linked和Unlinked

默认情况下,OreDict模式为Linked,即“连接”,这样当你Shift+点击物品时,可以让所有相同类型的物品(输入槽里的)同步选择。也就是多个输入槽中都放了一样的物品时,只需要改一个物品的矿物词典,其他的也会跟着同步改变。

Unlinked可以让你对每个物品都独立选择自己的OreDict。

 

全部木大

工匠之作wiki全文(个人翻译并润色)-第9张图片

点这个按钮清空所有槽里的物品


入门指南(开始写脚本啦!)

AW就是专门为CRT魔改整合包而设计的mod,不整点脚本,天理不容!

关于CRT的教程,具体可见友谊妈之https://crt.imc.wiki/Zen/

 

添加配方

导包

import mods.artisanworktables.builder.RecipeBuilder;

然后选择合成用的工匠台

RecipeBuilder.get("basic");    //“basic”处指的是工匠台的名称,这里即“基础工匠台”,最后列了张表方便大家查看
 
如下是通过声明变量的方式编写配方
import mods.artisanworktables.builder.RecipeBuilder;
 
val builder = RecipeBuilder.get("basic");         //将工匠台变成变量,这样就不必写一堆啦
builder.setShapeless([<minecraft:dirt>]);
builder.addOutput(<minecraft:cobblestone>);
builder.create();

 

然而并不是所有人都喜欢用变量的方式编写。

也许此时就有人在想:“变量你就是歌姬吧!”

AW还提供了另一种编写方式

不需要变量的长链式

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .create();


各有各的好处

变量式

import mods.artisanworktables.builder.RecipeBuilder;
 
val builder = RecipeBuilder.get("basic");
builder.setShapeless([<minecraft:dirt>]);
builder.addOutput(<minecraft:cobblestone>);
builder.create();
 
builder.setShapeless([<minecraft:wool>]);
builder.addOutput(<minecraft:stone>);
builder.create();
 
builder.setShapeless([<minecraft:log>]);
builder.addOutput(<minecraft:dirt>);
builder.create();
 
builder.setShapeless([<minecraft:grass>]);
builder.addOutput(<minecraft:dirt>);
builder.create();

长链式

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
    .setShapeless([<minecraft:dirt>])
    .addOutput(<minecraft:cobblestone>)
    .create();
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .create();
 
 
RecipeBuilder.get("basic")
    .setShapeless([<minecraft:wool>])
    .addOutput(<minecraft:stone>)
    .create();
 
RecipeBuilder.get("basic")
    .setShapeless([<minecraft:log>])
    .addOutput(<minecraft:dirt>)
    .create();
 
RecipeBuilder.get("basic")
    .setShapeless([<minecraft:grass>])
    .addOutput(<minecraft:dirt>)
    .create();

(小朋友们开动脑筋对比一下两者的不同点,很简单我就不说了,写出来还挺麻烦的,说白了还是条懒狗)

 

几个小细节还是不得不说:

为什么长链式的配方只有最后的.creat();后有“;”呢?

因为长链式的配方实际上是一整条语句,只是为了增加可读性从而分段

本来孩子应该长这样:

RecipeBuilder.get("basic").setShapeless([<minecraft:dirt>]).addOutput(<minecraft:cobblestone>).create();

生出来之后给大伙看蒙了,你这玩意有本事再长点啊?

来小亮,给他整个活!

RecipeBuilder.get("basic").setShaped([[<minecraft:cobblestone>, <minecraft:cobblestone>, <minecraft:cobblestone>],[<minecraft:cobblestone>, null, <minecraft:cobblestone>],[<minecraft:cobblestone>, <minecraft:cobblestone>, <minecraft:cobblestone>]]).addOutput(<minecraft:furnace>).setSecondaryIngredients([<minecraft:gravel> * 8, <minecraft:string>]).setMinimumTier(2).setExtraOutputOne(<minecraft:string>, 0.75).setExtraOutputTwo(<minecraft:diamond>, 0.25).addTool(<ore:artisansHammer>, 10).setLevelRequired(30).setConsumeExperience(false).create();

所以咱就叫它“长链式”吧!

 

变量式适合有“一个脚本文件对应一个工匠台”的习惯的人编辑,因为你只需要写一次变量

val builder = RecipeBuilder.get("basic");

之后只需引用变量即可

缺点在于不灵活

 

长链式相对而言更加的灵活与独立,每条配方你都能单独设置工匠台

也因如此每条配方你都得写一遍RecipeBuilder.get("basic");

好处嘛,让配方看起来排列整齐,有头有尾

缺点也显而易见,灵活过头了就容易导致混乱的发生,有时候你都不知道在一个脚本里头自己加了多少工匠台

因此建议亲亲两个方式结合起来用哦

 

完成配方

 “.create();”是一定要有的,正如山东不能失去菏泽曹县,配方决不能漏掉“.create()”,它可是配方的“句号”,完成配方的标志,为创建更多的配方做好准备。


基本合成

众所周知:

1.      配方至少要有输入和输出

2.      配方类型有有序和无序

前面说过了编写AW脚本你会用到的两种整体结构

接下来看一下具体的语句

 

添加有序配方

RecipeBuilder setShaped(IIngredient[][] ingredients);

添加镜像配方(不懂什么叫镜像给爷去看CRT教程)

RecipeBuilder setMirrored();

 

举个栗子

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShaped([
    [<minecraft:cobblestone>, <minecraft:cobblestone>, <minecraft:cobblestone>],
    [<minecraft:cobblestone>, null, <minecraft:cobblestone>],
    [<minecraft:cobblestone>, <minecraft:cobblestone>, <minecraft:cobblestone>]])
  .addOutput(<minecraft:furnace>)
  .create();

 

无序配方

RecipeBuilder setShapeless(IIngredient[] ingredients);

 

梅开二度

import mods.artisanworktables.builder.RecipeBuilder;

RecipeBuilder.get("basic")
  .setShapeless([<ore:logWood>])
  .addOutput(<minecraft:planks>)
  .create();

配方名称

为你自己着想,最好给每个配方都整一个名字

要是你没给它起名,在默认情况下,系统会尝试分配给配方一个独特的名字

配方名称可用于设计蓝图、NBT之类的

 

给配方命名

RecipeBuilder setName(String name);

给配方命名真的能提供很多便利,而且若是你主动给配方命的名的话,系统是不会更改的(大概意思就是:系统自动分配的配方的名称,可能会被系统更改)

另外注意,配方名称尽量别重复(要不然系统就给你个大逼兜)

其实这也不是什么大事,检测到重复后,先警告,之后就会给你擦屁股:给重复名后面加一个数字


工匠台等级

工匠台有三种等级:工作台、工作站、工作坊

等级

主要槽数

工具

流体容量

次级槽数

工作台(0)

3x3

1

4,000mb

0

工作站(1)

3x3

2

8,000mb

9

工作坊(2)

5x5

3

16,000mb

9

 

设置合成配方的工匠台的最低等级

RecipeBuilder setMinimumTier(int minimumTier);

设置合成配方的工匠台的最高等级

RecipeBuilder setMaximumTier(int maximumTier);

minimumTier和maxmumTier内的值就在上表的等级列里(0/1/2  台/站/坊)

 

举例时间到!

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .setMinimumTier(2)
  .create();

最小等级是2,也就是5*5的工作坊,即便配方是3*3以内的,也只能在工作坊里合成

 

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .setMaximumTier(0)
  .create();

而这个配方就只能在3*3的工作台里合成


让工具参与合成

最开始AW是想着单纯引入“工具参与合成”这一概念,随着逐渐发展,现在已经能达到最多使用三个工具参与合成,当然你在设计配方的时候也可以选择不加工具。这边建议最好在工具方面设置的时候人性化一点,避免游玩过程过于冗长。(除非你想喜提“折磨王”)

 

加入工具

RecipeBuilder addTool(IIngredient tool, int damage);

“damage”表示合成一次会消耗工具多少耐久

 

来举个栗子吧

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .addTool(<ore:artisansHammer>, 10)
  .create();

 

最多可以添加三个工具

import mods.artisanworktables.builder.RecipeBuilder;

RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .addTool(<ore:artisansHammer>, 10)
  .addTool(<ore:artisansAthame>, 5)
  .addTool(<ore:artisansQuill>, 13)
  .create();

矿物词典

还记得前面说过的工具矿典吗,恭喜你熬过来了!

先看看各种工具的有效名(部分)

<ore:artisansAthame>
<ore:artisansBeaker>
<ore:artisansBurner>
<ore:artisansCarver>
<ore:artisansChisel>
<ore:artisansCompass>

在这儿你会发现一个小细节:每个工具都有ore前缀,这代表它们有自己的矿典,AW提供两种类型的矿典组,即按工具类型分类和按工具材料分类

工匠之作wiki全文(个人翻译并润色)-第10张图片

正如之前所说的,对输入槽的物品Shift+左键能更改它的矿物词典,有三个选项:

1.      none,即不用矿典,只用这个工具合成

2.      工具的类型,图中是锤子,即任意锤子就能合成,不管你是钻石的还是石头的

3.      工具的材料,图中是钻石,即任意钻石材质的工具就能合成

 

各种工具的有效名(具体列表放在最后)

阿巴阿巴


工具材料的有效名

以artisansTool 为起始,后接材料名(首字母大写)

如<ore:artisansToolWood> 、 <ore:artisansToolStone>

 

获取完整材料组的列表,请看config/artisanworktables/文件夹里的以下文件

artisanworktables.module.Tools.Materials.Generated.json

(没有必要搁这下太多时间,毕竟人家是可视化合成,又不需要你自己编写)


副产物

一个配方最多可设置三种副产物,让玩家在进行合成操作时,有概率获得。

当生成副产物时,它们会出现在GUI的最右边,三个副产物槽中的其中一个槽里。

要是副产物槽满了,导致副产物没办法被放进去的话,那么它们就会从工匠台里弹出来(当 面 脱 出)

 

给配方添加副产物

RecipeBuilder setExtraOutputOne(IItemStack output, float chance);   
RecipeBuilder setExtraOutputTwo(IItemStack output, float chance);
RecipeBuilder setExtraOutputThree(IItemStack output, float chance);

其中,“chance”是在[0,1]区间范围内的浮点类型值,浮点数也就是小数的意思

 

你这栗子保熟吗

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .setExtraOutputOne(<minecraft:string>, 0.75)
  .setExtraOutputTwo(<minecraft:diamond>, 0.25)
  .create();

此配方有75%的概率掉落线,还有25%的概率掉落钻石


主要输出权重

相比原版工作台,工匠台所具有颠覆性的一点是:它可以输出不止一件东西。这可能是很多玩家想都没想到的(这tm不就是抽卡?)

既然是输出多个,那必然要有“概率”这一概念,而加权,就是设置哪个东西被输出的概率更高,哪个更低

当你只是输出一个东西的时候,那概率肯定就是100%咯

而你想输出多个物品时,就要开始给它们加上权重了(weight)

RecipeBuilder addOutput(IItemStack output, @Optional int weight);

权重是可选参数,如果配方只输出一个,weight不必写,还是原汁原味的addOutput

输出多个的话,weight其实也可以不写,那么这样就是告诉系统,把概率平摊

 

嗨嗨嗨,栗子来了奥

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .addOutput(<minecraft:diamond>)
  .create();

以上是没填weight参数例子,于是系统就让两个物品各有50%的概率被制作出来

 

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>, 90)
  .addOutput(<minecraft:diamond>, 10)
  .create();

加上权重,系统就按权重输出


次级材料

也是合成所需要的物品,但是它们并不放在合成槽中,而是在GUI下方的次级槽里

工作站和工作坊最多支持9个次级材料

 

给配方添加次级材料

RecipeBuilder setSecondaryIngredients(IIngredient[] secondaryIngredients);

 

如果希望配方中用到次级材料,却不消耗掉的话

RecipeBuilder setConsumeSecondaryIngredients(boolean consumeSecondaryIngredients);

括号内为布尔值true与false

 

啊哈哈哈,栗子来咯

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .setSecondaryIngredients([<minecraft:gravel> * 8, <minecraft:string>])
  .addOutput(<minecraft:cobblestone>)
  .create();

设置合成时要有次级材料 砂砾和线的参与

 

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .setSecondaryIngredients([<minecraft:gravel> * 8, <minecraft:string>])
  .setConsumeSecondaryIngredients(false)
  .addOutput(<minecraft:cobblestone>)
  .create();

与上例一样,不同之处在于此配方不消耗次级材料


经验需求

可以设置合成时是否有经验上的需求,如有需要的话,还可以进一步设置是否消耗经验和其消耗数量

 

为配方添加经验需求

RecipeBuilder setExperienceRequired(int experienceRequired);    //经验上的需求
RecipeBuilder setLevelRequired(int levelRequired);    //等级上的需求

 

默认情况下,当设置了经验需求后,合成配方将会消耗经验或等级,你可以进一步设置选择是否会消耗掉相对应的经验

RecipeBuilder setConsumeExperience(boolean consumeExperience);

 

栗子

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .addOutput(<minecraft:cobblestone>)
  .setExperienceRequired(20)
  .create();

合成配方将消耗20经验

 

import mods.artisanworktables.builder.RecipeBuilder;
 
RecipeBuilder.get("basic")
  .setShapeless([<minecraft:dirt>])
  .setLevelRequired(30)
  .setConsumeExperience(false)
  .addOutput(<minecraft:cobblestone>)
  .create();

这里则是要求玩家只有在30级的时候才能合成,不过不会消耗经验


隐藏配方

这样玩家就没法在JEI上找到合成表了

RecipeBuilder setHidden(@Optional(default = true) hidden);

Hidden一开看不见…


拷贝配方(重新翻译)

为什么叫做“重新翻译”呢?

之前翻译到这里的时候,感觉状态不佳,一时间没仔细看,导致以为这块很难搞,再加上前文也没有提到过这里,就轻易下了“这块不重要”的结论,只是随便翻译了就没再管。

今天偶然重新翻阅,经过仔细研读,终于基本理解,这才发现这里对于魔改相当重要,这块可以帮助你用恰当的方法就可以减少很多工作量。


任何与合成有关的都必须有RecipeBuilder.get("basic")

拷贝配方是一个非常好用的方式,学会了之后可以批量魔改已有的配方

具体原理就是:先拷贝配方,然后根据需要对这个配方进行修改

别忘记导包

import mods.artisanworktables.builder.Copy;

 
设置拷贝

RecipeBuilder setCopy(Copy copy);

它与RecipeBuilder setShaped()相当

只是setCopy是更改现有的配方

而setShaped是添加配方

本质上都与合成有关,既然与合成有关,就与工匠台有关,则就要有RecipeBuilder.get("basic")

正如任何合成语句都要在setShaped里

任何与拷贝合成有关的语句都要放在setCopy里

 

拷贝配方

提供了三种拷贝方法

Copy byName(String recipeName);   //通过配方名称
Copy byRecipe(ICraftingRecipe recipe);     //通过ICraftingRecipe类型
Copy byOutput(IIngredient[] outputs);      //通过输出物

第一种最常用

第三种可能会拷贝到多个配方,毕竟一个物品也许有很多种配方

 

拒绝配方输入材料

Copy noInput();

用法

builder.setCopy(Copy.byName("minecraft:furnace").noInput());

如果拒绝材料输入的话,相当于只拷贝了配方的输出物品,那么就得给配方提供输入,如.addShaped

它与以下方法互斥

noOutput()   //总不可能既拒绝输入又拒绝输出吧,那还拷贝什么?
replaceInput(IIngredient, IIngredient)
replaceShapedInput(int, int, IIngredient)

 

替换配方输入材料

复制配方后,可以对配方的每个合成槽里的材料进行替换

Copy replaceInput(@Nullable IIngredient toReplace, @Nullable IIngredient replacement);
Copy replaceShapedInput(int col, int row, @Nullable IIngredient replacement);

第一个条根据材料替换,逗号前写要把什么材料替换,逗号后写替换为哪种新材料(逗号前写Null就是“把所有空的槽替换成XXX”;逗号后写Null就是“把这一材料替换成空槽”)

第二条则是通过行列替换,col列row行

上述替换方法仅适用于3*3

写着@Nullable的皆可为空,只是replaceInput只能空一个(全空的话那有什么意义?)

整个栗子看看

RecipeBuilder.get("basic")
    .setCopy(
        Copy.byName("minecraft:furnace")
            .replaceInput(null, <ore:stickWood>) 
            .replaceShapedInput(0, 0, <minecraft:diamond>)
            .replaceShapedInput(2, 0, null)
            .replaceShapedInput(0, 2, null)
            .replaceShapedInput(2, 2, <minecraft:diamond>)
    )
            .addTool(<ore:artisansHammer>, 1)                .create();

工匠之作wiki全文(个人翻译并润色)-第11张图片

拒绝配方输出的物品

Copy noOutput();

用法

builder.setCopy(Copy.byName("minecraft:furnace").noOutput());

如果拒绝输出的话,相当于只要配方输入的材料,不要配方输出的物品,那么就得给它添加输出,如.setOutput

noOutput()与noInput()和replaceOutput(IItemStack)是互斥的。

 

替换输出

Copy replaceOutput(IItemStack replacement);

被替换物的输出数量将与拷贝的配方输出数一致

用法

builder.setCopy(Copy.byName("minecraft:furnace").replaceOutput(<minecraft:diamond>));

复制熔炉配方,然后把配方输出改成输出钻石


replaceOutput(IItemStack)与noOutput()是互斥的。

 

拷贝CRT配方

CRT魔改的配方并不能被直接复制,你需要先追踪CRT配方,再进行改写

Copy runAfter();


builder.setCopy(Copy.byName("crafttweaker:customrecipe").runAfter());

 

接下来是各种栗子

1.      给如原版配方添加工具(通过配方名)

import mods.artisanworktables.builder.RecipeBuilder;
import mods.artisanworktables.builder.Copy;
 
RecipeBuilder.get("basic")
  .setCopy(Copy.byName("minecraft:furnace"))
  .addTool(<ore:artisansHammer>, 10)
  .create();

 

2.      更改大量配方(这里用的是通过ICraftingRecipe类型)

import mods.artisanworktables.builder.RecipeBuilder;
import mods.artisanworktables.builder.Copy;
 
val builder = RecipeBuilder.get("basic");
 
for recipe in recipes.getRecipesFor(<ore:ingotGold>) {
    builder
        .setCopy(Copy.byRecipe(recipe).replaceOutput(<minecraft:diamond>))
        .addTool(<ore:artisansHammer>, 10)
        .create();
}

 很多时候想要批量魔改免不了使用for循环(将来也许会写写关于for循环的教程)


3.      更改大量配方输出(这里通过输出物)

import mods.artisanworktables.builder.RecipeBuilder;
import mods.artisanworktables.builder.Copy;
 
RecipeBuilder.get("basic")
  .setCopy(Copy.byOutput([<ore:ingotIron>, <ore:ingotGold>]).noOutput())
  .addTool(<ore:artisansHammer>, 10)
  .addOutput(<minecraft:string>)
  .create();

定制工具材料

打开config文件夹里的.json文件,以此来修改工具材料

文件位置

config/

  artisanworktables/

    artisanworktables.module.Tools.Materials.Custom.json

    artisanworktables.module.Tools.Materials.Generated.json

你会发现有两个文件,其中….Generated.json,这个文件是每次载入游戏时就会重新生成,代表这个文件是用来提供默认值的,哪天你想清空定制的文件时,给Generated重命名成….Custom.json就行

artisanworktables.module.Tools.Materials.Custom.json才是你应该修改的文件

json格式

{

  "name": "wood",

  "harvestLevel": 0,

  "maxUses": 59,

  "efficiency": 2.0,

  "damage": 0.0,

  "enchantability": 15,

  "color": "73523e",

  "shiny": false,

  "ingredient": "ore:plankWood",

  "langKey": "material.athenaeum.wood",

  "oreDictKey": "artisansToolWood"

}

一目了然,咱就不具体翻译了

下面将解释一些不太容易看懂的地方

 

Ingredient

即材料,也就是合成这个工具的配方中主要的材料

 

LangKey:

assets/athenaeum/lang语言文件en_us里的,也就是这个工具的英文名

关于这个有一些不常用而且也有点bug的操作,没有翻译,这里贴出网址,如有需求请自行查看

https://artisan-worktables.readthedocs.io/en/latest/tools/custommaterials/

 

oreDictKey:

这里的矿物词典不是指材料,而是工具(可见之前说过的矿物词典)


附录:1

ZenMethod速查

import mods.artisanworktables.builder.RecipeBuilder;    //导包
static RecipeBuilder get(String table);    //用何种工作台
RecipeBuilder setName(String name);     //设置配方名称
RecipeBuilder setShaped(IIngredient[][] ingredients);     //添加有序合成
RecipeBuilder setShapeless(IIngredient[] ingredients);    //添加无序合成
RecipeBuilder setFluid(ILiquidStack fluidIngredient);    //添加液体合成
RecipeBuilder setSecondaryIngredients(IIngredient[] secondaryIngredients);    //添加次级材料
RecipeBuilder setConsumeSecondaryIngredients(@Optional(default = true) boolean consume);    //是否消耗次级材料
RecipeBuilder setMirrored(@Optional(default = true) boolean mirrored);    //是否镜像合成
RecipeBuilder addTool(IIngredient tool, int damage);    //添加工具(参与合成)
RecipeBuilder addOutput(IItemStack output, @Optional(default = 1) int weight);    //添加输出
RecipeBuilder setExtraOutputOne(IItemStack output, float chance);    //设置副产物
RecipeBuilder setExtraOutputTwo(IItemStack output, float chance);    //设置第二种副产物
RecipeBuilder setExtraOutputThree(IItemStack output, float chance);    //设置第三种副产物
RecipeBuilder setMinimumTier(int minimumTier);    //设置配方所用工匠台的最低等级
RecipeBuilder setMaximumTier(int maximumTier);    //设置配方所用工匠台的最高等级
RecipeBuilder setExperienceRequired(int experienceRequired);    //配方的经验要求
RecipeBuilder setLevelRequired(int levelRequired);    //配方的等级要求
RecipeBuilder setConsumeExperience(@Optional(default = true) boolean consume);    //合成是否消耗经验
RecipeBuilder setHidden(@Optional(default = true) boolean hidden);    //添加隐藏配方
RecipeBuilder setRecipeFunction(IRecipeFunction recipeFunction);    //设置合成函数
RecipeBuilder setRecipeAction (IRecipeAction recipeAction);    //设置合成行为
RecipeBuilder create();    //完成配方
RecipeBuilder addRequirement(IMatchRequirementBuilder requirementBuilder);
import mods.artisanworktables.builder.Copy;
RecipeBuilder setCopy(Copy copyTask);
static Copy byName(String recipeName);
static Copy byRecipe(ICraftingRecipe recipe);static Copy byOutput(IIngredient[] outputs);
Copy noInput();Copy replaceInput(@Nullable IIngredient toReplace, @Nullable IIngredient replacement);
 Copy replaceShapedInput(int col, int row, @Nullable IIngredient replacement);
 Copy noOutput();
 Copy replaceOutput(IItemStack replacement);

 附录:2

工匠台名称

以下是有效名称

用于static RecipeBuilder get(String table);中

all
basic
blacksmith
carpenter
chef
chemist
engineer
farmer
jeweler
mage
mason
potter
scribe
tailor
tanner

 

工具组的矿物词典

(矿物词典应该都懂吧,每个工具都有不同的材质,比如铁锤、金锤、钻石锤等等,用工具组的矿物词典可以使得各种材质的工具通用)

<ore:artisansAthame>
<ore:artisansBeaker>
<ore:artisansBurner>
<ore:artisansCarver>
<ore:artisansChisel>
<ore:artisansCompass>
<ore:artisansCutters>
<ore:artisansCuttingBoard>
<ore:artisansDriver>
<ore:artisansFile>
<ore:artisansFramingHammer>
<ore:artisansGemCutter>
<ore:artisansGrimoire>
<ore:artisansGroover>
<ore:artisansHammer>
<ore:artisansHandsaw>
<ore:artisansHatchet>
<ore:artisansKnife>
<ore:artisansLens>
<ore:artisansNeedle>
<ore:artisansPan>
<ore:artisansPencil>
<ore:artisansPliers>
<ore:artisansPunch>
<ore:artisansQuill>
<ore:artisansShears>
<ore:artisansSifter>
<ore:artisansSolderer>
<ore:artisansSpanner>
<ore:artisansTrowel>
<ore:artisansTSquare>