Added tag targeted toggles
May God have mercy on us all
This commit is contained in:
@@ -88,6 +88,12 @@ const DenormalisedOnlyCreaturePropertySchema = new SimpleSchema({
|
||||
index: 1,
|
||||
removeBeforeCompute: true,
|
||||
},
|
||||
deactivatingToggleId: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
optional: true,
|
||||
removeBeforeCompute: true,
|
||||
},
|
||||
// When this is true on any property, the creature needs to be recomputed
|
||||
dirty: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
import walkDown from '/imports/api/engine/computation/utility/walkdown.js';
|
||||
import { getEffectTagTargets } from '/imports/api/engine/computation/buildComputation/linkTypeDependencies.js';
|
||||
|
||||
export default function computeToggleDependencies(node, dependencyGraph){
|
||||
export default function computeToggleDependencies(node, dependencyGraph, computation, forest) {
|
||||
const prop = node.node;
|
||||
// Only for toggles that aren't inactive and aren't set to enabled or disabled
|
||||
if (
|
||||
prop.inactive ||
|
||||
prop.type !== 'toggle' ||
|
||||
prop.disabled ||
|
||||
prop.enabled
|
||||
) return;
|
||||
// Only for toggles
|
||||
if (prop.type !== 'toggle') return;
|
||||
|
||||
if (prop.targetByTags) {
|
||||
// Find all the props targeted by tags, and disable them and their children
|
||||
getEffectTagTargets(prop, computation).forEach(targetId => {
|
||||
const target = forest.nodeIndex[targetId];
|
||||
if (!target) return;
|
||||
target.node._computationDetails.toggleAncestors.push(prop);
|
||||
dependencyGraph.addLink(target.node._id, prop._id, 'toggle');
|
||||
walkDown(target.children, child => {
|
||||
// The child nodes depend on the toggle
|
||||
child.node._computationDetails.toggleAncestors.push(prop);
|
||||
dependencyGraph.addLink(child.node._id, prop._id, 'toggle');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// We don't need to link direct children of static toggles, it's already done
|
||||
if (prop.disabled || prop.enabled) return;
|
||||
|
||||
walkDown(node.children, child => {
|
||||
// The child nodes depend on the toggle condition compuation
|
||||
// The child nodes depend on the toggle
|
||||
child.node._computationDetails.toggleAncestors.push(prop);
|
||||
dependencyGraph.addLink(child.node._id, prop._id, 'toggle');
|
||||
});
|
||||
|
||||
@@ -164,7 +164,7 @@ function linkEffects(dependencyGraph, prop, computation) {
|
||||
}
|
||||
|
||||
// Returns an array of IDs of the properties the effect targets
|
||||
function getEffectTagTargets(effect, computation) {
|
||||
export function getEffectTagTargets(effect, computation) {
|
||||
let targets = getTargetListFromTags(effect.targetTags, computation);
|
||||
let notIds = [];
|
||||
if (effect.extraTags) {
|
||||
|
||||
@@ -29,7 +29,7 @@ import removeSchemaFields from './buildComputation/removeSchemaFields.js';
|
||||
* computed toggles
|
||||
*/
|
||||
|
||||
export default function buildCreatureComputation(creatureId){
|
||||
export default function buildCreatureComputation(creatureId) {
|
||||
const creature = getCreature(creatureId);
|
||||
const variables = getVariables(creatureId);
|
||||
const properties = getProperties(creatureId);
|
||||
@@ -37,7 +37,7 @@ export default function buildCreatureComputation(creatureId){
|
||||
return computation;
|
||||
}
|
||||
|
||||
export function buildComputationFromProps(properties, creature, variables){
|
||||
export function buildComputationFromProps(properties, creature, variables) {
|
||||
|
||||
const computation = new CreatureComputation(properties, creature, variables);
|
||||
// Dependency graph where edge(a, b) means a depends on b
|
||||
@@ -49,14 +49,14 @@ export function buildComputationFromProps(properties, creature, variables){
|
||||
const dependencyGraph = computation.dependencyGraph;
|
||||
|
||||
// Link the denormalizedStats from the creature
|
||||
if (creature && creature.denormalizedStats){
|
||||
if (creature.denormalizedStats.xp){
|
||||
if (creature && creature.denormalizedStats) {
|
||||
if (creature.denormalizedStats.xp) {
|
||||
dependencyGraph.addNode('xp', {
|
||||
baseValue: creature.denormalizedStats.xp,
|
||||
type: '_variable'
|
||||
});
|
||||
}
|
||||
if (creature.denormalizedStats.milestoneLevels){
|
||||
if (creature.denormalizedStats.milestoneLevels) {
|
||||
dependencyGraph.addNode('milestoneLevels', {
|
||||
baseValue: creature.denormalizedStats.milestoneLevels,
|
||||
type: '_variable'
|
||||
@@ -93,7 +93,7 @@ export function buildComputationFromProps(properties, creature, variables){
|
||||
// Inactive status must be complete for the whole tree before toggle deps
|
||||
// are calculated
|
||||
walkDown(forest, node => {
|
||||
computeToggleDependencies(node, dependencyGraph);
|
||||
computeToggleDependencies(node, dependencyGraph, computation, forest);
|
||||
computeSlotQuantityFilled(node, dependencyGraph);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import pointBuy from './computeByType/computePointBuy.js';
|
||||
import propertySlot from './computeByType/computeSlot.js';
|
||||
import container from './computeByType/computeContainer.js';
|
||||
import spellList from './computeByType/computeSpellList.js';
|
||||
import toggle from './computeByType/computeToggle.js';
|
||||
import _calculation from './computeByType/computeCalculation.js';
|
||||
|
||||
export default Object.freeze({
|
||||
@@ -19,4 +20,5 @@ export default Object.freeze({
|
||||
propertySlot,
|
||||
spell: action,
|
||||
spellList,
|
||||
toggle,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export default function computeToggle(computation, node) {
|
||||
const prop = node.data;
|
||||
if (!prop.enabled && !prop.disabled && prop.condition && !prop.condition.value) {
|
||||
prop.inactive = true;
|
||||
prop.deactivatedBySelf = true;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
export default function evaluateToggles(computation, node){
|
||||
export default function evaluateToggles(computation, node) {
|
||||
let prop = node.data;
|
||||
if (!prop) return;
|
||||
let toggles = prop._computationDetails?.toggleAncestors;
|
||||
if (!toggles) return;
|
||||
toggles.forEach(toggle => {
|
||||
if (!toggle.condition) return;
|
||||
if (!toggle.condition.value){
|
||||
if (
|
||||
(!toggle.enabled && !toggle.disabled && toggle.condition && !toggle.condition.value)
|
||||
|| (toggle.disabled)
|
||||
) {
|
||||
prop.inactive = true;
|
||||
prop.deactivatedByToggle = true;
|
||||
prop.deactivatingToggleId = toggle._id;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import { EJSON } from 'meteor/ejson';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import propertySchemasIndex from '/imports/api/properties/computedOnlyPropertySchemasIndex.js';
|
||||
|
||||
export default function writeAlteredProperties(computation){
|
||||
export default function writeAlteredProperties(computation) {
|
||||
let bulkWriteOperations = [];
|
||||
// Loop through all properties on the memo
|
||||
computation.props.forEach(changed => {
|
||||
let schema = propertySchemasIndex[changed.type];
|
||||
if (!schema){
|
||||
if (!schema) {
|
||||
console.warn('No schema for ' + changed.type);
|
||||
return;
|
||||
}
|
||||
@@ -20,12 +20,13 @@ export default function writeAlteredProperties(computation){
|
||||
'deactivatedBySelf',
|
||||
'deactivatedByAncestor',
|
||||
'deactivatedByToggle',
|
||||
'deactivatingToggleId',
|
||||
'damage',
|
||||
'dirty',
|
||||
...schema.objectKeys(),
|
||||
];
|
||||
op = addChangedKeysToOp(op, keys, original, changed);
|
||||
if (op){
|
||||
if (op) {
|
||||
bulkWriteOperations.push(op);
|
||||
}
|
||||
});
|
||||
@@ -37,10 +38,10 @@ function addChangedKeysToOp(op, keys, original, changed) {
|
||||
// Loop through all keys that can be changed by computation
|
||||
// and compile an operation that sets all those keys
|
||||
for (let key of keys) {
|
||||
if (!EJSON.equals(original[key], changed[key])){
|
||||
if (!EJSON.equals(original[key], changed[key])) {
|
||||
if (!op) op = newOperation(original._id, changed.type);
|
||||
let value = changed[key];
|
||||
if (value === undefined){
|
||||
if (value === undefined) {
|
||||
// Unset values that become undefined
|
||||
addUnsetOp(op, key);
|
||||
} else {
|
||||
@@ -52,32 +53,32 @@ function addChangedKeysToOp(op, keys, original, changed) {
|
||||
return op;
|
||||
}
|
||||
|
||||
function newOperation(_id, type){
|
||||
function newOperation(_id, type) {
|
||||
let newOp = {
|
||||
updateOne: {
|
||||
filter: {_id},
|
||||
filter: { _id },
|
||||
update: {},
|
||||
}
|
||||
};
|
||||
if (Meteor.isClient){
|
||||
if (Meteor.isClient) {
|
||||
newOp.type = type;
|
||||
}
|
||||
return newOp;
|
||||
}
|
||||
|
||||
function addSetOp(op, key, value){
|
||||
if (op.updateOne.update.$set){
|
||||
function addSetOp(op, key, value) {
|
||||
if (op.updateOne.update.$set) {
|
||||
op.updateOne.update.$set[key] = value;
|
||||
} else {
|
||||
op.updateOne.update.$set = {[key]: value};
|
||||
op.updateOne.update.$set = { [key]: value };
|
||||
}
|
||||
}
|
||||
|
||||
function addUnsetOp(op, key){
|
||||
if (op.updateOne.update.$unset){
|
||||
function addUnsetOp(op, key) {
|
||||
if (op.updateOne.update.$unset) {
|
||||
op.updateOne.update.$unset[key] = 1;
|
||||
} else {
|
||||
op.updateOne.update.$unset = {[key]: 1};
|
||||
op.updateOne.update.$unset = { [key]: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,14 +101,14 @@ function writePropertiesSequentially(bulkWriteOps) {
|
||||
// in the UI because of incompatibility with latency compensation. If the
|
||||
// duplicate redraws can be fixed, this is a strictly better way of processing
|
||||
// writes
|
||||
function bulkWriteProperties(bulkWriteOps){
|
||||
function bulkWriteProperties(bulkWriteOps) {
|
||||
if (!bulkWriteOps.length) return;
|
||||
// bulkWrite is only available on the server
|
||||
if (Meteor.isServer) {
|
||||
CreatureProperties.rawCollection().bulkWrite(
|
||||
bulkWriteOps,
|
||||
{ordered : false},
|
||||
function(e){
|
||||
{ ordered: false },
|
||||
function (e) {
|
||||
if (e) {
|
||||
console.error('Bulk write failed: ');
|
||||
console.error(e);
|
||||
|
||||
@@ -26,6 +26,7 @@ export function nodeArrayToTree(nodes) {
|
||||
forest.push(treeNode);
|
||||
}
|
||||
});
|
||||
forest.nodeIndex = nodeIndex;
|
||||
return forest;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
import TagTargetingSchema from '/imports/api/properties/subSchemas/TagTargetingSchema.js';
|
||||
|
||||
/*
|
||||
* Effects are reason-value attached to skills and abilities
|
||||
@@ -50,57 +51,7 @@ let EffectSchema = createPropertySchema({
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// True when targeting by tags instead of stats
|
||||
targetByTags: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// If targeting by tags, the field which will be targeted
|
||||
targetField: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// Which tags the effect is applied to
|
||||
targetTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'targetTags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
extraTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.extraTagsCount,
|
||||
},
|
||||
'extraTags.$': {
|
||||
type: Object,
|
||||
},
|
||||
'extraTags.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
'extraTags.$.operation': {
|
||||
type: String,
|
||||
allowedValues: ['OR', 'NOT'],
|
||||
defaultValue: 'OR',
|
||||
},
|
||||
'extraTags.$.tags': {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'extraTags.$.tags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
});
|
||||
}).extend(TagTargetingSchema);
|
||||
|
||||
const ComputedOnlyEffectSchema = createPropertySchema({
|
||||
amount: {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import TagTargetingSchema from '/imports/api/properties/subSchemas/TagTargetingSchema.js';
|
||||
|
||||
let ProficiencySchema = new SimpleSchema({
|
||||
name: {
|
||||
@@ -24,57 +25,7 @@ let ProficiencySchema = new SimpleSchema({
|
||||
allowedValues: [0.49, 0.5, 1, 2],
|
||||
defaultValue: 1,
|
||||
},
|
||||
// True when targeting by tags instead of stats
|
||||
targetByTags: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// If targeting by tags, the field which will be targeted
|
||||
targetField: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// Which tags the proficiency is applied to
|
||||
targetTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'targetTags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
extraTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.extraTagsCount,
|
||||
},
|
||||
'extraTags.$': {
|
||||
type: Object,
|
||||
},
|
||||
'extraTags.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue() {
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
'extraTags.$.operation': {
|
||||
type: String,
|
||||
allowedValues: ['OR', 'NOT'],
|
||||
defaultValue: 'OR',
|
||||
},
|
||||
'extraTags.$.tags': {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'extraTags.$.tags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
});
|
||||
}).extend(TagTargetingSchema);
|
||||
|
||||
const ComputedOnlyProficiencySchema = new SimpleSchema({});
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import SimpleSchema from 'simpl-schema';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
import TagTargetingSchema from '/imports/api/properties/subSchemas/TagTargetingSchema.js';
|
||||
|
||||
/*
|
||||
* Skills are anything that results in a modifier to be added to a D20
|
||||
@@ -59,52 +60,8 @@ let SkillSchema = createPropertySchema({
|
||||
type: 'inlineCalculationFieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
// Skills can apply their value to other calculations as a proficiency
|
||||
// True when applying skill to tagged props
|
||||
targetByTags: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Which tags the proficiency is applied to
|
||||
targetTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'targetTags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
extraTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.extraTagsCount,
|
||||
},
|
||||
'extraTags.$': {
|
||||
type: Object,
|
||||
},
|
||||
'extraTags.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue() {
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
'extraTags.$.operation': {
|
||||
type: String,
|
||||
allowedValues: ['OR', 'NOT'],
|
||||
defaultValue: 'OR',
|
||||
},
|
||||
'extraTags.$.tags': {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'extraTags.$.tags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
});
|
||||
// Skills can apply their value to other calculations as a proficiency using tag targeting
|
||||
}).extend(TagTargetingSchema);
|
||||
|
||||
let ComputedOnlySkillSchema = createPropertySchema({
|
||||
// Computed value of skill to be added to skill rolls
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
import TagTargetingSchema from '/imports/api/properties/subSchemas/TagTargetingSchema.js';
|
||||
|
||||
const ToggleSchema = createPropertySchema({
|
||||
name: {
|
||||
@@ -31,7 +32,7 @@ const ToggleSchema = createPropertySchema({
|
||||
type: 'fieldToCompute',
|
||||
optional: true,
|
||||
},
|
||||
});
|
||||
}).extend(TagTargetingSchema);
|
||||
|
||||
const ComputedOnlyToggleSchema = createPropertySchema({
|
||||
condition: {
|
||||
|
||||
57
app/imports/api/properties/subSchemas/TagTargetingSchema.js
Normal file
57
app/imports/api/properties/subSchemas/TagTargetingSchema.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
|
||||
const TagTargetingSchema = new SimpleSchema({
|
||||
// True when targeting by tags instead of stats
|
||||
targetByTags: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// If targeting by tags, the field which will be targeted
|
||||
targetField: {
|
||||
type: String,
|
||||
optional: true,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// Which tags the effect is applied to
|
||||
targetTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'targetTags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
extraTags: {
|
||||
type: Array,
|
||||
optional: true,
|
||||
maxCount: STORAGE_LIMITS.extraTagsCount,
|
||||
},
|
||||
'extraTags.$': {
|
||||
type: Object,
|
||||
},
|
||||
'extraTags.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue() {
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
'extraTags.$.operation': {
|
||||
type: String,
|
||||
allowedValues: ['OR', 'NOT'],
|
||||
defaultValue: 'OR',
|
||||
},
|
||||
'extraTags.$.tags': {
|
||||
type: Array,
|
||||
defaultValue: [],
|
||||
maxCount: STORAGE_LIMITS.tagCount,
|
||||
},
|
||||
'extraTags.$.tags.$': {
|
||||
type: String,
|
||||
max: STORAGE_LIMITS.tagLength,
|
||||
},
|
||||
});
|
||||
|
||||
export default TagTargetingSchema;
|
||||
@@ -45,6 +45,29 @@
|
||||
/>
|
||||
</v-col>
|
||||
</v-expand-transition>
|
||||
<v-col cols="12">
|
||||
<smart-toggle
|
||||
label="Enabled or disable properties"
|
||||
:value="model.targetByTags"
|
||||
:options="[
|
||||
{name: 'Descendants', value: false},
|
||||
{name: 'By target tags', value: true},
|
||||
]"
|
||||
@change="change('targetByTags', ...arguments)"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-expand-transition>
|
||||
<tag-targeting
|
||||
v-if="model.targetByTags"
|
||||
:model="model"
|
||||
:errors="errors"
|
||||
@change="e => $emit('change', e)"
|
||||
@push="e => $emit('push', e)"
|
||||
@pull="e => $emit('pull', e)"
|
||||
/>
|
||||
</v-expand-transition>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<form-sections type="toggle">
|
||||
@@ -69,8 +92,12 @@
|
||||
|
||||
<script lang="js">
|
||||
import propertyFormMixin from '/imports/client/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import TagTargeting from '/imports/client/ui/properties/forms/shared/TagTargeting.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TagTargeting,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
computed: {
|
||||
radioSelection() {
|
||||
|
||||
@@ -3,6 +3,50 @@
|
||||
v-if="model && $options.components[model.type]"
|
||||
class="property-viewer"
|
||||
>
|
||||
<v-row dense>
|
||||
<property-field
|
||||
v-if="model.inactive"
|
||||
name="Status"
|
||||
:cols="{cols: 12}"
|
||||
>
|
||||
<div
|
||||
style="width: 100%"
|
||||
class="text--disabled"
|
||||
>
|
||||
<div>
|
||||
Inactive
|
||||
</div>
|
||||
<div
|
||||
v-if="model.deactivatedByToggle && deactivatingToggle"
|
||||
class="pt-2"
|
||||
>
|
||||
<div>Deactivated by:</div>
|
||||
<v-btn
|
||||
block
|
||||
:data-id="`tree-node-${model.deactivatingToggleId}`"
|
||||
style="text-transform: initial;"
|
||||
@click="selectSubProperty(model.deactivatingToggleId)"
|
||||
>
|
||||
<tree-node-view
|
||||
:model="deactivatingToggle"
|
||||
/>
|
||||
</v-btn>
|
||||
</div>
|
||||
<div
|
||||
v-if="model.deactivatedByAncestor"
|
||||
class="pt-2"
|
||||
>
|
||||
Deactivated by ancestor
|
||||
</div>
|
||||
<div
|
||||
v-if="model.deactivatedBySelf"
|
||||
class="pt-2"
|
||||
>
|
||||
Deactivated by own settings
|
||||
</div>
|
||||
</div>
|
||||
</property-field>
|
||||
</v-row>
|
||||
<component
|
||||
:is="model.type"
|
||||
:key="model._id"
|
||||
@@ -109,12 +153,15 @@ import propertyViewerIndex from '/imports/client/ui/properties/viewers/shared/pr
|
||||
import CreaturePropertiesTree from '/imports/client/ui/creature/creatureProperties/CreaturePropertiesTree.vue';
|
||||
import PropertyField from '/imports/client/ui/properties/viewers/shared/PropertyField.vue';
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import TreeNodeView from '/imports/client/ui/properties/treeNodeViews/TreeNodeView.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
...propertyViewerIndex,
|
||||
CreaturePropertiesTree,
|
||||
PropertyField,
|
||||
TreeNodeView,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
@@ -131,6 +178,12 @@ export default {
|
||||
childrenLength: 0,
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
deactivatingToggle() {
|
||||
if (!this.model.deactivatingToggleId) return;
|
||||
return CreatureProperties.findOne(this.model.deactivatingToggleId);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
slotFillTypeName() {
|
||||
return getPropertyName(this.model.slotFillerType);
|
||||
|
||||
@@ -17,39 +17,10 @@
|
||||
name="Amount"
|
||||
:value="displayedValue || ' '"
|
||||
/>
|
||||
<property-field
|
||||
<property-target-tags
|
||||
v-if="model.targetByTags"
|
||||
name="Targeted tags"
|
||||
>
|
||||
<div>
|
||||
<div class="d-flex flex-wrap">
|
||||
<v-chip
|
||||
v-for="(tag, index) in model.targetTags"
|
||||
:key="index"
|
||||
class="ma-1"
|
||||
>
|
||||
{{ tag }}
|
||||
</v-chip>
|
||||
</div>
|
||||
<div
|
||||
v-for="ex in model.extraTags"
|
||||
:key="ex._id"
|
||||
>
|
||||
<span class="ma-2">
|
||||
{{ ex.operation }}
|
||||
</span>
|
||||
<div class="d-flex flex-wrap">
|
||||
<v-chip
|
||||
v-for="(extraTag, index) in ex.tags"
|
||||
:key="index"
|
||||
class="ma-1"
|
||||
>
|
||||
{{ extraTag }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</property-field>
|
||||
:model="model"
|
||||
/>
|
||||
<property-field
|
||||
v-else
|
||||
name="Stats"
|
||||
@@ -76,10 +47,14 @@
|
||||
|
||||
<script lang="js">
|
||||
import propertyViewerMixin from '/imports/client/ui/properties/viewers/shared/propertyViewerMixin.js';
|
||||
import PropertyTargetTags from '/imports/client/ui/properties/viewers/shared/PropertyTargetTags.vue';
|
||||
import getEffectIcon from '/imports/client/ui/utility/getEffectIcon.js';
|
||||
import { isFinite } from 'lodash';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PropertyTargetTags,
|
||||
},
|
||||
mixins: [propertyViewerMixin],
|
||||
computed: {
|
||||
resolvedValue() {
|
||||
|
||||
@@ -14,7 +14,12 @@
|
||||
{{ proficiencyText }}
|
||||
</div>
|
||||
</property-field>
|
||||
<property-target-tags
|
||||
v-if="model.targetByTags"
|
||||
:model="model"
|
||||
/>
|
||||
<property-field
|
||||
v-else
|
||||
name="Stats"
|
||||
:value="model.stats && model.stats.join(', ')"
|
||||
mono
|
||||
@@ -26,10 +31,12 @@
|
||||
<script lang="js">
|
||||
import propertyViewerMixin from '/imports/client/ui/properties/viewers/shared/propertyViewerMixin.js';
|
||||
import ProficiencyIcon from '/imports/client/ui/properties/shared/ProficiencyIcon.vue';
|
||||
import PropertyTargetTags from '/imports/client/ui/properties/viewers/shared/PropertyTargetTags.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ProficiencyIcon,
|
||||
PropertyTargetTags,
|
||||
},
|
||||
mixins: [propertyViewerMixin],
|
||||
computed: {
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
name="Overridden"
|
||||
value="Overriden by another property with the same variable name"
|
||||
/>
|
||||
<property-target-tags
|
||||
:model="model"
|
||||
/>
|
||||
</v-row>
|
||||
<v-row dense>
|
||||
<property-description
|
||||
@@ -127,11 +130,13 @@ import SkillProficiency from '/imports/client/ui/properties/components/skills/Sk
|
||||
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';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AttributeEffect,
|
||||
SkillProficiency,
|
||||
PropertyTargetTags,
|
||||
},
|
||||
mixins: [propertyViewerMixin],
|
||||
inject: {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/>
|
||||
<property-field
|
||||
v-if="model.disabled || model.enabled"
|
||||
name="Status"
|
||||
name="State"
|
||||
:value="model.enabled ? 'Enabled' : 'Disabled'"
|
||||
/>
|
||||
<template v-else-if="model.condition">
|
||||
@@ -16,6 +16,9 @@
|
||||
name="Condition"
|
||||
:calculation="model.condition"
|
||||
/>
|
||||
<property-target-tags
|
||||
:model="model"
|
||||
/>
|
||||
</template>
|
||||
</v-row>
|
||||
</div>
|
||||
@@ -23,8 +26,12 @@
|
||||
|
||||
<script lang="js">
|
||||
import propertyViewerMixin from '/imports/client/ui/properties/viewers/shared/propertyViewerMixin.js'
|
||||
import PropertyTargetTags from '/imports/client/ui/properties/viewers/shared/PropertyTargetTags.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PropertyTargetTags,
|
||||
},
|
||||
mixins: [propertyViewerMixin],
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<template lang="html">
|
||||
<property-field
|
||||
v-if="model.targetByTags"
|
||||
name="Targeted tags"
|
||||
>
|
||||
<div
|
||||
class="py-1"
|
||||
>
|
||||
<div class="d-flex flex-wrap">
|
||||
<v-chip
|
||||
v-for="(tag, index) in model.targetTags"
|
||||
:key="index"
|
||||
class="mr-1"
|
||||
disabled
|
||||
small
|
||||
>
|
||||
{{ tag }}
|
||||
</v-chip>
|
||||
</div>
|
||||
<div
|
||||
v-for="ex in model.extraTags"
|
||||
:key="ex._id"
|
||||
>
|
||||
<span class="ma-2">
|
||||
{{ ex.operation }}
|
||||
</span>
|
||||
<div class="d-flex flex-wrap">
|
||||
<v-chip
|
||||
v-for="(extraTag, index) in ex.tags"
|
||||
:key="index"
|
||||
class="mr-1"
|
||||
disabled
|
||||
small
|
||||
>
|
||||
{{ extraTag }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</property-field>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import PropertyField from '/imports/client/ui/properties/viewers/shared/PropertyField.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PropertyField,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user