From 67da6412442a14caf9d2b434a3fee185638f2061 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Tue, 31 Jan 2023 20:36:26 +0200 Subject: [PATCH] Migrated internal variables to ~ prefix --- .../methods/damageProperty.js | 12 ++--- .../applyPropertyByType/applyAction.js | 52 +++++++++---------- .../applyPropertyByType/applyBranch.js | 8 +-- .../applyPropertyByType/applyDamage.js | 8 +-- .../actions/applyPropertyByType/applyRoll.js | 2 +- .../applyPropertyByType/applySavingThrow.js | 20 +++---- app/imports/api/engine/actions/doCastSpell.js | 3 +- app/imports/api/engine/actions/doCheck.js | 10 ++-- .../writeComputation/writeScope.js | 13 +++-- app/imports/constants/VARIABLE_NAME_REGEX.js | 2 +- app/imports/parser/grammar.js | 2 +- app/imports/parser/grammar.ne | 2 +- app/vue.d.ts | 13 +++++ 13 files changed, 82 insertions(+), 65 deletions(-) create mode 100644 app/vue.d.ts diff --git a/app/imports/api/creature/creatureProperties/methods/damageProperty.js b/app/imports/api/creature/creatureProperties/methods/damageProperty.js index f129a562..a8cd0696 100644 --- a/app/imports/api/creature/creatureProperties/methods/damageProperty.js +++ b/app/imports/api/creature/creatureProperties/methods/damageProperty.js @@ -64,12 +64,12 @@ export function damagePropertyWork({ prop, operation, value, actionContext, logF // Save the value to the scope before applying the before triggers if (operation === 'increment') { if (value >= 0) { - actionContext.scope['$damage'] = value; + actionContext.scope['~damage'] = { value }; } else { - actionContext.scope['$healing'] = -value; + actionContext.scope['~healing'] = { value: -value }; } } else { - actionContext.scope['$set'] = value; + actionContext.scope['~set'] = { value }; } applyTriggers(actionContext.triggers?.damageProperty?.before, prop, actionContext); @@ -77,12 +77,12 @@ export function damagePropertyWork({ prop, operation, value, actionContext, logF // fetch the value from the scope after the before triggers, in case they changed them if (operation === 'increment') { if (value >= 0) { - value = actionContext.scope['$damage']; + value = actionContext.scope['~damage']?.value; } else { - value = -actionContext.scope['$healing']; + value = -actionContext.scope['~healing']?.value; } } else { - value = actionContext.scope['$set']; + value = actionContext.scope['~set']?.value; } let damage, newValue, increment; diff --git a/app/imports/api/engine/actions/applyPropertyByType/applyAction.js b/app/imports/api/engine/actions/applyPropertyByType/applyAction.js index 7587f9cc..ff2f9024 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applyAction.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applyAction.js @@ -51,11 +51,11 @@ export default function applyAction(node, actionContext) { } function applyAttackWithoutTarget({ attack, actionContext }) { - delete actionContext.scope['$attackHit']; - delete actionContext.scope['$attackMiss']; - delete actionContext.scope['$criticalHit']; - delete actionContext.scope['$criticalMiss']; - delete actionContext.scope['$attackRoll']; + delete actionContext.scope['~attackHit']; + delete actionContext.scope['~attackMiss']; + delete actionContext.scope['~criticalHit']; + delete actionContext.scope['~criticalMiss']; + delete actionContext.scope['~attackRoll']; recalculateCalculation(attack, actionContext); const scope = actionContext.scope; @@ -66,16 +66,16 @@ function applyAttackWithoutTarget({ attack, actionContext }) { criticalMiss, } = rollAttack(attack, scope); let name = criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit'; - if (scope['$attackAdvantage'] === 1) { + if (scope['~attackAdvantage']?.value === 1) { name += ' (Advantage)'; - } else if (scope['$attackAdvantage'] === -1) { + } else if (scope['~attackAdvantage']?.value === -1) { name += ' (Disadvantage)'; } if (!criticalMiss) { - scope['$attackHit'] = true + scope['~attackHit'] = { value: true } } if (!criticalHit) { - scope['$attackMiss'] = true; + scope['~attackMiss'] = { value: true }; } actionContext.addLog({ @@ -87,12 +87,12 @@ function applyAttackWithoutTarget({ attack, actionContext }) { function applyAttackToTarget({ attack, target, actionContext }) { const scope = actionContext.scope; - delete scope['$attackHit']; - delete scope['$attackMiss']; - delete scope['$criticalHit']; - delete scope['$criticalMiss']; - delete scope['$attackDiceRoll']; - delete scope['$attackRoll']; + delete scope['~attackHit']; + delete scope['~attackMiss']; + delete scope['~criticalHit']; + delete scope['~criticalMiss']; + delete scope['~attackDiceRoll']; + delete scope['~attackRoll']; recalculateCalculation(attack, actionContext); @@ -109,9 +109,9 @@ function applyAttackToTarget({ attack, target, actionContext }) { let name = criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : result > armor ? 'Hit!' : 'Miss!'; - if (scope['$attackAdvantage'] === 1) { + if (scope['~attackAdvantage']?.value === 1) { name += ' (Advantage)'; - } else if (scope['$attackAdvantage'] === -1) { + } else if (scope['~attackAdvantage']?.value === -1) { name += ' (Disadvantage)'; } @@ -121,9 +121,9 @@ function applyAttackToTarget({ attack, target, actionContext }) { inline: true, }); if (criticalMiss || result < armor) { - scope['$attackMiss'] = true; + scope['~attackMiss'] = { value: true }; } else { - scope['$attackHit'] = true; + scope['~attackHit'] = { value: true }; } } else { actionContext.addLog({ @@ -141,7 +141,7 @@ function applyAttackToTarget({ attack, target, actionContext }) { function rollAttack(attack, scope) { const rollModifierText = numberToSignedString(attack.value, true); let value, resultPrefix; - if (scope['$attackAdvantage'] === 1) { + if (scope['~attackAdvantage']?.value === 1) { const [a, b] = rollDice(2, 20); if (a >= b) { value = a; @@ -150,7 +150,7 @@ function rollAttack(attack, scope) { value = b; resultPrefix = `1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`; } - } else if (scope['$attackAdvantage'] === -1) { + } else if (scope['~attackAdvantage']?.value === -1) { const [a, b] = rollDice(2, 20); if (a <= b) { value = a; @@ -163,23 +163,23 @@ function rollAttack(attack, scope) { value = rollDice(1, 20)[0]; resultPrefix = `1d20 [${value}] ${rollModifierText}` } - scope['$attackDiceRoll'] = value; + scope['~attackDiceRoll'] = { value }; const result = value + attack.value; - scope['$attackRoll'] = result; + scope['~attackRoll'] = { value: result }; const { criticalHit, criticalMiss } = applyCrits(value, scope); return { resultPrefix, result, value, criticalHit, criticalMiss }; } function applyCrits(value, scope) { - let criticalHitTarget = scope.criticalHitTarget?.value || 20; + const criticalHitTarget = 20; // scope['~criticalHitTarget']?.value || 20; let criticalHit = value >= criticalHitTarget; let criticalMiss; if (criticalHit) { - scope['$criticalHit'] = true; + scope['~criticalHit'] = { value: true }; } else { criticalMiss = value === 1; if (criticalMiss) { - scope['$criticalMiss'] = true; + scope['~criticalMiss'] = { value: true }; } } return { criticalHit, criticalMiss }; diff --git a/app/imports/api/engine/actions/applyPropertyByType/applyBranch.js b/app/imports/api/engine/actions/applyPropertyByType/applyBranch.js index e02ac55a..d48ebc01 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applyBranch.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applyBranch.js @@ -35,25 +35,25 @@ export default function applyBranch(node, actionContext) { } break; case 'hit': - if (scope['$attackHit']) { + if (scope['~attackHit']?.value) { if (!targets.length && !prop.silent) actionContext.addLog({ value: '**On hit**' }); applyChildren(); } break; case 'miss': - if (scope['$attackMiss']) { + if (scope['~attackMiss']?.value) { if (!targets.length && !prop.silent) actionContext.addLog({ value: '**On miss**' }); applyChildren(); } break; case 'failedSave': - if (scope['$saveFailed']) { + if (scope['~saveFailed']?.value) { if (!targets.length && !prop.silent) actionContext.addLog({ value: '**On failed save**' }); applyChildren(); } break; case 'successfulSave': - if (scope['$saveSucceeded']) { + if (scope['~saveSucceeded']?.value) { if (!targets.length && !prop.silent) actionContext.addLog({ value: '**On save**', }); applyChildren(); } diff --git a/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js b/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js index 366d62f4..af6f91ee 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js @@ -27,7 +27,7 @@ export default function applyDamage(node, actionContext) { // Choose target let damageTargets = prop.target === 'self' ? [actionContext.creature] : actionContext.targets; // Determine if the hit is critical - let criticalHit = scope['$criticalHit'] && + let criticalHit = scope['~criticalHit']?.value && prop.damageType !== 'healing' // Can't critically heal ; // Double the damage rolls if the hit is critical @@ -73,12 +73,12 @@ export default function applyDamage(node, actionContext) { damage = Math.floor(damage); // Convert extra damage into the stored type - if (prop.damageType === 'extra' && scope['$lastDamageType']) { - prop.damageType = scope['$lastDamageType']; + if (prop.damageType === 'extra' && scope['~lastDamageType']?.value) { + prop.damageType = scope['~lastDamageType']?.value; } // Store current damage type if (prop.damageType !== 'healing') { - scope['$lastDamageType'] = prop.damageType; + scope['~lastDamageType'] = { value: prop.damageType }; } // Memoise the damage suffix for the log diff --git a/app/imports/api/engine/actions/applyPropertyByType/applyRoll.js b/app/imports/api/engine/actions/applyPropertyByType/applyRoll.js index 2a0a9002..68892231 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applyRoll.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applyRoll.js @@ -46,7 +46,7 @@ export default function applyRoll(node, actionContext) { } const value = reduced.value; - actionContext.scope[prop.variableName] = value; + actionContext.scope[prop.variableName] = { value }; logValue.push(`**${value}**`); if (!prop.silent) { diff --git a/app/imports/api/engine/actions/applyPropertyByType/applySavingThrow.js b/app/imports/api/engine/actions/applyPropertyByType/applySavingThrow.js index f9f01ce5..2e2133e8 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applySavingThrow.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applySavingThrow.js @@ -31,18 +31,18 @@ export default function applySavingThrow(node, actionContext) { // If there are no save targets, apply all children as if the save both // succeeeded and failed if (!saveTargets?.length) { - scope['$saveFailed'] = true; - scope['$saveSucceeded'] = true; + scope['~saveFailed'] = { value: true }; + scope['~saveSucceeded'] = { value: true }; applyNodeTriggers(node, 'after', actionContext); return node.children.forEach(child => applyProperty(child, actionContext)); } // Each target makes the saving throw saveTargets.forEach(target => { - delete scope['$saveFailed']; - delete scope['$saveSucceeded']; - delete scope['$saveDiceRoll']; - delete scope['$saveRoll']; + delete scope['~saveFailed']; + delete scope['~saveSucceeded']; + delete scope['~saveDiceRoll']; + delete scope['~saveRoll']; const applyChildren = function () { applyNodeTriggers(node, 'after', actionContext); @@ -90,14 +90,14 @@ export default function applySavingThrow(node, actionContext) { value = values[0]; resultPrefix = `1d20 [ ${value} ] ${rollModifierText}` } - scope['$saveDiceRoll'] = value; + scope['~saveDiceRoll'] = { value }; const result = value + rollModifier || 0; - scope['$saveRoll'] = result; + scope['~saveRoll'] = { value: result }; const saveSuccess = result >= dc; if (saveSuccess) { - scope['$saveSucceeded'] = true; + scope['~saveSucceeded'] = { value: true }; } else { - scope['$saveFailed'] = true; + scope['~saveFailed'] = { value: true }; } if (!prop.silent) actionContext.addLog({ name: saveSuccess ? 'Successful save' : 'Failed save', diff --git a/app/imports/api/engine/actions/doCastSpell.js b/app/imports/api/engine/actions/doCastSpell.js index f512e4ed..4ea03630 100644 --- a/app/imports/api/engine/actions/doCastSpell.js +++ b/app/imports/api/engine/actions/doCastSpell.js @@ -117,7 +117,8 @@ const doAction = new ValidatedMethod({ } } - actionContext.scope['slotLevel'] = slotLevel; + actionContext.scope['slotLevel'] = { value: slotLevel }; + actionContext.scope['~slotLevel'] = { value: slotLevel }; // Do the action doActionWork({ diff --git a/app/imports/api/engine/actions/doCheck.js b/app/imports/api/engine/actions/doCheck.js index 5d9b4164..452c32eb 100644 --- a/app/imports/api/engine/actions/doCheck.js +++ b/app/imports/api/engine/actions/doCheck.js @@ -81,7 +81,7 @@ function rollCheck(prop, actionContext) { rollModifier += effectBonus; let value, values, resultPrefix; - if (scope['$checkAdvantage'] === 1) { + if (scope['~checkAdvantage']?.value === 1) { logName += ' (Advantage)'; const [a, b] = rollDice(2, 20); if (a >= b) { @@ -91,7 +91,7 @@ function rollCheck(prop, actionContext) { value = b; resultPrefix = `1d20 [ ~~${a}~~, ${b} ] ${rollModifierText} = `; } - } else if (scope['$checkAdvantage'] === -1) { + } else if (scope['~checkAdvantage']?.value === -1) { logName += ' (Disadvantage)'; const [a, b] = rollDice(2, 20); if (a <= b) { @@ -107,9 +107,9 @@ function rollCheck(prop, actionContext) { resultPrefix = `1d20 [ ${value} ] ${rollModifierText} = ` } const result = (value + rollModifier) || 0; - scope['$checkDiceRoll'] = value; - scope['$checkRoll'] = result; - scope['$checkModifier'] = rollModifier; + scope['~checkDiceRoll'] = { value }; + scope['~checkRoll'] = { value: result }; + scope['~checkModifier'] = { value: rollModifier }; actionContext.addLog({ name: logName, value: `${resultPrefix} **${result}**`, diff --git a/app/imports/api/engine/computation/writeComputation/writeScope.js b/app/imports/api/engine/computation/writeComputation/writeScope.js index d96c2bfe..18d93373 100644 --- a/app/imports/api/engine/computation/writeComputation/writeScope.js +++ b/app/imports/api/engine/computation/writeComputation/writeScope.js @@ -15,18 +15,21 @@ export default function writeScope(creatureId, computation) { let $set, $unset; - for (const key in scope){ + for (const key in scope) { + // Mongo can't handle keys that start with a dollar sign + if (key[0] === '$' || key[0] === '_') continue; + // Remove large properties that aren't likely to be accessed delete scope[key].parent; delete scope[key].ancestors; - + // Remove empty keys for (const subKey in scope[key]) { if (scope[key][subKey] === undefined) { delete scope[key][subKey] } } - + // Only update changed fields if (!EJSON.equals(variables[key], scope[key])) { if (!$set) $set = {}; @@ -53,9 +56,9 @@ export default function writeScope(creatureId, computation) { const update = {}; if ($set) update.$set = $set; if ($unset) update.$unset = $unset; - CreatureVariables.update({_creatureId: creatureId}, update); + CreatureVariables.update({ _creatureId: creatureId }, update); } if (computation.creature?.dirty) { - Creatures.update({_id: creatureId}, {$unset: { dirty: 1 }}); + Creatures.update({ _id: creatureId }, { $unset: { dirty: 1 } }); } } diff --git a/app/imports/constants/VARIABLE_NAME_REGEX.js b/app/imports/constants/VARIABLE_NAME_REGEX.js index 2ff1621f..53671d83 100644 --- a/app/imports/constants/VARIABLE_NAME_REGEX.js +++ b/app/imports/constants/VARIABLE_NAME_REGEX.js @@ -1,4 +1,4 @@ // Must contain a letter, and be made of word characters only -const VARIABLE_NAME_REGEX = /^[a-z$][\w_]*$/i; +const VARIABLE_NAME_REGEX = /^[a-zA-Z~][a-zA-Z_0-9]+$/i; export default VARIABLE_NAME_REGEX; diff --git a/app/imports/parser/grammar.js b/app/imports/parser/grammar.js index 43f5b70f..f48896f0 100644 --- a/app/imports/parser/grammar.js +++ b/app/imports/parser/grammar.js @@ -13,7 +13,7 @@ function id(x) { return x[0]; } value: s => s.slice(1, -1).replace('\\n', '\n'), }, name: { - match: /[a-zA-Z_#$]*[a-ce-zA-Z_#$][a-zA-Z0-9_#$]*/, + match: /[a-zA-Z~#][a-zA-Z0-9_]+/, type: moo.keywords({ 'keywords': ['true', 'false'], }), diff --git a/app/imports/parser/grammar.ne b/app/imports/parser/grammar.ne index 3ebdba75..05d2b427 100644 --- a/app/imports/parser/grammar.ne +++ b/app/imports/parser/grammar.ne @@ -11,7 +11,7 @@ value: s => s.slice(1, -1).replace('\\n', '\n'), }, name: { - match: /[a-zA-Z_#$]*[a-ce-zA-Z_#$][a-zA-Z0-9_#$]*/, + match: /[a-zA-Z~#][a-zA-Z0-9_]+/, type: moo.keywords({ 'keywords': ['true', 'false'], }), diff --git a/app/vue.d.ts b/app/vue.d.ts new file mode 100644 index 00000000..d41459e9 --- /dev/null +++ b/app/vue.d.ts @@ -0,0 +1,13 @@ +declare module 'vue/types/options' { + interface ComponentOptions { + meteor?: any; + } +} + +declare module 'vue/types/vue' { + interface Vue { + $subscribe: (name: string, params: any[]) => void; + $autorun: (fn: () => void) => number; + $subReady: Record; + } +} \ No newline at end of file