implement reactor loading

This commit is contained in:
CodedSakura 2026-07-10 15:19:52 +03:00
parent 585335c21c
commit 131a2f2dd2
6 changed files with 86 additions and 33 deletions

View File

@ -23,14 +23,7 @@
<button data-alt="i">Invert</button> <button data-alt="i">Invert</button>
</div> </div>
<div data-section="View" data-alt="v"> <div data-section="View" data-alt="v">
<div data-section="Test" data-alt="e"> <button data-alt="c" data-toggle data-toggled="false" data-button="show-casing">Show casing</button>
<div data-section="Test" data-alt="e">
<button disabled>1</button>
</div>
<button disabled>2</button>
<button>102983019283012</button>
</div>
<button disabled>3</button>
</div> </div>
</nav> </nav>
<aside id="left-menu" data-state="planning"> <aside id="left-menu" data-state="planning">

View File

@ -1,7 +1,6 @@
import { emitEvent } from "./events.js"; import { emitEvent } from "./events.js";
import { checkEquivalence } from "./ncpf-utils.js";
let atlasSize = 0; // in items
let atlasResolution = 0; // in px
export let atlases = []; export let atlases = [];
async function getTextureSize(data) { async function getTextureSize(data) {
@ -150,3 +149,18 @@ export function getAtlasMetadata(index) {
return null; return null;
} }
export function getAtlasIndexFromMetadata(metadata, configuration, configurationList = null) {
let index = 0;
for (const atlas of atlases) {
for (const atlasItemMeta of atlas.metadata) {
if (checkEquivalence(metadata, atlasItemMeta)
&& atlasItemMeta.configuration === configuration
&& (!configurationList || atlasItemMeta.configurationList === configurationList)) {
return index;
}
index++;
}
}
return -1;
}

View File

@ -1,5 +1,6 @@
import { awaitEvent, emitEvent } from "./events.js"; import { awaitEvent, emitEvent } from "./events.js";
import { clearPlanner } from "./planner.js"; import { clearPlanner, loadPlanner } from "./planner.js";
import { getAtlasIndexFromMetadata } from "./atlas.js";
export function showOpenFileDialog() { export function showOpenFileDialog() {
const input = document.createElement("input"); const input = document.createElement("input");
@ -38,7 +39,10 @@ export async function loadFile(data) {
if (!design) throw new Error("no design"); if (!design) throw new Error("no design");
clearPlanner(design.dimensions, design.type); const blocks = data.configuration[design.type].blocks
console.log(data); .map(block => getAtlasIndexFromMetadata(block, design.type, "blocks"));
console.log(design);
const designWithAtlas = design.design.map(a => a.map(b => b.map(c => c === -1 ? -1 : blocks[c])));
loadPlanner(design.dimensions, design.type, designWithAtlas);
} }

View File

@ -1,19 +1,30 @@
import { configuration } from "./configuration.js"; import { configuration } from "./configuration.js";
function findInPossible(entryList, entry) { export function checkEquivalence(a, b) {
switch (entry.type) { if (!a.type || !b.type || a.type !== b.type) return false;
switch (a.type) {
case "legacy_block": case "legacy_block":
return entryList.find(v => v.name === entry.name return a.name === b.name
&& v.metadata === entry.metadata && a.metadata === b.metadata
&& (!entry.blockstate || JSON.stringify(v.blockstate) === JSON.stringify(entry.blockstate))); && (a.blockstate === undefined && b.blockstate === undefined
|| JSON.stringify(a.blockstate) === JSON.stringify(b.blockstate));
case "oredict": case "oredict":
return entryList.find(v => v.oredict === entry.oredict); return a.oredict === b.oredict;
default: default:
console.warn("unknown type", entry.type); console.warn("unknown type", a.type, a, b);
} }
return null; return false;
}
export function findFullEntry(type, entry, { configurationHint }) {
const possibleEntries = [
...Object.entries(configuration.configuration),
...configuration.addons.flatMap(a => Object.entries(a.configuration)),
]
.filter(([k, v]) => (!configurationHint || k === configurationHint) && type in v)
.flatMap(([, v]) => v[type]);
return possibleEntries.find(other => checkEquivalence(entry, other));
} }
export function resolveBlockName(block, { configurationHint }) { export function resolveBlockName(block, { configurationHint }) {
@ -51,7 +62,7 @@ export function resolveBlockName(block, { configurationHint }) {
.filter(([k, v]) => (!configurationHint || k === configurationHint) && "blocks" in v) .filter(([k, v]) => (!configurationHint || k === configurationHint) && "blocks" in v)
.flatMap(([, v]) => v.blocks); .flatMap(([, v]) => v.blocks);
const entry = findInPossible(possibleBlocks, block); const entry = possibleBlocks.find(other => checkEquivalence(block, other));
if (!entry) return null; if (!entry) return null;
return entry.modules["plannerator:display_name"].display_name; return entry.modules["plannerator:display_name"].display_name;
@ -69,5 +80,5 @@ export function lookupFromMetadata(metadata) {
.flatMap(([, v]) => v[metadata.configurationList]) .flatMap(([, v]) => v[metadata.configurationList])
.filter(v => v.type === metadata.type); .filter(v => v.type === metadata.type);
return findInPossible(possibleEntries, metadata); return possibleEntries.find(other => checkEquivalence(metadata, other));
} }

View File

@ -4,6 +4,7 @@ import { emitEvent, listenTo } from "./events.js";
import { Filter } from "./filter.js"; import { Filter } from "./filter.js";
import { createTooltip } from "./tooltip.js"; import { createTooltip } from "./tooltip.js";
import { lookupFromMetadata, resolveBlockName } from "./ncpf-utils.js"; import { lookupFromMetadata, resolveBlockName } from "./ncpf-utils.js";
import { addEventToButton } from "./dom-utils.js";
let suppressHover = false; let suppressHover = false;
let multiblockSize = [9, 7, 9]; // width (screen x), height (xy grids), depth (screen y) let multiblockSize = [9, 7, 9]; // width (screen x), height (xy grids), depth (screen y)
@ -110,6 +111,21 @@ export function initializePlanner() {
listenTo("config:end", buildBlockPicker); listenTo("config:end", buildBlockPicker);
listenTo("config:end", buildPlanner); listenTo("config:end", buildPlanner);
addEventToButton("show-casing", "click", e => {
const wasChecked = e.currentTarget.dataset.toggled === "true";
const show = !wasChecked;
e.currentTarget.dataset.toggled = show.toString();
const planner = document.querySelector("#planner");
planner.dataset.casing = show ? "show" : "hide";
});
document.addEventListener("keydown", e => {
if (e.key === "H") {
suppressHover = !suppressHover;
}
});
} }
function buildBlockPicker() { function buildBlockPicker() {
@ -135,12 +151,9 @@ function buildBlockPicker() {
}); });
} }
function buildPlanner() { function buildPlanner(textures) {
document.addEventListener("keydown", e => { // handle case when 1st argument is event
if (e.key === "H") { if (!Array.isArray(textures)) textures = undefined;
suppressHover = !suppressHover;
}
});
const planner = document.querySelector("#planner"); const planner = document.querySelector("#planner");
planner.dataset.casing = "hide"; planner.dataset.casing = "hide";
@ -158,17 +171,21 @@ function buildPlanner() {
grid.clear(); grid.clear();
for (let z = 0; z < multiblockSize[2]; z++) { for (let z = 0; z < multiblockSize[2]; z++) {
for (let x = 0; x < multiblockSize[0]; x++) { for (let x = 0; x < multiblockSize[0]; x++) {
const texture = textures ? textures[x][y][z] : -1;
if (textures && !texture) {
console.log(x, y, z, textures);
}
const cell = grid.makeItem(); const cell = grid.makeItem();
cell.dataset.x = x.toString(10); cell.dataset.x = x.toString(10);
cell.dataset.y = y.toString(10); cell.dataset.y = y.toString(10);
cell.dataset.z = z.toString(10); cell.dataset.z = z.toString(10);
cell.dataset.tile = (-1).toString(10); cell.dataset.tile = texture.toString(10);
if (x === 0 || x === multiblockSize[0] - 1 if (x === 0 || x === multiblockSize[0] - 1
|| y === 0 || y === multiblockSize[1] - 1 || y === 0 || y === multiblockSize[1] - 1
|| z === 0 || z === multiblockSize[2] - 1) { || z === 0 || z === multiblockSize[2] - 1) {
cell.dataset.casing = ""; cell.dataset.casing = "";
} }
cell.appendChild(makeAtlasImage(-1)); cell.appendChild(makeAtlasImage(texture));
cell.addEventListener("mouseenter", cellHoverEvent); cell.addEventListener("mouseenter", cellHoverEvent);
cell.addEventListener("mouseleave", cellHoverEvent); cell.addEventListener("mouseleave", cellHoverEvent);
cell.addEventListener("mousedown", cellClickEvent); cell.addEventListener("mousedown", cellClickEvent);
@ -187,6 +204,11 @@ export function clearPlanner(size, type) {
multiblockType = type; multiblockType = type;
buildPlanner(); buildPlanner();
} }
export function loadPlanner(size, type, textures) {
multiblockSize = size;
multiblockType = type;
buildPlanner(textures);
}
function* getBlockTooltip(metadata) { function* getBlockTooltip(metadata) {
const data = lookupFromMetadata(metadata); const data = lookupFromMetadata(metadata);

View File

@ -284,6 +284,15 @@ input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
.menu-bar .alt-key { .menu-bar .alt-key {
text-decoration: underline; text-decoration: underline;
} }
.menu-bar [data-section]:has(> [data-toggle]) > button:not([data-toggle]) {
padding-left: 1em;
}
.menu-bar button[data-toggle][data-toggled="false"]::before {
content: '[ ] ';
}
.menu-bar button[data-toggle][data-toggled="true"]::before {
content: '[x] ';
}
.dialog.hidden { .dialog.hidden {
display: none; display: none;