diff --git a/app/imports/api/engine/actions/doCheck.js b/app/imports/api/engine/actions/doCheck.js index 42e98f61..7242e57e 100644 --- a/app/imports/api/engine/actions/doCheck.js +++ b/app/imports/api/engine/actions/doCheck.js @@ -7,6 +7,7 @@ import rollDice from '/imports/parser/rollDice.js'; import numberToSignedString from '/imports/ui/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'; const doCheck = new ValidatedMethod({ name: 'creatureProperties.doCheck', @@ -72,7 +73,11 @@ function rollCheck(prop, actionContext) { throw (`${prop.type} not supported for checks`); } - const rollModifierText = numberToSignedString(rollModifier, true); + let rollModifierText = numberToSignedString(rollModifier, true); + + const { effectBonus, effectString } = applyUnresolvedEffects(prop, scope) + rollModifierText += effectString; + rollModifier += effectBonus; let value, values, resultPrefix; if (scope['$checkAdvantage'] === 1){ @@ -106,3 +111,21 @@ function rollCheck(prop, actionContext) { value: `${resultPrefix} **${result}**`, }); } + +function applyUnresolvedEffects(prop, scope) { + let effectBonus = 0; + let effectString = ''; + if (!prop.effects) { + return { effectBonus, effectString}; + } + prop.effects.forEach(effect => { + if (!effect.amount?.parseNode) return; + if (effect.operation !== 'add') return; + effect.amount._parseLevel = 'reduce'; + evaluateCalculation(effect.amount, scope); + if (typeof effect.amount?.value !== 'number') return; + effectBonus += effect.amount.value; + effectString += ` ${effect.amount.value < 0 ? '-' : '+'} [${effect.amount.calculation}] ${Math.abs(effect.amount.value)}` + }); + return { effectBonus, effectString}; +} diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js index e4a58317..6cab306a 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js @@ -1,3 +1,5 @@ +import { pick } from "lodash"; + export default function aggregateEffect({node, linkedNode, link}){ if (link.data !== 'effect') return; // store the effect aggregator, its presence indicates that the variable is @@ -19,11 +21,22 @@ export default function aggregateEffect({node, linkedNode, link}){ // Store a summary of the effect itself node.data.effects = node.data.effects || []; + // Store either just + let effectAmount; + if (!linkedNode.data.amount) { + effectAmount = undefined; + } else if (typeof linkedNode.data.amount.value === 'string') { + effectAmount = pick(linkedNode.data.amount, [ + 'calculation', 'parseNode', 'parseError', 'value' + ]); + } else { + effectAmount = pick(linkedNode.data.amount, ['value']); + } node.data.effects.push({ _id: linkedNode.data._id, name: linkedNode.data.name, operation: linkedNode.data.operation, - amount: linkedNode.data.amount && {value: linkedNode.data.amount.value}, + amount: effectAmount, type: linkedNode.data.type, // ancestors: linkedNode.data.ancestors, }); @@ -33,7 +46,7 @@ export default function aggregateEffect({node, linkedNode, link}){ // Get the result of the effect const result = linkedNode.data.amount?.value; // Skip aggregating if the result is not resolved completely - if (typeof result === 'string') return; + if (typeof result === 'string' || result === undefined) return; // Aggregate the effect based on its operation switch(linkedNode.data.operation){ case 'base': diff --git a/app/imports/ui/properties/viewers/AttributeViewer.vue b/app/imports/ui/properties/viewers/AttributeViewer.vue index 6561dfd1..b36e5184 100644 --- a/app/imports/ui/properties/viewers/AttributeViewer.vue +++ b/app/imports/ui/properties/viewers/AttributeViewer.vue @@ -134,6 +134,7 @@ import IncrementButton from '/imports/ui/components/IncrementButton.vue'; import getProficiencyIcon from '/imports/ui/utility/getProficiencyIcon.js'; import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js'; + import sortEffects from '/imports/ui/utility/sortEffects.js'; export default { components: { @@ -177,6 +178,9 @@ proficiencyIcon(){ return getProficiencyIcon(this.model.proficiency); }, + effects() { + return sortEffects(this.model.effects); + }, }, methods: { numberToSignedString, @@ -202,11 +206,6 @@ }); }, }, - meteor: { - effects() { - return this.model.effects; - }, - }, } diff --git a/app/imports/ui/properties/viewers/SkillViewer.vue b/app/imports/ui/properties/viewers/SkillViewer.vue index 3b31157a..651fd9c5 100644 --- a/app/imports/ui/properties/viewers/SkillViewer.vue +++ b/app/imports/ui/properties/viewers/SkillViewer.vue @@ -126,6 +126,7 @@ import AttributeEffect from '/imports/ui/properties/components/attributes/Attrib import SkillProficiency from '/imports/ui/properties/components/skills/SkillProficiency.vue'; import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables.js'; import getProficiencyIcon from '/imports/ui/utility/getProficiencyIcon.js'; +import sortEffects from '/imports/ui/utility/sortEffects.js'; export default { components: { @@ -169,7 +170,10 @@ export default { }, passiveScore(){ return 10 + this.model.value + this.model.passiveBonus; - } + }, + effects() { + return sortEffects(this.model.effects); + }, }, methods: { numberToSignedString, @@ -186,9 +190,6 @@ export default { variables(){ return CreatureVariables.findOne({_creatureId: this.context.creatureId}) || {}; }, - effects() { - return this.model.effects; - }, baseProficiencies(){ if (this.context.creatureId){ let creatureId = this.context.creatureId;