Added custom sheet events
Made rest buttons optional
This commit is contained in:
@@ -18,6 +18,11 @@ let CreatureSettingsSchema = new SimpleSchema({
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
//hide rest buttons
|
||||
hideRestButtons: {
|
||||
type: Boolean,
|
||||
optional: true,
|
||||
},
|
||||
// Swap around the modifier and stat
|
||||
swapStatAndModifier: {
|
||||
type: Boolean,
|
||||
|
||||
@@ -49,7 +49,7 @@ const restCreature = new ValidatedMethod({
|
||||
applyTriggers(afterTriggers, null, actionContext);
|
||||
|
||||
// Insert log
|
||||
actionContext.writeLog();
|
||||
actionContext.writeLog();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -57,88 +57,123 @@ function doRestWork(restType, actionContext) {
|
||||
const creatureId = actionContext.creature._id;
|
||||
// Long rests reset short rest properties as well
|
||||
let resetFilter;
|
||||
if (restType === 'shortRest'){
|
||||
if (restType === 'shortRest') {
|
||||
resetFilter = 'shortRest'
|
||||
} else {
|
||||
resetFilter = {$in: ['shortRest', 'longRest']}
|
||||
resetFilter = { $in: ['shortRest', 'longRest'] }
|
||||
}
|
||||
resetProperties(creatureId, resetFilter, actionContext);
|
||||
|
||||
// Reset half hit dice on a long rest, starting with the highest dice
|
||||
if (restType === 'longRest') {
|
||||
resetHitDice(creatureId, actionContext);
|
||||
}
|
||||
}
|
||||
|
||||
export function resetProperties(creatureId, resetFilter, actionContext) {
|
||||
// Only apply to active properties
|
||||
let filter = {
|
||||
const filter = {
|
||||
'ancestors.id': creatureId,
|
||||
reset: resetFilter,
|
||||
removed: { $ne: true },
|
||||
inactive: { $ne: true },
|
||||
};
|
||||
// update all attribute's damage
|
||||
filter.type = 'attribute';
|
||||
CreatureProperties.update(filter, {
|
||||
const attributeFilter = {
|
||||
...filter,
|
||||
type: 'attribute',
|
||||
damage: { $ne: 0 },
|
||||
}
|
||||
CreatureProperties.find(attributeFilter, {
|
||||
fields: { name: 1, damage: 1 }
|
||||
}).forEach(prop => {
|
||||
actionContext.addLog({
|
||||
name: prop.name,
|
||||
value: prop.damage >= 0 ? `Restored ${prop.damage}` : `Removed ${-prop.damage}`
|
||||
});
|
||||
});
|
||||
CreatureProperties.update(attributeFilter, {
|
||||
$set: {
|
||||
damage: 0,
|
||||
dirty: true,
|
||||
}
|
||||
}, {
|
||||
selector: {type: 'attribute'},
|
||||
selector: { type: 'attribute' },
|
||||
multi: true,
|
||||
});
|
||||
// Update all action-like properties' usesUsed
|
||||
filter.type = {$in: [
|
||||
'action',
|
||||
'attack',
|
||||
'spell'
|
||||
]};
|
||||
CreatureProperties.update(filter, {
|
||||
const actionFilter = {
|
||||
...filter,
|
||||
type: {
|
||||
$in: ['action', 'spell']
|
||||
},
|
||||
usesUsed: { $ne: 0 },
|
||||
};
|
||||
CreatureProperties.find(actionFilter, {
|
||||
fields: { name: 1, usesUsed: 1 }
|
||||
}).forEach(prop => {
|
||||
actionContext.addLog({
|
||||
name: prop.name,
|
||||
value: prop.usesUsed >= 0 ? `Restored ${prop.usesUsed} uses` : `Removed ${-prop.usesUsed} uses`
|
||||
});
|
||||
});
|
||||
CreatureProperties.update(actionFilter, {
|
||||
$set: {
|
||||
usesUsed: 0,
|
||||
dirty: true,
|
||||
}
|
||||
}, {
|
||||
selector: {type: 'action'},
|
||||
selector: { type: 'action' },
|
||||
multi: true,
|
||||
});
|
||||
// Reset half hit dice on a long rest, starting with the highest dice
|
||||
if (restType === 'longRest'){
|
||||
let hitDice = CreatureProperties.find({
|
||||
'ancestors.id': creatureId,
|
||||
type: 'attribute',
|
||||
attributeType: 'hitDice',
|
||||
removed: {$ne: true},
|
||||
inactive: {$ne: true},
|
||||
}, {
|
||||
fields: {
|
||||
hitDiceSize: 1,
|
||||
damage: 1,
|
||||
total: 1,
|
||||
}
|
||||
|
||||
function resetHitDice(creatureId, actionContext) {
|
||||
let hitDice = CreatureProperties.find({
|
||||
'ancestors.id': creatureId,
|
||||
type: 'attribute',
|
||||
attributeType: 'hitDice',
|
||||
removed: { $ne: true },
|
||||
inactive: { $ne: true },
|
||||
}, {
|
||||
fields: {
|
||||
hitDiceSize: 1,
|
||||
damage: 1,
|
||||
total: 1,
|
||||
}
|
||||
}).fetch();
|
||||
// Use a collator to do sorting in natural order
|
||||
let collator = new Intl.Collator('en', {
|
||||
numeric: true, sensitivity: 'base'
|
||||
});
|
||||
// Get the hit dice in decending order of hitDiceSize
|
||||
let compare = (a, b) => collator.compare(b.hitDiceSize, a.hitDiceSize)
|
||||
hitDice.sort(compare);
|
||||
// Get the total number of hit dice that can be recovered this rest
|
||||
let totalHd = hitDice.reduce((sum, hd) => sum + (hd.total || 0), 0);
|
||||
let resetMultiplier = actionContext.creature.settings.hitDiceResetMultiplier || 0.5;
|
||||
let recoverableHd = Math.max(Math.floor(totalHd * resetMultiplier), 1);
|
||||
// recover each hit dice in turn until the recoverable amount is used up
|
||||
let amountToRecover, resultingDamage;
|
||||
hitDice.forEach(hd => {
|
||||
if (!recoverableHd) return;
|
||||
amountToRecover = Math.min(recoverableHd, hd.damage || 0);
|
||||
if (!amountToRecover) return;
|
||||
recoverableHd -= amountToRecover;
|
||||
resultingDamage = hd.damage - amountToRecover;
|
||||
actionContext.addLog({
|
||||
name: hd.name,
|
||||
value: amountToRecover >= 0 ? `Restored ${amountToRecover} hit dice` : `Removed ${-amountToRecover} hit dice`
|
||||
});
|
||||
CreatureProperties.update(hd._id, {
|
||||
$set: {
|
||||
damage: resultingDamage,
|
||||
dirty: true,
|
||||
}
|
||||
}).fetch();
|
||||
// Use a collator to do sorting in natural order
|
||||
let collator = new Intl.Collator('en', {
|
||||
numeric: true, sensitivity: 'base'
|
||||
}, {
|
||||
selector: { type: 'attribute' },
|
||||
});
|
||||
// Get the hit dice in decending order of hitDiceSize
|
||||
let compare = (a, b) => collator.compare(b.hitDiceSize, a.hitDiceSize)
|
||||
hitDice.sort(compare);
|
||||
// Get the total number of hit dice that can be recovered this rest
|
||||
let totalHd = hitDice.reduce((sum, hd) => sum + (hd.total || 0), 0);
|
||||
let resetMultiplier = actionContext.creature.settings.hitDiceResetMultiplier || 0.5;
|
||||
let recoverableHd = Math.max(Math.floor(totalHd*resetMultiplier), 1);
|
||||
// recover each hit dice in turn until the recoverable amount is used up
|
||||
let amountToRecover, resultingDamage;
|
||||
hitDice.forEach(hd => {
|
||||
if (!recoverableHd) return;
|
||||
amountToRecover = Math.min(recoverableHd, hd.damage || 0);
|
||||
if (!amountToRecover) return;
|
||||
recoverableHd -= amountToRecover;
|
||||
resultingDamage = hd.damage - amountToRecover;
|
||||
CreatureProperties.update(hd._id, {
|
||||
$set: {
|
||||
damage: resultingDamage,
|
||||
dirty: true,
|
||||
}
|
||||
}, {
|
||||
selector: {type: 'attribute'},
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default restCreature;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { adjustQuantityWork } from '/imports/api/creature/creatureProperties/met
|
||||
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.js';
|
||||
import { resetProperties } from '/imports/api/creature/creatures/methods/restCreature.js';
|
||||
|
||||
export default function applyAction(node, actionContext) {
|
||||
applyNodeTriggers(node, 'before', actionContext);
|
||||
@@ -16,7 +17,7 @@ export default function applyAction(node, actionContext) {
|
||||
|
||||
// Log the name and summary
|
||||
let content = { name: prop.name };
|
||||
if (prop.summary?.text){
|
||||
if (prop.summary?.text) {
|
||||
recalculateInlineCalculations(prop.summary, actionContext);
|
||||
content.value = prop.summary.value;
|
||||
}
|
||||
@@ -29,24 +30,27 @@ export default function applyAction(node, actionContext) {
|
||||
const attack = prop.attackRoll || prop.attackRollBonus;
|
||||
|
||||
// Attack if there is an attack roll
|
||||
if (attack && attack.calculation){
|
||||
if (targets.length){
|
||||
if (attack && attack.calculation) {
|
||||
if (targets.length) {
|
||||
targets.forEach(target => {
|
||||
applyAttackToTarget({attack, target, actionContext});
|
||||
applyAttackToTarget({ attack, target, actionContext });
|
||||
// Apply the children, but only to the current target
|
||||
actionContext.targets = [target];
|
||||
applyChildren(node, actionContext);
|
||||
});
|
||||
} else {
|
||||
applyAttackWithoutTarget({attack, actionContext});
|
||||
applyAttackWithoutTarget({ attack, actionContext });
|
||||
applyChildren(node, actionContext);
|
||||
}
|
||||
} else {
|
||||
applyChildren(node, actionContext);
|
||||
}
|
||||
if (prop.actionType === 'event' && prop.variableName) {
|
||||
resetProperties(actionContext.creature._id, prop.variableName, actionContext);
|
||||
}
|
||||
}
|
||||
|
||||
function applyAttackWithoutTarget({attack, actionContext}){
|
||||
function applyAttackWithoutTarget({ attack, actionContext }) {
|
||||
delete actionContext.scope['$attackHit'];
|
||||
delete actionContext.scope['$attackMiss'];
|
||||
delete actionContext.scope['$criticalHit'];
|
||||
@@ -62,16 +66,16 @@ function applyAttackWithoutTarget({attack, actionContext}){
|
||||
criticalMiss,
|
||||
} = rollAttack(attack, scope);
|
||||
let name = criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit';
|
||||
if (scope['$attackAdvantage'] === 1){
|
||||
if (scope['$attackAdvantage'] === 1) {
|
||||
name += ' (Advantage)';
|
||||
} else if(scope['$attackAdvantage'] === -1){
|
||||
} else if (scope['$attackAdvantage'] === -1) {
|
||||
name += ' (Disadvantage)';
|
||||
}
|
||||
if (!criticalMiss){
|
||||
scope['$attackHit'] = {value: true}
|
||||
if (!criticalMiss) {
|
||||
scope['$attackHit'] = { value: true }
|
||||
}
|
||||
if (!criticalHit){
|
||||
scope['$attackMiss'] = {value: true};
|
||||
if (!criticalHit) {
|
||||
scope['$attackMiss'] = { value: true };
|
||||
}
|
||||
|
||||
actionContext.addLog({
|
||||
@@ -81,7 +85,7 @@ function applyAttackWithoutTarget({attack, actionContext}){
|
||||
});
|
||||
}
|
||||
|
||||
function applyAttackToTarget({attack, target, actionContext}){
|
||||
function applyAttackToTarget({ attack, target, actionContext }) {
|
||||
const scope = actionContext.scope;
|
||||
delete scope['$attackHit'];
|
||||
delete scope['$attackMiss'];
|
||||
@@ -99,15 +103,15 @@ function applyAttackToTarget({attack, target, actionContext}){
|
||||
criticalMiss,
|
||||
} = rollAttack(attack, scope);
|
||||
|
||||
if (target.variables.armor){
|
||||
if (target.variables.armor) {
|
||||
const armor = target.variables.armor.value;
|
||||
|
||||
let name = criticalHit ? 'Critical Hit!' :
|
||||
criticalMiss ? 'Critical Miss!' :
|
||||
result > armor ? 'Hit!' : 'Miss!';
|
||||
if (scope['$attackAdvantage'] === 1){
|
||||
result > armor ? 'Hit!' : 'Miss!';
|
||||
if (scope['$attackAdvantage'] === 1) {
|
||||
name += ' (Advantage)';
|
||||
} else if(scope['$attackAdvantage'] === -1){
|
||||
} else if (scope['$attackAdvantage'] === -1) {
|
||||
name += ' (Disadvantage)';
|
||||
}
|
||||
|
||||
@@ -116,15 +120,15 @@ function applyAttackToTarget({attack, target, actionContext}){
|
||||
value: `${resultPrefix}\n**${result}**`,
|
||||
inline: true,
|
||||
});
|
||||
if (criticalMiss || result < armor){
|
||||
scope['$attackMiss'] = {value: true};
|
||||
if (criticalMiss || result < armor) {
|
||||
scope['$attackMiss'] = { value: true };
|
||||
} else {
|
||||
scope['$attackHit'] = {value: true};
|
||||
scope['$attackHit'] = { value: true };
|
||||
}
|
||||
} else {
|
||||
actionContext.addLog({
|
||||
name: 'Error',
|
||||
value:'Target has no `armor`',
|
||||
value: 'Target has no `armor`',
|
||||
});
|
||||
actionContext.addLog({
|
||||
name: criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit',
|
||||
@@ -134,10 +138,10 @@ function applyAttackToTarget({attack, target, actionContext}){
|
||||
}
|
||||
}
|
||||
|
||||
function rollAttack(attack, scope){
|
||||
function rollAttack(attack, scope) {
|
||||
const rollModifierText = numberToSignedString(attack.value, true);
|
||||
let value, resultPrefix;
|
||||
if (scope['$attackAdvantage'] === 1){
|
||||
if (scope['$attackAdvantage'] === 1) {
|
||||
const [a, b] = rollDice(2, 20);
|
||||
if (a >= b) {
|
||||
value = a;
|
||||
@@ -146,7 +150,7 @@ function rollAttack(attack, scope){
|
||||
value = b;
|
||||
resultPrefix = `1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
||||
}
|
||||
} else if (scope['$attackAdvantage'] === -1){
|
||||
} else if (scope['$attackAdvantage'] === -1) {
|
||||
const [a, b] = rollDice(2, 20);
|
||||
if (a <= b) {
|
||||
value = a;
|
||||
@@ -159,25 +163,25 @@ function rollAttack(attack, scope){
|
||||
value = rollDice(1, 20)[0];
|
||||
resultPrefix = `1d20 [${value}] ${rollModifierText}`
|
||||
}
|
||||
scope['$attackRoll'] = {value};
|
||||
scope['$attackRoll'] = { value };
|
||||
const result = value + attack.value;
|
||||
const {criticalHit, criticalMiss} = applyCrits(value, scope);
|
||||
return {resultPrefix, result, value, criticalHit, criticalMiss};
|
||||
const { criticalHit, criticalMiss } = applyCrits(value, scope);
|
||||
return { resultPrefix, result, value, criticalHit, criticalMiss };
|
||||
}
|
||||
|
||||
function applyCrits(value, scope){
|
||||
function applyCrits(value, scope) {
|
||||
let criticalHitTarget = scope.criticalHitTarget?.value || 20;
|
||||
let criticalHit = value >= criticalHitTarget;
|
||||
let criticalMiss;
|
||||
if (criticalHit){
|
||||
scope['$criticalHit'] = {value: true};
|
||||
if (criticalHit) {
|
||||
scope['$criticalHit'] = { value: true };
|
||||
} else {
|
||||
criticalMiss = value === 1;
|
||||
if (criticalMiss){
|
||||
scope['$criticalMiss'] = {value: true};
|
||||
if (criticalMiss) {
|
||||
scope['$criticalMiss'] = { value: true };
|
||||
}
|
||||
}
|
||||
return {criticalHit, criticalMiss};
|
||||
return { criticalHit, criticalMiss };
|
||||
}
|
||||
|
||||
function applyChildren(node, actionContext) {
|
||||
@@ -185,9 +189,9 @@ function applyChildren(node, actionContext) {
|
||||
node.children.forEach(child => applyProperty(child, actionContext));
|
||||
}
|
||||
|
||||
function spendResources(prop, actionContext){
|
||||
function spendResources(prop, actionContext) {
|
||||
// Check Uses
|
||||
if (prop.usesLeft <= 0){
|
||||
if (prop.usesLeft <= 0) {
|
||||
if (!prop.silent) actionContext.addLog({
|
||||
name: 'Error',
|
||||
value: `${prop.name || 'action'} does not have enough uses left`,
|
||||
@@ -195,7 +199,7 @@ function spendResources(prop, actionContext){
|
||||
return true;
|
||||
}
|
||||
// Resources
|
||||
if (prop.insufficientResources){
|
||||
if (prop.insufficientResources) {
|
||||
if (!prop.silent) actionContext.addLog({
|
||||
name: 'Error',
|
||||
value: 'This creature doesn\'t have sufficient resources to perform this action',
|
||||
@@ -209,14 +213,14 @@ function spendResources(prop, actionContext){
|
||||
try {
|
||||
prop.resources.itemsConsumed.forEach(itemConsumed => {
|
||||
recalculateCalculation(itemConsumed.quantity, actionContext);
|
||||
if (!itemConsumed.itemId){
|
||||
if (!itemConsumed.itemId) {
|
||||
throw 'No ammo was selected for this prop';
|
||||
}
|
||||
let item = CreatureProperties.findOne(itemConsumed.itemId);
|
||||
if (!item || item.ancestors[0].id !== prop.ancestors[0].id){
|
||||
if (!item || item.ancestors[0].id !== prop.ancestors[0].id) {
|
||||
throw 'The prop\'s ammo was not found on the creature';
|
||||
}
|
||||
if (!item.equipped){
|
||||
if (!item.equipped) {
|
||||
throw 'The selected ammo is not equipped';
|
||||
}
|
||||
if (
|
||||
@@ -229,16 +233,16 @@ function spendResources(prop, actionContext){
|
||||
value: itemConsumed.quantity.value,
|
||||
});
|
||||
let logName = item.name;
|
||||
if (itemConsumed.quantity.value > 1 || itemConsumed.quantity.value < -1){
|
||||
if (itemConsumed.quantity.value > 1 || itemConsumed.quantity.value < -1) {
|
||||
logName = item.plural || logName;
|
||||
}
|
||||
if (itemConsumed.quantity.value > 0){
|
||||
if (itemConsumed.quantity.value > 0) {
|
||||
spendLog.push(logName + ': ' + itemConsumed.quantity.value);
|
||||
} else if (itemConsumed.quantity.value < 0){
|
||||
} else if (itemConsumed.quantity.value < 0) {
|
||||
gainLog.push(logName + ': ' + -itemConsumed.quantity.value);
|
||||
}
|
||||
});
|
||||
} catch (e){
|
||||
} catch (e) {
|
||||
actionContext.addLog({
|
||||
name: 'Error',
|
||||
value: e,
|
||||
@@ -251,9 +255,9 @@ function spendResources(prop, actionContext){
|
||||
itemQuantityAdjustments.forEach(adjustQuantityWork);
|
||||
|
||||
// Use uses
|
||||
if (prop.usesLeft){
|
||||
if (prop.usesLeft) {
|
||||
CreatureProperties.update(prop._id, {
|
||||
$inc: {usesUsed: 1}
|
||||
$inc: { usesUsed: 1 }
|
||||
}, {
|
||||
selector: prop
|
||||
});
|
||||
@@ -270,7 +274,7 @@ function spendResources(prop, actionContext){
|
||||
|
||||
if (!attConsumed.quantity?.value) return;
|
||||
let stat = actionContext.scope[attConsumed.variableName];
|
||||
if (!stat){
|
||||
if (!stat) {
|
||||
spendLog.push(stat.name + ': ' + ' not found');
|
||||
return;
|
||||
}
|
||||
@@ -280,9 +284,9 @@ function spendResources(prop, actionContext){
|
||||
value: attConsumed.quantity.value,
|
||||
actionContext,
|
||||
});
|
||||
if (attConsumed.quantity.value > 0){
|
||||
if (attConsumed.quantity.value > 0) {
|
||||
spendLog.push(stat.name + ': ' + attConsumed.quantity.value);
|
||||
} else if (attConsumed.quantity.value < 0){
|
||||
} else if (attConsumed.quantity.value < 0) {
|
||||
gainLog.push(stat.name + ': ' + -attConsumed.quantity.value);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import SimpleSchema from 'simpl-schema';
|
||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||
import { storedIconsSchema } from '/imports/api/icons/Icons.js';
|
||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.js';
|
||||
import VARIABLE_NAME_REGEX from '/imports/constants/VARIABLE_NAME_REGEX.js';
|
||||
|
||||
/*
|
||||
* Actions are things a character can do
|
||||
@@ -24,9 +25,17 @@ let ActionSchema = createPropertySchema({
|
||||
// long actions take longer than 1 round to cast
|
||||
actionType: {
|
||||
type: String,
|
||||
allowedValues: ['action', 'bonus', 'attack', 'reaction', 'free', 'long'],
|
||||
allowedValues: ['action', 'bonus', 'attack', 'reaction', 'free', 'long', 'event'],
|
||||
defaultValue: 'action',
|
||||
},
|
||||
// If the action type is an event, what is the variable name of that event?
|
||||
variableName: {
|
||||
type: String,
|
||||
optional: true,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
min: 2,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// Who is the action directed at
|
||||
target: {
|
||||
type: String,
|
||||
@@ -56,8 +65,10 @@ let ActionSchema = createPropertySchema({
|
||||
// How this action's uses are reset automatically
|
||||
reset: {
|
||||
type: String,
|
||||
allowedValues: ['longRest', 'shortRest'],
|
||||
optional: true,
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
min: 2,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
// Resources
|
||||
resources: {
|
||||
@@ -74,7 +85,7 @@ let ActionSchema = createPropertySchema({
|
||||
'resources.itemsConsumed.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
autoValue() {
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
@@ -101,7 +112,7 @@ let ActionSchema = createPropertySchema({
|
||||
'resources.attributesConsumed.$._id': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
autoValue(){
|
||||
autoValue() {
|
||||
if (!this.isSet) return Random.id();
|
||||
}
|
||||
},
|
||||
@@ -218,4 +229,4 @@ const ComputedActionSchema = new SimpleSchema()
|
||||
.extend(ActionSchema)
|
||||
.extend(ComputedOnlyActionSchema);
|
||||
|
||||
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema};
|
||||
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema };
|
||||
|
||||
@@ -129,7 +129,9 @@ let AttributeSchema = createPropertySchema({
|
||||
reset: {
|
||||
type: String,
|
||||
optional: true,
|
||||
allowedValues: ['shortRest', 'longRest'],
|
||||
regEx: VARIABLE_NAME_REGEX,
|
||||
min: 2,
|
||||
max: STORAGE_LIMITS.variableName,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
46
app/imports/ui/components/ResetSelector.vue
Normal file
46
app/imports/ui/components/ResetSelector.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<smart-select
|
||||
label="Reset"
|
||||
clearable
|
||||
style="flex-basis: 300px;"
|
||||
:hint="hint"
|
||||
:items="resetOptions"
|
||||
:value="value"
|
||||
:error-messages="errorMessages"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="(value, ack) => $emit('change', value, ack)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import createListOfProperties from '/imports/ui/properties/forms/shared/lists/createListOfProperties.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: [String, Number, Date, Array, Object, Boolean],
|
||||
errorMessages: [String, Array],
|
||||
hint: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
resetOptions() {
|
||||
const eventActions = createListOfProperties({
|
||||
type: 'action',
|
||||
actionType: 'event',
|
||||
}, true);
|
||||
const defaultEvents = [
|
||||
{
|
||||
text: 'Short rest',
|
||||
value: 'shortRest',
|
||||
}, {
|
||||
text: 'Long rest',
|
||||
value: 'longRest',
|
||||
}
|
||||
];
|
||||
return [...defaultEvents, ...eventActions];
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -39,6 +39,11 @@
|
||||
:input-value="model.settings.hideUnusedStats"
|
||||
@change="value => $emit('change', {path: ['settings','hideUnusedStats'], value: !!value})"
|
||||
/>
|
||||
<v-switch
|
||||
label="Hide rest buttons"
|
||||
:input-value="model.settings.hideRestButtons"
|
||||
@change="value => $emit('change', {path: ['settings','hideRestButtons'], value: !!value})"
|
||||
/>
|
||||
<v-switch
|
||||
label="Show spells tab"
|
||||
:input-value="!model.settings.hideSpellsTab"
|
||||
|
||||
@@ -3,19 +3,30 @@
|
||||
<health-bar-card-container :creature-id="creatureId" />
|
||||
|
||||
<column-layout>
|
||||
<div class="character-buttons">
|
||||
<div
|
||||
v-if="!creature.settings.hideRestButtons || (events && events.length)"
|
||||
class="character-buttons"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-text class="layout column align-center">
|
||||
<rest-button
|
||||
v-if="!creature.settings.hideRestButtons"
|
||||
:creature-id="creatureId"
|
||||
type="shortRest"
|
||||
class="ma-1"
|
||||
/>
|
||||
<rest-button
|
||||
v-if="!creature.settings.hideRestButtons"
|
||||
:creature-id="creatureId"
|
||||
type="longRest"
|
||||
class="ma-1"
|
||||
/>
|
||||
<event-button
|
||||
v-for="event in events"
|
||||
:key="event._id"
|
||||
:model="event"
|
||||
class="ma-1"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
@@ -352,7 +363,9 @@ import RestButton from '/imports/ui/creature/RestButton.vue';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
||||
import EventButton from '/imports/ui/properties/components/actions/EventButton.vue';
|
||||
import { snackbar } from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||
import { uniqBy } from 'lodash';
|
||||
|
||||
const getProperties = function (creature, filter, options = {
|
||||
sort: { order: 1 }
|
||||
@@ -401,6 +414,7 @@ export default {
|
||||
SpellSlotListTile,
|
||||
ActionCard,
|
||||
ToggleCard,
|
||||
EventButton,
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
@@ -473,8 +487,12 @@ export default {
|
||||
languages() {
|
||||
return getSkillOfType(this.creature, 'language');
|
||||
},
|
||||
events() {
|
||||
const events = getProperties(this.creature, { type: 'action', actionType: 'event' });
|
||||
return uniqBy(events.fetch(), e => e.variableName);
|
||||
},
|
||||
actions() {
|
||||
return getProperties(this.creature, { type: 'action' });
|
||||
return getProperties(this.creature, { type: 'action', actionType: { $ne: 'event' } });
|
||||
},
|
||||
appliedBuffs() {
|
||||
return getProperties(this.creature, { type: 'buff' });
|
||||
|
||||
80
app/imports/ui/properties/components/actions/EventButton.vue
Normal file
80
app/imports/ui/properties/components/actions/EventButton.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template lang="html">
|
||||
<v-btn
|
||||
:loading="doActionLoading"
|
||||
:disabled="context.editPermission === false"
|
||||
outlined
|
||||
class="event-button"
|
||||
style="min-width: 160px; max-width: 100%;"
|
||||
:color="model.color"
|
||||
@click="doAction"
|
||||
>
|
||||
<property-icon
|
||||
style="margin-left: -4px; margin-right: 8px;"
|
||||
:model="model"
|
||||
/>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
{{ model.name }}
|
||||
</div>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import doAction from '/imports/api/engine/actions/doAction.js';
|
||||
import PropertyIcon from '/imports/ui/properties/shared/PropertyIcon.vue';
|
||||
import { snackbar } from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PropertyIcon,
|
||||
},
|
||||
inject: {
|
||||
context: { default: {} }
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data(){return {
|
||||
activated: undefined,
|
||||
doActionLoading: false,
|
||||
hovering: false,
|
||||
}},
|
||||
methods: {
|
||||
click(e) {
|
||||
this.$emit('click', e);
|
||||
},
|
||||
doAction({ advantage }) {
|
||||
this.doActionLoading = true;
|
||||
this.shwing();
|
||||
doAction.call({
|
||||
actionId: this.model._id,
|
||||
scope: {
|
||||
$attackAdvantage: advantage,
|
||||
}
|
||||
}, error => {
|
||||
this.doActionLoading = false;
|
||||
if (error) {
|
||||
console.error(error);
|
||||
snackbar({ text: error.reason });
|
||||
}
|
||||
});
|
||||
},
|
||||
shwing() {
|
||||
this.activated = true;
|
||||
setTimeout(() => {
|
||||
this.activated = undefined;
|
||||
}, 150);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.event-button .v-btn__content {
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,9 @@
|
||||
<template lang="html">
|
||||
<v-card
|
||||
:hover="hasClickListener"
|
||||
:class="hover ? 'elevation-8': ''"
|
||||
@click="click"
|
||||
@mouseover="hover = true"
|
||||
@mouseleave="hover = false"
|
||||
>
|
||||
<div class="layout align-center">
|
||||
<div
|
||||
@@ -18,19 +20,29 @@
|
||||
{{ model.name }}
|
||||
</v-card-title>
|
||||
</div>
|
||||
<card-highlight :active="hover" />
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import flipToggle from '/imports/api/creature/creatureProperties/methods/flipToggle.js';
|
||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CardHighlight,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hover: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasClickListener(){
|
||||
return this.$listeners && !!this.$listeners.click
|
||||
|
||||
@@ -41,6 +41,17 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-slide-x-transition mode="out-in">
|
||||
<text-field
|
||||
v-if="model.actionType === 'event'"
|
||||
label="Event variable name"
|
||||
:value="model.variableName"
|
||||
hint="Variable name of the event that this action represents"
|
||||
:error-messages="errors.variableName"
|
||||
@change="change('variableName', ...arguments)"
|
||||
/>
|
||||
</v-slide-x-transition>
|
||||
|
||||
<v-slide-x-transition mode="out-in">
|
||||
<v-switch
|
||||
v-if="!isAttack"
|
||||
@@ -154,15 +165,10 @@
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<smart-select
|
||||
label="Reset"
|
||||
clearable
|
||||
<reset-selector
|
||||
hint="When number of uses used should be reset to zero"
|
||||
style="flex-basis: 300px;"
|
||||
:items="resetOptions"
|
||||
:value="model.reset"
|
||||
:error-messages="errors.reset"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="change('reset', ...arguments)"
|
||||
/>
|
||||
</form-section>
|
||||
@@ -171,77 +177,74 @@
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
||||
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
||||
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ResourcesForm,
|
||||
IconColorMenu,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
data(){
|
||||
let data = {
|
||||
actionTypes: [
|
||||
{
|
||||
text: 'Action',
|
||||
value: 'action',
|
||||
}, {
|
||||
text: 'Bonus action',
|
||||
value: 'bonus',
|
||||
}, {
|
||||
text: 'Attack action',
|
||||
value: 'attack',
|
||||
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
|
||||
}, {
|
||||
text: 'Reaction',
|
||||
value: 'reaction',
|
||||
}, {
|
||||
text: 'Free action',
|
||||
value: 'free',
|
||||
help: 'You can take one free action on your turn without using an action or bonus action'
|
||||
}, {
|
||||
text: 'Long action',
|
||||
value: 'long',
|
||||
help: 'Long actions take longer than one turn to complete'
|
||||
},
|
||||
],
|
||||
targetOptions: [
|
||||
{
|
||||
text: 'Self',
|
||||
value: 'self',
|
||||
}, {
|
||||
text: 'Single target',
|
||||
value: 'singleTarget',
|
||||
}, {
|
||||
text: 'Multiple targets',
|
||||
value: 'multipleTargets',
|
||||
},
|
||||
],
|
||||
resetOptions: [
|
||||
{
|
||||
text: 'Short rest',
|
||||
value: 'shortRest',
|
||||
}, {
|
||||
text: 'Long rest',
|
||||
value: 'longRest',
|
||||
}
|
||||
],
|
||||
attackSwitch: false,
|
||||
};
|
||||
data.actionTypeHints = {};
|
||||
data.actionTypes.forEach(type => {
|
||||
data.actionTypeHints[type.value] = type.help;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
computed: {
|
||||
isAttack(){
|
||||
return this.attackSwitch || !!this.model.attackRoll?.calculation
|
||||
}
|
||||
export default {
|
||||
components: {
|
||||
ResourcesForm,
|
||||
IconColorMenu,
|
||||
ResetSelector,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
data(){
|
||||
let data = {
|
||||
actionTypes: [
|
||||
{
|
||||
text: 'Action',
|
||||
value: 'action',
|
||||
}, {
|
||||
text: 'Bonus action',
|
||||
value: 'bonus',
|
||||
}, {
|
||||
text: 'Attack action',
|
||||
value: 'attack',
|
||||
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
|
||||
}, {
|
||||
text: 'Reaction',
|
||||
value: 'reaction',
|
||||
}, {
|
||||
text: 'Free action',
|
||||
value: 'free',
|
||||
help: 'You can take one free action on your turn without using an action or bonus action'
|
||||
}, {
|
||||
text: 'Long action',
|
||||
value: 'long',
|
||||
help: 'Long actions take longer than one turn to complete'
|
||||
}, {
|
||||
text: 'Event',
|
||||
value: 'event',
|
||||
help: 'Events are actions that happen to the character like rests or dawn'
|
||||
},
|
||||
],
|
||||
targetOptions: [
|
||||
{
|
||||
text: 'Self',
|
||||
value: 'self',
|
||||
}, {
|
||||
text: 'Single target',
|
||||
value: 'singleTarget',
|
||||
}, {
|
||||
text: 'Multiple targets',
|
||||
value: 'multipleTargets',
|
||||
},
|
||||
],
|
||||
attackSwitch: false,
|
||||
};
|
||||
data.actionTypeHints = {};
|
||||
data.actionTypes.forEach(type => {
|
||||
data.actionTypeHints[type.value] = type.help;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
computed: {
|
||||
isAttack(){
|
||||
return this.attackSwitch || !!this.model.attackRoll?.calculation
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -250,16 +250,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout wrap">
|
||||
<smart-select
|
||||
<reset-selector
|
||||
v-if="model.attributeType !== 'hitDice'"
|
||||
label="Reset"
|
||||
clearable
|
||||
style="flex-basis: 300px;"
|
||||
hint="When damage should be reset to zero"
|
||||
:items="resetOptions"
|
||||
:value="model.reset"
|
||||
:error-messages="errors.reset"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="change('reset', ...arguments)"
|
||||
/>
|
||||
</div>
|
||||
@@ -273,12 +268,14 @@ import FormSection from '/imports/ui/properties/forms/shared/FormSection.vue';
|
||||
import FormSections from '/imports/ui/properties/forms/shared/FormSections.vue';
|
||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
||||
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormSection,
|
||||
FormSections,
|
||||
ColorPicker,
|
||||
ResetSelector,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
inject: {
|
||||
|
||||
@@ -278,15 +278,10 @@
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<smart-select
|
||||
label="Reset"
|
||||
clearable
|
||||
<reset-selector
|
||||
hint="When number of uses used should be reset to zero"
|
||||
style="flex-basis: 300px;"
|
||||
:items="resetOptions"
|
||||
:value="model.reset"
|
||||
:error-messages="errors.reset"
|
||||
:menu-props="{auto: true, lazy: true}"
|
||||
@change="change('reset', ...arguments)"
|
||||
/>
|
||||
</form-section>
|
||||
@@ -318,6 +313,7 @@ import FormSection, { FormSections } from '/imports/ui/properties/forms/shared/F
|
||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
||||
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
||||
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -325,6 +321,7 @@ export default {
|
||||
FormSection,
|
||||
IconColorMenu,
|
||||
ResourcesForm,
|
||||
ResetSelector,
|
||||
},
|
||||
mixins: [propertyFormMixin],
|
||||
data() {
|
||||
@@ -401,15 +398,6 @@ export default {
|
||||
value: 'multipleTargets',
|
||||
},
|
||||
],
|
||||
resetOptions: [
|
||||
{
|
||||
text: 'Short rest',
|
||||
value: 'shortRest',
|
||||
}, {
|
||||
text: 'Long rest',
|
||||
value: 'longRest',
|
||||
}
|
||||
],
|
||||
attackSwitch: false,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
|
||||
export default function createListOfProperties(filter = {}){
|
||||
filter.removed = {$ne: true};
|
||||
export default function createListOfProperties(filter = {}, getNamesWithValues) {
|
||||
filter.removed = { $ne: true };
|
||||
let propertyList = [];
|
||||
let variableNames = new Set();
|
||||
function addUniquePropertys(property){
|
||||
if (property.variableName && !variableNames.has(property.variableName)){
|
||||
function addUniquePropertys(property) {
|
||||
if (property.variableName && !variableNames.has(property.variableName)) {
|
||||
variableNames.add(property.variableName);
|
||||
propertyList.push({
|
||||
text: property.name || property.variableName,
|
||||
@@ -15,8 +15,9 @@ export default function createListOfProperties(filter = {}){
|
||||
});
|
||||
}
|
||||
}
|
||||
let options = {sort: {order: 1, variableName: 1}}
|
||||
let options = { sort: { order: 1, variableName: 1 } }
|
||||
CreatureProperties.find(filter, options).forEach(addUniquePropertys);
|
||||
LibraryNodes.find(filter, options).forEach(addUniquePropertys);
|
||||
if (getNamesWithValues) return propertyList;
|
||||
return Array.from(variableNames);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
const ActionForm = () => import('/imports/ui/properties/forms/ActionForm.vue');
|
||||
const AdjustmentForm = () => import('/imports/ui/properties/forms/AdjustmentForm.vue');
|
||||
const AttributeForm = () => import('/imports/ui/properties/forms/AttributeForm.vue');
|
||||
const BuffForm = () => import('/imports/ui/properties/forms/BuffForm.vue');
|
||||
const BuffRemoverForm = () => import('/imports/ui/properties/forms/BuffRemoverForm.vue');
|
||||
const BranchForm = () => import('/imports/ui/properties/forms/BranchForm.vue');
|
||||
const ClassForm = () => import('/imports/ui/properties/forms/ClassForm.vue');
|
||||
const ClassLevelForm = () => import('/imports/ui/properties/forms/ClassLevelForm.vue');
|
||||
const ConstantForm = () => import('/imports/ui/properties/forms/ConstantForm.vue');
|
||||
const ContainerForm = () => import('/imports/ui/properties/forms/ContainerForm.vue');
|
||||
const DamageForm = () => import('/imports/ui/properties/forms/DamageForm.vue');
|
||||
const DamageMultiplierForm = () => import('/imports/ui/properties/forms/DamageMultiplierForm.vue');
|
||||
const EffectForm = () => import('/imports/ui/properties/forms/EffectForm.vue');
|
||||
const FeatureForm = () => import('/imports/ui/properties/forms/FeatureForm.vue');
|
||||
const FolderForm = () => import('/imports/ui/properties/forms/FolderForm.vue');
|
||||
const ItemForm = () => import('/imports/ui/properties/forms/ItemForm.vue');
|
||||
const NoteForm = () => import('/imports/ui/properties/forms/NoteForm.vue');
|
||||
const PointBuyForm = () => import('/imports/ui/properties/forms/PointBuyForm.vue');
|
||||
const ProficiencyForm = () => import('/imports/ui/properties/forms/ProficiencyForm.vue');
|
||||
const ReferenceForm = () => import('/imports/ui/properties/forms/ReferenceForm.vue');
|
||||
const RollForm = () => import('/imports/ui/properties/forms/RollForm.vue');
|
||||
const SavingThrowForm = () => import('/imports/ui/properties/forms/SavingThrowForm.vue');
|
||||
const SkillForm = () => import('/imports/ui/properties/forms/SkillForm.vue');
|
||||
const SlotForm = () => import('/imports/ui/properties/forms/SlotForm.vue');
|
||||
const SlotFillerForm = () => import('/imports/ui/properties/forms/SlotFillerForm.vue');
|
||||
const SpellListForm = () => import('/imports/ui/properties/forms/SpellListForm.vue');
|
||||
const SpellForm = () => import('/imports/ui/properties/forms/SpellForm.vue');
|
||||
const ToggleForm = () => import('/imports/ui/properties/forms/ToggleForm.vue');
|
||||
const TriggerForm = () => import('/imports/ui/properties/forms/TriggerForm.vue');
|
||||
import ActionForm from '/imports/ui/properties/forms/ActionForm.vue';
|
||||
import AdjustmentForm from '/imports/ui/properties/forms/AdjustmentForm.vue';
|
||||
import AttributeForm from '/imports/ui/properties/forms/AttributeForm.vue';
|
||||
import BuffForm from '/imports/ui/properties/forms/BuffForm.vue';
|
||||
import BuffRemoverForm from '/imports/ui/properties/forms/BuffRemoverForm.vue';
|
||||
import BranchForm from '/imports/ui/properties/forms/BranchForm.vue';
|
||||
import ClassForm from '/imports/ui/properties/forms/ClassForm.vue';
|
||||
import ClassLevelForm from '/imports/ui/properties/forms/ClassLevelForm.vue';
|
||||
import ConstantForm from '/imports/ui/properties/forms/ConstantForm.vue';
|
||||
import ContainerForm from '/imports/ui/properties/forms/ContainerForm.vue';
|
||||
import DamageForm from '/imports/ui/properties/forms/DamageForm.vue';
|
||||
import DamageMultiplierForm from '/imports/ui/properties/forms/DamageMultiplierForm.vue';
|
||||
import EffectForm from '/imports/ui/properties/forms/EffectForm.vue';
|
||||
import FeatureForm from '/imports/ui/properties/forms/FeatureForm.vue';
|
||||
import FolderForm from '/imports/ui/properties/forms/FolderForm.vue';
|
||||
import ItemForm from '/imports/ui/properties/forms/ItemForm.vue';
|
||||
import NoteForm from '/imports/ui/properties/forms/NoteForm.vue';
|
||||
import PointBuyForm from '/imports/ui/properties/forms/PointBuyForm.vue';
|
||||
import ProficiencyForm from '/imports/ui/properties/forms/ProficiencyForm.vue';
|
||||
import ReferenceForm from '/imports/ui/properties/forms/ReferenceForm.vue';
|
||||
import RollForm from '/imports/ui/properties/forms/RollForm.vue';
|
||||
import SavingThrowForm from '/imports/ui/properties/forms/SavingThrowForm.vue';
|
||||
import SkillForm from '/imports/ui/properties/forms/SkillForm.vue';
|
||||
import SlotForm from '/imports/ui/properties/forms/SlotForm.vue';
|
||||
import SlotFillerForm from '/imports/ui/properties/forms/SlotFillerForm.vue';
|
||||
import SpellListForm from '/imports/ui/properties/forms/SpellListForm.vue';
|
||||
import SpellForm from '/imports/ui/properties/forms/SpellForm.vue';
|
||||
import ToggleForm from '/imports/ui/properties/forms/ToggleForm.vue';
|
||||
import TriggerForm from '/imports/ui/properties/forms/TriggerForm.vue';
|
||||
|
||||
export default {
|
||||
action: ActionForm,
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
const ActionViewer = () => import ('/imports/ui/properties/viewers/ActionViewer.vue');
|
||||
const AdjustmentViewer = () => import ('/imports/ui/properties/viewers/AdjustmentViewer.vue');
|
||||
const AttributeViewer = () => import ('/imports/ui/properties/viewers/AttributeViewer.vue');
|
||||
const BuffViewer = () => import ('/imports/ui/properties/viewers/BuffViewer.vue');
|
||||
const BuffRemoverViewer = () => import ('/imports/ui/properties/viewers/BuffRemoverViewer.vue');
|
||||
const BranchViewer = () => import ('/imports/ui/properties/viewers/BranchViewer.vue');
|
||||
const ContainerViewer = () => import ('/imports/ui/properties/viewers/ContainerViewer.vue');
|
||||
const ClassViewer = () => import ('/imports/ui/properties/viewers/ClassViewer.vue');
|
||||
const ClassLevelViewer = () => import ('/imports/ui/properties/viewers/ClassLevelViewer.vue');
|
||||
const ConstantViewer = () => import ('/imports/ui/properties/viewers/ConstantViewer.vue');
|
||||
const DamageViewer = () => import ('/imports/ui/properties/viewers/DamageViewer.vue');
|
||||
const DamageMultiplierViewer = () => import ('/imports/ui/properties/viewers/DamageMultiplierViewer.vue');
|
||||
const EffectViewer = () => import ('/imports/ui/properties/viewers/EffectViewer.vue');
|
||||
const FeatureViewer = () => import ('/imports/ui/properties/viewers/FeatureViewer.vue');
|
||||
const FolderViewer = () => import ('/imports/ui/properties/viewers/FolderViewer.vue');
|
||||
const ItemViewer = () => import ('/imports/ui/properties/viewers/ItemViewer.vue');
|
||||
const NoteViewer = () => import ('/imports/ui/properties/viewers/NoteViewer.vue');
|
||||
const PointBuyViewer = () => import ('/imports/ui/properties/viewers/PointBuyViewer.vue');
|
||||
const ProficiencyViewer = () => import ('/imports/ui/properties/viewers/ProficiencyViewer.vue');
|
||||
const ReferenceViewer = () => import ('/imports/ui/properties/viewers/ReferenceViewer.vue');
|
||||
const RollViewer = () => import ('/imports/ui/properties/viewers/RollViewer.vue');
|
||||
const SkillViewer = () => import ('/imports/ui/properties/viewers/SkillViewer.vue');
|
||||
const SavingThrowViewer = () => import ('/imports/ui/properties/viewers/SavingThrowViewer.vue');
|
||||
const SlotViewer = () => import ('/imports/ui/properties/viewers/SlotViewer.vue');
|
||||
const SlotFillerViewer = () => import ('/imports/ui/properties/viewers/SlotFillerViewer.vue');
|
||||
const SpellListViewer = () => import ('/imports/ui/properties/viewers/SpellListViewer.vue');
|
||||
const SpellViewer = () => import ('/imports/ui/properties/viewers/SpellViewer.vue');
|
||||
const ToggleViewer = () => import ('/imports/ui/properties/viewers/ToggleViewer.vue');
|
||||
const TriggerViewer = () => import ('/imports/ui/properties/viewers/TriggerViewer.vue');
|
||||
import ActionViewer from '/imports/ui/properties/viewers/ActionViewer.vue';
|
||||
import AdjustmentViewer from '/imports/ui/properties/viewers/AdjustmentViewer.vue';
|
||||
import AttributeViewer from '/imports/ui/properties/viewers/AttributeViewer.vue';
|
||||
import BuffViewer from '/imports/ui/properties/viewers/BuffViewer.vue';
|
||||
import BuffRemoverViewer from '/imports/ui/properties/viewers/BuffRemoverViewer.vue';
|
||||
import BranchViewer from '/imports/ui/properties/viewers/BranchViewer.vue';
|
||||
import ContainerViewer from '/imports/ui/properties/viewers/ContainerViewer.vue';
|
||||
import ClassViewer from '/imports/ui/properties/viewers/ClassViewer.vue';
|
||||
import ClassLevelViewer from '/imports/ui/properties/viewers/ClassLevelViewer.vue';
|
||||
import ConstantViewer from '/imports/ui/properties/viewers/ConstantViewer.vue';
|
||||
import DamageViewer from '/imports/ui/properties/viewers/DamageViewer.vue';
|
||||
import DamageMultiplierViewer from '/imports/ui/properties/viewers/DamageMultiplierViewer.vue';
|
||||
import EffectViewer from '/imports/ui/properties/viewers/EffectViewer.vue';
|
||||
import FeatureViewer from '/imports/ui/properties/viewers/FeatureViewer.vue';
|
||||
import FolderViewer from '/imports/ui/properties/viewers/FolderViewer.vue';
|
||||
import ItemViewer from '/imports/ui/properties/viewers/ItemViewer.vue';
|
||||
import NoteViewer from '/imports/ui/properties/viewers/NoteViewer.vue';
|
||||
import PointBuyViewer from '/imports/ui/properties/viewers/PointBuyViewer.vue';
|
||||
import ProficiencyViewer from '/imports/ui/properties/viewers/ProficiencyViewer.vue';
|
||||
import ReferenceViewer from '/imports/ui/properties/viewers/ReferenceViewer.vue';
|
||||
import RollViewer from '/imports/ui/properties/viewers/RollViewer.vue';
|
||||
import SkillViewer from '/imports/ui/properties/viewers/SkillViewer.vue';
|
||||
import SavingThrowViewer from '/imports/ui/properties/viewers/SavingThrowViewer.vue';
|
||||
import SlotViewer from '/imports/ui/properties/viewers/SlotViewer.vue';
|
||||
import SlotFillerViewer from '/imports/ui/properties/viewers/SlotFillerViewer.vue';
|
||||
import SpellListViewer from '/imports/ui/properties/viewers/SpellListViewer.vue';
|
||||
import SpellViewer from '/imports/ui/properties/viewers/SpellViewer.vue';
|
||||
import ToggleViewer from '/imports/ui/properties/viewers/ToggleViewer.vue';
|
||||
import TriggerViewer from '/imports/ui/properties/viewers/TriggerViewer.vue';
|
||||
|
||||
export default {
|
||||
action: ActionViewer,
|
||||
|
||||
@@ -121,8 +121,7 @@
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"vuetify/no-deprecated-classes": "error"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user