Compare commits
2 Commits
b69bcacb78
...
7948a27f39
| Author | SHA1 | Date |
|---|---|---|
|
|
7948a27f39 | |
|
|
880017ddf3 |
17
index.html
17
index.html
|
|
@ -97,5 +97,22 @@
|
|||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
<div class="dialog hidden" data-dialog="fileSave:nameDesign">
|
||||
<section>
|
||||
<header>Save your design</header>
|
||||
<main class="list-choice">
|
||||
<form id="fileSave:nameDesign:form" data-form="fileSave:nameDesign">
|
||||
<label>
|
||||
Name:
|
||||
<input name="name" autofocus />
|
||||
</label>
|
||||
</form>
|
||||
</main>
|
||||
<footer>
|
||||
<button data-dialog-action="cancel">Cancel</button>
|
||||
<button form="fileSave:nameDesign:form">Save</button>
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,29 +1,50 @@
|
|||
import { DomList } from "./dom-list.js";
|
||||
import { addEventToElement, setText } from "./dom-utils.js";
|
||||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
export function initializeDialogs() {
|
||||
registerLoadCallback(() => {
|
||||
listenTo("fileLoad:chooseDesign", designChoiceDialog);
|
||||
}
|
||||
listenTo("fileSave:nameDesign", designNameDialog);
|
||||
});
|
||||
|
||||
function designChoiceDialog(e) {
|
||||
const dialog = document.querySelector('[data-dialog="fileLoad:chooseDesign"]');
|
||||
function initializeDialog(dialogName, endEvent, { emptyValue, onDismiss } = {}) {
|
||||
const dialog = document.querySelector(`[data-dialog="${dialogName}"]`);
|
||||
|
||||
const dismiss = (data) => {
|
||||
dialog.classList.add("hidden");
|
||||
emitEvent("fileLoad:chooseDesign:choice", data);
|
||||
console.log("dimiss > emit", data);
|
||||
emitEvent(endEvent, data);
|
||||
if (onDismiss) {
|
||||
onDismiss();
|
||||
}
|
||||
}
|
||||
|
||||
addEventToElement(
|
||||
"dialog-action", "cancel", "click",
|
||||
() => dismiss(-1),
|
||||
() => dismiss(emptyValue),
|
||||
{ element: dialog },
|
||||
);
|
||||
dialog.addEventListener("click", e => {
|
||||
if (e.target !== e.currentTarget) return;
|
||||
dismiss(-1);
|
||||
dismiss(emptyValue);
|
||||
});
|
||||
|
||||
queueMicrotask(() => {
|
||||
dialog.classList.remove("hidden");
|
||||
});
|
||||
|
||||
return {
|
||||
dialog,
|
||||
dismiss,
|
||||
};
|
||||
}
|
||||
|
||||
function designChoiceDialog(e) {
|
||||
const {
|
||||
dialog, dismiss
|
||||
} = initializeDialog("fileLoad:chooseDesign", "fileLoad:chooseDesign:choice", -1);
|
||||
|
||||
const list = new DomList(dialog.querySelector(":scope > section > main"));
|
||||
list.clear();
|
||||
|
||||
|
|
@ -35,6 +56,20 @@ function designChoiceDialog(e) {
|
|||
button.addEventListener("click", () => dismiss(designIndex));
|
||||
list.addItem(button);
|
||||
}
|
||||
|
||||
dialog.classList.remove("hidden");
|
||||
}
|
||||
|
||||
function designNameDialog() {
|
||||
const {
|
||||
dismiss
|
||||
} = initializeDialog(
|
||||
"fileSave:nameDesign",
|
||||
"fileSave:nameDesign:named",
|
||||
{
|
||||
emptyValue: null
|
||||
}
|
||||
);
|
||||
|
||||
awaitEvent("fileSave:nameDesign:submit").then(e => {
|
||||
dismiss(new FormData(e.detail.target).get("name"));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { deleteTooltip } from "./tooltip.js";
|
||||
import { deleteSolverMetadata } from "./solver.js";
|
||||
|
||||
export class DomList {
|
||||
list;
|
||||
|
|
@ -10,7 +11,10 @@ export class DomList {
|
|||
}
|
||||
|
||||
clear() {
|
||||
this.list.querySelectorAll("[data-tooltip]").forEach(e => deleteTooltip(Number(e.dataset.tooltip)))
|
||||
this.list.querySelectorAll("[data-tooltip]")
|
||||
.forEach(e => deleteTooltip(Number(e.dataset.tooltip)));
|
||||
this.list.querySelectorAll("[data-solver-metadata]")
|
||||
.forEach(e => deleteSolverMetadata(Number(e.dataset.solverMetadata)));
|
||||
this.list.replaceChildren(...this.list.querySelectorAll(":scope > template, :scope > [data-keep]"));
|
||||
}
|
||||
|
||||
|
|
|
|||
149
scripts/files.js
149
scripts/files.js
|
|
@ -1,20 +1,29 @@
|
|||
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
||||
import { findFullEntry, stripEntryToMinimums } from "./ncpf-utils.js";
|
||||
import { getPlannerMultiblockSize, getPlannerMultiblockType, loadPlanner, readPlannerTiles } from "./planner.js";
|
||||
import { checkEquivalence, findFullEntry, stripEntryToMinimums } from "./ncpf-utils.js";
|
||||
import {
|
||||
getPlannerDom,
|
||||
getPlannerMultiblockSize,
|
||||
getPlannerMultiblockType,
|
||||
loadPlanner,
|
||||
readPlannerCellData
|
||||
} from "./planner.js";
|
||||
import { getAtlasIndexFromMetadata, getAtlasMetadata } from "./atlas.js";
|
||||
import { resetSolver } from "./solver.js";
|
||||
import { getSolverMetadata, resetSolver } from "./solver.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
export function initializeFileEvents() {
|
||||
registerLoadCallback(() => {
|
||||
listenTo("file:load", () => showOpenFileDialog());
|
||||
listenTo("file:new", () => {});
|
||||
listenTo("file:save", () => saveFile("test"));
|
||||
}
|
||||
listenTo("file:save", () => saveFile());
|
||||
});
|
||||
|
||||
export function showOpenFileDialog() {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = ".ncpf.json";
|
||||
input.addEventListener("change", async () => {
|
||||
const basename = input.files[0].name.split(/[/\\]/).pop();
|
||||
const filename = basename.replace(/\.json$/, "").replace(/\.ncpf$/, "");
|
||||
const data = await new Promise(resolve => {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener("load", () => {
|
||||
|
|
@ -22,7 +31,7 @@ export function showOpenFileDialog() {
|
|||
});
|
||||
reader.readAsText(input.files[0]);
|
||||
});
|
||||
void loadFile(data);
|
||||
void loadFile(data, filename);
|
||||
});
|
||||
input.click();
|
||||
}
|
||||
|
|
@ -31,10 +40,10 @@ export async function loadExampleFile(filename) {
|
|||
const data = await fetch(`./examples/${filename}.ncpf.json`)
|
||||
.then(data => data.json());
|
||||
return loadFile(data);
|
||||
// return loadFile(data, filename);
|
||||
}
|
||||
|
||||
export async function loadFile(data) {
|
||||
console.log(data);
|
||||
export async function loadFile(data, name) {
|
||||
if (!data.designs) throw new Error("invalid file");
|
||||
if (data.designs.length === 0) throw new Error("no designs");
|
||||
|
||||
|
|
@ -54,13 +63,36 @@ export async function loadFile(data) {
|
|||
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);
|
||||
resetSolver(design, data.configuration[design.type]);
|
||||
|
||||
if (name) {
|
||||
getPlannerDom().dataset.name = name;
|
||||
}
|
||||
|
||||
console.log("load file", data);
|
||||
}
|
||||
|
||||
export async function saveFile(name = undefined) {
|
||||
if (!name) {
|
||||
name = getPlannerDom().dataset.name;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
emitEvent("fileSave:nameDesign");
|
||||
const nameEvent = await awaitEvent("fileSave:nameDesign:named");
|
||||
name = nameEvent.detail;
|
||||
console.log(nameEvent)
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
name = "unnamed";
|
||||
}
|
||||
|
||||
export async function saveFile(name) {
|
||||
const multiblockType = getPlannerMultiblockType();
|
||||
|
||||
const designAsAtlas = readPlannerTiles();
|
||||
const designAsCellData = readPlannerCellData();
|
||||
const designAsAtlas = designAsCellData
|
||||
.map(xPlane => xPlane.map(yRow => yRow.map(c => Number(c.tile))));
|
||||
const designBlocksAtlasMap = Object.fromEntries(
|
||||
[...new Set(designAsAtlas.flat(3))]
|
||||
.filter(v => v !== -1)
|
||||
|
|
@ -74,36 +106,75 @@ export async function saveFile(name) {
|
|||
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 = {
|
||||
const blockRecipes = designAsBlocks
|
||||
.map((xPlane, x) => xPlane
|
||||
.map((yRow, y) => yRow
|
||||
.map((block, z) => {
|
||||
if (!block) return;
|
||||
const fullBlock = findFullEntry(
|
||||
"blocks",
|
||||
block,
|
||||
{ configurationHint: multiblockType },
|
||||
);
|
||||
if (!fullBlock || !fullBlock.modules || !("ncpf:block_recipes" in fullBlock.modules)) return;
|
||||
|
||||
const designIndex = designBlocksAtlasMap[Number(designAsCellData[x][y][z].tile)].designIndex;
|
||||
const solverMetadata = getSolverMetadata(designAsCellData[x][y][z].solverMetadata);
|
||||
const minimizedBlock = minimizedBlocks[designIndex];
|
||||
let recipeIndex = -1;
|
||||
|
||||
if (multiblockType === "nuclearcraft:overhaul_sfr") {
|
||||
if (!minimizedBlock.modules) {
|
||||
minimizedBlock.modules = {};
|
||||
}
|
||||
if (!minimizedBlock.modules["ncpf:block_recipes"]) {
|
||||
minimizedBlock.modules["ncpf:block_recipes"] = {
|
||||
recipes: [],
|
||||
};
|
||||
}
|
||||
const recipes = minimizedBlock.modules["ncpf:block_recipes"].recipes;
|
||||
const recipe = solverMetadata["block_recipe"];
|
||||
recipeIndex = recipes.findIndex(r => checkEquivalence(r, recipe));
|
||||
if (recipeIndex === -1) {
|
||||
recipes.push(stripEntryToMinimums(recipe));
|
||||
recipeIndex = recipes.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return recipeIndex;
|
||||
})
|
||||
.filter(b => b != null)
|
||||
)
|
||||
.filter(r => r.length > 0)
|
||||
)
|
||||
.filter(p => p.length > 0);
|
||||
|
||||
let fileData = null;
|
||||
|
||||
if (multiblockType === "nuclearcraft:overhaul_sfr") {
|
||||
const coolantRecipes = [];
|
||||
let coolantRecipeIndex = -1;
|
||||
const plannerMetadata = getSolverMetadata(getPlannerDom());
|
||||
|
||||
coolantRecipes.push(stripEntryToMinimums(plannerMetadata["coolant_recipe"]));
|
||||
coolantRecipeIndex = 0;
|
||||
|
||||
fileData = {
|
||||
addons: [],
|
||||
configurations: {
|
||||
configuration: {
|
||||
[multiblockType]: {
|
||||
blocks: minimizedBlocks,
|
||||
coolant_recipes: [], // FIXME
|
||||
coolant_recipes: coolantRecipes,
|
||||
},
|
||||
},
|
||||
designs: [
|
||||
{
|
||||
block_recipes: [], // FIXME
|
||||
coolant_recipe: 0, // FIXME
|
||||
block_recipes: blockRecipes,
|
||||
coolant_recipe: coolantRecipeIndex,
|
||||
design: designAsBlockIndices,
|
||||
dimensions: getPlannerMultiblockSize(),
|
||||
type: multiblockType,
|
||||
|
|
@ -111,7 +182,17 @@ export async function saveFile(name) {
|
|||
],
|
||||
version: 1,
|
||||
};
|
||||
|
||||
console.log(designBlocksAtlasMap);
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
console.log(`save file (${name})`, fileData);
|
||||
|
||||
if (fileData) {
|
||||
const blob = new Blob([ JSON.stringify(fileData) ], {
|
||||
type: "application/json",
|
||||
});
|
||||
const a = document.createElement("a");
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = `${name}.ncpf.json`;
|
||||
a.click();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
import { loadConfiguration } from "./configuration.js";
|
||||
import { initializeDialogs } from "./dialogs.js";
|
||||
import { addEventToButton, addEventToInput, debounce, getElements } from "./dom-utils.js";
|
||||
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
||||
import { initializeFileEvents, loadExampleFile, saveFile, showOpenFileDialog } from "./files.js";
|
||||
import { initializePlanner } from "./planner.js";
|
||||
import { initializeMenuResizing } from "./resize-menus.js";
|
||||
import { loadExampleFile } from "./files.js";
|
||||
import { getState, setState, STATE } from "./state.js";
|
||||
import { initializeTooltips } from "./tooltip.js";
|
||||
import { initializeMenuBar } from "./menu-bar.js";
|
||||
import "./menu-bar.js";
|
||||
import "./dialogs.js";
|
||||
|
||||
let loadCallbacks = [];
|
||||
export function registerLoadCallback(cb) {
|
||||
queueMicrotask(() => {
|
||||
loadCallbacks.push(cb);
|
||||
});
|
||||
}
|
||||
function runLoadCallbacks() {
|
||||
loadCallbacks.forEach(cb => cb());
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
emitEvent("setup-start");
|
||||
|
|
@ -41,6 +48,12 @@ window.addEventListener("load", () => {
|
|||
emitEvent(elem.dataset.input + ":change", e);
|
||||
});
|
||||
});
|
||||
getElements("form", "*").forEach(elem => {
|
||||
elem.addEventListener("submit", e => {
|
||||
e.preventDefault();
|
||||
emitEvent(elem.dataset.form + ":submit", e);
|
||||
});
|
||||
});
|
||||
|
||||
addEventToInput("configuration", "input", loadConfiguration);
|
||||
addEventToButton("load-configuration", "click", loadConfiguration);
|
||||
|
|
@ -57,12 +70,7 @@ window.addEventListener("load", () => {
|
|||
|
||||
listenTo("config:end", () => setState(STATE.planning));
|
||||
|
||||
initializeFileEvents();
|
||||
initializePlanner();
|
||||
initializeMenuResizing();
|
||||
initializeTooltips();
|
||||
initializeMenuBar();
|
||||
initializeDialogs();
|
||||
runLoadCallbacks();
|
||||
|
||||
emitEvent("setup-end");
|
||||
|
||||
|
|
@ -70,5 +78,4 @@ window.addEventListener("load", () => {
|
|||
|
||||
awaitEvent("config:end").then(() => loadExampleFile("tiny reactor"));
|
||||
// awaitEvent("config:end").then(() => loadExampleFile("multi-reactor"));
|
||||
awaitEvent("solver:reset:done").then(() => emitEvent("file:save"));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import { positionAsTooltip } from "./tooltip.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
let activeMenuBar = null;
|
||||
|
||||
export function initializeMenuBar() {
|
||||
registerLoadCallback(() => {
|
||||
console.log("menubar-load");
|
||||
document.querySelectorAll(".menu-bar").forEach(menuBar => {
|
||||
menuBar.querySelectorAll("button").forEach(button => {
|
||||
button.setAttribute("tabindex", "-1");
|
||||
|
|
@ -66,7 +68,7 @@ export function initializeMenuBar() {
|
|||
});
|
||||
|
||||
// TODO: keyboard navigation with alt and arrow keys
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handleGlobalClick() {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,17 @@ export function checkEquivalence(a, b) {
|
|||
&& a.metadata === b.metadata
|
||||
&& (a.blockstate === undefined && b.blockstate === undefined
|
||||
|| JSON.stringify(a.blockstate) === JSON.stringify(b.blockstate));
|
||||
|
||||
case "legacy_fluid":
|
||||
return a.name === b.name;
|
||||
|
||||
case "oredict":
|
||||
return a.oredict === b.oredict;
|
||||
|
||||
case "list":
|
||||
return a.elements.length === b.elements.length &&
|
||||
a.elements.every((aE, i) => checkEquivalence(aE, b.elements[i]));
|
||||
|
||||
default:
|
||||
console.warn("unknown type", a.type, a, b);
|
||||
}
|
||||
|
|
@ -24,8 +32,17 @@ export function stripEntryToMinimums(entry) {
|
|||
case "legacy_block":
|
||||
return objectKeepKeys(entry, "type", "name", "metadata", "blockstate");
|
||||
|
||||
case "legacy_fluid":
|
||||
return objectKeepKeys(entry, "type", "name");
|
||||
|
||||
case "oredict":
|
||||
return objectKeepKeys(entry, "type", "oredict");
|
||||
|
||||
case "list":
|
||||
return {
|
||||
type: entry.type,
|
||||
elements: entry.elements.map(stripEntryToMinimums),
|
||||
};
|
||||
}
|
||||
throw new Error(`unknown entry type ${entry.type}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { initialize3dArray } from "./js-utils.js";
|
|||
import { recall, save } from "./storage.js";
|
||||
import { createTooltip, tooltipDataToPlain } from "./tooltip.js";
|
||||
import { lookupFromMetadata, resolveBlockName } from "./ncpf-utils.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
const zoomOptions = [ 0.5, 1, 2, 3, 4, 5 ];
|
||||
const zoomDefault = 2;
|
||||
|
|
@ -17,7 +18,7 @@ let multiblockSize = [9, 7, 9]; // width (screen x), height (xy grids), depth (s
|
|||
let multiblockType = "nuclearcraft:overhaul_sfr";
|
||||
let activeItem = -1;
|
||||
|
||||
export function initializePlanner() {
|
||||
registerLoadCallback(() => {
|
||||
listenTo("config:end", buildBlockPicker);
|
||||
listenTo("config:end", buildPlanner);
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ export function initializePlanner() {
|
|||
console.log("Suppressing hover:", suppressHover);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function buildBlockPicker() {
|
||||
const filter = Filter.fromInput("block-picker:filter");
|
||||
|
|
@ -306,7 +307,7 @@ export function loadPlanner(size, type, textures) {
|
|||
buildPlanner(textures);
|
||||
}
|
||||
|
||||
export function readPlannerTiles() {
|
||||
export function readPlannerCellData() {
|
||||
const planner = document.getElementById("planner");
|
||||
const tiles = initialize3dArray(...multiblockSize, -1);
|
||||
const grids = [...planner.children].filter(e => e.dataset.y);
|
||||
|
|
@ -315,12 +316,21 @@ export function readPlannerTiles() {
|
|||
const gridTiles = [...grid.children].filter(e => e.dataset.tile);
|
||||
for (let z = 0; z < multiblockSize[2]; z++) {
|
||||
for (let x = 0; x < multiblockSize[0]; x++) {
|
||||
tiles[x][y][z] = Number(gridTiles[x + z * multiblockSize[0]].dataset.tile);
|
||||
tiles[x][y][z] = { ...gridTiles[x + z * multiblockSize[0]].dataset };
|
||||
}
|
||||
}
|
||||
}
|
||||
return tiles;
|
||||
}
|
||||
export function getPlannerDom() {
|
||||
return document.getElementById("planner");
|
||||
}
|
||||
export function getPlannerCellsDom() {
|
||||
return document.querySelectorAll("#planner [data-tile]");
|
||||
}
|
||||
export function getPlannerCellDom(x, y, z) {
|
||||
return document.querySelector(`#planner [data-x="${x}"][data-y="${y}"][data-z="${z}"]`);
|
||||
}
|
||||
|
||||
export const getPlannerMultiblockType = () => multiblockType;
|
||||
export const getPlannerMultiblockSize = () => multiblockSize;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { recall, save } from "./storage.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
export function initializeMenuResizing() {
|
||||
registerLoadCallback(() => {
|
||||
const handles = document.querySelectorAll('[data-resize]');
|
||||
handles.forEach(handle => {
|
||||
handle.addEventListener("mousedown", startResize);
|
||||
|
|
@ -9,7 +10,7 @@ export function initializeMenuResizing() {
|
|||
document.body.style.setProperty(`--${handle.dataset.resize}-size`, stored);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function startResize(e) {
|
||||
window.addEventListener("mouseup", endResize);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,72 @@
|
|||
import { configuration } from "./configuration.js";
|
||||
import { emitEvent } from "./events.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { getPlannerCellDom, getPlannerDom } from "./planner.js";
|
||||
import { findFullEntry } from "./ncpf-utils.js";
|
||||
|
||||
registerLoadCallback(() => {
|
||||
});
|
||||
|
||||
const solverMetadata = {};
|
||||
let solverMetadataCounter = 0;
|
||||
function createSolverMetadata(data) {
|
||||
const id = solverMetadataCounter;
|
||||
solverMetadata[id] = data;
|
||||
solverMetadataCounter++;
|
||||
return id;
|
||||
}
|
||||
export function setSolverMetadata(domNode, data) {
|
||||
if (domNode.dataset.solverMetadata) {
|
||||
solverMetadata[Number(domNode.dataset.solverMetadata)] = data;
|
||||
return;
|
||||
}
|
||||
domNode.dataset.solverMetadata = createSolverMetadata(data).toString(10);
|
||||
}
|
||||
export function getSolverMetadata(id) {
|
||||
if (typeof id === "object") {
|
||||
// assume DOM element
|
||||
if (id.dataset && id.dataset.solverMetadata) {
|
||||
return getSolverMetadata(id.dataset.solverMetadata);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (typeof id === "string") {
|
||||
return getSolverMetadata(Number(id));
|
||||
}
|
||||
return solverMetadata[id];
|
||||
}
|
||||
export function deleteSolverMetadata(id) {
|
||||
delete solverMetadata[id];
|
||||
}
|
||||
|
||||
export function resetSolver(design = undefined, designConfiguration) {
|
||||
const planner = getPlannerDom();
|
||||
if (design && designConfiguration) {
|
||||
planner.dataset.type = design.type;
|
||||
if (design.type === "nuclearcraft:overhaul_sfr") {
|
||||
// design has coolant_recipe and block_recipes
|
||||
const designCoolantRecipe = designConfiguration.coolant_recipes[design.coolant_recipe];
|
||||
const fullCoolantRecipe = findFullEntry(
|
||||
"coolant_recipes",
|
||||
designCoolantRecipe,
|
||||
{ configurationHint: design.type },
|
||||
);
|
||||
setSolverMetadata(planner, { coolant_recipe: fullCoolantRecipe });
|
||||
|
||||
const designBlockRecipes = design.block_recipes.flat(3);
|
||||
for (let x = 0; x < design.dimensions[0]; x++) {
|
||||
for (let y = 0; y < design.dimensions[1]; y++) {
|
||||
for (let z = 0; z < design.dimensions[2]; z++) {
|
||||
const block = designConfiguration.blocks[design.design[x][y][z]];
|
||||
if (!block || !block.modules || !block.modules["ncpf:block_recipes"]) continue;
|
||||
const blockRecipeIndex = designBlockRecipes.shift();
|
||||
const blockRecipe = block.modules["ncpf:block_recipes"].recipes[blockRecipeIndex];
|
||||
setSolverMetadata(getPlannerCellDom(x, y, z), { block_recipe: blockRecipe });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function resetSolver(design = undefined) {
|
||||
console.log("solver", configuration, design);
|
||||
emitEvent("solver:reset:done");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { debounce } from "./dom-utils.js";
|
||||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
|
||||
const tooltips = {};
|
||||
let tooltipsCounter = 0;
|
||||
|
|
@ -7,7 +8,7 @@ let lastCoordinates = null;
|
|||
let suppressTooltips = false;
|
||||
let activeTooltipTarget = null;
|
||||
|
||||
export function initializeTooltips() {
|
||||
registerLoadCallback(() => {
|
||||
document.querySelectorAll("[data-retain-tooltip-hover]").forEach(elem =>
|
||||
elem.addEventListener("mousemove", e => {
|
||||
if (lastCoordinates !== null) {
|
||||
|
|
@ -40,7 +41,7 @@ export function initializeTooltips() {
|
|||
suppressTooltips = !suppressTooltips;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export function createTooltip(data) {
|
||||
const id = tooltipsCounter;
|
||||
|
|
|
|||
Loading…
Reference in New Issue