119 lines
3.8 KiB
JavaScript
119 lines
3.8 KiB
JavaScript
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
|
import { findFullEntry, stripEntryToMinimums } from "./ncpf-utils.js";
|
|
import { getPlannerMultiblockSize, getPlannerMultiblockType, loadPlanner, readPlannerTiles } from "./planner.js";
|
|
import { getAtlasIndexFromMetadata, getAtlasMetadata } from "./atlas.js";
|
|
import { resetSolver } from "./solver.js";
|
|
import { registerLoadCallback } from "./main.js";
|
|
|
|
registerLoadCallback(() => {
|
|
listenTo("file:load", () => showOpenFileDialog());
|
|
listenTo("file:new", () => {});
|
|
listenTo("file:save", () => saveFile("test"));
|
|
});
|
|
|
|
export function showOpenFileDialog() {
|
|
const input = document.createElement("input");
|
|
input.type = "file";
|
|
input.accept = ".ncpf.json";
|
|
input.addEventListener("change", async () => {
|
|
const data = await new Promise(resolve => {
|
|
const reader = new FileReader();
|
|
reader.addEventListener("load", () => {
|
|
resolve(JSON.parse(reader.result));
|
|
});
|
|
reader.readAsText(input.files[0]);
|
|
});
|
|
void loadFile(data);
|
|
});
|
|
input.click();
|
|
}
|
|
|
|
export async function loadExampleFile(filename) {
|
|
const data = await fetch(`./examples/${filename}.ncpf.json`)
|
|
.then(data => data.json());
|
|
return loadFile(data);
|
|
}
|
|
|
|
export async function loadFile(data) {
|
|
console.log(data);
|
|
if (!data.designs) throw new Error("invalid file");
|
|
if (data.designs.length === 0) throw new Error("no designs");
|
|
|
|
let design = data.designs[0];
|
|
if (data.designs.length > 1) {
|
|
const prepChoice = awaitEvent("fileLoad:chooseDesign:choice");
|
|
emitEvent("fileLoad:chooseDesign", data);
|
|
const res = await prepChoice;
|
|
design = data.designs[res.detail];
|
|
}
|
|
|
|
if (!design) throw new Error("no design");
|
|
|
|
const blocks = data.configuration[design.type].blocks
|
|
.map(block => getAtlasIndexFromMetadata(block, design.type, "blocks"));
|
|
|
|
const designWithAtlas = design.design.map(a => a.map(b => b.map(c => c === -1 ? -1 : blocks[c])));
|
|
|
|
loadPlanner(design.dimensions, design.type, designWithAtlas);
|
|
resetSolver(design);
|
|
}
|
|
|
|
export async function saveFile(name) {
|
|
const multiblockType = getPlannerMultiblockType();
|
|
|
|
const designAsAtlas = readPlannerTiles();
|
|
const designBlocksAtlasMap = Object.fromEntries(
|
|
[...new Set(designAsAtlas.flat(3))]
|
|
.filter(v => v !== -1)
|
|
.sort((a, b) => a - b)
|
|
.map((ai, di) => [ ai, { ...getAtlasMetadata(ai), designIndex: di } ])
|
|
);
|
|
const designAsBlocks = designAsAtlas
|
|
.map(xPlane => xPlane
|
|
.map(yRow => yRow.map(atlasIndex => designBlocksAtlasMap[atlasIndex]))
|
|
);
|
|
const designAsBlockIndices = designAsBlocks
|
|
.map(xPlane => xPlane.map(yRow => yRow.map(b => b?.designIndex ?? -1)));
|
|
|
|
const designBlocksWithRecipes = designAsBlocks
|
|
.map(xPlane => xPlane
|
|
.map(yRow => yRow
|
|
.map(block => {
|
|
if (!block) return;
|
|
return findFullEntry("blocks", block, { configurationHint: multiblockType });
|
|
})
|
|
.filter(b => b && b.modules && "ncpf:block_recipes" in b.modules)
|
|
)
|
|
.filter(r => r.length > 0)
|
|
)
|
|
.filter(p => p.length > 0);
|
|
console.log("designBlocksWithRecipes", designBlocksWithRecipes)
|
|
|
|
const minimizedBlocks = Object.entries(designBlocksAtlasMap)
|
|
.sort(([a], [b]) => a - b)
|
|
.map(([, m]) => stripEntryToMinimums(m));
|
|
|
|
const data = {
|
|
addons: [],
|
|
configurations: {
|
|
[multiblockType]: {
|
|
blocks: minimizedBlocks,
|
|
coolant_recipes: [], // FIXME
|
|
},
|
|
},
|
|
designs: [
|
|
{
|
|
block_recipes: [], // FIXME
|
|
coolant_recipe: 0, // FIXME
|
|
design: designAsBlockIndices,
|
|
dimensions: getPlannerMultiblockSize(),
|
|
type: multiblockType,
|
|
},
|
|
],
|
|
version: 1,
|
|
};
|
|
|
|
console.log(designBlocksAtlasMap);
|
|
console.log(data);
|
|
}
|