特别感谢来自 PFT 的 Phoenixvine 分享这些脚本
步骤 1)
下载以下两个文件并将其放在您电脑上任意位置的同一文件夹中。
步骤 2)
将您的复制/粘贴小工具置于复制模式,选择您的结构。
步骤 3)
将您的小工具放入模板管理器。您可以放入一张纸并点击保存以确保它是正确的结构。然后点击复制将 json 保存到您的剪贴板。
步骤 4)
运行 .bat 文件,它应该会打开控制台并看起来像这样:
步骤 5)
输入您从模板管理器复制的 json 字符串。
步骤 6)
按回车键。它应该会运行并输出新的 GTM 结构格式。您现在可以复制/粘贴并使用它。
js
.aisle("AAAAAAABAAABAAAAAAA", "AAAAAAABAAABAAAAAAA", "AAAAAAACCCCCAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAD")
.aisle("AAAAABAAAAAAABAAAAA", "AAAAABAAAAAAABAAAAA", "AAAACCAAAAAAACCAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAAAABAAABAAAAAAA", "AAAAAAACCCCCAAAAAAA", "AAACCAAAAAAAAACCAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAABAAAAAAABAAAAA", "AAAACCAAAAAAACCAAAA", "AACAAAAAAAAAAAAACAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAAAAACCCAAAAAAAA", "AAACCAAAAAAAAACCAAA", "ACCAAAAAAAAAAAAACCA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("ABABACCAAAAACCABABA", "ABACAAAAAAAAAAACABA", "ACAAAAAAAAAAAAAAACA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAACAAAAAAACAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("BABAAAAAAAAAAAAABAB", "BACAAAAAAAAAAAAACAB", "CAAAAAAAAAAAAAAAAAC", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAACAAAEFGAAACAAAA", "AACAAAAABABAAAAACAA", "CAAAAAAABABAAAAAAAC", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAAHHHAAAAAAAA", "AAAAAAAAIIIAAAAAAAA", "AAAAAAAAIIIAAAAAAAA", "AAAAAAAAIIIAAAAAAAA")
.aisle("AAAACAAAEEJAAACAAAA", "AACAAAAAAEAAAAAACAA", "CAAAAAAAAEAAAAAAAAC", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAAEAAAAAAAAA", "AAAAAAAAHEHAAAAAAAA", "AAAAAAAAIEIAAAAAAAA", "AAAAAAAAIKIAAAAAAAA", "AAAAAAAAIIIAAAAAAAA")
.aisle("AAAACAAAELLAAACAAAA", "AACAAAAABABAAAAACAA", "CAAAAAAABABAAAAAAAC", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAABABAAAAAAAA", "AAAAAAAAHHHAAAAAAAA", "AAAAAAAAIIIAAAAAAAA", "AAAAAAAAIIIAAAAAAAA", "AAAAAAAAIIIAAAAAAAA")
.aisle("BABAAAAAAAAAAAAABAB", "BACAAAAAAAAAAAAACAB", "CAAAAAAAAAAAAAAAAAC", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAACAAAAAAACAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("ABABACCAAAAACCABABA", "ABACAAAAAAAAAAACABA", "ACAAAAAAAAAAAAAAACA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAAAAACCCAAAAAAAA", "AAACCAAAAAAAAACCAAA", "ACCAAAAAAAAAAAAACCA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAABAAAAAAABAAAAA", "AAAACCAAAAAAACCAAAA", "AACAAAAAAAAAAAAACAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAAAABAABAAAAAAAA", "AAAAAAACCCCCAAAAAAA", "AAACCAAAAAAAAACCAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("AAAAABAAAAAAABAAAAA", "AAAAABAAAAAAABAAAAA", "AAAACCAAAAAAACCAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.aisle("DAAAAAABAAABAAAAAAA", "AAAAAAABAAABAAAAAAA", "AAAAAAACCCCCAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAA")
.where("A", Predicates.blocks("minecraft:air"))
.where("B", Predicates.blocks("gtceu:stainless_steel_frame"))
.where("C", Predicates.blocks("tfg:casings/machine_casing_red_solar_panel"))
.where("D", Predicates.blocks("minecraft:oak_planks"))
.where("E", Predicates.blocks("tfg:casings/machine_casing_iron_desh"))
.where("F", Predicates.blocks("tfg:large_solar_panel"))
.where("G", Predicates.blocks("gtceu:configurable_maintenance_hatch"))
.where("H", Predicates.blocks("ad_astra:iron_plateblock"))
.where("I", Predicates.blocks("gtceu:tempered_glass"))
.where("J", Predicates.blocks("gtceu:ulv_energy_output_hatch"))
.where("K", Predicates.blocks("gtceu:silver_block"))
.where("L", Predicates.blocks("gtceu:ulv_input_bus"))步骤 7)
您可能需要稍微重新格式化输出。以下是上面示例清理后的 Java 形式:
java
.pattern(definition -> FactoryBlockPattern.start()
.aisle(" B B ", " B B ", " CCCCC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " B B ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " CCCCC ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " CC CC ", " C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" CCC ", " CC CC ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B CC CC B B ", " B C C B ", " C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle("B B B", "B C C B", "C C", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" C FFF C B ", " C B B C ", "C B B C", " B B ", " B B ", " B B ", " B B ", " B B ", " B B ", " B B ", " EEE ", " GGG ", " GGG ", " GGG ")
.aisle(" C HIF C ", " C I C ", "C I C", " I ", " I ", " I ", " I ", " I ", " I ", " I ", " EIE ", " GIG ", " GKG ", " GGG ")
.aisle(" C FFF C ", " C B B C ", "C B B C", " B B ", " B B ", " B B ", " B B ", " B B ", " B B ", " B B ", " EEE ", " GGG ", " GGG ", " GGG ")
.aisle("B B B B", "B C C B", "C C", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B CC CC B B ", " B C C B ", " C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" CCC ", " CC CC ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " CC CC ", " C C ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " CCCCC ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " B B ", " CC CC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.aisle(" B B ", " B B ", " CCCCC ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ")
.where("H", Predicates.controller(Predicates.blocks(definition.get())))
.where("B", Predicates.frames(GTMaterials.StainlessSteel))
.where("C", Predicates.blocks(ForgeRegistries.BLOCKS.getValue(TFGCore.id("casings/machine_casing_red_solar_panel"))))
.where("E", Predicates.blocks(ForgeRegistries.BLOCKS.getValue(ResourceLocation.parse("ad_astra:iron_plateblock"))))
.where("F", Predicates.blocks(ForgeRegistries.BLOCKS.getValue(TFGCore.id("casings/machine_casing_iron_desh")))
.or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(2).setPreviewCount(1))
.or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))
.or(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setMaxGlobalLimited(2).setPreviewCount(1))
.or(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setMaxGlobalLimited(2).setPreviewCount(1))
.or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1))
.or(Predicates.abilities(PartAbility.OUTPUT_ENERGY).setExactLimit(1))
)
.where("G", Predicates.blocks(GTBlocks.CASING_TEMPERED_GLASS.get()))
.where("I", Predicates.blocks(ForgeRegistries.BLOCKS.getValue(TFGCore.id("casings/machine_casing_iron_desh"))))
.where("K", Predicates.blocks(ChemicalHelper.getBlock(TagPrefix.block, GTMaterials.Silver)))
.where(" ", Predicates.any())
.build()
)可选步骤
目前脚本在命令行中接受 json 字符串,但如果 json 字符串长于文本限制,这将无法工作。因此我有一个修改版的 python 脚本,可以从 json 文件读取并输出到 JS 文件。
将 'multis.py' 中的代码替换为此代码:
py
import re
import json
def transform_json(input_data):
statePos_str = input_data.get("statePosArrayList", "")
m_blocks = re.search(r"blockstatemap:\[(.*?)\](?:,|})", statePos_str)
if not m_blocks:
raise ValueError("在 statePosArrayList 中未找到 blockstatemap.")
blockstatemap_str = m_blocks.group(1)
block_names = re.findall(r'Name:"(.*?)"', blockstatemap_str)
# Wyciągamy startpos i endpos
m_start = re.search(r"startpos:\{(.*?)\}", statePos_str)
m_end = re.search(r"endpos:\{(.*?)\}", statePos_str)
if not m_start or not m_end:
raise ValueError("在 statePosArrayList 中未找到 startpos 或 endpos.")
def parse_pos(pos_str):
pos = {}
for part in pos_str.split(","):
key, value = part.split(":")
pos[key.strip()] = int(value.strip())
return pos
startpos = parse_pos(m_start.group(1))
endpos = parse_pos(m_end.group(1))
x_dim = endpos["X"] - startpos["X"] + 1
y_dim = endpos["Y"] - startpos["Y"] + 1
z_dim = endpos["Z"] - startpos["Z"] + 1
total_blocks = x_dim * y_dim * z_dim
m_list = re.search(r"statelist:\[I;(.*?)\]", statePos_str)
if not m_list:
raise ValueError("在 statePosArrayList 中未找到 statelist.")
statelist_str = m_list.group(1)
statelist_nums = [int(x) for x in statelist_str.split(",") if x.strip() != ""]
if len(statelist_nums) != total_blocks:
raise ValueError(
"statelist 中的元素数量与结构维度不匹配."
)
block_to_letter = {"minecraft:air": " "}
next_letter_ord = ord("A")
def assign_letter(block_type):
nonlocal next_letter_ord
if block_type == "minecraft:air":
return " "
if block_type not in block_to_letter:
block_to_letter[block_type] = chr(next_letter_ord)
next_letter_ord += 1
return block_to_letter[block_type]
structure = []
index = 0
for _ in range(z_dim):
layer = []
for _ in range(y_dim):
row = []
for _ in range(x_dim):
block_index = statelist_nums[index]
index += 1
block_type = block_names[block_index]
letter = assign_letter(block_type)
row.append(letter)
layer.append(row)
structure.append(layer)
keys = {v: k for k, v in block_to_letter.items()}
return {"structure": structure, "keys": keys}
def gen_output(data):
output_lines = []
for aisle in data["structure"]:
rows_str = ["".join(row) for row in aisle]
tmp = ", ".join(f'"{row}"' for row in rows_str)
line = f".aisle({tmp})"
output_lines.append(line)
for key, block in data["keys"].items():
output_lines.append(f' .where("{key}", Predicates.blocks("{block}"))')
return output_lines
def main():
with open("input.json", "r", encoding="utf-8") as f:
input_json = json.load(f)
data = transform_json(input_json)
lines = gen_output(data)
with open("output.js", "w", encoding="utf-8") as out_file:
out_file.write("\n".join(lines))
if __name__ == "__main__":
main()现在,它不会要求输入 json 字符串,而是会读取文件夹中名为 "input.json" 的文件(您将在此处放置代码),并写入文件夹中名为 "output.js" 的文件。此外,这会将空气设置为 " " 而不是 "A",以获得更好的可读性。