本篇教程由作者设定使用 CC BY-NC 协议。
前言
最近在鼓捣GTL整合包的事情,发现其缺少将各种破碎、有瑕、无瑕晶体打粉的配方。
辛辛苦苦筛出来的宝石,居然不能打粉,我不能忍!😂
花了点时间研究了下js语法和kubuJS脚本解决了这个问题,基于整合包版本1.4.1.3
整理了下思路,可以将脚本分为三步
按标签读取物品列表
生成输入输出和recipeID列表
执行recipe注册
读取物品列表
kubeJS在其turial里面有提及相关的接口,如下
eventServerEvents.tags('item', event => {
// Add all items from the forge:stone tag to the c:stone tag, unless the id contains diorite
const stones = event.get('forge:stone').getObjectIds() //笔者注: 这里读取了含有输入标签的全部物品列表,返回的是一个obj类型数组
const blacklist = Ingredient.of(/.*diorite.*/)
stones.forEach(stone => {
if (!blacklist.test(stone)) event.add('c:stone', stone)
})
})
通过 event.get('forge:stone').getObjectIds() 可以顺利得到含有需要的物品信息的数组
于是可以搞出下面这几句
let chippedGemsObjList = event.get('forge:chipped_gems').getObjectIds()
let flawedGemsObjList = event.get('forge:flawed_gems').getObjectIds()
let flawlessGemsObjList = event.get('forge:flawless_gems').getObjectIds()
let exquisiteGemsObjList = event.get('forge:exquisite_gems').getObjectIds()
有一个需要注意的点,这个数组和c++里面的数组不太一样,不能通过xxx[y]的形式访问,用typeof关键字确定其为java.util.ArrayList类型的数组,由目前未知的obj类型组成。
但是问题不大,可以通过以下的代码获取该obj类型的属性和值
//做非空判断避免错误
if(chippedGemsObjList.isEmpty() == false)
{
//通过get(int index)访问特定元素
let obj = chippedGemsObjList.get(0).namespace
//打印各个属性的参数
Object.keys(obj).forEach(key => {
console.log(`${key}: ${obj[key]}`);
});
}
reload一下,得到以下输出:
[17:41:19] [INFO] debug.js#52: withPath: Function
[17:41:19] [INFO] debug.js#52: getClass: Function
[17:41:19] [INFO] debug.js#52: wait: Function
[17:41:19] [INFO] debug.js#52: toShortLanguageKey: Function
[17:41:19] [INFO] debug.js#52: withPrefix: Function
[17:41:19] [INFO] debug.js#52: notifyAll: Function
[17:41:19] [INFO] debug.js#52: setPath: Function
[17:41:19] [INFO] debug.js#52: compareTo: Function
[17:41:19] [INFO] debug.js#52: notify: Function
[17:41:19] [INFO] debug.js#52: path: chipped_rock_salt_gem
[17:41:19] [INFO] debug.js#52: toLanguageKey: Function
[17:41:19] [INFO] debug.js#52: getNamespace: Function
[17:41:19] [INFO] debug.js#52: hashCode: Function
[17:41:19] [INFO] debug.js#52: equals: Function
[17:41:19] [INFO] debug.js#52: compareNamespaced: Function
[17:41:19] [INFO] debug.js#52: getPath: Function
[17:41:19] [INFO] debug.js#52: namespace: gtceu
[17:41:19] [INFO] debug.js#52: toString: Function
[17:41:19] [INFO] debug.js#52: setNamespace: Function
[17:41:19] [INFO] debug.js#52: class: class net.minecraft.resources.ResourceLocation
[17:41:19] [INFO] debug.js#52: specialEquals: Function
[17:41:19] [INFO] debug.js#52: withSuffix: Function
[17:41:19] [INFO] debug.js#52: toDebugFileName: Function
注意到参数中namespace代表了物品所属的模组,path代表了物品的ID
obj类型的数组不能通过string 的方法进行处理,需要将其转换为string类型数组
//用forEach方法直接遍历访问各个元素的namespace和path属性,将其存储到新的一个数组中
function getGemInput(gemsObjList){
let returnStringList = []
gemsObjList.forEach(aaa =>{
returnStringList.push("1x "+ aaa.namespace + ":" + aaa.path)
})
return returnStringList
}
别忘了之前是读取了四个标签的物品列表,这里将四个列表进行合并
用到了concat方法套娃
let gemsObjlist = chippedGemsObjList.concat(flawedGemsObjList.concat(flawlessGemsObjList.concat(exquisiteGemsObjList)))
到这里就已经读取列表完成了
看着很简单精炼,实际上卡了好久,第一次搞js语言,走了好多弯路
生成recipeID和输出产物
之前读取了四种标签的输入,四个标签的需要区分不同的产物
故定义了四种常数字符串
在生成产物数组的函数中额外添加了两个输入参数,分别是前缀(控制产物是小撮粉、普通粉还是小堆粉以及数量)、类型(识别是哪种碎宝石),用于区分
const prefix_chipped = "1x gtceu:tiny_"
const prefix_flawed = "2x gtceu:small_"
const prefix_flawless = "2x gtceu:"
const prefix_exquisite = "4x gtceu:"
const Type_Chipped = "chipped"
const Type_flawed = "flawed"
const Type_flawless = "flawless"
const Type_exquisite = "exquisite"
function getGemOutput(gems, prefix, gemType) {
let returnList = []
gems.forEach(gem => {
let segments = gem.path.split("_");
let filteredSegments = segments.filter(segment => segment !== gemType && segment !== "gem");
let newElement = prefix + filteredSegments.join("_") + "_dust";
returnList.push(newElement);
})
return returnList
}
实际调用,分别调用输入产物数组,存到输出产物数组中,最后concat套娃到一个数组中去
let chippedOutput = getGemOutput(chippedGemsObjList,prefix_chipped,Type_Chipped)
let flawedOutput = getGemOutput(flawedGemsObjList,prefix_flawed,Type_flawed)
let flawlessOutput = getGemOutput(flawlessGemsObjList,prefix_flawless,Type_flawless)
let exquisiteOutput = getGemOutput(exquisiteGemsObjList,prefix_exquisite,Type_exquisite)
gemOutput = chippedOutput.concat(flawedOutput.concat(flawlessOutput.concat(exquisiteOutput)))
至此,输出产物数组就完成了
同理可以搞定recipeID数组,用于区分每一个recipe,定义一个处理函数
function getGemRecipeID(gemsObjList){
let retrunStringListRecipeID = []
gemsObjList.forEach(aaa=>{
retrunStringListRecipeID.push(aaa.path + "2Dsut")
})
return retrunStringListRecipeID
}
直接对总的输入产物数组调用该函数,生成recipeID数组
gemRecipe = getGemRecipeID(gemsObjlist)
用于批量生成recipe的数组全部生成完毕,下一步就是批量生成了
批量生成
直接用数组遍历,因为之前定义时就不使用查询函数返回的那个类型,而是string数组类型,所以可以直接使用xxx[y]的形式索引
ServerEvents.recipes(event => {
for(let i = 0; i < gemRecipe.length ; i++)
{
event.recipes.gtceu.macerator(gemRecipe[i])
.itemInputs(gemInput[i])
.itemOutputs(gemOutput[i])
.EUt(GTValues.VA[GTValues.ULV])
.duration(20)
}
})
代码总览
上面的文本是将每个部分分开解释,这里给出完成后的整个文件,放在server_scripts文件夹下
//添加破碎、有瑕、无瑕、精致的宝石粉碎配方
let gemRecipe = []
let gemInput = []
let gemOutput = []
//生成recipeID列表
function getGemRecipeID(gemsObjList){
let retrunStringListRecipeID = []
gemsObjList.forEach(aaa=>{
retrunStringListRecipeID.push(aaa.path + "2Dsut")
})
return retrunStringListRecipeID
}
//生成输入物品列表
function getGemInput(gemsObjList){
let returnStringList = []
gemsObjList.forEach(aaa =>{
returnStringList.push("1x "+ aaa.namespace + ":" + aaa.path)
})
return returnStringList
}
//生成输出物品列表
function getGemOutput(gems, prefix, gemType) {
let returnList = []
gems.forEach(gem => {
let segments = gem.path.split("_");
let filteredSegments = segments.filter(segment => segment !== gemType && segment !== "gem");
let newElement = prefix + filteredSegments.join("_") + "_dust";
returnList.push(newElement);
})
return returnList
}
//监控标签事件,按标签读取列表和生成输入输出和recipceID等
ServerEvents.tags('item', event => {
const prefix_chipped = "1x gtceu:tiny_"
const prefix_flawed = "2x gtceu:small_"
const prefix_flawless = "2x gtceu:"
const prefix_exquisite = "4x gtceu:"
const Type_Chipped = "chipped"
const Type_flawed = "flawed"
const Type_flawless = "flawless"
const Type_exquisite = "exquisite"
let chippedGemsObjList = event.get('forge:chipped_gems').getObjectIds()
let flawedGemsObjList = event.get('forge:flawed_gems').getObjectIds()
let flawlessGemsObjList = event.get('forge:flawless_gems').getObjectIds()
let exquisiteGemsObjList = event.get('forge:exquisite_gems').getObjectIds()
let gemsObjlist = chippedGemsObjList.concat(flawedGemsObjList.concat(flawlessGemsObjList.concat(exquisiteGemsObjList)))
gemRecipe = getGemRecipeID(gemsObjlist)
gemInput = getGemInput(gemsObjlist)
let chippedOutput = getGemOutput(chippedGemsObjList,prefix_chipped,Type_Chipped)
let flawedOutput = getGemOutput(flawedGemsObjList,prefix_flawed,Type_flawed)
let flawlessOutput = getGemOutput(flawlessGemsObjList,prefix_flawless,Type_flawless)
let exquisiteOutput = getGemOutput(exquisiteGemsObjList,prefix_exquisite,Type_exquisite)
gemOutput = chippedOutput.concat(flawedOutput.concat(flawlessOutput.concat(exquisiteOutput)))
})
//导入配方
ServerEvents.recipes(event => {
for(let i = 0; i < gemRecipe.length ; i++)
{
event.recipes.gtceu.macerator(gemRecipe[i])
.itemInputs(gemInput[i])
.itemOutputs(gemOutput[i])
.EUt(GTValues.VA[GTValues.ULV])
.duration(20)
}
})
最终效果