Overhauled computations to allow for toggles :'( that sucked
This commit is contained in:
@@ -1,22 +1,45 @@
|
||||
import { includes, cloneDeep, has } from 'lodash';
|
||||
import { includes, cloneDeep } from 'lodash';
|
||||
|
||||
// The computation memo is an in-memory data structure used only during the
|
||||
// computation process
|
||||
export default class ComputationMemo {
|
||||
constructor(props){
|
||||
this.statsByVariableName = {};
|
||||
this.extraStatsByVariableName = {};
|
||||
this.statsById = {};
|
||||
this.originalPropsById = {};
|
||||
this.propsById = {};
|
||||
this.skillsByAbility = {};
|
||||
this.unassignedEffects = [];
|
||||
this.classes = {};
|
||||
props.filter((prop) => {
|
||||
// skip effects, proficiencies, and class levels for the next pass
|
||||
this.classLevelsById = {};
|
||||
this.togglesById = {};
|
||||
this.toggleIds = new Set();
|
||||
// First note all the ids of all the toggles
|
||||
props.forEach((prop) => {
|
||||
if (
|
||||
prop.type === 'effect' ||
|
||||
prop.type === 'proficiency' ||
|
||||
prop.type === 'classLevel'
|
||||
) return true;
|
||||
// Add all the stats
|
||||
this.addStat(prop);
|
||||
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 {
|
||||
return true;
|
||||
}
|
||||
}).forEach((prop) => {
|
||||
// Now add all effects and proficiencies
|
||||
if (prop.type === 'effect'){
|
||||
@@ -32,8 +55,14 @@ export default class ComputationMemo {
|
||||
this.originalPropsById[prop._id] = cloneDeep(prop);
|
||||
this.propsById[prop._id] = prop;
|
||||
prop.computationDetails = propDetails(prop);
|
||||
prop.ancestors.forEach(ancestor => {
|
||||
if (this.toggleIds.has(ancestor.id)){
|
||||
prop.computationDetails.toggleAncestors.push(ancestor.id);
|
||||
}
|
||||
});
|
||||
return prop;
|
||||
}
|
||||
/*
|
||||
storeHighestClassLevel(name, prop, isBaseClass){
|
||||
// Only store the highest level classLevel
|
||||
let stat = this.statsByVariableName[name]
|
||||
@@ -72,33 +101,51 @@ export default class ComputationMemo {
|
||||
level += this.classes[name].level || 0;
|
||||
}
|
||||
this.statsByVariableName['level'].value = level;
|
||||
}*/
|
||||
addToggle(prop){
|
||||
prop = this.registerProperty(prop);
|
||||
this.togglesById[prop._id] = prop;
|
||||
}
|
||||
addClassLevel(prop){
|
||||
prop = this.registerProperty(prop);
|
||||
if (prop.variableName){
|
||||
this.storeHighestClassLevel(prop.variableName, prop);
|
||||
}
|
||||
if (prop.baseClass){
|
||||
this.storeHighestClassLevel(prop.baseClass, prop, true);
|
||||
}
|
||||
this.classLevelsById[prop._id] = prop;
|
||||
}
|
||||
addStat(prop){
|
||||
prop = this.registerProperty(prop);
|
||||
let variableName = prop.variableName;
|
||||
if (!variableName) return;
|
||||
if (this.statsByVariableName[variableName]){
|
||||
prop.value = NaN;
|
||||
prop.computationDetails.error = 'variableNameCollision';
|
||||
if (Meteor.isClient) console.warn('variableNameCollision', prop);
|
||||
return;
|
||||
}
|
||||
this.statsByVariableName[variableName] = prop;
|
||||
if (
|
||||
prop.type === 'skill' &&
|
||||
isSkillCheck(prop) &&
|
||||
prop.ability
|
||||
){
|
||||
this.addSkillToAbility(prop, prop.ability)
|
||||
let existingStat = this.statsByVariableName[variableName];
|
||||
if (existingStat){
|
||||
existingStat.computationDetails.idsOfSameName.push(prop._id);
|
||||
this.originalPropsById[prop._id] = cloneDeep(prop);
|
||||
if (prop.baseValueCalculation){
|
||||
existingStat.computationDetails.effects.push({
|
||||
operation: 'base',
|
||||
calculation: prop.baseValueCalculation,
|
||||
stats: [variableName],
|
||||
computationDetails: propDetailsByType.effect(),
|
||||
statBase: true,
|
||||
});
|
||||
}
|
||||
if (prop.baseProficiency){
|
||||
existingStat.computationDetails.proficiencies.push({
|
||||
value: prop.baseProficiency,
|
||||
stats: [variableName],
|
||||
computationDetails: propDetailsByType.proficiency(),
|
||||
type: 'proficiency',
|
||||
statBase: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
prop = this.registerProperty(prop);
|
||||
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){
|
||||
@@ -152,9 +199,14 @@ export default class ComputationMemo {
|
||||
let target = this.statsByVariableName[statName];
|
||||
if (!target) return;
|
||||
targets.add(target);
|
||||
if (isAbility(target) && isSkillCheck(prop)) {
|
||||
if (isAbility(target)) {
|
||||
let extras = this.skillsByAbility[statName] || [];
|
||||
targets.add(...extras)
|
||||
extras.forEach(ex =>{
|
||||
// Only pass on ability proficiencies to skills and checks
|
||||
if (ex.skillType === 'skill' || ex.skillType === 'check'){
|
||||
targets.add(ex)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return targets;
|
||||
@@ -188,11 +240,22 @@ function propDetails(prop){
|
||||
}
|
||||
|
||||
const propDetailsByType = {
|
||||
toggle(){
|
||||
return {
|
||||
computed: false,
|
||||
busyComputing: false,
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
};
|
||||
},
|
||||
attribute(){
|
||||
return {
|
||||
computed: false,
|
||||
busyComputing: false,
|
||||
effects: [],
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
idsOfSameName: [],
|
||||
};
|
||||
},
|
||||
skill(){
|
||||
@@ -201,19 +264,30 @@ const propDetailsByType = {
|
||||
busyComputing: false,
|
||||
effects: [],
|
||||
proficiencies: [],
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
idsOfSameName: [],
|
||||
};
|
||||
},
|
||||
effect(){
|
||||
return {
|
||||
computed: false,
|
||||
busyComputing: false,
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
};
|
||||
},
|
||||
classLevel(){
|
||||
return {
|
||||
computed: true,
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
};
|
||||
},
|
||||
proficiency(){
|
||||
return {};
|
||||
return {
|
||||
toggleAncestors: [],
|
||||
disabledByToggle: false,
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ export default class EffectAggregator{
|
||||
case 'base':
|
||||
// Take the largest base value
|
||||
this.base = result > this.base ? result : this.base;
|
||||
if (effect.statBase){
|
||||
this.statBaseValue = result > this.statBaseValue ? result : this.statBaseValue;
|
||||
}
|
||||
break;
|
||||
case 'add':
|
||||
// Add all adds together
|
||||
|
||||
11
app/imports/api/creature/computation/applyToggles.js
Normal file
11
app/imports/api/creature/computation/applyToggles.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import computeToggle from '/imports/api/creature/computation/computeToggle.js';
|
||||
|
||||
export default function applyToggles(prop, memo){
|
||||
prop.computationDetails.toggleAncestors.forEach(toggleId => {
|
||||
let toggle = memo.togglesById[toggleId];
|
||||
computeToggle(toggle, memo);
|
||||
if (!toggle.toggleResult){
|
||||
prop.computationDetails.disabledByToggle = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import computeStat from '/imports/api/creature/computation/computeStat.js';
|
||||
|
||||
import applyToggles from '/imports/api/creature/computation/applyToggles.js';
|
||||
|
||||
export default function combineStat(stat, aggregator, memo){
|
||||
if (stat.type === 'attribute'){
|
||||
@@ -37,7 +37,13 @@ function combineSkill(stat, aggregator, memo){
|
||||
stat.proficiency = stat.baseProficiency || 0;
|
||||
for (let i in stat.computationDetails.proficiencies){
|
||||
let prof = stat.computationDetails.proficiencies[i];
|
||||
if (prof.value > stat.proficiency) stat.proficiency = prof.value;
|
||||
applyToggles(prof, memo);
|
||||
if (
|
||||
!prof.computationDetails.disabledByToggle &&
|
||||
prof.value > stat.proficiency
|
||||
){
|
||||
stat.proficiency = prof.value;
|
||||
}
|
||||
}
|
||||
// Get the character's proficiency bonus to apply
|
||||
let profBonusStat = memo.statsByVariableName['proficiencyBonus'];
|
||||
|
||||
@@ -1,7 +1,25 @@
|
||||
import evaluateCalculation from '/imports/api/creature/computation/evaluateCalculation.js';
|
||||
import applyToggles from '/imports/api/creature/computation/applyToggles.js';
|
||||
|
||||
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
|
||||
if (!effect.calculation){
|
||||
if(effect.operation === 'add' || effect.operation === 'base'){
|
||||
effect.result = 0;
|
||||
@@ -16,4 +34,5 @@ export default function computeEffect(effect, memo){
|
||||
effect.result = evaluateCalculation(effect.calculation, memo);
|
||||
}
|
||||
effect.computationDetails.computed = true;
|
||||
effect.computationDetails.busyComputing = false;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { each, forOwn } from 'lodash';
|
||||
import computeStat from '/imports/api/creature/computation/computeStat.js';
|
||||
import computeEffect from '/imports/api/creature/computation/computeEffect.js';
|
||||
import computeToggle from '/imports/api/creature/computation/computeToggle.js';
|
||||
|
||||
export default function computeMemo(memo){
|
||||
forOwn(memo.statsByVariableName, (stat) => {
|
||||
// Compute all stats, even if they are overriden
|
||||
forOwn(memo.statsById, stat => {
|
||||
computeStat (stat, memo);
|
||||
});
|
||||
each(memo.unassignedEffects, (effect) => {
|
||||
// Compute effects which didn't end up targeting a stat
|
||||
each(memo.unassignedEffects, effect => {
|
||||
computeEffect(effect, memo);
|
||||
});
|
||||
forOwn(memo.togglesById, toggle => {
|
||||
computeToggle(toggle, memo);
|
||||
});
|
||||
// Compute class levels
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import combineStat from '/imports/api/creature/computation/combineStat.js';
|
||||
import computeEffect from '/imports/api/creature/computation/computeEffect.js';
|
||||
import EffectAggregator from '/imports/api/creature/computation/EffectAggregator.js';
|
||||
import applyToggles from '/imports/api/creature/computation/applyToggles.js';
|
||||
import { each } from 'lodash';
|
||||
|
||||
export default function computeStat(stat, memo){
|
||||
@@ -18,14 +19,21 @@ export default function computeStat(stat, memo){
|
||||
}
|
||||
// Before doing any work, mark this stat as busy
|
||||
stat.computationDetails.busyComputing = true;
|
||||
// Compute and aggregate all the effects
|
||||
let aggregator = new EffectAggregator(stat, memo)
|
||||
each(stat.computationDetails.effects, (effect) => {
|
||||
computeEffect(effect, memo);
|
||||
aggregator.addEffect(effect);
|
||||
});
|
||||
// Conglomerate all the effects to compute the final stat values
|
||||
combineStat(stat, aggregator, memo);
|
||||
// Apply any toggles
|
||||
applyToggles(stat, memo);
|
||||
|
||||
if (!stat.computationDetails.disabledByToggle){
|
||||
// Compute and aggregate all the effects
|
||||
let aggregator = new EffectAggregator(stat, memo)
|
||||
each(stat.computationDetails.effects, (effect) => {
|
||||
computeEffect(effect, memo);
|
||||
if (!effect.computationDetails.disabledByToggle){
|
||||
aggregator.addEffect(effect);
|
||||
}
|
||||
});
|
||||
// Conglomerate all the effects to compute the final stat values
|
||||
combineStat(stat, aggregator, memo);
|
||||
}
|
||||
// Mark the attribute as computed
|
||||
stat.computationDetails.computed = true;
|
||||
stat.computationDetails.busyComputing = false;
|
||||
|
||||
30
app/imports/api/creature/computation/computeToggle.js
Normal file
30
app/imports/api/creature/computation/computeToggle.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import evaluateCalculation from '/imports/api/creature/computation/evaluateCalculation.js';
|
||||
|
||||
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;
|
||||
|
||||
// Do work
|
||||
if (toggle.enabled){
|
||||
toggle.toggleResult = true;
|
||||
} else if (!toggle.condition){
|
||||
toggle.toggleResult = false;
|
||||
} else if (Number.isFinite(+toggle.condition)){
|
||||
toggle.toggleResult = !!+toggle.condition;
|
||||
} else {
|
||||
toggle.toggleResult = evaluateCalculation(toggle.condition, memo);
|
||||
}
|
||||
toggle.computationDetails.computed = true;
|
||||
toggle.computationDetails.busyComputing = false;
|
||||
}
|
||||
@@ -32,6 +32,7 @@ const calculationPropertyTypes = [
|
||||
'effect',
|
||||
'proficiency',
|
||||
'classLevel',
|
||||
'toggle',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,11 @@ const calculationPropertyTypes = [
|
||||
* - Write the computed results back to the database
|
||||
*/
|
||||
export function recomputeCreatureById(creatureId){
|
||||
let props = getActiveProperties(creatureId, {type: {$in: calculationPropertyTypes}});
|
||||
let props = getActiveProperties({
|
||||
ancestorId: creatureId,
|
||||
filter: {type: {$in: calculationPropertyTypes}},
|
||||
includeUntoggled: true,
|
||||
});
|
||||
let computationMemo = new ComputationMemo(props);
|
||||
computeMemo(computationMemo);
|
||||
writeAlteredProperties(computationMemo);
|
||||
|
||||
@@ -3,51 +3,60 @@ import { isEqual, forOwn } from 'lodash';
|
||||
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills.js';
|
||||
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects.js';
|
||||
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
const schemasByType = {
|
||||
'skill': ComputedOnlySkillSchema,
|
||||
'attribute': ComputedOnlyAttributeSchema,
|
||||
'effect': ComputedOnlyEffectSchema,
|
||||
'toggle': ComputedOnlyToggleSchema,
|
||||
};
|
||||
|
||||
export default function writeAlteredProperties(memo){
|
||||
let bulkWriteOperations = [];
|
||||
// Loop through all properties on the memo
|
||||
forOwn(memo.originalPropsById, (original, _id) => {
|
||||
let changed = memo.propsById[_id];
|
||||
|
||||
let schema;
|
||||
switch (changed.type){
|
||||
case 'skill':
|
||||
schema = ComputedOnlySkillSchema;
|
||||
break;
|
||||
case 'attribute':
|
||||
schema = ComputedOnlyAttributeSchema;
|
||||
break;
|
||||
case 'effect':
|
||||
schema = ComputedOnlyEffectSchema;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
forOwn(memo.propsById, changed => {
|
||||
let schema = schemasByType[changed.type];
|
||||
if (!schema) return;
|
||||
let extraIds = changed.computationDetails.idsOfSameName;
|
||||
let ids;
|
||||
if (extraIds && extraIds.length){
|
||||
ids = [changed._id, ...extraIds];
|
||||
} else {
|
||||
ids = [changed._id];
|
||||
}
|
||||
let op = undefined;
|
||||
// Loop through all keys that can be changed by computation
|
||||
// and compile an operation that sets all those keys
|
||||
for (let key of schema.objectKeys()){
|
||||
if (!isEqual(original[key], changed[key])){
|
||||
if (!op) op = newOperation(_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);
|
||||
}
|
||||
ids.forEach(id => {
|
||||
let op = undefined;
|
||||
let original = memo.originalPropsById[id];
|
||||
op = addChangedKeysToOp(op, schema.objectKeys(), original, changed);
|
||||
if (op){
|
||||
bulkWriteOperations.push(op);
|
||||
}
|
||||
}
|
||||
if (op){
|
||||
bulkWriteOperations.push(op);
|
||||
}
|
||||
});
|
||||
});
|
||||
bulkWriteProperties(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: {
|
||||
@@ -92,7 +101,8 @@ function bulkWriteProperties(bulkWriteOps){
|
||||
);
|
||||
} else {
|
||||
bulkWriteOps.forEach(op => {
|
||||
CreatureProperties.update(op.updateOne.filter, op.updateOne.update, {
|
||||
let updateOneOrMany = op.updateOne || op.updateMany;
|
||||
CreatureProperties.update(updateOneOrMany.filter, updateOneOrMany.update, {
|
||||
// The server code is bypassing collection 2 validation, so do the same
|
||||
// on the client
|
||||
// include this if bypass is off:
|
||||
|
||||
@@ -24,7 +24,10 @@ export const recomputeDamageMultipliers = new ValidatedMethod({
|
||||
|
||||
export function recomputeDamageMultipliersById(creatureId){
|
||||
if (!creatureId) throw 'Creature ID is required';
|
||||
let props = getActiveProperties(creatureId, {type: 'damageMultiplier'});
|
||||
let props = getActiveProperties({
|
||||
ancestorId: creatureId,
|
||||
filter: {type: 'damageMultiplier'},
|
||||
});
|
||||
|
||||
// Count of how many weakness, resistances and immunities each damage type has
|
||||
let multipliersByName = {};
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||
|
||||
export default function getActiveProperties(ancestorId, filter = {}, options){
|
||||
export default function getActiveProperties({
|
||||
ancestorId,
|
||||
filter = {},
|
||||
options,
|
||||
includeUntoggled = false
|
||||
}){
|
||||
if (!ancestorId){
|
||||
throw 'Ancestor Id is required to get active properties'
|
||||
}
|
||||
// First get ids of disabled properties, unequiped items, unapplied buffs
|
||||
let disabledAncestorIds = CreatureProperties.find({
|
||||
let disabledAncestorsFilter = {
|
||||
'ancestors.id': ancestorId,
|
||||
$or: [
|
||||
{disabled: true},
|
||||
{equipped: false},
|
||||
{applied: false},
|
||||
],
|
||||
}, {
|
||||
};
|
||||
if (!includeUntoggled){
|
||||
disabledAncestorsFilter.$or.push({toggleResult: false});
|
||||
}
|
||||
let disabledAncestorIds = CreatureProperties.find(disabledAncestorsFilter, {
|
||||
fields: {_id: 1},
|
||||
}).map(prop => prop._id);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ResourcesSchema from '/imports/api/properties/subSchemas/ResourcesSchema.js'
|
||||
import ResultsSchema from '/imports/api/properties/subSchemas/ResultsSchema.js';
|
||||
|
||||
/*
|
||||
* Actions are things a character can do
|
||||
@@ -41,10 +40,6 @@ let ActionSchema = new SimpleSchema({
|
||||
'tags.$': {
|
||||
type: String,
|
||||
},
|
||||
results: {
|
||||
type: ResultsSchema,
|
||||
defaultValue: {},
|
||||
},
|
||||
resources: {
|
||||
type: ResourcesSchema,
|
||||
defaultValue: {},
|
||||
|
||||
27
app/imports/api/properties/Adjustments.js
Normal file
27
app/imports/api/properties/Adjustments.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
const AdjustmentSchema = new SimpleSchema({
|
||||
// The roll that determines how much to change the attribute
|
||||
adjustment: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: '1',
|
||||
},
|
||||
// Who this adjustment applies to
|
||||
target: {
|
||||
type: String,
|
||||
defaultValue: 'every',
|
||||
allowedValues: [
|
||||
'self', // the character who took the action
|
||||
'each', // rolled once for `each` target
|
||||
'every', // rolled once and applied to `every` target
|
||||
],
|
||||
},
|
||||
// The stat this rolls applies to
|
||||
stat: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
export { AdjustmentSchema };
|
||||
@@ -1,6 +1,4 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { Random } from 'meteor/random';
|
||||
import { StoredEffectSchema } from '/imports/api/properties/Effects.js';
|
||||
|
||||
let BuffSchema = new SimpleSchema({
|
||||
name: {
|
||||
@@ -15,20 +13,12 @@ let BuffSchema = new SimpleSchema({
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
// The effects in the stored buff need to be resolved to a number before being
|
||||
// placed on other characters, if they are applied to self, they can remain as
|
||||
// calculations, provided they don't contain any rolls
|
||||
let StoredBuffSchema = new SimpleSchema({
|
||||
effects: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'effects.$': {
|
||||
type: StoredEffectSchema,
|
||||
},
|
||||
target: {
|
||||
applied: {
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
index: 1,
|
||||
},
|
||||
target: {
|
||||
type: String,
|
||||
allowedValues: [
|
||||
'self', // the character who took the buff
|
||||
@@ -37,21 +27,14 @@ let StoredBuffSchema = new SimpleSchema({
|
||||
],
|
||||
defaultValue: 'every',
|
||||
},
|
||||
}).extend(BuffSchema);
|
||||
|
||||
let StoredBuffWithIdSchema = new SimpleSchema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet){
|
||||
return Random.id();
|
||||
}
|
||||
},
|
||||
},
|
||||
}).extend(StoredBuffSchema);
|
||||
});
|
||||
|
||||
let AppliedBuffSchema = new SimpleSchema({
|
||||
applied: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
index: 1,
|
||||
},
|
||||
durationSpent: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
@@ -73,4 +56,4 @@ let AppliedBuffSchema = new SimpleSchema({
|
||||
},
|
||||
}).extend(BuffSchema);
|
||||
|
||||
export { AppliedBuffSchema, StoredBuffSchema, StoredBuffWithIdSchema };
|
||||
export { AppliedBuffSchema, BuffSchema };
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { Random } from 'meteor/random';
|
||||
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
||||
|
||||
const DamageSchema = new SimpleSchema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
// The roll that determines how much to damage the attribute
|
||||
damage: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: '1d8 + strength.modifier',
|
||||
},
|
||||
// Who this adjustment applies to
|
||||
// Who this damage applies to
|
||||
target: {
|
||||
type: String,
|
||||
defaultValue: 'every',
|
||||
@@ -33,4 +25,4 @@ const DamageSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
export default DamageSchema;
|
||||
export { DamageSchema };
|
||||
@@ -1,5 +1,4 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { Random } from 'meteor/random';
|
||||
|
||||
/*
|
||||
* Effects are reason-value attached to skills and abilities
|
||||
@@ -42,16 +41,6 @@ let EffectSchema = new SimpleSchema({
|
||||
},
|
||||
});
|
||||
|
||||
const StoredEffectSchema = new SimpleSchema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
}).extend(EffectSchema);
|
||||
|
||||
const ComputedOnlyEffectSchema = new SimpleSchema({
|
||||
// The computed result of the effect
|
||||
result: {
|
||||
@@ -64,4 +53,4 @@ const ComputedEffectSchema = new SimpleSchema()
|
||||
.extend(ComputedOnlyEffectSchema)
|
||||
.extend(EffectSchema);
|
||||
|
||||
export { EffectSchema, StoredEffectSchema, ComputedEffectSchema, ComputedOnlyEffectSchema };
|
||||
export { EffectSchema, ComputedEffectSchema, ComputedOnlyEffectSchema };
|
||||
|
||||
15
app/imports/api/properties/Results.js
Normal file
15
app/imports/api/properties/Results.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
const ResultSchema = new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Expression of whether or not to apply the children
|
||||
comparison: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
export { ResultSchema };
|
||||
@@ -1,5 +1,4 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import RollResultsSchema from '/imports/api/properties/subSchemas/RollResultsSchema.js'
|
||||
|
||||
/**
|
||||
* Rolls are children to actions or other rolls, they are triggered with 0 or
|
||||
@@ -34,13 +33,6 @@ let RollSchema = new SimpleSchema({
|
||||
'tags.$': {
|
||||
type: String,
|
||||
},
|
||||
rollResults: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'rollResults.$': {
|
||||
type: RollResultsSchema,
|
||||
},
|
||||
});
|
||||
|
||||
export { RollSchema };
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import ResultsSchema from '/imports/api/properties/subSchemas/ResultsSchema.js';
|
||||
|
||||
// These are the rolls made when saves are called for
|
||||
// For the saving throw bonus or proficiency, see ./Skills.js
|
||||
@@ -8,18 +7,10 @@ let SavingThrowSchema = new SimpleSchema ({
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The variable name of ability the saving throw relies on
|
||||
ability: {
|
||||
// The variable name of ability the save to roll
|
||||
stat: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
passResults: {
|
||||
type: ResultsSchema,
|
||||
defaultValue: {},
|
||||
},
|
||||
failResults: {
|
||||
type: ResultsSchema,
|
||||
defaultValue: {},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
36
app/imports/api/properties/Toggles.js
Normal file
36
app/imports/api/properties/Toggles.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
const ToggleSchema = new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
enabled: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// if neither disabled or enabled, the condition will be run to determine
|
||||
// if the children of the toggle should be active
|
||||
condition: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedOnlyToggleSchema = new SimpleSchema({
|
||||
// The computed result of the effect
|
||||
toggleResult: {
|
||||
type: SimpleSchema.oneOf(Number, String, Boolean),
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const ComputedToggleSchema = new SimpleSchema()
|
||||
.extend(ComputedOnlyToggleSchema)
|
||||
.extend(ToggleSchema);
|
||||
|
||||
export { ToggleSchema, ComputedOnlyToggleSchema, ComputedToggleSchema };
|
||||
@@ -1,9 +1,11 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ActionSchema } from '/imports/api/properties/Actions.js';
|
||||
import { AdjustmentSchema } from '/imports/api/properties/Adjustments.js';
|
||||
import { AttackSchema } from '/imports/api/properties/Attacks.js';
|
||||
import { ComputedAttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||
import { AppliedBuffSchema } from '/imports/api/properties/Buffs.js';
|
||||
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
||||
import { DamageSchema } from '/imports/api/properties/Damages.js';
|
||||
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers.js';
|
||||
import { ComputedEffectSchema } from '/imports/api/properties/Effects.js';
|
||||
import { ExperienceSchema } from '/imports/api/properties/Experiences.js';
|
||||
@@ -11,21 +13,25 @@ import { FeatureSchema } from '/imports/api/properties/Features.js';
|
||||
import { FolderSchema } from '/imports/api/properties/Folders.js';
|
||||
import { NoteSchema } from '/imports/api/properties/Notes.js';
|
||||
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
||||
import { ResultSchema } from '/imports/api/properties/Results.js';
|
||||
import { RollSchema } from '/imports/api/properties/Rolls.js';
|
||||
import { SavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
||||
import { ComputedSkillSchema } from '/imports/api/properties/Skills.js';
|
||||
import { SlotSchema } from '/imports/api/properties/Slots.js';
|
||||
import { SpellListSchema } from '/imports/api/properties/SpellLists.js';
|
||||
import { SpellSchema } from '/imports/api/properties/Spells.js';
|
||||
import { ToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||
import { ContainerSchema } from '/imports/api/properties/Containers.js';
|
||||
import { ItemSchema } from '/imports/api/properties/Items.js';
|
||||
|
||||
const propertySchemasIndex = {
|
||||
action: ActionSchema,
|
||||
adjustment: AdjustmentSchema,
|
||||
attack: AttackSchema,
|
||||
attribute: ComputedAttributeSchema,
|
||||
buff: AppliedBuffSchema,
|
||||
classLevel: ClassLevelSchema,
|
||||
damage: DamageSchema,
|
||||
damageMultiplier: DamageMultiplierSchema,
|
||||
effect: ComputedEffectSchema,
|
||||
experience: ExperienceSchema,
|
||||
@@ -33,12 +39,14 @@ const propertySchemasIndex = {
|
||||
folder: FolderSchema,
|
||||
note: NoteSchema,
|
||||
proficiency: ProficiencySchema,
|
||||
result: ResultSchema,
|
||||
roll: RollSchema,
|
||||
savingThrow: SavingThrowSchema,
|
||||
skill: ComputedSkillSchema,
|
||||
slot: SlotSchema,
|
||||
spellList: SpellListSchema,
|
||||
spell: SpellSchema,
|
||||
toggle: ToggleSchema,
|
||||
container: ContainerSchema,
|
||||
item: ItemSchema,
|
||||
any: new SimpleSchema({}),
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ActionSchema } from '/imports/api/properties/Actions.js';
|
||||
import { AdjustmentSchema } from '/imports/api/properties/Adjustments.js';
|
||||
import { AttackSchema } from '/imports/api/properties/Attacks.js';
|
||||
import { AttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||
import { StoredBuffSchema } from '/imports/api/properties/Buffs.js';
|
||||
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
||||
import { DamageSchema } from '/imports/api/properties/Damages.js';
|
||||
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers.js';
|
||||
import { EffectSchema } from '/imports/api/properties/Effects.js';
|
||||
import { ExperienceSchema } from '/imports/api/properties/Experiences.js';
|
||||
@@ -11,21 +13,25 @@ import { FeatureSchema } from '/imports/api/properties/Features.js';
|
||||
import { FolderSchema } from '/imports/api/properties/Folders.js';
|
||||
import { NoteSchema } from '/imports/api/properties/Notes.js';
|
||||
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
||||
import { ResultSchema } from '/imports/api/properties/Results.js';
|
||||
import { RollSchema } from '/imports/api/properties/Rolls.js';
|
||||
import { SavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
||||
import { SkillSchema } from '/imports/api/properties/Skills.js';
|
||||
import { SlotSchema } from '/imports/api/properties/Slots.js';
|
||||
import { SpellListSchema } from '/imports/api/properties/SpellLists.js';
|
||||
import { SpellSchema } from '/imports/api/properties/Spells.js';
|
||||
import { ToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||
import { ContainerSchema } from '/imports/api/properties/Containers.js';
|
||||
import { ItemSchema } from '/imports/api/properties/Items.js';
|
||||
|
||||
const propertySchemasIndex = {
|
||||
action: ActionSchema,
|
||||
adjustment: AdjustmentSchema,
|
||||
attack: AttackSchema,
|
||||
attribute: AttributeSchema,
|
||||
buff: StoredBuffSchema,
|
||||
classLevel: ClassLevelSchema,
|
||||
damage: DamageSchema,
|
||||
damageMultiplier: DamageMultiplierSchema,
|
||||
effect: EffectSchema,
|
||||
experience: ExperienceSchema,
|
||||
@@ -33,12 +39,14 @@ const propertySchemasIndex = {
|
||||
folder: FolderSchema,
|
||||
note: NoteSchema,
|
||||
proficiency: ProficiencySchema,
|
||||
result: ResultSchema,
|
||||
roll: RollSchema,
|
||||
savingThrow: SavingThrowSchema,
|
||||
skill: SkillSchema,
|
||||
slot: SlotSchema,
|
||||
spellList: SpellListSchema,
|
||||
spell: SpellSchema,
|
||||
toggle: ToggleSchema,
|
||||
container: ContainerSchema,
|
||||
item: ItemSchema,
|
||||
any: new SimpleSchema({}),
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
import AdjustmentSchema from '/imports/api/properties/subSchemas/AdjustmentSchema.js';
|
||||
import DamageSchema from '/imports/api/properties/subSchemas/DamageSchema.js';
|
||||
import { StoredBuffWithIdSchema } from '/imports/api/properties/Buffs.js';
|
||||
|
||||
let ResultsSchema = new SimpleSchema({
|
||||
// Adjustments applied when taking this action
|
||||
// Ideally, if these adjustments can't be made, the action should be unusable
|
||||
adjustments: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'adjustments.$': {
|
||||
type: AdjustmentSchema,
|
||||
},
|
||||
// Damage is done to hitpoints or hitpoint-like stats
|
||||
// has a damage type, can be mitigated by resistances, etc.
|
||||
damages: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'damages.$': {
|
||||
type: DamageSchema,
|
||||
},
|
||||
// Buffs applied when taking this action
|
||||
buffs: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'buffs.$': {
|
||||
type: StoredBuffWithIdSchema,
|
||||
},
|
||||
});
|
||||
|
||||
export default ResultsSchema;
|
||||
@@ -75,6 +75,10 @@ const PROPERTIES = Object.freeze({
|
||||
icon: 'category',
|
||||
name: 'Item'
|
||||
},
|
||||
toggle: {
|
||||
icon: 'power_settings_new',
|
||||
name: 'Toggle'
|
||||
},
|
||||
});
|
||||
|
||||
export default PROPERTIES;
|
||||
|
||||
@@ -276,13 +276,14 @@
|
||||
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
||||
import ActionListTile from '/imports/ui/properties/components/actions/ActionListTile.vue';
|
||||
import AttackListTile from '/imports/ui/properties/components/actions/AttackListTile.vue';
|
||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||
|
||||
const getProperties = function(creatureId, filter = {}){
|
||||
filter['ancestors.id'] = creatureId;
|
||||
filter.removed = {$ne: true};
|
||||
return CreatureProperties.find(filter, {
|
||||
sort: {order: 1}
|
||||
});
|
||||
const getProperties = function(creatureId, filter){
|
||||
return getActiveProperties({
|
||||
ancestorId: creatureId,
|
||||
filter,
|
||||
options: {sort: {order: 1}},
|
||||
});
|
||||
};
|
||||
|
||||
const getAttributeOfType = function(creatureId, type){
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template lang="html">
|
||||
<div class="results-form">
|
||||
<div class="subheading" v-if="model.damages.length">
|
||||
<div
|
||||
v-if="model.damages.length"
|
||||
class="subheading"
|
||||
>
|
||||
Damage
|
||||
</div>
|
||||
<damage-list-form
|
||||
@@ -10,7 +13,10 @@
|
||||
@push="({path, value, ack}) => $emit('push', {path: ['damages', ...path], value, ack})"
|
||||
@pull="({path, ack}) => $emit('pull', {path: ['damages', ...path], ack})"
|
||||
/>
|
||||
<div class="subheading" v-if="model.adjustments.length">
|
||||
<div
|
||||
v-if="model.adjustments.length"
|
||||
class="subheading"
|
||||
>
|
||||
Adjustments
|
||||
</div>
|
||||
<adjustment-list-form
|
||||
@@ -20,7 +26,10 @@
|
||||
@push="({path, value, ack}) => $emit('push', {path: ['adjustments', ...path], value, ack})"
|
||||
@pull="({path, ack}) => $emit('pull', {path: ['adjustments', ...path], ack})"
|
||||
/>
|
||||
<div class="subheading" v-if="model.buffs.length">
|
||||
<div
|
||||
v-if="model.buffs.length"
|
||||
class="subheading"
|
||||
>
|
||||
Buffs
|
||||
</div>
|
||||
<buff-list-form
|
||||
@@ -32,8 +41,13 @@
|
||||
@pull="({path, ack}) => $emit('pull', {path: ['buffs', ...path], ack})"
|
||||
/>
|
||||
<div class="layout row justify-center">
|
||||
<v-menu origin="center center" transition="scale-transition" nudge-top="50%" nudge-left="50%">
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-menu
|
||||
origin="center center"
|
||||
transition="scale-transition"
|
||||
nudge-top="50%"
|
||||
nudge-left="50%"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
:loading="addResultLoading"
|
||||
:disabled="addResultLoading"
|
||||
@@ -48,13 +62,16 @@
|
||||
<v-list>
|
||||
<v-list-tile@click="addDamage">
|
||||
<v-list-tile-title>Add Damage</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile@click="addAdjustment">
|
||||
<v-list-tile-title>Add Adjustment</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile@click="addBuff">
|
||||
<v-list-tile-title>Add Buff</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list-tile>
|
||||
<v-list-tile@click="addAdjustment">
|
||||
<v-list-tile-title>Add Adjustment</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile@click="addBuff">
|
||||
<v-list-tile-title>Add Buff</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list-tile@click="addbuff">
|
||||
</v-list-tile@click="addadjustment">
|
||||
</v-list-tile@click="adddamage">
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
@@ -65,9 +82,6 @@
|
||||
import AdjustmentListForm from '/imports/ui/properties/forms/AdjustmentListForm.vue';
|
||||
import DamageListForm from '/imports/ui/properties/forms/DamageListForm.vue';
|
||||
import BuffListForm from '/imports/ui/properties/forms/BuffListForm.vue';
|
||||
import ResultsSchema from '/imports/api/properties/subSchemas/ResultsSchema.js';
|
||||
import DamageSchema from '/imports/api/properties/subSchemas/DamageSchema.js';
|
||||
import AdjustmentSchema from '/imports/api/properties/subSchemas/AdjustmentSchema.js';
|
||||
import { StoredBuffWithIdSchema } from '/imports/api/properties/Buffs.js';
|
||||
|
||||
export default {
|
||||
@@ -76,13 +90,10 @@
|
||||
DamageListForm,
|
||||
BuffListForm,
|
||||
},
|
||||
data(){return {
|
||||
addResultLoading: false,
|
||||
}},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
default: () => (ResultsSchema.clean({})),
|
||||
default: () => ({}),
|
||||
},
|
||||
parentTarget: {
|
||||
type: String,
|
||||
@@ -96,6 +107,9 @@
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
data(){return {
|
||||
addResultLoading: false,
|
||||
}},
|
||||
methods: {
|
||||
acknowledgeAddResult(){
|
||||
this.addResultLoading = false;
|
||||
|
||||
@@ -34,24 +34,6 @@
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<results-form
|
||||
:model="rollResult.results"
|
||||
:parent-target="model.target"
|
||||
@change="({path, value, ack}) => $emit('change', {
|
||||
path: ['rollResults', index, 'results', ...path],
|
||||
value,
|
||||
ack
|
||||
})"
|
||||
@push="({path, value, ack}) => $emit('push', {
|
||||
path: ['rollResults', index, 'results', ...path],
|
||||
value,
|
||||
ack
|
||||
})"
|
||||
@pull="({path, ack}) => $emit('pull', {
|
||||
path: ['rollResults', index, 'results', ...path],
|
||||
ack
|
||||
})"
|
||||
/>
|
||||
<v-divider class="my-4" />
|
||||
</div>
|
||||
</v-slide-x-transition>
|
||||
@@ -84,14 +66,11 @@
|
||||
|
||||
<script>
|
||||
import FormSection, {FormSections} from '/imports/ui/properties/forms/shared/FormSection.vue';
|
||||
import RollResultsSchema from '/imports/api/properties/subSchemas/RollResultsSchema.js';
|
||||
import ResultsForm from '/imports/ui/properties/forms/ResultsForm.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormSection,
|
||||
FormSections,
|
||||
ResultsForm,
|
||||
},
|
||||
props: {
|
||||
stored: {
|
||||
@@ -117,14 +96,6 @@
|
||||
acknowledgeAddResult(){
|
||||
this.addResultLoading = false;
|
||||
},
|
||||
addResult(){
|
||||
this.addResultLoading = true;
|
||||
this.$emit('push', {
|
||||
path: ['rollResults'],
|
||||
value: RollResultsSchema.clean({}),
|
||||
ack: this.acknowledgeAddResult,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
40
app/imports/ui/properties/forms/ToggleForm.vue
Normal file
40
app/imports/ui/properties/forms/ToggleForm.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template lang="html">
|
||||
<div class="feature-form">
|
||||
<text-field
|
||||
label="Name"
|
||||
:value="model.name"
|
||||
:error-messages="errors.name"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
|
||||
/>
|
||||
<text-field
|
||||
label="Condition"
|
||||
:value="model.condition"
|
||||
:error-messages="errors.condition"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['condition'], value, ack})"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
errors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
debounceTime: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -17,6 +17,7 @@ import SavingThrowForm from '/imports/ui/properties/forms/SavingThrowForm.vue';
|
||||
import SkillForm from '/imports/ui/properties/forms/SkillForm.vue';
|
||||
import SpellListForm from '/imports/ui/properties/forms/SpellListForm.vue';
|
||||
import SpellForm from '/imports/ui/properties/forms/SpellForm.vue';
|
||||
import ToggleForm from '/imports/ui/properties/forms/ToggleForm.vue';
|
||||
|
||||
export default {
|
||||
action: ActionForm,
|
||||
@@ -38,4 +39,5 @@ export default {
|
||||
skill: SkillForm,
|
||||
spellList: SpellListForm,
|
||||
spell: SpellForm,
|
||||
toggle: ToggleForm,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user