Tested and fixed effect computations
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
export default function computeAction(graph, node, scope){
|
||||
export default function computeAction(computation, node){
|
||||
const prop = node.data;
|
||||
if (prop.uses){
|
||||
prop.usesLeft = prop.uses.value - (prop.usesUsed || 0);
|
||||
}
|
||||
computeResources(graph, node, scope);
|
||||
computeResources(computation, node);
|
||||
if (!prop.resources) return;
|
||||
prop.resources.itemsConsumed.forEach(itemConsumed => {
|
||||
if (!itemConsumed.itemId) return;
|
||||
@@ -19,12 +19,12 @@ export default function computeAction(graph, node, scope){
|
||||
});
|
||||
}
|
||||
|
||||
function computeResources(graph, node, scope){
|
||||
function computeResources(computation, node){
|
||||
const resources = node.data?.resources;
|
||||
if (!resources) return;
|
||||
resources.attributesConsumed.forEach(attConsumed => {
|
||||
if (!attConsumed.variableName) return;
|
||||
const att = scope[attConsumed.variableName];
|
||||
const att = computation.scope[attConsumed.variableName];
|
||||
attConsumed.available = att.value;
|
||||
attConsumed.statId = att._id;
|
||||
attConsumed.statName = att.name;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// uses its base value and damage since no effects can target it
|
||||
// If this attribute does have a variable name, it is recomputed later
|
||||
// by computeVariableAsAttribute
|
||||
export default function computeAttribute(graph, node){
|
||||
export default function computeAttribute(computation, node){
|
||||
const prop = node.data;
|
||||
prop.total = prop.baseValue?.value || 0;
|
||||
prop.value = prop.total - (prop.damage || 0);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import aggregate from './computeVariable/aggregate/index.js';
|
||||
|
||||
export default function computeContainer(graph, node){
|
||||
export default function computeContainer(computation, node){
|
||||
if (!node.data) node.data = {};
|
||||
aggregateLinks(graph, node);
|
||||
aggregateLinks(computation, node);
|
||||
}
|
||||
|
||||
function aggregateLinks(graph, node){
|
||||
graph.forEachLinkedNode(
|
||||
function aggregateLinks(computation, node){
|
||||
computation.dependencyGraph.forEachLinkedNode(
|
||||
node.id,
|
||||
(linkedNode, link) => {
|
||||
if (!linkedNode.data) linkedNode.data = {};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function computSlot(graph, node){
|
||||
export default function computSlot(computation, node){
|
||||
const prop = node.data;
|
||||
if (prop.quantityExpected){
|
||||
prop.spaceLeft = prop.quantityExpected - prop.totalFilled;
|
||||
|
||||
@@ -5,21 +5,22 @@ import computeVariableAsConstant from './computeVariable/computeVariableAsConsta
|
||||
import computeVariableAsClass from './computeVariable/computeVariableAsClass.js';
|
||||
import computeImplicitVariable from './computeVariable/computeImplicitVariable.js';
|
||||
|
||||
export default function computeVariable(graph, node, scope){
|
||||
export default function computeVariable(computation, node){
|
||||
const scope = computation.scope;
|
||||
if (!node.data) node.data = {};
|
||||
aggregateLinks(graph, node);
|
||||
combineAggregations(node, scope);
|
||||
aggregateLinks(computation, node);
|
||||
combineAggregations(computation, node);
|
||||
if (node.data.definingProp){
|
||||
// Add the defining variable to the scope
|
||||
scope[node.id] = node.data.definingProp
|
||||
} else {
|
||||
// Otherwise add an implicit variable to the scope
|
||||
scope[node.id] = computeImplicitVariable(node, scope);
|
||||
scope[node.id] = computeImplicitVariable(node);
|
||||
}
|
||||
}
|
||||
|
||||
function aggregateLinks(graph, node){
|
||||
graph.forEachLinkedNode(
|
||||
function aggregateLinks(computation, node){
|
||||
computation.dependencyGraph.forEachLinkedNode(
|
||||
node.id,
|
||||
(linkedNode, link) => {
|
||||
if (!linkedNode.data) linkedNode.data = {};
|
||||
@@ -38,24 +39,24 @@ function aggregateLinks(graph, node){
|
||||
);
|
||||
}
|
||||
|
||||
function combineAggregations(node, scope){
|
||||
function combineAggregations(computation, node){
|
||||
combineMultiplierAggregator(node);
|
||||
node.data.overridenProps?.forEach(prop => {
|
||||
computeVariableProp(node, prop, scope);
|
||||
computeVariableProp(computation, node, prop);
|
||||
});
|
||||
computeVariableProp(node, node.data.definingProp, scope);
|
||||
computeVariableProp(computation, node, node.data.definingProp);
|
||||
}
|
||||
|
||||
function computeVariableProp(node, prop, scope){
|
||||
function computeVariableProp(computation, node, prop){
|
||||
if (!prop) return;
|
||||
if (prop.type === 'attribute'){
|
||||
computeVariableAsAttribute(node, prop, scope)
|
||||
computeVariableAsAttribute(computation, node, prop)
|
||||
} else if (prop.type === 'skill'){
|
||||
computeVariableAsSkill(node, prop, scope)
|
||||
computeVariableAsSkill(computation, node, prop)
|
||||
} else if (prop.type === 'constant'){
|
||||
computeVariableAsConstant(node, prop, scope)
|
||||
computeVariableAsConstant(computation, node, prop)
|
||||
} else if (prop.type === 'class'){
|
||||
computeVariableAsClass(node, prop, scope)
|
||||
computeVariableAsClass(computation, node, prop)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import getAggregatorResult from './getAggregatorResult.js';
|
||||
|
||||
export default function computeVariableAsAttribute(node, prop, scope){
|
||||
export default function computeVariableAsAttribute(computation, node, prop){
|
||||
let result = getAggregatorResult(node, prop) || 0;
|
||||
|
||||
prop.total = result;
|
||||
@@ -16,7 +16,7 @@ export default function computeVariableAsAttribute(node, prop, scope){
|
||||
|
||||
// Hit dice denormalise constitution modifier
|
||||
if (prop.attributeType === 'hitDice') {
|
||||
prop.constitutionMod = scope['constitution']?.modifier || 0;
|
||||
prop.constitutionMod = computation.scope['constitution']?.modifier || 0;
|
||||
}
|
||||
|
||||
// Stats that have no effects or base value can be hidden
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function computeVariableAsAttribute(node, prop){
|
||||
export default function computeVariableAsAttribute(computation, node, prop){
|
||||
let classLevelAgg = node.data.classLevelAggregator;
|
||||
if (!classLevelAgg) return;
|
||||
prop.level = classLevelAgg.level;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { parse } from '/imports/parser/parser.js';
|
||||
|
||||
export default function computeVariableAsConstant(node, prop){
|
||||
export default function computeVariableAsConstant(computation, node, prop){
|
||||
let string = prop.calculation;
|
||||
if (!string) return;
|
||||
let parseNode;
|
||||
|
||||
@@ -2,11 +2,11 @@ import { CompilationContext } from '/imports/parser/parser.js';
|
||||
import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js';
|
||||
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
||||
|
||||
export default function computeCalculations(node, scope){
|
||||
export default function computeCalculations(computation, node){
|
||||
if (!node.data) return;
|
||||
// evaluate all the calculations
|
||||
node.data._computationDetails?.calculations?.forEach(calcObj => {
|
||||
evaluateCalculation(calcObj, scope)
|
||||
evaluateCalculation(calcObj, computation.scope)
|
||||
});
|
||||
node.data._computationDetails?.inlineCalculations?.forEach(inlineCalcObj => {
|
||||
embedInlineCalculations(inlineCalcObj);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default function evaluateToggles(node){
|
||||
export default function evaluateToggles(computation, node){
|
||||
let prop = node.data;
|
||||
if (!prop) return;
|
||||
let toggles = prop._computationDetails?.toggleAncestors;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js';
|
||||
import { assert } from 'chai';
|
||||
import computeCreatureComputation from '../../computeCreatureComputation.js';
|
||||
import clean from '../../utility/cleanProp.testFn.js';
|
||||
|
||||
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',
|
||||
variableName: 'strength',
|
||||
type: 'attribute',
|
||||
attributeType: 'ability',
|
||||
baseValue: {
|
||||
calculation: '8'
|
||||
},
|
||||
}),
|
||||
clean({
|
||||
_id: 'strength2Id',
|
||||
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'],
|
||||
}),
|
||||
];
|
||||
@@ -4,6 +4,7 @@ import computeClasses from './computeClasses.testFn.js';
|
||||
import computeConstants from './computeConstants.testFn.js';
|
||||
import computeInventory from './computeInventory.testFn.js';
|
||||
import computeDamageMultipliers from './computeDamageMultipliers.testFn.js';
|
||||
import computeEffects from './computeEffects.testFn.js';
|
||||
|
||||
export default [{
|
||||
text: 'Computes actions',
|
||||
@@ -23,4 +24,7 @@ export default [{
|
||||
},{
|
||||
text: 'Computes damage multipliers',
|
||||
fn: computeDamageMultipliers,
|
||||
},{
|
||||
text: 'Computes effects',
|
||||
fn: computeEffects,
|
||||
}];
|
||||
|
||||
@@ -5,7 +5,6 @@ import computeByType from '/imports/api/creature/computation/newEngine/computeCo
|
||||
export default function computeCreatureComputation(computation){
|
||||
const stack = [];
|
||||
// Computation scope of {variableName: prop}
|
||||
const scope = computation.scope;
|
||||
const graph = computation.dependencyGraph;
|
||||
// Add all nodes to the stack
|
||||
graph.forEachNode(node => {
|
||||
@@ -24,7 +23,7 @@ export default function computeCreatureComputation(computation){
|
||||
top._visited = true;
|
||||
stack.pop();
|
||||
// Compute the top object of the stack
|
||||
compute(graph, top, scope);
|
||||
compute(computation, top);
|
||||
} else {
|
||||
top._visitedChildren = true;
|
||||
// Push dependencies to graph to be computed first
|
||||
@@ -33,12 +32,12 @@ export default function computeCreatureComputation(computation){
|
||||
}
|
||||
}
|
||||
|
||||
function compute(graph, node, scope){
|
||||
function compute(computation, node){
|
||||
// Determine the prop's active status by its toggles
|
||||
computeToggles(node);
|
||||
computeCalculations(node, scope);
|
||||
computeToggles(computation, node);
|
||||
computeCalculations(computation, node);
|
||||
// Compute the property by type
|
||||
computeByType[node.data?.type || '_variable']?.(graph, node, scope);
|
||||
computeByType[node.data?.type || '_variable']?.(computation, node);
|
||||
}
|
||||
|
||||
function pushDependenciesToStack(nodeId, graph, stack){
|
||||
|
||||
@@ -27,7 +27,6 @@ let EffectSchema = createPropertySchema({
|
||||
'passiveAdd',
|
||||
'fail',
|
||||
'conditional',
|
||||
'rollBonus',
|
||||
],
|
||||
},
|
||||
amount: {
|
||||
|
||||
Reference in New Issue
Block a user