Merge branch 'develop' into version-2-tabletop

This commit is contained in:
Stefan Zermatten
2023-01-14 19:12:17 +02:00
100 changed files with 1228 additions and 1953 deletions

View File

@@ -15,7 +15,8 @@
:model="prop"
:data-id="prop._id"
@click="$emit('click-property', {_id: prop._id})"
@sub-click="_id => $emit('sub-click', _id)"
@click-property="e => $emit('click-property', e)"
@sub-click="e => $emit('sub-click', e)"
@remove="$emit('remove', prop._id)"
/>
</v-card>
@@ -27,15 +28,15 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur
import propComponents from '/imports/client/ui/properties/components/folders/propertyComponentIndex.js';
export default {
components: {
...propComponents,
},
props: {
model: {
type: Object,
required: true,
}
},
beforeCreate() {
Object.assign(this.$options.components, propComponents);
},
meteor: {
properties() {
const props = [];
@@ -50,6 +51,7 @@ export default {
deactivatedByAncestor: { $ne: true },
},
{
type: { $ne: 'toggle' },
inactive: { $ne: true }
},
],
@@ -60,7 +62,7 @@ export default {
}, {
sort: { order: 1 },
}).forEach(prop => {
if (this.$options.components[prop.type]) {
if (propComponents[prop.type]) {
props.push(prop);
}
});

View File

@@ -1,44 +1,55 @@
<template>
<div class="attribute">
<ability-list-tile
v-if="model.attributeType === 'ability'"
<div>
<div
class="attribute"
:data-id="dataId"
>
<ability-list-tile
v-if="model.attributeType === 'ability'"
:model="model"
@click="$emit('click')"
/>
<hit-dice-list-tile
v-else-if="model.attributeType === 'hitDice'"
:model="model"
@click="$emit('click')"
@change="({ type, value }) => damageProperty({type, value: -value})"
/>
<health-bar
v-else-if="model.attributeType === 'healthBar'"
:model="model"
@change="damageProperty"
@click="$emit('click')"
/>
<spell-slot-list-tile
v-else-if="model.attributeType === 'spellSlot'"
:model="model"
@click="$emit('click')"
/>
<resource-card-content
v-else-if="model.attributeType === 'resource'"
:model="model"
@click="$emit('click')"
@change="({ type, value }) => damageProperty({type, value: -value})"
@mouseover="hover = true"
@mouseleave="hover = false"
/>
<attribute-card-content
v-else-if="model.attributeType !== 'utility'"
class="pointer"
:model="model"
@click="$emit('click')"
@mouseover="hover = true"
@mouseleave="hover = false"
/>
<card-highlight :active="hover" />
</div>
<folder-group-children
:model="model"
@click="$emit('click')"
@click-property="e => $emit('click-property', e)"
@sub-click="e => $emit('sub-click', e)"
@remove="e => $emit('remove', e)"
/>
<hit-dice-list-tile
v-else-if="model.attributeType === 'hitDice'"
:model="model"
@click="$emit('click')"
@change="({ type, value }) => damageProperty({type, value: -value})"
/>
<health-bar
v-else-if="model.attributeType === 'healthBar'"
:model="model"
@change="damageProperty"
@click="$emit('click')"
/>
<spell-slot-list-tile
v-else-if="model.attributeType === 'spellSlot'"
:model="model"
@click="$emit('click')"
/>
<resource-card-content
v-else-if="model.attributeType === 'resource'"
:model="model"
@click="$emit('click')"
@change="({ type, value }) => damageProperty({type, value: -value})"
@mouseover="hover = true"
@mouseleave="hover = false"
/>
<attribute-card-content
v-else-if="model.attributeType !== 'utility'"
class="pointer"
:model="model"
@click="$emit('click')"
@mouseover="hover = true"
@mouseleave="hover = false"
/>
<card-highlight :active="hover" />
</div>
</template>
@@ -50,6 +61,7 @@ import SpellSlotListTile from '/imports/client/ui/properties/components/attribut
import ResourceCardContent from '/imports/client/ui/properties/components/attributes/ResourceCardContent.vue';
import AttributeCardContent from '/imports/client/ui/properties/components/attributes/AttributeCardContent.vue';
import CardHighlight from '/imports/client/ui/components/CardHighlight.vue';
import FolderGroupChildren from '/imports/client/ui/properties/components/folders/folderGroupComponents/FolderGroupChildren.vue';
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
@@ -62,12 +74,17 @@ export default {
ResourceCardContent,
AttributeCardContent,
CardHighlight,
FolderGroupChildren,
},
props: {
model: {
type: Object,
required: true,
},
dataId: {
type: String,
required: true,
},
},
data() {
return {
@@ -81,6 +98,10 @@ export default {
value: change.value
});
},
log({_id}) {
console.log(...arguments)
this.$emit('click-property', { _id });
}
}
}
</script>

View File

@@ -0,0 +1,66 @@
<template>
<div
v-if="properties && properties.length"
>
<component
:is="prop.type"
v-for="prop in properties"
:key="prop._id"
:model="prop"
:data-id="prop._id"
@click="$emit('click-property', {_id: prop._id})"
@click-property="(e) => $emit('click-property', e)"
@sub-click="(e) => $emit('sub-click', e)"
@remove="$emit('remove', prop._id)"
/>
</div>
</template>
<script lang="js">
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import propComponents from '/imports/client/ui/properties/components/folders/propertyComponentIndex.js';
export default {
props: {
model: {
type: Object,
required: true,
}
},
beforeCreate() {
Object.assign(this.$options.components, propComponents);
},
meteor: {
properties() {
const props = [];
CreatureProperties.find({
'parent.id': this.model._id,
removed: { $ne: true },
overridden: { $ne: true },
$or: [
{
type: 'toggle',
showUI: true,
deactivatedByAncestor: { $ne: true },
},
{
type: { $ne: 'toggle' },
inactive: { $ne: true },
},
],
$nor: [
{ hideWhenTotalZero: true, total: 0 },
{ hideWhenValueZero: true, value: 0 },
],
}, {
sort: { order: 1 },
}).forEach(prop => {
if (propComponents[prop.type]) {
props.push(prop);
}
});
return props;
},
},
}
</script>

