Compare commits
No commits in common. "main" and "pre-alpha/1.5" have entirely different histories.
main
...
pre-alpha/
|
|
@ -1,11 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitSharedSettings">
|
||||
<option name="FORCE_PUSH_PROHIBITED_PATTERNS">
|
||||
<list />
|
||||
</option>
|
||||
<option name="synchronizeBranchProtectionRules" value="false" />
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
{"addons":[],"configuration":{"nuclearcraft:overhaul_sfr":{"blocks":[{"name":"nuclearcraft:solid_fission_controller","type":"legacy_block"},{"name":"nuclearcraft:fission_vent","type":"legacy_block","blockstate":{"active":false}},{"name":"nuclearcraft:fission_vent","type":"legacy_block","blockstate":{"active":true}},{"name":"nuclearcraft:fission_casing","type":"legacy_block"},{"name":"nuclearcraft:fission_glass","type":"legacy_block"},{"metadata":2,"name":"nuclearcraft:fission_source","type":"legacy_block","blockstate":{"type":"californium"}},{"name":"nuclearcraft:solid_fission_cell","type":"legacy_block","modules":{"ncpf:block_recipes":{"recipes":[{"oredict":"ingotHEU233ZA","type":"oredict"}]}}},{"name":"nuclearcraft:fission_cell_port","type":"legacy_block","blockstate":{"active":false},"modules":{"ncpf:block_recipes":{"recipes":[{"oredict":"ingotHEU233ZA","type":"oredict"}]}}},{"name":"nuclearcraft:fission_cell_port","type":"legacy_block","blockstate":{"active":true},"modules":{"ncpf:block_recipes":{"recipes":[{"oredict":"ingotHEU233ZA","type":"oredict"}]}}},{"name":"nuclearcraft:heavy_water_moderator","type":"legacy_block"},{"metadata":0,"name":"nuclearcraft:fission_shield","type":"legacy_block","blockstate":{"active":false,"type":"boron_silver"}},{"metadata":0,"name":"nuclearcraft:fission_shield","type":"legacy_block","blockstate":{"active":true,"type":"boron_silver"}}],"coolant_recipes":[{"elements":[{"name":"water","type":"legacy_fluid"},{"name":"condensate_water","type":"legacy_fluid"}],"type":"list"}]}},"designs":[{"design":[[[3,3,3,3,3,3,3,3,3],[3,0,1,2,7,8,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,3,3,3,3,3,3,3,3]],[[3,5,4,4,4,4,4,4,3],[4,6,-1,-1,-1,6,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,9,-1,-1,-1,9,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,10,-1,-1,-1,10,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,9,-1,-1,-1,9,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,6,9,11,9,6,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,4,4,4,4,4,4,4,3],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[4,-1,-1,-1,-1,-1,-1,-1,4],[3,4,4,4,4,4,4,4,3]],[[3,3,3,3,3,3,3,3,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,4,4,4,4,4,4,4,3],[3,3,3,3,3,3,3,3,3]]],"block_recipes":[[[0,0]],[[0,0]],[[0,0]]],"type":"nuclearcraft:overhaul_sfr","coolant_recipe":0,"dimensions":[9,7,9]}],"version":1}
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
</section>
|
||||
</aside>
|
||||
<footer>
|
||||
<div>alpha 1.8</div>
|
||||
<div>pre-alpha 1.5</div>
|
||||
<div>
|
||||
<a href="https://discord.gg/Eq72HwPqfg">Discord server</a>
|
||||
</div>
|
||||
|
|
@ -146,7 +146,7 @@
|
|||
Roadmap:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Reactor stats</li>
|
||||
<li>Reactor verification and stats</li>
|
||||
<li>Casing improvements</li>
|
||||
<li>Keyboard shortcuts</li>
|
||||
<li>MSR support</li>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { createTooltip, tooltipDataToPlain } from "./tooltip.js";
|
|||
import { emitEvent, listenTo } from "./events.js";
|
||||
import { getPlannerMultiblockType } from "./planner.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { lookupFromMetadata, parseRuleAsString, resolveBlockName } from "./ncpf-utils.js";
|
||||
import { lookupFromMetadata, resolveBlockName } from "./ncpf-utils.js";
|
||||
|
||||
registerLoadCallback(() => {
|
||||
listenTo("config:end", buildBlockPicker);
|
||||
|
|
@ -78,7 +78,7 @@ function* getBlockTooltip(metadata) {
|
|||
}
|
||||
if (heatSink.rules) {
|
||||
for (const rule of heatSink.rules) {
|
||||
yield "Requires " + parseRuleAsString(rule, { configurationHint: metadata.configuration });
|
||||
yield "Requires " + parseRuleAsTooltip(rule, { configurationHint: metadata.configuration });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -99,15 +99,15 @@ function* getBlockTooltip(metadata) {
|
|||
|
||||
if ("nuclearcraft:overhaul_sfr:fuel_cell" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
yield "Fuel cell";
|
||||
yield "Fuel Cell";
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:port" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
if (data.modules["nuclearcraft:overhaul_sfr:port"].output) {
|
||||
yield "Output port";
|
||||
yield "Output Port";
|
||||
} else {
|
||||
yield "Input port";
|
||||
yield "Input Port";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ function* getBlockTooltip(metadata) {
|
|||
if ("nuclearcraft:overhaul_sfr:neutron_source" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const neutronSource = data.modules["nuclearcraft:overhaul_sfr:neutron_source"];
|
||||
yield "Neutron source";
|
||||
yield "Neutron Source";
|
||||
yield `Efficiency: ${neutronSource.efficiency}`;
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ function* getBlockTooltip(metadata) {
|
|||
hasAdditionalData = true;
|
||||
const moderator = data.modules["nuclearcraft:overhaul_sfr:moderator"];
|
||||
yield "Moderator";
|
||||
yield `Flux factor: ${moderator.flux}`;
|
||||
yield `Flux: ${moderator.flux}`;
|
||||
yield `Efficiency: ${moderator.efficiency}`;
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ function* getBlockTooltip(metadata) {
|
|||
if ("nuclearcraft:overhaul_sfr:neutron_shield" in data.modules) {
|
||||
hasAdditionalData = true;
|
||||
const shield = data.modules["nuclearcraft:overhaul_sfr:neutron_shield"];
|
||||
yield "Neutron shield";
|
||||
yield "Neutron Shield";
|
||||
yield `Efficiency: ${shield.efficiency}`;
|
||||
yield `Heat per Flux: ${shield.heat_per_flux}`;
|
||||
}
|
||||
|
|
@ -162,6 +162,54 @@ function* getBlockTooltip(metadata) {
|
|||
};
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ registerLoadCallback(() => {
|
|||
});
|
||||
|
||||
awaitEvent("config:end").then(() => {
|
||||
void loadExampleFile("shield test");
|
||||
void loadExampleFile("Pandora's Fission Reactor");
|
||||
});
|
||||
|
||||
queueMicrotask(() => emitEvent("dev-mode:end"));
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ export async function saveFile(name = undefined) {
|
|||
if (!fullBlock || !fullBlock.modules || !("ncpf:block_recipes" in fullBlock.modules)) return;
|
||||
|
||||
const designIndex = designBlocksAtlasMap[Number(designAsCellData[x][y][z].tile)].designIndex;
|
||||
const solverMetadata = getMetadata(designAsCellData[x][y][z].metadata);
|
||||
const solverMetadata = getMetadata(designAsCellData[x][y][z].solverMetadata);
|
||||
const minimizedBlock = minimizedBlocks[designIndex];
|
||||
let recipeIndex = -1;
|
||||
|
||||
|
|
@ -156,8 +156,6 @@ export async function saveFile(name = undefined) {
|
|||
}
|
||||
}
|
||||
|
||||
console.log(recipeIndex)
|
||||
|
||||
return recipeIndex;
|
||||
})
|
||||
.filter(b => b != null)
|
||||
|
|
|
|||
|
|
@ -9,19 +9,17 @@ function createMetadata(data) {
|
|||
return id;
|
||||
}
|
||||
export function setDomMetadata(domNode, data) {
|
||||
if (domNode.dataset.metadata) {
|
||||
metadata[Number(domNode.dataset.metadata)] = data;
|
||||
if (domNode.dataset.solverMetadata) {
|
||||
metadata[Number(domNode.dataset.solverMetadata)] = data;
|
||||
return;
|
||||
}
|
||||
domNode.dataset.metadata = createMetadata(data).toString(10);
|
||||
domNode.dataset.solverMetadata = createMetadata(data).toString(10);
|
||||
}
|
||||
export function setCellMetadata(node, key, value) {
|
||||
if (!node.dataset.metadata) {
|
||||
node.dataset.metadata = createMetadata({ [key]: value }).toString(10);
|
||||
} else if (!metadata[Number(node.dataset.metadata)]) {
|
||||
metadata[Number(node.dataset.metadata)] = { [key]: value };
|
||||
if (!node.dataset.solverMetadata) {
|
||||
node.dataset.solverMetadata = createMetadata({ [key]: value }).toString(10);
|
||||
} else {
|
||||
metadata[Number(node.dataset.metadata)][key] = value;
|
||||
metadata[Number(node.dataset.solverMetadata)][key] = value;
|
||||
}
|
||||
processCellOverlays(node, key, true);
|
||||
}
|
||||
|
|
@ -29,8 +27,8 @@ export function setCellMetadata(node, key, value) {
|
|||
export function getMetadata(id) {
|
||||
if (typeof id === "object") {
|
||||
// assume DOM element
|
||||
if (id.dataset && id.dataset.metadata) {
|
||||
return getMetadata(id.dataset.metadata);
|
||||
if (id.dataset && id.dataset.solverMetadata) {
|
||||
return getMetadata(id.dataset.solverMetadata);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -40,23 +38,21 @@ export function getMetadata(id) {
|
|||
return metadata[id];
|
||||
}
|
||||
export function getCellMetadata(node, key) {
|
||||
if (!node.dataset.metadata) return null;
|
||||
return metadata[Number(node.dataset.metadata)][key];
|
||||
return metadata[Number(node.dataset.solverMetadata)][key];
|
||||
}
|
||||
|
||||
export function deleteMetadata(id) {
|
||||
if (typeof id === "object") {
|
||||
// assume DOM object
|
||||
if (id.dataset && id.dataset.metadata) {
|
||||
if (id.dataset && id.dataset.solverMetadata) {
|
||||
clearCellOverlays(id);
|
||||
return deleteMetadata(id.dataset.metadata);
|
||||
return deleteMetadata(id.dataset.solverMetadata);
|
||||
}
|
||||
}
|
||||
delete metadata[id];
|
||||
}
|
||||
export function clearCellMetadata(node, key) {
|
||||
if (!node.dataset.metadata) return;
|
||||
if (!metadata[Number(node.dataset.metadata)]) return;
|
||||
delete metadata[Number(node.dataset.metadata)][key];
|
||||
if (!node.dataset.solverMetadata) return;
|
||||
delete metadata[Number(node.dataset.solverMetadata)][key];
|
||||
processCellOverlays(node, key, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,51 +153,3 @@ export function lookupFromMetadata(metadata) {
|
|||
|
||||
return possibleEntries.find(other => checkEquivalence(metadata, other));
|
||||
}
|
||||
|
||||
export function parseRuleAsString(rule, props = { configurationHint: null }) {
|
||||
switch (rule.type) {
|
||||
case "and":
|
||||
return rule.rules.map(r => parseRuleAsString(r, props)).join(" AND ");
|
||||
|
||||
case "or":
|
||||
return rule.rules.map(r => parseRuleAsString(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 "???";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ import { getAtlasIndexFromMetadata, makeAtlasImage } from "./atlas.js";
|
|||
|
||||
export function processCellOverlays(node, key = null, added = null) {
|
||||
if (key) {
|
||||
node.replaceChildren(...node.querySelectorAll(`:scope > *:not([data-overlay="${key}"])`));
|
||||
|
||||
const metadata = getCellMetadata(node, key);
|
||||
const atlasIndex = getAtlasIndexFromMetadata(metadata);
|
||||
if (atlasIndex && atlasIndex !== -1) {
|
||||
|
|
@ -13,14 +11,6 @@ export function processCellOverlays(node, key = null, added = null) {
|
|||
overlayNode.classList.add("planner--overlay");
|
||||
node.appendChild(overlayNode);
|
||||
}
|
||||
|
||||
if (key === "active" && added) {
|
||||
const overlayNode = makeAtlasImage(-1);
|
||||
overlayNode.dataset.overlay = key;
|
||||
overlayNode.dataset.active = metadata ? "true" : "false";
|
||||
overlayNode.classList.add("planner--overlay");
|
||||
node.appendChild(overlayNode);
|
||||
}
|
||||
// FIXME: handle remove
|
||||
}
|
||||
// TODO: handle generic update
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import { initialize3dArray } from "./js-utils.js";
|
|||
import { recall, save } from "./storage.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { getBlockPickerActiveItem, getBlockPickerRecipe } from "./block-picker.js";
|
||||
import { clearCellMetadata, deleteMetadata, getMetadata, setCellMetadata } from "./metadata.js";
|
||||
import { clearCellMetadata, getMetadata, setCellMetadata } from "./metadata.js";
|
||||
import { retainTooltipHover } from "./tooltip.js";
|
||||
import { checkEquivalence, lookupFromMetadata, parseRuleAsString } from "./ncpf-utils.js";
|
||||
import { checkEquivalence, lookupFromMetadata } from "./ncpf-utils.js";
|
||||
|
||||
const zoomOptions = [ 0.5, 1, 2, 3, 4, 5 ];
|
||||
const zoomDefault = 2;
|
||||
|
|
@ -250,14 +250,13 @@ function cellClickEvent(e) {
|
|||
if (e.target.tile === "-1") return;
|
||||
|
||||
e.target.dataset.previewRemove = "yes";
|
||||
deleteMetadata(e.target);
|
||||
clearCellMetadata(e.target, "block_recipe");
|
||||
} else if (e.buttons === 1) {
|
||||
// add
|
||||
if (e.target.dataset.preview === activeItem.toString(10)) return;
|
||||
|
||||
e.target.dataset.preview = activeItem.toString(10);
|
||||
e.target.replaceChildren(makeAtlasImage(activeItem));
|
||||
deleteMetadata(e.target);
|
||||
const pickerRecipe = getBlockPickerRecipe();
|
||||
if (pickerRecipe) {
|
||||
setCellMetadata(e.target, "block_recipe", pickerRecipe);
|
||||
|
|
@ -325,7 +324,7 @@ export function getPlannerDom() {
|
|||
return document.getElementById("planner");
|
||||
}
|
||||
export function getPlannerCellsDom() {
|
||||
return [...document.querySelectorAll("#planner [data-tile]")];
|
||||
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}"]`);
|
||||
|
|
@ -353,74 +352,6 @@ export function* getCellTooltip(cell) {
|
|||
name: recipe.modules["plannerator:display_name"].display_name,
|
||||
atlasIndex: getAtlasIndexFromMetadata(recipe, multiblockType, "ncpf:block_recipes"),
|
||||
}
|
||||
if ("nuclearcraft:overhaul_sfr:fuel_stats" in recipe.modules) {
|
||||
const stats = recipe.modules["nuclearcraft:overhaul_sfr:fuel_stats"];
|
||||
|
||||
if (solverMetadata.primer) {
|
||||
if (solverMetadata.primer.dom === cell) {
|
||||
yield "Primed (self-priming)";
|
||||
} else {
|
||||
const direction = ["x", "y", "z"].flatMap((d) => solverMetadata.primer[d] !== cell.dataset[d] ? d : [])
|
||||
.map(d => (Number(cell.dataset[d]) < Number(solverMetadata.primer[d]) ? "+" : "-") + d.toUpperCase())[0];
|
||||
yield `Primed (${solverMetadata.primer.tile.modules["plannerator:display_name"].display_name}, ${direction})`;
|
||||
}
|
||||
} else {
|
||||
yield "Not primed";
|
||||
}
|
||||
yield {
|
||||
type: "compound",
|
||||
items: [
|
||||
`Criticality: `,
|
||||
{
|
||||
type: "bold",
|
||||
text: `${solverMetadata.flux ?? 0}/${stats.criticality}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:moderator" in data.modules) {
|
||||
const moderator = data.modules["nuclearcraft:overhaul_sfr:moderator"];
|
||||
yield `Flux factor: ${moderator.flux}`;
|
||||
yield `Efficiency: ${moderator.efficiency}`;
|
||||
yield {
|
||||
type: "compound",
|
||||
items: [
|
||||
"Moderator ",
|
||||
{
|
||||
type: "bold",
|
||||
text: solverMetadata?.active ? "active" : "inactive",
|
||||
},
|
||||
" for heat sinks",
|
||||
],
|
||||
};
|
||||
if (solverMetadata?.flux) {
|
||||
for (const [axis, flux] of Object.entries(solverMetadata.flux)) {
|
||||
yield `Flux on ${axis}: ${flux}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:reflector" in data.modules) {
|
||||
const reflector = data.modules["nuclearcraft:overhaul_sfr:reflector"];
|
||||
yield `Efficiency: ${reflector.efficiency}`;
|
||||
yield `Reflectivity: ${reflector.reflectivity}`;
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:heat_sink" in data.modules) {
|
||||
const heatSink = data.modules["nuclearcraft:overhaul_sfr:heat_sink"];
|
||||
if (heatSink.rules && !solverMetadata.active) {
|
||||
for (const rule of heatSink.rules) {
|
||||
yield "Rule not met: " + parseRuleAsString(rule, { configurationHint: metadata.configuration });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("nuclearcraft:overhaul_sfr:irradiator" in data.modules) {
|
||||
if (solverMetadata?.flux) {
|
||||
yield `Flux: ${solverMetadata.flux}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ function initializeRecipePicker({
|
|||
const filter = Filter.fromInput(filterElem);
|
||||
const recipeList = new DomList(parent.querySelector(":scope > .select"));
|
||||
recipeList.clear();
|
||||
console.log(recipes);
|
||||
for (let i = 0; i < recipes.length; i++) {
|
||||
const recipe = recipes[i];
|
||||
const recipeItem = recipeList.makeItem();
|
||||
|
|
@ -130,6 +131,9 @@ function initializeRecipePicker({
|
|||
}
|
||||
|
||||
function rescanDesignRecipes() {
|
||||
console.log("rescan recipes");
|
||||
console.log(configuration);
|
||||
|
||||
const multiblockType = getPlannerMultiblockType();
|
||||
|
||||
const configs = [
|
||||
|
|
@ -194,6 +198,8 @@ function rescanSelectionRecipes() {
|
|||
const tileMetadata = getAtlasMetadata(selectedCells.length > 0 ? selectedCells[0].dataset.tile : pickerTile);
|
||||
const tiles = findFullEntryFromAtlasMetadata(tileMetadata, { all: true });
|
||||
|
||||
console.log(tiles);
|
||||
|
||||
if (!tiles[0] || !tiles[0].modules || !tiles[0].modules["ncpf:block_recipes"]) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -201,6 +207,7 @@ function rescanSelectionRecipes() {
|
|||
const cellRecipes = selectedCells.map(v => getMetadata(v)?.block_recipe);
|
||||
const recipeSet = cellRecipes.some(v => v);
|
||||
const recipeAllSame = cellRecipes.every(v => v === cellRecipes[0] || checkEquivalence(v, cellRecipes[0]));
|
||||
console.log(">", cellRecipes, recipeSet, recipeAllSame);
|
||||
|
||||
const recipes = tiles.flatMap(t => t.modules["ncpf:block_recipes"].recipes);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,7 @@
|
|||
import { awaitEvent, emitEvent, listenTo } from "./events.js";
|
||||
import {
|
||||
getPlannerCellDom,
|
||||
getPlannerCellsDom,
|
||||
getPlannerDom,
|
||||
getPlannerMultiblockSize,
|
||||
getPlannerMultiblockType
|
||||
} from "./planner.js";
|
||||
import { checkEquivalence, findFullEntry, findFullEntryFromAtlasMetadata } from "./ncpf-utils.js";
|
||||
import { clearCellMetadata, deleteMetadata, getMetadata, setCellMetadata, setDomMetadata } from "./metadata.js";
|
||||
import { registerLoadCallback } from "./main.js";
|
||||
import { getAtlasMetadata } from "./atlas.js";
|
||||
import { initialize3dArray } from "./js-utils.js";
|
||||
|
||||
const SFR_MODERATOR_MAX_LEN = 3;
|
||||
const SFR_MODERATOR_REFLECTOR_MAX_LEN = 2;
|
||||
|
||||
registerLoadCallback(() => {
|
||||
listenTo("fileLoad:end", runSolver);
|
||||
listenTo("planner:cell:change", runSolver);
|
||||
});
|
||||
import { emitEvent } from "./events.js";
|
||||
import { getPlannerCellDom, getPlannerDom } from "./planner.js";
|
||||
import { findFullEntry } from "./ncpf-utils.js";
|
||||
import { setCellMetadata, setDomMetadata } from "./metadata.js";
|
||||
|
||||
export function resetSolver(design = undefined, designConfiguration) {
|
||||
const planner = getPlannerDom();
|
||||
|
|
@ -39,12 +22,10 @@ export function resetSolver(design = undefined, designConfiguration) {
|
|||
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]];
|
||||
const cellDom = getPlannerCellDom(x, y, z);
|
||||
deleteMetadata(cellDom);
|
||||
if (!block || !block.modules || !block.modules["ncpf:block_recipes"]) continue;
|
||||
const blockRecipeIndex = designBlockRecipes.shift();
|
||||
const blockRecipe = block.modules["ncpf:block_recipes"].recipes[blockRecipeIndex];
|
||||
setCellMetadata(cellDom, "block_recipe", blockRecipe);
|
||||
setCellMetadata(getPlannerCellDom(x, y, z), "block_recipe", blockRecipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -53,303 +34,3 @@ export function resetSolver(design = undefined, designConfiguration) {
|
|||
|
||||
emitEvent("solver:reset:done");
|
||||
}
|
||||
|
||||
const sixAxes = {
|
||||
"-X": { x: -1, y: 0, z: 0 },
|
||||
"-Y": { x: 0, y: -1, z: 0 },
|
||||
"-Z": { x: 0, y: 0, z: -1 },
|
||||
"+X": { x: 1, y: 0, z: 0 },
|
||||
"+Y": { x: 0, y: 1, z: 0 },
|
||||
"+Z": { x: 0, y: 0, z: 1 },
|
||||
};
|
||||
function *travelUntil(grid, { x, y, z }, {x: dirX = 0, y: dirY = 0, z: dirZ = 0}, shouldStop = (pos) => false) {
|
||||
x = Number(x);
|
||||
y = Number(y);
|
||||
z = Number(z);
|
||||
while (!shouldStop({x, y, z})
|
||||
&& x > 0 && y > 0 && z > 0
|
||||
&& x < grid.length - 1 && y < grid[0].length - 1 && z < grid[0][0].length - 1) {
|
||||
x += dirX;
|
||||
y += dirY;
|
||||
z += dirZ;
|
||||
yield grid[x][y][z];
|
||||
}
|
||||
}
|
||||
function neighbor(grid, { x, y, z }, {x: dirX = 0, y: dirY = 0, z: dirZ = 0}) {
|
||||
x = Number(x);
|
||||
y = Number(y);
|
||||
z = Number(z);
|
||||
if (x > 0 && y > 0 && z > 0
|
||||
&& x < grid.length - 1 && y < grid[0].length - 1 && z < grid[0][0].length - 1) {
|
||||
x += dirX;
|
||||
y += dirY;
|
||||
z += dirZ;
|
||||
return grid[x][y][z];
|
||||
}
|
||||
}
|
||||
|
||||
async function debugBlockSolver(data) {
|
||||
const planner = getPlannerDom();
|
||||
|
||||
if (planner.dataset.debugSolver) {
|
||||
emitEvent("solver:pause", data);
|
||||
await awaitEvent("solver:continue");
|
||||
}
|
||||
}
|
||||
|
||||
export async function runSolver() {
|
||||
const startTime = performance.now()
|
||||
emitEvent("solver:begin");
|
||||
|
||||
const multiblockType = getPlannerMultiblockType();
|
||||
|
||||
const plannerBlocks = getPlannerCellsDom()
|
||||
.map(b => ({ dom: b, ...b.dataset }))
|
||||
.filter(b => b.tile !== "-1")
|
||||
.map(b => (b.metadata ? { ...b, metadata: getMetadata(b.metadata) } : b));
|
||||
const tileMap = Object.fromEntries([...new Set(plannerBlocks.map(b => b.tile))]
|
||||
.map(idx => [idx, getAtlasMetadata(idx)])
|
||||
.map(([idx, md]) => [idx, findFullEntry("blocks", md, { configurationHint: multiblockType })]));
|
||||
plannerBlocks.forEach(v => v.tile = tileMap[v.tile]);
|
||||
plannerBlocks.forEach(v => clearCellMetadata(v.dom, "active"));
|
||||
|
||||
const plannerBlocksGrid = initialize3dArray(...getPlannerMultiblockSize());
|
||||
plannerBlocks.forEach(b => {
|
||||
plannerBlocksGrid[b.x][b.y][b.z] = b;
|
||||
});
|
||||
|
||||
if (multiblockType === "nuclearcraft:overhaul_sfr") {
|
||||
const fuelCells = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:fuel_cell"]);
|
||||
// const neutronSources = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:neutron_source"]);
|
||||
// const reflectors = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:reflector"]);
|
||||
// const shields = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:neutron_shield"]);
|
||||
// const moderators = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:moderator"]);
|
||||
const heatSinks = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:heat_sink"]);
|
||||
// const irradiators = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:irradiator"]);
|
||||
// const conductors = plannerBlocks.filter(b => b.tile.modules && b.tile.modules["nuclearcraft:overhaul_sfr:conductor"]);
|
||||
|
||||
fuelCells.forEach(cell => {
|
||||
const recipeList = cell.tile.modules["ncpf:block_recipes"].recipes;
|
||||
cell.recipe = recipeList.find(r => checkEquivalence(r, cell.metadata?.block_recipe));
|
||||
// TODO: handle blank recipe
|
||||
if (!cell.recipe) return; // FIXME
|
||||
cell.axes = Object.values(sixAxes).map(dir => [...travelUntil(
|
||||
plannerBlocksGrid,
|
||||
cell,
|
||||
dir,
|
||||
({x, y, z}) => {
|
||||
const block = plannerBlocksGrid[x][y][z];
|
||||
if (block === cell) {
|
||||
return false;
|
||||
}
|
||||
if (!block) {
|
||||
return false;
|
||||
}
|
||||
if (block.tile.modules) {
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:fuel_cell"]) return true;
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:reflector"]) return true;
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:irradiator"]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
)]);
|
||||
if (cell.recipe.modules["nuclearcraft:overhaul_sfr:fuel_stats"].self_priming) {
|
||||
cell.primer = cell;
|
||||
cell.active = true;
|
||||
} else if (cell.axes.some(a => (a[a.length - 1]?.tile?.modules ?? {})["nuclearcraft:overhaul_sfr:neutron_source"])) {
|
||||
const primerAxis = cell.axes.find(a => (a[a.length - 1]?.tile?.modules ?? {})["nuclearcraft:overhaul_sfr:neutron_source"]);
|
||||
cell.primer = primerAxis[primerAxis.length - 1];
|
||||
cell.active = true;
|
||||
}
|
||||
setCellMetadata(cell.dom, "primer", cell.primer);
|
||||
});
|
||||
console.log(fuelCells)
|
||||
|
||||
await debugBlockSolver("primed");
|
||||
|
||||
const seenModerators = new Set();
|
||||
const activeCells = fuelCells.filter(c => c.active);
|
||||
let activeCellIndex = 0;
|
||||
while (activeCellIndex < activeCells.length) {
|
||||
const cell = activeCells[activeCellIndex];
|
||||
if (!cell.axes) return; // ignore bad cells
|
||||
Object.keys(sixAxes).map((directionName, i) => {
|
||||
let valid = false;
|
||||
let moderatorPath = [];
|
||||
let length = 0;
|
||||
let reflectMultiplier = 1;
|
||||
let reflect = false;
|
||||
let fluxDestination;
|
||||
for (const block of cell.axes[i]) {
|
||||
if (!block) break;
|
||||
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:moderator"]) {
|
||||
moderatorPath.push(block);
|
||||
seenModerators.add(block);
|
||||
length += 1;
|
||||
continue;
|
||||
}
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:neutron_shield"]) {
|
||||
length += 1;
|
||||
continue;
|
||||
}
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:fuel_cell"] || block.tile.modules["nuclearcraft:overhaul_sfr:irradiator"]) {
|
||||
valid = length <= SFR_MODERATOR_MAX_LEN;
|
||||
fluxDestination = block;
|
||||
}
|
||||
if (block.tile.modules["nuclearcraft:overhaul_sfr:reflector"]) {
|
||||
valid = length <= SFR_MODERATOR_REFLECTOR_MAX_LEN;
|
||||
reflect = true;
|
||||
reflectMultiplier = block.tile.modules["nuclearcraft:overhaul_sfr:reflector"].reflectivity;
|
||||
console.log(reflectMultiplier)
|
||||
fluxDestination = cell;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (moderatorPath.length < 1) {
|
||||
valid = false;
|
||||
}
|
||||
if (!valid) return;
|
||||
|
||||
moderatorPath[0].active = true;
|
||||
let totalFlux = 0;
|
||||
for (const mod of moderatorPath) {
|
||||
totalFlux += mod.tile.modules["nuclearcraft:overhaul_sfr:moderator"].flux;
|
||||
if (!mod.flux) {
|
||||
mod.flux = {};
|
||||
}
|
||||
mod.flux[directionName] = totalFlux;
|
||||
}
|
||||
if (reflect) {
|
||||
totalFlux *= reflectMultiplier;
|
||||
const backAxis = directionName.replace(/^[+-]/, s => s === "+" ? "-" : "+");
|
||||
for (const mod of moderatorPath.toReversed()) {
|
||||
totalFlux += mod.tile.modules["nuclearcraft:overhaul_sfr:moderator"].flux * reflectMultiplier;
|
||||
mod.flux[backAxis] = totalFlux;
|
||||
}
|
||||
}
|
||||
fluxDestination.flux = (fluxDestination.flux ?? 0) + totalFlux;
|
||||
|
||||
if (fluxDestination.tile.modules["nuclearcraft:overhaul_sfr:fuel_cell"] && !fluxDestination.active) {
|
||||
if (!fluxDestination.recipe) return; // FIXME
|
||||
const fuelStats = fluxDestination.recipe.modules["nuclearcraft:overhaul_sfr:fuel_stats"];
|
||||
if (fuelStats.criticality <= fluxDestination.flux) {
|
||||
fluxDestination.active = true;
|
||||
activeCells.push(fluxDestination);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
activeCellIndex++;
|
||||
}
|
||||
seenModerators.forEach(moderator => {
|
||||
setCellMetadata(moderator.dom, "flux", moderator.flux);
|
||||
if (moderator.active) {
|
||||
setCellMetadata(moderator.dom, "active", moderator.active);
|
||||
}
|
||||
});
|
||||
fuelCells.forEach(cell => {
|
||||
if (cell.flux) {
|
||||
setCellMetadata(cell.dom, "flux", cell.flux);
|
||||
}
|
||||
setCellMetadata(cell.dom, "active", cell.active ?? false);
|
||||
});
|
||||
|
||||
await debugBlockSolver("moderators");
|
||||
|
||||
heatSinks.forEach(hs => {
|
||||
hs.neighbors = {};
|
||||
Object.entries(sixAxes).forEach(([name, dir]) => {
|
||||
hs.neighbors[name] = neighbor(plannerBlocksGrid, hs, dir);
|
||||
});
|
||||
hs.rules = hs.tile.modules["nuclearcraft:overhaul_sfr:heat_sink"].rules;
|
||||
});
|
||||
let heatSinkProcessed = false;
|
||||
const unprocessedHeatSinks = new Set(heatSinks);
|
||||
do {
|
||||
heatSinkProcessed = false;
|
||||
unprocessedHeatSinks.forEach(hs => {
|
||||
if (hs.active) {
|
||||
console.log("active hs in queue", hs);
|
||||
return;
|
||||
}
|
||||
const activeNeighbors = Object.entries(hs.neighbors).filter(([_, n]) => {
|
||||
if (!n) return false;
|
||||
if (n.active) return true;
|
||||
if (n.tile.modules) {
|
||||
return n.tile.modules["nuclearcraft:overhaul_sfr:reflector"]
|
||||
|| n.tile.modules["nuclearcraft:overhaul_sfr:irradiator"]
|
||||
|| n.tile.modules["nuclearcraft:overhaul_sfr:casing"]
|
||||
|| n.tile.modules["nuclearcraft:overhaul_sfr:neutron_shield"];
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (activeNeighbors.length === 0) return;
|
||||
|
||||
let valid = false;
|
||||
for (const rule of hs.rules) {
|
||||
if (checkHeatSinkRule(hs, rule, activeNeighbors)) {
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
heatSinkProcessed = true;
|
||||
unprocessedHeatSinks.delete(hs);
|
||||
hs.active = true;
|
||||
setCellMetadata(hs.dom, "active", true);
|
||||
}
|
||||
});
|
||||
} while (heatSinkProcessed);
|
||||
unprocessedHeatSinks.forEach(hs => {
|
||||
setCellMetadata(hs.dom, "active", false);
|
||||
});
|
||||
console.log(unprocessedHeatSinks);
|
||||
|
||||
await debugBlockSolver("heatsinks");
|
||||
}
|
||||
|
||||
const endTime = performance.now()
|
||||
console.log(`Solver took ${endTime - startTime}ms`);
|
||||
}
|
||||
|
||||
function checkHeatSinkRule(hs, rule, activeNeighbors) {
|
||||
switch (rule.type) {
|
||||
case "and":
|
||||
return rule.rules.every(r => checkHeatSinkRule(hs, r, activeNeighbors));
|
||||
|
||||
case "or":
|
||||
return rule.rules.some(r => checkHeatSinkRule(hs, r, activeNeighbors));
|
||||
|
||||
case "between": {
|
||||
const blocks = activeNeighbors
|
||||
.map(([,b]) => b.tile)
|
||||
.filter(b => {
|
||||
if (rule.block.type === "module") {
|
||||
return b.modules && rule.block.name in b.modules;
|
||||
}
|
||||
return checkEquivalence(rule.block, b);
|
||||
});
|
||||
return rule.min <= blocks.length && blocks.length <= rule.max;
|
||||
}
|
||||
case "axial": {
|
||||
const axialPairs = activeNeighbors
|
||||
.filter(([,b]) => {
|
||||
if (rule.block.type === "module") {
|
||||
return b.tile.modules && rule.block.name in b.tile.modules;
|
||||
}
|
||||
return checkEquivalence(rule.block, b.tile);
|
||||
})
|
||||
.reduce((acc, [dir, block]) => {
|
||||
acc[dir[1]] = acc[dir[1]] ?? [];
|
||||
acc[dir[1]].push(block);
|
||||
return acc;
|
||||
}, {});
|
||||
const count = Object.values(axialPairs).filter(p => p.length === 2).length;
|
||||
return rule.min <= count && count <= rule.max;
|
||||
}
|
||||
default:
|
||||
console.warn("unknown rule: %o", rule);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,68 +136,43 @@ function createTooltipDom(data) {
|
|||
div.classList.add("tooltip");
|
||||
for (const row of data) {
|
||||
const rowElem = document.createElement("div");
|
||||
rowElem.appendChild(createTooltipNode(row));
|
||||
|
||||
if (typeof row === "string") {
|
||||
rowElem.innerText = row;
|
||||
} else {
|
||||
if (!row.type) {
|
||||
throw row;
|
||||
}
|
||||
// TODO: support richer tooltips
|
||||
switch (row.type) {
|
||||
case "italics":
|
||||
rowElem.innerText = row.text;
|
||||
rowElem.classList.add("italics");
|
||||
break;
|
||||
|
||||
case "item":
|
||||
if (row.prefix) {
|
||||
rowElem.appendChild(document.createTextNode(row.prefix));
|
||||
}
|
||||
rowElem.appendChild(makeAtlasImage(row.atlasIndex));
|
||||
rowElem.appendChild(document.createTextNode(row.name));
|
||||
rowElem.classList.add("tooltip--item");
|
||||
break;
|
||||
|
||||
case "meta":
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn("unknown tooltip type", row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
div.appendChild(rowElem);
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
function createTooltipNode(tooltip) {
|
||||
if (typeof tooltip === "string") {
|
||||
return document.createTextNode(tooltip);
|
||||
}
|
||||
|
||||
if (!tooltip.type) {
|
||||
throw tooltip;
|
||||
}
|
||||
|
||||
switch (tooltip.type) {
|
||||
case "plain":
|
||||
return createTooltipNode(tooltip.text);
|
||||
|
||||
case "italics": {
|
||||
const elem = document.createElement("span");
|
||||
elem.classList.add("italics");
|
||||
elem.appendChild(createTooltipNode(tooltip.text));
|
||||
return elem;
|
||||
}
|
||||
|
||||
case "bold": {
|
||||
const elem = document.createElement("span");
|
||||
elem.classList.add("bold");
|
||||
elem.appendChild(createTooltipNode(tooltip.text));
|
||||
return elem;
|
||||
}
|
||||
|
||||
case "item": {
|
||||
const elem = document.createElement("div");
|
||||
if (tooltip.prefix) {
|
||||
elem.appendChild(createTooltipNode(tooltip.prefix));
|
||||
}
|
||||
elem.classList.add("tooltip--item");
|
||||
elem.appendChild(makeAtlasImage(tooltip.atlasIndex));
|
||||
elem.appendChild(createTooltipNode(tooltip.name));
|
||||
break;
|
||||
}
|
||||
|
||||
case "compound": {
|
||||
const fragment = document.createDocumentFragment();
|
||||
for (const item of tooltip.items) {
|
||||
fragment.appendChild(createTooltipNode(item));
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
case "meta":
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn("unknown tooltip type", tooltip);
|
||||
break;
|
||||
}
|
||||
return document.createDocumentFragment();
|
||||
}
|
||||
|
||||
function createAutoTooltipDom(element) {
|
||||
if (element.dataset.x && element.dataset.tile) {
|
||||
return createTooltipDom([...getCellTooltip(element)]);
|
||||
|
|
|
|||
11
style.css
11
style.css
|
|
@ -268,17 +268,6 @@ input:not([type="checkbox"]):not([type="radio"]):not([type="file"]) {
|
|||
inset: 0;
|
||||
opacity: var(--overlay-opacity, 0.8);
|
||||
}
|
||||
.planner--cell > .planner--overlay[data-overlay="block_recipe"] {
|
||||
transform: scale(var(--recipe-scale-factor, 0.8));
|
||||
}
|
||||
#planner .planner--cell > .planner--overlay[data-overlay="active"][data-active="true"] {
|
||||
outline-offset: calc(var(--scale-factor) * -1px);
|
||||
outline: calc(var(--scale-factor) * 1px) solid var(--cell-active-outline, #0f08);
|
||||
}
|
||||
#planner .planner--cell > .planner--overlay[data-overlay="active"][data-active="false"] {
|
||||
outline-offset: calc(var(--scale-factor) * -1px);
|
||||
outline: calc(var(--scale-factor) * 1px) solid var(--cell-inactive-outline, #f008);
|
||||
}
|
||||
|
||||
.planner--resize {
|
||||
--resize-width: var(--width);
|
||||
|
|
|
|||
Loading…
Reference in New Issue