Denormalized some calculations into recomputation step

This commit is contained in:
Stefan Zermatten
2020-06-07 21:08:53 +02:00
parent 5198c655e9
commit 1535e00093
22 changed files with 320 additions and 132 deletions

View File

@@ -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 = {

View File

@@ -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;
}
}

View File

@@ -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);
});
} }

View File

@@ -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;

View File

@@ -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){

View File

@@ -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){

View File

@@ -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};

View File

@@ -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,

View File

@@ -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 };

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 };

View File

@@ -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 };

View File

@@ -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 };

View File

@@ -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,

View File

@@ -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,
}, },

View File

@@ -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: {

View File

@@ -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){

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -7,7 +7,7 @@
/> />
{{ model.damageType }} {{ model.damageType }}
<span v-if="model.damageType !== 'healing'"> <span v-if="model.damageType !== 'healing'">
damage &nbsp;damage
</span> </span>
</div> </div>
</template> </template>