Fixed skill and attribute effect lists

Now using effectId lists
This commit is contained in:
ThaumRystra
2023-11-12 17:38:51 +02:00
parent b32b6db21a
commit 2e3e6e22b6
8 changed files with 94 additions and 88 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 @@
</property-field>
</v-row>
<v-row
v-if="baseProficiencies.length || proficiencies.length"
v-if="proficiencies.length"
dense
>
<property-field
@@ -98,15 +100,6 @@
name="Proficiencies"
>
<v-list style="width: 100%">
<skill-proficiency
v-for="proficiency in baseProficiencies"
:key="proficiency._id"
:model="proficiency"
:proficiency-bonus="proficiencyBonus"
:hide-breadcrumbs="proficiency._id === model._id"
:data-id="proficiency._id"
@click="clickEffect(proficiency._id)"
/>
<skill-proficiency
v-for="proficiency in proficiencies"
:key="proficiency._id"
@@ -127,7 +120,6 @@ import numberToSignedString from '../../../../api/utility/numberToSignedString.j
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import AttributeEffect from '/imports/client/ui/properties/components/attributes/AttributeEffect.vue';
import SkillProficiency from '/imports/client/ui/properties/components/skills/SkillProficiency.vue';
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables.js';
import getProficiencyIcon from '/imports/client/ui/utility/getProficiencyIcon.js';
import sortEffects from '/imports/client/ui/utility/sortEffects.js';
import PropertyTargetTags from '/imports/client/ui/properties/viewers/shared/PropertyTargetTags.vue';
@@ -179,7 +171,9 @@ export default {
return 10 + this.model.value + this.model.passiveBonus;
},
effects() {
return sortEffects(this.model.effects);
if (!this.model.effectIds) return [];
const effects = CreatureProperties.find({ _id: { $in: this.model.effectIds } }).fetch();
return sortEffects(effects);
},
},
methods: {
@@ -194,70 +188,44 @@ export default {
},
},
meteor: {
variables() {
return CreatureVariables.findOne({ _creatureId: this.context.creatureId }) || {};
},
baseProficiencies() {
if (this.context.creatureId) {
let creatureId = this.context.creatureId;
return CreatureProperties.find({
'ancestors.id': creatureId,
type: 'skill',
variableName: this.model.variableName,
removed: { $ne: true },
inactive: { $ne: true },
}).map(prop => ({
_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;
},
},
}

View File

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