diff --git a/app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js b/app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js index 814449c3..7ff3f578 100644 --- a/app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js +++ b/app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js @@ -277,7 +277,6 @@ function linkPointBuy(dependencyGraph, prop) { linkVariableName(dependencyGraph, pointBuyRow); dependencyGraph.addLink(pointBuyRow._id, prop._id, 'pointBuyRow'); }); - if (prop.inactive) return; } function linkProficiencies(dependencyGraph, prop, computation) { diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computePointBuy.js b/app/imports/api/engine/computation/computeComputation/computeByType/computePointBuy.js index 65e16aa3..f39bfaa6 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computePointBuy.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computePointBuy.js @@ -7,10 +7,6 @@ export default function computePointBuy(computation, node) { const max = has(prop, 'max.value') ? prop.max.value : null; prop.spent = 0; prop.values?.forEach(row => { - // Clean up added properties - // delete row.tableId; - // delete row.tableName; - // delete row.type; row.spent = 0; if (row.value === undefined) return; diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js index 5ef7d0be..92c52756 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js @@ -6,6 +6,7 @@ import computeVariableAsClass from './computeVariable/computeVariableAsClass.js' import computeVariableAsToggle from './computeVariable/computeVariableAsToggle.js'; import computeImplicitVariable from './computeVariable/computeImplicitVariable.js'; import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js'; +import { computedInlineCalculationField } from '/imports/api/properties/subSchemas/inlineCalculationField'; export default function computeVariable(computation, node) { const scope = computation.scope; @@ -31,6 +32,11 @@ function aggregateLinks(computation, node) { if (!linkedNode.data) linkedNode.data = {}; // Ignore inactive props if (linkedNode.data.inactive) return; + // Ignore point buy rows if their base table is inactive + if ( + linkedNode.data.tableId + && computation.propsById[linkedNode.data.tableId]?.inactive + ) return; // Apply all the aggregations let arg = { node, linkedNode, link, computation }; aggregate.classLevel(arg); diff --git a/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js index 8650a9e2..357e7c51 100644 --- a/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js @@ -1,59 +1,52 @@ import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; -import clean from '../../utility/cleanProp.testFn.js'; +import { propsFromForest } from '/imports/api/properties/tests/propTestBuilder.testFn.js'; -export default function(){ +export default function () { const computation = buildComputationFromProps(testProperties); computeCreatureComputation(computation); const prop = id => computation.propsById[id]; assert.equal(prop('strengthId').value, 26); } -var testProperties = [ - clean({ - _id: 'strengthId', +var testProperties = propsFromForest([ + { variableName: 'strength', type: 'attribute', attributeType: 'ability', baseValue: { calculation: '8' }, - }), - clean({ - _id: 'strength2Id', + }, { + // This strength is later in order, so it will override the other + _id: 'strengthId', variableName: 'strength', type: 'attribute', attributeType: 'ability', baseValue: { calculation: '10' }, - }), - clean({ - _id: 'strengthBaseId', + }, { type: 'effect', operation: 'base', amount: { calculation: '10 + 2' }, stats: ['strength'], - }), - clean({ - _id: 'strengthAddId', + }, { type: 'effect', operation: 'add', amount: { calculation: '1' }, stats: ['strength'], - }), - clean({ - _id: 'strengthMulId', + }, { type: 'effect', operation: 'mul', amount: { calculation: '2' }, stats: ['strength'], - }), -]; + }, +]); diff --git a/app/imports/api/engine/computation/computeComputation/tests/computePointBuys.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computePointBuys.testFn.js new file mode 100644 index 00000000..f70efa87 --- /dev/null +++ b/app/imports/api/engine/computation/computeComputation/tests/computePointBuys.testFn.js @@ -0,0 +1,38 @@ +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; +import { assert } from 'chai'; +import computeCreatureComputation from '../../computeCreatureComputation.js'; +import { propsFromForest } from '/imports/api/properties/tests/propTestBuilder.testFn.js'; + +export default function () { + const computation = buildComputationFromProps(testProperties); + computeCreatureComputation(computation); + const prop = id => computation.propsById[id]; + assert.equal(prop('strengthId').value, 11, 'Point buys should apply a base value when active'); +} + +var testProperties = propsFromForest([ + { + _id: 'strengthId', + variableName: 'strength', + type: 'attribute', + attributeType: 'ability', + baseValue: { + calculation: '8' + }, + }, { + // calculated inactive toggle with point buy under it + // It should not impact the ability score + type: 'toggle', + condition: { calculation: 'false' }, + children: [ + { + _id: 'inactivePointBuy', + type: 'pointBuy', + values: [{ variableName: 'strength', value: 13 }], + } + ] + }, { + type: 'pointBuy', + values: [{ variableName: 'strength', value: 11 }], + } +]); diff --git a/app/imports/api/engine/computation/computeComputation/tests/index.js b/app/imports/api/engine/computation/computeComputation/tests/index.js index b97bb486..87ae6f07 100644 --- a/app/imports/api/engine/computation/computeComputation/tests/index.js +++ b/app/imports/api/engine/computation/computeComputation/tests/index.js @@ -7,6 +7,7 @@ import computeInventory from './computeInventory.testFn.js'; import computeDamageMultipliers from './computeDamageMultipliers.testFn.js'; import computeEffects from './computeEffects.testFn.js'; import computeSkills from './computeSkills.testFn.js'; +import computePointBuys from './computePointBuys.testFn.js'; import computeProficiencies from './computeProficiencies.testFn.js'; export default [{ @@ -36,6 +37,9 @@ export default [{ }, { text: 'Computes skills', fn: computeSkills, +}, { + text: 'Computes point buys', + fn: computePointBuys, }, { text: 'Computes proficiencies', fn: computeProficiencies, diff --git a/app/imports/api/properties/tests/propTestBuilder.testFn.js b/app/imports/api/properties/tests/propTestBuilder.testFn.js new file mode 100644 index 00000000..3052394b --- /dev/null +++ b/app/imports/api/properties/tests/propTestBuilder.testFn.js @@ -0,0 +1,40 @@ +/** + * Take a forest of props, which can have sub-props nested in children: [], and return a list of + * clean props with correct tree and ancestry data + * @param props + * @returns + */ +export function propsFromForest( + props, + ancestry = [{ id: 'creatureId', collection: 'creatures' }], +) { + const result = []; + props.forEach(prop => { + const children = prop.children; + // Check the property has a type + if (!prop.type) { + console.log(prop); + throw 'Type is required on every property, not found on above doc'; + } + // Create the clean doc + const doc = { ...prop }; + if (!doc._id) { + doc._id = Random.id(); + } + delete doc.children; + doc.order = result.length; + doc.parent = { ...ancestry[ancestry.length - 1] }; + doc.ancestors = [...ancestry]; + + // Add the doc to the result and ancestry + result.push(doc); + if (children) { + ancestry.push({ id: doc._id, collection: 'creatureProperties' }); + // Add the children to the result + result.push(...propsFromForest(children, ancestry)); + // Remove the doc from the ancestry after its children are done + ancestry.pop(); + } + }); + return result; +}