Agradecimentos especiais a Phoenixvine do PFT por compartilhar estes scripts
Passo 1
Baixe estes dois arquivos e coloque-os na mesma pasta em qualquer lugar do seu PC.
Passo 2
Com sua ferramenta de copiar/colar no modo de cópia, selecione a estrutura.
Passo 3
Coloque sua ferramenta no gerenciador de templates. Você pode inserir um pedaço de papel e salvar para confirmar que é a estrutura correta. Em seguida, clique em copiar para salvar o JSON na área de transferência.
Passo 4
Execute o arquivo .bat; isso abrirá o console e deverá parecer com isto:
Passo 5
Cole a string JSON que você copiou do gerenciador de templates.
Passo 6
Pressione Enter. O script será executado e gerará a nova estrutura no formato GTM. Você pode então copiar/colar e utilizar o resultado.
.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"))Passo 7
Provavelmente será necessário reformatar um pouco o resultado. Aqui está o exemplo acima formatado em 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()
)Opcional Atualmente o script aceita uma string JSON via linha de comando, mas isso falha se a string for maior que o limite de texto. Abaixo há um script Python modificado para ler de um arquivo JSON e gerar um arquivo JS.
Substitua o código em 'multis.py' por este:
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("Nie znaleziono blockstatemap w statePosArrayList.")
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("Nie znaleziono startpos lub endpos w statePosArrayList.")
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("Nie znaleziono statelist w statePosArrayList.")
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(
"Liczba elementów w statelist nie zgadza się z wymiarami struktury."
)
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()Agora, em vez de solicitar a string JSON via entrada, o script lerá um arquivo chamado "input.json" na mesma pasta (onde você deverá colocar o JSON) e gravará a saída em "output.js". Além disso, o ar será representado como " " em vez de "A" para melhor legibilidade.