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 LogContentSchema from '/imports/api/creature/log/LogContentSchema';
import { getPropertyChildren, getSingleProperty, getVariables } from '/imports/api/engine/loadCreatures'; import { getPropertyChildren, getSingleProperty, getVariables } from '/imports/api/engine/loadCreatures';
import recalculateInlineCalculations from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateInlineCalculations'; 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 rollDice from '/imports/parser/rollDice';
import { toString } from '/imports/parser/resolve';
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
@@ -828,6 +829,12 @@ const applyPropertyByType = {
return result; 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> { async note(prop, task: Task, action: Action): Promise<PartialTaskResult> {
const result = createResult(); const result = createResult();
@@ -858,6 +865,60 @@ const applyPropertyByType = {
return result; 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 = { type DamageProp = {

View File

@@ -78,6 +78,10 @@ describe('Interrupt action system', function () {
'Applying increment adjustments should return the correct updates' '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?) { function createAction(prop, targetIds?) {
@@ -123,7 +127,8 @@ function allLogContent(action: Action) {
return contents; return contents;
} }
let note1Id, ifTruthyBranchId, ifFalsyBranchId, indexBranchId, choiceBranchId, adjustedStatId, adjustmentIncrementId, adjustmentSetId; let note1Id, ifTruthyBranchId, ifFalsyBranchId, indexBranchId, choiceBranchId, adjustedStatId,
adjustmentIncrementId, adjustmentSetId, rollId;
const propForest = [ const propForest = [
// Apply a simple note // Apply a simple note
@@ -201,6 +206,16 @@ const propForest = [
{ type: 'note', summary: { text: 'adjustment increment applied' } }, { 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() { function insertActionTestProps() {

View File

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