Merge branch 'develop' of https://github.com/ThaumRystra/DiceCloud into develop
This commit is contained in:
@@ -103,7 +103,7 @@ function subDocsExist(prop, key) {
|
||||
|
||||
export function removeEmptyCalculations(prop) {
|
||||
prop._computationDetails.emptyCalculations.forEach(calcObj => {
|
||||
if (!calcObj.effects?.length) {
|
||||
if (!calcObj.effectIds?.length && !calcObj.proficiencyIds?.length) {
|
||||
unset(prop, calcObj._key);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -48,6 +48,7 @@ function unloadCreature(creatureId, subscription) {
|
||||
export function getSingleProperty(creatureId: string, propertyId: string) {
|
||||
const creature = loadedCreatures.get(creatureId)
|
||||
const property = creature?.properties.get(propertyId);
|
||||
if (property?.removed) return;
|
||||
if (property) {
|
||||
return EJSON.clone(property);
|
||||
}
|
||||
@@ -64,8 +65,9 @@ export function getSingleProperty(creatureId: string, propertyId: string) {
|
||||
export function getProperties(creatureId: string): CreatureProperty[] {
|
||||
const creature = loadedCreatures.get(creatureId);
|
||||
if (creature) {
|
||||
const props = Array.from(creature.properties.values());
|
||||
props.sort((a, b) => a.left - b.left);
|
||||
const props = Array.from(creature.properties.values())
|
||||
.sort((a, b) => a.left - b.left)
|
||||
.filter(prop => !prop.removed);
|
||||
return EJSON.clone(props);
|
||||
}
|
||||
// console.time(`Cache miss on creature properties: ${creatureId}`)
|
||||
@@ -82,13 +84,10 @@ export function getProperties(creatureId: string): CreatureProperty[] {
|
||||
export function getPropertiesOfType(creatureId, propType) {
|
||||
const creature = loadedCreatures.get(creatureId);
|
||||
if (creature) {
|
||||
const props: CreatureProperty[] = []
|
||||
for (const prop of creature.properties.values()) {
|
||||
if (prop.type === propType) {
|
||||
props.push(prop);
|
||||
}
|
||||
}
|
||||
props.sort((a, b) => a.left - b.left);
|
||||
const props = Array.from(
|
||||
creature.properties.values()
|
||||
.filter(prop => !prop.removed && prop.type === propType)
|
||||
).sort((a, b) => a.left - b.left);
|
||||
return EJSON.clone(props);
|
||||
}
|
||||
// console.time(`Cache miss on creature properties: ${creatureId}`)
|
||||
@@ -112,13 +111,10 @@ export function getPropertiesOfType(creatureId, propType) {
|
||||
export function getPropertiesByFilter(creatureId, filterFn: (any) => boolean, mongoFilter: Mongo.Selector<object>) {
|
||||
const creature = loadedCreatures.get(creatureId);
|
||||
if (creature) {
|
||||
const props: CreatureProperty[] = []
|
||||
for (const prop of creature.properties.values()) {
|
||||
if (filterFn(prop)) {
|
||||
props.push(prop);
|
||||
}
|
||||
}
|
||||
props.sort((a, b) => a.left - b.left);
|
||||
const props: CreatureProperty[] = Array.from(
|
||||
creature.properties.values()
|
||||
.filter(filterFn)
|
||||
).sort((a, b) => a.left - b.left);
|
||||
return EJSON.clone(props);
|
||||
}
|
||||
// console.time(`Cache miss on creature properties: ${creatureId}`)
|
||||
@@ -235,7 +231,7 @@ export function getPropertyChildren(creatureId, property) {
|
||||
if (!creature) return [];
|
||||
const props: CreatureProperty[] = [];
|
||||
for (const prop of creature.properties.values()) {
|
||||
if (prop.parentId === property._id) {
|
||||
if (prop.parentId === property._id && prop.removed !== true) {
|
||||
props.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import '/imports/api/sharing/sharing';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS';
|
||||
|
||||
export interface Shared {
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
<tree-node-view
|
||||
:model="node"
|
||||
:selected="selected"
|
||||
:show-external-details="showExternalDetails"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,7 +57,6 @@
|
||||
:organize="organize"
|
||||
:selected-node="selectedNode"
|
||||
:start-expanded="startExpanded"
|
||||
:show-external-details="showExternalDetails"
|
||||
@move-within-root="e => $emit('move-within-root', e)"
|
||||
@move-between-roots="e => $emit('move-between-roots', e)"
|
||||
@selected="e => $emit('selected', e)"
|
||||
@@ -117,7 +115,6 @@ export default {
|
||||
},
|
||||
selected: Boolean,
|
||||
startExpanded: Boolean,
|
||||
showExternalDetails: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
:organize="organize"
|
||||
:lazy="lazy"
|
||||
:start-expanded="startExpanded"
|
||||
:show-external-details="showExternalDetails"
|
||||
@selected="e => $emit('selected', e)"
|
||||
@move-within-root="e => $emit('move-within-root', e)"
|
||||
@move-between-roots="e => $emit('move-between-roots', e)"
|
||||
@@ -68,7 +67,6 @@ export default {
|
||||
default: () => [],
|
||||
},
|
||||
startExpanded: Boolean,
|
||||
showExternalDetails: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -30,7 +30,7 @@ type DoActionParams = BaseDoActionParams & {
|
||||
* the decisions the user makes, then applying the action as a method call to the server with the
|
||||
* saved decisions, which will persist the action results.
|
||||
*/
|
||||
export default async function doAction({ propId, creatureId, $store, elementId, task }: DoActionParams | DoTaskParams) {
|
||||
export default async function doAction({ propId, creatureId, $store, elementId, task }: DoActionParams | DoTaskParams): Promise<any | void> {
|
||||
if (!task) {
|
||||
if (!propId) throw new Meteor.Error('no-prop-id', 'Either propId or task must be provided');
|
||||
task = {
|
||||
@@ -64,7 +64,7 @@ export default async function doAction({ propId, creatureId, $store, elementId,
|
||||
return callActionMethod(finishedAction);
|
||||
} catch (e) {
|
||||
if (e !== 'input-requested') throw e;
|
||||
return new Promise(resolve => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
$store.commit('pushDialogStack', {
|
||||
component: 'action-dialog',
|
||||
elementId,
|
||||
@@ -72,9 +72,14 @@ export default async function doAction({ propId, creatureId, $store, elementId,
|
||||
actionId,
|
||||
task,
|
||||
},
|
||||
callback(action: EngineAction) {
|
||||
if (!action) return;
|
||||
resolve(callActionMethod(action));
|
||||
async callback(action: EngineAction) {
|
||||
try {
|
||||
if (action) await callActionMethod(action);
|
||||
resolve();
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
return elementId;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
outlined
|
||||
style="font-size: 16px; letter-spacing: normal;"
|
||||
class="mr-2"
|
||||
data-id="do-action-button"
|
||||
:data-id="`${model._id}-do-action-button`"
|
||||
:color="model.color || 'primary'"
|
||||
:loading="doActionLoading"
|
||||
:disabled="model.insufficientResources || !context.editPermission || !!targetingError"
|
||||
@@ -89,7 +89,6 @@
|
||||
<tree-node-list
|
||||
v-if="children && children.length"
|
||||
start-expanded
|
||||
show-external-details
|
||||
:children="children"
|
||||
:root="model.root"
|
||||
@selected="e => $emit('sub-click', e)"
|
||||
@@ -229,7 +228,7 @@ export default {
|
||||
propId: this.model._id,
|
||||
creatureId: this.model.root.id,
|
||||
$store: this.$store,
|
||||
elementId: 'do-action-button',
|
||||
elementId: `${this.model._id}-do-action-button`,
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
}).finally(() => {
|
||||
|
||||
@@ -33,16 +33,22 @@
|
||||
|
||||
<script lang="js">
|
||||
import getEffectIcon from '/imports/client/ui/utility/getEffectIcon';
|
||||
import { isFinite } from 'lodash';
|
||||
import { isFinite } from 'lodash';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
hideBreadcrumbs: Boolean,
|
||||
model: {
|
||||
type: Object,
|
||||
effectId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
model() {
|
||||
return CreatureProperties.findOne(this.effectId);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
hasClickListener(){
|
||||
return this.$listeners && this.$listeners.click
|
||||
|
||||
@@ -27,17 +27,23 @@
|
||||
<script lang="js">
|
||||
import ProficiencyIcon from '/imports/client/ui/properties/shared/ProficiencyIcon.vue';
|
||||
import numberToSignedString from '/imports/api/utility/numberToSignedString';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ProficiencyIcon,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
proficiencyId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
model() {
|
||||
return CreatureProperties.findOne(this.proficiencyId);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
displayedText(){
|
||||
return this.model.name || (this.model.type == 'proficiency' ? 'Proficiency' : 'Skill')
|
||||
|
||||
@@ -46,12 +46,11 @@ export default {
|
||||
return true;
|
||||
},
|
||||
displayedValue() {
|
||||
let value = this.model.value;
|
||||
// Use the base value instead if the calculation has it, because effects can modify the value
|
||||
if (this.model.baseValue !== undefined) {
|
||||
value = this.model.baseValue;
|
||||
// Use the unaffected value instead if the calculation has it, because effects can modify the value
|
||||
if (this.model.unaffected !== undefined) {
|
||||
return this.model.unaffected;
|
||||
}
|
||||
return value;
|
||||
return this.model.value;
|
||||
},
|
||||
errorList(){
|
||||
if (this.model.parseError){
|
||||
|
||||
@@ -18,24 +18,6 @@
|
||||
<span v-if="model.target === 'self'">to self</span>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="showExternalDetails">
|
||||
<div
|
||||
v-for="effect in (model.amount && model.amount.effects)"
|
||||
:key="effect._id"
|
||||
>
|
||||
<div
|
||||
v-if="effect.amount.value !== 0"
|
||||
style="position:relative; top:-15px; left:5px; height:25px;"
|
||||
>
|
||||
<inline-effect
|
||||
:key="effect._id"
|
||||
hide-breadcrumbs
|
||||
:data-id="effect._id"
|
||||
:model="effect"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
:is="treeNodeView"
|
||||
:model="model"
|
||||
:selected="selected"
|
||||
:show-external-details="showExternalDetails"
|
||||
:class="{
|
||||
'inactive': model.inactive,
|
||||
}"
|
||||
@@ -25,7 +24,6 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
selected: Boolean,
|
||||
showExternalDetails: Boolean,
|
||||
},
|
||||
computed: {
|
||||
treeNodeView(){
|
||||
|
||||
@@ -12,7 +12,6 @@ export default {
|
||||
},
|
||||
selected: Boolean,
|
||||
hideIcon: Boolean,
|
||||
showExternalDetails: Boolean,
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
'justify-end': end,
|
||||
'flex-wrap': wrap,
|
||||
'mono': isMono,
|
||||
'flex-grow-0': calculation && calculation.effects,
|
||||
'flex-grow-1': !calculation || !calculation.effects,
|
||||
'ma-3': calculation && calculation.effects,
|
||||
'flex-grow-0': hasEffectsOrProficiencies,
|
||||
'flex-grow-1': !hasEffectsOrProficiencies,
|
||||
'ma-3': hasEffectsOrProficiencies,
|
||||
...$attrs.class,
|
||||
}"
|
||||
style="overflow-x: auto;"
|
||||
@@ -49,36 +49,32 @@
|
||||
</slot>
|
||||
</div>
|
||||
<div
|
||||
v-if="calculation && (calculation.effects || calculation.proficiencies)"
|
||||
v-if="hasEffectsOrProficiencies"
|
||||
class="flex-grow-1"
|
||||
style="max-width: 100%;"
|
||||
>
|
||||
<inline-effect
|
||||
v-if="typeof calculation.value === 'number' && calculation.baseValue !== 0"
|
||||
hide-breadcrumbs
|
||||
:model="{
|
||||
name: 'Base value',
|
||||
operation: 'base',
|
||||
amount: {value: calculation.baseValue},
|
||||
}"
|
||||
@click="clickEffect(effect._id)"
|
||||
/>
|
||||
<inline-effect
|
||||
v-for="effect in calculation.effects"
|
||||
:key="effect._id"
|
||||
:data-id="effect._id"
|
||||
:model="effect"
|
||||
@click="clickEffect(effect._id)"
|
||||
v-for="effectId in calculation.effectIds"
|
||||
:key="effectId"
|
||||
:data-id="effectId"
|
||||
:effect-id="effectId"
|
||||
@click="clickEffect(effectId)"
|
||||
/>
|
||||
<inline-proficiency
|
||||
v-for="proficiency in calculation.proficiencies"
|
||||
:key="proficiency._id"
|
||||
:data-id="proficiency._id"
|
||||
:model="proficiency"
|
||||
:proficiency-bonus="calculation.proficiencyBonus"
|
||||
@click="clickEffect(proficiency._id)"
|
||||
v-for="proficiencyId in calculation.proficiencyIds"
|
||||
:key="proficiencyId"
|
||||
:data-id="proficiencyId"
|
||||
:proficiency-id="proficiencyId"
|
||||
@click="clickEffect(proficiencyId)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasEffectsOrProficiencies"
|
||||
class="d-flex justify-end border-t-sm pt-2"
|
||||
style="width: 100%; opacity: 0.5"
|
||||
>
|
||||
{{ calculation.value }}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</v-col>
|
||||
@@ -152,6 +148,9 @@ export default {
|
||||
if (this.signed) {
|
||||
return numberToSignedString(calculation.value);
|
||||
}
|
||||
if (this.hasEffectsOrProficiencies) {
|
||||
return calculation.unaffected;
|
||||
}
|
||||
return calculation.value;
|
||||
},
|
||||
// large and center are only applied to calculations if we are showing their
|
||||
@@ -172,6 +171,15 @@ export default {
|
||||
if (this.valueNotReduced) return true;
|
||||
return this.mono;
|
||||
},
|
||||
hasEffects(){
|
||||
return this.calculation?.effectIds?.length > 0;
|
||||
},
|
||||
hasProficiencies(){
|
||||
return this.calculation?.proficiencyIds?.length > 0;
|
||||
},
|
||||
hasEffectsOrProficiencies() {
|
||||
return this.hasEffects || this.hasProficiencies;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
numberToSignedString,
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
<tree-node-list
|
||||
v-if="children && children.length"
|
||||
start-expanded
|
||||
show-external-details
|
||||
:children="children"
|
||||
:root="model.root"
|
||||
@selected="e => $emit('sub-click', e)"
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
<tree-node-list
|
||||
v-if="children && children.length"
|
||||
start-expanded
|
||||
show-external-details
|
||||
:children="children"
|
||||
:root="model.root"
|
||||
@selected="e => $emit('sub-click', e)"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { assertViewPermission } from '/imports/api/creature/creatures/creaturePe
|
||||
import computeCreature from '/imports/api/engine/computeCreature';
|
||||
import VERSION from '/imports/constants/VERSION';
|
||||
import { getCreature, getProperties, getVariables } from '/imports/api/engine/loadCreatures';
|
||||
import SCHEMA_VERSION from '/imports/constants/SCHEMA_VERSION';
|
||||
|
||||
JsonRoutes.add('get', 'api/creature/:id', function (req, res) {
|
||||
const creatureId = req.params.id;
|
||||
@@ -46,6 +47,9 @@ JsonRoutes.add('get', 'api/creature/:id', function (req, res) {
|
||||
// Send the results
|
||||
JsonRoutes.sendResult(res, {
|
||||
data: {
|
||||
meta: {
|
||||
schemaVersion: SCHEMA_VERSION,
|
||||
},
|
||||
creatures: [creature],
|
||||
creatureProperties: getProperties(creatureId),
|
||||
creatureVariables: getVariables(creatureId),
|
||||
|
||||
@@ -17,4 +17,5 @@ import '/imports/api/creature/creatureProperties/methods/index';
|
||||
import '/imports/api/creature/archive/methods/index';
|
||||
import '/imports/api/creature/creatures/methods/index';
|
||||
import '/imports/api/engine/action/methods/index';
|
||||
import '/imports/api/sharing/sharing';
|
||||
import '/imports/server/config/publicationStrategies';
|
||||
|
||||
Reference in New Issue
Block a user