Moved properties out of creature folder, since they apply to library nodes as well now
This commit is contained in:
131
app/imports/api/properties/Actions.js
Normal file
131
app/imports/api/properties/Actions.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import AdjustmentSchema from '/imports/api/creature/subSchemas/AdjustmentSchema.js';
|
||||
import StoredBuffSchema from '/imports/api/properties/Buffs.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Actions = new Mongo.Collection('actions');
|
||||
|
||||
/*
|
||||
* Actions are things a character can do
|
||||
* Any rolls that are children of actions will be rolled when taking the action
|
||||
* Any actions that are children of this action will be considered alternatives
|
||||
* to this action
|
||||
*/
|
||||
let ActionSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// What time-resource is used to take the action in combat
|
||||
// long actions take longer than 1 round to cast
|
||||
type: {
|
||||
type: String,
|
||||
allowedValues: ['action', 'bonus', 'attack', 'reaction', 'free', 'long'],
|
||||
defaultValue: 'action',
|
||||
},
|
||||
// Who is the action directed at
|
||||
target: {
|
||||
type: String,
|
||||
defaultValue: 'singleTarget',
|
||||
allowedValues: [
|
||||
'self',
|
||||
'singleTarget',
|
||||
'multipleTargets',
|
||||
],
|
||||
},
|
||||
// Effects can apply to this tag specifically
|
||||
// Ranged spell attack, Ranged weapon attack, etc.
|
||||
tags: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'tags.$': {
|
||||
type: String,
|
||||
},
|
||||
// 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,
|
||||
},
|
||||
// Buffs applied when taking this action
|
||||
buffs: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'buffs.$': {
|
||||
type: StoredBuffSchema,
|
||||
},
|
||||
// Calculation of how many times this action can be used
|
||||
// Only set if this action tracks its own uses, rather than adjusting
|
||||
// resources
|
||||
uses: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Integer of how many times it has already been used
|
||||
usesUsed: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
// How this action's uses are reset automatically
|
||||
reset: {
|
||||
type: String,
|
||||
allowedValues: ["longRest", "shortRest"],
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
ActionSchema.extend(ColorSchema);
|
||||
|
||||
Actions.attachSchema(ActionSchema);
|
||||
Actions.attachSchema(PropertySchema);
|
||||
|
||||
const insertAction = new ValidatedMethod({
|
||||
name: 'Actions.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Actions,
|
||||
permission: 'edit',
|
||||
schema: ActionSchema,
|
||||
run(action) {
|
||||
return Actions.insert(action);
|
||||
},
|
||||
});
|
||||
|
||||
const updateAction = new ValidatedMethod({
|
||||
name: 'Actions.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Actions,
|
||||
permission: 'edit',
|
||||
schema: ActionSchema,
|
||||
});
|
||||
|
||||
export default Actions;
|
||||
export { ActionSchema, insertAction, updateAction };
|
||||
186
app/imports/api/properties/Attributes.js
Normal file
186
app/imports/api/properties/Attributes.js
Normal file
@@ -0,0 +1,186 @@
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
import getModifierFields from '/imports/api/getModifierFields.js';
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import {
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin
|
||||
} from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
|
||||
let Attributes = new Mongo.Collection('attributes');
|
||||
|
||||
/*
|
||||
* Attributes are numbered stats of a character
|
||||
*/
|
||||
let AttributeSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: 'New Attribute',
|
||||
},
|
||||
// The technical, lowercase, single-word name used in formulae
|
||||
variableName: {
|
||||
type: String,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
min: 3,
|
||||
defaultValue: 'newAttribute',
|
||||
},
|
||||
// How it is displayed and computed is determined by type
|
||||
type: {
|
||||
type: String,
|
||||
allowedValues: [
|
||||
'ability', //Strength, Dex, Con, etc.
|
||||
'stat', // Speed, Armor Class
|
||||
'modifier', // Proficiency Bonus, Initiative
|
||||
'hitDice', // d12 hit dice
|
||||
'healthBar', // Hitpoints, Temporary Hitpoints, can take damage
|
||||
'bar', // Displayed as a health bar, can't take damage
|
||||
'resource', // Rages, sorcery points
|
||||
'spellSlot', // Level 1, 2, 3... spell slots
|
||||
'utility', // Aren't displayed, Jump height, Carry capacity
|
||||
],
|
||||
defaultValue: 'stat',
|
||||
index: 1,
|
||||
},
|
||||
// The starting value, before effects
|
||||
baseValue: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
// The damage done to the attribute, always positive
|
||||
damage: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
min: 0,
|
||||
},
|
||||
// Can the value be decimal?
|
||||
decimal: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Automatically zero the adjustment on these conditions
|
||||
reset: {
|
||||
type: String,
|
||||
optional: true,
|
||||
allowedValues: ['shortRest', 'longRest'],
|
||||
},
|
||||
// Some things are only reset their adjustment by up to half of the value
|
||||
resetMultiplier: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
AttributeSchema.extend(ColorSchema);
|
||||
|
||||
const ComputedAttributeSchema = schema({
|
||||
// The computed value of the attribute
|
||||
value: {
|
||||
type: Number,
|
||||
defaultValue: 0,
|
||||
},
|
||||
// The computed modifier, provided the attribute type is `ability`
|
||||
mod: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
}).extend(AttributeSchema);
|
||||
|
||||
Attributes.attachSchema(ComputedAttributeSchema);
|
||||
Attributes.attachSchema(PropertySchema);
|
||||
|
||||
const insertAttribute = new ValidatedMethod({
|
||||
name: 'Attributes.methods.insert',
|
||||
mixins: [
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Attributes,
|
||||
permission: 'edit',
|
||||
schema: AttributeSchema,
|
||||
run(attribute) {
|
||||
return Attributes.insert(attribute);
|
||||
},
|
||||
});
|
||||
|
||||
const updateAttribute = new ValidatedMethod({
|
||||
name: 'Attributes.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Attributes,
|
||||
permission: 'edit',
|
||||
schema: AttributeSchema.omit(['adjutment']),
|
||||
skipRecompute({update}){
|
||||
let fields = getModifierFields(update);
|
||||
return !fields.hasAny([
|
||||
'variableName',
|
||||
'type',
|
||||
'baseValue',
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
const adjustAttribute = new ValidatedMethod({
|
||||
name: 'Attributes.methods.adjust',
|
||||
mixins: [
|
||||
simpleSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Attributes,
|
||||
permission: 'edit',
|
||||
schema: new SimpleSchema({
|
||||
_id: SimpleSchema.RegEx.Id,
|
||||
type: {
|
||||
type: String,
|
||||
allowedValues: ['set', 'increment']
|
||||
},
|
||||
value: Number,
|
||||
}),
|
||||
run({_id, type, value}) {
|
||||
if (type === 'set'){
|
||||
let currentValue = currentAttribute.value;
|
||||
// Set represents what we want the value to be after adjustment
|
||||
// So we need the actual adjustment to get to that value
|
||||
let adjustment = value - currentValue;
|
||||
// Ajustment can't exceed total value
|
||||
if (-adjustment > currentValue) adjustment = -currentValue;
|
||||
// Adjustment must be negative
|
||||
if (adjustment > 0) adjustment = 0;
|
||||
return Attributes.update(_id, {$set: {adjustment}});
|
||||
} else if (type === 'increment'){
|
||||
let remaining = currentAttribute.value + (currentAttribute.adjustment || 0);
|
||||
let adj = currentAttribute.adjustment;
|
||||
// Can't decrease adjustment below remaining value
|
||||
let increment = value;
|
||||
if (-increment > remaining) increment = -remaining;
|
||||
// Can't increase adjustment above zero
|
||||
if (increment > -adj) increment = -adj;
|
||||
if (typeof currentAttribute.adjustment === 'number'){
|
||||
return Attributes.update(_id, {$inc: {adjustment: increment}});
|
||||
} else {
|
||||
return Attributes.update(_id, {$set: {adjustment: increment}});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default Attributes;
|
||||
export { AttributeSchema, insertAttribute, updateAttribute, adjustAttribute };
|
||||
114
app/imports/api/properties/Buffs.js
Normal file
114
app/imports/api/properties/Buffs.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import { EffectSchema } from '/imports/api/properties/Effects.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Buffs = new Mongo.Collection('buffs');
|
||||
|
||||
let BuffSchema = new SimpleSchema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
duration: {
|
||||
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: EffectSchema,
|
||||
},
|
||||
target: {
|
||||
type: String,
|
||||
allowedValues: [
|
||||
'self', // the character who took the buff
|
||||
'each', // rolled once for `each` target
|
||||
'every', // rolled once and applied to `every` target
|
||||
],
|
||||
defaultValue: 'every',
|
||||
},
|
||||
}).extend(BuffSchema);
|
||||
|
||||
let AppliedBuffSchema = schema({
|
||||
durationSpent: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
min: 0,
|
||||
},
|
||||
appliedBy: {
|
||||
type: Object,
|
||||
},
|
||||
'appliedBy.name': {
|
||||
type: String,
|
||||
},
|
||||
'appliedBy.id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
'appliedBy.collection': {
|
||||
type: String,
|
||||
},
|
||||
}).extend(BuffSchema);
|
||||
|
||||
Buffs.attachSchema(AppliedBuffSchema);
|
||||
Buffs.attachSchema(PropertySchema);
|
||||
|
||||
const insertBuff = new ValidatedMethod({
|
||||
name: 'Buffs.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Buffs,
|
||||
permission: 'edit',
|
||||
schema: BuffSchema,
|
||||
run(buff) {
|
||||
return Buffs.insert(buff);
|
||||
},
|
||||
});
|
||||
|
||||
const updateBuff = new ValidatedMethod({
|
||||
name: 'Buffs.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Buffs,
|
||||
permission: 'edit',
|
||||
schema: BuffSchema,
|
||||
});
|
||||
|
||||
export default Buffs;
|
||||
export { AppliedBuffSchema, StoredBuffSchema, insertBuff, updateBuff };
|
||||
73
app/imports/api/properties/ClassLevels.js
Normal file
73
app/imports/api/properties/ClassLevels.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let ClassLevels = new Mongo.Collection("classLevels");
|
||||
|
||||
let ClassLevelSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The name of this class level's variable
|
||||
variableName: {
|
||||
type: String,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
},
|
||||
// The variable name of the base class this level is attached to
|
||||
baseClass: {
|
||||
type: String,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
optional: true,
|
||||
},
|
||||
level: {
|
||||
type: SimpleSchema.Integer,
|
||||
defaultValue: 1,
|
||||
},
|
||||
});
|
||||
|
||||
ClassLevels.attachSchema(ClassLevelSchema);
|
||||
ClassLevels.attachSchema(PropertySchema);
|
||||
|
||||
// Todo ensure the class level is being parented to a compatible class, and that
|
||||
// previous level requirements are met
|
||||
const insertClassLevel = new ValidatedMethod({
|
||||
name: 'ClassLevels.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: ClassLevels,
|
||||
permission: 'edit',
|
||||
schema: ClassLevelSchema,
|
||||
run(classLevel) {
|
||||
return ClassLevels.insert(classLevel);
|
||||
},
|
||||
});
|
||||
|
||||
const updateClassLevel = new ValidatedMethod({
|
||||
name: 'ClassLevels.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: ClassLevels,
|
||||
permission: 'edit',
|
||||
schema: ClassLevelSchema,
|
||||
});
|
||||
|
||||
export default ClassLevels;
|
||||
export { ClassLevelSchema, insertClassLevel, updateClassLevel };
|
||||
64
app/imports/api/properties/Classes.js
Normal file
64
app/imports/api/properties/Classes.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Classes = new Mongo.Collection("classes");
|
||||
|
||||
// TODO use variable name in computation engine, rather than a generated one
|
||||
let ClassSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
variableName: {
|
||||
type: String,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
},
|
||||
});
|
||||
|
||||
ClassSchema.extend(ColorSchema);
|
||||
|
||||
Classes.attachSchema(ClassSchema);
|
||||
Classes.attachSchema(PropertySchema);
|
||||
|
||||
const insertClass = new ValidatedMethod({
|
||||
name: 'Classes.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Classes,
|
||||
permission: 'edit',
|
||||
schema: ClassSchema,
|
||||
run(cls) {
|
||||
return Classes.insert(cls);
|
||||
},
|
||||
});
|
||||
|
||||
const updateClass = new ValidatedMethod({
|
||||
name: 'Classes.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Classes,
|
||||
permission: 'edit',
|
||||
schema: ClassSchema,
|
||||
});
|
||||
|
||||
export default Classes;
|
||||
export { ClassSchema, insertClass, updateClass };
|
||||
49
app/imports/api/properties/Containers.js
Normal file
49
app/imports/api/properties/Containers.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||
|
||||
//set up the collection for containers
|
||||
let Containers = new Mongo.Collection("containers");
|
||||
|
||||
let ContainerSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
trim: false
|
||||
},
|
||||
carried: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
optional: true,
|
||||
},
|
||||
contentsWeightless: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
weight: {
|
||||
type: Number,
|
||||
min: 0,
|
||||
defaultValue: 0
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
min: 0,
|
||||
defaultValue: 0
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
trim: false
|
||||
},
|
||||
});
|
||||
|
||||
ContainerSchema.extend(ColorSchema);
|
||||
|
||||
Containers.attachSchema(ContainerSchema);
|
||||
Containers.attachSchema(PropertySchema);
|
||||
Containers.attachSchema(ChildSchema);
|
||||
|
||||
export default Containers;
|
||||
export { ContainerSchema };
|
||||
75
app/imports/api/properties/DamageMultipliers.js
Normal file
75
app/imports/api/properties/DamageMultipliers.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let DamageMultipliers = new Mongo.Collection("damageMultipliers");
|
||||
|
||||
/*
|
||||
* DamageMultipliers are multipliers that affect how much damage is taken from
|
||||
* a given damage type
|
||||
*/
|
||||
let DamageMultiplierSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The technical, lowercase, single-word name used in formulae
|
||||
damageType: {
|
||||
type: String,
|
||||
allowedValues: DAMAGE_TYPES,
|
||||
defaultValue: 'bludgeoning',
|
||||
},
|
||||
// The value of the damage multiplier
|
||||
value: {
|
||||
type: Number,
|
||||
defaultValue: 0.5,
|
||||
allowedValues: [0, 0.5, 2],
|
||||
},
|
||||
});
|
||||
|
||||
DamageMultipliers.attachSchema(DamageMultiplierSchema);
|
||||
DamageMultipliers.attachSchema(PropertySchema);
|
||||
|
||||
const insertDamageMultiplier = new ValidatedMethod({
|
||||
name: 'DamageMultipliers.methods.insert',
|
||||
mixins: [
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: DamageMultipliers,
|
||||
permission: 'edit',
|
||||
schema: DamageMultiplierSchema,
|
||||
run(dm) {
|
||||
return DamageMultipliers.insert(dm);
|
||||
},
|
||||
});
|
||||
|
||||
const updateDamageMultiplier = new ValidatedMethod({
|
||||
name: 'DamageMultipliers.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: DamageMultipliers,
|
||||
permission: 'edit',
|
||||
schema: DamageMultiplierSchema,
|
||||
});
|
||||
|
||||
export default DamageMultipliers;
|
||||
export { DamageMultiplierSchema, insertDamageMultiplier, updateDamageMultiplier };
|
||||
110
app/imports/api/properties/Effects.js
Normal file
110
app/imports/api/properties/Effects.js
Normal file
@@ -0,0 +1,110 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Effects = new Mongo.Collection('effects');
|
||||
|
||||
/*
|
||||
* Effects are reason-value attached to skills and abilities
|
||||
* that modify their final value or presentation in some way
|
||||
*/
|
||||
let EffectSchema = schema({
|
||||
_id: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
operation: {
|
||||
type: String,
|
||||
defaultValue: 'add',
|
||||
allowedValues: [
|
||||
'base',
|
||||
'add',
|
||||
'mul',
|
||||
'min',
|
||||
'max',
|
||||
'advantage',
|
||||
'disadvantage',
|
||||
'passiveAdd',
|
||||
'fail',
|
||||
'conditional',
|
||||
],
|
||||
},
|
||||
calculation: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
//which stat the effect is applied to
|
||||
stat: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
const EffectComputedSchema = new SimpleSchema({
|
||||
// The computed result of the effect
|
||||
result: {
|
||||
type: SimpleSchema.oneOf(Number, String),
|
||||
optional: true,
|
||||
},
|
||||
}).extend(EffectSchema);
|
||||
|
||||
Effects.attachSchema(EffectComputedSchema);
|
||||
Effects.attachSchema(PropertySchema);
|
||||
|
||||
const insertEffect = new ValidatedMethod({
|
||||
name: 'Effects.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Effects,
|
||||
permission: 'edit',
|
||||
schema: EffectSchema,
|
||||
run(effect) {
|
||||
return Effects.insert(effect);
|
||||
},
|
||||
});
|
||||
|
||||
const updateEffect = new ValidatedMethod({
|
||||
name: 'Effects.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Effects,
|
||||
permission: 'edit',
|
||||
schema: EffectSchema,
|
||||
skipRecompute({update}){
|
||||
let fields = getModifierFields(update);
|
||||
return !fields.hasAny([
|
||||
'operation',
|
||||
'calculation',
|
||||
'stat',
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
export default Effects;
|
||||
export { EffectSchema };
|
||||
101
app/imports/api/properties/Experiences.js
Normal file
101
app/imports/api/properties/Experiences.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import recomputeCreatureXP from '/imports/api/creature/creatureComputation.js';
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Experiences = new Mongo.Collection("experience");
|
||||
|
||||
let ExperienceSchema = schema({
|
||||
title: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Potentially long description of the event
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The amount of XP this experience gives
|
||||
value: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
// The real-world date that it occured
|
||||
date: {
|
||||
type: Date,
|
||||
autoValue: function() {
|
||||
// If the date isn't set, set it to now
|
||||
if (!this.isSet) {
|
||||
return new Date();
|
||||
}
|
||||
},
|
||||
},
|
||||
// The date in-world of this event
|
||||
worldDate: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
Experiences.attachSchema(ExperienceSchema);
|
||||
Experiences.attachSchema(PropertySchema);
|
||||
|
||||
const insertExperience = new ValidatedMethod({
|
||||
name: 'Experiences.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Experiences,
|
||||
permission: 'edit',
|
||||
schema: ExperienceSchema,
|
||||
skipRecompute(experience){
|
||||
return !experience.value;
|
||||
},
|
||||
run(experience) {
|
||||
let result = Experiences.insert(experience);
|
||||
if (experience.value){
|
||||
recomputeCreatureXP(charId);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
const updateExperience = new ValidatedMethod({
|
||||
name: 'Experiences.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Experiences,
|
||||
permission: 'edit',
|
||||
schema: ExperienceSchema,
|
||||
skipRecompute({update}){
|
||||
return !('value' in update);
|
||||
},
|
||||
run({_id, update, charId}) {
|
||||
let result = Experiences.update(_id, {$set: update});
|
||||
if ('value' in update){
|
||||
recomputeCreatureXP(charId);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
export default Experiences;
|
||||
export { ExperienceSchema, insertExperience, updateExperience };
|
||||
70
app/imports/api/properties/Features.js
Normal file
70
app/imports/api/properties/Features.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Features = new Mongo.Collection('features');
|
||||
|
||||
let FeatureSchema = new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
enabled: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
alwaysEnabled: {
|
||||
type: Boolean,
|
||||
defaultValue: true
|
||||
},
|
||||
});
|
||||
|
||||
FeatureSchema.extend(ColorSchema);
|
||||
|
||||
Features.attachSchema(FeatureSchema);
|
||||
Features.attachSchema(PropertySchema);
|
||||
|
||||
const insertFeature = new ValidatedMethod({
|
||||
name: 'Features.methods.insert',
|
||||
mixins: [
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocAncestryMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Features,
|
||||
permission: 'edit',
|
||||
schema: FeatureSchema,
|
||||
run(feature) {
|
||||
return Features.insert(feature);
|
||||
},
|
||||
});
|
||||
|
||||
const updateFeature = new ValidatedMethod({
|
||||
name: 'Features.methods.update',
|
||||
mixins: [
|
||||
updateSchemaMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Features,
|
||||
permission: 'edit',
|
||||
schema: FeatureSchema,
|
||||
});
|
||||
|
||||
export default Features;
|
||||
export { FeatureSchema, insertFeature, updateFeature }
|
||||
56
app/imports/api/properties/Folders.js
Normal file
56
app/imports/api/properties/Folders.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Folders = new Mongo.Collection('folders');
|
||||
|
||||
// Folders organize a character sheet into a tree, particularly to group things
|
||||
// like 'race' and 'background'
|
||||
let FolderSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
Folders.attachSchema(FolderSchema);
|
||||
Folders.attachSchema(PropertySchema);
|
||||
|
||||
const insertFolder = new ValidatedMethod({
|
||||
name: 'Folders.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Folders,
|
||||
permission: 'edit',
|
||||
schema: FolderSchema,
|
||||
run(folder) {
|
||||
return Folders.insert(folder);
|
||||
},
|
||||
});
|
||||
|
||||
const updateFolder = new ValidatedMethod({
|
||||
name: 'Folders.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Folders,
|
||||
permission: 'edit',
|
||||
schema: FolderSchema,
|
||||
});
|
||||
|
||||
export default Folders;
|
||||
export { FolderSchema, insertFolder, updateFolder };
|
||||
62
app/imports/api/properties/Items.js
Normal file
62
app/imports/api/properties/Items.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||
|
||||
Items = new Mongo.Collection("items");
|
||||
|
||||
ItemSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: "New Item",
|
||||
},
|
||||
// Plural name of the item, if there is more than one
|
||||
plural: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Number currently held
|
||||
quantity: {
|
||||
type: SimpleSchema.Integer,
|
||||
min: 0,
|
||||
defaultValue: 1
|
||||
},
|
||||
// Weight per item in the stack
|
||||
weight: {
|
||||
type: Number,
|
||||
min: 0,
|
||||
defaultValue: 0,
|
||||
},
|
||||
// Value per item in the stack, in gold pieces
|
||||
value: {
|
||||
type: Number,
|
||||
min: 0,
|
||||
defaultValue: 0,
|
||||
},
|
||||
// If this item is equipped, it requires attunement
|
||||
// Being equipped is `enabled === true`
|
||||
requiresAttunement: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Show increment/decrement buttons in item lists
|
||||
showIncrement: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
ItemSchema.extend(ColorSchema);
|
||||
|
||||
Items.attachSchema(ItemSchema);
|
||||
Items.attachSchema(PropertySchema);
|
||||
Items.attachSchema(ChildSchema);
|
||||
|
||||
export default Items;
|
||||
export { ItemSchema };
|
||||
62
app/imports/api/properties/Notes.js
Normal file
62
app/imports/api/properties/Notes.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Notes = new Mongo.Collection("notes");
|
||||
|
||||
let NoteSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
NoteSchema.extend(ColorSchema);
|
||||
|
||||
Notes.attachSchema(NoteSchema);
|
||||
Notes.attachSchema(PropertySchema);
|
||||
|
||||
const insertNote = new ValidatedMethod({
|
||||
name: 'Notes.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
setDocToLastMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Notes,
|
||||
permission: 'edit',
|
||||
schema: NoteSchema,
|
||||
run(note) {
|
||||
return Notes.insert(note);
|
||||
},
|
||||
});
|
||||
|
||||
const updateNote = new ValidatedMethod({
|
||||
name: 'Notes.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Notes,
|
||||
permission: 'edit',
|
||||
schema: NoteSchema,
|
||||
});
|
||||
|
||||
export default Notes;
|
||||
export { NoteSchema, insertNote, updateNote };
|
||||
72
app/imports/api/properties/Proficiencies.js
Normal file
72
app/imports/api/properties/Proficiencies.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Proficiencies = new Mongo.Collection("proficiencies");
|
||||
|
||||
let ProficiencySchema = schema({
|
||||
// The variableName of the skill to apply this to
|
||||
skill: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// A number representing how proficient the character is
|
||||
value: {
|
||||
type: Number,
|
||||
allowedValues: [0.5, 1, 2],
|
||||
defaultValue: 1,
|
||||
},
|
||||
});
|
||||
|
||||
Proficiencies.attachSchema(ProficiencySchema);
|
||||
Proficiencies.attachSchema(PropertySchema);
|
||||
|
||||
const insertProficiency = new ValidatedMethod({
|
||||
name: 'Proficiencies.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Proficiencies,
|
||||
permission: 'edit',
|
||||
schema: ProficiencySchema,
|
||||
run(prof) {
|
||||
return Proficiencies.insert(prof);
|
||||
},
|
||||
});
|
||||
|
||||
const updateProficiency = new ValidatedMethod({
|
||||
name: 'Proficiencies.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Proficiencies,
|
||||
permission: 'edit',
|
||||
schema: ProficiencySchema,
|
||||
skipRecompute({update}){
|
||||
let fields = getModifierFields(update);
|
||||
return !fields.hasAny([
|
||||
'value',
|
||||
'skill',
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
export default Proficiencies;
|
||||
export { ProficiencySchema, insertProficiency, updateProficiency };
|
||||
64
app/imports/api/properties/Properties.js
Normal file
64
app/imports/api/properties/Properties.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import SoftRemovableSchema from '/imports/api/parenting/SoftRemovableSchema.js';
|
||||
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
|
||||
import softRemove from '/imports/api/parenting/softRemove.js';
|
||||
import getCollectionByName from '/imports/api/parenting/getCollectionByName.js';
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
|
||||
const PropertySchema = new SimpleSchema({
|
||||
charId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
optional: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
enabled: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
},
|
||||
order: {
|
||||
type: SimpleSchema.Integer,
|
||||
index: true,
|
||||
},
|
||||
});
|
||||
|
||||
PropertySchema.extend(SoftRemovableSchema);
|
||||
PropertySchema.extend(ChildSchema);
|
||||
|
||||
// Always recomputes the character, because we don't know the extent of the tree
|
||||
// that was removed with this document
|
||||
const softRemoveProperty = new ValidatedMethod({
|
||||
name: 'softRemoveProperty',
|
||||
mixins: [
|
||||
simpleSchemaMixin,
|
||||
recomputeCreatureMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
getCharId({_id, collection}){
|
||||
let col = getCollectionByName(collection);
|
||||
let doc = col.findOne(_id, {fields: {charId: 1}});
|
||||
if (!doc || !doc.charId){
|
||||
throw new Meteor.Error(`Could not find charId of ${_id} in ${collection}`);
|
||||
} else {
|
||||
return doc.charId;
|
||||
}
|
||||
},
|
||||
permission: 'edit',
|
||||
schema: new SimpleSchema({
|
||||
_id: SimpleSchema.RegEx.Id,
|
||||
collection: String,
|
||||
}),
|
||||
run({_id, collection}){
|
||||
softRemove({_id, collection});
|
||||
},
|
||||
});
|
||||
|
||||
export { PropertySchema, softRemoveProperty };
|
||||
135
app/imports/api/properties/Rolls.js
Normal file
135
app/imports/api/properties/Rolls.js
Normal file
@@ -0,0 +1,135 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import AdjustmentSchema from '/imports/api/creature/subSchemas/AdjustmentSchema.js';
|
||||
import StoredBuffSchema from '/imports/api/properties/Buffs.js';
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Rolls = new Mongo.Collection('rolls');
|
||||
|
||||
let RollChildrenSchema = new SimpleSchema({
|
||||
// The adjustments to be applied
|
||||
adjustments: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'adjustments.$': {
|
||||
type: AdjustmentSchema,
|
||||
},
|
||||
// The buffs to be applied
|
||||
buffs: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'buffs.$': {
|
||||
type: StoredBuffSchema,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Rolls are children to actions or other rolls, they are triggered with 0 or
|
||||
* more targets and then apply their results to the character taking the action
|
||||
* or the target of the action.
|
||||
*
|
||||
* # Rolls are resolved in one of two ways:
|
||||
* Regular rolls:
|
||||
* The target number is computed in the target's context
|
||||
* The roll is computed in the action taker's context
|
||||
* If the roll meets or exceeds the target number, the adjustments and buffs
|
||||
* are applied
|
||||
*
|
||||
* Saving throws:
|
||||
* The target number is computed in the action taker's context
|
||||
* The roll is computed in the target's context
|
||||
* If the roll fails to meet or exceed the target number, the adjustments and
|
||||
* child rolls are applied
|
||||
*/
|
||||
let RollSchema = new SimpleSchema({
|
||||
// The roll made against the target value. A calculation that resolves to a
|
||||
// number or a roll. If it is a number, it will be added to a d20 roll
|
||||
roll: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The target number to meet or exceed
|
||||
targetNumber: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Is this roll a saving throw
|
||||
rollType: {
|
||||
type: String,
|
||||
defaultValue: 'roll',
|
||||
allowedValues: ['roll', 'savingThrow'],
|
||||
},
|
||||
// Apply this only if the parent roll missed
|
||||
// i.e. roll failed or target suceeded on their save
|
||||
onMiss: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Swap who wins ties
|
||||
invertTies: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Effects can apply to this tag specifically
|
||||
// Ranged spell attack, Ranged weapon attack, etc.
|
||||
tags: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'tags.$': {
|
||||
type: String,
|
||||
},
|
||||
// The buffs and adjustments to apply based on the outcome of the roll
|
||||
hit: {
|
||||
type: RollChildrenSchema,
|
||||
defaultValue: {},
|
||||
},
|
||||
miss: {
|
||||
type: RollChildrenSchema,
|
||||
defaultValue: {},
|
||||
},
|
||||
});
|
||||
|
||||
Rolls.attachSchema(RollSchema);
|
||||
Rolls.attachSchema(PropertySchema);
|
||||
|
||||
const insertRoll = new ValidatedMethod({
|
||||
name: 'Rolls.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Rolls,
|
||||
permission: 'edit',
|
||||
schema: RollSchema,
|
||||
run(roll) {
|
||||
return Rolls.insert(roll);
|
||||
},
|
||||
});
|
||||
|
||||
const updateRoll = new ValidatedMethod({
|
||||
name: 'Rolls.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Rolls,
|
||||
permission: 'edit',
|
||||
schema: RollSchema,
|
||||
});
|
||||
|
||||
export default Rolls;
|
||||
export { RollSchema, insertRoll, updateRoll };
|
||||
149
app/imports/api/properties/Skills.js
Normal file
149
app/imports/api/properties/Skills.js
Normal file
@@ -0,0 +1,149 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||
|
||||
// Mixins
|
||||
import recomputeCreatureMixin from '/imports/api/creature/mixins/recomputeCreatureMixin.js';
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
let Skills = new Mongo.Collection("skills");
|
||||
|
||||
/*
|
||||
* Skills are anything that results in a modifier to be added to a D20
|
||||
* Skills have an ability score modifier that they use as their basis
|
||||
*/
|
||||
let SkillSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The technical, lowercase, single-word name used in formulae
|
||||
variableName: {
|
||||
type: String,
|
||||
regEx: /^\w*[a-z]\w*$/i,
|
||||
},
|
||||
// The variable name of the ability this skill relies on
|
||||
ability: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// What type of skill is this
|
||||
type: {
|
||||
type: String,
|
||||
allowedValues: [
|
||||
"skill",
|
||||
"save",
|
||||
"check",
|
||||
"tool",
|
||||
"weapon",
|
||||
"language",
|
||||
"utility", //not displayed anywhere
|
||||
],
|
||||
defaultValue: 'skill',
|
||||
},
|
||||
// If the baseValue is higher than the computed value, it will be used as `value`
|
||||
baseValue: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
// The base proficiency of this skill
|
||||
baseProficiency: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
SkillSchema.extend(ColorSchema);
|
||||
|
||||
let ComputedSkillSchema = schema({
|
||||
// Computed value of skill to be added to skill rolls
|
||||
value: {
|
||||
type: Number,
|
||||
defaultValue: 0,
|
||||
},
|
||||
// Computed value added by the ability
|
||||
abilityMod: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
// Computed advantage/disadvantage
|
||||
advantage: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
allowedValues: [-1, 0, 1],
|
||||
},
|
||||
// Computed bonus to passive checks
|
||||
passiveBonus: {
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
// Computed proficiency multiplier
|
||||
proficiency: {
|
||||
type: Number,
|
||||
allowedValues: [0, 0.5, 1, 2],
|
||||
defaultValue: 0,
|
||||
},
|
||||
// Computed number of total conditional benefits
|
||||
conditionalBenefits: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
// Computed number of things forcing this skill to fail
|
||||
fail: {
|
||||
type: SimpleSchema.Integer,
|
||||
optional: true,
|
||||
},
|
||||
}).extend(SkillSchema);
|
||||
|
||||
Skills.attachSchema(ComputedSkillSchema);
|
||||
Skills.attachSchema(PropertySchema);
|
||||
|
||||
const insertSkill = new ValidatedMethod({
|
||||
name: 'Skills.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
recomputeCreatureMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Skills,
|
||||
permission: 'edit',
|
||||
schema: SkillSchema,
|
||||
run(skill) {
|
||||
return Skills.insert(skill);
|
||||
},
|
||||
});
|
||||
|
||||
const updateSkill = new ValidatedMethod({
|
||||
name: 'Skills.methods.update',
|
||||
mixins: [
|
||||
recomputeCreatureMixin,
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Skills,
|
||||
permission: 'edit',
|
||||
schema: SkillSchema,
|
||||
skipRecompute({update}){
|
||||
let fields = getModifierFields(update);
|
||||
return !fields.hasAny([
|
||||
'variableName',
|
||||
'ability',
|
||||
'type',
|
||||
'baseValue',
|
||||
'baseProficiency',
|
||||
]);
|
||||
},
|
||||
});
|
||||
|
||||
export default Skills;
|
||||
export { SkillSchema };
|
||||
74
app/imports/api/properties/SpellLists.js
Normal file
74
app/imports/api/properties/SpellLists.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import ColorSchema from "/imports/api/creature/subSchemas/ColorSchema.js";
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
|
||||
let SpellLists = new Mongo.Collection("spellLists");
|
||||
|
||||
let SpellListSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// The technical, lowercase, single-word name used in formulae
|
||||
variableName: {
|
||||
type: String,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
min: 3,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// Calculation of how many spells in this list can be prepared
|
||||
maxPrepared: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
|
||||
SpellListSchema.extend(ColorSchema);
|
||||
|
||||
SpellLists.attachSchema(SpellListSchema);
|
||||
SpellLists.attachSchema(PropertySchema);
|
||||
|
||||
const insertSpellList = new ValidatedMethod({
|
||||
name: 'SpellLists.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: SpellLists,
|
||||
permission: 'edit',
|
||||
schema: SpellListSchema,
|
||||
run(spellList) {
|
||||
return SpellLists.insert(spellList);
|
||||
},
|
||||
});
|
||||
|
||||
const updateSpellList = new ValidatedMethod({
|
||||
name: 'SpellLists.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: SpellLists,
|
||||
permission: 'edit',
|
||||
schema: SpellListSchema,
|
||||
});
|
||||
|
||||
export default SpellLists;
|
||||
export { SpellListSchema }
|
||||
132
app/imports/api/properties/Spells.js
Normal file
132
app/imports/api/properties/Spells.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import ColorSchema from '/imports/api/creature/subSchemas/ColorSchema.js';
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import schema from '/imports/api/schema.js';
|
||||
import { PropertySchema } from '/imports/api/properties/Properties.js'
|
||||
|
||||
// Mixins
|
||||
import creaturePermissionMixin from '/imports/api/creature/mixins/creaturePermissionMixin.js';
|
||||
import { setDocToLastMixin } from '/imports/api/creature/mixins/setDocToLastMixin.js';
|
||||
import { setDocAncestryMixin, ensureAncestryContainsCharIdMixin } from '/imports/api/parenting/parenting.js';
|
||||
import simpleSchemaMixin from '/imports/api/creature/mixins/simpleSchemaMixin.js';
|
||||
import propagateInheritanceUpdateMixin from '/imports/api/creature/mixins/propagateInheritanceUpdateMixin.js';
|
||||
import updateSchemaMixin from '/imports/api/creature/mixins/updateSchemaMixin.js';
|
||||
|
||||
const magicSchools = [
|
||||
'abjuration',
|
||||
'conjuration',
|
||||
'divination',
|
||||
'enchantment',
|
||||
'evocation',
|
||||
'illusion',
|
||||
'necromancy',
|
||||
'transmutation',
|
||||
];
|
||||
|
||||
let Spells = new Mongo.Collection('spells');
|
||||
|
||||
let SpellSchema = schema({
|
||||
name: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
// If it's always prepared, it doesn't count against the number of spells
|
||||
// prepared in a spell list, and enabled should be true
|
||||
alwaysPrepared: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Spell lists that this spell appears on
|
||||
spellLists: {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
},
|
||||
'spellLists.$': {
|
||||
type: String,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
castingTime: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: 'action',
|
||||
},
|
||||
range: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
duration: {
|
||||
type: String,
|
||||
optional: true,
|
||||
defaultValue: 'Instantaneous',
|
||||
},
|
||||
verbal: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
somatic: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
concentration: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
material: {
|
||||
type: String,
|
||||
optional: true,
|
||||
},
|
||||
ritual: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
level: {
|
||||
type: SimpleSchema.Integer,
|
||||
defaultValue: 1,
|
||||
max: 9,
|
||||
min: 0,
|
||||
},
|
||||
school: {
|
||||
type: String,
|
||||
defaultValue: 'abjuration',
|
||||
allowedValues: magicSchools,
|
||||
},
|
||||
});
|
||||
|
||||
SpellSchema.extend(ColorSchema);
|
||||
|
||||
Spells.attachSchema(SpellSchema);
|
||||
Spells.attachSchema(PropertySchema);
|
||||
|
||||
const insertSpell = new ValidatedMethod({
|
||||
name: 'Spells.methods.insert',
|
||||
mixins: [
|
||||
creaturePermissionMixin,
|
||||
setDocToLastMixin,
|
||||
setDocAncestryMixin,
|
||||
ensureAncestryContainsCharIdMixin,
|
||||
simpleSchemaMixin,
|
||||
],
|
||||
collection: Spells,
|
||||
permission: 'edit',
|
||||
schema: SpellSchema,
|
||||
run(spell) {
|
||||
return Spells.insert(spell);
|
||||
},
|
||||
});
|
||||
|
||||
const updateSpell = new ValidatedMethod({
|
||||
name: 'Spells.methods.update',
|
||||
mixins: [
|
||||
propagateInheritanceUpdateMixin,
|
||||
updateSchemaMixin,
|
||||
creaturePermissionMixin,
|
||||
],
|
||||
collection: Spells,
|
||||
permission: 'edit',
|
||||
schema: SpellSchema,
|
||||
});
|
||||
|
||||
export default Spells;
|
||||
export { SpellSchema, insertSpell, updateSpell };
|
||||
Reference in New Issue
Block a user