diff --git a/app/imports/api/creature/computation/afterComputation/embedInlineCalculations.js b/app/imports/api/creature/computation/afterComputation/embedInlineCalculations.js deleted file mode 100644 index 10841dba..00000000 --- a/app/imports/api/creature/computation/afterComputation/embedInlineCalculations.js +++ /dev/null @@ -1,11 +0,0 @@ -import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js'; - -export default function embedInlineCalculations(string, calculations){ - if (!string) return ''; - if (!calculations) return string; - let index = 0; - return string.replace(INLINE_CALCULATION_REGEX, substring => { - let comp = calculations && calculations[index++]; - return (comp && 'result' in comp) ? comp.result : substring; - }); -} diff --git a/app/imports/api/creature/computation/afterComputation/evaluateString.js b/app/imports/api/creature/computation/afterComputation/evaluateString.js deleted file mode 100644 index f193d341..00000000 --- a/app/imports/api/creature/computation/afterComputation/evaluateString.js +++ /dev/null @@ -1,67 +0,0 @@ -import { parse, CompilationContext } from '/imports/parser/parser.js'; -import ConstantNode from '/imports/parser/parseTree/ConstantNode.js'; -import SymbolNode from '/imports/parser/parseTree/SymbolNode.js'; -import ErrorNode from '/imports/parser/parseTree/ErrorNode.js'; - -//TODO replace constants with their parsed node - -export default function evaluateString({string, scope, fn = 'compile', context}){ - if (!context){ - context = new CompilationContext({}); - } - if (!string){ - context.storeError('No string provided'); - return {result: {value: string}, context}; - } - - if (!scope) context.storeError('No scope provided'); - - // Parse the string using mathjs - let node; - try { - node = parse(string); - } catch (e) { - context.storeError(e); - return {result: {value: string}, context}; - } - node = replaceConstants({calc: node, context, scope}); - let result = node[fn](scope, context); - return {result, context}; -} - -// Replace constants in the calc with the right ParseNodes -function replaceConstants({calc, context, scope}){ - let constFailed = []; - calc = calc.replaceNodes(node => { - if (!(node instanceof SymbolNode)) return; - let constant = scope[node.name]; - // replace constants that aren't overridden by stats or disabled by a toggle - if (constant && constant.type === 'constant'){ - // Fail if the constant has errors - if (constant.errors && constant.errors.length){ - constFailed.push(node.name); - return; - } - let parsedConstantNode; - try { - parsedConstantNode = parse(constant.calculation); - } catch(e){ - constFailed.push(node.name); - return; - } - if (!parsedConstantNode) constFailed.push(node.name); - return parsedConstantNode; - } - }); - constFailed.forEach(name => { - context.storeError({ - type: 'error', - message: `${name} is a constant property with parsing errors` - }); - }); - let failed = !!constFailed.length; - if (failed){ - calc = new ErrorNode({error: 'Failed to replace constants'}); - } - return calc; -} diff --git a/app/imports/api/creature/computation/engine/ComputationMemo.js b/app/imports/api/creature/computation/engine/ComputationMemo.js deleted file mode 100644 index 75d270da..00000000 --- a/app/imports/api/creature/computation/engine/ComputationMemo.js +++ /dev/null @@ -1,289 +0,0 @@ -import { includes, cloneDeep } from 'lodash'; -import findAncestorByType from '/imports/api/creature/computation/engine/findAncestorByType.js'; - -// The computation memo is an in-memory data structure used only during the -// computation process -export default class ComputationMemo { - constructor(props, creature){ - this.statsByVariableName = {}; - this.constantsByVariableName = {}; - this.constantsById = {}; - this.extraStatsByVariableName = {}; - this.statsById = {}; - this.originalPropsById = {}; - this.propsById = {}; - this.skillsByAbility = {}; - this.unassignedEffects = []; - this.classLevelsById = {}; - this.classes = {}; - this.togglesById = {}; - this.toggleIds = new Set(); - // Equipped items that might be used as ammo - this.equipmentById = {}; - // Properties that have calculations, but don't impact other properties - this.endStepPropsById = {}; - // First note all the ids of all the toggles - props.forEach((prop) => { - if ( - prop.type === 'toggle' - ) { - this.toggleIds.add(prop._id); - } - }); - props.filter((prop) => { - if ( - prop.type === 'toggle' - ) { - this.addToggle(prop); - } else { - return true; - } - }).filter((prop) => { - if ( - prop.type === 'attribute' || - prop.type === 'skill' - ) { - // Add all the stats - this.addStat(prop); - } else if ( - prop.type === 'item' - ) { - this.addEquipment(prop); - } else { - return true; - } - }).forEach((prop) => { - // Now add everything else - if (prop.type === 'effect'){ - this.addEffect(prop); - } else if (prop.type === 'proficiency') { - this.addProficiency(prop); - } else if (prop.type === 'classLevel'){ - this.addClassLevel(prop); - } else if (prop.type === 'constant'){ - this.addConstant(prop); - } else { - this.addEndStepProp(prop); - } - }); - for (let name in creature.denormalizedStats){ - if (!this.statsByVariableName[name]){ - this.statsByVariableName[name] = { - variableName: name, - value: creature.denormalizedStats[name], - computationDetails: propDetailsByType.denormalizedStat(), - } - } - } - } - addConstant(prop){ - prop = this.registerProperty(prop); - this.constantsById[prop._id] = prop; - } - registerProperty(prop){ - this.originalPropsById[prop._id] = cloneDeep(prop); - this.propsById[prop._id] = prop; - prop.dependencies = []; - prop.computationDetails = propDetails(prop); - prop.ancestors.forEach(ancestor => { - if (this.toggleIds.has(ancestor.id)){ - prop.computationDetails.toggleAncestors.push(ancestor.id); - } - }); - return prop; - } - addToggle(prop){ - prop = this.registerProperty(prop); - this.togglesById[prop._id] = prop; - } - addClassLevel(prop){ - prop = this.registerProperty(prop); - this.classLevelsById[prop._id] = prop; - } - addStat(prop){ - let variableName = prop.variableName; - if (!variableName) return; - let existingStat = this.statsByVariableName[variableName]; - prop = this.registerProperty(prop); - if (existingStat){ - existingStat.computationDetails.idsOfSameName.push(prop._id); - } else { - this.statsById[prop._id] = prop; - this.statsByVariableName[variableName] = prop; - if ( - prop.type === 'skill' && - isSkillCheck(prop) && - prop.ability - ){ - this.addSkillToAbility(prop, prop.ability) - } - } - } - addSkillToAbility(prop, ability){ - if (!this.skillsByAbility[ability]){ - this.skillsByAbility[ability] = []; - } - this.skillsByAbility[ability].push(prop); - } - addEffect(prop){ - prop = this.registerProperty(prop); - let targets = this.getEffectTargets(prop); - targets.forEach(target => { - if (target.computationDetails && target.computationDetails.effects){ - target.computationDetails.effects.push(prop); - } - }); - if (!targets.size){ - this.unassignedEffects.push(prop); - } - } - getEffectTargets(prop){ - let targets = new Set(); - if (!prop.stats) return targets; - prop.stats.forEach((statName) => { - let target; - if (statName[0] === '#'){ - target = findAncestorByType({ - type: statName.slice(1), - prop, - memo: this - }); - } else { - target = this.statsByVariableName[statName]; - } - if (!target) return; - targets.add(target); - if (isSkillOperation(prop) && isAbility(target)){ - let extras = this.skillsByAbility[statName] || []; - extras.forEach(ex =>{ - // Only pass on ability effects to skills and checks - if (ex.skillType === 'skill' || ex.skillType === 'check'){ - targets.add(ex) - } - }); - } - }); - return targets; - } - addProficiency(prop){ - prop = this.registerProperty(prop); - let targets = this.getProficiencyTargets(prop); - targets.forEach(target => { - if(target.computationDetails.proficiencies){ - target.computationDetails.proficiencies.push(prop); - } - }); - } - getProficiencyTargets(prop){ - let targets = new Set(); - if (!prop.stats) return targets; - prop.stats.forEach(statName => { - let target = this.statsByVariableName[statName]; - if (!target) return; - targets.add(target); - if (isAbility(target)) { - let extras = this.skillsByAbility[statName] || []; - extras.forEach(ex =>{ - // Only pass on ability proficiencies to skills and checks - if (ex.skillType === 'skill' || ex.skillType === 'check'){ - targets.add(ex) - } - }); - } - }); - return targets; - } - addEquipment(prop){ - prop = this.registerProperty(prop); - this.equipmentById[prop._id] = prop; - } - addEndStepProp(prop){ - prop = this.registerProperty(prop); - this.endStepPropsById[prop._id] = prop; - } -} - -function isAbility(prop){ - return prop.type === 'attribute' && - prop.attributeType === 'ability' -} - -function isSkillCheck(prop){ - return includes(['skill', 'check', 'save', 'utility'], prop.skillType); -} - -const skillOperations = [ - 'advantage', - 'disadvantage', - 'passiveAdd', - 'fail', - 'conditional', - 'rollBonus', -]; - -function isSkillOperation(prop){ - return skillOperations.includes(prop.operation); -} - -function propDetails(prop){ - return propDetailsByType[prop.type] && propDetailsByType[prop.type]() || - propDetailsByType.default(); -} - -const propDetailsByType = { - default(){ - return { - toggleAncestors: [], - }; - }, - toggle(){ - return { - computed: false, - busyComputing: false, - toggleAncestors: [], - }; - }, - attribute(){ - return { - computed: false, - busyComputing: false, - effects: [], - proficiencies: [], - toggleAncestors: [], - idsOfSameName: [], - }; - }, - skill(){ - return { - computed: false, - busyComputing: false, - effects: [], - proficiencies: [], - toggleAncestors: [], - idsOfSameName: [], - }; - }, - effect(){ - return { - computed: false, - busyComputing: false, - toggleAncestors: [], - }; - }, - classLevel(){ - return { - computed: true, - toggleAncestors: [], - }; - }, - proficiency(){ - return { - toggleAncestors: [], - }; - }, - denormalizedStat(){ - return { - toggleAncestors: [], - }; - } -} diff --git a/app/imports/api/creature/computation/engine/EffectAggregator.js b/app/imports/api/creature/computation/engine/EffectAggregator.js deleted file mode 100644 index 83e30f32..00000000 --- a/app/imports/api/creature/computation/engine/EffectAggregator.js +++ /dev/null @@ -1,78 +0,0 @@ -export default class EffectAggregator{ - constructor(){ - this.base = undefined; - this.add = 0; - this.mul = 1; - this.min = Number.NEGATIVE_INFINITY; - this.max = Number.POSITIVE_INFINITY; - this.advantage = 0; - this.disadvantage = 0; - this.passiveAdd = undefined; - this.fail = 0; - this.set = undefined; - this.conditional = []; - this.rollBonus = []; - this.hasNoEffects = true; - } - addEffect(effect){ - let result = effect.result; - if (this.hasNoEffects) this.hasNoEffects = false; - switch(effect.operation){ - case 'base': - // Take the largest base value - if (Number.isFinite(result)){ - if(Number.isFinite(this.base)){ - this.base = Math.max(this.base, result); - } else { - this.base = result; - } - } - break; - case 'add': - // Add all adds together - this.add += result; - break; - case 'mul': - // Multiply the muls together - this.mul *= result; - break; - case 'min': - // Take the largest min value - this.min = result > this.min ? result : this.min; - break; - case 'max': - // Take the smallest max value - this.max = result < this.max ? result : this.max; - break; - case 'set': - // Take the highest set value - this.set = this.set === undefined || result > this.set ? result : this.set; - break; - case 'advantage': - // Sum number of advantages - this.advantage++; - break; - case 'disadvantage': - // Sum number of disadvantages - this.disadvantage++; - break; - case 'passiveAdd': - // Add all passive adds together - if (this.passiveAdd === undefined) this.passiveAdd = 0; - this.passiveAdd += result; - break; - case 'fail': - // Sum number of fails - this.fail++; - break; - case 'conditional': - // Store array of conditionals - this.conditional.push(result); - break; - case 'rollBonus': - // Store array of roll bonuses - this.rollBonus.push(result); - break; - } - } -} diff --git a/app/imports/api/creature/computation/engine/applyToggles.js b/app/imports/api/creature/computation/engine/applyToggles.js deleted file mode 100644 index 74839c35..00000000 --- a/app/imports/api/creature/computation/engine/applyToggles.js +++ /dev/null @@ -1,25 +0,0 @@ -import computeToggle from '/imports/api/creature/computation/engine/computeToggle.js'; -import { union } from 'lodash'; - -export default function applyToggles(prop, memo){ - // If it used to be inactive delete those fields - if (prop.inactive) prop.inactive = undefined; - if (prop.deactivatedByAncestor) prop.deactivatedByAncestor = undefined; - if (prop.deactivatedByToggle) prop.deactivatedByToggle = undefined; - // Iterate through the toggle ancestors from oldest to nearest - prop.computationDetails.toggleAncestors.forEach(toggleId => { - let toggle = memo.togglesById[toggleId]; - computeToggle(toggle, memo); - prop.dependencies = union( - prop.dependencies, - [toggle._id], - toggle.dependencies, - ); - // Deactivate if the toggle is false - if (!toggle.toggleResult){ - prop.inactive = true; - prop.deactivatedByAncestor = true; - prop.deactivatedByToggle = true; - } - }); -} diff --git a/app/imports/api/creature/computation/engine/combineStat.js b/app/imports/api/creature/computation/engine/combineStat.js deleted file mode 100644 index e69d9c27..00000000 --- a/app/imports/api/creature/computation/engine/combineStat.js +++ /dev/null @@ -1,197 +0,0 @@ -import computeStat from '/imports/api/creature/computation/engine/computeStat.js'; -import computeProficiency from '/imports/api/creature/computation/engine/computeProficiency.js'; -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import stripFloatingPointOddities from '/imports/api/creature/computation/newEngine/utility/stripFloatingPointOddities.js'; -import { union } from 'lodash'; - -export default function combineStat(stat, aggregator, memo){ - if (stat.type === 'attribute'){ - combineAttribute(stat, aggregator, memo); - } else if (stat.type === 'skill'){ - combineSkill(stat, aggregator, memo); - } else if (stat.type === 'damageMultiplier'){ - combineDamageMultiplier(stat, memo); - } -} - -function getAggregatorResult(stat, aggregator){ - let base; - if (!Number.isFinite(aggregator.base)){ - base = stat.baseValue || 0; - } else if (!Number.isFinite(stat.baseValue)){ - base = aggregator.base || 0; - } else { - base = Math.max(aggregator.base, stat.baseValue); - } - let result = (base + aggregator.add) * aggregator.mul; - if (result < aggregator.min) { - result = aggregator.min; - } - if (result > aggregator.max) { - result = aggregator.max; - } - if (aggregator.set !== undefined) { - result = aggregator.set; - } - if (!stat.decimal && Number.isFinite(result)){ - result = Math.floor(result); - } else if (Number.isFinite(result)){ - result = stripFloatingPointOddities(result); - } - return result; -} - -function combineAttribute(stat, aggregator, memo){ - stat.value = getAggregatorResult(stat, aggregator); - if (stat.attributeType === 'spellSlot'){ - let { - result, - context, - dependencies - } = evaluateCalculation({ - string: stat.spellSlotLevelCalculation, - memo, - prop: stat, - }); - stat.spellSlotLevelValue = result.value; - stat.spellSlotLevelErrors = context.errors; - stat.dependencies = union(stat.dependencies, dependencies); - } - stat.currentValue = stat.value - (stat.damage || 0); - // Ability scores get modifiers - if (stat.attributeType === 'ability') { - stat.modifier = Math.floor((stat.currentValue - 10) / 2); - } else { - stat.modifier = undefined; - } - // Hit dice get constitution modifiers - stat.constitutionMod = undefined; - if (stat.attributeType === 'hitDice') { - let conStat = memo.statsByVariableName['constitution']; - if (conStat && 'modifier' in conStat){ - stat.constitutionMod = conStat.modifier; - stat.dependencies = union( - stat.dependencies, - [conStat._id], - conStat.dependencies, - ); - } - } - // Stats that have no effects can be hidden based on a sheet setting - stat.hide = aggregator.hasNoEffects && - stat.baseValue === undefined || - undefined -} - -function combineSkill(stat, aggregator, memo){ - // Skills are based on some ability Modifier - let ability = stat.ability && memo.statsByVariableName[stat.ability] - if (stat.ability && ability){ - computeStat(ability, memo); - stat.abilityMod = ability.modifier; - stat.dependencies = union( - stat.dependencies, - [ability._id], - ability.dependencies, - ); - } else { - stat.abilityMod = 0; - } - // Combine all the child proficiencies - stat.proficiency = 0; - for (let i in stat.computationDetails.proficiencies){ - let prof = stat.computationDetails.proficiencies[i]; - computeProficiency(prof, memo); - if ( - !prof.deactivatedByToggle && - prof.value > stat.proficiency - ){ - stat.proficiency = prof.value; - stat.dependencies = union( - stat.dependencies, - [prof._id], - prof.dependencies, - ); - } - } - // Get the character's proficiency bonus to apply - let profBonusStat = memo.statsByVariableName['proficiencyBonus']; - let profBonus = profBonusStat && profBonusStat.value; - - if (profBonusStat){ - stat.dependencies = union( - stat.dependencies, - [profBonusStat._id], - profBonusStat.dependencies, - ); - } - - if (typeof profBonus !== 'number' && memo.statsByVariableName['level']){ - let levelProp = memo.statsByVariableName['level']; - let level = levelProp.value; - profBonus = Math.ceil(level / 4) + 1; - if (levelProp._id){ - stat.dependencies = union(stat.dependencies, [levelProp._id]); - } - if (levelProp.dependencies){ - stat.dependencies = union(stat.dependencies, levelProp.dependencies); - } - } - - // Multiply the proficiency bonus by the actual proficiency - if(stat.proficiency === 0.49){ - // Round down proficiency bonus in the special case - profBonus = Math.floor(profBonus * 0.5); - } else { - profBonus = Math.ceil(profBonus * stat.proficiency); - } - - // Combine everything to get the final result - let base = aggregator.base || 0; - let result = (base + stat.abilityMod + profBonus + aggregator.add) * aggregator.mul; - if (result < aggregator.min) result = aggregator.min; - if (result > aggregator.max) result = aggregator.max; - if (aggregator.set !== undefined) { - result = aggregator.set; - } - if (Number.isFinite(result)){ - result = Math.floor(result); - } - stat.value = result; - // Advantage/disadvantage - if (aggregator.advantage && !aggregator.disadvantage){ - stat.advantage = 1; - } else if (aggregator.disadvantage && !aggregator.advantage){ - stat.advantage = -1; - } else { - stat.advantage = 0; - } - // Passive bonus - stat.passiveBonus = aggregator.passiveAdd; - // conditional benefits - stat.conditionalBenefits = aggregator.conditional; - // Roll bonuses - stat.rollBonus = aggregator.rollBonus; - // Forced to fail - stat.fail = aggregator.fail; - // Rollbonus - stat.rollBonuses = aggregator.rollBonus; - // Hide - stat.hide = aggregator.hasNoEffects && - stat.baseValue === undefined && - stat.proficiency == 0 || - undefined; -} - -function combineDamageMultiplier(stat){ - if (stat.immunityCount) return 0; - let result; - if (stat.resistanceCount && !stat.vulnerabilityCount){ - result = 0.5; - } else if (!stat.resistanceCount && stat.vulnerabilityCount){ - result = 2; - } else { - result = 1; - } - stat.value = result; -} diff --git a/app/imports/api/creature/computation/engine/computeConstant.js b/app/imports/api/creature/computation/engine/computeConstant.js deleted file mode 100644 index 4d972c57..00000000 --- a/app/imports/api/creature/computation/engine/computeConstant.js +++ /dev/null @@ -1,12 +0,0 @@ -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; - -export default function computeConstant(constant, memo){ - // Apply any toggles - applyToggles(constant, memo); - if (constant.deactivatedByToggle) return; - if ( - !memo.constantsByVariableName[constant.variableName] - ){ - memo.constantsByVariableName[constant.variableName] = constant - } -} diff --git a/app/imports/api/creature/computation/engine/computeEffect.js b/app/imports/api/creature/computation/engine/computeEffect.js deleted file mode 100644 index 75d880b4..00000000 --- a/app/imports/api/creature/computation/engine/computeEffect.js +++ /dev/null @@ -1,55 +0,0 @@ -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; -import { union } from 'lodash'; - -export default function computeEffect(effect, memo){ - if (effect.computationDetails.computed) return; - if (effect.computationDetails.busyComputing){ - // Trying to compute this effect again while it is already computing. - // We must be in a dependency loop. - effect.computationDetails.computed = true; - effect.result = NaN; - effect.computationDetails.busyComputing = false; - effect.computationDetails.error = 'dependencyLoop'; - if (Meteor.isClient) console.warn('dependencyLoop', effect); - return; - } - // Before doing any work, mark this effect as busy - effect.computationDetails.busyComputing = true; - - // Apply any toggles - applyToggles(effect, memo); - - // Determine result of effect calculation - delete effect.errors; - if (!effect.calculation){ - if(effect.operation === 'add' || effect.operation === 'base'){ - effect.result = 0; - } else { - delete effect.result - } - } else if (Number.isFinite(+effect.calculation)){ - effect.result = +effect.calculation; - } else if(effect.operation === 'conditional' || effect.operation === 'rollBonus'){ - effect.result = effect.calculation; - } else if(_.contains(['advantage', 'disadvantage', 'fail'], effect.operation)){ - effect.result = 1; - } else { - let { - result, - context, - dependencies, - } = evaluateCalculation({ - string: effect.calculation, - prop: effect, - memo - }); - effect.result = result.value; - effect.dependencies = union(effect.dependencies, dependencies); - if (context.errors.length){ - effect.errors = context.errors; - } - } - effect.computationDetails.computed = true; - effect.computationDetails.busyComputing = false; -} diff --git a/app/imports/api/creature/computation/engine/computeEndStepProperty.js b/app/imports/api/creature/computation/engine/computeEndStepProperty.js deleted file mode 100644 index fad2afd4..00000000 --- a/app/imports/api/creature/computation/engine/computeEndStepProperty.js +++ /dev/null @@ -1,129 +0,0 @@ -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import ConstantNode from '/imports/parser/parseTree/ConstantNode.js'; -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; -import { union } from 'lodash'; - -export default function computeEndStepProperty(prop, memo){ - applyToggles(prop, memo); - - switch (prop.type){ - case 'action': - case 'spell': - computeAction(prop, memo); - break; - case 'adjustment': - case 'damage': - computePropertyField(prop, memo, 'amount', 'compile'); - break; - case 'attack': - computeAction(prop, memo); - computePropertyField(prop, memo, 'rollBonus'); - break; - case 'savingThrow': - computePropertyField(prop, memo, 'dc'); - break; - case 'spellList': - computePropertyField(prop, memo, 'maxPrepared'); - computePropertyField(prop, memo, 'attackRollBonus'); - computePropertyField(prop, memo, 'dc'); - break; - case 'propertySlot': - computePropertyField(prop, memo, 'quantityExpected'); - computePropertyField(prop, memo, 'slotCondition'); - break; - case 'roll': - computePropertyField(prop, memo, 'roll', 'compile'); - break; - } -} - -function computeAction(prop, memo){ - // Uses - let { - result, - context, - dependencies, - } = evaluateCalculation({ string: prop.uses, prop, memo}); - prop.usesResult = result.value; - prop.dependencies = union(prop.dependencies, dependencies); - if (context.errors.length){ - prop.usesErrors = context.errors; - } else { - delete prop.usesErrors; - } - prop.insufficientResources = undefined; - if (prop.usesUsed >= prop.usesResult){ - prop.insufficientResources = true; - } - if (!prop.resources) return; - // Attributes consumed - prop.resources.attributesConsumed.forEach((attConsumed, i) => { - if (attConsumed.variableName){ - let stat = memo.statsByVariableName[attConsumed.variableName]; - prop.resources.attributesConsumed[i].statId = stat && stat._id; - prop.resources.attributesConsumed[i].statName = stat && stat.name; - let available = stat && stat.currentValue || 0; - prop.resources.attributesConsumed[i].available = available; - if (available < attConsumed.quantity){ - prop.insufficientResources = true; - } - if (stat){ - prop.dependencies = union( - prop.dependencies, - [stat._id], - stat.dependencies - ); - } - } - }); - // Items consumed - prop.resources.itemsConsumed.forEach((itemConsumed, i) => { - let item = itemConsumed.itemId ? - memo.equipmentById[itemConsumed.itemId] : - undefined; - let available = item ? item.quantity : 0; - prop.resources.itemsConsumed[i].available = available; - if (!item || available < itemConsumed.quantity){ - prop.insufficientResources = true; - } - if (item){ - prop.resources.itemsConsumed[i].itemId = item._id; - let name = item.name; - if (item.quantity !== 1 && item.plural){ - name = item.plural; - } - if (name) prop.resources.itemsConsumed[i].itemName = name; - if (item.icon) prop.resources.itemsConsumed[i].itemIcon = item.icon; - if (item.color) prop.resources.itemsConsumed[i].itemColor = item.color; - prop.dependencies = union( - prop.dependencies, - [item._id], - item.dependencies - ); - } else { - delete prop.resources.itemsConsumed[i].itemId; - delete prop.resources.itemsConsumed[i].itemName; - delete prop.resources.itemsConsumed[i].itemIcon; - delete prop.resources.itemsConsumed[i].itemColor; - } - }); -} - -function computePropertyField(prop, memo, fieldName, fn){ - let { - result, - context, - dependencies, - } = evaluateCalculation({string: prop[fieldName], prop, memo, fn}); - if (result instanceof ConstantNode){ - prop[`${fieldName}Result`] = result.value; - } else { - prop[`${fieldName}Result`] = result.toString(); - } - prop.dependencies = union(prop.dependencies, dependencies); - if (context.errors.length){ - prop[`${fieldName}Errors`] = context.errors; - } else { - delete prop[`${fieldName}Errors`]; - } -} diff --git a/app/imports/api/creature/computation/engine/computeInlineCalculations.js b/app/imports/api/creature/computation/engine/computeInlineCalculations.js deleted file mode 100644 index eb54d998..00000000 --- a/app/imports/api/creature/computation/engine/computeInlineCalculations.js +++ /dev/null @@ -1,40 +0,0 @@ -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js'; -import ErrorNode from '/imports/parser/parseTree/ErrorNode.js'; -import { union } from 'lodash'; - -export default function computeInlineCalculations(prop, memo){ - if (prop.summary){ - computeInlineCalcsForField(prop, memo, 'summary'); - } - if (prop.description){ - computeInlineCalcsForField(prop, memo, 'description'); - } -} - -function computeInlineCalcsForField(prop, memo, field){ - let string = prop[field]; - let inlineComputations = []; - let matches = string.matchAll(INLINE_CALCULATION_REGEX); - for (let match of matches){ - let calculation = match[1]; - let { - result, - context, - dependencies, - } = evaluateCalculation({string: calculation, prop, memo, fn: 'compile'}); - if (result instanceof ErrorNode){ - result = '`Calculation Error`'; - } - let computation = { - calculation, - result: result && result.toString(), - }; - if (context.errors.length){ - computation.errors = context.errors; - } - inlineComputations.push(computation); - prop.dependencies = union(prop.dependencies, dependencies); - } - prop[`${field}Calculations`] = inlineComputations; -} diff --git a/app/imports/api/creature/computation/engine/computeLevels.js b/app/imports/api/creature/computation/engine/computeLevels.js deleted file mode 100644 index 21757025..00000000 --- a/app/imports/api/creature/computation/engine/computeLevels.js +++ /dev/null @@ -1,66 +0,0 @@ -import { forOwn, has, union } from 'lodash'; -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; - -export default function computeLevels(memo){ - computeClassLevels(memo); - computeTotalLevel(memo); -} - -function computeClassLevels(memo){ - forOwn(memo.classLevelsById, classLevel => { - applyToggles(classLevel, memo); - // class levels are mutually dependent - classLevel.dependencies = union( - classLevel.dependencies, - Object.keys(memo.classLevelsById) - ); - if (classLevel.deactivatedByToggle) return; - let name = classLevel.variableName; - let stat = memo.statsByVariableName[name]; - if (!stat){ - memo.statsByVariableName[name] = classLevel; - memo.classes[name] = classLevel; - } else if (!has(stat, 'level')){ - // Stat is overriden by an attribute - return; - } else if (stat.level < classLevel.level) { - memo.statsByVariableName[name] = classLevel; - memo.classes[name] = classLevel; - } - }); -} - -function computeTotalLevel(memo){ - let currentLevel = memo.statsByVariableName['level']; - if (!currentLevel || currentLevel.deactivatedByToggle){ - currentLevel = { - value: 0, - dependencies: [], - computationDetails: { - builtIn: true, - computed: true, - } - }; - memo.statsByVariableName['level'] = currentLevel; - } - // bail out if overriden by an attribute - if (!currentLevel.computationDetails.builtIn) return; - let level = 0; - for (let name in memo.classes){ - let cls = memo.classes[name]; - level += cls.level || 0; - if (cls._id){ - currentLevel.dependencies = union( - currentLevel.dependencies, - [cls._id] - ) - } - if (cls.dependencies){ - currentLevel.dependencies = union( - currentLevel.dependencies, - cls.dependencies, - ) - } - } - currentLevel.value = level; -} diff --git a/app/imports/api/creature/computation/engine/computeMemo.js b/app/imports/api/creature/computation/engine/computeMemo.js deleted file mode 100644 index 5eeb32e1..00000000 --- a/app/imports/api/creature/computation/engine/computeMemo.js +++ /dev/null @@ -1,37 +0,0 @@ -import { each, forOwn } from 'lodash'; -import computeLevels from '/imports/api/creature/computation/engine/computeLevels.js'; -import computeStat from '/imports/api/creature/computation/engine/computeStat.js'; -import computeEffect from '/imports/api/creature/computation/engine/computeEffect.js'; -import computeToggle from '/imports/api/creature/computation/engine/computeToggle.js'; -import computeEndStepProperty from '/imports/api/creature/computation/engine/computeEndStepProperty.js'; -import computeInlineCalculations from '/imports/api/creature/computation/engine/computeInlineCalculations.js'; -import computeConstant from '/imports/api/creature/computation/engine/computeConstant.js'; - -export default function computeMemo(memo){ - // Compute level - computeLevels(memo); - // Compute all constants that could be used - forOwn(memo.constantsById, constant => { - computeConstant (constant, memo); - }); - // Compute all stats, even if they are overriden - forOwn(memo.statsById, stat => { - computeStat (stat, memo); - }); - // Compute effects which didn't end up targeting a stat - each(memo.unassignedEffects, effect => { - computeEffect(effect, memo); - }); - // Compute toggles which didn't already get computed by dependencies - forOwn(memo.togglesById, toggle => { - computeToggle(toggle, memo); - }); - // Compute end step properties - forOwn(memo.endStepPropsById, prop => { - computeEndStepProperty(prop, memo); - }); - // Compute inline calculations - forOwn(memo.propsById, prop => { - computeInlineCalculations(prop, memo); - }); -} diff --git a/app/imports/api/creature/computation/engine/computeProficiency.js b/app/imports/api/creature/computation/engine/computeProficiency.js deleted file mode 100644 index 112a594b..00000000 --- a/app/imports/api/creature/computation/engine/computeProficiency.js +++ /dev/null @@ -1,23 +0,0 @@ -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; - -export default function computeEffect(proficiency, memo){ - if (proficiency.computationDetails.computed) return; - if (proficiency.computationDetails.busyComputing){ - // Trying to compute this proficiency again while it is already computing. - // We must be in a dependency loop. - proficiency.computationDetails.computed = true; - proficiency.result = NaN; - proficiency.computationDetails.busyComputing = false; - proficiency.computationDetails.error = 'dependencyLoop'; - if (Meteor.isClient) console.warn('dependencyLoop', proficiency); - return; - } - // Before doing any work, mark this proficiency as busy - proficiency.computationDetails.busyComputing = true; - - // Apply any toggles - applyToggles(proficiency, memo); - - proficiency.computationDetails.computed = true; - proficiency.computationDetails.busyComputing = false; -} diff --git a/app/imports/api/creature/computation/engine/computeStat.js b/app/imports/api/creature/computation/engine/computeStat.js deleted file mode 100644 index a455a43a..00000000 --- a/app/imports/api/creature/computation/engine/computeStat.js +++ /dev/null @@ -1,162 +0,0 @@ -import combineStat from '/imports/api/creature/computation/engine/combineStat.js'; -import computeEffect from '/imports/api/creature/computation/engine/computeEffect.js'; -import EffectAggregator from '/imports/api/creature/computation/engine/EffectAggregator.js'; -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; -import { each, union, without } from 'lodash'; - -export default function computeStat(stat, memo){ - // If the stat is already computed, skip it - if (stat.computationDetails.computed) return; - if (stat.computationDetails.busyComputing){ - // Trying to compute this stat again while it is already computing. - // We must be in a dependency loop. - stat.computationDetails.computed = true; - stat.value = NaN; - stat.computationDetails.busyComputing = false; - stat.computationDetails.error = 'dependencyLoop'; - if (Meteor.isClient) console.warn('dependencyLoop', stat); - return; - } - // Before doing any work, mark this stat as busy - stat.computationDetails.busyComputing = true; - - let effects = stat.computationDetails.effects || []; - let proficiencies = stat.computationDetails.proficiencies || []; - - // Get references to all the stats that share the variable name - let sameNameStats - - if (stat.computationDetails.idsOfSameName){ - sameNameStats = stat.computationDetails.idsOfSameName.map( - id => memo.propsById[id] - ); - } else { - sameNameStats = []; - } - - let allStats = [stat, ...sameNameStats]; - - // Decide which stat is the last active stat - // The last active stat is considered the cannonical stat - let lastActiveStat; - allStats.forEach(candidateStat => { - applyToggles(candidateStat, memo); - if (!candidateStat.inactive) lastActiveStat = candidateStat; - candidateStat.overridden = undefined; - }); - if (!lastActiveStat){ - delete memo.statsByVariableName[stat.variableName]; - return; - } - // Make sure the active stat has all the effects and proficiencies - lastActiveStat.computationDetails.effects = effects; - lastActiveStat.computationDetails.proficiencies = proficiencies; - - // Update the memo's stat with the chosen stat - memo.statsByVariableName[stat.variableName] = lastActiveStat; - - // Recreate list of the non-cannonical stats - sameNameStats = without(allStats, lastActiveStat); - - sameNameStats.forEach(statInstance => { - // Mark the non-cannonical stats as overridden - statInstance.overridden = true; - - // Apply the cannonical damage - statInstance.damage = lastActiveStat.damage; - }); - - let baseDependencies = []; - allStats.forEach(statInstance => { - // Add this stat and its deps to the dependencies - baseDependencies = union( - baseDependencies, - [statInstance._id], - statInstance.dependencies, - ); - - // Apply all the base proficiencies - if (statInstance.baseProficiency && !statInstance.inactive){ - proficiencies.push({ - value: statInstance.baseProficiency, - stats: [statInstance.variableName], - type: 'proficiency', - dependencies: statInstance.overridden ? - union(statInstance.dependencies, [statInstance._id]) : - [], - computationDetails: { - computed: true, - } - }); - } - - // Compute each active stat's baseValue calculation and apply it - if (!statInstance.inactive) { - delete statInstance.baseValueErrors; - let { - result, - context, - dependencies - } = evaluateCalculation({ - string: statInstance.baseValueCalculation, - prop: statInstance, - memo - }); - result.value = +result.value; - if (!isNaN(result.value)){ - statInstance.baseValue = result.value; - } else { - statInstance.baseValue = undefined; - } - statInstance.dependencies = union(statInstance.dependencies, dependencies); - if (context.errors.length){ - statInstance.baseValueErrors = context.errors; - } - // Apply all the base values - if (Number.isFinite(statInstance.baseValue)){ - effects.push({ - operation: 'base', - calculation: statInstance.baseValueCalculation, - result: statInstance.baseValue, - stats: [statInstance.variableName], - dependencies: statInstance.overridden ? - union(statInstance.dependencies, [statInstance._id]) : - [], - computationDetails: { - computed: true, - }, - }); - } - } - }); - - // Compute and aggregate all the effects - let aggregator = new EffectAggregator(); - let effectDeps = []; - each(effects, (effect) => { - // Compute - computeEffect(effect, memo); - if (effect.deactivatedByToggle) return; - - // dependencies - if (effect._id) effectDeps = union(effectDeps, [effect._id]); - effectDeps = union(effectDeps, effect.dependencies); - - // Add computed effect to aggregator - aggregator.addEffect(effect); - }); - - // Combine the effects into the stats - allStats.forEach(statInstance => { - // Conglomerate all the effects to compute the final stat values - combineStat(statInstance, aggregator, memo); - // Mark the stats as computed - statInstance.computationDetails.computed = true; - statInstance.computationDetails.busyComputing = false; - // Only the active stat instance depeneds on the effects - if (!statInstance.overridden){ - statInstance.dependencies = union(statInstance.dependencies, effectDeps); - } - }); -} diff --git a/app/imports/api/creature/computation/engine/computeToggle.js b/app/imports/api/creature/computation/engine/computeToggle.js deleted file mode 100644 index dad8174b..00000000 --- a/app/imports/api/creature/computation/engine/computeToggle.js +++ /dev/null @@ -1,55 +0,0 @@ -import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js'; -import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js'; -import { union } from 'lodash'; - -export default function computeToggle(toggle, memo){ - if (toggle.computationDetails.computed) return; - if (toggle.computationDetails.busyComputing){ - // Trying to compute this effect again while it is already computing. - // We must be in a dependency loop. - toggle.computationDetails.computed = true; - toggle.result = false; - toggle.computationDetails.busyComputing = false; - toggle.computationDetails.error = 'dependencyLoop'; - if (Meteor.isClient) console.warn('dependencyLoop', toggle); - return; - } - // Before doing any work, mark this toggle as busy - toggle.computationDetails.busyComputing = true; - - // Apply any parent toggles - applyToggles(toggle, memo); - - // Do work - delete toggle.errors; - if (toggle.enabled){ - toggle.toggleResult = true; - } else if (toggle.disabled){ - toggle.toggleResult = false; - } else if (!toggle.condition){ - toggle.toggleResult = false; - } else if (Number.isFinite(+toggle.condition)){ - toggle.toggleResult = !!+toggle.condition; - } else { - let { - result, - context, - dependencies, - } = evaluateCalculation({string: toggle.condition, prop: toggle, memo}); - toggle.toggleResult = !!result.value; - toggle.dependencies = union( - toggle.dependencies, - dependencies, - ); - if (context.errors.length){ - toggle.errors = context.errors; - } - } - if (!toggle.toggleResult){ - toggle.inactive = true; - toggle.deactivatedBySelf = true; - toggle.deactivatedByToggle = true; - } - toggle.computationDetails.computed = true; - toggle.computationDetails.busyComputing = false; -} diff --git a/app/imports/api/creature/computation/engine/evaluateCalculation.js b/app/imports/api/creature/computation/engine/evaluateCalculation.js deleted file mode 100644 index 9266efd3..00000000 --- a/app/imports/api/creature/computation/engine/evaluateCalculation.js +++ /dev/null @@ -1,137 +0,0 @@ -import computeStat from '/imports/api/creature/computation/engine/computeStat.js'; -import { prettifyParseError, parse, CompilationContext } from '/imports/parser/parser.js'; -import SymbolNode from '/imports/parser/parseTree/SymbolNode.js'; -import AccessorNode from '/imports/parser/parseTree/AccessorNode.js'; -import ConstantNode from '/imports/parser/parseTree/ConstantNode.js'; -import ErrorNode from '/imports/parser/parseTree/ErrorNode.js'; -import findAncestorByType from '/imports/api/creature/computation/engine/findAncestorByType.js'; -import { union } from 'lodash'; - -/* Convert a calculation into a constant output and errors*/ -export default function evaluateCalculation({ - string, - prop, - memo, - fn = 'reduce', -}){ - let dependencies = []; - let context = new CompilationContext(); - if (!string) return { - result: new ConstantNode({value: string, type: 'string'}), - context, - dependencies, - }; - if (typeof string !== 'string'){ - string = string.toString(); - } - // Parse the string - let calc; - try { - calc = parse(string); - } catch (e) { - let error = prettifyParseError(e); - return { - result: new ErrorNode({context, error}), - context, - dependencies, - }; - } - - // Replace constants with their parsed constant - let replaceResults = replaceConstants({ - calc, memo, prop, dependencies, context - }); - dependencies = replaceResults.dependencies; - calc = replaceResults.calc; - if (replaceResults.failed){ - return { - result: new ConstantNode({value: string, type: 'string'}), - context, - dependencies, - }; - } - - // Ensure all symbol nodes are defined and computed - dependencies = computeSymbols({calc, memo, prop, dependencies}) - - // Evaluate - let result = calc[fn](memo.statsByVariableName, context); - return {result, context, dependencies}; -} - -// Replace constants in the calc with the right ParseNodes -function replaceConstants({calc, memo, prop, dependencies, context}){ - let constFailed = []; - calc = calc.replaceNodes(node => { - if (!(node instanceof SymbolNode)) return; - let stat, constant; - if (node.name[0] !== '#'){ - stat = memo.statsByVariableName[node.name] - constant = memo.constantsByVariableName[node.name]; - } else if (node.name === '#constant'){ - constant = findAncestorByType({type: 'constant', prop, memo}); - } - // replace constants that aren't overridden by stats or disabled by a toggle - if (constant && !constant.deactivatedByToggle && !stat){ - dependencies = union(dependencies, [ - constant._id, - ...constant.dependencies - ]); - // Fail if the constant has errors - if (constant.errors && constant.errors.length){ - constFailed.push(node.name); - return; - } - let parsedConstantNode; - try { - parsedConstantNode = parse(constant.calculation); - } catch(e){ - constFailed.push(node.name); - return; - } - if (!parsedConstantNode) constFailed.push(node.name); - return parsedConstantNode; - } - }); - constFailed.forEach(name => { - context.storeError({ - type: 'error', - message: `${name} is a constant property with parsing errors` - }); - }); - let failed = !!constFailed.length; - if (failed){ - calc = new ErrorNode({error: 'Failed to replace constants'}); - } - return { failed, dependencies, calc }; -} - - // Ensure all symbol nodes are defined and computed -function computeSymbols({calc, memo, prop, dependencies}){ - calc.traverse(node => { - if (node instanceof SymbolNode || node instanceof AccessorNode){ - let stat; - // References up the tree start with # - if (node.name[0] === '#'){ - stat = findAncestorByType({type: node.name.slice(1), prop, memo}); - memo.statsByVariableName[node.name] = stat; - } else { - stat = memo.statsByVariableName[node.name]; - } - if (stat && stat.computationDetails && !stat.computationDetails.computed){ - computeStat(stat, memo); - } - if (stat){ - if (stat.dependencies){ - dependencies = union(dependencies, [ - stat._id || node.name, - ...stat.dependencies - ]); - } else { - dependencies = union(dependencies, [stat._id || node.name]); - } - } - } - }); - return dependencies; -} diff --git a/app/imports/api/creature/computation/engine/findAncestorByType.js b/app/imports/api/creature/computation/engine/findAncestorByType.js deleted file mode 100644 index f8bafdf4..00000000 --- a/app/imports/api/creature/computation/engine/findAncestorByType.js +++ /dev/null @@ -1,10 +0,0 @@ -export default function findAncestorByType({type, prop, memo}){ - if (!prop || !prop.ancestors) return; - let ancestor; - for (let i = prop.ancestors.length - 1; i >= 0; i--){ - ancestor = memo.propsById[prop.ancestors[i].id]; - if (ancestor && ancestor.type === type){ - return ancestor; - } - } -} diff --git a/app/imports/api/creature/computation/engine/getComputationProperties.js b/app/imports/api/creature/computation/engine/getComputationProperties.js deleted file mode 100644 index aee7575e..00000000 --- a/app/imports/api/creature/computation/engine/getComputationProperties.js +++ /dev/null @@ -1,24 +0,0 @@ -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; - -export default function getComputationProperties(creatureId){ - // Find all the relevant properties - return CreatureProperties.find({ - 'ancestors.id': creatureId, - removed: {$ne: true}, - $or: [ - // All active properties - {inactive: {$ne: true}}, - // Unless they were deactivated because of a toggle - {deactivatedByToggle: true}, - ] - }, { - // Filter out fields never used by calculations - fields: { - icon: 0, - }, - // Obey tree order - sort: { - order: 1, - } - }).fetch(); -} diff --git a/app/imports/api/creature/computation/engine/getDependentProperties.js b/app/imports/api/creature/computation/engine/getDependentProperties.js deleted file mode 100644 index d87a70ed..00000000 --- a/app/imports/api/creature/computation/engine/getDependentProperties.js +++ /dev/null @@ -1,51 +0,0 @@ -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -import { union } from 'lodash'; - -export default function getDependentProperties({ - creatureId, - propertyIds, - propertiesDependedAponIds, - }){ - // find ids of all dependant toggles that have conditions, even if inactive - let toggleIds = CreatureProperties.find({ - 'ancestors.id': creatureId, - type: 'toggle', - removed: {$ne: true}, - condition: { $exists: true }, - dependencies: {$in: propertyIds}, - }, { - fields: {_id: 1}, - }).map(t => t._id); - // Find all the dependant properties - let props = CreatureProperties.find({ - 'ancestors.id': creatureId, - removed: {$ne: true}, - dependencies: {$in: propertyIds}, - $or: [ - // All active properties - {inactive: {$ne: true}}, - // All active and inactive toggles with conditions - // Same as {$in: toggleIds}, but should be slightly faster - {type: 'toggle', condition: { $exists: true }}, - // All decendents of the above toggles - {'ancestors.id': {$in: toggleIds}}, - ] - }, { fields: {_id: 1, dependencies: 1} }).fetch(); - // Add all the properties that changing props depend on, but haven't yet been - // included to make an array of every property we need - let allConnectedPropIds = [...propertyIds, ...propertiesDependedAponIds]; - props.forEach(prop => { - allConnectedPropIds = union( - allConnectedPropIds, - prop.dependencies, - [prop._id]); - }); - // Add on all the properties and the objects they depend apon - return CreatureProperties.find({ - _id: {$in: allConnectedPropIds} - }, { - // Ignore fields not used in computations - fields: {icon: 0}, - sort: {order: 1}, - }).fetch(); -} diff --git a/app/imports/api/creature/computation/engine/writeAlteredProperties.js b/app/imports/api/creature/computation/engine/writeAlteredProperties.js deleted file mode 100644 index 6927ea9e..00000000 --- a/app/imports/api/creature/computation/engine/writeAlteredProperties.js +++ /dev/null @@ -1,118 +0,0 @@ -import { Meteor } from 'meteor/meteor' -import { isEqual, forOwn } from 'lodash'; -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -import propertySchemasIndex from '/imports/api/properties/computedOnlyPropertySchemasIndex.js'; - -export default function writeAlteredProperties(memo){ - let bulkWriteOperations = []; - // Loop through all properties on the memo - forOwn(memo.propsById, changed => { - let schema = propertySchemasIndex[changed.type]; - if (!schema){ - console.warn('No schema for ' + changed.type); - return; - } - let id = changed._id; - let op = undefined; - let original = memo.originalPropsById[id]; - let keys = [ - 'dependencies', - 'inactive', - 'deactivatedBySelf', - 'deactivatedByAncestor', - 'deactivatedByToggle', - 'damage', - ...schema.objectKeys(), - ]; - op = addChangedKeysToOp(op, keys, original, changed); - if (op){ - bulkWriteOperations.push(op); - } - }); - writePropertiesSequentially(bulkWriteOperations); -} - -function addChangedKeysToOp(op, keys, original, changed) { - // Loop through all keys that can be changed by computation - // and compile an operation that sets all those keys - for (let key of keys){ - if (!isEqual(original[key], changed[key])){ - if (!op) op = newOperation(original._id, changed.type); - let value = changed[key]; - if (value === undefined){ - // Unset values that become undefined - addUnsetOp(op, key); - } else { - // Set values that changed to something else - addSetOp(op, key, value); - } - } - } - return op; -} - -function newOperation(_id, type){ - let newOp = { - updateOne: { - filter: {_id}, - update: {}, - } - }; - if (Meteor.isClient){ - newOp.type = type; - } - return newOp; -} - -function addSetOp(op, key, value){ - if (op.updateOne.update.$set){ - op.updateOne.update.$set[key] = value; - } else { - op.updateOne.update.$set = {[key]: value}; - } -} - -function addUnsetOp(op, key){ - if (op.updateOne.update.$unset){ - op.updateOne.update.$unset[key] = 1; - } else { - op.updateOne.update.$unset = {[key]: 1}; - } -} - -// We use this instead of bulkWriteProperties because it functions with latency -// compensation without needing to roll back changes, which causes multiple -// expensive redraws of the character sheet -function writePropertiesSequentially(bulkWriteOps){ - bulkWriteOps.forEach(op => { - let updateOneOrMany = op.updateOne || op.updateMany; - CreatureProperties.update(updateOneOrMany.filter, updateOneOrMany.update, { - // The bulk code is bypassing validation, so do the same here - // selector: {type: op.type} // include this if bypass is off - bypassCollection2: true, - }); - }); -} - -// This is more efficient on the database, but significantly less efficient -// in the UI because of incompatibility with latency compensation. If the -// duplicate redraws can be fixed, this is a strictly better way of processing -// writes -function bulkWriteProperties(bulkWriteOps){ - if (!bulkWriteOps.length) return; - // bulkWrite is only available on the server - if (Meteor.isServer){ - CreatureProperties.rawCollection().bulkWrite( - bulkWriteOps, - {ordered : false}, - function(e){ - if (e) { - console.error('Bulk write failed: '); - console.error(e); - } - } - ); - } else { - writePropertiesSequentially(bulkWriteOps); - } -} diff --git a/app/imports/api/creature/computation/engine/writeCreatureVariables.js b/app/imports/api/creature/computation/engine/writeCreatureVariables.js deleted file mode 100644 index c8ccb7d8..00000000 --- a/app/imports/api/creature/computation/engine/writeCreatureVariables.js +++ /dev/null @@ -1,59 +0,0 @@ -import { pick, forOwn } from 'lodash'; -import Creatures from '/imports/api/creature/creatures/Creatures.js'; -import VERSION from '/imports/constants/VERSION.js'; - -export default function writeCreatureVariables(memo, creatureId, fullRecompute = true) { - const fields = [ - 'ability', - 'abilityMod', - 'advantage', - 'attributeType', - 'baseProficiency', - 'baseValue', - 'calculation', - 'conditionalBenefits', - 'currentValue', - 'damage', - 'decimal', - 'fail', - 'level', - 'modifier', - 'name', - 'passiveBonus', - 'proficiency', - 'reset', - 'resetMultiplier', - 'rollBonuses', - 'skillType', - 'spellSlotLevelValue', - 'type', - 'value', - ]; - - if (fullRecompute){ - memo.creatureVariables = {}; - forOwn(memo.statsByVariableName, (stat, variableName) => { - // Don't save context variables - if (variableName[0] === '#') return; - let condensedStat = pick(stat, fields); - memo.creatureVariables[variableName] = condensedStat; - }); - forOwn(memo.constantsByVariableName, (stat, variableName) => { - let condensedStat = pick(stat, fields); - if (!memo.creatureVariables[variableName]){ - memo.creatureVariables[variableName] = condensedStat; - } - }); - Creatures.update(creatureId, {$set: { - variables: memo.creatureVariables, - computeVersion: VERSION, - }}); - } else { - let $set = {}; - forOwn(memo.statsByVariableName, (stat, variableName) => { - let condensedStat = pick(stat, fields); - $set[`variables.${variableName}`] = condensedStat; - }); - Creatures.update(creatureId, {$set}); - } -} diff --git a/app/imports/api/creature/computation/methods/recomputeCreature.js b/app/imports/api/creature/computation/methods/recomputeCreature.js deleted file mode 100644 index 781304ae..00000000 --- a/app/imports/api/creature/computation/methods/recomputeCreature.js +++ /dev/null @@ -1,120 +0,0 @@ -import { ValidatedMethod } from 'meteor/mdg:validated-method'; -import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; -import SimpleSchema from 'simpl-schema'; -import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import ComputationMemo from '/imports/api/creature/computation/engine/ComputationMemo.js'; -import getComputationProperties from '/imports/api/creature/computation/engine/getComputationProperties.js'; -import computeMemo from '/imports/api/creature/computation/engine/computeMemo.js'; -import writeAlteredProperties from '/imports/api/creature/computation/engine/writeAlteredProperties.js'; -import writeCreatureVariables from '/imports/api/creature/computation/engine/writeCreatureVariables.js'; -import { recomputeDamageMultipliersById } from '/imports/api/creature/denormalise/recomputeDamageMultipliers.js'; -import recomputeSlotFullness from '/imports/api/creature/denormalise/recomputeSlotFullness.js'; -import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import getDependentProperties from '/imports/api/creature/computation/engine/getDependentProperties.js'; -import Creatures from '/imports/api/creature/creatures/Creatures.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; - -export const recomputeCreature = new ValidatedMethod({ - - name: 'creatures.recomputeCreature', - - validate: new SimpleSchema({ - charId: { type: String } - }).validator(), - - mixins: [RateLimiterMixin], - rateLimit: { - numRequests: 5, - timeInterval: 5000, - }, - - run({charId}) { - let creature = Creatures.findOne(charId); - // Permission - assertEditPermission(creature, this.userId); - // Work, call this direcly if you are already in a method that has checked - // for permission to edit a given character - recomputeCreatureById(charId); - }, - -}); - -export function recomputeCreatureById(creatureId){ - let creature = Creatures.findOne(creatureId); - recomputeCreatureByDoc(creature); -} - -/** - * This function is the heart of DiceCloud. It recomputes a creature's stats, - * distilling down effects and proficiencies into the final stats that make up - * a creature. - * - * Essentially this is a depth first tree traversal algorithm that computes - * stats' dependencies before computing stats themselves, while detecting - * dependency loops. - * - * At the moment it makes no effort to limit recomputation to just what was - * changed. - * - * Attempting to implement dependency management to limit recomputation to just - * change affected stats should only happen as a last resort, when this function - * can no longer be performed more efficiently, and server resources can not be - * expanded to meet demand. - * - * A brief overview: - * - Fetch the stats of the creature and add them to - * an object for quick lookup - * - Fetch the effects and proficiencies which apply to each stat and store them with the stat - * - Fetch the class levels and store them as well - * - Mark each stat and effect as uncomputed - * - Iterate over each stat in order and compute it - * - If the stat is already computed, skip it - * - If the stat is busy being computed, we are in a dependency loop, make it NaN and mark computed - * - Mark the stat as busy computing - * - Iterate over each effect which applies to the attribute - * - If the effect is not computed compute it - * - If the effect relies on another attribute, get its computed value - * - Recurse if that attribute is uncomputed - * - apply the effect to the attribute - * - Conglomerate all the effects to compute the final stat values - * - Mark the stat as computed - * - Write the computed results back to the database - */ -export function recomputeCreatureByDoc(creature){ - const creatureId = creature._id; - let props = getComputationProperties(creatureId); - let computationMemo = new ComputationMemo(props, creature); - computeMemo(computationMemo); - writeAlteredProperties(computationMemo); - writeCreatureVariables(computationMemo, creatureId); - recomputeDamageMultipliersById(creatureId); - recomputeSlotFullness(creatureId); - return computationMemo; -} - -export function recomputePropertyDependencies(property){ - let creature = getRootCreatureAncestor(property); - recomputeCreatureByDependencies({ - creature, - propertyIds: [property._id], - propertiesDependedAponIds: property.dependencies, - }); -} - -export function recomputeCreatureByDependencies({ - creature, - propertyIds, - propertiesDependedAponIds -}){ - let props = getDependentProperties({ - creatureId: creature._id, - propertyIds, - propertiesDependedAponIds, - }); - let computationMemo = new ComputationMemo(props, creature); - computeMemo(computationMemo); - writeAlteredProperties(computationMemo); - writeCreatureVariables(computationMemo, creature._id, false) - recomputeInactiveProperties(creature._id); - return computationMemo; -} diff --git a/app/imports/api/creature/creatureProperties/CreatureProperties.js b/app/imports/api/creature/creatureProperties/CreatureProperties.js index 0f4591fb..0b2a491f 100644 --- a/app/imports/api/creature/creatureProperties/CreatureProperties.js +++ b/app/imports/api/creature/creatureProperties/CreatureProperties.js @@ -95,8 +95,8 @@ for (let key in propertySchemasIndex){ } import '/imports/api/creature/creatureProperties/methods/index.js'; -import '/imports/api/creature/actions/doAction.js'; -import '/imports/api/creature/actions/castSpellWithSlot.js'; +//import '/imports/api/creature/actions/doAction.js'; +//import '/imports/api/creature/actions/castSpellWithSlot.js'; export default CreatureProperties; export { diff --git a/app/imports/api/creature/creatureProperties/methods/adjustQuantity.js b/app/imports/api/creature/creatureProperties/methods/adjustQuantity.js index 430e37fe..b9958fcb 100644 --- a/app/imports/api/creature/creatureProperties/methods/adjustQuantity.js +++ b/app/imports/api/creature/creatureProperties/methods/adjustQuantity.js @@ -4,8 +4,7 @@ import SimpleSchema from 'simpl-schema'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const adjustQuantity = new ValidatedMethod({ name: 'creatureProperties.adjustQuantity', @@ -33,8 +32,7 @@ const adjustQuantity = new ValidatedMethod({ // Changing quantity does not change dependencies, but recomputing the // inventory changes many deps at once, so recompute fully - recomputeCreatureByDoc(rootCreature); - recomputeInventory(rootCreature._id); + computeCreature(rootCreature._id); }, }); diff --git a/app/imports/api/creature/creatureProperties/methods/damagePropertiesByName.js b/app/imports/api/creature/creatureProperties/methods/damagePropertiesByName.js index 2a67299c..673f71ad 100644 --- a/app/imports/api/creature/creatureProperties/methods/damagePropertiesByName.js +++ b/app/imports/api/creature/creatureProperties/methods/damagePropertiesByName.js @@ -5,7 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import Creatures from '/imports/api/creature/creatures/Creatures.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js'; -import { recomputePropertyDependencies } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreatureDependencyGroup } from '/imports/api/engine/computeCreature.js'; const damagePropertiesByName = new ValidatedMethod({ name: 'CreatureProperties.damagePropertiesByName', @@ -50,7 +50,7 @@ const damagePropertiesByName = new ValidatedMethod({ damagePropertyWork({property, operation, value}); lastProperty = property; }); - if (lastProperty) recomputePropertyDependencies(lastProperty); + if (lastProperty) computeCreatureDependencyGroup(lastProperty); } }); diff --git a/app/imports/api/creature/creatureProperties/methods/damageProperty.js b/app/imports/api/creature/creatureProperties/methods/damageProperty.js index da6b64da..d00ea3c4 100644 --- a/app/imports/api/creature/creatureProperties/methods/damageProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/damageProperty.js @@ -4,7 +4,7 @@ import SimpleSchema from 'simpl-schema'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; -import { recomputePropertyDependencies } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreatureDependencyGroup } from '/imports/api/engine/computeCreature.js'; const damageProperty = new ValidatedMethod({ name: 'creatureProperties.damage', @@ -39,7 +39,7 @@ const damageProperty = new ValidatedMethod({ } let result = damagePropertyWork({property, operation, value}); // Dependencies can't be changed through damage, only recompute deps - recomputePropertyDependencies(property); + computeCreatureDependencyGroup(property); return result; }, }); diff --git a/app/imports/api/creature/creatureProperties/methods/dealDamage.js b/app/imports/api/creature/creatureProperties/methods/dealDamage.js index ea3f3607..173132c2 100644 --- a/app/imports/api/creature/creatureProperties/methods/dealDamage.js +++ b/app/imports/api/creature/creatureProperties/methods/dealDamage.js @@ -5,7 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import Creatures from '/imports/api/creature/creatures/Creatures.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js'; -import { recomputeCreatureByDependencies } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const dealDamage = new ValidatedMethod({ name: 'creatureProperties.dealDamage', @@ -61,11 +61,7 @@ const dealDamage = new ValidatedMethod({ propertyIds.push(healthBar._id); propertiesDependedAponIds.push(...healthBar.dependencies); }); - recomputeCreatureByDependencies({ - creature, - propertyIds, - propertiesDependedAponIds, - }); + computeCreature(creatureId); return totalDamage; }, }); diff --git a/app/imports/api/creature/creatureProperties/methods/duplicateProperty.js b/app/imports/api/creature/creatureProperties/methods/duplicateProperty.js index 60761aa8..03c505c2 100644 --- a/app/imports/api/creature/creatureProperties/methods/duplicateProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/duplicateProperty.js @@ -8,10 +8,8 @@ import { setLineageOfDocs, renewDocIds } from '/imports/api/parenting/parenting.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; import { reorderDocs } from '/imports/api/parenting/order.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; var snackbar; if (Meteor.isClient){ snackbar = require( @@ -89,14 +87,8 @@ const duplicateProperty = new ValidatedMethod({ ancestorId: property.ancestors[0].id, }); - // Inserting the active status of the property needs to be denormalised - recomputeInactiveProperties(creature._id); - - // Recompute the inventory - recomputeInventory(creature._id); - // Inserting a creature property invalidates dependencies: full recompute - recomputeCreatureByDoc(creature); + computeCreature(creature._id); return propertyId; }, diff --git a/app/imports/api/creature/creatureProperties/methods/equipItem.js b/app/imports/api/creature/creatureProperties/methods/equipItem.js index ba1a0444..24cb51fa 100644 --- a/app/imports/api/creature/creatureProperties/methods/equipItem.js +++ b/app/imports/api/creature/creatureProperties/methods/equipItem.js @@ -4,9 +4,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { organizeDoc } from '/imports/api/parenting/organizeMethods.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS.js'; import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag.js'; @@ -49,9 +47,7 @@ const equipItem = new ValidatedMethod({ skipRecompute: true, }); - recomputeInactiveProperties(creature._id); - recomputeInventory(creature._id); - recomputeCreatureByDoc(creature); + computeCreature(creature._id); }, }); diff --git a/app/imports/api/creature/creatureProperties/methods/insertProperty.js b/app/imports/api/creature/creatureProperties/methods/insertProperty.js index 1dec5491..4535e1fe 100644 --- a/app/imports/api/creature/creatureProperties/methods/insertProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/insertProperty.js @@ -5,9 +5,7 @@ import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/ge import SimpleSchema from 'simpl-schema'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { reorderDocs } from '/imports/api/parenting/order.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import { getAncestry } from '/imports/api/parenting/parenting.js'; import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag.js'; import { RefSchema } from '/imports/api/parenting/ChildSchema.js'; @@ -140,15 +138,8 @@ export function insertPropertyWork({property, creature}){ collection: CreatureProperties, ancestorId: creature._id, }); - // Inserting the active status of the property needs to be denormalised - recomputeInactiveProperties(creature._id); - - // Recompute the inventory if it has changed - if (property.type === 'item' || property.type === 'container'){ - recomputeInventory(creature._id); - } // Inserting a creature property invalidates dependencies: full recompute - recomputeCreatureByDoc(creature); + computeCreature(creature._id); return _id; } diff --git a/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js b/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js index 1cb44914..e73cbe33 100644 --- a/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js +++ b/app/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js @@ -5,8 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import LibraryNodes from '/imports/api/library/LibraryNodes.js'; import { RefSchema } from '/imports/api/parenting/ChildSchema.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { setLineageOfDocs, @@ -15,7 +14,6 @@ import { } from '/imports/api/parenting/parenting.js'; import { reorderDocs } from '/imports/api/parenting/order.js'; import { setDocToLastOrder } from '/imports/api/parenting/order.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js'; const insertPropertyFromLibraryNode = new ValidatedMethod({ @@ -74,12 +72,8 @@ const insertPropertyFromLibraryNode = new ValidatedMethod({ ancestorId: rootCreature._id, }); - // The library properties need to denormalise which of them are inactive - recomputeInactiveProperties(rootCreature._id); - // Some of the library properties may be items or containers - recomputeInventory(rootCreature._id); // Inserting a creature property invalidates dependencies: full recompute - recomputeCreatureByDoc(rootCreature); + computeCreature(rootCreature._id); // Return the docId of the last property, the inserted root property return rootId; }, diff --git a/app/imports/api/creature/creatureProperties/methods/pullFromProperty.js b/app/imports/api/creature/creatureProperties/methods/pullFromProperty.js index a5ad2929..fa2acf78 100644 --- a/app/imports/api/creature/creatureProperties/methods/pullFromProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/pullFromProperty.js @@ -3,7 +3,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const pullFromProperty = new ValidatedMethod({ name: 'creatureProperties.pull', @@ -28,7 +28,7 @@ const pullFromProperty = new ValidatedMethod({ }); // TODO figure out if this method can change deps or not - recomputeCreatureByDoc(rootCreature); + computeCreature(rootCreature._id); // recomputePropertyDependencies(property); } }); diff --git a/app/imports/api/creature/creatureProperties/methods/pushToProperty.js b/app/imports/api/creature/creatureProperties/methods/pushToProperty.js index c1054490..e730065c 100644 --- a/app/imports/api/creature/creatureProperties/methods/pushToProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/pushToProperty.js @@ -3,7 +3,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import { get } from 'lodash'; const pushToProperty = new ValidatedMethod({ @@ -45,8 +45,7 @@ const pushToProperty = new ValidatedMethod({ }); // TODO figure out if this method can change deps or not - recomputeCreatureByDoc(rootCreature); - // recomputePropertyDependencies(property); + computeCreature(rootCreature._id); } }); diff --git a/app/imports/api/creature/creatureProperties/methods/restoreProperty.js b/app/imports/api/creature/creatureProperties/methods/restoreProperty.js index 864bdf36..b612e6c7 100644 --- a/app/imports/api/creature/creatureProperties/methods/restoreProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/restoreProperty.js @@ -5,9 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { restore } from '/imports/api/parenting/softRemove.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const restoreProperty = new ValidatedMethod({ name: 'creatureProperties.restore', @@ -28,12 +26,8 @@ const restoreProperty = new ValidatedMethod({ // Do work restore({_id, collection: CreatureProperties}); - // Items and containers might be restored - recomputeInventory(rootCreature._id); - // Parents active status may have changed while it was deleted - recomputeInactiveProperties(rootCreature._id); // Changes dependency tree by restoring children - recomputeCreatureByDoc(rootCreature); + computeCreature(rootCreature._id); } }); diff --git a/app/imports/api/creature/creatureProperties/methods/selectAmmoItem.js b/app/imports/api/creature/creatureProperties/methods/selectAmmoItem.js index 3c735ca1..c1e4baa3 100644 --- a/app/imports/api/creature/creatureProperties/methods/selectAmmoItem.js +++ b/app/imports/api/creature/creatureProperties/methods/selectAmmoItem.js @@ -4,7 +4,7 @@ import SimpleSchema from 'simpl-schema'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const selectAmmoItem = new ValidatedMethod({ name: 'creatureProperties.selectAmmoItem', @@ -45,7 +45,7 @@ const selectAmmoItem = new ValidatedMethod({ // Changing the linked item does change the dependency tree // TODO: We can predict exactly which deps will be affected instead of // recomputing the entire creature - recomputeCreatureByDoc(rootCreature); + computeCreature(rootCreature._id); }, }); diff --git a/app/imports/api/creature/creatureProperties/methods/softRemoveProperty.js b/app/imports/api/creature/creatureProperties/methods/softRemoveProperty.js index 328d3d8e..86df9247 100644 --- a/app/imports/api/creature/creatureProperties/methods/softRemoveProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/softRemoveProperty.js @@ -5,8 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { softRemove } from '/imports/api/parenting/softRemove.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; const softRemoveProperty = new ValidatedMethod({ name: 'creatureProperties.softRemove', @@ -27,10 +26,8 @@ const softRemoveProperty = new ValidatedMethod({ // Do work softRemove({_id, collection: CreatureProperties}); - // Potentially changes items and containers - recomputeInventory(rootCreature._id); // Changes dependency tree by removing children - recomputeCreatureByDoc(rootCreature); + computeCreature(rootCreature._id); } }); diff --git a/app/imports/api/creature/creatureProperties/methods/updateCreatureProperty.js b/app/imports/api/creature/creatureProperties/methods/updateCreatureProperty.js index 19ff8047..5d0bbfb4 100644 --- a/app/imports/api/creature/creatureProperties/methods/updateCreatureProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/updateCreatureProperty.js @@ -3,9 +3,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; const updateCreatureProperty = new ValidatedMethod({ name: 'creatureProperties.update', @@ -47,20 +45,9 @@ const updateCreatureProperty = new ValidatedMethod({ selector: {type: property.type}, }); - // Some updates might cause other properties to become inactive - if ([ - 'applied', 'equipped', 'prepared', 'alwaysPrepared', 'disabled' - ].includes(path[0])){ - recomputeInactiveProperties(rootCreature._id); - } - - if (property.type === 'item' || property.type === 'container'){ - // Potentially changes items and containers - recomputeInventory(rootCreature._id); - } // Updating a property is likely to change dependencies, do a full recompute // denormalised stats might change, so fetch the creature again - recomputeCreatureById(rootCreature._id); + computeCreature(rootCreature._id); }, }); diff --git a/app/imports/api/creature/creatureProperties/recomputeCreaturesByProperty.js b/app/imports/api/creature/creatureProperties/recomputeCreaturesByProperty.js index aa71e48f..ec8fb927 100644 --- a/app/imports/api/creature/creatureProperties/recomputeCreaturesByProperty.js +++ b/app/imports/api/creature/creatureProperties/recomputeCreaturesByProperty.js @@ -1,4 +1,4 @@ -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; /** * Recomputes all ancestor creatures of this property @@ -6,7 +6,7 @@ import { recomputeCreatureById } from '/imports/api/creature/computation/methods export default function recomputeCreaturesByProperty(property){ for (let ref of property.ancestors){ if (ref.collection === 'creatures') { - recomputeCreatureById.call(ref.id); + computeCreature.call(ref.id); } } } diff --git a/app/imports/api/creature/creatures/methods/restCreature.js b/app/imports/api/creature/creatures/methods/restCreature.js index a0464a00..a82f331b 100644 --- a/app/imports/api/creature/creatures/methods/restCreature.js +++ b/app/imports/api/creature/creatures/methods/restCreature.js @@ -4,7 +4,7 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import Creatures from '/imports/api/creature/creatures/Creatures.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; const restCreature = new ValidatedMethod({ name: 'creature.methods.longRest', @@ -109,7 +109,7 @@ const restCreature = new ValidatedMethod({ }); }); } - recomputeCreatureById(creatureId); + computeCreature(creatureId); }, }); diff --git a/app/imports/api/creature/denormalise/recomputeDamageMultipliers.js b/app/imports/api/creature/denormalise/recomputeDamageMultipliers.js deleted file mode 100644 index b31b1ece..00000000 --- a/app/imports/api/creature/denormalise/recomputeDamageMultipliers.js +++ /dev/null @@ -1,78 +0,0 @@ -import { ValidatedMethod } from 'meteor/mdg:validated-method'; -import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; -import SimpleSchema from 'simpl-schema'; -import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import Creatures from '/imports/api/creature/creatures/Creatures.js'; -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; - -export const recomputeDamageMultipliers = new ValidatedMethod({ - - name: 'creatures.recomputeDamageMultipliers', - - validate: new SimpleSchema({ - creatureId: { type: String } - }).validator(), - - mixins: [RateLimiterMixin], - rateLimit: { - numRequests: 5, - timeInterval: 5000, - }, - - run({creatureId}) { - // Permission - assertEditPermission(creatureId, this.userId); - // Work, call this direcly if you are already in a method that has checked - // for permission to edit a given character - recomputeDamageMultipliersById(creatureId); - }, - -}); - -export function recomputeDamageMultipliersById(creatureId){ - if (!creatureId) throw 'Creature ID is required'; - let props = CreatureProperties.find({ - 'ancestors.id': creatureId, - type: 'damageMultiplier', - removed: {$ne: true}, - inactive: {$ne: true}, - }, { - sort: {order: 1} - }); - - // Count of how many weakness, resistances and immunities each damage type has - let multipliersByName = {}; - props.forEach(dm => { - dm.damageTypes.forEach(damageType => { - if (!multipliersByName[damageType]){ - multipliersByName[damageType] = { - weaknesses: 0, - resistances: 0, - immunities: 0, - }; - } - if (dm.value === 0){ - multipliersByName[damageType].immunities++; - } else if (dm.value === 0.5){ - multipliersByName[damageType].resistances++; - } else if (dm.value === 2){ - multipliersByName[damageType].weaknesses++; - } - }); - }); - // Make an Object with keys of all the damage types that have a resulting - // immunity, weakness, or resistance - let damageMultipliers = {}; - for (let damageType in multipliersByName){ - let multiplier = multipliersByName[damageType]; - if (multiplier.immunities){ - damageMultipliers[damageType] = 0; - } else if (multiplier.resistances && !multiplier.weaknesses){ - damageMultipliers[damageType] = 0.5; - } else if (multiplier.weaknesses && !multiplier.resistances){ - damageMultipliers[damageType] = 2; - } - } - // Store the Object on the creature document - Creatures.update(creatureId, {$set: {damageMultipliers}}); -} diff --git a/app/imports/api/creature/denormalise/recomputeInactiveProperties.js b/app/imports/api/creature/denormalise/recomputeInactiveProperties.js deleted file mode 100644 index 8cff24a5..00000000 --- a/app/imports/api/creature/denormalise/recomputeInactiveProperties.js +++ /dev/null @@ -1,75 +0,0 @@ -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; - -export default function recomputeInactiveProperties(ancestorId){ - let disabledFilter = { - 'ancestors.id': ancestorId, - $or: [ - {disabled: true}, // Everything can be disabled - {type: 'buff', applied: false}, // Buffs can be applied - {type: 'item', equipped: {$ne: true}}, - {type: 'spell', prepared: {$ne: true}, alwaysPrepared: {$ne: true}}, - ], - }; - let disabledIds = CreatureProperties.find(disabledFilter, { - fields: {_id: 1}, - }).map(prop => prop._id); - - // Deactivate relevant properties - // Inactive properties - CreatureProperties.update({ - 'ancestors.id': ancestorId, - '_id': {$in: disabledIds}, - $or: [ - {inactive: {$ne: true}}, - {deactivatedBySelf: {$ne: true}}, - {deactivatedByAncestor: true}, - ], - }, { - $set: { - inactive: true, - deactivatedBySelf: true, - }, - $unset: {deactivatedByAncestor: 1}, - }, { - multi: true, - selector: {type: 'any'}, - }); - // Decendants of inactive properties - CreatureProperties.update({ - 'ancestors.id': {$eq: ancestorId, $in: disabledIds}, - $or: [ - {inactive: {$ne: true}}, - {deactivatedByAncestor: {$ne: true}}, - ], - }, { - $set: { - inactive: true, - deactivatedByAncestor: true, - }, - }, { - multi: true, - selector: {type: 'any'}, - }); - - // Remove inactive from all the properties that are inactive but shouldn't be - CreatureProperties.update({ - 'ancestors.id': {$eq: ancestorId, $nin: disabledIds}, - '_id': {$nin: disabledIds}, - // if it was a toggle responsible, we leave it alone - deactivatedByToggle: {$ne: true}, - $or: [ - {inactive: true}, - {deactivatedByAncestor: true}, - {deactivatedBySelf: true} - ], - }, { - $unset: { - inactive: 1, - deactivatedByAncestor: 1, - deactivatedBySelf: 1, - }, - }, { - multi: true, - selector: {type: 'any'}, - }); -} diff --git a/app/imports/api/creature/denormalise/recomputeInventory.js b/app/imports/api/creature/denormalise/recomputeInventory.js deleted file mode 100644 index 3bf7d1a2..00000000 --- a/app/imports/api/creature/denormalise/recomputeInventory.js +++ /dev/null @@ -1,111 +0,0 @@ -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -import Creatures from '/imports/api/creature/creatures/Creatures.js'; -import nodesToTree from '/imports/api/parenting/nodesToTree.js'; - -export default function recomputeInventory(creatureId){ - let inventoryForest = nodesToTree({ - collection: CreatureProperties, - ancestorId: creatureId, - filter: { - type: {$in: ['container', 'item']}, - }, - deactivatedByAncestor: {$ne: true}, - }); - let containersToWrite = []; - let data = getChildrenInventoryData(inventoryForest, containersToWrite); - containersToWrite.forEach(container => { - CreatureProperties.update(container._id, {$set: { - contentsWeight: container.contentsWeight, - contentsValue: container.contentsValue, - }}, {selector: {type: 'container'}}); - }); - Creatures.update(creatureId, {$set: { - 'denormalizedStats.weightTotal': data.weightTotal, - 'denormalizedStats.weightEquipment': data.weightEquipment, - 'denormalizedStats.weightCarried': data.weightCarried, - 'denormalizedStats.valueTotal': data.valueTotal, - 'denormalizedStats.valueEquipment': data.valueEquipment, - 'denormalizedStats.valueCarried': data.valueCarried, - 'denormalizedStats.itemsAttuned': data.itemsAttuned, - }}); - return data; -} - -function getChildrenInventoryData(forest, containersToWrite){ - let data = { - weightTotal: 0, - weightEquipment: 0, - weightCarried: 0, - valueTotal: 0, - valueEquipment: 0, - valueCarried: 0, - itemsAttuned: 0, - } - forest.forEach(tree => { - let treeData = getInventoryData(tree, containersToWrite); - for (let key in data){ - data[key] += treeData[key] || 0; - } - }); - return data; -} - -function getInventoryData(tree, containersToWrite){ - let data = { - weightTotal: 0, - weightEquipment: 0, - weightCarried: 0, - valueTotal: 0, - valueEquipment: 0, - valueCarried: 0, - itemsAttuned: 0, - } - let childData = getChildrenInventoryData(tree.children, containersToWrite); - let node = tree.node; - if (node.type === 'container'){ - data.weightTotal += node.weight || 0; - data.valueTotal += node.value || 0; - data.weightCarried += node.weight || 0; - data.valueCarried += node.value || 0; - storeContentsData(node, childData, containersToWrite); - } else if (node.type === 'item'){ - data.weightTotal += (node.weight * node.quantity) || 0; - data.valueTotal += (node.value * node.quantity) || 0; - data.weightCarried += (node.weight * node.quantity) || 0; - data.valueCarried += (node.value * node.quantity) || 0; - if (node.equipped){ - data.weightEquipment += (node.weight * node.quantity) || 0; - data.valueEquipment += (node.value * node.quantity) || 0; - } - if (node.attuned){ - data.itemsAttuned += 1; - } - } - for (let key in data){ - data[key] += childData[key]; - } - if (node.contentsWeightless){ - data.weightCarried = node.weight; - } - if (node.carried === false){ - data.weightCarried = 0; - data.valueCarried = 0; - } - return data -} - -function storeContentsData(node, childData, containersToWrite){ - let newContentsWeight = childData.weightCarried - if (node.contentsWeight !== newContentsWeight){ - node.contentsWeight = newContentsWeight; - node.contentsWeightChanged = true; - } - let newContentsValue = childData.valueCarried; - if (node.contentsValue !== newContentsValue){ - node.contentsValue = newContentsValue; - node.contentsValueChanged = true; - } - if (node.contentsWeightChanged || node.contentsValueChanged){ - containersToWrite.push(node); - } -} diff --git a/app/imports/api/creature/denormalise/recomputeSlotFullness.js b/app/imports/api/creature/denormalise/recomputeSlotFullness.js deleted file mode 100644 index a99731c7..00000000 --- a/app/imports/api/creature/denormalise/recomputeSlotFullness.js +++ /dev/null @@ -1,43 +0,0 @@ -import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -// n + 1 database queries + n potential updates for n slots. Could be sped up. -export default function recomputeSlotFullness(ancestorId){ - CreatureProperties.find({ - 'ancestors.id': ancestorId, - type: 'propertySlot', - }).forEach(slot => { - let children = CreatureProperties.find({ - 'parent.id': slot._id, - removed: {$ne: true}, - }, { - fields: { - slotQuantityFilled: 1, - type: 1 - } - }).fetch(); - let totalFilled = 0; - children.forEach(child => { - if (child.type === 'slotFiller'){ - totalFilled += child.slotQuantityFilled; - } else { - totalFilled++; - } - }); - let spaceLeft; - let expected = slot.quantityExpectedResult; - if (typeof expected !== 'number'){ - expected = 1; - } - if (expected === 0){ - spaceLeft = null; - } else { - spaceLeft = expected - totalFilled; - } - if (slot.totalFilled !== totalFilled || slot.spaceLeft !== spaceLeft){ - CreatureProperties.update(slot._id, { - $set: {totalFilled, spaceLeft}, - }, { - selector: {type: 'propertySlot'} - }); - } - }); -} diff --git a/app/imports/api/creature/experience/Experiences.js b/app/imports/api/creature/experience/Experiences.js index 100e87c3..89304e2b 100644 --- a/app/imports/api/creature/experience/Experiences.js +++ b/app/imports/api/creature/experience/Experiences.js @@ -3,7 +3,7 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method'; import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; import Creatures from '/imports/api/creature/creatures/Creatures.js'; -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js'; let Experiences = new Mongo.Collection('experiences'); @@ -175,7 +175,7 @@ const recomputeExperiences = new ValidatedMethod({ 'denormalizedStats.xp': xp, 'denormalizedStats.milestoneLevels': milestoneLevels }}); - recomputeCreatureById(creatureId); + computeCreature(creatureId); }, }); diff --git a/app/imports/api/creature/mixins/recomputeCreatureMixin.js b/app/imports/api/creature/mixins/recomputeCreatureMixin.js index 05c0abde..5aaf87ae 100644 --- a/app/imports/api/creature/mixins/recomputeCreatureMixin.js +++ b/app/imports/api/creature/mixins/recomputeCreatureMixin.js @@ -1,4 +1,4 @@ -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; export default function recomputeCreatureMixin(methodOptions){ let runFunc = methodOptions.run; @@ -10,7 +10,7 @@ export default function recomputeCreatureMixin(methodOptions){ ) { return result; } - recomputeCreatureById(charId); + computeCreature(charId); return result; }; return methodOptions; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/CreatureComputation.js b/app/imports/api/engine/computation/CreatureComputation.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildComputation/CreatureComputation.js rename to app/imports/api/engine/computation/CreatureComputation.js diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/computeInactiveStatus.js b/app/imports/api/engine/computation/buildComputation/computeInactiveStatus.js similarity index 90% rename from app/imports/api/creature/computation/newEngine/buildComputation/computeInactiveStatus.js rename to app/imports/api/engine/computation/buildComputation/computeInactiveStatus.js index 6645067d..0ec51aa4 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/computeInactiveStatus.js +++ b/app/imports/api/engine/computation/buildComputation/computeInactiveStatus.js @@ -1,4 +1,4 @@ -import walkDown from '/imports/api/creature/computation/newEngine/utility/walkdown.js'; +import walkDown from '/imports/api/engine/computation/utility/walkdown.js'; export default function computeInactiveStatus(node){ const prop = node.node; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/computeSlotQuantityFilled.js b/app/imports/api/engine/computation/buildComputation/computeSlotQuantityFilled.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildComputation/computeSlotQuantityFilled.js rename to app/imports/api/engine/computation/buildComputation/computeSlotQuantityFilled.js diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/computeToggleDependencies.js b/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js similarity index 84% rename from app/imports/api/creature/computation/newEngine/buildComputation/computeToggleDependencies.js rename to app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js index 40d77ea5..6b168c3c 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/computeToggleDependencies.js +++ b/app/imports/api/engine/computation/buildComputation/computeToggleDependencies.js @@ -1,4 +1,4 @@ -import walkDown from '/imports/api/creature/computation/newEngine/utility/walkdown.js'; +import walkDown from '/imports/api/engine/computation/utility/walkdown.js'; export default function computeToggleDependencies(node, dependencyGraph){ const prop = node.node; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/linkCalculationDependencies.js b/app/imports/api/engine/computation/buildComputation/linkCalculationDependencies.js similarity index 93% rename from app/imports/api/creature/computation/newEngine/buildComputation/linkCalculationDependencies.js rename to app/imports/api/engine/computation/buildComputation/linkCalculationDependencies.js index e6081faa..69f747ee 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/linkCalculationDependencies.js +++ b/app/imports/api/engine/computation/buildComputation/linkCalculationDependencies.js @@ -1,6 +1,6 @@ import SymbolNode from '/imports/parser/parseTree/SymbolNode.js'; import AccessorNode from '/imports/parser/parseTree/AccessorNode.js'; -import findAncestorByType from '/imports/api/creature/computation/newEngine/utility/findAncestorByType.js'; +import findAncestorByType from '/imports/api/engine/computation/utility/findAncestorByType.js'; export default function linkCalculationDependencies(dependencyGraph, prop, {propsById}){ prop._computationDetails.calculations.forEach(calcObj => { diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/linkInventory.js b/app/imports/api/engine/computation/buildComputation/linkInventory.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildComputation/linkInventory.js rename to app/imports/api/engine/computation/buildComputation/linkInventory.js diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/linkTypeDependencies.js b/app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildComputation/linkTypeDependencies.js rename to app/imports/api/engine/computation/buildComputation/linkTypeDependencies.js diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/parseCalculationFields.js b/app/imports/api/engine/computation/buildComputation/parseCalculationFields.js similarity index 96% rename from app/imports/api/creature/computation/newEngine/buildComputation/parseCalculationFields.js rename to app/imports/api/engine/computation/buildComputation/parseCalculationFields.js index eecc7641..6c55e290 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/parseCalculationFields.js +++ b/app/imports/api/engine/computation/buildComputation/parseCalculationFields.js @@ -1,7 +1,7 @@ import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js'; import { prettifyParseError, parse } from '/imports/parser/parser.js'; import ErrorNode from '/imports/parser/parseTree/ErrorNode.js'; -import applyFnToKey from '/imports/api/creature/computation/newEngine/utility/applyFnToKey.js'; +import applyFnToKey from '/imports/api/engine/computation/utility/applyFnToKey.js'; import { get } from 'lodash'; export default function parseCalculationFields(prop, schemas){ diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/removeSchemaFields.js b/app/imports/api/engine/computation/buildComputation/removeSchemaFields.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildComputation/removeSchemaFields.js rename to app/imports/api/engine/computation/buildComputation/removeSchemaFields.js diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeInactiveStatus.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js similarity index 96% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/computeInactiveStatus.testFn.js rename to app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js index 780716e3..19754fb9 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeInactiveStatus.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeInactiveStatus.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeSlotQuantityFilled.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js similarity index 87% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/computeSlotQuantityFilled.testFn.js rename to app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js index 1a6bbba4..8a8af817 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeSlotQuantityFilled.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeSlotQuantityFilled.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeToggleDependencies.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js similarity index 94% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/computeToggleDependencies.testFn.js rename to app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js index 3b6028c4..268ea2ef 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/computeToggleDependencies.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/computeToggleDependencies.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkCalculationDependencies.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js similarity index 92% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/linkCalculationDependencies.testFn.js rename to app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js index 918767ba..ca81ae6e 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkCalculationDependencies.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/linkCalculationDependencies.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkInventory.testFn.js b/app/imports/api/engine/computation/buildComputation/tests/linkInventory.testFn.js similarity index 95% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/linkInventory.testFn.js rename to app/imports/api/engine/computation/buildComputation/tests/linkInventory.testFn.js index 5bda55ab..cb22544a 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkInventory.testFn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/linkInventory.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkTypeDependencies.testfn.js b/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js similarity index 85% rename from app/imports/api/creature/computation/newEngine/buildComputation/tests/linkTypeDependencies.testfn.js rename to app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js index 5733bd4a..b8f9d4f1 100644 --- a/app/imports/api/creature/computation/newEngine/buildComputation/tests/linkTypeDependencies.testfn.js +++ b/app/imports/api/engine/computation/buildComputation/tests/linkTypeDependencies.testfn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/buildCreatureComputation.js b/app/imports/api/engine/computation/buildCreatureComputation.js similarity index 97% rename from app/imports/api/creature/computation/newEngine/buildCreatureComputation.js rename to app/imports/api/engine/computation/buildCreatureComputation.js index c577459c..af4d7fbb 100644 --- a/app/imports/api/creature/computation/newEngine/buildCreatureComputation.js +++ b/app/imports/api/engine/computation/buildCreatureComputation.js @@ -12,7 +12,7 @@ import computeToggleDependencies from './buildComputation/computeToggleDependenc import linkCalculationDependencies from './buildComputation/linkCalculationDependencies.js'; import linkTypeDependencies from './buildComputation/linkTypeDependencies.js'; import computeSlotQuantityFilled from './buildComputation/computeSlotQuantityFilled.js'; -import CreatureComputation from './buildComputation/CreatureComputation.js'; +import CreatureComputation from './CreatureComputation.js'; import removeSchemaFields from './buildComputation/removeSchemaFields.js'; /** diff --git a/app/imports/api/creature/computation/newEngine/buildCreatureComputation.test.js b/app/imports/api/engine/computation/buildCreatureComputation.test.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/buildCreatureComputation.test.js rename to app/imports/api/engine/computation/buildCreatureComputation.test.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType.js b/app/imports/api/engine/computation/computeComputation/computeByType.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType.js rename to app/imports/api/engine/computation/computeComputation/computeByType.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeAction.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeAction.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeAction.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeAction.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeAttribute.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeAttribute.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeAttribute.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeAttribute.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeContainer.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeContainer.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeContainer.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeContainer.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeSlot.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeSlot.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeSlot.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeSlot.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateClassLevel.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateClassLevel.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateClassLevel.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateClassLevel.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateDamageMultiplier.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateDamageMultiplier.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateDamageMultiplier.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateDamageMultiplier.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateDefinition.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateDefinition.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateDefinition.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateDefinition.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateEffect.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateInventory.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateInventory.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateInventory.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateInventory.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/index.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/index.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/aggregate/index.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/index.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeImplicitVariable.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeImplicitVariable.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeImplicitVariable.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeImplicitVariable.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsClass.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsClass.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsClass.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsClass.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsConstant.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsConstant.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsConstant.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsConstant.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/getAggregatorResult.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/getAggregatorResult.js similarity index 91% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/getAggregatorResult.js rename to app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/getAggregatorResult.js index 573a5766..95905904 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/computeByType/computeVariable/getAggregatorResult.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/getAggregatorResult.js @@ -1,4 +1,4 @@ -import stripFloatingPointOddities from '/imports/api/creature/computation/newEngine/utility/stripFloatingPointOddities.js'; +import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities.js'; export default function getAggregatorResult(node){ // Work out the base value as the greater of the deining stat value or diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeCalculations.js b/app/imports/api/engine/computation/computeComputation/computeCalculations.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeCalculations.js rename to app/imports/api/engine/computation/computeComputation/computeCalculations.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/computeToggles.js b/app/imports/api/engine/computation/computeComputation/computeToggles.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/computeToggles.js rename to app/imports/api/engine/computation/computeComputation/computeToggles.js diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAction.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeAction.testFn.js similarity index 95% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAction.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeAction.testFn.js index 0365b200..2fc425bc 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAction.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeAction.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAttribute.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeAttribute.testFn.js similarity index 93% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAttribute.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeAttribute.testFn.js index 160e0615..37c30504 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeAttribute.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeAttribute.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeClasses.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js similarity index 92% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeClasses.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js index d49011e2..2c6bdc8f 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeClasses.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeClasses.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeConstants.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js similarity index 85% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeConstants.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js index 8bf8b91d..94fd414e 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeConstants.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeConstants.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeDamageMultipliers.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeDamageMultipliers.testFn.js similarity index 89% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeDamageMultipliers.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeDamageMultipliers.testFn.js index 94ce0b24..ef1ec555 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeDamageMultipliers.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeDamageMultipliers.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeEffects.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js similarity index 91% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeEffects.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js index dea3f464..8650a9e2 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeEffects.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeEffects.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeInventory.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeInventory.testFn.js similarity index 93% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeInventory.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeInventory.testFn.js index d77b5b59..d2cc2f1d 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeInventory.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeInventory.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeSkills.testFn.js b/app/imports/api/engine/computation/computeComputation/tests/computeSkills.testFn.js similarity index 94% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/computeSkills.testFn.js rename to app/imports/api/engine/computation/computeComputation/tests/computeSkills.testFn.js index fa6c86a8..2557296a 100644 --- a/app/imports/api/creature/computation/newEngine/computeComputation/tests/computeSkills.testFn.js +++ b/app/imports/api/engine/computation/computeComputation/tests/computeSkills.testFn.js @@ -1,4 +1,4 @@ -import { buildComputationFromProps } from '/imports/api/creature/computation/newEngine/buildCreatureComputation.js'; +import { buildComputationFromProps } from '/imports/api/engine/computation/buildCreatureComputation.js'; import { assert } from 'chai'; import computeCreatureComputation from '../../computeCreatureComputation.js'; import clean from '../../utility/cleanProp.testFn.js'; diff --git a/app/imports/api/creature/computation/newEngine/computeComputation/tests/index.js b/app/imports/api/engine/computation/computeComputation/tests/index.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeComputation/tests/index.js rename to app/imports/api/engine/computation/computeComputation/tests/index.js diff --git a/app/imports/api/creature/computation/newEngine/computeCreatureComputation.js b/app/imports/api/engine/computation/computeCreatureComputation.js similarity index 79% rename from app/imports/api/creature/computation/newEngine/computeCreatureComputation.js rename to app/imports/api/engine/computation/computeCreatureComputation.js index a317e383..2c542c92 100644 --- a/app/imports/api/creature/computation/newEngine/computeCreatureComputation.js +++ b/app/imports/api/engine/computation/computeCreatureComputation.js @@ -1,6 +1,6 @@ -import computeCalculations from '/imports/api/creature/computation/newEngine/computeComputation/computeCalculations.js'; -import computeToggles from '/imports/api/creature/computation/newEngine/computeComputation/computeToggles.js'; -import computeByType from '/imports/api/creature/computation/newEngine/computeComputation/computeByType.js'; +import computeCalculations from '/imports/api/engine/computation/computeComputation/computeCalculations.js'; +import computeToggles from '/imports/api/engine/computation/computeComputation/computeToggles.js'; +import computeByType from '/imports/api/engine/computation/computeComputation/computeByType.js'; export default function computeCreatureComputation(computation){ const stack = []; diff --git a/app/imports/api/creature/computation/newEngine/computeCreatureComputation.test.js b/app/imports/api/engine/computation/computeCreatureComputation.test.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/computeCreatureComputation.test.js rename to app/imports/api/engine/computation/computeCreatureComputation.test.js diff --git a/app/imports/api/creature/computation/newEngine/utility/applyFnToKey.js b/app/imports/api/engine/computation/utility/applyFnToKey.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/applyFnToKey.js rename to app/imports/api/engine/computation/utility/applyFnToKey.js diff --git a/app/imports/api/creature/computation/newEngine/utility/applyFnToKey.test.js b/app/imports/api/engine/computation/utility/applyFnToKey.test.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/applyFnToKey.test.js rename to app/imports/api/engine/computation/utility/applyFnToKey.test.js diff --git a/app/imports/api/creature/computation/newEngine/utility/cleanProp.testFn.js b/app/imports/api/engine/computation/utility/cleanProp.testFn.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/cleanProp.testFn.js rename to app/imports/api/engine/computation/utility/cleanProp.testFn.js diff --git a/app/imports/api/creature/computation/newEngine/utility/findAncestorByType.js b/app/imports/api/engine/computation/utility/findAncestorByType.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/findAncestorByType.js rename to app/imports/api/engine/computation/utility/findAncestorByType.js diff --git a/app/imports/api/creature/computation/newEngine/utility/stripFloatingPointOddities.js b/app/imports/api/engine/computation/utility/stripFloatingPointOddities.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/stripFloatingPointOddities.js rename to app/imports/api/engine/computation/utility/stripFloatingPointOddities.js diff --git a/app/imports/api/creature/computation/newEngine/utility/walkdown.js b/app/imports/api/engine/computation/utility/walkdown.js similarity index 100% rename from app/imports/api/creature/computation/newEngine/utility/walkdown.js rename to app/imports/api/engine/computation/utility/walkdown.js diff --git a/app/imports/api/engine/computeCreature.js b/app/imports/api/engine/computeCreature.js new file mode 100644 index 00000000..2a5192d5 --- /dev/null +++ b/app/imports/api/engine/computeCreature.js @@ -0,0 +1,17 @@ +import buildCreatureComputation from './computation/buildCreatureComputation.js'; +import computeCreatureComputation from './computation/computeCreatureComputation.js'; + +export default function computeCreature(creatureId){ + const computation = buildCreatureComputation(creatureId); + computeCreatureComputation(computation); + // TODO: writeCreatureComputation(computation); +} + +// For now just recompute the whole creature, later only recompute a single +// connected section of the depdendency graph +export function computeCreatureDependencyGroup(property){ + let creatureId = property.ancestors[0].id; + const computation = buildCreatureComputation(creatureId); + computeCreatureComputation(computation); + // TODO: writeCreatureComputation(computation); +} diff --git a/app/imports/api/creature/actions/applyAction.js b/app/imports/api/engine/oldActions/applyAction.js similarity index 74% rename from app/imports/api/creature/actions/applyAction.js rename to app/imports/api/engine/oldActions/applyAction.js index 1ffb7990..1611a764 100644 --- a/app/imports/api/creature/actions/applyAction.js +++ b/app/imports/api/engine/oldActions/applyAction.js @@ -1,13 +1,13 @@ import spendResources from '/imports/api/creature/actions/spendResources.js' -import embedInlineCalculations from '/imports/api/creature/computation/afterComputation/embedInlineCalculations.js'; export default function applyAction({prop, log}){ let content = { name: prop.name }; + /* if (prop.summary){ content.value = embedInlineCalculations( prop.summary, prop.summaryCalculations ); - } + }*/ log.content.push(content); spendResources({prop, log}); } diff --git a/app/imports/api/creature/actions/applyAdjustment.js b/app/imports/api/engine/oldActions/applyAdjustment.js similarity index 100% rename from app/imports/api/creature/actions/applyAdjustment.js rename to app/imports/api/engine/oldActions/applyAdjustment.js diff --git a/app/imports/api/creature/actions/applyAttack.js b/app/imports/api/engine/oldActions/applyAttack.js similarity index 100% rename from app/imports/api/creature/actions/applyAttack.js rename to app/imports/api/engine/oldActions/applyAttack.js diff --git a/app/imports/api/creature/actions/applyBuff.js b/app/imports/api/engine/oldActions/applyBuff.js similarity index 100% rename from app/imports/api/creature/actions/applyBuff.js rename to app/imports/api/engine/oldActions/applyBuff.js diff --git a/app/imports/api/creature/actions/applyDamage.js b/app/imports/api/engine/oldActions/applyDamage.js similarity index 100% rename from app/imports/api/creature/actions/applyDamage.js rename to app/imports/api/engine/oldActions/applyDamage.js diff --git a/app/imports/api/creature/actions/applyProperties.js b/app/imports/api/engine/oldActions/applyProperties.js similarity index 100% rename from app/imports/api/creature/actions/applyProperties.js rename to app/imports/api/engine/oldActions/applyProperties.js diff --git a/app/imports/api/creature/actions/applyRoll.js b/app/imports/api/engine/oldActions/applyRoll.js similarity index 100% rename from app/imports/api/creature/actions/applyRoll.js rename to app/imports/api/engine/oldActions/applyRoll.js diff --git a/app/imports/api/creature/actions/applySave.js b/app/imports/api/engine/oldActions/applySave.js similarity index 100% rename from app/imports/api/creature/actions/applySave.js rename to app/imports/api/engine/oldActions/applySave.js diff --git a/app/imports/api/creature/actions/applyToggle.js b/app/imports/api/engine/oldActions/applyToggle.js similarity index 100% rename from app/imports/api/creature/actions/applyToggle.js rename to app/imports/api/engine/oldActions/applyToggle.js diff --git a/app/imports/api/creature/actions/castSpellWithSlot.js b/app/imports/api/engine/oldActions/castSpellWithSlot.js similarity index 96% rename from app/imports/api/creature/actions/castSpellWithSlot.js rename to app/imports/api/engine/oldActions/castSpellWithSlot.js index 9e2b3570..54d4686c 100644 --- a/app/imports/api/creature/actions/castSpellWithSlot.js +++ b/app/imports/api/engine/oldActions/castSpellWithSlot.js @@ -5,7 +5,7 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur import Creatures from '/imports/api/creature/creatures/Creatures.js'; import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js'; import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import { doActionWork } from '/imports/api/creature/actions/doAction.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import getAncestorContext from '/imports/api/creature/actions/getAncestorContext.js'; diff --git a/app/imports/api/creature/actions/doAction.js b/app/imports/api/engine/oldActions/doAction.js similarity index 80% rename from app/imports/api/creature/actions/doAction.js rename to app/imports/api/engine/oldActions/doAction.js index 8cbe6690..cfea79e2 100644 --- a/app/imports/api/creature/actions/doAction.js +++ b/app/imports/api/engine/oldActions/doAction.js @@ -6,11 +6,9 @@ import Creatures from '/imports/api/creature/creatures/Creatures.js'; import { CreatureLogSchema, insertCreatureLogWork } from '/imports/api/creature/log/CreatureLogs.js'; import getRootCreatureAncestor from '/imports/api/creature/creatureProperties/getRootCreatureAncestor.js'; import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import { recomputeCreatureByDoc } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import computeCreature from '/imports/api/engine/computeCreature.js'; import nodesToTree from '/imports/api/parenting/nodesToTree.js'; import applyProperties from '/imports/api/creature/actions/applyProperties.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; import getAncestorContext from '/imports/api/creature/actions/getAncestorContext.js'; const doAction = new ValidatedMethod({ @@ -50,17 +48,11 @@ const doAction = new ValidatedMethod({ }); doActionWork({action, creature, targets, actionContext, method: this}); - // The acting creature might have used ammo - recomputeInventory(creature._id); - - // The action might add properties which need to be activated - recomputeInactiveProperties(creature._id); - // recompute creatures - recomputeCreatureByDoc(creature); + computeCreature(creature._id); + targets.forEach(target => { - recomputeInactiveProperties(target._id); - recomputeCreatureByDoc(target); + computeCreature(target._id); }); }, }); diff --git a/app/imports/api/creature/actions/doCheck.js b/app/imports/api/engine/oldActions/doCheck.js similarity index 100% rename from app/imports/api/creature/actions/doCheck.js rename to app/imports/api/engine/oldActions/doCheck.js diff --git a/app/imports/api/creature/actions/getAncestorContext.js b/app/imports/api/engine/oldActions/getAncestorContext.js similarity index 100% rename from app/imports/api/creature/actions/getAncestorContext.js rename to app/imports/api/engine/oldActions/getAncestorContext.js diff --git a/app/imports/api/creature/actions/spendResources.js b/app/imports/api/engine/oldActions/spendResources.js similarity index 100% rename from app/imports/api/creature/actions/spendResources.js rename to app/imports/api/engine/oldActions/spendResources.js diff --git a/app/imports/api/parenting/organizeMethods.js b/app/imports/api/parenting/organizeMethods.js index 624a2525..e67fdc45 100644 --- a/app/imports/api/parenting/organizeMethods.js +++ b/app/imports/api/parenting/organizeMethods.js @@ -8,9 +8,8 @@ import { RefSchema } from '/imports/api/parenting/ChildSchema.js'; import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import fetchDocByRef from '/imports/api/parenting/fetchDocByRef.js'; import getCollectionByName from '/imports/api/parenting/getCollectionByName.js'; -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; -import recomputeInactiveProperties from '/imports/api/creature/denormalise/recomputeInactiveProperties.js'; -import recomputeInventory from '/imports/api/creature/denormalise/recomputeInventory.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; + const organizeDoc = new ValidatedMethod({ name: 'organize.organizeDoc', validate: new SimpleSchema({ @@ -60,14 +59,8 @@ const organizeDoc = new ValidatedMethod({ let creaturesToRecompute = union(docCreatures, parentCreatures); // Recompute the creatures creaturesToRecompute.forEach(id => { - // The active status of some properties might change due to a change in - // ancestry - recomputeInactiveProperties(id); - if (doc.type === 'container' || doc.type === 'item'){ - recomputeInventory(id); - } // Some Dependencies depend on ancestry, so a full recompute is needed - recomputeCreatureById(id); + computeCreature(id); }); } }, @@ -93,7 +86,7 @@ const reorderDoc = new ValidatedMethod({ safeUpdateDocOrder({docRef, order}); // Recompute the affected creatures getCreatureAncestors(doc).forEach(id => { - recomputeCreatureById(id); + computeCreature(id); }); }, }); diff --git a/app/imports/migrations/server/2.0-beta.33-dbv1.js b/app/imports/migrations/server/2.0-beta.33-dbv1.js index 112e22ce..d5ed8489 100644 --- a/app/imports/migrations/server/2.0-beta.33-dbv1.js +++ b/app/imports/migrations/server/2.0-beta.33-dbv1.js @@ -1,8 +1,6 @@ import { Migrations } from 'meteor/percolate:migrations'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import LibraryNodes from '/imports/api/library/LibraryNodes.js'; -import { get } from 'lodash'; -import embedInlineCalculations from '/imports/api/creature/computation/afterComputation/embedInlineCalculations.js'; import transformFields from '/imports/migrations/server/transformFields.js'; import SCHEMA_VERSION from '/imports/constants/SCHEMA_VERSION.js'; import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js'; @@ -172,9 +170,6 @@ function getInlineComputationTransforms(key){ return [ {from: key, to: `${key}.text`}, {from: `${key}Calculations`, to: `${key}.inlineCalculations`}, - {to: `${key}.value`, up: (val, doc) => - embedInlineCalculations(get(doc, key), get(doc, `${key}Calculations`)) - }, {from: `${key}Calculations.$.result`, to: `${key}.inlineCalculations.$.value`}, ]; } diff --git a/app/imports/server/publications/singleCharacter.js b/app/imports/server/publications/singleCharacter.js index 105ffed2..d879de52 100644 --- a/app/imports/server/publications/singleCharacter.js +++ b/app/imports/server/publications/singleCharacter.js @@ -3,8 +3,7 @@ import Creatures from '/imports/api/creature/creatures/Creatures.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js'; import { assertViewPermission } from '/imports/api/creature/creatures/creaturePermissions.js'; -import recomputeInvetory from '/imports/api/creature/denormalise/recomputeInventory.js'; -import { recomputeCreatureById } from '/imports/api/creature/computation/methods/recomputeCreature.js'; +import { computeCreature } from '/imports/api/engine/computeCreature.js'; import VERSION from '/imports/constants/VERSION.js'; let schema = new SimpleSchema({ @@ -27,8 +26,7 @@ Meteor.publish('singleCharacter', function(creatureId){ catch(e){ return [] } if (creature.computeVersion !== VERSION){ try { - recomputeInvetory(creatureId); - recomputeCreatureById(creatureId) + computeCreature(creatureId) } catch(e){ console.error(e) } } diff --git a/app/imports/ui/components/computation/EmbedInlineComputations.vue b/app/imports/ui/components/computation/EmbedInlineComputations.vue index befe1c41..c624c566 100644 --- a/app/imports/ui/components/computation/EmbedInlineComputations.vue +++ b/app/imports/ui/components/computation/EmbedInlineComputations.vue @@ -6,7 +6,7 @@