View File

@@ -0,0 +1,82 @@
<template>
<build-tree-node-list
:children="slotBuildTree"
class="mx-2"
@selected="_id => $emit('sub-click', _id)"
/>
</template>
<script lang="js">
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import BuildTreeNodeList from '/imports/client/ui/creature/buildTree/BuildTreeNodeList.vue';
function traverse(tree, callback, parents = []){
tree.forEach(node => {
callback(node, parents);
traverse(node.children, callback, [...parents, node]);
});
}
export default {
components: {
BuildTreeNodeList,
},
props: {
model: {
type: Object,
required: true,
},
},
meteor: {
slotBuildTree() {
const slots = CreatureProperties.find({
$and: [ {
$or: [
{ 'ancestors.id': this.model._id, },
{ '_id': this.model._id, },
],
}, {
$or:
[
{ 'slotCondition.value': { $nin: [false, 0, ''] } },
{ 'slotCondition.value': { $exists: false } },
{ 'slotCondition': { $exists: false } },
],
} ],
type: { $in: ['propertySlot', 'pointBuy'] },
removed: { $ne: true },
inactive: { $ne: true },
}, {
sort: { order: 1 }
});
const slotIds = slots.map(s => s._id);
const slotChildren = CreatureProperties.find({
'parent.id': { $in: slotIds },
removed: { $ne: true },
}, {
sort: { order: 1 },
});
const tree = nodeArrayToTree([
...slots.fetch(),
...slotChildren.fetch()
]);
traverse(tree, (child, parents) => {
const model = child.node;
const isSlotWithSpace = model.type === 'propertySlot' && (
model.spaceLeft > 0 ||
!model.quantityExpected ||
model.quantityExpected.value === 0
);
if (isSlotWithSpace) {
model._canFill = true;
parents.forEach(node => {
node.node._descendantCanFill = true;
});
}
});
return tree;
},
}
}
</script>

View File

@@ -17,16 +17,17 @@ import item from '/imports/client/ui/properties/components/inventory/ItemListTil
import note from '/imports/client/ui/properties/components/persona/NoteCard.vue';
//import pointBuy from '';
//import proficiency from '';
//import propertySlot from '';
import propertySlot from '/imports/client/ui/properties/components/folders/folderGroupComponents/SlotBuildTree.vue';
//import reference from '';
//import roll from '';
//import savingThrow from '';
import skill from '/imports/client/ui/properties/components/skills/SkillListTile.vue';
//import slotFiller from '';
//import spellList from '';
//import spell from '';
import spellList from '/imports/client/ui/properties/components/spells/SpellListCard.vue';
import spell from '/imports/client/ui/properties/components/spells/SpellListTile.vue';
import toggle from '/imports/client/ui/properties/components/toggles/ToggleCard.vue';
//import trigger from '';
import FolderGroupChildren from '/imports/client/ui/properties/components/folders/folderGroupComponents/FolderGroupChildren.vue';
export default {
action,
@@ -43,19 +44,19 @@ export default {
//damageMultiplier,
//effect,
feature,
//folder,
// folder // Like actions, we don't show sub-folders
item,
note,
//pointBuy,
//proficiency,
//propertySlot,
propertySlot,
//reference,
//roll,
//savingThrow,
skill,
//slotFiller,
//spellList,
//spell,
slotFiller: FolderGroupChildren,
spellList,
spell,
toggle,
//trigger,
};

View File

@@ -5,11 +5,21 @@
@toolbarclick="clickSpellList(model._id)"
>
<template slot="toolbar">
<v-toolbar-title>
<v-toolbar-title
v-if="!preparingSpells"
>
{{ model.name }}
</v-toolbar-title>
<v-spacer v-if="!preparingSpells && preparedError" />
<v-toolbar-title
v-if="preparingSpells || preparedError"
:class="{'error--text' : preparedError}"
>
{{ numPrepared }}/{{ model.maxPrepared.value }} spells prepared
</v-toolbar-title>
<v-spacer />
<v-menu
v-if="!preparingSpells"
bottom
left
transition="slide-y-transition"
@@ -33,22 +43,29 @@
/>
</v-list>
</v-menu>
</template>
<v-expand-transition>
<v-card-text
v-if="preparedError || preparingSpells"
:class="{'error--text' : preparedError}"
class="pb-0"
<v-btn
v-else
icon
@click.stop="preparingSpells = false"
>
<div v-if="model.maxPrepared && model.maxPrepared.value">
{{ numPrepared }}/{{ model.maxPrepared.value }} spells prepared
</div>
<v-switch
v-model="preparingSpells"
label="Change prepared spells"
/>
</v-card-text>
</v-expand-transition>
<v-icon>mdi-check</v-icon>
</v-btn>
</template>
<!-- Disabled because it changes the height of the card
<v-card-text
v-if="preparedError || preparingSpells"
:class="{'error--text' : preparedError}"
class="pb-0"
>
<div v-if="model.maxPrepared && model.maxPrepared.value">
{{ numPrepared }}/{{ model.maxPrepared.value }} spells prepared
</div>
<v-switch
v-model="preparingSpells"
label="Change prepared spells"
/>
</v-card-text>
-->
<spell-list
:spells="spells"
:parent-ref="{id: model._id, collection: 'creatureProperties'}"