From 2e3e6e22b6a4aa63a8eeda7edb2419075ac5329a Mon Sep 17 00:00:00 2001 From: ThaumRystra <9525416+ThaumRystra@users.noreply.github.com> Date: Sun, 12 Nov 2023 17:38:51 +0200 Subject: [PATCH] Fixed skill and attribute effect lists Now using effectId lists --- .../aggregate/aggregateProficiency.js | 15 +++- .../computeVariableAsAttribute.js | 3 +- .../computeVariable/computeVariableAsSkill.js | 3 +- .../components/attributes/AttributeEffect.vue | 29 ++++++-- .../components/skills/SkillProficiency.vue | 24 ++++-- .../ui/properties/viewers/AttributeViewer.vue | 6 +- .../ui/properties/viewers/SkillViewer.vue | 74 ++++++------------- app/imports/client/ui/utility/sortEffects.js | 28 +++---- 8 files changed, 94 insertions(+), 88 deletions(-) diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js index ea4383e6..a89cfa08 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/aggregate/aggregateProficiency.js @@ -1,21 +1,28 @@ -export default function aggregateProficiency({node, linkedNode, link}){ +export default function aggregateProficiency({ node, linkedNode, link }) { if ( link.data !== 'proficiency' && !(link.data === 'definition' && linkedNode.data.type === 'skill') ) return; let proficiency; - if (link.data === 'proficiency'){ + if (link.data === 'proficiency') { proficiency = linkedNode.data.value || 0; - } else if (link.data === 'definition' && linkedNode.data.type === 'skill'){ + } else if (link.data === 'definition' && linkedNode.data.type === 'skill') { proficiency = linkedNode.data.baseProficiency || 0; } else { return; } + + if (proficiency) { + // Store a link to the proficiency + node.data.proficiencyIds = node.data.proficiencyIds || []; + node.data.proficiencyIds.push(linkedNode.data._id); + } + // Store the highest proficiency if ( node.data.proficiency === undefined || proficiency > node.data.proficiency - ){ + ) { node.data.proficiency = proficiency; } } diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js index cfe4a4c1..a56028fc 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsAttribute.js @@ -48,6 +48,7 @@ export default function computeVariableAsAttribute(computation, node, prop) { prop.baseValue === undefined || undefined - // Store effects + // Store effects and proficiencies prop.effectIds = node.data.effectIds; + prop.proficiencyIds = node.data.proficiencyIds; } diff --git a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js index 41f00188..dedb4e3d 100644 --- a/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js +++ b/app/imports/api/engine/computation/computeComputation/computeByType/computeVariable/computeVariableAsSkill.js @@ -33,8 +33,9 @@ export default function computeVariableAsSkill(computation, node, prop) { const aggregator = node.data.effectAggregator; const aggregatorBase = aggregator?.base || 0; - // Store effects + // Store effects and proficiencies prop.effectIds = node.data.effectIds; + prop.proficiencyIds = node.data.proficiencyIds; // If there is no aggregator, determine if the prop can hide, then exit if (!aggregator) { diff --git a/app/imports/client/ui/properties/components/attributes/AttributeEffect.vue b/app/imports/client/ui/properties/components/attributes/AttributeEffect.vue index 43f4e212..801c30d0 100644 --- a/app/imports/client/ui/properties/components/attributes/AttributeEffect.vue +++ b/app/imports/client/ui/properties/components/attributes/AttributeEffect.vue @@ -44,7 +44,7 @@ import getEffectIcon from '/imports/client/ui/utility/getEffectIcon.js'; import Breadcrumbs from '/imports/client/ui/creature/creatureProperties/Breadcrumbs.vue'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -import { isFinite } from 'lodash'; +import { isFinite, find } from 'lodash'; export default { components: { @@ -56,13 +56,17 @@ export default { type: Object, required: true, }, + attribute: { + type: Object, + required: true, + }, }, computed: { hasClickListener(){ return this.$listeners && this.$listeners.click }, displayedText(){ - if (this.model.operation === 'conditional'){ + if (this.operation === 'conditional'){ return this.model.text || this.model.name || this.operation } else { return this.model.name || this.operation @@ -75,10 +79,16 @@ export default { }, effectIcon(){ let value = this.resolvedValue; - return getEffectIcon(this.model.operation, value); + return getEffectIcon(this.operation, value); }, - operation(){ - switch(this.model.operation) { + operation() { + if (this.model.type === 'pointBuy' || this.model.type === 'attribute') { + return 'base' + } + return this.model.operation; + }, + operationText() { + switch(this.operation) { case 'base': return 'Base value'; case 'add': return 'Add'; case 'mul': return 'Multiply'; @@ -93,7 +103,7 @@ export default { } }, showValue(){ - switch(this.model.operation) { + switch(this.operation) { case 'base': return true; case 'add': return true; case 'mul': return true; @@ -109,7 +119,12 @@ export default { }, displayedValue(){ let value = this.resolvedValue; - switch(this.model.operation) { + if (this.model.type === 'pointBuy') { + return find(this.model.values, row => this.attribute.variableName === row.variableName)?.value; + } else if (this.model.type === 'attribute') { + return this.model.baseValue?.value; + } + switch(this.operation) { case 'base': return value; case 'add': return isFinite(value) ? Math.abs(value) : value; case 'mul': return value; diff --git a/app/imports/client/ui/properties/components/skills/SkillProficiency.vue b/app/imports/client/ui/properties/components/skills/SkillProficiency.vue index 66b7ed03..9811c1bc 100644 --- a/app/imports/client/ui/properties/components/skills/SkillProficiency.vue +++ b/app/imports/client/ui/properties/components/skills/SkillProficiency.vue @@ -44,7 +44,8 @@ import propertyViewerMixin from '/imports/client/ui/properties/viewers/shared/propertyViewerMixin.js'; import Breadcrumbs from '/imports/client/ui/creature/creatureProperties/Breadcrumbs.vue'; import getProficiencyIcon from '/imports/client/ui/utility/getProficiencyIcon.js'; - + import numberToSignedString from '/imports/api/utility/numberToSignedString'; + export default { components: { Breadcrumbs, @@ -54,15 +55,22 @@ hideBreadcrumbs: Boolean, proficiencyBonus: { type: Number, - default: null, + default: 0, }, }, computed: { icon(){ - return getProficiencyIcon(this.model.value); + return getProficiencyIcon(this.proficiency); + }, + proficiency() { + switch (this.model.type) { + case 'proficiency': return this.model.value; + case 'skill': return this.model.proficiency; + default: return 0; + } }, proficiencyText(){ - switch (this.model.value){ + switch (this.proficiency){ case 0.49: return 'Half proficiency bonus rounded down'; case 0.5: return 'Half proficiency bonus rounded up'; case 1: return 'Proficient'; @@ -71,11 +79,11 @@ } }, proficiencyValue(){ - if (!this.proficiencyBonus) return; - if (this.model.value === 0.49){ - return Math.floor(0.5 * this.proficiencyBonus); + if (!this.proficiencyBonus) return numberToSignedString(0); + if (this.proficiency === 0.49){ + return numberToSignedString(Math.floor(0.5 * this.proficiencyBonus)); } else { - return Math.ceil(this.model.value * this.proficiencyBonus); + return numberToSignedString(Math.ceil(this.proficiency * this.proficiencyBonus)); } }, }, diff --git a/app/imports/client/ui/properties/viewers/AttributeViewer.vue b/app/imports/client/ui/properties/viewers/AttributeViewer.vue index a6230491..d0d7ed26 100644 --- a/app/imports/client/ui/properties/viewers/AttributeViewer.vue +++ b/app/imports/client/ui/properties/viewers/AttributeViewer.vue @@ -126,6 +126,7 @@ v-for="effect in effects" :key="effect._id" :model="effect" + :attribute="model" :data-id="effect._id" :hide-breadcrumbs="effect._id === model._id" @click="effect._id !== model._id && clickEffect(effect._id)" @@ -145,6 +146,7 @@ import getProficiencyIcon from '/imports/client/ui/utility/getProficiencyIcon.js'; import {snackbar} from '/imports/client/ui/components/snackbars/SnackbarQueue.js'; import sortEffects from '/imports/client/ui/utility/sortEffects.js'; + import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties'; export default { components: { @@ -189,7 +191,9 @@ return getProficiencyIcon(this.model.proficiency); }, effects() { - return sortEffects(this.model.effects); + if (!this.model.effectIds) return []; + const effects = CreatureProperties.find({ _id: { $in: this.model.effectIds } }).fetch(); + return sortEffects(effects); }, fallbackValue() { return this.model.baseValue?.value ?? this.model.baseValue?.calculation; diff --git a/app/imports/client/ui/properties/viewers/SkillViewer.vue b/app/imports/client/ui/properties/viewers/SkillViewer.vue index d790436a..92006743 100644 --- a/app/imports/client/ui/properties/viewers/SkillViewer.vue +++ b/app/imports/client/ui/properties/viewers/SkillViewer.vue @@ -76,6 +76,7 @@ v-if="ability" :key="ability._id" :model="ability" + :attribute="model" :data-id="ability._id" @click="clickEffect(ability._id)" /> @@ -83,6 +84,7 @@ v-for="effect in effects" :key="effect._id" :model="effect" + :attribute="model" :data-id="effect._id" @click="clickEffect(effect._id)" /> @@ -90,7 +92,7 @@ - ({ - _id: prop._id, - name: 'Skill base proficiency', - value: prop.baseProficiency, - stats: [prop.variableName], - ancestors: prop.ancestors, - })).filter(prof => prof.value); - } else { - return []; - } - }, proficiencies() { - let creatureId = this.context.creatureId; - if (creatureId) { - return CreatureProperties.find({ - 'ancestors.id': creatureId, - stats: this.model.variableName, - type: 'proficiency', - removed: { $ne: true }, - inactive: { $ne: true }, - }).fetch(); - } else { - return []; - } + if (!this.model.proficiencyIds) return []; + return CreatureProperties.find({ + _id: {$in: this.model.proficiencyIds}, + }, { + sort: {order: 1} + }).fetch(); }, ability() { let creatureId = this.context.creatureId; let ability = this.model.ability; if (!creatureId || !ability) return; let abilityProp = CreatureProperties.findOne({ - 'ancestors.id': creatureId, variableName: ability, type: 'attribute', removed: { $ne: true }, inactive: { $ne: true }, overridden: { $ne: true }, + 'ancestors.id': creatureId, }); if (!abilityProp) return; return { _id: abilityProp._id, name: abilityProp.name, - operation: 'add', + operation: 'base', amount: { value: abilityProp.modifier }, stats: [this.model.variableName], ancestors: abilityProp.ancestors, } }, proficiencyBonus() { - let creatureId = this.context.creatureId; - if (!creatureId) return; - return this.variables.proficiencyBonus && - this.variables.proficiencyBonus.value; + return CreatureProperties.findOne({ + variableName: 'proficiencyBonus', + overridden: { $ne: true }, + removed: { $ne: true }, + inactive: { $ne: true }, + 'ancestors.id': this.context.creatureId, + })?.value; }, }, } diff --git a/app/imports/client/ui/utility/sortEffects.js b/app/imports/client/ui/utility/sortEffects.js index d7779cdd..1b026e37 100644 --- a/app/imports/client/ui/utility/sortEffects.js +++ b/app/imports/client/ui/utility/sortEffects.js @@ -1,20 +1,22 @@ const INDEX = { - 'base': 1, - 'add': 2, - 'mul': 3, - 'min': 4, - 'max': 5, - 'advantage': 6, - 'disadvantage': 7, - 'passiveAdd': 8, - 'fail': 9, - 'conditional': 10, + 'attribute': 1, + 'pointBuy': 2, + 'base': 3, + 'add': 4, + 'mul': 5, + 'min': 6, + 'max': 7, + 'advantage': 8, + 'disadvantage': 9, + 'passiveAdd': 10, + 'fail': 11, + 'conditional': 12, }; -function sortEffects(effects){ +function sortEffects(effects) { if (!effects || !effects.length) return []; - return [...effects].sort( - (a, b) => (INDEX[a.operation] || 99) - (INDEX[b.operation] || 99) + return effects.sort( + (a, b) => (INDEX[a.operation || a.type] || 99) - (INDEX[b.operation || b.type] || 99) ); }