move block-picker into it's own file
This commit is contained in:
parent
c17c7415c9
commit
586cea0529
|
|
@ -0,0 +1,199 @@
|
|||
import { DomList } from "./dom-list.js";
|
||||
import { atlases, makeAtlasImage } from "./atlas.js";
|
||||
import { Filter } from "./filter.js";
|
||||
import { createTooltip, tooltipDataToPlain } from "./tooltip.js";
|
||||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { getPlannerMultiblockType } from "./planner.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { lookupFromMetadata, resolveBlockName } from "./ncpf-utils.js";
|
||||
|
||||
registerLoadCallback(() => {
|
||||
listenTo("config:end", buildBlockPicker);
|
||||
listenTo("block-picker:filter:input", buildBlockPicker);
|
||||
});
|
||||
|
||||
function buildBlockPicker() {
|
||||
const filter = Filter.fromInput("block-picker:filter");
|
||||
|
||||
const grid = new DomList(document.getElementById("block-picker-list"));
|
||||
grid.clear();
|
||||
|
||||
atlases.flatMap(a => a.metadata)
|
||||
.filter(m => m.configuration === getPlannerMultiblockType() && m.configurationList === "blocks")
|
||||
.forEach(m => {
|
||||
const item = grid.makeItem();
|
||||
item.dataset.index = m.index.toString(10);
|
||||
const tooltipData = [...getBlockTooltip(m)];
|
||||
item.dataset.tooltip = createTooltip(tooltipData).toString(10);
|
||||
if (!filter.test(...tooltipDataToPlain(tooltipData))) {
|
||||
item.classList.add("hidden");
|
||||
}
|
||||
item.appendChild(makeAtlasImage(m.index));
|
||||
item.addEventListener("click", blockPickerClickEvent);
|
||||
grid.addItem(item);
|
||||
});
|
||||
}
|
||||
|
||||
function blockPickerClickEvent(e) {
|
||||
const blockPickerDom = document.getElementById("block-picker-list");
|
||||
const items = document.querySelectorAll("#block-picker-list [data-index]");
|
||||
if (e.currentTarget.dataset.active !== undefined) {
|
||||
items.forEach(i => delete i.dataset.active);
|
||||
blockPickerDom.dataset.activeItem = (-1).toString(10);
|
||||
delete e.currentTarget.dataset.active;
|
||||
emitEvent("block-picker:selection", -1);
|
||||
emitEvent("block-picker:selection:clear");
|
||||
return;
|
||||
}
|
||||
items.forEach(i => delete i.dataset.active);
|
||||
blockPickerDom.dataset.activeItem = e.currentTarget.dataset.index;
|
||||
e.currentTarget.dataset.active = "";
|
||||
emitEvent("block-picker:selection", blockPickerDom.dataset.activeItem);
|
||||
}
|
||||
|
||||
function* getBlockTooltip(metadata) {
|
||||
const data = lookupFromMetadata(metadata);
|
||||
|
||||
if (!data) {
|
||||
console.warn("failed to get data from metadata", metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
yield data.modules["plannerator:display_name"].display_name;
|
||||
|
||||
let hasAdditionalData = false;
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:heat_sink" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const heatSink = data.modules["nuclearcraft:overhaul_sfr:heat_sink"];
|
||||
yield "Heatsink";
|
||||
if (heatSink.cooling) {
|
||||
yield `Cooling: ${heatSink.cooling} H/t`;
|
||||
}
|
||||
if (heatSink.rules) {
|
||||
for (const rule of heatSink.rules) {
|
||||
yield "Requires " + parseRuleAsTooltip(rule, { configurationHint: metadata.configuration });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:casing" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Casing";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:controller" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Controller";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:fuel_cell" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Fuel Cell";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:port" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
if (data.modules["nuclearcraft:overhaul_sfr:port"].output) {
|
||||
yield "Output Port";
|
||||
} else {
|
||||
yield "Input Port";
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:irradiator" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Irradiator";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:conductor" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Conductor";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:moderator" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const moderator = data.modules["nuclearcraft:overhaul_sfr:moderator"];
|
||||
yield "Moderator";
|
||||
yield `Flux: ${moderator.flux}`;
|
||||
yield `Efficiency: ${moderator.efficiency}`;
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:reflector" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const reflector = data.modules["nuclearcraft:overhaul_sfr:reflector"];
|
||||
yield "Reflector";
|
||||
yield `Efficiency: ${reflector.efficiency}`;
|
||||
yield `Reflectivity: ${reflector.reflectivity}`;
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:neutron_shield" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const shield = data.modules["nuclearcraft:overhaul_sfr:neutron_shield"];
|
||||
yield "Neutron Shield";
|
||||
yield `Efficiency: ${shield.efficiency}`;
|
||||
yield `Heat per Flux: ${shield.heat_per_flux}`;
|
||||
}
|
||||
|
||||
if (!hasAdditionalData) {
|
||||
console.log("unknown block", data);
|
||||
}
|
||||
|
||||
yield {
|
||||
type: "italics",
|
||||
text: metadata.configurationAddon.name,
|
||||
};
|
||||
}
|
||||
|
||||
function parseRuleAsTooltip(rule, props) {
|
||||
switch (rule.type) {
|
||||
case "and":
|
||||
return rule.rules.map(r => parseRuleAsTooltip(r, props)).join(" AND ");
|
||||
|
||||
case "or":
|
||||
return rule.rules.map(r => parseRuleAsTooltip(r, props)).join(" OR ");
|
||||
|
||||
case "between": {
|
||||
const block = resolveBlockName(rule.block, props);
|
||||
if (!block) {
|
||||
console.warn("could not find block %o", rule.block);
|
||||
return "???";
|
||||
}
|
||||
if (rule.min === rule.max) {
|
||||
return `exactly ${rule.min} ${block}`;
|
||||
} else if (rule.max === 6) {
|
||||
return `at least ${rule.min} ${block}`;
|
||||
} else if (rule.min === 0) {
|
||||
return `no more than ${rule.max} ${block}`;
|
||||
} else {
|
||||
return `between ${rule.min} and ${rule.max} ${block}`;
|
||||
}
|
||||
}
|
||||
|
||||
case "axial": {
|
||||
const block = resolveBlockName(rule.block, props);
|
||||
if (!block) {
|
||||
console.warn("could not find block %o", rule.block);
|
||||
return "???";
|
||||
}
|
||||
if (rule.min === rule.max) {
|
||||
return `exactly ${rule.min} axial ${block}`;
|
||||
} else if (rule.max === 3) {
|
||||
return `at least ${rule.min} axial ${block}`;
|
||||
} else if (rule.min === 0) {
|
||||
return `no more than ${rule.max} axial ${block}`;
|
||||
} else {
|
||||
return `between ${rule.min} and ${rule.max} axial ${block}`;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
console.warn("unknown rule: %o", rule);
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
export function getBlockPickerActiveItem() {
|
||||
const blockPickerDom = document.getElementById("block-picker-list");
|
||||
return Number(blockPickerDom.dataset.activeItem);
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import "./atlas.js";
|
||||
import "./block-picker.js";
|
||||
import { loadConfiguration } from "./configuration.js";
|
||||
import "./dialogs.js";
|
||||
import "./dom-list.js";
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
import { atlases, makeAtlasImage } from "./atlas.js";
|
||||
import { makeAtlasImage } from "./atlas.js";
|
||||
import { DomList } from "./dom-list.js";
|
||||
import { getElements } from "./dom-utils.js";
|
||||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { Filter } from "./filter.js";
|
||||
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";
|
||||
import { getBlockPickerActiveItem } from "./block-picker.js";
|
||||
|
||||
const zoomOptions = [ 0.5, 1, 2, 3, 4, 5 ];
|
||||
const zoomDefault = 2;
|
||||
|
|
@ -16,14 +14,10 @@ const zoomStorageKey = "zoom-size";
|
|||
let suppressHover = false;
|
||||
let multiblockSize = [9, 7, 9]; // width (screen x), height (xy grids), depth (screen y)
|
||||
let multiblockType = "nuclearcraft:overhaul_sfr";
|
||||
let activeItem = -1;
|
||||
|
||||
registerLoadCallback(() => {
|
||||
listenTo("config:end", buildBlockPicker);
|
||||
listenTo("config:end", buildPlanner);
|
||||
|
||||
listenTo("block-picker:filter:input", buildBlockPicker);
|
||||
|
||||
listenTo("planner:toggle-casing", e => {
|
||||
const planner = document.getElementById("planner");
|
||||
planner.dataset.casing = e.detail.state ? "show" : "hide";
|
||||
|
|
@ -77,6 +71,7 @@ registerLoadCallback(() => {
|
|||
|
||||
save(zoomStorageKey, scale);
|
||||
});
|
||||
|
||||
listenTo("block-picker:selection", clearSelectedCells);
|
||||
|
||||
document.addEventListener("keydown", e => {
|
||||
|
|
@ -87,44 +82,6 @@ registerLoadCallback(() => {
|
|||
});
|
||||
});
|
||||
|
||||
function buildBlockPicker() {
|
||||
const filter = Filter.fromInput("block-picker:filter");
|
||||
|
||||
const grid = new DomList(document.getElementById("block-picker-list"));
|
||||
grid.clear();
|
||||
|
||||
atlases.flatMap(a => a.metadata)
|
||||
.filter(m => m.configuration === multiblockType && m.configurationList === "blocks")
|
||||
.forEach(m => {
|
||||
const item = grid.makeItem();
|
||||
item.dataset.index = m.index.toString(10);
|
||||
const tooltipData = [...getBlockTooltip(m)];
|
||||
item.dataset.tooltip = createTooltip(tooltipData).toString(10);
|
||||
if (!filter.test(...tooltipDataToPlain(tooltipData))) {
|
||||
item.classList.add("hidden");
|
||||
}
|
||||
item.appendChild(makeAtlasImage(m.index));
|
||||
item.addEventListener("click", blockPickerClickEvent);
|
||||
grid.addItem(item);
|
||||
});
|
||||
}
|
||||
|
||||
function blockPickerClickEvent(e) {
|
||||
const items = document.querySelectorAll("#block-picker-list [data-index]");
|
||||
if (e.currentTarget.dataset.active !== undefined) {
|
||||
items.forEach(i => delete i.dataset.active);
|
||||
activeItem = -1;
|
||||
delete e.currentTarget.dataset.active;
|
||||
emitEvent("block-picker:selection", activeItem);
|
||||
emitEvent("block-picker:selection:clear");
|
||||
return;
|
||||
}
|
||||
items.forEach(i => delete i.dataset.active);
|
||||
activeItem = Number(e.currentTarget.dataset.index);
|
||||
e.currentTarget.dataset.active = "";
|
||||
emitEvent("block-picker:selection", activeItem);
|
||||
}
|
||||
|
||||
function buildPlanner(textures) {
|
||||
// handle case when 1st argument is event
|
||||
if (!Array.isArray(textures)) textures = undefined;
|
||||
|
|
@ -176,7 +133,7 @@ function buildPlanner(textures) {
|
|||
|
||||
function cellHoverEvent(e) {
|
||||
if (suppressHover) return;
|
||||
if (activeItem === -1) return;
|
||||
if (getBlockPickerActiveItem() === -1) return;
|
||||
if (document.body.dataset.resizing) return;
|
||||
|
||||
const cells = document.querySelectorAll("#planner [data-x]");
|
||||
|
|
@ -219,6 +176,7 @@ function cellClickEvent(e) {
|
|||
return;
|
||||
}
|
||||
|
||||
const activeItem = getBlockPickerActiveItem();
|
||||
if (activeItem === -1) {
|
||||
cellSelectEvent(e);
|
||||
return;
|
||||
|
|
@ -339,145 +297,3 @@ export function getPlannerCellDom(x, y, z) {
|
|||
|
||||
export const getPlannerMultiblockType = () => multiblockType;
|
||||
export const getPlannerMultiblockSize = () => multiblockSize;
|
||||
|
||||
function* getBlockTooltip(metadata) {
|
||||
const data = lookupFromMetadata(metadata);
|
||||
|
||||
if (!data) {
|
||||
console.warn("failed to get data from metadata", metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
yield data.modules["plannerator:display_name"].display_name;
|
||||
|
||||
let hasAdditionalData = false;
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:heat_sink" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const heatSink = data.modules["nuclearcraft:overhaul_sfr:heat_sink"];
|
||||
yield "Heatsink";
|
||||
if (heatSink.cooling) {
|
||||
yield `Cooling: ${heatSink.cooling} H/t`;
|
||||
}
|
||||
if (heatSink.rules) {
|
||||
for (const rule of heatSink.rules) {
|
||||
yield "Requires " + parseRuleAsTooltip(rule, { configurationHint: metadata.configuration });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:casing" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Casing";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:controller" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Controller";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:fuel_cell" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Fuel Cell";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:port" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
if (data.modules["nuclearcraft:overhaul_sfr:port"].output) {
|
||||
yield "Output Port";
|
||||
} else {
|
||||
yield "Input Port";
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:irradiator" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Irradiator";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:conductor" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Conductor";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:moderator" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const moderator = data.modules["nuclearcraft:overhaul_sfr:moderator"];
|
||||
yield "Moderator";
|
||||
yield `Flux: ${moderator.flux}`;
|
||||
yield `Efficiency: ${moderator.efficiency}`;
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:reflector" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const reflector = data.modules["nuclearcraft:overhaul_sfr:reflector"];
|
||||
yield "Reflector";
|
||||
yield `Efficiency: ${reflector.efficiency}`;
|
||||
yield `Reflectivity: ${reflector.reflectivity}`;
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:neutron_shield" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const shield = data.modules["nuclearcraft:overhaul_sfr:neutron_shield"];
|
||||
yield "Neutron Shield";
|
||||
yield `Efficiency: ${shield.efficiency}`;
|
||||
yield `Heat per Flux: ${shield.heat_per_flux}`;
|
||||
}
|
||||
|
||||
if (!hasAdditionalData) {
|
||||
console.log("unknown block", data);
|
||||
}
|
||||
|
||||
yield {
|
||||
type: "italics",
|
||||
text: metadata.configurationAddon.name,
|
||||
};
|
||||
}
|
||||
|
||||
function parseRuleAsTooltip(rule, props) {
|
||||
switch (rule.type) {
|
||||
case "and":
|
||||
return rule.rules.map(r => parseRuleAsTooltip(r, props)).join(" AND ");
|
||||
|
||||
case "or":
|
||||
return rule.rules.map(r => parseRuleAsTooltip(r, props)).join(" OR ");
|
||||
|
||||
case "between": {
|
||||
const block = resolveBlockName(rule.block, props);
|
||||
if (!block) {
|
||||
console.warn("could not find block %o", rule.block);
|
||||
return "???";
|
||||
}
|
||||
if (rule.min === rule.max) {
|
||||
return `exactly ${rule.min} ${block}`;
|
||||
} else if (rule.max === 6) {
|
||||
return `at least ${rule.min} ${block}`;
|
||||
} else if (rule.min === 0) {
|
||||
return `no more than ${rule.max} ${block}`;
|
||||
} else {
|
||||
return `between ${rule.min} and ${rule.max} ${block}`;
|
||||
}
|
||||
}
|
||||
|
||||
case "axial": {
|
||||
const block = resolveBlockName(rule.block, props);
|
||||
if (!block) {
|
||||
console.warn("could not find block %o", rule.block);
|
||||
return "???";
|
||||
}
|
||||
if (rule.min === rule.max) {
|
||||
return `exactly ${rule.min} axial ${block}`;
|
||||
} else if (rule.max === 3) {
|
||||
return `at least ${rule.min} axial ${block}`;
|
||||
} else if (rule.min === 0) {
|
||||
return `no more than ${rule.max} axial ${block}`;
|
||||
} else {
|
||||
return `between ${rule.min} and ${rule.max} axial ${block}`;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
console.warn("unknown rule: %o", rule);
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue