Added Rolls to action system rewrite

This commit is contained in:
Thaum Rystra
2023-11-21 11:35:07 +02:00
parent fa9f64dd51
commit 936ca862db
4 changed files with 93 additions and 17 deletions

View File

@@ -3,8 +3,9 @@ import { forEach, get, isEmpty, pick } from 'lodash';
import LogContentSchema from '/imports/api/creature/log/LogContentSchema';
import { getPropertyChildren, getSingleProperty, getVariables } from '/imports/api/engine/loadCreatures';
import recalculateInlineCalculations from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateInlineCalculations';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
import recalculateCalculation, { rollAndReduceCalculation } from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
import rollDice from '/imports/parser/rollDice';
import { toString } from '/imports/parser/resolve';
/* eslint-disable @typescript-eslint/no-explicit-any */
@@ -828,6 +829,12 @@ const applyPropertyByType = {
return result;
},
async folder(prop, task: Task, action: Action): Promise<PartialTaskResult> {
const result = createResult();
doNext(action, await childAndTriggerTasks(action, prop, task.targetIds));
return result;
},
async note(prop, task: Task, action: Action): Promise<PartialTaskResult> {
const result = createResult();
@@ -858,6 +865,60 @@ const applyPropertyByType = {
return result;
},
async roll(prop, task: Task, action: Action): Promise<PartialTaskResult> {
const result = createResult();
// If there isn't a calculation, just apply the children instead
if (!prop.roll?.calculation) {
doNext(action, await childAndTriggerTasks(action, prop, task.targetIds));
return result;
}
const logValue: string[] = [];
// roll the dice only and store that string
const {
rolled, reduced, errors
} = rollAndReduceCalculation(prop.roll, action);
if (rolled.parseType !== 'constant') {
logValue.push(toString(rolled));
}
errors?.forEach(error => {
result.appendLog({ name: 'Error', value: error.message }, task.targetIds);
});
// Store the result
if (reduced.parseType === 'constant') {
prop.roll.value = reduced.value;
} else if (reduced.parseType === 'error') {
prop.roll.value = null;
} else {
prop.roll.value = toString(reduced);
}
// If we didn't end up with a constant or a number of finite value, give up
if (reduced?.parseType !== 'constant' || (reduced.valueType === 'number' && !isFinite(reduced.value))) {
doNext(action, await childAndTriggerTasks(action, prop, task.targetIds));
return result;
}
const value = reduced.value;
result.scope[prop.variableName] = { value };
logValue.push(`**${value}**`);
result.appendLog({
name: prop.name,
value: logValue.join('\n'),
inline: true,
silenced: prop.silent,
}, task.targetIds);
// Apply children
doNext(action, await childAndTriggerTasks(action, prop, task.targetIds));
return result;
},
}
type DamageProp = {

View File

@@ -78,6 +78,10 @@ describe('Interrupt action system', function () {
'Applying increment adjustments should return the correct updates'
);
});
it('Applies rolls', async function () {
const action = await runActionById(rollId);
console.log(allLogContent(action));
});
});
function createAction(prop, targetIds?) {
@@ -123,7 +127,8 @@ function allLogContent(action: Action) {
return contents;
}
let note1Id, ifTruthyBranchId, ifFalsyBranchId, indexBranchId, choiceBranchId, adjustedStatId, adjustmentIncrementId, adjustmentSetId;
let note1Id, ifTruthyBranchId, ifFalsyBranchId, indexBranchId, choiceBranchId, adjustedStatId,
adjustmentIncrementId, adjustmentSetId, rollId;
const propForest = [
// Apply a simple note
@@ -201,6 +206,16 @@ const propForest = [
{ type: 'note', summary: { text: 'adjustment increment applied' } },
],
},
// Apply rolls
{
_id: rollId = Random.id(),
type: 'roll',
roll: { calculation: '1 + 3 + 1d20 + 5' },
variableName: 'rollVar',
children: [
{ type: 'note', summary: { text: 'rollVar: {rollVar}' } }
]
}
];
function insertActionTestProps() {

View File

@@ -1,5 +1,5 @@
import logErrors from './logErrors.js';
import { toPrimitiveOrString } from '/imports/parser/resolve.js';
import { Context, toPrimitiveOrString } from '/imports/parser/resolve.js';
import {
aggregateCalculationEffects,
aggregateCalculationProficiencies,
@@ -9,12 +9,15 @@ import { getSingleProperty } from '/imports/api/engine/loadCreatures';
import resolve from '/imports/parser/resolve.js';
import { getEffectiveActionScope } from '/imports/api/engine/actions/Actions';
// TODO move this whole file to Actions.ts
// Redo the work of imports/api/engine/computation/computeComputation/computeByType/computeCalculation.js
// But in the action scope
export default function recalculateCalculation(calcObj, action, parseLevel = 'reduce', context) {
export default function recalculateCalculation(calcObj, action, parseLevel = 'reduce', context, scope) {
if (!calcObj?.parseNode) return;
calcObj._parseLevel = parseLevel;
const scope = getEffectiveActionScope(action);
if (!scope) {
scope = getEffectiveActionScope(action);
}
// Re-resolve the parse node
resolveCalculationNode(calcObj, calcObj.parseNode, scope, context);
// store the unaffected value
@@ -36,26 +39,22 @@ export default function recalculateCalculation(calcObj, action, parseLevel = 're
// Store the primitive value
calcObj.value = toPrimitiveOrString(calcObj.valueNode);
logErrors(calcObj.errors, action);
// TODO log errors
}
export function rollAndReduceCalculation(calcObj, actionContext, context) {
export function rollAndReduceCalculation(calcObj, action) {
const context = new Context();
const scope = getEffectiveActionScope(action);
// Compile
recalculateCalculation(calcObj, actionContext, 'compile', context);
recalculateCalculation(calcObj, action, 'compile', context, scope);
const compiled = calcObj.valueNode;
const compileErrors = context.errors;
// Roll
context.errors = [];
const { result: rolled } = resolve('roll', calcObj.valueNode, actionContext.scope, context);
const rollErrors = context.errors;
const { result: rolled } = resolve('roll', calcObj.valueNode, scope, context);
// Reduce
context.errors = [];
const { result: reduced } = resolve('reduce', rolled, actionContext.scope, context);
const reduceErrors = context.errors;
const { result: reduced } = resolve('reduce', rolled, scope, context);
// Return
return { compiled, compileErrors, rolled, rollErrors, reduced, reduceErrors };
return { compiled, rolled, reduced, errors: context.errors };
}