Settling on a data structure to balance compatibility

with not being wrong
This commit is contained in:
Thaum Rystra
2023-11-09 16:08:04 +02:00
parent 6ce7542c4b
commit 9e5b6b11e1
22 changed files with 312 additions and 338 deletions

View File

@@ -3,7 +3,7 @@ import applyChildren from '/imports/api/engine/actions/applyPropertyByType/share
import { insertCreatureLog } from '/imports/api/creature/log/CreatureLogs.js';
import resolve, { Context, toString } from '/imports/parser/resolve.js';
import logErrors from './shared/logErrors.js';
import applyEffectsToCalculationParseNode from '/imports/api/engine/actions/applyPropertyByType/shared/applyEffectsToCalculationParseNode.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation.js'
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
import {
getPropertiesOfType
@@ -37,8 +37,8 @@ export default function applyDamage(node, actionContext) {
const logName = prop.damageType === 'healing' ? 'Healing' : 'Damage';
// roll the dice only and store that string
applyEffectsToCalculationParseNode(prop.amount, actionContext);
const { result: rolled } = resolve('roll', prop.amount.parseNode, scope, context);
recalculateCalculation(prop.amount, actionContext, undefined, 'compile');
const { result: rolled } = resolve('roll', prop.amount.valueNode, scope, context);
if (rolled.parseType !== 'constant') {
logValue.push(toString(rolled));
}
@@ -88,8 +88,8 @@ export default function applyDamage(node, actionContext) {
let damageOnSave, saveNode, saveRoll;
if (prop.save) {
if (prop.save.damageFunction?.calculation) {
applyEffectsToCalculationParseNode(prop.save.damageFunction, actionContext);
let { result: saveDamageRolled } = resolve('roll', prop.save.damageFunction.parseNode, scope, context);
recalculateCalculation(prop.save.damageFunction, actionContext, undefined, 'compile');
let { result: saveDamageRolled } = resolve('roll', prop.save.damageFunction.valueNode, scope, context);
saveRoll = toString(saveDamageRolled);
let { result: saveDamageResult } = resolve('reduce', saveDamageRolled, scope, context);
// If we didn't end up with a constant of finite amount, give up

View File

@@ -1,6 +1,6 @@
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import logErrors from './shared/logErrors.js';
import applyEffectsToCalculationParseNode from '/imports/api/engine/actions/applyPropertyByType/shared/applyEffectsToCalculationParseNode.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation.js';
import resolve, { toString } from '/imports/parser/resolve.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
@@ -12,8 +12,8 @@ export default function applyRoll(node, actionContext) {
const logValue = [];
// roll the dice only and store that string
applyEffectsToCalculationParseNode(prop.roll, actionContext);
const { result: rolled, context } = resolve('roll', prop.roll.parseNode, actionContext.scope);
recalculateCalculation(prop.roll, actionContext, undefined, 'compile');
const { result: rolled, context } = resolve('roll', prop.roll.valueNode, actionContext.scope);
if (rolled.parseType !== 'constant') {
logValue.push(toString(rolled));
}

View File

@@ -1,46 +0,0 @@
import operator from '/imports/parser/parseTree/operator.js';
import { parse } from '/imports/parser/parser.js';
import logErrors from './logErrors.js';
export default function applyEffectsToCalculationParseNode(calcObj, actionContext) {
calcObj.effects?.forEach(effect => {
if (effect.operation !== 'add') return;
if (!effect.amount) return;
if (effect.amount.value === null) return;
let effectParseNode;
try {
effectParseNode = parse(effect.amount.value.toString());
calcObj.parseNode = operator.create({
left: calcObj.parseNode,
right: effectParseNode,
operator: '+',
fn: 'add'
});
} catch (e) {
logErrors([e], actionContext)
}
});
// Add the highest proficiency as well
let highestProficiency;
calcObj.proficiencies?.forEach(proficiency => {
if (
proficiency.value > highestProficiency
|| (highestProficiency === undefined && Number.isFinite(proficiency.value))
) {
highestProficiency = proficiency.value;
}
});
if (highestProficiency) {
try {
let profParseNode = parse(highestProficiency.toString());
calcObj.parseNode = operator.create({
left: calcObj.parseNode,
right: profParseNode,
operator: '+',
fn: 'add'
});
} catch (e) {
logErrors([e], actionContext)
}
}
}

View File

@@ -1,11 +1,38 @@
import evaluateCalculation from '/imports/api/engine/computation/utility/evaluateCalculation.js';
import applyEffectsToCalculationParseNode from '/imports/api/engine/actions/applyPropertyByType/shared/applyEffectsToCalculationParseNode.js';
import logErrors from './logErrors.js';
import { toPrimitiveOrString } from '/imports/parser/resolve.js';
import {
aggregateCalculationEffects,
aggregateCalculationProficiencies,
resolveCalculationNode,
} from '/imports/api/engine/computation/computeComputation/computeByType/computeCalculation.js';
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
export default function recalculateCalculation(calc, actionContext, context) {
if (!calc?.parseNode) return;
calc._parseLevel = 'reduce';
applyEffectsToCalculationParseNode(calc, actionContext);
evaluateCalculation(calc, actionContext.scope, context);
logErrors(calc.errors, actionContext);
// Redo the work of imports/api/engine/computation/computeComputation/computeByType/computeCalculation.js
// But in the action scope
export default function recalculateCalculation(calcObj, actionContext, context, parseLevel = 'reduce') {
if (!calcObj?.parseNode) return;
calcObj._parseLevel = parseLevel;
// Re-resolve the parse node
resolveCalculationNode(calcObj, calcObj.parseNode, actionContext.scope, context);
// store the unaffected value
if (calcObj.effectIds || calcObj.proficiencyIds) {
calcObj.unaffected = toPrimitiveOrString(calcObj.valueNode);
}
// Apply all the effects and proficiencies
aggregateCalculationEffects(
calcObj,
id => getSingleProperty(actionContext.creature._id, id)
);
aggregateCalculationProficiencies(
calcObj,
id => getSingleProperty(actionContext.creature._id, id),
actionContext.scope['proficiencyBonus']?.value || 0
);
// Resolve the modified valueNode
resolveCalculationNode(calcObj, calcObj.valueNode, actionContext.scope, context);
// Store the primitive value
calcObj.value = toPrimitiveOrString(calcObj.valueNode);
logErrors(calcObj.errors, actionContext);
}

View File

@@ -7,7 +7,7 @@ import rollDice from '/imports/parser/rollDice.js';
import numberToSignedString from '/imports/api/utility/numberToSignedString.js';
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import ActionContext from '/imports/api/engine/actions/ActionContext.js';
import evaluateCalculation from '/imports/api/engine/computation/utility/evaluateCalculation.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
const doCheck = new ValidatedMethod({
name: 'creatureProperties.doCheck',
@@ -76,7 +76,7 @@ function rollCheck(prop, actionContext) {
let rollModifierText = numberToSignedString(rollModifier, true);
const { effectBonus, effectString } = applyUnresolvedEffects(prop, scope)
const { effectBonus, effectString } = applyUnresolvedEffects(prop, actionContext)
rollModifierText += effectString;
rollModifier += effectBonus;
@@ -116,7 +116,8 @@ function rollCheck(prop, actionContext) {
});
}
export function applyUnresolvedEffects(prop, scope) {
// TODO replace this with recalculating and then rolling/reducing the value node
export function applyUnresolvedEffects(prop, actionContext) {
let effectBonus = 0;
let effectString = '';
if (!prop.effects) {
@@ -125,8 +126,7 @@ export function applyUnresolvedEffects(prop, scope) {
prop.effects.forEach(effect => {
if (!effect.amount?.parseNode) return;
if (effect.operation !== 'add') return;
effect.amount._parseLevel = 'reduce';
evaluateCalculation(effect.amount, scope);
recalculateCalculation(effect.amount, actionContext, context, 'reduce');
if (typeof effect.amount?.value !== 'number') return;
effectBonus += effect.amount.value;
effectString += ` ${effect.amount.value < 0 ? '-' : '+'} [${effect.amount.calculation}] ${Math.abs(effect.amount.value)}`