asdfg
This commit is contained in:
parent
f6d7412744
commit
091afc2b5c
77 changed files with 4405 additions and 8223 deletions
|
|
@ -185,13 +185,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
function setEffectivePower(node, directDriven, directOn, worldRef) {
|
||||
function setEffectivePower(node, directDriven, directOn, worldRef, provenance = {}) {
|
||||
const wasOn = Boolean(node?._achievementSignalWasOn);
|
||||
node._directSignalDriven = Boolean(directDriven);
|
||||
node._directSignalOn = Boolean(directDriven && directOn);
|
||||
node._achievementSignalWasOn = node._directSignalOn;
|
||||
if (!wasOn && node._directSignalOn) {
|
||||
global.TarinaiAchievements?.recordSignalActivation?.({ world: worldRef, target: node, type: node.type });
|
||||
const detectorSources = [...new Set((Array.isArray(provenance.detectorSources) ? provenance.detectorSources : []).filter(Boolean))];
|
||||
global.TarinaiAchievements?.recordSignalActivation?.({
|
||||
world: worldRef,
|
||||
target: node,
|
||||
type: node.type,
|
||||
source: detectorSources[0] || null,
|
||||
detectorSources,
|
||||
detectorDriven: detectorSources.length > 0,
|
||||
connected: Boolean(directDriven),
|
||||
});
|
||||
if (node.type === "robot_cleaner") global.TarinaiAchievements?.evaluateCleanFreak?.(worldRef, { robot: node, source: "signal-power" });
|
||||
}
|
||||
node._signalDriven = node._directSignalDriven;
|
||||
|
|
@ -323,7 +332,12 @@
|
|||
visited.add(node); nodes.push(node);
|
||||
for (const next of adjacency.get(node) || []) if (!visited.has(next)) stack.push(next);
|
||||
}
|
||||
const component = { nodes, active: false, hasSource: nodes.some(node => SIGNAL_SOURCE_TYPES.has(node.type) || (node.type === "circuit_terminal" && node.direction === "output")) };
|
||||
const component = {
|
||||
nodes,
|
||||
active: false,
|
||||
hasSource: nodes.some(node => SIGNAL_SOURCE_TYPES.has(node.type) || (node.type === "circuit_terminal" && node.direction === "output")),
|
||||
detectorSources: [],
|
||||
};
|
||||
components.push(component);
|
||||
nodes.forEach(node => componentOf.set(node, component));
|
||||
}
|
||||
|
|
@ -331,33 +345,55 @@
|
|||
// Board outputs can depend on other boards, so resolve the graph to a
|
||||
// fixed point. Unstable internal combinational cycles are forced OFF by the
|
||||
// board evaluator; external feedback is still bounded to avoid hanging the simulation.
|
||||
const detectorSourceSignature = sources => [...new Set((sources || []).map(source => String(source?.id || source?.familyKey || ""))).values()].sort().join("|");
|
||||
const refreshComponentState = component => {
|
||||
const directDetectors = component.nodes.filter(node => SIGNAL_SOURCE_TYPES.has(node.type) && node.signalActive);
|
||||
const outputDetectors = component.nodes.flatMap(node => (
|
||||
node.type === "circuit_terminal" && node.direction === "output" && node.signalActive
|
||||
? (Array.isArray(node._signalDetectorSources) ? node._signalDetectorSources : [])
|
||||
: []
|
||||
));
|
||||
const nextSources = [...new Set([...directDetectors, ...outputDetectors].filter(Boolean))];
|
||||
const active = component.hasSource && component.nodes.some(node => (
|
||||
(SIGNAL_SOURCE_TYPES.has(node.type) && node.signalActive)
|
||||
|| (node.type === "circuit_terminal" && node.direction === "output" && node.signalActive)
|
||||
));
|
||||
const changed = active !== component.active
|
||||
|| detectorSourceSignature(nextSources) !== detectorSourceSignature(component.detectorSources);
|
||||
component.active = active;
|
||||
component.detectorSources = active ? nextSources : [];
|
||||
return changed;
|
||||
};
|
||||
|
||||
const maxCircuitPasses = Math.min(256, Math.max(16, boards.length * 2 + 4));
|
||||
for (let pass = 0; pass < maxCircuitPasses; pass += 1) {
|
||||
let changed = false;
|
||||
for (const component of components) {
|
||||
const active = component.hasSource && component.nodes.some(node => (SIGNAL_SOURCE_TYPES.has(node.type) && node.signalActive) || (node.type === "circuit_terminal" && node.direction === "output" && node.signalActive));
|
||||
if (active !== component.active) { component.active = active; changed = true; }
|
||||
}
|
||||
for (const component of components) changed = refreshComponentState(component) || changed;
|
||||
for (const board of boards) {
|
||||
const inputs = Object.create(null);
|
||||
const inputProvenance = Object.create(null);
|
||||
for (const port of circuit?.ports?.(board) || []) {
|
||||
if (port.direction !== "input") continue;
|
||||
const terminal = circuit.terminal(board, port.portId);
|
||||
inputs[port.id] = Boolean(componentOf.get(terminal)?.active);
|
||||
const component = componentOf.get(terminal);
|
||||
inputs[port.id] = Boolean(component?.active);
|
||||
inputProvenance[port.id] = component?.detectorSources || [];
|
||||
}
|
||||
const before = JSON.stringify(board._circuitOutputState || {});
|
||||
circuit?.evaluate?.(board, inputs);
|
||||
if (before !== JSON.stringify(board._circuitOutputState || {})) changed = true;
|
||||
const beforeSources = JSON.stringify(Object.fromEntries(Object.entries(board._circuitOutputDetectorSources || {}).map(([id, sources]) => [id, detectorSourceSignature(sources)])));
|
||||
circuit?.evaluate?.(board, inputs, inputProvenance);
|
||||
const afterSources = JSON.stringify(Object.fromEntries(Object.entries(board._circuitOutputDetectorSources || {}).map(([id, sources]) => [id, detectorSourceSignature(sources)])));
|
||||
if (before !== JSON.stringify(board._circuitOutputState || {}) || beforeSources !== afterSources) changed = true;
|
||||
}
|
||||
if (!changed) break;
|
||||
}
|
||||
for (const component of components) {
|
||||
component.active = component.hasSource && component.nodes.some(node => (SIGNAL_SOURCE_TYPES.has(node.type) && node.signalActive) || (node.type === "circuit_terminal" && node.direction === "output" && node.signalActive));
|
||||
refreshComponentState(component);
|
||||
for (const node of component.nodes) {
|
||||
if (!DIRECT_SIGNAL_SINK_TYPES.has(node.type)) continue;
|
||||
node._wireSignalDriven = component.hasSource;
|
||||
node._wireSignalOn = component.hasSource && component.active;
|
||||
setEffectivePower(node, component.hasSource, component.active, worldRef);
|
||||
setEffectivePower(node, component.hasSource, component.active, worldRef, { detectorSources: component.detectorSources });
|
||||
}
|
||||
}
|
||||
for (const entry of wires) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue