Lots of progress testing and fixing computation engine

This commit is contained in:
Stefan Zermatten
2021-09-16 14:31:28 +02:00
parent dfd7ad4af5
commit a660ccc458
34 changed files with 775 additions and 90 deletions

View File

@@ -1,10 +1,6 @@
import SimpleSchema from 'simpl-schema';
import {
ResourcesSchema,
ResourcesComputedOnlySchema,
ResourcesComputedSchema,
} from '/imports/api/properties/subSchemas/ResourcesSchema.js';
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
import { storedIconsSchema } from '/imports/api/icons/Icons.js';
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
SimpleSchema.extendOptions(['parseLevel']);
@@ -45,11 +41,6 @@ let ActionSchema = createPropertySchema({
'multipleTargets',
],
},
// Resources schema changes for between standard, computed, and computedOnly
resources: {
type: ResourcesSchema,
defaultValue: {},
},
// Calculation of how many times this action can be used
uses: {
type: 'fieldToCompute',
@@ -66,6 +57,61 @@ let ActionSchema = createPropertySchema({
allowedValues: ['longRest', 'shortRest'],
optional: true,
},
// Resources
resources: {
type: Object,
defaultValue: {},
},
'resources.itemsConsumed': {
type: Array,
defaultValue: [],
},
'resources.itemsConsumed.$': {
type: Object,
},
'resources.itemsConsumed.$._id': {
type: String,
regEx: SimpleSchema.RegEx.Id,
autoValue(){
if (!this.isSet) return Random.id();
}
},
'resources.itemsConsumed.$.tag': {
type: String,
optional: true,
},
'resources.itemsConsumed.$.quantity': {
type: 'fieldToCompute',
optional: true,
},
'resources.itemsConsumed.$.itemId': {
type: String,
regEx: SimpleSchema.RegEx.Id,
optional: true,
},
'resources.attributesConsumed': {
type: Array,
defaultValue: [],
},
'resources.attributesConsumed.$': {
type: Object,
},
'resources.attributesConsumed.$._id': {
type: String,
regEx: SimpleSchema.RegEx.Id,
autoValue(){
if (!this.isSet) return Random.id();
}
},
'resources.attributesConsumed.$.variableName': {
type: String,
optional: true,
max: STORAGE_LIMITS.variableName,
},
'resources.attributesConsumed.$.quantity': {
type: 'fieldToCompute',
optional: true,
},
});
const ComputedOnlyActionSchema = createPropertySchema({
@@ -77,10 +123,6 @@ const ComputedOnlyActionSchema = createPropertySchema({
type: 'computedOnlyInlineCalculationField',
optional: true,
},
resources: {
type: ResourcesComputedOnlySchema,
defaultValue: {},
},
// True if the uses left is zero, or any item or attribute consumed is
// insufficient
insufficientResources: {
@@ -96,16 +138,70 @@ const ComputedOnlyActionSchema = createPropertySchema({
type: Number,
optional: true,
},
// Resources
resources: {
type: Object,
defaultValue: {},
},
'resources.itemsConsumed': {
type: Array,
defaultValue: [],
},
'resources.itemsConsumed.$': {
type: Object,
},
'resources.itemsConsumed.$.available': {
type: Number,
optional: true,
},
'resources.itemsConsumed.$.quantity': {
type: 'computedOnlyField',
optional: true,
},
'resources.itemsConsumed.$.itemName': {
type: String,
max: STORAGE_LIMITS.name,
optional: true,
},
'resources.itemsConsumed.$.itemIcon': {
type: storedIconsSchema,
optional: true,
max: STORAGE_LIMITS.icon,
},
'resources.itemsConsumed.$.itemColor': {
type: String,
optional: true,
max: STORAGE_LIMITS.color,
},
'resources.attributesConsumed': {
type: Array,
defaultValue: [],
},
'resources.attributesConsumed.$': {
type: Object,
},
'resources.attributesConsumed.$.quantity': {
type: 'computedOnlyField',
optional: true,
},
'resources.attributesConsumed.$.available': {
type: Number,
optional: true,
},
'resources.attributesConsumed.$.statId': {
type: String,
regEx: SimpleSchema.RegEx.Id,
optional: true,
},
'resources.attributesConsumed.$.statName': {
type: String,
optional: true,
max: STORAGE_LIMITS.name,
},
});
const ComputedActionSchema = new SimpleSchema()
.extend(ActionSchema)
.extend(ComputedOnlyActionSchema)
.extend({
resources: {
type: ResourcesComputedSchema,
defaultValue: {},
},
});
.extend(ComputedOnlyActionSchema);
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema};

View File

@@ -3,7 +3,7 @@ import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
let ClassLevelSchema = createPropertySchema({
const ClassLevelSchema = createPropertySchema({
name: {
type: String,
optional: true,
@@ -27,4 +27,6 @@ let ClassLevelSchema = createPropertySchema({
},
});
export { ClassLevelSchema };
const ComputedOnlyClassLevelSchema = new SimpleSchema({});
export { ClassLevelSchema, ComputedOnlyClassLevelSchema };

View File

@@ -85,4 +85,6 @@ function parseString(string, fn = 'compile'){
return {result, context}
}
export { ConstantSchema };
const ComputedOnlyConstantSchema = new SimpleSchema({});
export { ConstantSchema, ComputedOnlyConstantSchema };

View File

@@ -49,4 +49,6 @@ let DamageMultiplierSchema = new SimpleSchema({
},
});
export { DamageMultiplierSchema };
const ComputedOnlyDamageMultiplierSchema = new SimpleSchema({});
export { DamageMultiplierSchema, ComputedOnlyDamageMultiplierSchema };

View File

@@ -10,4 +10,6 @@ let FolderSchema = new SimpleSchema({
},
});
export { FolderSchema };
const ComputedOnlyFolderSchema = new SimpleSchema({});
export { FolderSchema, ComputedOnlyFolderSchema };

View File

@@ -26,4 +26,6 @@ let ProficiencySchema = new SimpleSchema({
},
});
export { ProficiencySchema };
const ComputedOnlyProficiencySchema = new SimpleSchema({});
export { ProficiencySchema, ComputedOnlyProficiencySchema };

View File

@@ -58,4 +58,6 @@ let ReferenceSchema = new SimpleSchema({
},
});
export { ReferenceSchema };
const ComputedOnlyReferenceSchema = new SimpleSchema({});
export { ReferenceSchema, ComputedOnlyReferenceSchema };

View File

@@ -39,4 +39,6 @@ let SlotFillerSchema = new SimpleSchema({
},
});
export { SlotFillerSchema };
const ComputedOnlySlotFillerSchema = new SimpleSchema({});
export { SlotFillerSchema, ComputedOnlySlotFillerSchema };

View File

@@ -5,23 +5,23 @@ import { ComputedOnlyAttackSchema } from '/imports/api/properties/Attacks.js';
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes.js';
import { ComputedOnlyBuffSchema } from '/imports/api/properties/Buffs.js';
import { ComputedOnlyClassSchema } from '/imports/api/properties/Classes.js';
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
import { ConstantSchema } from '/imports/api/properties/Constants.js';
import { ComputedOnlyClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
import { ComputedOnlyConstantSchema } from '/imports/api/properties/Constants.js';
import { ComputedOnlyContainerSchema } from '/imports/api/properties/Containers.js';
import { ComputedOnlyDamageSchema } from '/imports/api/properties/Damages.js';
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers.js';
import { ComputedOnlyDamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers.js';
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects.js';
import { ComputedOnlyFeatureSchema } from '/imports/api/properties/Features.js';
import { FolderSchema } from '/imports/api/properties/Folders.js';
import { ComputedOnlyFolderSchema } from '/imports/api/properties/Folders.js';
import { ComputedOnlyItemSchema } from '/imports/api/properties/Items.js';
import { ComputedOnlyNoteSchema } from '/imports/api/properties/Notes.js';
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
import { ReferenceSchema } from '/imports/api/properties/References.js';
import { ComputedOnlyProficiencySchema } from '/imports/api/properties/Proficiencies.js';
import { ComputedOnlyReferenceSchema } from '/imports/api/properties/References.js';
import { ComputedOnlyRollSchema } from '/imports/api/properties/Rolls.js';
import { ComputedOnlySavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills.js';
import { ComputedOnlySlotSchema } from '/imports/api/properties/Slots.js';
import { SlotFillerSchema } from '/imports/api/properties/SlotFillers.js';
import { ComputedOnlySlotFillerSchema } from '/imports/api/properties/SlotFillers.js';
import { ComputedOnlySpellSchema } from '/imports/api/properties/Spells.js';
import { ComputedOnlySpellListSchema } from '/imports/api/properties/SpellLists.js';
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles.js';
@@ -33,23 +33,23 @@ const propertySchemasIndex = {
attribute: ComputedOnlyAttributeSchema,
buff: ComputedOnlyBuffSchema,
characterClass: ComputedOnlyClassSchema,
classLevel: ClassLevelSchema,
constant: ConstantSchema,
classLevel: ComputedOnlyClassLevelSchema,
constant: ComputedOnlyConstantSchema,
container: ComputedOnlyContainerSchema,
damage: ComputedOnlyDamageSchema,
damageMultiplier: DamageMultiplierSchema,
damageMultiplier: ComputedOnlyDamageMultiplierSchema,
effect: ComputedOnlyEffectSchema,
feature: ComputedOnlyFeatureSchema,
folder: FolderSchema,
folder: ComputedOnlyFolderSchema,
item: ComputedOnlyItemSchema,
note: ComputedOnlyNoteSchema,
proficiency: ProficiencySchema,
proficiency: ComputedOnlyProficiencySchema,
propertySlot: ComputedOnlySlotSchema,
reference: ReferenceSchema,
reference: ComputedOnlyReferenceSchema,
roll: ComputedOnlyRollSchema,
savingThrow: ComputedOnlySavingThrowSchema,
skill: ComputedOnlySkillSchema,
slotFiller: SlotFillerSchema,
slotFiller: ComputedOnlySlotFillerSchema,
spellList: ComputedOnlySpellListSchema,
spell: ComputedOnlySpellSchema,
toggle: ComputedOnlyToggleSchema,

View File

@@ -5,27 +5,20 @@ import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
// Get schemas that apply fields directly so they can be gracefully extended
// because {type: Schema} fields can't be extended
function fieldToCompute(field){
return new SimpleSchema({
// The object should already be set, but set again just in case
[field]: {
type: Object,
optional: true,
},
const schemaObj = {
// This is required, if we don't have a calculation delete the whole object
[`${field}.calculation`]: {
type: String,
max: STORAGE_LIMITS.calculation,
},
});
}
// If the field is an array, we need to include those fields as well
includeParentFields(field, schemaObj);
return new SimpleSchema(schemaObj);
}
function computedOnlyField(field){
return new SimpleSchema({
// The object should already be set, but set again just in case
[field]: {
type: Object,
optional: true,
},
const schemaObj = {
[`${field}.value`]: {
type: SimpleSchema.oneOf(String, Number),
optional: true,
@@ -38,6 +31,30 @@ function computedOnlyField(field){
[`${field}.errors.$`]:{
type: ErrorSchema,
},
}
includeParentFields(field, schemaObj);
return new SimpleSchema(schemaObj);
}
// We must include parent array and object fields for the schema to be valid
function includeParentFields(field, schemaObj){
const splitField = field.split('.');
if (splitField.length === 1){
schemaObj[field] = {type: Object};
return;
}
let key = '';
splitField.push('');
splitField.forEach(value => {
if (key){
if (value === '$'){
schemaObj[key] = {type: Array};
} else {
schemaObj[key] = {type: Object};
}
key += '.';
}
key += value;
});
}