Added Rolls to action system rewrite
This commit is contained in:
@@ -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 = {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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 };
|
||||||
}
|
}
|
||||||
|
|||||||
1
app/packages/redis-oplog
Submodule
1
app/packages/redis-oplog
Submodule
Submodule app/packages/redis-oplog added at 83e302c154
Reference in New Issue
Block a user