Denormalized some calculations into recomputation step
This commit is contained in:
@@ -15,6 +15,8 @@ export default class ComputationMemo {
|
|||||||
this.classes = {};
|
this.classes = {};
|
||||||
this.togglesById = {};
|
this.togglesById = {};
|
||||||
this.toggleIds = new Set();
|
this.toggleIds = new Set();
|
||||||
|
// Properties that have calculations, but don't impact other properties
|
||||||
|
this.endStepPropsById = {};
|
||||||
// First note all the ids of all the toggles
|
// First note all the ids of all the toggles
|
||||||
props.forEach((prop) => {
|
props.forEach((prop) => {
|
||||||
if (
|
if (
|
||||||
@@ -49,6 +51,8 @@ export default class ComputationMemo {
|
|||||||
this.addProficiency(prop);
|
this.addProficiency(prop);
|
||||||
} else if (prop.type === 'classLevel'){
|
} else if (prop.type === 'classLevel'){
|
||||||
this.addClassLevel(prop);
|
this.addClassLevel(prop);
|
||||||
|
} else {
|
||||||
|
this.addEndStepProp(prop);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (let name in creature.denormalizedStats){
|
for (let name in creature.denormalizedStats){
|
||||||
@@ -181,6 +185,10 @@ export default class ComputationMemo {
|
|||||||
});
|
});
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
addEndStepProp(prop){
|
||||||
|
prop = this.registerProperty(prop);
|
||||||
|
this.endStepPropsById[prop._id] = prop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAbility(prop){
|
function isAbility(prop){
|
||||||
@@ -206,7 +214,7 @@ function isSkillOperation(prop){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function propDetails(prop){
|
function propDetails(prop){
|
||||||
return propDetailsByType[prop.type]() || {};
|
return propDetailsByType[prop.type] && propDetailsByType[prop.type]() || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const propDetailsByType = {
|
const propDetailsByType = {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import evaluateCalculation from '/imports/api/creature/computation/evaluateCalculation.js';
|
||||||
|
|
||||||
|
export default function computeEndStepProperty(prop, memo){
|
||||||
|
switch (prop.type){
|
||||||
|
case 'action':
|
||||||
|
case 'spell':
|
||||||
|
computeAction(prop, memo);
|
||||||
|
break;
|
||||||
|
case 'attack':
|
||||||
|
computeAction(prop, memo);
|
||||||
|
computeAttack(prop, memo);
|
||||||
|
break;
|
||||||
|
case 'savingThrow':
|
||||||
|
computeSavingThrow(prop, memo);
|
||||||
|
break;
|
||||||
|
case 'spellList':
|
||||||
|
computeSpellList(prop, memo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeAction(prop, memo){
|
||||||
|
let {value, errors} = evaluateCalculation(prop.uses, memo);
|
||||||
|
prop.usesResult = value;
|
||||||
|
if (errors.length){
|
||||||
|
prop.usesErrors = errors;
|
||||||
|
} else {
|
||||||
|
delete prop.usesErrors;
|
||||||
|
}
|
||||||
|
// TODO compute resources.$.$.available and insufficientResources
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeAttack(prop, memo){
|
||||||
|
let {value, errors} = evaluateCalculation(prop.rollBonus, memo);
|
||||||
|
prop.rollBonusResult = value;
|
||||||
|
if (errors.length){
|
||||||
|
prop.rollBonusErrors = errors;
|
||||||
|
} else {
|
||||||
|
delete prop.rollBonusErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeSavingThrow(prop, memo){
|
||||||
|
let {value, errors} = evaluateCalculation(prop.dc, memo);
|
||||||
|
prop.dcResult = value;
|
||||||
|
if (errors.length){
|
||||||
|
prop.dcErrors = errors;
|
||||||
|
} else {
|
||||||
|
delete prop.dcErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeSpellList(prop, memo){
|
||||||
|
let {value, errors} = evaluateCalculation(prop.maxPrepared, memo);
|
||||||
|
prop.maxPreparedResult = value;
|
||||||
|
if (errors.length){
|
||||||
|
prop.maxPreparedErrors = errors;
|
||||||
|
} else {
|
||||||
|
delete prop.maxPreparedErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import computeLevels from '/imports/api/creature/computation/computeLevels.js';
|
|||||||
import computeStat from '/imports/api/creature/computation/computeStat.js';
|
import computeStat from '/imports/api/creature/computation/computeStat.js';
|
||||||
import computeEffect from '/imports/api/creature/computation/computeEffect.js';
|
import computeEffect from '/imports/api/creature/computation/computeEffect.js';
|
||||||
import computeToggle from '/imports/api/creature/computation/computeToggle.js';
|
import computeToggle from '/imports/api/creature/computation/computeToggle.js';
|
||||||
|
import computeEndStepProperty from '/imports/api/creature/computation/computeEndStepProperty.js';
|
||||||
|
|
||||||
export default function computeMemo(memo){
|
export default function computeMemo(memo){
|
||||||
// Compute level
|
// Compute level
|
||||||
@@ -15,8 +16,12 @@ export default function computeMemo(memo){
|
|||||||
each(memo.unassignedEffects, effect => {
|
each(memo.unassignedEffects, effect => {
|
||||||
computeEffect(effect, memo);
|
computeEffect(effect, memo);
|
||||||
});
|
});
|
||||||
|
// Compute toggles which didn't already get computed by dependencies
|
||||||
forOwn(memo.togglesById, toggle => {
|
forOwn(memo.togglesById, toggle => {
|
||||||
computeToggle(toggle, memo);
|
computeToggle(toggle, memo);
|
||||||
});
|
});
|
||||||
// Compute class levels
|
// Compute end step properties
|
||||||
|
forOwn(memo.endStepPropsById, prop => {
|
||||||
|
computeEndStepProperty(prop, memo);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import math from '/imports/math.js';
|
|||||||
|
|
||||||
/* Convert a calculation into a constant output and errors*/
|
/* Convert a calculation into a constant output and errors*/
|
||||||
export default function evaluateCalculation(string, memo){
|
export default function evaluateCalculation(string, memo){
|
||||||
if (!string) return string;
|
if (!string) return {errors: [], value: string};
|
||||||
let errors = [];
|
let errors = [];
|
||||||
// Parse the string using mathjs
|
// Parse the string using mathjs
|
||||||
let calc;
|
let calc;
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ const calculationPropertyTypes = [
|
|||||||
'proficiency',
|
'proficiency',
|
||||||
'classLevel',
|
'classLevel',
|
||||||
'toggle',
|
'toggle',
|
||||||
|
// End step types
|
||||||
|
'action',
|
||||||
|
'attack',
|
||||||
|
'savingThrow',
|
||||||
|
'spellList',
|
||||||
|
'spell',
|
||||||
];
|
];
|
||||||
|
|
||||||
export function recomputeCreatureById(creatureId){
|
export function recomputeCreatureById(creatureId){
|
||||||
|
|||||||
@@ -1,16 +1,29 @@
|
|||||||
import { Meteor } from 'meteor/meteor'
|
import { Meteor } from 'meteor/meteor'
|
||||||
import { isEqual, forOwn } from 'lodash';
|
import { isEqual, forOwn } from 'lodash';
|
||||||
|
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
||||||
|
// Schemas
|
||||||
|
// Calculated props
|
||||||
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills.js';
|
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills.js';
|
||||||
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes.js';
|
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||||
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects.js';
|
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects.js';
|
||||||
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles.js';
|
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||||
import CreatureProperties from '/imports/api/creature/CreatureProperties.js';
|
// End step props
|
||||||
|
import { ComputedOnlyActionSchema } from '/imports/api/properties/Actions.js';
|
||||||
|
import { ComputedOnlyAttackSchema } from '/imports/api/properties/Attacks.js';
|
||||||
|
import { ComputedOnlySavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
||||||
|
import { ComputedOnlySpellListSchema } from '/imports/api/properties/SpellLists.js';
|
||||||
|
import { ComputedOnlySpellSchema } from '/imports/api/properties/Spells.js';
|
||||||
|
|
||||||
const schemasByType = {
|
const schemasByType = {
|
||||||
'skill': ComputedOnlySkillSchema,
|
'skill': ComputedOnlySkillSchema,
|
||||||
'attribute': ComputedOnlyAttributeSchema,
|
'attribute': ComputedOnlyAttributeSchema,
|
||||||
'effect': ComputedOnlyEffectSchema,
|
'effect': ComputedOnlyEffectSchema,
|
||||||
'toggle': ComputedOnlyToggleSchema,
|
'toggle': ComputedOnlyToggleSchema,
|
||||||
|
'action': ComputedOnlyActionSchema,
|
||||||
|
'attack': ComputedOnlyAttackSchema,
|
||||||
|
'savingThrow': ComputedOnlySavingThrowSchema,
|
||||||
|
'spellList': ComputedOnlySpellListSchema,
|
||||||
|
'spell': ComputedOnlySpellSchema,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function writeAlteredProperties(memo){
|
export default function writeAlteredProperties(memo){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import ResourcesSchema from '/imports/api/properties/subSchemas/ResourcesSchema.js'
|
import ResourcesSchema from '/imports/api/properties/subSchemas/ResourcesSchema.js'
|
||||||
|
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Actions are things a character can do
|
* Actions are things a character can do
|
||||||
@@ -64,4 +65,39 @@ let ActionSchema = new SimpleSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { ActionSchema };
|
const ComputedOnlyActionSchema = new SimpleSchema({
|
||||||
|
usesResult: {
|
||||||
|
type: SimpleSchema.Integer,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
usesErrors: {
|
||||||
|
type: Array,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'usesErrors.$':{
|
||||||
|
type: ErrorSchema,
|
||||||
|
},
|
||||||
|
resources: Object,
|
||||||
|
'resources.itemsConsumed': Array,
|
||||||
|
'resources.itemsConsumed.$': Object,
|
||||||
|
'resources.itemsConsumed.$.available': {
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'resources.attributesConsumed': Array,
|
||||||
|
'resources.attributesConsumed.$': Object,
|
||||||
|
'resources.attributesConsumed.$.available': {
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
insufficientResources: {
|
||||||
|
type: Boolean,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ComputedActionSchema = new SimpleSchema()
|
||||||
|
.extend(ActionSchema)
|
||||||
|
.extend(ComputedOnlyActionSchema);
|
||||||
|
|
||||||
|
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import SimpleSchema from 'simpl-schema';
|
|||||||
|
|
||||||
const AdjustmentSchema = new SimpleSchema({
|
const AdjustmentSchema = new SimpleSchema({
|
||||||
// The roll that determines how much to change the attribute
|
// The roll that determines how much to change the attribute
|
||||||
|
// This can be simplified, but should only compute when activated
|
||||||
amount: {
|
amount: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import { ActionSchema } from '/imports/api/properties/Actions.js';
|
import { ActionSchema, ComputedOnlyActionSchema } from '/imports/api/properties/Actions.js';
|
||||||
|
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||||
|
|
||||||
// Attacks are special instances of actions
|
// Attacks are special instances of actions
|
||||||
let AttackSchema = new SimpleSchema()
|
let AttackSchema = new SimpleSchema()
|
||||||
@@ -25,4 +26,24 @@ let AttackSchema = new SimpleSchema()
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { AttackSchema };
|
const ComputedOnlyAttackSchema = new SimpleSchema()
|
||||||
|
.extend(ComputedOnlyActionSchema)
|
||||||
|
.extend({
|
||||||
|
rollBonusResult: {
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
rollBonusErrors: {
|
||||||
|
type: Array,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'rollBonusErrors.$':{
|
||||||
|
type: ErrorSchema,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ComputedAttackSchema = new SimpleSchema()
|
||||||
|
.extend(AttackSchema)
|
||||||
|
.extend(ComputedOnlyAttackSchema);
|
||||||
|
|
||||||
|
export { AttackSchema, ComputedOnlyAttackSchema, ComputedAttackSchema };
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import DAMAGE_TYPES from '/imports/constants/DAMAGE_TYPES.js';
|
|||||||
|
|
||||||
const DamageSchema = new SimpleSchema({
|
const DamageSchema = new SimpleSchema({
|
||||||
// The roll that determines how much to damage the attribute
|
// The roll that determines how much to damage the attribute
|
||||||
|
// This can be simplified, but only computed when applied
|
||||||
amount: {
|
amount: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import SimpleSchema from 'simpl-schema';
|
|||||||
* child rolls are applied
|
* child rolls are applied
|
||||||
*/
|
*/
|
||||||
let RollSchema = new SimpleSchema({
|
let RollSchema = new SimpleSchema({
|
||||||
// The roll
|
// The roll, can be simplified, but only computed in context
|
||||||
roll: {
|
roll: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||||
|
|
||||||
// These are the rolls made when saves are called for
|
// These are the rolls made when saves are called for
|
||||||
// For the saving throw bonus or proficiency, see ./Skills.js
|
// For the saving throw bonus or proficiency, see ./Skills.js
|
||||||
@@ -18,4 +19,22 @@ let SavingThrowSchema = new SimpleSchema ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { SavingThrowSchema };
|
const ComputedOnlySavingThrowSchema = new SimpleSchema({
|
||||||
|
dcResult: {
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
dcErrors: {
|
||||||
|
type: Array,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'dcErrors.$':{
|
||||||
|
type: ErrorSchema,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ComputedSavingThrowSchema = new SimpleSchema()
|
||||||
|
.extend(SavingThrowSchema)
|
||||||
|
.extend(ComputedOnlySavingThrowSchema);
|
||||||
|
|
||||||
|
export { SavingThrowSchema, ComputedOnlySavingThrowSchema, ComputedSavingThrowSchema };
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
import ErrorSchema from '/imports/api/properties/subSchemas/ErrorSchema.js';
|
||||||
|
|
||||||
let SpellListSchema = new SimpleSchema({
|
let SpellListSchema = new SimpleSchema({
|
||||||
name: {
|
name: {
|
||||||
@@ -16,4 +17,22 @@ let SpellListSchema = new SimpleSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { SpellListSchema }
|
const ComputedOnlySpellListSchema = new SimpleSchema({
|
||||||
|
maxPreparedResult: {
|
||||||
|
type: Number,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
maxPreparedErrors: {
|
||||||
|
type: Array,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
'maxPreparedErrors.$':{
|
||||||
|
type: ErrorSchema,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const ComputedSpellListSchema = new SimpleSchema()
|
||||||
|
.extend(SpellListSchema)
|
||||||
|
.extend(ComputedOnlySpellListSchema);
|
||||||
|
|
||||||
|
export { SpellListSchema, ComputedOnlySpellListSchema, ComputedSpellListSchema };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ActionSchema } from '/imports/api/properties/Actions.js';
|
import { ActionSchema, ComputedOnlyActionSchema } from '/imports/api/properties/Actions.js';
|
||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
|
||||||
const magicSchools = [
|
const magicSchools = [
|
||||||
@@ -93,4 +93,11 @@ let SpellSchema = new SimpleSchema({})
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { SpellSchema };
|
const ComputedOnlySpellSchema = new SimpleSchema()
|
||||||
|
.extend(ComputedOnlyActionSchema);
|
||||||
|
|
||||||
|
const ComputedSpellSchema = new SimpleSchema()
|
||||||
|
.extend(SpellSchema)
|
||||||
|
.extend(ComputedOnlySpellSchema);
|
||||||
|
|
||||||
|
export { SpellSchema, ComputedOnlySpellSchema, ComputedSpellSchema };
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import { ActionSchema } from '/imports/api/properties/Actions.js';
|
import { ComputedActionSchema } from '/imports/api/properties/Actions.js';
|
||||||
import { AdjustmentSchema } from '/imports/api/properties/Adjustments.js';
|
import { AdjustmentSchema } from '/imports/api/properties/Adjustments.js';
|
||||||
import { AttackSchema } from '/imports/api/properties/Attacks.js';
|
import { ComputedAttackSchema } from '/imports/api/properties/Attacks.js';
|
||||||
import { ComputedAttributeSchema } from '/imports/api/properties/Attributes.js';
|
import { ComputedAttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||||
import { BuffSchema } from '/imports/api/properties/Buffs.js';
|
import { BuffSchema } from '/imports/api/properties/Buffs.js';
|
||||||
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
||||||
@@ -15,17 +15,17 @@ import { ItemSchema } from '/imports/api/properties/Items.js';
|
|||||||
import { NoteSchema } from '/imports/api/properties/Notes.js';
|
import { NoteSchema } from '/imports/api/properties/Notes.js';
|
||||||
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
||||||
import { RollSchema } from '/imports/api/properties/Rolls.js';
|
import { RollSchema } from '/imports/api/properties/Rolls.js';
|
||||||
import { SavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
import { ComputedSavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
||||||
import { ComputedSkillSchema } from '/imports/api/properties/Skills.js';
|
import { ComputedSkillSchema } from '/imports/api/properties/Skills.js';
|
||||||
import { SlotSchema } from '/imports/api/properties/Slots.js';
|
import { SlotSchema } from '/imports/api/properties/Slots.js';
|
||||||
import { SpellSchema } from '/imports/api/properties/Spells.js';
|
import { ComputedSpellSchema } from '/imports/api/properties/Spells.js';
|
||||||
import { SpellListSchema } from '/imports/api/properties/SpellLists.js';
|
import { ComputedSpellListSchema } from '/imports/api/properties/SpellLists.js';
|
||||||
import { ToggleSchema } from '/imports/api/properties/Toggles.js';
|
import { ToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||||
|
|
||||||
const propertySchemasIndex = {
|
const propertySchemasIndex = {
|
||||||
action: ActionSchema,
|
action: ComputedActionSchema,
|
||||||
adjustment: AdjustmentSchema,
|
adjustment: AdjustmentSchema,
|
||||||
attack: AttackSchema,
|
attack: ComputedAttackSchema,
|
||||||
attribute: ComputedAttributeSchema,
|
attribute: ComputedAttributeSchema,
|
||||||
buff: BuffSchema,
|
buff: BuffSchema,
|
||||||
classLevel: ClassLevelSchema,
|
classLevel: ClassLevelSchema,
|
||||||
@@ -37,11 +37,11 @@ const propertySchemasIndex = {
|
|||||||
note: NoteSchema,
|
note: NoteSchema,
|
||||||
proficiency: ProficiencySchema,
|
proficiency: ProficiencySchema,
|
||||||
roll: RollSchema,
|
roll: RollSchema,
|
||||||
savingThrow: SavingThrowSchema,
|
savingThrow: ComputedSavingThrowSchema,
|
||||||
skill: ComputedSkillSchema,
|
skill: ComputedSkillSchema,
|
||||||
slot: SlotSchema,
|
slot: SlotSchema,
|
||||||
spellList: SpellListSchema,
|
spellList: ComputedSpellSchema,
|
||||||
spell: SpellSchema,
|
spell: ComputedSpellListSchema,
|
||||||
toggle: ToggleSchema,
|
toggle: ToggleSchema,
|
||||||
container: ContainerSchema,
|
container: ContainerSchema,
|
||||||
item: ItemSchema,
|
item: ItemSchema,
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
|
|
||||||
const ErrorSchema = new SimpleSchema({
|
const ErrorSchema = new SimpleSchema({
|
||||||
// The roll that determines how much to change the attribute
|
|
||||||
message: {
|
message: {
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
// Who this adjustment applies to
|
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -276,9 +276,10 @@
|
|||||||
subheader
|
subheader
|
||||||
>
|
>
|
||||||
<v-subheader>Attacks</v-subheader>
|
<v-subheader>Attacks</v-subheader>
|
||||||
<attack-list-tile
|
<action-list-tile
|
||||||
v-for="attack in attacks"
|
v-for="attack in attacks"
|
||||||
:key="attack._id"
|
:key="attack._id"
|
||||||
|
attack
|
||||||
:model="attack"
|
:model="attack"
|
||||||
:data-id="attack._id"
|
:data-id="attack._id"
|
||||||
@click="clickProperty({_id: attack._id})"
|
@click="clickProperty({_id: attack._id})"
|
||||||
@@ -303,7 +304,6 @@
|
|||||||
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
||||||
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
||||||
import ActionListTile from '/imports/ui/properties/components/actions/ActionListTile.vue';
|
import ActionListTile from '/imports/ui/properties/components/actions/ActionListTile.vue';
|
||||||
import AttackListTile from '/imports/ui/properties/components/actions/AttackListTile.vue';
|
|
||||||
import RestButton from '/imports/ui/creature/RestButton.vue';
|
import RestButton from '/imports/ui/creature/RestButton.vue';
|
||||||
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
import getActiveProperties from '/imports/api/creature/getActiveProperties.js';
|
||||||
|
|
||||||
@@ -346,7 +346,6 @@
|
|||||||
ResourceCard,
|
ResourceCard,
|
||||||
SpellSlotListTile,
|
SpellSlotListTile,
|
||||||
ActionListTile,
|
ActionListTile,
|
||||||
AttackListTile,
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
creatureId: {
|
creatureId: {
|
||||||
@@ -398,10 +397,24 @@
|
|||||||
return getSkillOfType(this.creature, 'language');
|
return getSkillOfType(this.creature, 'language');
|
||||||
},
|
},
|
||||||
actions(){
|
actions(){
|
||||||
return getProperties(this.creature, {type: 'action'});
|
let props = getProperties(this.creature, {type: 'action'}).map(action => {
|
||||||
|
action.children = getActiveProperties({
|
||||||
|
ancestorId: action._id,
|
||||||
|
options: {sort: {order: 1}},
|
||||||
|
});
|
||||||
|
return action;
|
||||||
|
});
|
||||||
|
return props;
|
||||||
},
|
},
|
||||||
attacks(){
|
attacks(){
|
||||||
return getProperties(this.creature, {type: 'attack'});
|
let props = getProperties(this.creature, {type: 'attack'}).map(attack => {
|
||||||
|
attack.children = getActiveProperties({
|
||||||
|
ancestorId: attack._id,
|
||||||
|
options: {sort: {order: 1}},
|
||||||
|
});
|
||||||
|
return attack;
|
||||||
|
});
|
||||||
|
return props;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -3,26 +3,69 @@
|
|||||||
class="ability-list-tile"
|
class="ability-list-tile"
|
||||||
v-on="hasClickListener ? {click} : {}"
|
v-on="hasClickListener ? {click} : {}"
|
||||||
>
|
>
|
||||||
|
<v-list-tile-avatar
|
||||||
|
v-if="attack"
|
||||||
|
class="headline"
|
||||||
|
>
|
||||||
|
{{ rollBonus }}
|
||||||
|
</v-list-tile-avatar>
|
||||||
<v-list-tile-content>
|
<v-list-tile-content>
|
||||||
<v-list-tile-title>
|
<v-list-tile-title>
|
||||||
{{ model.name }}
|
{{ model.name }}
|
||||||
</v-list-tile-title>
|
</v-list-tile-title>
|
||||||
|
<v-list-tile-sub-title
|
||||||
|
v-if="childText"
|
||||||
|
v-html="childText"
|
||||||
|
/>
|
||||||
</v-list-tile-content>
|
</v-list-tile-content>
|
||||||
|
<v-list-tile-action v-if="model.usesResult">
|
||||||
|
<v-list-tile-action-text>
|
||||||
|
{{ model.usesResult - (model.usesUsed) }}/{{ model.usesResult }}
|
||||||
|
</v-list-tile-action-text>
|
||||||
|
</v-list-tile-action>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
inject: {
|
||||||
|
context: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
model: {
|
model: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
}
|
},
|
||||||
|
attack: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hasClickListener(){
|
hasClickListener(){
|
||||||
return this.$listeners && this.$listeners.click
|
return this.$listeners && this.$listeners.click
|
||||||
},
|
},
|
||||||
|
rollBonus(){
|
||||||
|
return numberToSignedString(this.model.rollBonusResult);
|
||||||
|
},
|
||||||
|
childText(){
|
||||||
|
let scope = this.context.creature && this.context.creature.variables;
|
||||||
|
if (!this.model.children || !this.model.children.length) return;
|
||||||
|
let textArray = [];
|
||||||
|
this.model.children.forEach(child => {
|
||||||
|
if (child.type === 'damage'){
|
||||||
|
let { result } = evaluateString(child.amount, scope);
|
||||||
|
textArray.push(`${result} ${child.damageType}`);
|
||||||
|
} else if (child.type === 'savingThrow'){
|
||||||
|
textArray.push(`DC ${child.dcResult} ${child.name}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return textArray.join(' ');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
click(e){
|
click(e){
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
<template lang="html">
|
|
||||||
<v-list-tile
|
|
||||||
class="ability-list-tile"
|
|
||||||
avatar
|
|
||||||
v-on="hasClickListener ? {click} : {}"
|
|
||||||
>
|
|
||||||
<v-list-tile-avatar color="grey darken-1">
|
|
||||||
<computed
|
|
||||||
signed
|
|
||||||
:value="model.rollBonus"
|
|
||||||
class="white--text headline"
|
|
||||||
/>
|
|
||||||
</v-list-tile-avatar>
|
|
||||||
<v-list-tile-content>
|
|
||||||
<v-list-tile-title>
|
|
||||||
{{ model.name }}
|
|
||||||
</v-list-tile-title>
|
|
||||||
</v-list-tile-content>
|
|
||||||
</v-list-tile>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ComputedForCreature from '/imports/ui/components/computation/ComputedForCreature.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Computed: ComputedForCreature,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
model: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
hasClickListener(){
|
|
||||||
return this.$listeners && this.$listeners.click
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
click(e){
|
|
||||||
this.$emit('click', e);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="css" scoped>
|
|
||||||
</style>
|
|
||||||
@@ -1,31 +1,33 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div class="action-viewer">
|
<div class="action-viewer">
|
||||||
<property-field
|
<div class="layout row wrap align-center">
|
||||||
name="Action type"
|
<div>
|
||||||
:value="model.actionType"
|
{{ model.actionType }}
|
||||||
/>
|
</div>
|
||||||
<property-field
|
<div class="flex">
|
||||||
name="Target"
|
<property-tags :tags="model.tags" />
|
||||||
:value="model.target"
|
</div>
|
||||||
/>
|
<div v-if="model.usesResult">
|
||||||
<property-field
|
{{ model.usesResult - (model.usesUsed) }}/{{ model.usesResult }}
|
||||||
v-if="model.tags.length"
|
</div>
|
||||||
name="tags"
|
</div>
|
||||||
:value="model.tags.join(', ')"
|
<div
|
||||||
/>
|
v-if="attack"
|
||||||
<property-field
|
class="layout row justify-center align-center ma-3"
|
||||||
name="Uses"
|
|
||||||
>
|
>
|
||||||
<computed :value="model.uses"/>
|
<div class="headline mr-2">
|
||||||
</property-field>
|
{{ rollBonus }}
|
||||||
<property-field
|
</div>
|
||||||
name="Uses used"
|
<em>
|
||||||
:value="model.usesUsed"
|
to hit
|
||||||
/>
|
</em>
|
||||||
<property-field
|
</div>
|
||||||
name="Reset"
|
<div
|
||||||
:value="reset"
|
v-if="reset"
|
||||||
/>
|
class="my-2"
|
||||||
|
>
|
||||||
|
{{ reset }}
|
||||||
|
</div>
|
||||||
<property-description
|
<property-description
|
||||||
v-if="model.description"
|
v-if="model.description"
|
||||||
:value="model.description"
|
:value="model.description"
|
||||||
@@ -35,12 +37,12 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import propertyViewerMixin from '/imports/ui/properties/viewers/shared/propertyViewerMixin.js';
|
import propertyViewerMixin from '/imports/ui/properties/viewers/shared/propertyViewerMixin.js';
|
||||||
import ComputedForCreature from '/imports/ui/components/computation/ComputedForCreature.vue';
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [propertyViewerMixin],
|
mixins: [propertyViewerMixin],
|
||||||
components: {
|
props: {
|
||||||
Computed: ComputedForCreature,
|
attack: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
reset(){
|
reset(){
|
||||||
@@ -51,7 +53,10 @@ export default {
|
|||||||
return 'Reset on a long rest';
|
return 'Reset on a long rest';
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
},
|
||||||
|
rollBonus(){
|
||||||
|
return numberToSignedString(this.model.rollBonusResult);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,37 +1,18 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div class="attack-viewer">
|
<action-viewer
|
||||||
<property-field name="Attack roll bonus">
|
:model="model"
|
||||||
<computed
|
attack
|
||||||
signed
|
/>
|
||||||
:value="model.rollBonus"
|
|
||||||
/>
|
|
||||||
</property-field>
|
|
||||||
<action-viewer :model="model" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import propertyViewerMixin from '/imports/ui/properties/viewers/shared/propertyViewerMixin.js';
|
import propertyViewerMixin from '/imports/ui/properties/viewers/shared/propertyViewerMixin.js';
|
||||||
import ComputedForCreature from '/imports/ui/components/computation/ComputedForCreature.vue';
|
|
||||||
import ActionViewer from '/imports/ui/properties/viewers/ActionViewer.vue';
|
import ActionViewer from '/imports/ui/properties/viewers/ActionViewer.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ActionViewer,
|
ActionViewer,
|
||||||
Computed: ComputedForCreature,
|
|
||||||
},
|
},
|
||||||
mixins: [propertyViewerMixin],
|
mixins: [propertyViewerMixin],
|
||||||
computed: {
|
|
||||||
reset(){
|
|
||||||
let reset = this.model.reset
|
|
||||||
if (reset === 'shortRest'){
|
|
||||||
return 'Reset on a short rest';
|
|
||||||
} else if (reset === 'longRest'){
|
|
||||||
return 'Reset on a long rest';
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/>
|
/>
|
||||||
{{ model.damageType }}
|
{{ model.damageType }}
|
||||||
<span v-if="model.damageType !== 'healing'">
|
<span v-if="model.damageType !== 'healing'">
|
||||||
damage
|
damage
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user