当我玩一些大型科技整合包的时候,总会头晕于复杂的合成表。比如我做一台低压卷板机,需要哪些材料?做十台me接口,又需要哪些东西?有人会说:ae2是个好东西。但是很多整合包作者不会在前期有给你接触到自动合成的可能。所以一种前期能用的计算材料的程序很有用处。
在1.12.2,有一些整合包会内置 Just Enough Calculation,它提供了一台游戏内的计算器,可以直接使用jei导入合成表或者是配方,相当灵活、方便。缺点是在“合成步骤”的功能里,有点眼花缭乱,一复杂,就基本不能看清配方到底是怎么回事。另一个缺点是有的整合包就没有它,那么玩起服务器的时候就用不了。
所以我萌生了用mma来计算合成表的想法。
首先肯定得告诉电脑,“配方”是个什么东西。于是定义了一条合成表:
{{{
用Grid看一看
第一行是原料,第二行是产物,第三行是消耗的时间,第四行是所需的机器。
每一个小格,第一个数字指的是物品数量,第二个字符串当然是物品的名字,第三个数字是随便什么数字,一般可以取0。第三个数字有什么用?会在后面讲到
第一个函数,是用来对合成表的物品数量进行乘除运算。
recipeMultiply
比如我输入这条电解二氧化硅的合成表:
recipeMultiply
它就能返回这条合成表所有系数*1/4的新合成表:
{{{
接下来的概念是“材料列表”。可以理解为一个mc里面的装有一堆东西的箱子。比如我的箱子里有三个原木,十二个木板,十二根木棍,
就可以这么写:
{{3, "Log", 2}, {12, "Wood Plank", 2}, {12, "Stick", 4}}
那么当我把另外十二根木棍丢进去的时候,一般会合并为二十四根木棍(当然你分开放也没问题)。所以这里有一个化简的过程。那么另外多出来一个新的“合成表”:十二根木棍+十二根木棍->二十四根木棍。
这里,第二个函数可以将一格的东西丢到含有许多物品的箱子里去。
materialAddOne
输入上面的例子:
materialAddOne
返回一个全新的箱子内容物,和多出来的“合并合成表”。
{{{
为什么的合成表不是合并而是分开?会在后面讲到。
第三个函数可以将一大堆东西扔到这个箱子里。
materialAdd
举个例子:我把十二根木棍、一根木棍、六十六个木板和两个垃圾,放进含有三个原木,十二个木板,十二根木棍的箱子里
materialAdd
那么我箱子里现在有这些东西,附带的还有多出来的合成表:
{{{
第四个函数是我输入一个物品和指定合成表,它会去检查给定的合成表里面有没有制作此物品的配方。返回的是原料,如果有配方的话后面就加一下这个配方。
findInput
反映的是这样的过程:将一个东西反正合成,拆出来的东西放进一个全新的箱子里
比如我提供一堆合成表后,要它拆三十个aa的木制外壳。
findInput
那么返回的是三十个个木制外壳的材料列表,当然还有此合成表
{{{
第五个函数是输入一堆东西,再尽量找出这些东西的原料。
findInputList
比如我除了要找到八个木制外壳的原料以外,我还要找到一个垃圾的原料
findInputList
垃圾的原料当然是找不到的,于是垃圾本身作为不能拆分的材料丢进箱子里。
{{{
第六个函数已经有点最终需求的味道了
procedureTable
给定合成表和产物,它会顺着这些产物反过去找到对应的原料,并且是将所有的原料拆到不能再拆为止。
首先输入所需的合成表:
recipes
然后让其去查八个小型板条箱的制作表
procedureTable
返回的东西是这样的:
虽然顺序有点混乱,但是勉强满足了要求。这里的分开便可以理解了,因为我们的思考过程和真正合成过程是反着来的。可以看到里面很详细的讲述了每一步过程:
第一步:取出92个原木,将其分开为88个原木和4个原木
第二步:88个原木分开为16个原木和72个原木
第三步:4个原木做成16个木板
第四步:16个原木分开为8个原木和8个原木
第五步:72个原木做成288个木板
第六步:8个原木做成32个木板
第七步:16个木板做32个木棍
第八步:8原木、32木板和32木棍,做成8木制外壳
第九步:288个木板分开为256个木板和32个木板
第十步:256个木板做成32个箱子
最后一步:32个木板、8个外壳和32个箱子,做成8个小型板条箱。
可以看到一切都计算正确、过程详细、合情合理,只是过程中有许多啰嗦的步骤,很烦。
第七个函数是将两个重复的合成表合起来。
比如我明显可以把:
16个原木+7个空气+78个二三三->8个原木+12个啥
92个原木+9个空气+1个二三三->88个原木+3个啥
这两个合并起来。
recipeAdd
合并了以后当然:原料有合并的过程,产物有分开的过程,这样才能进行接下来的合成。于是返回的是:
{{{{
第八个函数可以将一批重复的合成表该合并的合并。
recipeTogetherOnce
比如我拿刚才做8个小型板条箱的合成表拿来合一遍:
recipeTogetherOnce
合出来是这样的:
可以看到“分开”和“合并”的过程并没有做任何合并,可以思考一下为什么
因为在工作台或者是机器里的合成表当然是可以合并的,比如:
1铁锭->2铁棍
3铁锭->6铁棍
变为
4铁锭->8铁棍
但是“分开”和“合并”的过程就不一样了:
7铁锭->4铁锭+3铁锭
4铁锭->2铁锭+2铁锭
合起来显然就不对了,我一共才7个铁锭,哪来的11个铁锭呢?
第九个函数是画图函数。我的最终目的是要给出一幅制作的流程图,所以当然需要画图。
drawRecipes
原理是将合成表们,变成一个一个有向线,然后填上对应的顶点标识、边标识。
其中对于分开和合并这两个特殊操作,我单独用两个小函数来表示了。
drawSplict
把上文的第八个函数的运行结果拿来画画看:
drawRecipes
可以看到初具规模。但还是存在需要解决的问题。比如这是什么?
有点绕远路的过程。
所以我提出要对图进行化简。就是对一组有向边进行化简。分为几种情况
情况1:将
这种变为这种:
graphSimplifyCase01Once
情况2:将
这种变为这种:
graphSimplifyCase02Once
情况3:将
变为这种:
graphSimplifyCase03Once
情况4:将
这种迂回曲折的图,变为这种:
graphSimplifyCase04Once
情况5:将
这种自己指到自己的去掉。
那么将所有步骤化简一遍应该就差不多了吧(我也不确定,反正大多数情况一遍没问题)
graphSimplify
将刚才那幅图:
化简一番再画,就得到:
很有道理!将化简的代码添加到画合成表函数里面,是这个结果:
清晰明了又可靠,很满足我最终的想法。
举一些例子。omnifactory里面,我想制作24台中压卷板机,流程图是?
{
omnifactory里面,环氧树脂板的合成路线是?
{
最近玩gtnh,大前期,岩浆桶好烫手,我要一幅手套,需要哪些材料?
{
原来要132个棉花和6个皮革。