Merge branch 'version-2' into version-2-dev
This commit is contained in:
@@ -24,7 +24,9 @@ export default function getSlotFillFilter({slot, libraryIds}){
|
||||
slotFillerType: 'classLevel',
|
||||
}]
|
||||
});
|
||||
filter.variableName = slot.variableName;
|
||||
if (slot.variableName) {
|
||||
filter.variableName = slot.variableName;
|
||||
}
|
||||
|
||||
// Only search for levels the class needs
|
||||
if (slot.missingLevels && slot.missingLevels.length) {
|
||||
|
||||
@@ -38,6 +38,11 @@ let CreatureSettingsSchema = new SimpleSchema({
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Hide calculation errors
|
||||
hideCalculationErrors: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// How much each hitDice resets on a long rest
|
||||
hitDiceResetMultiplier: {
|
||||
type: Number,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import { groupBy, remove, rest, union } from 'lodash';
|
||||
import { groupBy, remove, union } from 'lodash';
|
||||
import {
|
||||
getCreature, getVariables, getPropertiesOfType
|
||||
} from '/imports/api/engine/loadCreatures.js';
|
||||
|
||||
@@ -11,15 +11,9 @@ export default function applyTriggers(node, { creature, targets, scope, log }, t
|
||||
const type = prop.type;
|
||||
if (creature.triggers?.[type]?.[timing]) {
|
||||
creature.triggers[type][timing].forEach(trigger => {
|
||||
// Tags
|
||||
if (!triggerMatchTags(trigger, prop)) return;
|
||||
// Condition
|
||||
if (trigger.condition?.parseNode) {
|
||||
recalculateCalculation(trigger.condition, scope, log);
|
||||
if (!trigger.condition.value) return;
|
||||
if (triggerMatchTags(trigger, prop)) {
|
||||
applyTrigger(trigger, { creature, targets, scope, log });
|
||||
}
|
||||
// Apply
|
||||
applyTrigger(trigger, { creature, targets, scope, log });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -57,6 +51,13 @@ function triggerMatchTags(trigger, prop) {
|
||||
}
|
||||
|
||||
export function applyTrigger(trigger, { creature, targets, scope, log }) {
|
||||
// Prevent triggers from firing if their condition is false
|
||||
if (trigger.condition?.parseNode) {
|
||||
recalculateCalculation(trigger.condition, scope, log);
|
||||
if (!trigger.condition.value) return;
|
||||
}
|
||||
|
||||
// Prevent triggers from firing themselves in a loop
|
||||
if (trigger.firing) {
|
||||
/*
|
||||
log.content.push({
|
||||
|
||||
@@ -31,9 +31,10 @@ function childrenActive(prop){
|
||||
switch (prop.type){
|
||||
// Only equipped items have active children
|
||||
case 'item': return !!prop.equipped;
|
||||
// The children of actions are always inactive
|
||||
// The children of actions, spells, and triggers are always inactive
|
||||
case 'action': return false;
|
||||
case 'spell': return false;
|
||||
case 'trigger': return false;
|
||||
// The children of notes are always inactive
|
||||
case 'note': return false;
|
||||
// Other children are active
|
||||
|
||||
@@ -56,12 +56,14 @@ function pushDependenciesToStack(nodeId, graph, stack, computation){
|
||||
oriented: true
|
||||
});
|
||||
const loop = pather.find(nodeId, nodeId);
|
||||
computation.errors.push({
|
||||
type: 'dependencyLoop',
|
||||
details: {
|
||||
nodes: loop.map(node => node.id)
|
||||
},
|
||||
});
|
||||
if (loop.length) {
|
||||
computation.errors.push({
|
||||
type: 'dependencyLoop',
|
||||
details: {
|
||||
nodes: loop.map(node => node.id)
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
stack.push(linkedNode);
|
||||
}, true);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/aws-s3-integration.md
|
||||
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { each, clone } from 'lodash';
|
||||
import { Random } from 'meteor/random';
|
||||
@@ -37,8 +36,9 @@ if (Meteor.isServer && Meteor.settings.useS3) {
|
||||
secretAccessKey: s3Conf.secret,
|
||||
endpoint: s3Conf.endpoint,
|
||||
sslEnabled: true, // optional
|
||||
maxRetries: 10,
|
||||
httpOptions: {
|
||||
timeout: 6000,
|
||||
timeout: 12000,
|
||||
agent: false
|
||||
}
|
||||
});
|
||||
@@ -48,7 +48,7 @@ if (Meteor.isServer && Meteor.settings.useS3) {
|
||||
storagePath,
|
||||
onBeforeUpload,
|
||||
onAfterUpload,
|
||||
debug = Meteor.isProduction,
|
||||
debug = !Meteor.isProduction,
|
||||
allowClientCode = false,
|
||||
}){
|
||||
const collection = new FilesCollection({
|
||||
@@ -222,7 +222,7 @@ if (Meteor.isServer && Meteor.settings.useS3) {
|
||||
storagePath,
|
||||
onBeforeUpload,
|
||||
onAfterUpload,
|
||||
debug = Meteor.isProduction,
|
||||
debug = !Meteor.isProduction,
|
||||
allowClientCode = false,
|
||||
}){
|
||||
const collection = new FilesCollection({
|
||||
|
||||
@@ -16,8 +16,11 @@ const LIBRARY_NODE_TREE_FIELDS = {
|
||||
ancestors: 1,
|
||||
tags: 1,
|
||||
slotFillerCondition: 1,
|
||||
removed: 1,
|
||||
removedAt: 1,
|
||||
// SlotFillers
|
||||
slotQuantityFilled: 1,
|
||||
slotFillerType: 1,
|
||||
// Effect
|
||||
operation: 1,
|
||||
targetTags: 1,
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<template lang="html">
|
||||
<v-container fluid>
|
||||
<v-row dense>
|
||||
<v-col cols="12">
|
||||
<character-errors
|
||||
class="mt-4"
|
||||
:creature-id="creatureId"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row dense>
|
||||
<v-col cols="12">
|
||||
<slot-cards-to-fill :creature-id="creatureId" />
|
||||
@@ -126,6 +134,7 @@ import BuildTreeNodeList from '/imports/ui/creature/buildTree/BuildTreeNodeList.
|
||||
import SlotCardsToFill from '/imports/ui/creature/slots/SlotCardsToFill.vue';
|
||||
import CreatureVariables from '../../../../api/creature/creatures/CreatureVariables';
|
||||
import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js';
|
||||
import CharacterErrors from '/imports/ui/creature/character/errors/CharacterErrors.vue';
|
||||
|
||||
function traverse(tree, callback, parents = []){
|
||||
tree.forEach(node => {
|
||||
@@ -136,6 +145,7 @@ function traverse(tree, callback, parents = []){
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CharacterErrors,
|
||||
BuildTreeNodeList,
|
||||
SlotCardsToFill,
|
||||
},
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
<div
|
||||
class="stats-tab ma-2"
|
||||
>
|
||||
<character-errors
|
||||
class="mx-2 mt-4"
|
||||
:creature-id="creatureId"
|
||||
/>
|
||||
|
||||
<health-bar-card-container :creature-id="creatureId" />
|
||||
|
||||
<column-layout>
|
||||
@@ -374,7 +369,6 @@
|
||||
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
||||
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||
import CharacterErrors from '/imports/ui/creature/character/errors/CharacterErrors.vue';
|
||||
|
||||
const getProperties = function(creature, filter, options = {
|
||||
sort: {order: 1}
|
||||
@@ -419,7 +413,6 @@
|
||||
SpellSlotListTile,
|
||||
ActionCard,
|
||||
ToggleCard,
|
||||
CharacterErrors,
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
|
||||
@@ -1,57 +1,109 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="creature && creature.computeErrors"
|
||||
class="character-sheet-errors"
|
||||
>
|
||||
<template v-for="(error, index) in creature.computeErrors">
|
||||
<dependency-loop-error
|
||||
v-if="error.type === 'dependencyLoop'"
|
||||
:key="index + 'dependencyLoopError'"
|
||||
:model="error"
|
||||
/>
|
||||
<v-alert
|
||||
v-else
|
||||
:key="index + 'otherError'"
|
||||
outlined
|
||||
dense
|
||||
type="error"
|
||||
<div v-if="creature && errors && errors.length">
|
||||
<v-btn
|
||||
fab
|
||||
small
|
||||
absolute
|
||||
right
|
||||
color="warning"
|
||||
class="mr-4"
|
||||
style="margin-top: -20px;"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
<v-icon
|
||||
v-if="expanded"
|
||||
style="color: rgba(0,0,0,0.8);"
|
||||
>
|
||||
{{ error.type }}
|
||||
</v-alert>
|
||||
</template>
|
||||
mdi-close
|
||||
</v-icon>
|
||||
<v-icon
|
||||
v-else
|
||||
style="color: rgba(0,0,0,0.8);"
|
||||
>
|
||||
mdi-alert-circle-outline
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
<v-slide-y-transition>
|
||||
<div
|
||||
v-if="expanded"
|
||||
class="character-sheet-errors"
|
||||
>
|
||||
<template v-for="(error, index) in errors">
|
||||
<dependency-loop-error
|
||||
v-if="error.type === 'dependencyLoop'"
|
||||
:key="index + 'dependencyLoopError'"
|
||||
:model="error"
|
||||
/>
|
||||
<v-alert
|
||||
v-else
|
||||
:key="index + 'otherError'"
|
||||
border="bottom"
|
||||
colored-border
|
||||
elevation="2"
|
||||
type="error"
|
||||
>
|
||||
{{ error.type }}
|
||||
</v-alert>
|
||||
</template>
|
||||
</div>
|
||||
</v-slide-y-transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import DependencyLoopError from '/imports/ui/creature/character/errors/DependencyLoopError.vue';
|
||||
import updateCreature from '/imports/api/creature/creatures/methods/updateCreature.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DependencyLoopError,
|
||||
},
|
||||
inject: {
|
||||
context: { default: {} },
|
||||
theme: {
|
||||
default: {
|
||||
isDark: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
}
|
||||
},
|
||||
data() { return {
|
||||
expanded: false,
|
||||
}},
|
||||
meteor: {
|
||||
creature() {
|
||||
if (!this.creatureId) return;
|
||||
return Creatures.findOne(this.creatureId, {fields: {computeErrors: 1}});
|
||||
return Creatures.findOne(this.creatureId, {fields: {computeErrors: 1, settings: 1}});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
errors() {
|
||||
if (!this.creature || !this.creature.computeErrors) return;
|
||||
return this.creature.computeErrors.map(error => {
|
||||
error.text = error.type;
|
||||
if (error.type === 'dependencyLoop') {
|
||||
error.text = 'Dependency Loop Detected';
|
||||
if (!this.creature || !this.creature.computeErrors) return [];
|
||||
return this.creature.computeErrors;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
expanded(value) {
|
||||
if (this.context.editPermission === false) return;
|
||||
updateCreature.call({
|
||||
_id: this.creatureId,
|
||||
path: ['settings', 'hideCalculationErrors'],
|
||||
value: !value || null,
|
||||
}, (error) => {
|
||||
if (error){
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.expanded = !this.creature.settings.hideCalculationErrors;
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<v-alert
|
||||
v-if="model"
|
||||
outlined
|
||||
dense
|
||||
border="bottom"
|
||||
colored-border
|
||||
elevation="2"
|
||||
type="warning"
|
||||
class="dependency-loop-error"
|
||||
>
|
||||
@@ -54,6 +54,13 @@ export default {
|
||||
components: {
|
||||
TreeNodeView,
|
||||
},
|
||||
inject: {
|
||||
theme: {
|
||||
default: {
|
||||
isDark: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
@@ -86,7 +93,7 @@ export default {
|
||||
elementId: `breadcrumb-${id}`,
|
||||
data: {_id: id},
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user