Merge feature-nested-sets into develop

This commit is contained in:
ThaumRystra
2023-12-18 18:27:17 +02:00
523 changed files with 5492 additions and 3763 deletions

View File

@@ -1,7 +1,7 @@
import { CreatureLogSchema, insertCreatureLogWork } from '/imports/api/creature/log/CreatureLogs.js';
import { CreatureLogSchema, insertCreatureLogWork } from '/imports/api/creature/log/CreatureLogs';
import {
getCreature, getVariables, getPropertiesOfType, replaceLinkedVariablesWithProps
} from '/imports/api/engine/loadCreatures.js';
} from '/imports/api/engine/loadCreatures';
import { groupBy, remove } from 'lodash';
export default class ActionContext {
@@ -56,10 +56,10 @@ export default class ActionContext {
// Group the triggers into triggers.<event>.<timing> or
// triggers.doActionProperty.<propertyType>.<timing>
this.triggers = groupBy(this.triggers, 'event');
for (let event in this.triggers) {
for (const event in this.triggers) {
if (event === 'doActionProperty') {
this.triggers[event] = groupBy(this.triggers[event], 'actionPropertyType');
for (let propertyType in this.triggers[event]) {
for (const propertyType in this.triggers[event]) {
this.triggers[event][propertyType] = groupBy(this.triggers[event][propertyType], 'timing');
}
} else {

View File

@@ -1,37 +0,0 @@
import action from './applyPropertyByType/applyAction.js';
import ammo from './applyPropertyByType/applyItemAsAmmo.js'
import adjustment from './applyPropertyByType/applyAdjustment.js';
import branch from './applyPropertyByType/applyBranch.js';
import buff from './applyPropertyByType/applyBuff.js';
import buffRemover from './applyPropertyByType/applyBuffRemover.js';
import damage from './applyPropertyByType/applyDamage.js';
import folder from './applyPropertyByType/applyFolder.js';
import note from './applyPropertyByType/applyNote.js';
import roll from './applyPropertyByType/applyRoll.js';
import savingThrow from './applyPropertyByType/applySavingThrow.js';
import toggle from './applyPropertyByType/applyToggle.js';
const applyPropertyByType = {
action,
ammo,
adjustment,
branch,
buff,
buffRemover,
damage,
folder,
note,
propertySlot: folder,
roll,
savingThrow,
spell: action,
toggle,
};
export default async function applyProperty(node, actionContext, ...rest) {
if (node.node.deactivatedByToggle) return;
actionContext.scope[`#${node.node.type}`] = node.node;
console.log('start apply props by type', node.node.type)
await applyPropertyByType[node.node.type]?.(node, actionContext, ...rest);
console.log('end apply prop by type', node.node.type)
}

View File

@@ -0,0 +1,38 @@
import action from './applyPropertyByType/applyAction';
import ammo from './applyPropertyByType/applyItemAsAmmo'
import adjustment from './applyPropertyByType/applyAdjustment';
import branch from './applyPropertyByType/applyBranch';
import buff from './applyPropertyByType/applyBuff';
import buffRemover from './applyPropertyByType/applyBuffRemover';
import damage from './applyPropertyByType/applyDamage';
import folder from './applyPropertyByType/applyFolder';
import note from './applyPropertyByType/applyNote';
import roll from './applyPropertyByType/applyRoll';
import savingThrow from './applyPropertyByType/applySavingThrow';
import toggle from './applyPropertyByType/applyToggle';
import ActionContext from '/imports/api/engine/actions/ActionContext';
import { TreeNode } from '/imports/api/parenting/parentingFunctions';
import { CreatureProperty } from '/imports/api/creature/creatureProperties/CreatureProperties';
const applyPropertyByType = {
action,
ammo,
adjustment,
branch,
buff,
buffRemover,
damage,
folder,
note,
propertySlot: folder,
roll,
savingThrow,
spell: action,
toggle,
};
export default function applyProperty(node: TreeNode<CreatureProperty>, actionContext: ActionContext, ...rest) {
if (node.doc.deactivatedByToggle) return;
actionContext.scope[`#${node.doc.type}`] = node.doc;
applyPropertyByType[node.doc.type]?.(node, actionContext, ...rest);
}

View File

@@ -1,22 +1,31 @@
import recalculateInlineCalculations from './shared/recalculateInlineCalculations.js';
import recalculateCalculation from './shared/recalculateCalculation.js';
import rollDice from '/imports/parser/rollDice.js';
import applyProperty from '../applyProperty.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
import numberToSignedString from '/imports/api/utility/numberToSignedString.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import { resetProperties } from '/imports/api/creature/creatures/methods/restCreature.js';
import recalculateInlineCalculations from './shared/recalculateInlineCalculations';
import recalculateCalculation from './shared/recalculateCalculation';
import rollDice from '/imports/parser/rollDice';
import applyProperty from '../applyProperty';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
import numberToSignedString from '/imports/api/utility/numberToSignedString';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import { resetProperties } from '/imports/api/creature/creatures/methods/restCreature';
import { TreeNode, hasAncestorRelationship } from '/imports/api/parenting/parentingFunctions';
import { Action } from '/imports/api/properties/Actions';
import { LogContent } from '/imports/api/creature/log/LogContentSchema';
import { Item } from '/imports/api/properties/Items';
export default async function applyAction(node, actionContext) {
await applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
interface Ammo extends Item {
type: 'ammo'
adjustment: number
}
export default function applyAction(node: TreeNode<Action>, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.doc;
if (prop.target === 'self') actionContext.targets = [actionContext.creature];
const targets = actionContext.targets;
// Log the name and summary
let content = { name: prop.name };
const content: LogContent = { name: prop.name, };
if (prop.summary?.text) {
recalculateInlineCalculations(prop.summary, actionContext);
content.value = prop.summary.value;
@@ -27,7 +36,7 @@ export default async function applyAction(node, actionContext) {
const failed = await spendResources(prop, actionContext);
if (failed) return;
const attack = prop.attackRoll || prop.attackRollBonus;
const attack = prop.attackRoll;
// Attack if there is an attack roll
if (attack && attack.calculation) {
@@ -59,7 +68,7 @@ function applyAttackWithoutTarget({ attack, actionContext }) {
recalculateCalculation(attack, actionContext);
const scope = actionContext.scope;
let {
const {
resultPrefix,
result,
criticalHit,
@@ -96,7 +105,7 @@ function applyAttackToTarget({ attack, target, actionContext }) {
recalculateCalculation(attack, actionContext);
let {
const {
resultPrefix,
result,
criticalHit,
@@ -176,7 +185,7 @@ function applyCrits(value, scope) {
scopeCrit = scopeCrit.value;
}
const criticalHitTarget = scopeCrit || 20;
let criticalHit = value >= criticalHitTarget;
const criticalHit = value >= criticalHitTarget;
let criticalMiss;
if (criticalHit) {
scope['~criticalHit'] = { value: true };
@@ -189,9 +198,9 @@ function applyCrits(value, scope) {
return { criticalHit, criticalMiss };
}
async function spendResources(prop, actionContext) {
function spendResources(prop: Action, actionContext) {
// Check Uses
if (prop.usesLeft <= 0) {
if (!prop.usesLeft || prop.usesLeft <= 0) {
if (!prop.silent) actionContext.addLog({
name: 'Error',
value: `${prop.name || 'action'} does not have enough uses left`,
@@ -207,42 +216,45 @@ async function spendResources(prop, actionContext) {
return true;
}
// Items
let spendLog = [];
let gainLog = [];
const ammoToApply = [];
const spendLog: string[] = [];
const gainLog: string[] = [];
const ammoToApply: TreeNode<Ammo>[] = [];
try {
prop.resources.itemsConsumed.forEach(itemConsumed => {
recalculateCalculation(itemConsumed.quantity, actionContext);
if (!itemConsumed.itemId) {
throw 'No ammo was selected for this prop';
}
let item = CreatureProperties.findOne(itemConsumed.itemId);
if (!item || item.ancestors[0].id !== prop.ancestors[0].id) {
const item = CreatureProperties.findOne(itemConsumed.itemId) as Item;
if (!item || item.root.id !== prop.root.id) {
throw 'The prop\'s ammo was not found on the creature';
}
if (
!itemConsumed?.quantity?.value ||
!isFinite(itemConsumed.quantity.value)
!isFinite(+itemConsumed.quantity.value)
) return;
const quantityConsumed = +itemConsumed.quantity.value;
let logName = item.name;
if (itemConsumed.quantity.value > 1 || itemConsumed.quantity.value < -1) {
if (quantityConsumed > 1 || quantityConsumed < -1) {
logName = item.plural || logName;
}
if (itemConsumed.quantity.value > 0) {
spendLog.push(logName + ': ' + itemConsumed.quantity.value);
} else if (itemConsumed.quantity.value < 0) {
gainLog.push(logName + ': ' + -itemConsumed.quantity.value);
if (quantityConsumed > 0) {
spendLog.push(logName + ': ' + quantityConsumed);
} else if (quantityConsumed < 0) {
gainLog.push(logName + ': ' + -quantityConsumed);
}
// So long as the item isn't an ancestor of the current prop apply it
// If it was an ancestor this would be an infinite loop
if (!hasAncestorRelationship(item, prop)) {
ammoToApply.push({
node: {
doc: {
...item,
// Use ammo pseudo-type
type: 'ammo',
// Store the adjustment to be applied
adjustment: itemConsumed.quantity.value,
adjustment: quantityConsumed,
},
children: []
});
@@ -263,6 +275,7 @@ async function spendResources(prop, actionContext) {
CreatureProperties.update(prop._id, {
$inc: { usesUsed: 1 }
}, {
//@ts-expect-error no typings for collection 2 selector
selector: prop
});
if (!prop.silent) actionContext.addLog({
@@ -277,8 +290,9 @@ async function spendResources(prop, actionContext) {
recalculateCalculation(attConsumed.quantity, actionContext);
if (!attConsumed.quantity?.value) return;
const quantityConsumed = +attConsumed.quantity.value;
if (!attConsumed.variableName) return;
let stat = actionContext.scope[attConsumed.variableName];
const stat = actionContext.scope[attConsumed.variableName];
if (!stat) {
spendLog.push(attConsumed.variableName + ': ' + ' not found');
return;
@@ -289,10 +303,10 @@ async function spendResources(prop, actionContext) {
value: attConsumed.quantity.value,
actionContext,
});
if (attConsumed.quantity.value > 0) {
spendLog.push(stat.name + ': ' + attConsumed.quantity.value);
} else if (attConsumed.quantity.value < 0) {
gainLog.push(stat.name + ': ' + -attConsumed.quantity.value);
if (quantityConsumed > 0) {
spendLog.push(stat.name + ': ' + quantityConsumed);
} else if (quantityConsumed < 0) {
gainLog.push(stat.name + ': ' + -quantityConsumed);
}
});
@@ -313,20 +327,3 @@ async function spendResources(prop, actionContext) {
inline: true,
});
}
function hasAncestorRelationship(a, b) {
let top, bottom;
if (a.ancestors.length === b.ancestors.length) {
// Can't be ancestors of one another if they have the same number of ancestors
return false;
} else if (a.ancestors.length > b.ancestors.length) {
// longer ancestor list goes on the bottom
top = b;
bottom = a;
} else {
top = a;
bottom = b;
}
const expectedAncestorPosition = top.ancestors.length;
return bottom.ancestors[expectedAncestorPosition]?.id === top._id;
}

View File

@@ -1,11 +1,11 @@
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import recalculateCalculation from './shared/recalculateCalculation.js';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import recalculateCalculation from './shared/recalculateCalculation';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default function applyAdjustment(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
const damageTargets = prop.target === 'self' ? [actionContext.creature] : actionContext.targets;
if (!prop.amount) {

View File

@@ -1,15 +1,14 @@
import applyProperty from '../applyProperty.js';
import recalculateCalculation from './shared/recalculateCalculation.js';
import rollDice from '/imports/parser/rollDice.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import getUserInput from '/imports/api/engine/actions/getUserInput';
import applyProperty from '../applyProperty';
import recalculateCalculation from './shared/recalculateCalculation';
import rollDice from '/imports/parser/rollDice';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default async function applyBranch(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const scope = actionContext.scope;
const targets = actionContext.targets;
const prop = node.node;
const prop = node.doc
switch (prop.branchType) {
case 'if':
recalculateCalculation(prop.condition, actionContext);

View File

@@ -1,24 +1,22 @@
import {
setLineageOfDocs,
renewDocIds
} from '/imports/api/parenting/parenting.js';
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import computedSchemas from '/imports/api/properties/computedPropertySchemasIndex.js';
import applyFnToKey from '/imports/api/engine/computation/utility/applyFnToKey.js';
renewDocIds,
} from '/imports/api/parenting/parentingFunctions';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import computedSchemas from '/imports/api/properties/computedPropertySchemasIndex';
import applyFnToKey from '/imports/api/engine/computation/utility/applyFnToKey';
import { get } from 'lodash';
import resolve, { map, toString } from '/imports/parser/resolve.js';
import accessor from '/imports/parser/parseTree/accessor.js';
import logErrors from './shared/logErrors.js';
import { insertCreatureLog } from '/imports/api/creature/log/CreatureLogs.js';
import cyrb53 from '/imports/api/engine/computation/utility/cyrb53.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX.js';
import recalculateInlineCalculations from './shared/recalculateInlineCalculations.js';
import resolve, { map, toString } from '/imports/parser/resolve';
import accessor from '/imports/parser/parseTree/accessor';
import logErrors from './shared/logErrors';
import { insertCreatureLog } from '/imports/api/creature/log/CreatureLogs';
import cyrb53 from '/imports/api/engine/computation/utility/cyrb53';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX';
import recalculateInlineCalculations from './shared/recalculateInlineCalculations';
export default function applyBuff(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
let buffTargets = prop.target === 'self' ? [actionContext.creature] : actionContext.targets;
// Mark the buff as dirty for recalculation
@@ -26,7 +24,7 @@ export default function applyBuff(node, actionContext) {
// Then copy the descendants of the buff to the targets
let propList = [prop];
function addChildrenToPropList(children, { skipCrystalize } = {}) {
function addChildrenToPropList(children, { skipCrystalize } = { skipCrystalize: false }) {
children.forEach(child => {
if (skipCrystalize) child.node._skipCrystalize = true;
propList.push(child.node);
@@ -41,13 +39,20 @@ export default function applyBuff(node, actionContext) {
crystalizeVariables({ propList, actionContext });
}
let oldParent = {
id: prop.parent.id,
collection: prop.parent.collection,
};
buffTargets.forEach(target => {
const targetPropList = EJSON.clone(propList);
// Move the properties to the target by replacing the old subtree parent and root with the '
// target id
renewDocIds({
docArray: targetPropList,
idMap: {
[prop.parentId]: target._id,
[prop.root.id]: target._id,
},
collectionMap: { [prop.root.collection]: 'creatures' }
});
// Apply the buff
copyNodeListToTarget(propList, target, oldParent);
CreatureProperties.batchInsert(targetPropList);
//Log the buff
let logValue = prop.description?.value
@@ -82,23 +87,6 @@ export default function applyBuff(node, actionContext) {
// Don't apply the children of the buff, they get copied to the target instead
}
function copyNodeListToTarget(propList, target, oldParent) {
let ancestry = [{ collection: 'creatures', id: target._id }];
setLineageOfDocs({
docArray: propList,
newAncestry: ancestry,
oldParent,
});
renewDocIds({
docArray: propList,
});
setDocToLastOrder({
collection: CreatureProperties,
doc: propList[0],
});
CreatureProperties.batchInsert(propList);
}
/**
* Replaces all variables with their resolved values
* except variables of the form `~target.thing.total` become `thing.total`

View File

@@ -1,17 +1,17 @@
import { findLast, difference, intersection, filter } from 'lodash';
import applyProperty from '../applyProperty.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import { getProperyAncestors, getPropertiesOfType } from '/imports/api/engine/loadCreatures.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import { softRemove } from '/imports/api/parenting/softRemove.js';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import applyProperty from '../applyProperty';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import { getPropertyAncestors, getPropertiesOfType } from '/imports/api/engine/loadCreatures';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import { softRemove } from '/imports/api/parenting/softRemove';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
export default function applyBuffRemover(node, actionContext) {
// Apply triggers
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
// Log Name
if (prop.name && !prop.silent) {
@@ -21,7 +21,7 @@ export default function applyBuffRemover(node, actionContext) {
// Remove buffs
if (prop.targetParentBuff) {
// Remove nearest ancestor buff
const ancestors = getProperyAncestors(actionContext.creature._id, prop._id);
const ancestors = getPropertyAncestors(actionContext.creature._id, prop._id);
const nearestBuff = findLast(ancestors, ancestor => ancestor.type === 'buff');
if (!nearestBuff) {
actionContext.addLog({

View File

@@ -1,21 +1,21 @@
import { some, intersection, difference, remove, includes } from 'lodash';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { insertCreatureLog } from '/imports/api/creature/log/CreatureLogs.js';
import resolve, { Context, toString } from '/imports/parser/resolve.js';
import logErrors from './shared/logErrors.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation.js'
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { insertCreatureLog } from '/imports/api/creature/log/CreatureLogs';
import resolve, { Context, toString } from '/imports/parser/resolve';
import logErrors from './shared/logErrors';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation'
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
import {
getPropertiesOfType
} from '/imports/api/engine/loadCreatures.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags.js';
import applySavingThrow from '/imports/api/engine/actions/applyPropertyByType/applySavingThrow.js';
} from '/imports/api/engine/loadCreatures';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
import applySavingThrow from '/imports/api/engine/actions/applyPropertyByType/applySavingThrow';
export default function applyDamage(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
const scope = actionContext.scope;
// Skip if there is no parse node to work with
@@ -167,7 +167,7 @@ export default function applyDamage(node, actionContext) {
creatureId: target._id,
content: [{
name,
value: `Recieved **${damageDealt}** ${suffix}`,
value: `Received **${damageDealt}** ${suffix}`,
}],
}
});

View File

@@ -1,5 +1,5 @@
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default function applyFolder(node, actionContext) {
// Apply triggers

View File

@@ -1,14 +1,14 @@
import { getPropertyDecendants } from '/imports/api/engine/loadCreatures.js';
import applyProperty from '../applyProperty.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import { adjustQuantityWork } from '/imports/api/creature/creatureProperties/methods/adjustQuantity.js';
import { getPropertyDescendants } from '/imports/api/engine/loadCreatures';
import applyProperty from '../applyProperty';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import { docsToForest as nodeArrayToTree } from '/imports/api/parenting/parentingFunctions';
import { adjustQuantityWork } from '/imports/api/creature/creatureProperties/methods/adjustQuantity';
export default function applyItemAsAmmo(node, actionContext) {
// The item node should come without children, since it is not part of the original action tree
const prop = node.node;
const prop = node.doc
// Get all the item's descendant properties
const properties = getPropertyDecendants(actionContext.creature._id, prop._id);
const properties = getPropertyDescendants(actionContext.creature._id, prop._id);
properties.sort((a, b) => a.order - b.order);
const propertyForest = nodeArrayToTree(properties);

View File

@@ -1,10 +1,10 @@
import recalculateInlineCalculations from './shared/recalculateInlineCalculations.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import recalculateInlineCalculations from './shared/recalculateInlineCalculations';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default async function applyNote(node, actionContext) {
await applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
export default function applyNote(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.doc
// Log Name, summary
let content = { name: prop.name };

View File

@@ -1,12 +1,12 @@
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import logErrors from './shared/logErrors.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation.js';
import resolve, { toString } from '/imports/parser/resolve.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import logErrors from './shared/logErrors';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
import resolve, { toString } from '/imports/parser/resolve';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default function applyRoll(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
if (prop.roll?.calculation) {
const logValue = [];

View File

@@ -1,14 +1,14 @@
import rollDice from '/imports/parser/rollDice.js';
import recalculateCalculation from './shared/recalculateCalculation.js';
import applyProperty from '../applyProperty.js';
import numberToSignedString from '/imports/api/utility/numberToSignedString.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import { applyUnresolvedEffects } from '/imports/api/engine/actions/doCheck.js';
import rollDice from '/imports/parser/rollDice';
import recalculateCalculation from './shared/recalculateCalculation';
import applyProperty from '../applyProperty';
import numberToSignedString from '/imports/api/utility/numberToSignedString';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import { applyUnresolvedEffects } from '/imports/api/engine/actions/doCheck';
export default function applySavingThrow(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
const originalTargets = actionContext.targets;
let saveTargets = prop.target === 'self' ? [actionContext.creature] : actionContext.targets;

View File

@@ -1,10 +1,10 @@
import recalculateCalculation from './shared/recalculateCalculation.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren.js';
import recalculateCalculation from './shared/recalculateCalculation';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
export default function applyToggle(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.node;
const prop = node.doc
recalculateCalculation(prop.condition, actionContext);
if (prop.condition?.value) {
return applyChildren(node, actionContext);

View File

@@ -1,5 +1,5 @@
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import applyProperty from '/imports/api/engine/actions/applyProperty.js';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
import applyProperty from '/imports/api/engine/actions/applyProperty';
export default async function applyChildren(node, actionContext) {
applyNodeTriggers(node, 'after', actionContext);

View File

@@ -1,13 +1,12 @@
import logErrors from './logErrors.js';
import { Context, toPrimitiveOrString } from '/imports/parser/resolve.js';
import logErrors from './logErrors';
import { toPrimitiveOrString } from '/imports/parser/resolve';
import {
aggregateCalculationEffects,
aggregateCalculationProficiencies,
resolveCalculationNode,
} from '/imports/api/engine/computation/computeComputation/computeByType/computeCalculation.js';
} from '/imports/api/engine/computation/computeComputation/computeByType/computeCalculation';
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
import resolve from '/imports/parser/resolve.js';
import { getEffectiveActionScope } from '/imports/api/engine/actions/Actions';
import resolve from '/imports/parser/resolve';
// TODO move this whole file to Actions.ts
// Redo the work of imports/api/engine/computation/computeComputation/computeByType/computeCalculation.js

View File

@@ -1,7 +1,7 @@
import embedInlineCalculations from '/imports/api/engine/computation/utility/embedInlineCalculations.js';
import recalculateCalculation from './recalculateCalculation.js'
import embedInlineCalculations from '/imports/api/engine/computation/utility/embedInlineCalculations';
import recalculateCalculation from './recalculateCalculation'
export default function recalculateInlineCalculations(inlineCalcObj, action) {
export default function recalculateInlineCalculations(inlineCalcObj, actionContext) {
// Skip if there are no calculations
if (!inlineCalcObj?.inlineCalculations?.length) return;
// Recalculate each calculation with the current scope

View File

@@ -1,5 +1,5 @@
import { triggerMatchTags } from '/imports/api/engine/actions/applyTriggers.js';
import clean from '/imports/api/engine/computation/utility/cleanProp.testFn.js';
import { triggerMatchTags } from '/imports/api/engine/actions/applyTriggers';
import clean from '/imports/api/engine/computation/utility/cleanProp.testFn';
import { assert } from 'chai';
export default function () {

View File

@@ -1,13 +1,13 @@
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation.js';
import recalculateInlineCalculations from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateInlineCalculations.js';
import { getPropertyDecendants } from '/imports/api/engine/loadCreatures.js';
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import applyProperty from '/imports/api/engine/actions/applyProperty.js';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
import recalculateInlineCalculations from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateInlineCalculations';
import { getPropertyDescendants } from '/imports/api/engine/loadCreatures';
import { TreeNode, docsToForest as nodeArrayToTree } from '/imports/api/parenting/parentingFunctions';
import applyProperty from '/imports/api/engine/actions/applyProperty';
import { difference, intersection } from 'lodash';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags.js';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
export async function applyNodeTriggers(node, timing, actionContext) {
const prop = node.node;
export function applyNodeTriggers(node: TreeNode<any>, timing, actionContext) {
const prop = node.doc;
const type = prop.type;
const triggers = actionContext.triggers?.doActionProperty?.[type]?.[timing];
if (triggers) {
@@ -68,7 +68,7 @@ export async function applyTrigger(trigger, prop, actionContext) {
if (!trigger.silent) actionContext.addLog(content);
// Get all the trigger's properties and apply them
const properties = getPropertyDecendants(actionContext.creature._id, trigger._id);
const properties = getPropertyDescendants(actionContext.creature._id, trigger._id);
properties.sort((a, b) => a.order - b.order);
const propertyForest = nodeArrayToTree(properties);
for (const node of propertyForest) {

View File

@@ -1,15 +1,15 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
import { docsToForest } from '/imports/api/parenting/parentingFunctions';
import {
getProperyAncestors, getPropertyDecendants
} from '/imports/api/engine/loadCreatures.js';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import applyProperty from './applyProperty.js';
import ActionContext from '/imports/api/engine/actions/ActionContext.js';
getPropertyAncestors, getPropertyDescendants
} from '/imports/api/engine/loadCreatures';
import Creatures from '/imports/api/creature/creatures/Creatures';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import applyProperty from './applyProperty';
import ActionContext from '/imports/api/engine/actions/ActionContext';
const doAction = new ValidatedMethod({
name: 'creatureProperties.doAction',
@@ -47,10 +47,10 @@ const doAction = new ValidatedMethod({
async run({ actionId, targetIds = [], scope, invocationId }) {
console.log('do Action running');
// Get action context
let action = CreatureProperties.findOne(actionId);
const creatureId = action.ancestors[0].id;
const actionContext = new ActionContext(creatureId, targetIds, this, invocationId);
const action = CreatureProperties.findOne(actionId);
if (!action) throw new Meteor.Error('not-found', 'The action was not found');
const creatureId = action.root.id;
const actionContext = new ActionContext(creatureId, targetIds, this);
// Check permissions
assertEditPermission(actionContext.creature, this.userId);
@@ -58,10 +58,10 @@ const doAction = new ValidatedMethod({
assertEditPermission(target, this.userId);
});
const ancestors = getProperyAncestors(creatureId, action._id);
const ancestors = getPropertyAncestors(creatureId, action._id);
ancestors.sort((a, b) => a.order - b.order);
const properties = getPropertyDecendants(creatureId, action._id);
const properties = getPropertyDescendants(creatureId, action._id);
properties.push(action);
properties.sort((a, b) => a.order - b.order);
@@ -86,7 +86,7 @@ export async function doActionWork({
}) {
// get the docs
const ancestorScope = getAncestorScope(ancestors);
const propertyForest = nodeArrayToTree(properties);
const propertyForest = docsToForest(properties);
if (propertyForest.length !== 1) {
throw new Meteor.Error(`The action has ${propertyForest.length} top level properties, expected 1`);
}
@@ -106,7 +106,7 @@ export async function doActionWork({
// Assumes ancestors are in tree order already
function getAncestorScope(ancestors) {
let scope = {};
const scope = {};
ancestors.forEach(prop => {
scope[`#${prop.type}`] = prop;
});

View File

@@ -1,10 +1,10 @@
import '/imports/api/simpleSchemaConfig.js';
//import testTypes from './testTypes/index.js';
import applyTriggers from '/imports/api/engine/actions/applyTriggers.testFn.js';
import { doActionWork } from './doAction.js';
import { CreatureLogSchema } from '/imports/api/creature/log/CreatureLogs.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import '/imports/api/simpleSchemaConfig';
//import testTypes from './testTypes/index';
import applyTriggers from '/imports/api/engine/actions/applyTriggers.testFn';
import { doActionWork } from './doAction';
import { CreatureLogSchema } from '/imports/api/creature/log/CreatureLogs';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import Creatures from '/imports/api/creature/creatures/Creatures';
function cleanProp(prop) {
let schema = CreatureProperties.simpleSchema(prop);

View File

@@ -1,15 +1,15 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import Creatures from '/imports/api/creature/creatures/Creatures';
import {
getProperyAncestors, getPropertyDecendants
} from '/imports/api/engine/loadCreatures.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
import { doActionWork } from '/imports/api/engine/actions/doAction.js';
import ActionContext from '/imports/api/engine/actions/ActionContext.js';
getPropertyAncestors, getPropertyDescendants
} from '/imports/api/engine/loadCreatures';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
import { doActionWork } from '/imports/api/engine/actions/doAction';
import ActionContext from '/imports/api/engine/actions/ActionContext';
const doAction = new ValidatedMethod({
name: 'creatureProperties.doCastSpell',
@@ -48,7 +48,7 @@ const doAction = new ValidatedMethod({
run({ spellId, slotId, ritual, targetIds = [], scope = {} }) {
// Get action context
let spell = CreatureProperties.findOne(spellId);
const creatureId = spell.ancestors[0].id;
const creatureId = spell.root.id;
const actionContext = new ActionContext(creatureId, targetIds, this);
// Check permissions
@@ -57,10 +57,10 @@ const doAction = new ValidatedMethod({
assertEditPermission(target, this.userId);
});
const ancestors = getProperyAncestors(creatureId, spell._id);
const ancestors = getPropertyAncestors(creatureId, spell._id);
ancestors.sort((a, b) => a.order - b.order);
const properties = getPropertyDecendants(creatureId, spell._id);
const properties = getPropertyDescendants(creatureId, spell._id);
properties.push(spell);
properties.sort((a, b) => a.order - b.order);

View File

@@ -1,12 +1,12 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
import rollDice from '/imports/parser/rollDice.js';
import numberToSignedString from '/imports/api/utility/numberToSignedString.js';
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers.js';
import ActionContext from '/imports/api/engine/actions/ActionContext.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
import rollDice from '/imports/parser/rollDice';
import numberToSignedString from '/imports/api/utility/numberToSignedString';
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers';
import ActionContext from '/imports/api/engine/actions/ActionContext';
import recalculateCalculation from '/imports/api/engine/actions/applyPropertyByType/shared/recalculateCalculation';
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
@@ -26,7 +26,8 @@ const doCheck = new ValidatedMethod({
},
run({ propId, scope }) {
const prop = CreatureProperties.findOne(propId);
const creatureId = prop.ancestors[0].id;
if (!prop) throw new Meteor.Error('not-found', 'The property was not found');
const creatureId = prop.root.id;
const actionContext = new ActionContext(creatureId, [creatureId], this);
Object.assign(actionContext.scope, scope);
actionContext.scope[`#${prop.type}`] = prop;

View File

@@ -1,2 +1,2 @@
import './doCastSpell.js';
import './doCheck.js';
import './doCastSpell';
import './doCheck';