Basic testing for attribute calculations

This commit is contained in:
Stefan Zermatten
2021-09-17 15:11:29 +02:00
parent a660ccc458
commit 1270e320ce
12 changed files with 120 additions and 23 deletions

View File

@@ -1,10 +1,12 @@
import _variable from './computeByType/computeVariable.js';
import action from './computeByType/computeAction.js';
import attribute from './computeByType/computeAttribute.js';
import slot from './computeByType/computeSlot.js';
export default Object.freeze({
_variable,
action,
attack: action,
attribute,
slot,
});

View File

@@ -1,5 +1,3 @@
import computeResources from './computeAction/computeResources.js';
export default function computeAction(graph, node, scope){
const prop = node.data;
if (prop.uses){
@@ -20,3 +18,15 @@ export default function computeAction(graph, node, scope){
}
});
}
function computeResources(graph, node, scope){
const resources = node.data?.resources;
if (!resources) return;
resources.attributesConsumed.forEach(attConsumed => {
if (!attConsumed.variableName) return;
const att = scope[attConsumed.variableName];
attConsumed.available = att.value;
attConsumed.statId = att._id;
attConsumed.statName = att.name;
});
}

View File

@@ -1,11 +0,0 @@
export default function computeResources(graph, node, scope){
const resources = node.data?.resources;
if (!resources) return;
resources.attributesConsumed.forEach(attConsumed => {
if (!attConsumed.variableName) return;
const att = scope[attConsumed.variableName];
attConsumed.available = att.value;
attConsumed.statId = att._id;
attConsumed.statName = att.name;
});
}

View File

@@ -0,0 +1,9 @@
// If we compute this attribute without a variable name, it just
// 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){
const prop = node.data;
prop.total = prop.baseValue?.value || 0;
prop.value = prop.total - (prop.damage || 0);
}

View File

@@ -1,7 +1,3 @@
/**
*
*/
export default function aggregateDamageMultipliers({node, linkedNode, link}){
if (link.data !== 'damageMultiplier') return;
const multiplierValue = linkedNode.data.value;

View File

@@ -18,7 +18,8 @@ export default function aggregateDefinition({node, linkedNode, link}){
}
// Aggregate the base value due to the defining properties
const propBaseValue = linkedNode.data.baseValue?.value;
const propBaseValue = prop.baseValue?.value;
if (propBaseValue === undefined) return;
if (node.data.baseValue === undefined || propBaseValue > node.data.baseValue){
node.data.baseValue = propBaseValue;

View File

@@ -1,7 +1,8 @@
import getAggregatorResult from './getAggregatorResult.js';
export default function computeVariableAsAttribute(node, prop, scope){
let result = getAggregatorResult(node);
let result = getAggregatorResult(node, prop) || 0;
prop.total = result;
prop.value = prop.total - (prop.damage || 0);

View File

@@ -3,7 +3,9 @@ import stripFloatingPointOddities from '/imports/api/creature/computation/newEng
export default function getAggregatorResult(node){
// Work out the base value as the greater of the deining stat value or
// the damage multiplier value
// This baseValue comes from aggregating definitions
let statBase = node.data.baseValue;
const damageMultiplyValue = node.data.damageMultiplyValue;
if (statBase === undefined || damageMultiplyValue > statBase){
statBase = damageMultiplyValue;

View File

@@ -0,0 +1,77 @@
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('emptyId').value, 0);
assert.equal(prop('noVariableNameId').value, 8);
assert.equal(prop('strengthId').value, 12);
assert.equal(prop('strengthId').modifier, 1);
assert.equal(prop('referencesDexId').value, 4);
assert.equal(prop('hitDiceId').constitutionMod, 5);
}
var testProperties = [
clean({
_id: 'emptyId',
type: 'attribute',
attributeType: 'ability',
}),
clean({
_id: 'noVariableNameId',
type: 'attribute',
attributeType: 'ability',
baseValue: {
calculation: '8'
},
}),
clean({
_id: 'strengthId',
variableName: 'strength',
type: 'attribute',
attributeType: 'ability',
baseValue: {
calculation: '12'
},
}),
clean({
_id: 'dexterityId',
variableName: 'dexterity',
type: 'attribute',
attributeType: 'ability',
baseValue: {
calculation: '15'
},
}),
clean({
_id: 'constitutionId',
variableName: 'constitution',
type: 'attribute',
attributeType: 'ability',
baseValue: {
calculation: '21'
},
}),
clean({
_id: 'referencesDexId',
variableName: 'refDex',
type: 'attribute',
baseValue: {
calculation: 'dexterity.modifier + 2'
},
}),
clean({
_id: 'hitDiceId',
variableName: 'hd',
type: 'attribute',
attributeType: 'hitDice',
hitDiceSize: 'd8',
baseValue: {
calculation: '4'
},
}),
];

View File

@@ -0,0 +1,10 @@
import computeAction from './computeAction.testFn.js';
import computeAttribute from './computeAttribute.testFn.js';
export default [{
text: 'Computes actions',
fn: computeAction,
},{
text: 'Computes attributes',
fn: computeAttribute,
},]

View File

@@ -2,7 +2,7 @@ import computeCreatureComputation from './computeCreatureComputation.js';
import { buildComputationFromProps } from './buildCreatureComputation.js';
import { assert } from 'chai';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import computeAction from './computeComputation/tests/computeAction.testFn.js';
import computeTests from './computeComputation/tests/index.js';
describe('Compute compuation', function(){
it('Computes something at all', function(){
@@ -10,7 +10,7 @@ describe('Compute compuation', function(){
computeCreatureComputation(computation);
assert.exists(computation);
});
it('Computes actions', computeAction);
computeTests.forEach(test => it(test.text, test.fn));
});
var testProperties = [

View File

@@ -9,15 +9,15 @@ import createPropertySchema from '/imports/api/properties/subSchemas/createPrope
let AttributeSchema = createPropertySchema({
name: {
type: String,
defaultValue: 'New Attribute',
optional: true,
max: STORAGE_LIMITS.name,
},
// The technical, lowercase, single-word name used in formulae
variableName: {
type: String,
optional: true,
regEx: VARIABLE_NAME_REGEX,
min: 2,
defaultValue: 'newAttribute',
max: STORAGE_LIMITS.variableName,
},
// How it is displayed and computed is determined by type