fixed: Show only the last event with a var name
This commit is contained in:
@@ -23,23 +23,26 @@ const linkDependenciesByType = {
|
||||
toggle: linkToggle,
|
||||
}
|
||||
|
||||
export default function linkTypeDependencies(dependencyGraph, prop, computation){
|
||||
export default function linkTypeDependencies(dependencyGraph, prop, computation) {
|
||||
linkDependenciesByType[prop.type]?.(dependencyGraph, prop, computation);
|
||||
}
|
||||
|
||||
function dependOnCalc({dependencyGraph, prop, key}){
|
||||
function dependOnCalc({ dependencyGraph, prop, key }) {
|
||||
let calc = get(prop, key);
|
||||
if (!calc) return;
|
||||
if (calc.type !== '_calculation'){
|
||||
if (calc.type !== '_calculation') {
|
||||
throw `Expected calculation got ${calc.type}`
|
||||
}
|
||||
dependencyGraph.addLink(prop._id, `${prop._id}.${key}`, 'calculation');
|
||||
}
|
||||
|
||||
function linkAction(dependencyGraph, prop, {propsById}){
|
||||
function linkAction(dependencyGraph, prop, { propsById }) {
|
||||
if (prop.variableName) {
|
||||
dependencyGraph.addLink(prop.variableName, prop._id, 'eventDefinition');
|
||||
}
|
||||
// The action depends on its attack roll and uses calculations
|
||||
dependOnCalc({dependencyGraph, prop, key: 'attackRoll'});
|
||||
dependOnCalc({dependencyGraph, prop, key: 'uses'});
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'attackRoll' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'uses' });
|
||||
|
||||
// Link the resources the action uses
|
||||
if (!prop.resources) return;
|
||||
@@ -47,7 +50,7 @@ function linkAction(dependencyGraph, prop, {propsById}){
|
||||
prop.resources.itemsConsumed.forEach((itemConsumed, index) => {
|
||||
if (!itemConsumed.itemId) return;
|
||||
const item = propsById[itemConsumed.itemId];
|
||||
if (!item || item.inactive){
|
||||
if (!item || item.inactive) {
|
||||
// Unlink if the item doesn't exist or is inactive
|
||||
itemConsumed.itemId = undefined;
|
||||
return;
|
||||
@@ -79,48 +82,48 @@ function linkAction(dependencyGraph, prop, {propsById}){
|
||||
});
|
||||
}
|
||||
|
||||
function linkAdjustment(dependencyGraph, prop){
|
||||
function linkAdjustment(dependencyGraph, prop) {
|
||||
// Adjustment depends on its amount
|
||||
dependOnCalc({dependencyGraph, prop, key: 'amount'});
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'amount' });
|
||||
}
|
||||
|
||||
function linkAttribute(dependencyGraph, prop){
|
||||
function linkAttribute(dependencyGraph, prop) {
|
||||
linkVariableName(dependencyGraph, prop);
|
||||
// Depends on spellSlotLevel
|
||||
dependOnCalc({dependencyGraph, prop, key: 'spellSlotLevel'});
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'spellSlotLevel' });
|
||||
|
||||
// Depends on base value
|
||||
dependOnCalc({dependencyGraph, prop, key: 'baseValue'});
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'baseValue' });
|
||||
|
||||
// hit dice depend on constitution
|
||||
if (prop.attributeType === 'hitDice'){
|
||||
if (prop.attributeType === 'hitDice') {
|
||||
dependencyGraph.addLink(prop._id, 'constitution', 'hitDiceConMod');
|
||||
}
|
||||
}
|
||||
|
||||
function linkBranch(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'condition'});
|
||||
function linkBranch(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'condition' });
|
||||
}
|
||||
|
||||
function linkBuff(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'duration'});
|
||||
function linkBuff(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'duration' });
|
||||
}
|
||||
|
||||
function linkClassLevel(dependencyGraph, prop) {
|
||||
if (prop.inactive) return;
|
||||
// The variableName of the prop depends on the prop
|
||||
if (prop.variableName && prop.level){
|
||||
if (prop.variableName && prop.level) {
|
||||
dependencyGraph.addLink(prop.variableName, prop._id, 'classLevel');
|
||||
// The level variable depends on the class variableName variable
|
||||
let existingLevelLink = dependencyGraph.getLink('level', prop.variableName);
|
||||
if (!existingLevelLink){
|
||||
if (!existingLevelLink) {
|
||||
dependencyGraph.addLink('level', prop.variableName, 'level');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function linkDamage(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'amount'});
|
||||
function linkDamage(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'amount' });
|
||||
}
|
||||
|
||||
function linkEffects(dependencyGraph, prop, computation) {
|
||||
@@ -132,7 +135,7 @@ function linkEffects(dependencyGraph, prop, computation) {
|
||||
if (prop.inactive) {
|
||||
// Inactive effects apply to no stats
|
||||
return;
|
||||
} else if (prop.targetByTags){
|
||||
} else if (prop.targetByTags) {
|
||||
getEffectTagTargets(prop, computation).forEach(targetId => {
|
||||
const targetProp = computation.propsById[targetId];
|
||||
if (
|
||||
@@ -147,8 +150,8 @@ function linkEffects(dependencyGraph, prop, computation) {
|
||||
// Otherwise target a field on that property
|
||||
const key = prop.targetField || getDefaultCalculationField(targetProp);
|
||||
const calcObj = get(targetProp, key);
|
||||
if (calcObj && calcObj.calculation){
|
||||
dependencyGraph.addLink(`${targetProp._id}.${key}`, prop._id , 'effect');
|
||||
if (calcObj && calcObj.calculation) {
|
||||
dependencyGraph.addLink(`${targetProp._id}.${key}`, prop._id, 'effect');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -161,14 +164,14 @@ function linkEffects(dependencyGraph, prop, computation) {
|
||||
}
|
||||
|
||||
// Returns an array of IDs of the properties the effect targets
|
||||
function getEffectTagTargets(effect, computation){
|
||||
function getEffectTagTargets(effect, computation) {
|
||||
let targets = getTargetListFromTags(effect.targetTags, computation);
|
||||
let notIds = [];
|
||||
if (effect.extraTags){
|
||||
if (effect.extraTags) {
|
||||
effect.extraTags.forEach(ex => {
|
||||
if (ex.operation === 'OR') {
|
||||
targets = union(targets, getTargetListFromTags(ex.tags, computation));
|
||||
} else if (ex.operation === 'NOT'){
|
||||
} else if (ex.operation === 'NOT') {
|
||||
ex.tags.forEach(tag => {
|
||||
const idList = computation.propsWithTag[tag];
|
||||
if (idList) {
|
||||
@@ -181,7 +184,7 @@ function getEffectTagTargets(effect, computation){
|
||||
return difference(targets, notIds);
|
||||
}
|
||||
|
||||
function getTargetListFromTags(tags, computation){
|
||||
function getTargetListFromTags(tags, computation) {
|
||||
const targetTagIdLists = [];
|
||||
if (!tags) return [];
|
||||
tags.forEach(tag => {
|
||||
@@ -192,8 +195,8 @@ function getTargetListFromTags(tags, computation){
|
||||
return targets;
|
||||
}
|
||||
|
||||
function getDefaultCalculationField(prop){
|
||||
switch (prop.type){
|
||||
function getDefaultCalculationField(prop) {
|
||||
switch (prop.type) {
|
||||
case 'action': return 'attackRoll';
|
||||
case 'adjustment': return 'amount';
|
||||
case 'attribute': return 'baseValue';
|
||||
@@ -223,13 +226,13 @@ function getDefaultCalculationField(prop){
|
||||
}
|
||||
}
|
||||
|
||||
function linkRoll(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'roll'});
|
||||
function linkRoll(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'roll' });
|
||||
}
|
||||
|
||||
function linkVariableName(dependencyGraph, prop){
|
||||
function linkVariableName(dependencyGraph, prop) {
|
||||
// The variableName of the prop depends on the prop if the prop is active
|
||||
if (prop.variableName && !prop.inactive){
|
||||
if (prop.variableName && !prop.inactive) {
|
||||
dependencyGraph.addLink(prop.variableName, prop._id, 'definition');
|
||||
}
|
||||
}
|
||||
@@ -243,7 +246,7 @@ function linkDamageMultiplier(dependencyGraph, prop) {
|
||||
});
|
||||
}
|
||||
|
||||
function linkPointBuy(dependencyGraph, prop){
|
||||
function linkPointBuy(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'min' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'max' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'cost' });
|
||||
@@ -265,7 +268,7 @@ function linkPointBuy(dependencyGraph, prop){
|
||||
if (prop.inactive) return;
|
||||
}
|
||||
|
||||
function linkProficiencies(dependencyGraph, prop){
|
||||
function linkProficiencies(dependencyGraph, prop) {
|
||||
// The stats depend on the proficiency
|
||||
if (prop.inactive) return;
|
||||
prop.stats.forEach(statName => {
|
||||
@@ -274,36 +277,36 @@ function linkProficiencies(dependencyGraph, prop){
|
||||
});
|
||||
}
|
||||
|
||||
function linkSavingThrow(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'dc'});
|
||||
function linkSavingThrow(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'dc' });
|
||||
}
|
||||
|
||||
function linkSkill(dependencyGraph, prop){
|
||||
function linkSkill(dependencyGraph, prop) {
|
||||
// Depends on base value
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'baseValue' });
|
||||
// Link dependents
|
||||
if (prop.inactive) return;
|
||||
linkVariableName(dependencyGraph, prop);
|
||||
// The prop depends on the variable references as the ability
|
||||
if (prop.ability){
|
||||
if (prop.ability) {
|
||||
dependencyGraph.addLink(prop._id, prop.ability, 'skillAbilityScore');
|
||||
}
|
||||
// Skills depend on the creature's proficiencyBonus
|
||||
dependencyGraph.addLink(prop._id, 'proficiencyBonus', 'skillProficiencyBonus');
|
||||
}
|
||||
|
||||
function linkSlot(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'quantityExpected'});
|
||||
dependOnCalc({dependencyGraph, prop, key: 'slotCondition'});
|
||||
function linkSlot(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'quantityExpected' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'slotCondition' });
|
||||
}
|
||||
|
||||
function linkSpellList(dependencyGraph, prop){
|
||||
dependOnCalc({dependencyGraph, prop, key: 'maxPrepared'});
|
||||
dependOnCalc({dependencyGraph, prop, key: 'attackRollBonus'});
|
||||
dependOnCalc({dependencyGraph, prop, key: 'dc'});
|
||||
function linkSpellList(dependencyGraph, prop) {
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'maxPrepared' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'attackRollBonus' });
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'dc' });
|
||||
}
|
||||
|
||||
function linkToggle(dependencyGraph, prop){
|
||||
function linkToggle(dependencyGraph, prop) {
|
||||
linkVariableName(dependencyGraph, prop);
|
||||
dependOnCalc({dependencyGraph, prop, key: 'condition'});
|
||||
dependOnCalc({ dependencyGraph, prop, key: 'condition' });
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export default function computeAction(computation, node){
|
||||
export default function computeAction(computation, node) {
|
||||
const prop = node.data;
|
||||
if (prop.uses){
|
||||
if (prop.uses) {
|
||||
prop.usesLeft = prop.uses.value - (prop.usesUsed || 0);
|
||||
if (!prop.usesLeft){
|
||||
if (!prop.usesLeft) {
|
||||
prop.insufficientResources = true;
|
||||
}
|
||||
}
|
||||
@@ -10,19 +10,19 @@ export default function computeAction(computation, node){
|
||||
if (!prop.resources) return;
|
||||
prop.resources.itemsConsumed.forEach(itemConsumed => {
|
||||
if (!itemConsumed.itemId) return;
|
||||
if (itemConsumed.available < itemConsumed.quantity?.value){
|
||||
if (itemConsumed.available < itemConsumed.quantity?.value) {
|
||||
prop.insufficientResources = true;
|
||||
}
|
||||
});
|
||||
prop.resources.attributesConsumed.forEach(attConsumed => {
|
||||
if (!attConsumed.variableName) return;
|
||||
if (attConsumed.available < attConsumed.quantity?.value){
|
||||
if (attConsumed.available < attConsumed.quantity?.value) {
|
||||
prop.insufficientResources = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function computeResources(computation, node){
|
||||
function computeResources(computation, node) {
|
||||
const resources = node.data?.resources;
|
||||
if (!resources) return;
|
||||
resources.attributesConsumed.forEach(attConsumed => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import computeVariableAsToggle from './computeVariable/computeVariableAsToggle.j
|
||||
import computeImplicitVariable from './computeVariable/computeImplicitVariable.js';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
|
||||
export default function computeVariable(computation, node){
|
||||
export default function computeVariable(computation, node) {
|
||||
const scope = computation.scope;
|
||||
if (!node.data) node.data = {};
|
||||
aggregateLinks(computation, node);
|
||||
@@ -15,7 +15,7 @@ export default function computeVariable(computation, node){
|
||||
// Don't add to the scope if the node id is not a legitimate variable name
|
||||
// Without this `some.thing` could break the entire sheet as a database key
|
||||
if (!VARIABLE_NAME_REGEX.test(node.id)) return;
|
||||
if (node.data.definingProp){
|
||||
if (node.data.definingProp) {
|
||||
// Add the defining variable to the scope
|
||||
scope[node.id] = node.data.definingProp
|
||||
} else {
|
||||
@@ -24,7 +24,7 @@ export default function computeVariable(computation, node){
|
||||
}
|
||||
}
|
||||
|
||||
function aggregateLinks(computation, node){
|
||||
function aggregateLinks(computation, node) {
|
||||
computation.dependencyGraph.forEachLinkedNode(
|
||||
node.id,
|
||||
(linkedNode, link) => {
|
||||
@@ -32,11 +32,12 @@ function aggregateLinks(computation, node){
|
||||
// Ignore inactive props
|
||||
if (linkedNode.data.inactive) return;
|
||||
// Apply all the aggregations
|
||||
let arg = {node, linkedNode, link, computation};
|
||||
let arg = { node, linkedNode, link, computation };
|
||||
aggregate.classLevel(arg);
|
||||
aggregate.damageMultiplier(arg);
|
||||
aggregate.definition(arg);
|
||||
aggregate.effect(arg);
|
||||
aggregate.eventDefinition(arg);
|
||||
aggregate.inventory(arg);
|
||||
aggregate.proficiency(arg);
|
||||
},
|
||||
@@ -44,7 +45,7 @@ function aggregateLinks(computation, node){
|
||||
);
|
||||
}
|
||||
|
||||
function combineAggregations(computation, node){
|
||||
function combineAggregations(computation, node) {
|
||||
combineMultiplierAggregator(node);
|
||||
node.data.overridenProps?.forEach(prop => {
|
||||
computeVariableProp(computation, node, prop);
|
||||
@@ -52,51 +53,51 @@ function combineAggregations(computation, node){
|
||||
computeVariableProp(computation, node, node.data.definingProp);
|
||||
}
|
||||
|
||||
function computeVariableProp(computation, node, prop){
|
||||
function computeVariableProp(computation, node, prop) {
|
||||
if (!prop) return;
|
||||
|
||||
// Combine damage multipliers in all props so that they can't be overridden
|
||||
if (node.data.immunity){
|
||||
if (node.data.immunity) {
|
||||
prop.immunity = node.data.immunity;
|
||||
prop.immunities = node.data.immunities;
|
||||
}
|
||||
if (node.data.resistance){
|
||||
if (node.data.resistance) {
|
||||
prop.resistance = node.data.resistance;
|
||||
prop.resistances = node.data.resistances;
|
||||
}
|
||||
if (node.data.vulnerability){
|
||||
if (node.data.vulnerability) {
|
||||
prop.vulnerability = node.data.vulnerability;
|
||||
prop.vulnerabilities = node.data.vulnerabilities;
|
||||
}
|
||||
|
||||
if (prop.type === 'attribute'){
|
||||
if (prop.type === 'attribute') {
|
||||
computeVariableAsAttribute(computation, node, prop);
|
||||
} else if (prop.type === 'skill'){
|
||||
} else if (prop.type === 'skill') {
|
||||
computeVariableAsSkill(computation, node, prop);
|
||||
} else if (prop.type === 'constant'){
|
||||
} else if (prop.type === 'constant') {
|
||||
computeVariableAsConstant(computation, node, prop);
|
||||
} else if (prop.type === 'class'){
|
||||
} else if (prop.type === 'class') {
|
||||
computeVariableAsClass(computation, node, prop);
|
||||
} else if (prop.type === 'toggle'){
|
||||
} else if (prop.type === 'toggle') {
|
||||
computeVariableAsToggle(computation, node, prop);
|
||||
}
|
||||
}
|
||||
|
||||
function combineMultiplierAggregator(node){
|
||||
function combineMultiplierAggregator(node) {
|
||||
// get a reference to the aggregator
|
||||
const aggregator = node.data.multiplierAggregator;
|
||||
if (!aggregator) return;
|
||||
|
||||
// Combine
|
||||
if (aggregator.immunities?.length){
|
||||
if (aggregator.immunities?.length) {
|
||||
node.data.immunity = true;
|
||||
node.data.immunities = aggregator.immunities;
|
||||
}
|
||||
if (aggregator.resistances?.length){
|
||||
if (aggregator.resistances?.length) {
|
||||
node.data.resistance = true;
|
||||
node.data.resistances = aggregator.resistances;
|
||||
}
|
||||
if (aggregator.vulnerabilities?.length){
|
||||
if (aggregator.vulnerabilities?.length) {
|
||||
node.data.vulnerability = true;
|
||||
node.data.vulnerabilities = aggregator.vulnerabilities;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
export default function aggregateEventDefinition({ node, linkedNode, link }) {
|
||||
// Look at all event definition links
|
||||
if (link.data !== 'eventDefinition') return;
|
||||
|
||||
// Store which property is THE defining event and which are overridden
|
||||
const prop = linkedNode.data;
|
||||
// get current defining event
|
||||
const definingEvent = node.data.definingEvent;
|
||||
// Find the last defining event
|
||||
if (
|
||||
!definingEvent ||
|
||||
prop.order > definingEvent.order
|
||||
) {
|
||||
// override the current defining prop
|
||||
if (definingEvent) definingEvent.overridden = true;
|
||||
// set this prop as the new defining prop
|
||||
node.data.definingEvent = prop;
|
||||
} else {
|
||||
prop.overridden = true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import definition from './aggregateDefinition.js';
|
||||
import damageMultiplier from './aggregateDamageMultiplier.js';
|
||||
import effect from './aggregateEffect.js';
|
||||
import eventDefinition from './aggregateEventDefinition.js';
|
||||
import proficiency from './aggregateProficiency.js';
|
||||
import classLevel from './aggregateClassLevel.js';
|
||||
import inventory from './aggregateInventory.js';
|
||||
@@ -10,6 +11,7 @@ export default Object.freeze({
|
||||
damageMultiplier,
|
||||
definition,
|
||||
effect,
|
||||
eventDefinition,
|
||||
inventory,
|
||||
proficiency,
|
||||
});
|
||||
|
||||
@@ -162,6 +162,12 @@ const ComputedOnlyActionSchema = createPropertySchema({
|
||||
optional: true,
|
||||
removeBeforeCompute: true,
|
||||
},
|
||||
// Denormalised tag if event is overridden by one with the same variable name
|
||||
overridden: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
removeBeforeCompute: true,
|
||||
},
|
||||
// Resources
|
||||
resources: {
|
||||
type: Object,
|
||||
|
||||
@@ -461,7 +461,7 @@ const propertyHandlers = {
|
||||
return { propPath: 'toggle' };
|
||||
},
|
||||
action(prop) {
|
||||
if (prop.actionType === 'event') {
|
||||
if (prop.actionType === 'event' && !prop.overridden) {
|
||||
return { propPath: 'event' };
|
||||
}
|
||||
return { propPath: null };
|
||||
|
||||
Reference in New Issue
Block a user