diff --git a/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js b/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js index 13549e73..315d93f0 100644 --- a/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js +++ b/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js @@ -10,8 +10,10 @@ export default function computeToggleDependencies(node, dependencyGraph){ prop.enabled ) return; walkDown(node.children, child => { - child.node._computationDetails.toggleAncestors.push(prop); + // Only for children that aren't inactive + if (child.node.inactive) return; // The child nodes depend on the toggle condition compuation + child.node._computationDetails.toggleAncestors.push(prop); dependencyGraph.addLink(child.node._id, prop._id, 'toggle'); }); } diff --git a/app/imports/api/engine/computation/buildCreatureComputation.js b/app/imports/api/engine/computation/buildCreatureComputation.js index d99d9290..a5009d2c 100644 --- a/app/imports/api/engine/computation/buildCreatureComputation.js +++ b/app/imports/api/engine/computation/buildCreatureComputation.js @@ -89,6 +89,10 @@ export function buildComputationFromProps(properties, creature, variables){ // Walk the property trees computing things that need to be inherited walkDown(forest, node => { computeInactiveStatus(node); + }); + // Inactive status must be complete for the whole tree before toggle deps + // are calculated + walkDown(forest, node => { computeToggleDependencies(node, dependencyGraph); computeSlotQuantityFilled(node, dependencyGraph); }); diff --git a/app/imports/api/engine/computation/computeCreatureComputation.js b/app/imports/api/engine/computation/computeCreatureComputation.js index 88dde8c7..7cd4b41c 100644 --- a/app/imports/api/engine/computation/computeCreatureComputation.js +++ b/app/imports/api/engine/computation/computeCreatureComputation.js @@ -51,11 +51,22 @@ function compute(computation, node){ function pushDependenciesToStack(nodeId, graph, stack, computation){ graph.forEachLinkedNode(nodeId, linkedNode => { - if (linkedNode._visitedChildren && !linkedNode._visited){ - const pather = path.nba(graph, { - oriented: true - }); - const loop = pather.find(nodeId, nodeId); + if (linkedNode._visitedChildren && !linkedNode._visited) { + // This is a dependency loop, find a path from the node to itself + // and store that path as a dependency loop error + const pather = path.nba(graph, { oriented: true }); + let loop = []; + // Pather doesn't like going from a node to iteself, so find all the + // paths going from the next node back to the original node + // and return the shortest one + graph.forEachLinkedNode(nodeId, nextNode => { + const newLoop = pather.find(nextNode.id, nodeId); + if (!newLoop.length) return; + if (!loop.length || newLoop.length < loop.length - 1) { + loop = [linkedNode, ...newLoop]; + } + }, true); + if (loop.length) { computation.errors.push({ type: 'dependencyLoop',