Compare commits
16 Commits
2.0-beta.4
...
2.0-beta.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c55d572134 | ||
|
|
0a2b60990e | ||
|
|
a437ff5aef | ||
|
|
3d31d62860 | ||
|
|
8377231254 | ||
|
|
1ec29365cb | ||
|
|
60b21c1901 | ||
|
|
03f87b0afa | ||
|
|
48291d2c8f | ||
|
|
1cedf55fbf | ||
|
|
bed4d4b162 | ||
|
|
a1d992ec8d | ||
|
|
008ef62517 | ||
|
|
c436309ba8 | ||
|
|
0bfdb73b47 | ||
|
|
a462cc5ca2 |
@@ -18,6 +18,11 @@ let CreatureSettingsSchema = new SimpleSchema({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
//hide rest buttons
|
||||||
|
hideRestButtons: {
|
||||||
|
type: Boolean,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
// Swap around the modifier and stat
|
// Swap around the modifier and stat
|
||||||
swapStatAndModifier: {
|
swapStatAndModifier: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const restCreature = new ValidatedMethod({
|
|||||||
applyTriggers(afterTriggers, null, actionContext);
|
applyTriggers(afterTriggers, null, actionContext);
|
||||||
|
|
||||||
// Insert log
|
// Insert log
|
||||||
actionContext.writeLog();
|
actionContext.writeLog();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -57,88 +57,124 @@ function doRestWork(restType, actionContext) {
|
|||||||
const creatureId = actionContext.creature._id;
|
const creatureId = actionContext.creature._id;
|
||||||
// Long rests reset short rest properties as well
|
// Long rests reset short rest properties as well
|
||||||
let resetFilter;
|
let resetFilter;
|
||||||
if (restType === 'shortRest'){
|
if (restType === 'shortRest') {
|
||||||
resetFilter = 'shortRest'
|
resetFilter = 'shortRest'
|
||||||
} else {
|
} 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
|
// Only apply to active properties
|
||||||
let filter = {
|
const filter = {
|
||||||
'ancestors.id': creatureId,
|
'ancestors.id': creatureId,
|
||||||
reset: resetFilter,
|
reset: resetFilter,
|
||||||
removed: { $ne: true },
|
removed: { $ne: true },
|
||||||
inactive: { $ne: true },
|
inactive: { $ne: true },
|
||||||
};
|
};
|
||||||
// update all attribute's damage
|
// update all attribute's damage
|
||||||
filter.type = 'attribute';
|
const attributeFilter = {
|
||||||
CreatureProperties.update(filter, {
|
...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: {
|
$set: {
|
||||||
damage: 0,
|
damage: 0,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
selector: {type: 'attribute'},
|
selector: { type: 'attribute' },
|
||||||
multi: true,
|
multi: true,
|
||||||
});
|
});
|
||||||
// Update all action-like properties' usesUsed
|
// Update all action-like properties' usesUsed
|
||||||
filter.type = {$in: [
|
const actionFilter = {
|
||||||
'action',
|
...filter,
|
||||||
'attack',
|
type: {
|
||||||
'spell'
|
$in: ['action', 'spell']
|
||||||
]};
|
},
|
||||||
CreatureProperties.update(filter, {
|
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: {
|
$set: {
|
||||||
usesUsed: 0,
|
usesUsed: 0,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
selector: {type: 'action'},
|
selector: { type: 'action' },
|
||||||
multi: true,
|
multi: true,
|
||||||
});
|
});
|
||||||
// Reset half hit dice on a long rest, starting with the highest dice
|
}
|
||||||
if (restType === 'longRest'){
|
|
||||||
let hitDice = CreatureProperties.find({
|
function resetHitDice(creatureId, actionContext) {
|
||||||
'ancestors.id': creatureId,
|
let hitDice = CreatureProperties.find({
|
||||||
type: 'attribute',
|
'ancestors.id': creatureId,
|
||||||
attributeType: 'hitDice',
|
type: 'attribute',
|
||||||
removed: {$ne: true},
|
attributeType: 'hitDice',
|
||||||
inactive: {$ne: true},
|
removed: { $ne: true },
|
||||||
}, {
|
inactive: { $ne: true },
|
||||||
fields: {
|
}, {
|
||||||
hitDiceSize: 1,
|
fields: {
|
||||||
damage: 1,
|
name: 1,
|
||||||
total: 1,
|
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
|
selector: { type: 'attribute' },
|
||||||
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;
|
|
||||||
CreatureProperties.update(hd._id, {
|
|
||||||
$set: {
|
|
||||||
damage: resultingDamage,
|
|
||||||
dirty: true,
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
selector: {type: 'attribute'},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default restCreature;
|
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 { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers.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) {
|
export default function applyAction(node, actionContext) {
|
||||||
applyNodeTriggers(node, 'before', actionContext);
|
applyNodeTriggers(node, 'before', actionContext);
|
||||||
@@ -16,7 +17,7 @@ export default function applyAction(node, actionContext) {
|
|||||||
|
|
||||||
// Log the name and summary
|
// Log the name and summary
|
||||||
let content = { name: prop.name };
|
let content = { name: prop.name };
|
||||||
if (prop.summary?.text){
|
if (prop.summary?.text) {
|
||||||
recalculateInlineCalculations(prop.summary, actionContext);
|
recalculateInlineCalculations(prop.summary, actionContext);
|
||||||
content.value = prop.summary.value;
|
content.value = prop.summary.value;
|
||||||
}
|
}
|
||||||
@@ -29,24 +30,27 @@ export default function applyAction(node, actionContext) {
|
|||||||
const attack = prop.attackRoll || prop.attackRollBonus;
|
const attack = prop.attackRoll || prop.attackRollBonus;
|
||||||
|
|
||||||
// Attack if there is an attack roll
|
// Attack if there is an attack roll
|
||||||
if (attack && attack.calculation){
|
if (attack && attack.calculation) {
|
||||||
if (targets.length){
|
if (targets.length) {
|
||||||
targets.forEach(target => {
|
targets.forEach(target => {
|
||||||
applyAttackToTarget({attack, target, actionContext});
|
applyAttackToTarget({ attack, target, actionContext });
|
||||||
// Apply the children, but only to the current target
|
// Apply the children, but only to the current target
|
||||||
actionContext.targets = [target];
|
actionContext.targets = [target];
|
||||||
applyChildren(node, actionContext);
|
applyChildren(node, actionContext);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
applyAttackWithoutTarget({attack, actionContext});
|
applyAttackWithoutTarget({ attack, actionContext });
|
||||||
applyChildren(node, actionContext);
|
applyChildren(node, actionContext);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
applyChildren(node, actionContext);
|
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['$attackHit'];
|
||||||
delete actionContext.scope['$attackMiss'];
|
delete actionContext.scope['$attackMiss'];
|
||||||
delete actionContext.scope['$criticalHit'];
|
delete actionContext.scope['$criticalHit'];
|
||||||
@@ -62,16 +66,16 @@ function applyAttackWithoutTarget({attack, actionContext}){
|
|||||||
criticalMiss,
|
criticalMiss,
|
||||||
} = rollAttack(attack, scope);
|
} = rollAttack(attack, scope);
|
||||||
let name = criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit';
|
let name = criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit';
|
||||||
if (scope['$attackAdvantage'] === 1){
|
if (scope['$attackAdvantage'] === 1) {
|
||||||
name += ' (Advantage)';
|
name += ' (Advantage)';
|
||||||
} else if(scope['$attackAdvantage'] === -1){
|
} else if (scope['$attackAdvantage'] === -1) {
|
||||||
name += ' (Disadvantage)';
|
name += ' (Disadvantage)';
|
||||||
}
|
}
|
||||||
if (!criticalMiss){
|
if (!criticalMiss) {
|
||||||
scope['$attackHit'] = {value: true}
|
scope['$attackHit'] = { value: true }
|
||||||
}
|
}
|
||||||
if (!criticalHit){
|
if (!criticalHit) {
|
||||||
scope['$attackMiss'] = {value: true};
|
scope['$attackMiss'] = { value: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
actionContext.addLog({
|
actionContext.addLog({
|
||||||
@@ -81,7 +85,7 @@ function applyAttackWithoutTarget({attack, actionContext}){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyAttackToTarget({attack, target, actionContext}){
|
function applyAttackToTarget({ attack, target, actionContext }) {
|
||||||
const scope = actionContext.scope;
|
const scope = actionContext.scope;
|
||||||
delete scope['$attackHit'];
|
delete scope['$attackHit'];
|
||||||
delete scope['$attackMiss'];
|
delete scope['$attackMiss'];
|
||||||
@@ -99,15 +103,15 @@ function applyAttackToTarget({attack, target, actionContext}){
|
|||||||
criticalMiss,
|
criticalMiss,
|
||||||
} = rollAttack(attack, scope);
|
} = rollAttack(attack, scope);
|
||||||
|
|
||||||
if (target.variables.armor){
|
if (target.variables.armor) {
|
||||||
const armor = target.variables.armor.value;
|
const armor = target.variables.armor.value;
|
||||||
|
|
||||||
let name = criticalHit ? 'Critical Hit!' :
|
let name = criticalHit ? 'Critical Hit!' :
|
||||||
criticalMiss ? 'Critical Miss!' :
|
criticalMiss ? 'Critical Miss!' :
|
||||||
result > armor ? 'Hit!' : 'Miss!';
|
result > armor ? 'Hit!' : 'Miss!';
|
||||||
if (scope['$attackAdvantage'] === 1){
|
if (scope['$attackAdvantage'] === 1) {
|
||||||
name += ' (Advantage)';
|
name += ' (Advantage)';
|
||||||
} else if(scope['$attackAdvantage'] === -1){
|
} else if (scope['$attackAdvantage'] === -1) {
|
||||||
name += ' (Disadvantage)';
|
name += ' (Disadvantage)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,15 +120,15 @@ function applyAttackToTarget({attack, target, actionContext}){
|
|||||||
value: `${resultPrefix}\n**${result}**`,
|
value: `${resultPrefix}\n**${result}**`,
|
||||||
inline: true,
|
inline: true,
|
||||||
});
|
});
|
||||||
if (criticalMiss || result < armor){
|
if (criticalMiss || result < armor) {
|
||||||
scope['$attackMiss'] = {value: true};
|
scope['$attackMiss'] = { value: true };
|
||||||
} else {
|
} else {
|
||||||
scope['$attackHit'] = {value: true};
|
scope['$attackHit'] = { value: true };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
actionContext.addLog({
|
actionContext.addLog({
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
value:'Target has no `armor`',
|
value: 'Target has no `armor`',
|
||||||
});
|
});
|
||||||
actionContext.addLog({
|
actionContext.addLog({
|
||||||
name: criticalHit ? 'Critical Hit!' : criticalMiss ? 'Critical Miss!' : 'To Hit',
|
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);
|
const rollModifierText = numberToSignedString(attack.value, true);
|
||||||
let value, resultPrefix;
|
let value, resultPrefix;
|
||||||
if (scope['$attackAdvantage'] === 1){
|
if (scope['$attackAdvantage'] === 1) {
|
||||||
const [a, b] = rollDice(2, 20);
|
const [a, b] = rollDice(2, 20);
|
||||||
if (a >= b) {
|
if (a >= b) {
|
||||||
value = a;
|
value = a;
|
||||||
@@ -146,7 +150,7 @@ function rollAttack(attack, scope){
|
|||||||
value = b;
|
value = b;
|
||||||
resultPrefix = `1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
resultPrefix = `1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
||||||
}
|
}
|
||||||
} else if (scope['$attackAdvantage'] === -1){
|
} else if (scope['$attackAdvantage'] === -1) {
|
||||||
const [a, b] = rollDice(2, 20);
|
const [a, b] = rollDice(2, 20);
|
||||||
if (a <= b) {
|
if (a <= b) {
|
||||||
value = a;
|
value = a;
|
||||||
@@ -159,25 +163,25 @@ function rollAttack(attack, scope){
|
|||||||
value = rollDice(1, 20)[0];
|
value = rollDice(1, 20)[0];
|
||||||
resultPrefix = `1d20 [${value}] ${rollModifierText}`
|
resultPrefix = `1d20 [${value}] ${rollModifierText}`
|
||||||
}
|
}
|
||||||
scope['$attackRoll'] = {value};
|
scope['$attackRoll'] = { value };
|
||||||
const result = value + attack.value;
|
const result = value + attack.value;
|
||||||
const {criticalHit, criticalMiss} = applyCrits(value, scope);
|
const { criticalHit, criticalMiss } = applyCrits(value, scope);
|
||||||
return {resultPrefix, result, value, criticalHit, criticalMiss};
|
return { resultPrefix, result, value, criticalHit, criticalMiss };
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCrits(value, scope){
|
function applyCrits(value, scope) {
|
||||||
let criticalHitTarget = scope.criticalHitTarget?.value || 20;
|
let criticalHitTarget = scope.criticalHitTarget?.value || 20;
|
||||||
let criticalHit = value >= criticalHitTarget;
|
let criticalHit = value >= criticalHitTarget;
|
||||||
let criticalMiss;
|
let criticalMiss;
|
||||||
if (criticalHit){
|
if (criticalHit) {
|
||||||
scope['$criticalHit'] = {value: true};
|
scope['$criticalHit'] = { value: true };
|
||||||
} else {
|
} else {
|
||||||
criticalMiss = value === 1;
|
criticalMiss = value === 1;
|
||||||
if (criticalMiss){
|
if (criticalMiss) {
|
||||||
scope['$criticalMiss'] = {value: true};
|
scope['$criticalMiss'] = { value: true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {criticalHit, criticalMiss};
|
return { criticalHit, criticalMiss };
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyChildren(node, actionContext) {
|
function applyChildren(node, actionContext) {
|
||||||
@@ -185,9 +189,9 @@ function applyChildren(node, actionContext) {
|
|||||||
node.children.forEach(child => applyProperty(child, actionContext));
|
node.children.forEach(child => applyProperty(child, actionContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
function spendResources(prop, actionContext){
|
function spendResources(prop, actionContext) {
|
||||||
// Check Uses
|
// Check Uses
|
||||||
if (prop.usesLeft <= 0){
|
if (prop.usesLeft <= 0) {
|
||||||
if (!prop.silent) actionContext.addLog({
|
if (!prop.silent) actionContext.addLog({
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
value: `${prop.name || 'action'} does not have enough uses left`,
|
value: `${prop.name || 'action'} does not have enough uses left`,
|
||||||
@@ -195,7 +199,7 @@ function spendResources(prop, actionContext){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Resources
|
// Resources
|
||||||
if (prop.insufficientResources){
|
if (prop.insufficientResources) {
|
||||||
if (!prop.silent) actionContext.addLog({
|
if (!prop.silent) actionContext.addLog({
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
value: 'This creature doesn\'t have sufficient resources to perform this action',
|
value: 'This creature doesn\'t have sufficient resources to perform this action',
|
||||||
@@ -209,14 +213,14 @@ function spendResources(prop, actionContext){
|
|||||||
try {
|
try {
|
||||||
prop.resources.itemsConsumed.forEach(itemConsumed => {
|
prop.resources.itemsConsumed.forEach(itemConsumed => {
|
||||||
recalculateCalculation(itemConsumed.quantity, actionContext);
|
recalculateCalculation(itemConsumed.quantity, actionContext);
|
||||||
if (!itemConsumed.itemId){
|
if (!itemConsumed.itemId) {
|
||||||
throw 'No ammo was selected for this prop';
|
throw 'No ammo was selected for this prop';
|
||||||
}
|
}
|
||||||
let item = CreatureProperties.findOne(itemConsumed.itemId);
|
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';
|
throw 'The prop\'s ammo was not found on the creature';
|
||||||
}
|
}
|
||||||
if (!item.equipped){
|
if (!item.equipped) {
|
||||||
throw 'The selected ammo is not equipped';
|
throw 'The selected ammo is not equipped';
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -229,16 +233,16 @@ function spendResources(prop, actionContext){
|
|||||||
value: itemConsumed.quantity.value,
|
value: itemConsumed.quantity.value,
|
||||||
});
|
});
|
||||||
let logName = item.name;
|
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;
|
logName = item.plural || logName;
|
||||||
}
|
}
|
||||||
if (itemConsumed.quantity.value > 0){
|
if (itemConsumed.quantity.value > 0) {
|
||||||
spendLog.push(logName + ': ' + itemConsumed.quantity.value);
|
spendLog.push(logName + ': ' + itemConsumed.quantity.value);
|
||||||
} else if (itemConsumed.quantity.value < 0){
|
} else if (itemConsumed.quantity.value < 0) {
|
||||||
gainLog.push(logName + ': ' + -itemConsumed.quantity.value);
|
gainLog.push(logName + ': ' + -itemConsumed.quantity.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e){
|
} catch (e) {
|
||||||
actionContext.addLog({
|
actionContext.addLog({
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
value: e,
|
value: e,
|
||||||
@@ -251,9 +255,9 @@ function spendResources(prop, actionContext){
|
|||||||
itemQuantityAdjustments.forEach(adjustQuantityWork);
|
itemQuantityAdjustments.forEach(adjustQuantityWork);
|
||||||
|
|
||||||
// Use uses
|
// Use uses
|
||||||
if (prop.usesLeft){
|
if (prop.usesLeft) {
|
||||||
CreatureProperties.update(prop._id, {
|
CreatureProperties.update(prop._id, {
|
||||||
$inc: {usesUsed: 1}
|
$inc: { usesUsed: 1 }
|
||||||
}, {
|
}, {
|
||||||
selector: prop
|
selector: prop
|
||||||
});
|
});
|
||||||
@@ -270,7 +274,7 @@ function spendResources(prop, actionContext){
|
|||||||
|
|
||||||
if (!attConsumed.quantity?.value) return;
|
if (!attConsumed.quantity?.value) return;
|
||||||
let stat = actionContext.scope[attConsumed.variableName];
|
let stat = actionContext.scope[attConsumed.variableName];
|
||||||
if (!stat){
|
if (!stat) {
|
||||||
spendLog.push(stat.name + ': ' + ' not found');
|
spendLog.push(stat.name + ': ' + ' not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -280,9 +284,9 @@ function spendResources(prop, actionContext){
|
|||||||
value: attConsumed.quantity.value,
|
value: attConsumed.quantity.value,
|
||||||
actionContext,
|
actionContext,
|
||||||
});
|
});
|
||||||
if (attConsumed.quantity.value > 0){
|
if (attConsumed.quantity.value > 0) {
|
||||||
spendLog.push(stat.name + ': ' + attConsumed.quantity.value);
|
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);
|
gainLog.push(stat.name + ': ' + -attConsumed.quantity.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import skill from './computeByType/computeSkill.js';
|
|||||||
import pointBuy from './computeByType/computePointBuy.js';
|
import pointBuy from './computeByType/computePointBuy.js';
|
||||||
import propertySlot from './computeByType/computeSlot.js';
|
import propertySlot from './computeByType/computeSlot.js';
|
||||||
import container from './computeByType/computeContainer.js';
|
import container from './computeByType/computeContainer.js';
|
||||||
|
import spellList from './computeByType/computeSpellList.js';
|
||||||
import _calculation from './computeByType/computeCalculation.js';
|
import _calculation from './computeByType/computeCalculation.js';
|
||||||
|
|
||||||
export default Object.freeze({
|
export default Object.freeze({
|
||||||
@@ -17,4 +18,5 @@ export default Object.freeze({
|
|||||||
pointBuy,
|
pointBuy,
|
||||||
propertySlot,
|
propertySlot,
|
||||||
spell: action,
|
spell: action,
|
||||||
|
spellList,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export default function computeSpelllist(computation, node) {
|
||||||
|
const prop = node.data;
|
||||||
|
|
||||||
|
const ability = computation.scope[prop.ability];
|
||||||
|
prop.abilityMod = ability?.modifier || 0;
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
|
|
||||||
export default function aggregateEffect({node, linkedNode, link}){
|
export default function aggregateEffect({ node, linkedNode, link }) {
|
||||||
if (link.data !== 'effect') return;
|
if (link.data !== 'effect') return;
|
||||||
// store the effect aggregator, its presence indicates that the variable is
|
// store the effect aggregator, its presence indicates that the variable is
|
||||||
// targeted by effects
|
// targeted by effects
|
||||||
@@ -38,6 +38,7 @@ export default function aggregateEffect({node, linkedNode, link}){
|
|||||||
operation: linkedNode.data.operation,
|
operation: linkedNode.data.operation,
|
||||||
amount: effectAmount,
|
amount: effectAmount,
|
||||||
type: linkedNode.data.type,
|
type: linkedNode.data.type,
|
||||||
|
text: linkedNode.data.text,
|
||||||
// ancestors: linkedNode.data.ancestors,
|
// ancestors: linkedNode.data.ancestors,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,14 +46,13 @@ export default function aggregateEffect({node, linkedNode, link}){
|
|||||||
const aggregator = node.data.effectAggregator;
|
const aggregator = node.data.effectAggregator;
|
||||||
// Get the result of the effect
|
// Get the result of the effect
|
||||||
const result = linkedNode.data.amount?.value;
|
const result = linkedNode.data.amount?.value;
|
||||||
// Skip aggregating if the result is not resolved completely
|
|
||||||
if (typeof result === 'string' || result === undefined) return;
|
|
||||||
// Aggregate the effect based on its operation
|
// Aggregate the effect based on its operation
|
||||||
switch(linkedNode.data.operation){
|
switch (linkedNode.data.operation) {
|
||||||
case 'base':
|
case 'base':
|
||||||
// Take the largest base value
|
// Take the largest base value
|
||||||
if (Number.isFinite(result)){
|
if (Number.isFinite(result)) {
|
||||||
if(Number.isFinite(aggregator.base)){
|
if (Number.isFinite(aggregator.base)) {
|
||||||
aggregator.base = Math.max(aggregator.base, result);
|
aggregator.base = Math.max(aggregator.base, result);
|
||||||
} else {
|
} else {
|
||||||
aggregator.base = result;
|
aggregator.base = result;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import SimpleSchema from 'simpl-schema';
|
|||||||
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
import createPropertySchema from '/imports/api/properties/subSchemas/createPropertySchema.js';
|
||||||
import { storedIconsSchema } from '/imports/api/icons/Icons.js';
|
import { storedIconsSchema } from '/imports/api/icons/Icons.js';
|
||||||
import STORAGE_LIMITS from '/imports/constants/STORAGE_LIMITS.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
|
* Actions are things a character can do
|
||||||
@@ -24,9 +25,17 @@ let ActionSchema = createPropertySchema({
|
|||||||
// long actions take longer than 1 round to cast
|
// long actions take longer than 1 round to cast
|
||||||
actionType: {
|
actionType: {
|
||||||
type: String,
|
type: String,
|
||||||
allowedValues: ['action', 'bonus', 'attack', 'reaction', 'free', 'long'],
|
allowedValues: ['action', 'bonus', 'attack', 'reaction', 'free', 'long', 'event'],
|
||||||
defaultValue: 'action',
|
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
|
// Who is the action directed at
|
||||||
target: {
|
target: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -56,8 +65,10 @@ let ActionSchema = createPropertySchema({
|
|||||||
// How this action's uses are reset automatically
|
// How this action's uses are reset automatically
|
||||||
reset: {
|
reset: {
|
||||||
type: String,
|
type: String,
|
||||||
allowedValues: ['longRest', 'shortRest'],
|
|
||||||
optional: true,
|
optional: true,
|
||||||
|
regEx: VARIABLE_NAME_REGEX,
|
||||||
|
min: 2,
|
||||||
|
max: STORAGE_LIMITS.variableName,
|
||||||
},
|
},
|
||||||
// Resources
|
// Resources
|
||||||
resources: {
|
resources: {
|
||||||
@@ -74,7 +85,7 @@ let ActionSchema = createPropertySchema({
|
|||||||
'resources.itemsConsumed.$._id': {
|
'resources.itemsConsumed.$._id': {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
autoValue(){
|
autoValue() {
|
||||||
if (!this.isSet) return Random.id();
|
if (!this.isSet) return Random.id();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -101,7 +112,7 @@ let ActionSchema = createPropertySchema({
|
|||||||
'resources.attributesConsumed.$._id': {
|
'resources.attributesConsumed.$._id': {
|
||||||
type: String,
|
type: String,
|
||||||
regEx: SimpleSchema.RegEx.Id,
|
regEx: SimpleSchema.RegEx.Id,
|
||||||
autoValue(){
|
autoValue() {
|
||||||
if (!this.isSet) return Random.id();
|
if (!this.isSet) return Random.id();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -218,4 +229,4 @@ const ComputedActionSchema = new SimpleSchema()
|
|||||||
.extend(ActionSchema)
|
.extend(ActionSchema)
|
||||||
.extend(ComputedOnlyActionSchema);
|
.extend(ComputedOnlyActionSchema);
|
||||||
|
|
||||||
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema};
|
export { ActionSchema, ComputedOnlyActionSchema, ComputedActionSchema };
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ let AttributeSchema = createPropertySchema({
|
|||||||
'stat', // Speed, Armor Class
|
'stat', // Speed, Armor Class
|
||||||
'modifier', // Proficiency Bonus, displayed as +x
|
'modifier', // Proficiency Bonus, displayed as +x
|
||||||
'hitDice', // d12 hit dice
|
'hitDice', // d12 hit dice
|
||||||
'healthBar', // Hitpoints, Temporary Hitpoints, can take damage
|
'healthBar', // Hitpoints, Temporary Hitpoints
|
||||||
'bar', // Displayed as a health bar, can't take damage
|
|
||||||
'resource', // Rages, sorcery points
|
'resource', // Rages, sorcery points
|
||||||
'spellSlot', // Level 1, 2, 3... spell slots
|
'spellSlot', // Level 1, 2, 3... spell slots
|
||||||
'utility', // Aren't displayed, Jump height, Carry capacity
|
'utility', // Aren't displayed, Jump height, Carry capacity
|
||||||
@@ -129,7 +128,9 @@ let AttributeSchema = createPropertySchema({
|
|||||||
reset: {
|
reset: {
|
||||||
type: String,
|
type: String,
|
||||||
optional: true,
|
optional: true,
|
||||||
allowedValues: ['shortRest', 'longRest'],
|
regEx: VARIABLE_NAME_REGEX,
|
||||||
|
min: 2,
|
||||||
|
max: STORAGE_LIMITS.variableName,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ let FolderSchema = new createPropertySchema({
|
|||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
max: STORAGE_LIMITS.name,
|
max: STORAGE_LIMITS.name,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
groupStats: {
|
||||||
|
type: Boolean,
|
||||||
|
optional: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ let SpellListSchema = createPropertySchema({
|
|||||||
type: 'fieldToCompute',
|
type: 'fieldToCompute',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
// The variable name of the ability this spell relies on
|
||||||
|
ability: {
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
max: STORAGE_LIMITS.variableName,
|
||||||
|
},
|
||||||
// Calculation of The attack roll bonus used by spell attacks in this list
|
// Calculation of The attack roll bonus used by spell attacks in this list
|
||||||
attackRollBonus: {
|
attackRollBonus: {
|
||||||
type: 'fieldToCompute',
|
type: 'fieldToCompute',
|
||||||
@@ -38,6 +44,12 @@ const ComputedOnlySpellListSchema = createPropertySchema({
|
|||||||
type: 'computedOnlyField',
|
type: 'computedOnlyField',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
// Computed value determined by the ability
|
||||||
|
abilityMod: {
|
||||||
|
type: SimpleSchema.Integer,
|
||||||
|
optional: true,
|
||||||
|
removeBeforeCompute: true,
|
||||||
|
},
|
||||||
attackRollBonus: {
|
attackRollBonus: {
|
||||||
type: 'computedOnlyField',
|
type: 'computedOnlyField',
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
import { Migrations } from 'meteor/percolate:migrations';
|
import { Migrations } from 'meteor/percolate:migrations';
|
||||||
import SCHEMA_VERSION from '/imports/constants/SCHEMA_VERSION.js';
|
import SCHEMA_VERSION from '/imports/constants/SCHEMA_VERSION.js';
|
||||||
|
|
||||||
if (Meteor.isServer){
|
if (Meteor.isServer) {
|
||||||
Meteor.startup(()=>{
|
Meteor.startup(() => {
|
||||||
const dbVersion = Migrations.getVersion();
|
const dbVersion = Migrations.getVersion();
|
||||||
|
// If there are no users, this is a new DB, set the version to latest
|
||||||
|
const aUser = Meteor.users.findOne({});
|
||||||
|
const latestVersion = Migrations._list[Migrations._list.length - 1].version
|
||||||
|
if (!aUser && dbVersion !== latestVersion) {
|
||||||
|
Migrations._collection.update({ _id: 'control' }, { version: latestVersion });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Otherwise put the app in maintenance mode if it's not the right version
|
||||||
if (
|
if (
|
||||||
!Meteor.settings.public.maintenanceMode &&
|
!Meteor.settings.public.maintenanceMode &&
|
||||||
dbVersion !== undefined &&
|
dbVersion !== undefined &&
|
||||||
SCHEMA_VERSION !== dbVersion
|
SCHEMA_VERSION !== dbVersion
|
||||||
){
|
) {
|
||||||
Meteor.settings.public.maintenanceMode = {
|
Meteor.settings.public.maintenanceMode = {
|
||||||
reason: 'App data needs to be migrated to the latest version'
|
reason: 'App data needs to be migrated to the latest version'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
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"
|
:input-value="model.settings.hideUnusedStats"
|
||||||
@change="value => $emit('change', {path: ['settings','hideUnusedStats'], value: !!value})"
|
@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
|
<v-switch
|
||||||
label="Show spells tab"
|
label="Show spells tab"
|
||||||
:input-value="!model.settings.hideSpellsTab"
|
:input-value="!model.settings.hideSpellsTab"
|
||||||
|
|||||||
@@ -1,21 +1,53 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<div class="stats-tab ma-2">
|
<div class="stats-tab ma-2">
|
||||||
<health-bar-card-container :creature-id="creatureId" />
|
<div
|
||||||
|
v-if="healthBars.length"
|
||||||
|
class="px-2 pt-2"
|
||||||
|
>
|
||||||
|
<v-card class="pa-2">
|
||||||
|
<health-bar
|
||||||
|
v-for="healthBar in healthBars"
|
||||||
|
:key="healthBar._id"
|
||||||
|
:model="healthBar"
|
||||||
|
@change="({ type, value }) => incrementChange(healthBar._id, { type, value: -value })"
|
||||||
|
@click="clickProperty({_id: healthBar._id})"
|
||||||
|
/>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<column-layout>
|
<column-layout>
|
||||||
<div class="character-buttons">
|
<folder-group-card
|
||||||
|
v-for="folder in folders"
|
||||||
|
:key="folder._id"
|
||||||
|
:model="folder"
|
||||||
|
@click-property="clickProperty"
|
||||||
|
@sub-click="_id => clickTreeProperty({_id})"
|
||||||
|
@remove="softRemove"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-if="!creature.settings.hideRestButtons || (events && events.length)"
|
||||||
|
class="character-buttons"
|
||||||
|
>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text class="layout column align-center">
|
<v-card-text class="layout column align-center">
|
||||||
<rest-button
|
<rest-button
|
||||||
|
v-if="!creature.settings.hideRestButtons"
|
||||||
:creature-id="creatureId"
|
:creature-id="creatureId"
|
||||||
type="shortRest"
|
type="shortRest"
|
||||||
class="ma-1"
|
class="ma-1"
|
||||||
/>
|
/>
|
||||||
<rest-button
|
<rest-button
|
||||||
|
v-if="!creature.settings.hideRestButtons"
|
||||||
:creature-id="creatureId"
|
:creature-id="creatureId"
|
||||||
type="longRest"
|
type="longRest"
|
||||||
class="ma-1"
|
class="ma-1"
|
||||||
/>
|
/>
|
||||||
|
<event-button
|
||||||
|
v-for="event in events"
|
||||||
|
:key="event._id"
|
||||||
|
:model="event"
|
||||||
|
class="ma-1"
|
||||||
|
/>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,26 +65,14 @@
|
|||||||
<v-card>
|
<v-card>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-subheader>Buffs and conditions</v-subheader>
|
<v-subheader>Buffs and conditions</v-subheader>
|
||||||
<v-list-item
|
<buff-list-item
|
||||||
v-for="buff in appliedBuffs"
|
v-for="buff in appliedBuffs"
|
||||||
:key="buff._id"
|
:key="buff._id"
|
||||||
:data-id="buff._id"
|
:data-id="buff._id"
|
||||||
|
:model="buff"
|
||||||
@click="clickProperty({_id: buff._id})"
|
@click="clickProperty({_id: buff._id})"
|
||||||
>
|
@remove="softRemove(buff._id)"
|
||||||
<v-list-item-content>
|
/>
|
||||||
<v-list-item-title>
|
|
||||||
{{ buff.name }}
|
|
||||||
</v-list-item-title>
|
|
||||||
</v-list-item-content>
|
|
||||||
<v-list-item-action v-if="!buff.hideRemoveButton">
|
|
||||||
<v-btn
|
|
||||||
icon
|
|
||||||
@click.stop="softRemove(buff._id)"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-delete</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</v-list-item-action>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -182,7 +202,6 @@
|
|||||||
:model="spellSlot"
|
:model="spellSlot"
|
||||||
:data-id="spellSlot._id"
|
:data-id="spellSlot._id"
|
||||||
@click="clickProperty({_id: spellSlot._id})"
|
@click="clickProperty({_id: spellSlot._id})"
|
||||||
@cast="castSpellWithSlot(spellSlot._id)"
|
|
||||||
/>
|
/>
|
||||||
</v-list>
|
</v-list>
|
||||||
<div
|
<div
|
||||||
@@ -338,11 +357,11 @@
|
|||||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
import softRemoveProperty from '/imports/api/creature/creatureProperties/methods/softRemoveProperty.js';
|
import softRemoveProperty from '/imports/api/creature/creatureProperties/methods/softRemoveProperty.js';
|
||||||
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||||
|
import HealthBar from '/imports/ui/properties/components/attributes/HealthBar.vue';
|
||||||
import AttributeCard from '/imports/ui/properties/components/attributes/AttributeCard.vue';
|
import AttributeCard from '/imports/ui/properties/components/attributes/AttributeCard.vue';
|
||||||
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
||||||
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||||
import DamageMultiplierCard from '/imports/ui/properties/components/damageMultipliers/DamageMultiplierCard.vue';
|
import DamageMultiplierCard from '/imports/ui/properties/components/damageMultipliers/DamageMultiplierCard.vue';
|
||||||
import HealthBarCardContainer from '/imports/ui/properties/components/attributes/HealthBarCardContainer.vue';
|
|
||||||
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
||||||
import SkillListTile from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
import SkillListTile from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
||||||
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
import ResourceCard from '/imports/ui/properties/components/attributes/ResourceCard.vue';
|
||||||
@@ -351,10 +370,14 @@ import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue
|
|||||||
import RestButton from '/imports/ui/creature/RestButton.vue';
|
import RestButton from '/imports/ui/creature/RestButton.vue';
|
||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
import ToggleCard from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||||
|
import BuffListItem from '/imports/ui/properties/components/buffs/BuffListItem.vue';
|
||||||
import doCastSpell from '/imports/api/engine/actions/doCastSpell.js';
|
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 { snackbar } from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||||
|
import FolderGroupCard from '/imports/ui/properties/components/folders/FolderGroupCard.vue';
|
||||||
|
import { uniqBy } from 'lodash';
|
||||||
|
|
||||||
const getProperties = function (creature, filter, options = {
|
const getProperties = function (creature, folderIds, filter, options = {
|
||||||
sort: { order: 1 }
|
sort: { order: 1 }
|
||||||
}) {
|
}) {
|
||||||
if (!creature) return;
|
if (!creature) return;
|
||||||
@@ -362,6 +385,7 @@ const getProperties = function (creature, filter, options = {
|
|||||||
filter.hide = { $ne: true };
|
filter.hide = { $ne: true };
|
||||||
}
|
}
|
||||||
filter['ancestors.id'] = creature._id;
|
filter['ancestors.id'] = creature._id;
|
||||||
|
filter['parent.id'] = {$nin: folderIds},
|
||||||
filter.removed = { $ne: true };
|
filter.removed = { $ne: true };
|
||||||
filter.inactive = { $ne: true };
|
filter.inactive = { $ne: true };
|
||||||
filter.overridden = { $ne: true };
|
filter.overridden = { $ne: true };
|
||||||
@@ -373,15 +397,15 @@ const getProperties = function (creature, filter, options = {
|
|||||||
return CreatureProperties.find(filter, options);
|
return CreatureProperties.find(filter, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAttributeOfType = function (creature, type) {
|
const getAttributeOfType = function (creature, folderIds, type) {
|
||||||
return getProperties(creature, {
|
return getProperties(creature, folderIds, {
|
||||||
type: 'attribute',
|
type: 'attribute',
|
||||||
attributeType: type,
|
attributeType: type,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSkillOfType = function (creature, type) {
|
const getSkillOfType = function (creature, folderIds, type) {
|
||||||
return getProperties(creature, {
|
return getProperties(creature, folderIds, {
|
||||||
type: 'skill',
|
type: 'skill',
|
||||||
skillType: type,
|
skillType: type,
|
||||||
});
|
});
|
||||||
@@ -389,18 +413,21 @@ const getSkillOfType = function (creature, type) {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
HealthBar,
|
||||||
RestButton,
|
RestButton,
|
||||||
|
BuffListItem,
|
||||||
AbilityListTile,
|
AbilityListTile,
|
||||||
AttributeCard,
|
AttributeCard,
|
||||||
ColumnLayout,
|
ColumnLayout,
|
||||||
DamageMultiplierCard,
|
DamageMultiplierCard,
|
||||||
HealthBarCardContainer,
|
|
||||||
HitDiceListTile,
|
HitDiceListTile,
|
||||||
SkillListTile,
|
SkillListTile,
|
||||||
ResourceCard,
|
ResourceCard,
|
||||||
SpellSlotListTile,
|
SpellSlotListTile,
|
||||||
ActionCard,
|
ActionCard,
|
||||||
ToggleCard,
|
ToggleCard,
|
||||||
|
EventButton,
|
||||||
|
FolderGroupCard,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
creatureId: {
|
creatureId: {
|
||||||
@@ -417,16 +444,27 @@ export default {
|
|||||||
creature() {
|
creature() {
|
||||||
return Creatures.findOne(this.creatureId, { fields: { settings: 1 } });
|
return Creatures.findOne(this.creatureId, { fields: { settings: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
folders() {
|
||||||
|
return getProperties(this.creature, [], { type: 'folder', groupStats: true });
|
||||||
|
},
|
||||||
|
folderIds() {
|
||||||
|
return this.folders.map(f => f._id);
|
||||||
|
},
|
||||||
|
healthBars() {
|
||||||
|
return getAttributeOfType(this.creature, this.folderIds, 'healthBar');
|
||||||
|
},
|
||||||
abilities() {
|
abilities() {
|
||||||
return getAttributeOfType(this.creature, 'ability');
|
return getAttributeOfType(this.creature, this.folderIds, 'ability');
|
||||||
},
|
},
|
||||||
stats() {
|
stats() {
|
||||||
return getAttributeOfType(this.creature, 'stat');
|
return getAttributeOfType(this.creature, this.folderIds, 'stat');
|
||||||
},
|
},
|
||||||
toggles() {
|
toggles() {
|
||||||
return CreatureProperties.find({
|
return CreatureProperties.find({
|
||||||
'ancestors.id': this.creatureId,
|
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
'parent.id': { $nin: this.folderIds },
|
||||||
removed: { $ne: true },
|
removed: { $ne: true },
|
||||||
deactivatedByAncestor: { $ne: true },
|
deactivatedByAncestor: { $ne: true },
|
||||||
showUI: true,
|
showUI: true,
|
||||||
@@ -435,52 +473,56 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
modifiers() {
|
modifiers() {
|
||||||
return getAttributeOfType(this.creature, 'modifier');
|
return getAttributeOfType(this.creature, this.folderIds, 'modifier');
|
||||||
},
|
},
|
||||||
resources() {
|
resources() {
|
||||||
return getAttributeOfType(this.creature, 'resource');
|
return getAttributeOfType(this.creature, this.folderIds, 'resource');
|
||||||
},
|
},
|
||||||
spellSlots() {
|
spellSlots() {
|
||||||
return getAttributeOfType(this.creature, 'spellSlot');
|
return getAttributeOfType(this.creature, this.folderIds, 'spellSlot');
|
||||||
},
|
},
|
||||||
hasSpells() {
|
hasSpells() {
|
||||||
const cursor = getProperties(this.creature, {
|
const cursor = getProperties(this.creature, this.folderIds, {
|
||||||
type: 'spell',
|
type: 'spell',
|
||||||
})
|
})
|
||||||
return cursor && cursor.count();
|
return cursor && cursor.count();
|
||||||
},
|
},
|
||||||
hitDice() {
|
hitDice() {
|
||||||
return getAttributeOfType(this.creature, 'hitDice');
|
return getAttributeOfType(this.creature, this.folderIds, 'hitDice');
|
||||||
},
|
},
|
||||||
checks() {
|
checks() {
|
||||||
return getSkillOfType(this.creature, 'check');
|
return getSkillOfType(this.creature, this.folderIds, 'check');
|
||||||
},
|
},
|
||||||
savingThrows() {
|
savingThrows() {
|
||||||
return getSkillOfType(this.creature, 'save');
|
return getSkillOfType(this.creature, this.folderIds, 'save');
|
||||||
},
|
},
|
||||||
skills() {
|
skills() {
|
||||||
return getSkillOfType(this.creature, 'skill');
|
return getSkillOfType(this.creature, this.folderIds, 'skill');
|
||||||
},
|
},
|
||||||
tools() {
|
tools() {
|
||||||
return getSkillOfType(this.creature, 'tool');
|
return getSkillOfType(this.creature, this.folderIds, 'tool');
|
||||||
},
|
},
|
||||||
weapons() {
|
weapons() {
|
||||||
return getSkillOfType(this.creature, 'weapon');
|
return getSkillOfType(this.creature, this.folderIds, 'weapon');
|
||||||
},
|
},
|
||||||
armors() {
|
armors() {
|
||||||
return getSkillOfType(this.creature, 'armor');
|
return getSkillOfType(this.creature, this.folderIds, 'armor');
|
||||||
},
|
},
|
||||||
languages() {
|
languages() {
|
||||||
return getSkillOfType(this.creature, 'language');
|
return getSkillOfType(this.creature, this.folderIds, 'language');
|
||||||
|
},
|
||||||
|
events() {
|
||||||
|
const events = getProperties(this.creature, this.folderIds, { type: 'action', actionType: 'event' });
|
||||||
|
return uniqBy(events.fetch(), e => e.variableName);
|
||||||
},
|
},
|
||||||
actions() {
|
actions() {
|
||||||
return getProperties(this.creature, { type: 'action' });
|
return getProperties(this.creature, this.folderIds, { type: 'action', actionType: { $ne: 'event' } });
|
||||||
},
|
},
|
||||||
appliedBuffs() {
|
appliedBuffs() {
|
||||||
return getProperties(this.creature, { type: 'buff' });
|
return getProperties(this.creature, this.folderIds, { type: 'buff' });
|
||||||
},
|
},
|
||||||
multipliers() {
|
multipliers() {
|
||||||
return getProperties(this.creature, {
|
return getProperties(this.creature, this.folderIds, {
|
||||||
type: 'damageMultiplier'
|
type: 'damageMultiplier'
|
||||||
}, {
|
}, {
|
||||||
sort: { value: 1, order: 1 }
|
sort: { value: 1, order: 1 }
|
||||||
@@ -503,13 +545,23 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
incrementChange(_id, { type, value }) {
|
incrementChange(_id, { type, value }) {
|
||||||
if (type === 'increment') {
|
damageProperty.call({
|
||||||
damageProperty.call({ _id, operation: 'increment', value: -value });
|
_id,
|
||||||
}
|
operation: type,
|
||||||
|
value: -value
|
||||||
|
}, error => {
|
||||||
|
if (error) {
|
||||||
|
snackbar({ text: error.reason || error.message || error.toString() });
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
softRemove(_id) {
|
softRemove(_id) {
|
||||||
softRemoveProperty.call({ _id }, error => {
|
softRemoveProperty.call({ _id }, error => {
|
||||||
if (error) console.error(error);
|
if (error) {
|
||||||
|
snackbar({ text: error.reason || error.message || error.toString() });
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
castSpell() {
|
castSpell() {
|
||||||
|
|||||||
@@ -0,0 +1,339 @@
|
|||||||
|
<template>
|
||||||
|
<div class="character-sheet-printed fill-height">
|
||||||
|
<v-fade-transition mode="out-in">
|
||||||
|
<div
|
||||||
|
v-if="!$subReady.singleCharacter"
|
||||||
|
key="character-loading"
|
||||||
|
class="fill-height layout justify-center align-center"
|
||||||
|
>
|
||||||
|
<v-progress-circular
|
||||||
|
indeterminate
|
||||||
|
color="primary"
|
||||||
|
size="64"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="!creature">
|
||||||
|
<v-layout
|
||||||
|
column
|
||||||
|
align-center
|
||||||
|
justify-center
|
||||||
|
>
|
||||||
|
<h2 style="margin: 48px 28px 16px">
|
||||||
|
Character not found
|
||||||
|
</h2>
|
||||||
|
<h3>
|
||||||
|
Either this character does not exist, or you don't have permission
|
||||||
|
to view it.
|
||||||
|
</h3>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
<v-theme-provider
|
||||||
|
v-else
|
||||||
|
light
|
||||||
|
>
|
||||||
|
<div class="page pa-3">
|
||||||
|
<div class="px-3 d-flex align-center">
|
||||||
|
<div class="logo-background" />
|
||||||
|
<div class="creature-name mr-3">
|
||||||
|
{{ creature.name }}
|
||||||
|
</div>
|
||||||
|
<div class="text-right flex mr-4">
|
||||||
|
<div v-if="creature.alignment || background">
|
||||||
|
{{ creature.alignment }} {{ background }}
|
||||||
|
</div>
|
||||||
|
<dir v-if="race || creature.gender">
|
||||||
|
{{ race }} {{ creature.gender }}
|
||||||
|
</dir>
|
||||||
|
<div v-if="level && classes && classes.length === 1">
|
||||||
|
Level {{ level }} {{ classes[0].name }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="level">
|
||||||
|
Level {{ level }} ({{ classes.map(c => `${c.name} ${c.level}`).join(', ') }})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<qrcode-vue
|
||||||
|
style="height: 100px"
|
||||||
|
render-as="svg"
|
||||||
|
:value="creatureUrl"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="text-right mt-3 mr-4"
|
||||||
|
style="font-size: 8pt; margin-bottom: -4px;"
|
||||||
|
>
|
||||||
|
{{ creatureUrl }}
|
||||||
|
</div>
|
||||||
|
<printed-stats :creature-id="creatureId" />
|
||||||
|
<printed-inventory :creature-id="creatureId" />
|
||||||
|
<printed-spells
|
||||||
|
v-if="!creature.settings.hideSpellsTab"
|
||||||
|
:creature-id="creatureId"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</v-theme-provider>
|
||||||
|
</v-fade-transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import PrintedStats from '/imports/ui/creature/character/printedCharacterSheet/PrintedStats.vue';
|
||||||
|
import PrintedInventory from '/imports/ui/creature/character/printedCharacterSheet/PrintedInventory.vue';
|
||||||
|
import PrintedSpells from '/imports/ui/creature/character/printedCharacterSheet/PrintedSpells.vue';
|
||||||
|
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||||
|
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables.js';
|
||||||
|
import QrcodeVue from 'qrcode.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
PrintedStats,
|
||||||
|
PrintedInventory,
|
||||||
|
PrintedSpells,
|
||||||
|
QrcodeVue,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
creatureId() {
|
||||||
|
return this.$route.params.id
|
||||||
|
},
|
||||||
|
creatureUrl() {
|
||||||
|
let props = this.$router.resolve({
|
||||||
|
name: 'characterSheet',
|
||||||
|
params: { id: this.creatureId},
|
||||||
|
});
|
||||||
|
return new URL(props?.href, document.baseURI).href
|
||||||
|
},
|
||||||
|
level() {
|
||||||
|
return this.variables?.level?.value;
|
||||||
|
},
|
||||||
|
highestLevels(){
|
||||||
|
let highestLevels = {};
|
||||||
|
let highestLevelsList = [];
|
||||||
|
this.classLevels.forEach(classLevel => {
|
||||||
|
let name = classLevel.variableName;
|
||||||
|
if (
|
||||||
|
!highestLevels[name] ||
|
||||||
|
highestLevels[name].level < classLevel.level
|
||||||
|
){
|
||||||
|
highestLevels[name] = classLevel;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (let name in highestLevels){
|
||||||
|
highestLevelsList.push(highestLevels[name]);
|
||||||
|
}
|
||||||
|
highestLevelsList.sort((a, b) => a.level - b.level);
|
||||||
|
return highestLevelsList;
|
||||||
|
},
|
||||||
|
classes() {
|
||||||
|
return [
|
||||||
|
...this.highestLevels,
|
||||||
|
...this.classProperties
|
||||||
|
].sort((a, b) => a.order - b.order);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
reactiveProvide: {
|
||||||
|
name: 'context',
|
||||||
|
include: ['creatureId', 'editPermission'],
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'creature.name'(value) {
|
||||||
|
this.$store.commit('setPageTitle', value ? ('Print ' + value) : 'Print Character Sheet');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.commit('setPageTitle',
|
||||||
|
(this.creature && this.creature.name) ?
|
||||||
|
('Print ' + this.creature.name) :
|
||||||
|
'Print Character Sheet'
|
||||||
|
);
|
||||||
|
this.nameObserver = Creatures.find({
|
||||||
|
creatureId: this.creatureId,
|
||||||
|
}, {
|
||||||
|
fields: { name: 1 },
|
||||||
|
}).observe({
|
||||||
|
added: ({ name }) =>
|
||||||
|
this.$store.commit('setPageTitle', name ? ('Print ' + name) : 'Print Character Sheet'),
|
||||||
|
changed: ({ name }) =>
|
||||||
|
this.$store.commit('setPageTitle', name ? ('Print ' + name) : 'Print Character Sheet'),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.nameObserver.stop();
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
$subscribe: {
|
||||||
|
'singleCharacter'() {
|
||||||
|
return [this.creatureId];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
creature() {
|
||||||
|
return Creatures.findOne(this.creatureId);
|
||||||
|
},
|
||||||
|
variables() {
|
||||||
|
return CreatureVariables.findOne({ _creatureId: this.creatureId }) || {};
|
||||||
|
},
|
||||||
|
race() {
|
||||||
|
if (this.variables?.race?.value?.valueType === 'string') return this.variables.race.value.value;
|
||||||
|
const prop = CreatureProperties.findOne({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
tags: 'race',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
overridden: { $ne: true },
|
||||||
|
});
|
||||||
|
if (prop?.name) return prop.name;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
background() {
|
||||||
|
if (this.variables?.background?.value?.valueType === 'string') return this.variables.background.value.value;
|
||||||
|
const prop = CreatureProperties.findOne({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
tags: 'background',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
overridden: { $ne: true },
|
||||||
|
});
|
||||||
|
if (prop?.name) return prop.name;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
classProperties(){
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
type: 'class',
|
||||||
|
removed: {$ne: true},
|
||||||
|
inactive: {$ne: true},
|
||||||
|
}, {
|
||||||
|
sort: {order: 1}
|
||||||
|
}).fetch();
|
||||||
|
},
|
||||||
|
classLevels() {
|
||||||
|
const classVariableNames = this.classProperties.map(c => c.variableName)
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
type: 'classLevel',
|
||||||
|
variableName: {$nin: classVariableNames},
|
||||||
|
removed: {$ne: true},
|
||||||
|
inactive: {$ne: true},
|
||||||
|
}, {
|
||||||
|
sort: {order: 1}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editPermission() {
|
||||||
|
try {
|
||||||
|
assertEditPermission(this.creature, Meteor.userId());
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.character-sheet-printed {
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
.page {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.character-sheet-printed .inactive {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
.character-sheet-printed .creature-name {
|
||||||
|
font-size: 24pt;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.character-sheet-printed .logo-background {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
margin-right: 8px;
|
||||||
|
background-image: url(/crown-dice-logo-cropped-transparent.png);
|
||||||
|
background-size: contain;
|
||||||
|
background-position: 0 center;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .v-divider {
|
||||||
|
border-color: rgba(0,0,0,0.3);
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .double-border {
|
||||||
|
position: relative;
|
||||||
|
padding: 11px 10px;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .double-border::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
border-image-source: url(/images/print/doubleLineImageBorder.png);
|
||||||
|
border-image-slice: 110 126 fill;
|
||||||
|
border-image-width: 16px;
|
||||||
|
border-image-repeat: stretch;
|
||||||
|
box-sizing: content-box;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .octagon-border {
|
||||||
|
position: relative;
|
||||||
|
padding: 4px 20px;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
.character-sheet-printed .octagon-border::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
border-image: url(/images/print/octagonBorder.png) 124 118 fill;
|
||||||
|
border-image-width: 22px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .stats .label {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .label {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-sheet-printed .span-all {
|
||||||
|
column-span: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen {
|
||||||
|
.character-sheet-printed {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.character-sheet-printed .page {
|
||||||
|
width: 210mm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
header {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
nav {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.v-main {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
class="inventory"
|
||||||
|
style="page-break-before: always;"
|
||||||
|
>
|
||||||
|
<column-layout wide-columns>
|
||||||
|
<div class="span-all">
|
||||||
|
<div class="double-border">
|
||||||
|
<div class="label text-center">
|
||||||
|
Inventory
|
||||||
|
</div>
|
||||||
|
<div class="d-flex inventory-stat">
|
||||||
|
<v-icon>$vuetify.icons.injustice</v-icon>
|
||||||
|
Weight Carried:
|
||||||
|
{{ weightCarried }} lb
|
||||||
|
</div>
|
||||||
|
<div class="d-flex inventory-stat">
|
||||||
|
<v-icon>$vuetify.icons.cash</v-icon>
|
||||||
|
Net worth:
|
||||||
|
<coin-value
|
||||||
|
class="ml-2"
|
||||||
|
:value="variables && variables.valueTotal && variables.valueTotal.value|| 0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex inventory-stat">
|
||||||
|
<v-icon>$vuetify.icons.spell</v-icon>
|
||||||
|
Items attuned:
|
||||||
|
{{ variables.itemsAttuned && variables.itemsAttuned.value }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="span-all">
|
||||||
|
<div class="octagon-border label text-center">
|
||||||
|
Equipped
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="item in equippedItems"
|
||||||
|
:key="item._id"
|
||||||
|
>
|
||||||
|
<printed-item
|
||||||
|
class="double-border"
|
||||||
|
:model="item"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="span-all">
|
||||||
|
<div class="octagon-border label text-center">
|
||||||
|
Carried
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="item in carriedItems"
|
||||||
|
:key="item._id"
|
||||||
|
>
|
||||||
|
<printed-item
|
||||||
|
class="double-border"
|
||||||
|
:model="item"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<template
|
||||||
|
v-for="container in containersWithoutAncestorContainers"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:key="container._id"
|
||||||
|
class="span-all container-header"
|
||||||
|
>
|
||||||
|
<printed-container
|
||||||
|
class="octagon-border"
|
||||||
|
:model="container"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="item in container.items"
|
||||||
|
:key="item._id"
|
||||||
|
>
|
||||||
|
<printed-item
|
||||||
|
class="double-border"
|
||||||
|
:model="item"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</column-layout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
|
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||||
|
import getParentRefByTag from '/imports/api/creature/creatureProperties/methods/getParentRefByTag.js';
|
||||||
|
import BUILT_IN_TAGS from '/imports/constants/BUILT_IN_TAGS.js';
|
||||||
|
import CoinValue from '/imports/ui/components/CoinValue.vue';
|
||||||
|
import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities.js';
|
||||||
|
import PrintedItem from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedItem.vue';
|
||||||
|
import PrintedContainer from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedContainer.vue';
|
||||||
|
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ColumnLayout,
|
||||||
|
CoinValue,
|
||||||
|
PrintedItem,
|
||||||
|
PrintedContainer,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
organize: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
containers() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
type: 'container',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
creature() {
|
||||||
|
return Creatures.findOne(this.creatureId, {
|
||||||
|
fields: {
|
||||||
|
color: 1,
|
||||||
|
variables: 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
variables() {
|
||||||
|
return CreatureVariables.findOne({ _creatureId: this.creatureId }) || {};
|
||||||
|
},
|
||||||
|
containersWithoutAncestorContainers() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': {
|
||||||
|
$eq: this.creatureId,
|
||||||
|
$nin: this.containerIds
|
||||||
|
},
|
||||||
|
type: 'container',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
}).map(c => {
|
||||||
|
c.items = CreatureProperties.find({
|
||||||
|
'parent.id': c._id,
|
||||||
|
type: { $in: ['item', 'container'] },
|
||||||
|
removed: { $ne: true },
|
||||||
|
equipped: { $ne: true },
|
||||||
|
deactivatedByAncestor: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
}).fetch();
|
||||||
|
return c;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
carriedItems() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': {
|
||||||
|
$eq: this.creatureId,
|
||||||
|
$nin: this.containerIds
|
||||||
|
},
|
||||||
|
type: 'item',
|
||||||
|
equipped: { $ne: true },
|
||||||
|
removed: { $ne: true },
|
||||||
|
deactivatedByAncestor: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
equippedItems() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': {
|
||||||
|
$eq: this.creatureId,
|
||||||
|
},
|
||||||
|
type: 'item',
|
||||||
|
equipped: true,
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
equipmentParentRef() {
|
||||||
|
return getParentRefByTag(
|
||||||
|
this.creatureId, BUILT_IN_TAGS.equipment
|
||||||
|
) || getParentRefByTag(
|
||||||
|
this.creatureId, BUILT_IN_TAGS.inventory
|
||||||
|
) || {
|
||||||
|
id: this.creatureId,
|
||||||
|
collection: 'creatures'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
carriedParentRef() {
|
||||||
|
return getParentRefByTag(
|
||||||
|
this.creatureId, BUILT_IN_TAGS.carried
|
||||||
|
) || getParentRefByTag(
|
||||||
|
this.creatureId, BUILT_IN_TAGS.inventory
|
||||||
|
) || {
|
||||||
|
id: this.creatureId,
|
||||||
|
collection: 'creatures'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
containerIds() {
|
||||||
|
return this.containers.map(container => container._id);
|
||||||
|
},
|
||||||
|
weightCarried() {
|
||||||
|
return stripFloatingPointOddities(
|
||||||
|
this.variables &&
|
||||||
|
this.variables.weightCarried &&
|
||||||
|
this.variables.weightCarried.value || 0
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clickProperty(_id) {
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'creature-property-dialog',
|
||||||
|
elementId: `tree-node-${_id}`,
|
||||||
|
data: { _id },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.octagon-border {
|
||||||
|
position: relative;
|
||||||
|
padding: 4px 20px;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
.octagon-border::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
border-image: url(/images/print/octagonBorder.png) 124 118 fill;
|
||||||
|
border-image-width: 22px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-variant: small-caps;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-stat {
|
||||||
|
font-size: 12pt;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
.inventory-stat > .v-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-header {
|
||||||
|
page-break-after: avoid;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
class="spells"
|
||||||
|
style="page-break-before: always;"
|
||||||
|
>
|
||||||
|
<column-layout wide-columns>
|
||||||
|
<div class="span-all">
|
||||||
|
<div class="label text-center octagon-border">
|
||||||
|
Spells
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="spell in spellsWithoutList"
|
||||||
|
:key="spell._id"
|
||||||
|
>
|
||||||
|
<printed-spell :model="spell" />
|
||||||
|
</div>
|
||||||
|
<template
|
||||||
|
v-for="spellList in spellListsWithoutAncestorSpellLists"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:key="spellList._id"
|
||||||
|
class="span-all"
|
||||||
|
>
|
||||||
|
<printed-spell-list
|
||||||
|
:model="spellList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="spell in spellList.spells"
|
||||||
|
:key="spell._id"
|
||||||
|
>
|
||||||
|
<printed-spell :model="spell" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</column-layout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import PrintedSpell from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedSpell.vue';
|
||||||
|
import PrintedSpellList from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedSpellList.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ColumnLayout,
|
||||||
|
PrintedSpell,
|
||||||
|
PrintedSpellList,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
organize: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
spellLists() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
type: 'spellList',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
spellsWithoutList() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': {
|
||||||
|
$eq: this.creatureId,
|
||||||
|
$nin: this.spellListIds,
|
||||||
|
},
|
||||||
|
type: 'spell',
|
||||||
|
removed: { $ne: true },
|
||||||
|
deactivatedByAncestor: { $ne: true },
|
||||||
|
deactivatedByToggle: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: {
|
||||||
|
level: 1,
|
||||||
|
order: 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
spellListsWithoutAncestorSpellLists() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': {
|
||||||
|
$eq: this.creatureId,
|
||||||
|
$nin: this.spellListIds,
|
||||||
|
},
|
||||||
|
type: 'spellList',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 }
|
||||||
|
}).map(sl => {
|
||||||
|
sl.spells = CreatureProperties.find({
|
||||||
|
'ancestors.id': sl._id,
|
||||||
|
type: 'spell',
|
||||||
|
removed: { $ne: true },
|
||||||
|
inactive: { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: {
|
||||||
|
level: 1,
|
||||||
|
order: 1,
|
||||||
|
}
|
||||||
|
}).fetch();
|
||||||
|
return sl;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
spellListIds() {
|
||||||
|
return this.spellLists?.map(spellList => spellList._id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,639 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div class="stats">
|
||||||
|
<column-layout>
|
||||||
|
<div
|
||||||
|
v-if="abilities.length"
|
||||||
|
class="ability-scores"
|
||||||
|
>
|
||||||
|
<div class="layout flex column">
|
||||||
|
<div
|
||||||
|
v-for="ability in abilities"
|
||||||
|
:key="ability._id"
|
||||||
|
class="ability"
|
||||||
|
>
|
||||||
|
<div class="score">
|
||||||
|
<div class="double-border top big-number">
|
||||||
|
<template v-if="creature.settings.swapScoresAndMods">
|
||||||
|
{{ ability.total }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ numberToSignedString(ability.modifier) }}
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<template v-if="creature.settings.swapScoresAndMods">
|
||||||
|
{{ numberToSignedString(ability.modifier) }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ ability.total }}
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="double-border name label">
|
||||||
|
{{ ability.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="toggle in toggles"
|
||||||
|
:key="toggle._id"
|
||||||
|
class="number-label"
|
||||||
|
>
|
||||||
|
<div class="box double-border" />
|
||||||
|
<div class="label double-border">
|
||||||
|
{{ toggle.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="stat in stats"
|
||||||
|
:key="stat._id"
|
||||||
|
class="number-label"
|
||||||
|
:class="stat.variableName == 'armor' && 'shield-number-label'"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:class="stat.variableName == 'armor' ? 'shield-border' : 'octagon-border'"
|
||||||
|
class="number big-number"
|
||||||
|
>
|
||||||
|
{{ stat.value }}
|
||||||
|
</div>
|
||||||
|
<div class="label double-border">
|
||||||
|
{{ stat.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="modifier in modifiers"
|
||||||
|
:key="modifier._id"
|
||||||
|
class="number-label"
|
||||||
|
>
|
||||||
|
<div class="number octagon-border big-number">
|
||||||
|
{{ numberToSignedString(modifier.value) }}
|
||||||
|
</div>
|
||||||
|
<div class="label double-border">
|
||||||
|
{{ modifier.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="check in checks"
|
||||||
|
:key="check._id"
|
||||||
|
class="number-label"
|
||||||
|
>
|
||||||
|
<div class="number octagon-border big-number">
|
||||||
|
{{ numberToSignedString(check.value) }}
|
||||||
|
</div>
|
||||||
|
<div class="label double-border">
|
||||||
|
{{ check.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="healthBar in healthBars"
|
||||||
|
:key="healthBar._id"
|
||||||
|
class="m-2"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<div class="label">
|
||||||
|
Total: {{ healthBar.total }}
|
||||||
|
</div>
|
||||||
|
<div style="height: 60px;" />
|
||||||
|
<div
|
||||||
|
style="text-align: center;"
|
||||||
|
class="label"
|
||||||
|
>
|
||||||
|
{{ healthBar.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="multipliers && multipliers.length">
|
||||||
|
<printed-damage-multipliers
|
||||||
|
class="double-border"
|
||||||
|
:multipliers="multipliers"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="hitDice.length"
|
||||||
|
class="hit-dice m-2"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<div>
|
||||||
|
<span class="label">
|
||||||
|
Total:
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-for="hitDie in hitDice"
|
||||||
|
:key="hitDie._id"
|
||||||
|
style="margin-right: 4px;"
|
||||||
|
>
|
||||||
|
{{ hitDie.total }}{{ hitDie.hitDiceSize }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div style="height: 60px;" />
|
||||||
|
<div
|
||||||
|
style="text-align: center;"
|
||||||
|
class="label"
|
||||||
|
>
|
||||||
|
Hit Dice
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="resource in resources"
|
||||||
|
:key="resource._id"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
:class="resource.total <= 8 && 'mb-2'"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="resource.total <= 8"
|
||||||
|
class="label"
|
||||||
|
>
|
||||||
|
{{ resource.name }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="resource.total > 8"
|
||||||
|
>
|
||||||
|
total: {{ resource.total }}
|
||||||
|
<div style="height: 60px;" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="resource.total <= 8"
|
||||||
|
class="d-flex justify-end"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="i in resource.total"
|
||||||
|
:key="i"
|
||||||
|
class="resource-bubble"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="resource.total > 8"
|
||||||
|
class="label text-center"
|
||||||
|
>
|
||||||
|
{{ resource.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="spellSlots && spellSlots.length"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<div class="label text-center">
|
||||||
|
Spell Slots
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="spellSlot in spellSlots"
|
||||||
|
:key="spellSlot._id"
|
||||||
|
class="mb-7"
|
||||||
|
:class="spellSlot.total <= 8 && 'mb-7'"
|
||||||
|
>
|
||||||
|
<div class="label">
|
||||||
|
{{ spellSlot.name }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="spellSlot.total > 8"
|
||||||
|
>
|
||||||
|
Total: {{ spellSlot.total }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="d-flex"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="i in spellSlot.total"
|
||||||
|
:key="i"
|
||||||
|
class="resource-bubble"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="savingThrows.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="save in savingThrows"
|
||||||
|
:key="save._id"
|
||||||
|
:model="save"
|
||||||
|
:data-id="save._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Saving Throws
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="skills.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="skill in skills"
|
||||||
|
:key="skill._id"
|
||||||
|
:model="skill"
|
||||||
|
:data-id="skill._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Skills
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="weapons && weapons.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="weapon in weapons"
|
||||||
|
:key="weapon._id"
|
||||||
|
hide-modifier
|
||||||
|
:model="weapon"
|
||||||
|
:data-id="weapon._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Weapons
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="armors && armors.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="armor in armors"
|
||||||
|
:key="armor._id"
|
||||||
|
hide-modifier
|
||||||
|
:model="armor"
|
||||||
|
:data-id="armor._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Armor
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="tools && tools.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="tool in tools"
|
||||||
|
:key="tool._id"
|
||||||
|
hide-modifier
|
||||||
|
:model="tool"
|
||||||
|
:data-id="tool._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Tools
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="languages && languages.length"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<printed-skill
|
||||||
|
v-for="language in languages"
|
||||||
|
:key="language._id"
|
||||||
|
hide-modifier
|
||||||
|
:model="language"
|
||||||
|
:data-id="language._id"
|
||||||
|
/>
|
||||||
|
<div class="label text-center">
|
||||||
|
Languages
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="note in notes"
|
||||||
|
:key="note._id"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<div class="label text-center">
|
||||||
|
{{ note.name }}
|
||||||
|
</div>
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="note.summary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="action in actions"
|
||||||
|
:key="action._id"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<printed-action
|
||||||
|
:model="action"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="feature in features"
|
||||||
|
:key="feature._id"
|
||||||
|
>
|
||||||
|
<div class="double-border">
|
||||||
|
<div class="label text-center">
|
||||||
|
{{ feature.name }}
|
||||||
|
</div>
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="feature.summary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</column-layout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||||
|
import ColumnLayout from '/imports/ui/components/ColumnLayout.vue';
|
||||||
|
import PrintedAction from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedAction.vue';
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import PrintedSkill from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedSkill.vue';
|
||||||
|
import PrintedDamageMultipliers from '/imports/ui/creature/character/printedCharacterSheet/components/PrintedDamageMultipliers.vue';
|
||||||
|
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue';
|
||||||
|
|
||||||
|
const getProperties = function (creature, filter, options = {
|
||||||
|
sort: { order: 1 }
|
||||||
|
}) {
|
||||||
|
if (!creature) return;
|
||||||
|
if (creature.settings.hideUnusedStats) {
|
||||||
|
filter.hide = { $ne: true };
|
||||||
|
}
|
||||||
|
filter['ancestors.id'] = creature._id;
|
||||||
|
filter.removed = { $ne: true };
|
||||||
|
filter.inactive = { $ne: true };
|
||||||
|
filter.overridden = { $ne: true };
|
||||||
|
filter.$nor = [
|
||||||
|
{ hideWhenTotalZero: true, total: 0 },
|
||||||
|
{ hideWhenValueZero: true, value: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
return CreatureProperties.find(filter, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAttributeOfType = function (creature, type) {
|
||||||
|
return getProperties(creature, {
|
||||||
|
type: 'attribute',
|
||||||
|
attributeType: type,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSkillOfType = function (creature, type) {
|
||||||
|
return getProperties(creature, {
|
||||||
|
type: 'skill',
|
||||||
|
skillType: type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ColumnLayout,
|
||||||
|
PrintedDamageMultipliers,
|
||||||
|
PrintedAction,
|
||||||
|
PrintedSkill,
|
||||||
|
PropertyDescription,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
creatureId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
doCheckLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
creature() {
|
||||||
|
return Creatures.findOne(this.creatureId, { fields: { settings: 1 } });
|
||||||
|
},
|
||||||
|
abilities() {
|
||||||
|
return getAttributeOfType(this.creature, 'ability');
|
||||||
|
},
|
||||||
|
stats() {
|
||||||
|
return getAttributeOfType(this.creature, 'stat');
|
||||||
|
},
|
||||||
|
toggles() {
|
||||||
|
return CreatureProperties.find({
|
||||||
|
'ancestors.id': this.creatureId,
|
||||||
|
type: 'toggle',
|
||||||
|
removed: { $ne: true },
|
||||||
|
deactivatedByAncestor: { $ne: true },
|
||||||
|
showUI: true,
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
healthBars() {
|
||||||
|
return getAttributeOfType(this.creature, 'healthBar');
|
||||||
|
},
|
||||||
|
modifiers() {
|
||||||
|
return getAttributeOfType(this.creature, 'modifier');
|
||||||
|
},
|
||||||
|
resources() {
|
||||||
|
return getAttributeOfType(this.creature, 'resource');
|
||||||
|
},
|
||||||
|
spellSlots() {
|
||||||
|
return getAttributeOfType(this.creature, 'spellSlot');
|
||||||
|
},
|
||||||
|
hasSpells() {
|
||||||
|
const cursor = getProperties(this.creature, {
|
||||||
|
type: 'spell',
|
||||||
|
})
|
||||||
|
return cursor && cursor.count();
|
||||||
|
},
|
||||||
|
hitDice() {
|
||||||
|
return getAttributeOfType(this.creature, 'hitDice');
|
||||||
|
},
|
||||||
|
checks() {
|
||||||
|
return getSkillOfType(this.creature, 'check');
|
||||||
|
},
|
||||||
|
savingThrows() {
|
||||||
|
return getSkillOfType(this.creature, 'save');
|
||||||
|
},
|
||||||
|
skills() {
|
||||||
|
return getSkillOfType(this.creature, 'skill');
|
||||||
|
},
|
||||||
|
tools() {
|
||||||
|
return getSkillOfType(this.creature, 'tool');
|
||||||
|
},
|
||||||
|
weapons() {
|
||||||
|
return getSkillOfType(this.creature, 'weapon');
|
||||||
|
},
|
||||||
|
armors() {
|
||||||
|
return getSkillOfType(this.creature, 'armor');
|
||||||
|
},
|
||||||
|
languages() {
|
||||||
|
return getSkillOfType(this.creature, 'language');
|
||||||
|
},
|
||||||
|
actions() {
|
||||||
|
return getProperties(this.creature, { type: 'action' }, {
|
||||||
|
sort: { actionType: 1, order: 1 }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
appliedBuffs() {
|
||||||
|
return getProperties(this.creature, { type: 'buff' });
|
||||||
|
},
|
||||||
|
multipliers() {
|
||||||
|
return getProperties(this.creature, {
|
||||||
|
type: 'damageMultiplier'
|
||||||
|
}, {
|
||||||
|
sort: { value: 1, order: 1 }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
features() {
|
||||||
|
return getProperties(this.creature, { type: 'feature' });
|
||||||
|
},
|
||||||
|
notes(){
|
||||||
|
return getProperties(this.creature, { type: 'note', summary: {$exists: true} });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
numberToSignedString,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.shield-border {
|
||||||
|
min-width: 64px !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 0.87;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
.shield-border::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: url(/images/print/shieldBorder.png);
|
||||||
|
print-color-adjust: exact;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.shield-number-label {
|
||||||
|
align-items: center !important;
|
||||||
|
}
|
||||||
|
.big-number {
|
||||||
|
font-size: 20pt;
|
||||||
|
}
|
||||||
|
.ability {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
.ability .score {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.ability .top {
|
||||||
|
min-width: 64px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: -10px;
|
||||||
|
padding: 14px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.ability .bottom {
|
||||||
|
font-size: 10pt;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 16px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.ability .bottom::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
border: solid white;
|
||||||
|
border-image-source: url(/images/print/upwardPointingBorder.png);
|
||||||
|
border-image-slice: 0 85 fill;
|
||||||
|
border-image-width: 0 16px;
|
||||||
|
border-image-outset: 0px 0px;
|
||||||
|
border-image-repeat: stretch;
|
||||||
|
box-sizing: content-box;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.ability .name {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: -16px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-variant: small-caps;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-label .label {
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-left: -30px;
|
||||||
|
padding-left: 34px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-label .number {
|
||||||
|
min-width: 72px;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-label .box {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
margin-left: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-bubble {
|
||||||
|
margin-bottom: -20px;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
background-color: white;
|
||||||
|
border: solid black 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
class="action-card"
|
||||||
|
:class="cardClasses"
|
||||||
|
>
|
||||||
|
<div class="label text-center">
|
||||||
|
{{ actionTypeName }}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<div class="avatar">
|
||||||
|
<div
|
||||||
|
v-if="rollBonus"
|
||||||
|
>
|
||||||
|
<template v-if="rollBonus && !rollBonusTooLong">
|
||||||
|
{{ rollBonus }}
|
||||||
|
</template>
|
||||||
|
<property-icon
|
||||||
|
v-else
|
||||||
|
:model="model"
|
||||||
|
color="rgba(0,0,0,0.7)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<property-icon
|
||||||
|
v-else
|
||||||
|
:model="model"
|
||||||
|
color="rgba(0,0,0,0.7)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="action-header flex d-flex column justify-center pl-1"
|
||||||
|
>
|
||||||
|
<div class="action-title my-1">
|
||||||
|
{{ model.name || propertyName }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="Number.isFinite(model.uses)"
|
||||||
|
class="action-sub-title d-flex align-center"
|
||||||
|
>
|
||||||
|
{{ model.uses }} uses
|
||||||
|
</div>
|
||||||
|
<div class="pb-3">
|
||||||
|
<div
|
||||||
|
v-if="model.resources && model.resources.attributesConsumed.length ||
|
||||||
|
model.resources.itemsConsumed.length"
|
||||||
|
class="resources my-2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="attributeConsumed in model.resources.attributesConsumed"
|
||||||
|
:key="attributeConsumed._id"
|
||||||
|
class="layout align-center justify-start"
|
||||||
|
>
|
||||||
|
Cost: {{ attributeConsumed.quantity && attributeConsumed.quantity.value }} {{ attributeConsumed.statName || attributeConsumed.variableName }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="itemConsumed in model.resources.itemsConsumed"
|
||||||
|
:key="itemConsumed._id"
|
||||||
|
>
|
||||||
|
<template v-if="itemConsumed.itemName">
|
||||||
|
Uses: {{ itemConsumed.quantity && itemConsumed.quantity.value || 0 }} {{ itemConsumed.itemName || itemConsumed.tag }}
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template v-if="model.summary">
|
||||||
|
<markdown-text :markdown="model.summary.value || model.summary.text" />
|
||||||
|
</template>
|
||||||
|
<v-divider v-if="children && children.length" />
|
||||||
|
<tree-node-list
|
||||||
|
v-if="children && children.length"
|
||||||
|
start-expanded
|
||||||
|
:children="children"
|
||||||
|
@selected="e => $emit('sub-click', e)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import AttributeConsumedView from '/imports/ui/properties/components/actions/AttributeConsumedView.vue';
|
||||||
|
import ItemConsumedView from '/imports/ui/properties/components/actions/ItemConsumedView.vue';
|
||||||
|
import PropertyIcon from '/imports/ui/properties/shared/PropertyIcon.vue';
|
||||||
|
import MarkdownText from '/imports/ui/components/MarkdownText.vue';
|
||||||
|
import TreeNodeList from '/imports/ui/components/tree/TreeNodeList.vue';
|
||||||
|
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import { some } from 'lodash';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AttributeConsumedView,
|
||||||
|
ItemConsumedView,
|
||||||
|
MarkdownText,
|
||||||
|
PropertyIcon,
|
||||||
|
TreeNodeList,
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
context: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
default: {
|
||||||
|
isDark: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activated: undefined,
|
||||||
|
doActionLoading: false,
|
||||||
|
hovering: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
rollBonus() {
|
||||||
|
if (!this.model.attackRoll) return;
|
||||||
|
return numberToSignedString(this.model.attackRoll.value);
|
||||||
|
},
|
||||||
|
rollBonusTooLong() {
|
||||||
|
return this.rollBonus && this.rollBonus.length > 3;
|
||||||
|
},
|
||||||
|
propertyName() {
|
||||||
|
return getPropertyName(this.model.type);
|
||||||
|
},
|
||||||
|
cardClasses() {
|
||||||
|
return {
|
||||||
|
'theme--dark': this.theme.isDark,
|
||||||
|
'theme--light': !this.theme.isDark,
|
||||||
|
'muted-text': this.model.insufficientResources,
|
||||||
|
'active': this.activated,
|
||||||
|
'elevation-8': this.hovering,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actionTypeName() {
|
||||||
|
return {
|
||||||
|
'action': 'Action',
|
||||||
|
'bonus': 'Bonus Action',
|
||||||
|
'attack': 'Attack',
|
||||||
|
'reaction': 'Reaction',
|
||||||
|
'free': 'Free Action',
|
||||||
|
'long': 'Long Action'
|
||||||
|
}[this.model.actionType] || this.model.actionType
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meteor: {
|
||||||
|
children() {
|
||||||
|
const indicesOfTerminatingProps = [];
|
||||||
|
const decendants = CreatureProperties.find({
|
||||||
|
'ancestors.id': this.model._id,
|
||||||
|
'removed': { $ne: true },
|
||||||
|
}, {
|
||||||
|
sort: {order: 1}
|
||||||
|
}).map(prop => {
|
||||||
|
// Get all the props we don't want to show the decendants of and
|
||||||
|
// where they might appear in the ancestor list
|
||||||
|
if (prop.type === 'buff' || prop.type === 'folder') {
|
||||||
|
indicesOfTerminatingProps.push({
|
||||||
|
id: prop._id,
|
||||||
|
ancestorIndex: prop.ancestors.length,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return prop;
|
||||||
|
}).filter(prop => {
|
||||||
|
// Filter out folders entirely
|
||||||
|
if (prop.type === 'folder') return false;
|
||||||
|
// Filter out decendants of terminating props
|
||||||
|
return !some(indicesOfTerminatingProps, buffIndex => {
|
||||||
|
return prop.ancestors[buffIndex.ancestorIndex]?.id === buffIndex.id;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return nodeArrayToTree(decendants);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.action-card {
|
||||||
|
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1),
|
||||||
|
transform 0.075s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
font-size: 18pt;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 40px;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-variant: small-caps;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
transition: .3s cubic-bezier(.25, .8, .5, 1);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resources {
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-child {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme--light.muted-text {
|
||||||
|
color: rgba(0, 0, 0, .3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme--dark.muted-text {
|
||||||
|
color: hsla(0, 0%, 100%, .3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-card {
|
||||||
|
transition: transform 0.15s cubic;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="css">
|
||||||
|
.action-card.theme--light.muted-text .v-icon {
|
||||||
|
color: rgba(0, 0, 0, .3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-card.theme--dark.muted-text .v-icon {
|
||||||
|
color: hsla(0, 0%, 100%, .3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-card .property-description>p:last-of-type {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="d-flex justify-center">
|
||||||
|
<property-icon
|
||||||
|
class="ml-2"
|
||||||
|
color="rgba(0,0,0,0.7)"
|
||||||
|
:model="model"
|
||||||
|
/>
|
||||||
|
<div class="label">
|
||||||
|
{{ model.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="model.value !== undefined || model.weight !== undefined"
|
||||||
|
class="weight-value my-2 d-flex justify-space-between"
|
||||||
|
>
|
||||||
|
<div class="value ml-4">
|
||||||
|
<div
|
||||||
|
v-if="model.value !== undefined"
|
||||||
|
>
|
||||||
|
<v-layout align-center>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.two_coins
|
||||||
|
</v-icon>
|
||||||
|
<coin-value
|
||||||
|
class="mr-2"
|
||||||
|
:value="model.value"
|
||||||
|
/>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-layout
|
||||||
|
align-center
|
||||||
|
class="mb-2"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.cash
|
||||||
|
</v-icon>
|
||||||
|
<coin-value
|
||||||
|
:value="model.contentsValue"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ml-1"
|
||||||
|
>
|
||||||
|
contents
|
||||||
|
</span>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="weight ml-4">
|
||||||
|
<div
|
||||||
|
v-if="model.weight !== undefined"
|
||||||
|
>
|
||||||
|
<v-layout align-center>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.weight
|
||||||
|
</v-icon>
|
||||||
|
{{ model.weight }} lb
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-layout
|
||||||
|
align-center
|
||||||
|
class="mb-2"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.injustice
|
||||||
|
</v-icon>
|
||||||
|
{{ model.contentsWeight }} lb
|
||||||
|
<span
|
||||||
|
class="ml-1"
|
||||||
|
>
|
||||||
|
contents
|
||||||
|
</span>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="model.description"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import treeNodeViewMixin from '/imports/ui/properties/treeNodeViews/treeNodeViewMixin.js';
|
||||||
|
import PROPERTIES from '/imports/constants/PROPERTIES.js';
|
||||||
|
import CoinValue from '/imports/ui/components/CoinValue.vue';
|
||||||
|
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue';
|
||||||
|
import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CoinValue,
|
||||||
|
PropertyDescription,
|
||||||
|
},
|
||||||
|
mixins: [treeNodeViewMixin],
|
||||||
|
inject: {
|
||||||
|
context: { default: {} }
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
preparingSpells: Boolean,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
incrementLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasClickListener() {
|
||||||
|
return this.$listeners && !!this.$listeners.click;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.item-avatar {
|
||||||
|
min-width: 32px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-for="(multiplier, multiplierIndex) in multipliers"
|
||||||
|
:key="multiplier._id"
|
||||||
|
:data-id="multiplier._id"
|
||||||
|
@click="$emit('click-multiplier', {_id: multiplier._id})"
|
||||||
|
>
|
||||||
|
<v-divider v-if="multiplierIndex" />
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-if="multiplier.name"
|
||||||
|
class="label text-center"
|
||||||
|
>
|
||||||
|
{{ multiplier.name }}
|
||||||
|
</div>
|
||||||
|
<div class="font-weight-medium">
|
||||||
|
{{ title(multiplier) }}
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-wrap align-center">
|
||||||
|
{{ multiplier.damageTypes.join(', ') }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="multiplier.includeTags && multiplier.includeTags.length"
|
||||||
|
class="d-flex flex-wrap align-center"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
For:
|
||||||
|
</div>
|
||||||
|
{{ multiplier.includeTags.join(', ') }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="multiplier.excludeTags && multiplier.excludeTags.length"
|
||||||
|
class="d-flex flex-wrap align-center"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
Except:
|
||||||
|
</div>
|
||||||
|
{{ multiplier.excludeTags.join(', ') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
multipliers:{
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
title(prop){
|
||||||
|
switch (prop.value){
|
||||||
|
case 0: return 'Immunity';
|
||||||
|
case 0.5: return 'Resistance';
|
||||||
|
case 2: return 'Vulnerability';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.label {
|
||||||
|
font-size: 10pt;
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<div class="item">
|
||||||
|
<div class="d-flex justify-space-between">
|
||||||
|
<div class="label">
|
||||||
|
{{ title }}
|
||||||
|
<template v-if="attunementText">
|
||||||
|
({{ attunementText }})
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<property-icon
|
||||||
|
class="ml-2"
|
||||||
|
color="rgba(0,0,0,0.7)"
|
||||||
|
:model="model"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="model.value !== undefined || model.weight !== undefined"
|
||||||
|
class="weight-value my-2 d-flex justify-space-between"
|
||||||
|
>
|
||||||
|
<div class="value ml-4">
|
||||||
|
<div
|
||||||
|
v-if="model.value !== undefined"
|
||||||
|
>
|
||||||
|
<v-layout
|
||||||
|
v-if="model.quantity > 1"
|
||||||
|
align-center
|
||||||
|
class="mb-2"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.cash
|
||||||
|
</v-icon>
|
||||||
|
<coin-value
|
||||||
|
:value="model.value * model.quantity"
|
||||||
|
/>
|
||||||
|
</v-layout>
|
||||||
|
<v-layout align-center>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.two_coins
|
||||||
|
</v-icon>
|
||||||
|
<coin-value
|
||||||
|
class="mr-2"
|
||||||
|
:value="model.value"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="model.quantity > 1"
|
||||||
|
class="ml-1"
|
||||||
|
>
|
||||||
|
each
|
||||||
|
</span>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="weight ml-4">
|
||||||
|
<div
|
||||||
|
v-if="model.weight !== undefined"
|
||||||
|
>
|
||||||
|
<v-layout
|
||||||
|
v-if="model.quantity > 1"
|
||||||
|
align-center
|
||||||
|
class="mb-2"
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.injustice
|
||||||
|
</v-icon>
|
||||||
|
{{ totalWeight }} lb
|
||||||
|
</v-layout>
|
||||||
|
<v-layout align-center>
|
||||||
|
<v-icon
|
||||||
|
class="mr-2"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
$vuetify.icons.weight
|
||||||
|
</v-icon>
|
||||||
|
{{ model.weight }} lb
|
||||||
|
<span
|
||||||
|
v-if="model.quantity > 1"
|
||||||
|
class="ml-1"
|
||||||
|
>
|
||||||
|
each
|
||||||
|
</span>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="model.description"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import treeNodeViewMixin from '/imports/ui/properties/treeNodeViews/treeNodeViewMixin.js';
|
||||||
|
import PROPERTIES from '/imports/constants/PROPERTIES.js';
|
||||||
|
import CoinValue from '/imports/ui/components/CoinValue.vue';
|
||||||
|
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue';
|
||||||
|
import stripFloatingPointOddities from '/imports/api/engine/computation/utility/stripFloatingPointOddities.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CoinValue,
|
||||||
|
PropertyDescription,
|
||||||
|
},
|
||||||
|
mixins: [treeNodeViewMixin],
|
||||||
|
inject: {
|
||||||
|
context: { default: {} }
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
preparingSpells: Boolean,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
incrementLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasClickListener() {
|
||||||
|
return this.$listeners && !!this.$listeners.click;
|
||||||
|
},
|
||||||
|
title() {
|
||||||
|
let model = this.model;
|
||||||
|
if (!model) return;
|
||||||
|
if (model.quantity !== 1) {
|
||||||
|
if (model.plural) {
|
||||||
|
return `${model.quantity} ${model.plural}`;
|
||||||
|
} else if (model.name) {
|
||||||
|
return `${model.quantity} ${model.name}`;
|
||||||
|
}
|
||||||
|
} else if (model.name) {
|
||||||
|
return model.name;
|
||||||
|
}
|
||||||
|
let prop = PROPERTIES[model.type]
|
||||||
|
return prop && prop.name;
|
||||||
|
},
|
||||||
|
totalValue() {
|
||||||
|
return stripFloatingPointOddities(this.model.value * this.model.quantity);
|
||||||
|
},
|
||||||
|
totalWeight() {
|
||||||
|
return stripFloatingPointOddities(this.model.weight * this.model.quantity);
|
||||||
|
},
|
||||||
|
attunementText() {
|
||||||
|
if (this.model.requiresAttunement) {
|
||||||
|
if (this.model.attuned) return 'Attuned';
|
||||||
|
return 'Requires attunement';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.item-avatar {
|
||||||
|
min-width: 32px;
|
||||||
|
}
|
||||||
|
.item .label {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
class="printed-skill pl-0 d-flex align-center"
|
||||||
|
>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<div
|
||||||
|
v-if="!hideModifier"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
<proficiency-icon
|
||||||
|
:value="model.proficiency"
|
||||||
|
class="prof-icon"
|
||||||
|
/>
|
||||||
|
<div class="prof-mod ml-2 mr-4 text-right">
|
||||||
|
{{ displayedModifier }}
|
||||||
|
</div>
|
||||||
|
<v-icon
|
||||||
|
v-if="model.advantage > 0"
|
||||||
|
size="20px"
|
||||||
|
>
|
||||||
|
mdi-chevron-double-up
|
||||||
|
</v-icon>
|
||||||
|
<v-icon
|
||||||
|
v-if="model.advantage < 0"
|
||||||
|
size="20px"
|
||||||
|
>
|
||||||
|
mdi-chevron-double-down
|
||||||
|
</v-icon>
|
||||||
|
</div>
|
||||||
|
<proficiency-icon
|
||||||
|
v-else
|
||||||
|
:value="model.proficiency"
|
||||||
|
class="prof-icon mr-2"
|
||||||
|
/>
|
||||||
|
<div class="text-truncate">
|
||||||
|
{{ model.name }}
|
||||||
|
<template v-if="model.conditionalBenefits && model.conditionalBenefits.length">
|
||||||
|
*
|
||||||
|
</template>
|
||||||
|
<template v-if="'passiveBonus' in model">
|
||||||
|
({{ passiveScore }})
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import ProficiencyIcon from '/imports/ui/properties/shared/ProficiencyIcon.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ProficiencyIcon,
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
context: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
hideModifier: Boolean,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
checkLoading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayedModifier() {
|
||||||
|
let mod = this.model.value;
|
||||||
|
if (this.model.fail) {
|
||||||
|
return 'fail';
|
||||||
|
} else {
|
||||||
|
return numberToSignedString(mod);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
passiveScore() {
|
||||||
|
return 10 + this.model.value + this.model.passiveBonus;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.printed-skill{
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prof-icon {
|
||||||
|
min-width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prof-mod {
|
||||||
|
min-width: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-icon.theme--light {
|
||||||
|
color: rgba(0, 0, 0, 0.7) !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<div
|
||||||
|
class="double-border"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="model.name"
|
||||||
|
class="label"
|
||||||
|
>
|
||||||
|
{{ model.name }}
|
||||||
|
</div>
|
||||||
|
<div v-if="model.level">
|
||||||
|
{{ levelText }} {{ model.school }} {{ model.ritual ? '(ritual)' : '' }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ model.school }} cantrip
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Casting Time: {{ model.castingTime }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Range: {{ model.range }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Components: {{ spellComponents }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Duration: {{ model.duration }}
|
||||||
|
</div>
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="model.summary"
|
||||||
|
/>
|
||||||
|
<v-divider class="my-2" />
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="model.description"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue';
|
||||||
|
|
||||||
|
const levelText = [
|
||||||
|
'cantrip', '1st-level', '2nd-level', '3rd-level', '4th-level', '5th-level',
|
||||||
|
'6th-level', '7th-level', '8th-level', '9th-level'
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
PropertyDescription,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
levelText() {
|
||||||
|
return levelText[this.model.level]
|
||||||
|
},
|
||||||
|
spellComponents() {
|
||||||
|
let components = [];
|
||||||
|
if (this.model.ritual) components.push('Ritual');
|
||||||
|
if (this.model.concentration) components.push('Concentration');
|
||||||
|
if (this.model.verbal) components.push('Verbal');
|
||||||
|
if (this.model.somatic) components.push('Somatic');
|
||||||
|
if (this.model.material) components.push(`Material (${this.model.material})`);
|
||||||
|
return components.join(', ');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.label {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<div class="octagon-border">
|
||||||
|
<div class="label text-center">
|
||||||
|
{{ model.name }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Spell Save DC: {{ model.dc && model.dc.value }}
|
||||||
|
</div>
|
||||||
|
<div v-if="model.ability">
|
||||||
|
Spell casting ability: {{ model.ability }}
|
||||||
|
</div>
|
||||||
|
<div v-if="model.ability">
|
||||||
|
Spell casting ability modifier: {{ model.abilityMod }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Spell Attack Bonus: {{ model.attackRollBonus && model.attackRollBonus.value }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Maximum prepared spells: {{ model.maxPrepared && model.maxPrepared.value }}
|
||||||
|
</div>
|
||||||
|
<property-description
|
||||||
|
text
|
||||||
|
:model="model.description"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import PropertyDescription from '/imports/ui/properties/viewers/shared/PropertyDescription.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
PropertyDescription,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -16,6 +16,14 @@
|
|||||||
flat
|
flat
|
||||||
@change="propertyHelpChanged"
|
@change="propertyHelpChanged"
|
||||||
/>
|
/>
|
||||||
|
<v-btn
|
||||||
|
v-if="tab === 1"
|
||||||
|
icon
|
||||||
|
data-id="help-button"
|
||||||
|
@click="helpDialog"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-help</v-icon>
|
||||||
|
</v-btn>
|
||||||
<text-field
|
<text-field
|
||||||
v-if="tab === 2"
|
v-if="tab === 2"
|
||||||
prepend-inner-icon="mdi-magnify"
|
prepend-inner-icon="mdi-magnify"
|
||||||
@@ -173,7 +181,7 @@
|
|||||||
<script lang="js">
|
<script lang="js">
|
||||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||||
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
import PROPERTIES, { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||||
import TreeNodeView from '/imports/ui/properties/treeNodeViews/TreeNodeView.vue';
|
import TreeNodeView from '/imports/ui/properties/treeNodeViews/TreeNodeView.vue';
|
||||||
import LibraryNodeExpansionContent from '/imports/ui/library/LibraryNodeExpansionContent.vue';
|
import LibraryNodeExpansionContent from '/imports/ui/library/LibraryNodeExpansionContent.vue';
|
||||||
import schemaFormMixin from '/imports/ui/properties/forms/shared/schemaFormMixin.js';
|
import schemaFormMixin from '/imports/ui/properties/forms/shared/schemaFormMixin.js';
|
||||||
@@ -235,7 +243,11 @@ export default {
|
|||||||
},
|
},
|
||||||
toolbarColor(){
|
toolbarColor(){
|
||||||
return getThemeColor('secondary');
|
return getThemeColor('secondary');
|
||||||
}
|
},
|
||||||
|
docsPath() {
|
||||||
|
const propDef = PROPERTIES[this.type];
|
||||||
|
return propDef && propDef.docsPath;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
type(newType){
|
type(newType){
|
||||||
@@ -259,6 +271,15 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
helpDialog() {
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'help-dialog',
|
||||||
|
elementId: 'help-button',
|
||||||
|
data: {
|
||||||
|
path: this.docsPath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
searchChanged(val, ack){
|
searchChanged(val, ack){
|
||||||
this._subs.searchLibraryNodes.setData('searchTerm', val);
|
this._subs.searchLibraryNodes.setData('searchTerm', val);
|
||||||
this._subs.searchLibraryNodes.setData('limit', undefined);
|
this._subs.searchLibraryNodes.setData('limit', undefined);
|
||||||
|
|||||||
@@ -12,6 +12,13 @@
|
|||||||
:value="model.color"
|
:value="model.color"
|
||||||
@input="value => change({path: ['color'], value})"
|
@input="value => change({path: ['color'], value})"
|
||||||
/>
|
/>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
data-id="help-button"
|
||||||
|
@click="helpDialog"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-help</v-icon>
|
||||||
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
<component
|
<component
|
||||||
:is="type"
|
:is="type"
|
||||||
@@ -44,6 +51,7 @@ import propertyFormIndex from '/imports/ui/properties/forms/shared/propertyFormI
|
|||||||
import schemaFormMixin from '/imports/ui/properties/forms/shared/schemaFormMixin.js';
|
import schemaFormMixin from '/imports/ui/properties/forms/shared/schemaFormMixin.js';
|
||||||
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
||||||
import propertySchemasIndex from '/imports/api/properties/propertySchemasIndex.js';
|
import propertySchemasIndex from '/imports/api/properties/propertySchemasIndex.js';
|
||||||
|
import PROPERTIES from '/imports/constants/PROPERTIES.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -77,6 +85,12 @@ export default {
|
|||||||
isLibraryForm: true,
|
isLibraryForm: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
docsPath() {
|
||||||
|
const propDef = PROPERTIES[this.type];
|
||||||
|
return propDef && propDef.docsPath;
|
||||||
|
},
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
type(newType) {
|
type(newType) {
|
||||||
if (!newType) return;
|
if (!newType) return;
|
||||||
@@ -87,6 +101,17 @@ export default {
|
|||||||
this.model = model;
|
this.model = model;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
helpDialog() {
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'help-dialog',
|
||||||
|
elementId: 'help-button',
|
||||||
|
data: {
|
||||||
|
path: this.docsPath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
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>
|
||||||
@@ -5,54 +5,19 @@
|
|||||||
@mouseover="hasClickListener ? hovering = true : undefined"
|
@mouseover="hasClickListener ? hovering = true : undefined"
|
||||||
@mouseleave="hasClickListener ? hovering = false : undefined"
|
@mouseleave="hasClickListener ? hovering = false : undefined"
|
||||||
>
|
>
|
||||||
<div class="layout align-center">
|
<attribute-card-content :model="model" />
|
||||||
<roll-popup
|
|
||||||
v-if="model.attributeType === 'modifier' || model.type === 'skill'"
|
|
||||||
button-class="px-0"
|
|
||||||
text
|
|
||||||
height="70"
|
|
||||||
min-width="72"
|
|
||||||
:roll-text="computedValue && computedValue.toString()"
|
|
||||||
:name="model.name"
|
|
||||||
:advantage="model.advantage"
|
|
||||||
:loading="checkLoading"
|
|
||||||
:disabled="!context.editPermission"
|
|
||||||
@roll="check"
|
|
||||||
>
|
|
||||||
<v-card-title class="value text-h4 flex-shrink-0">
|
|
||||||
{{ computedValue }}
|
|
||||||
</v-card-title>
|
|
||||||
</roll-popup>
|
|
||||||
<v-card-title
|
|
||||||
v-else
|
|
||||||
class="value text-h4 flex-shrink-0"
|
|
||||||
>
|
|
||||||
{{ computedValue }}
|
|
||||||
</v-card-title>
|
|
||||||
<v-card-title class="name text-subtitle-1 text-truncate d-block pl-0">
|
|
||||||
{{ model.name }}
|
|
||||||
</v-card-title>
|
|
||||||
</div>
|
|
||||||
<card-highlight :active="hasClickListener && hovering" />
|
<card-highlight :active="hasClickListener && hovering" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
|
||||||
import RollPopup from '/imports/ui/components/RollPopup.vue';
|
|
||||||
import doCheck from '/imports/api/engine/actions/doCheck.js';
|
|
||||||
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
|
||||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
import AttributeCardContent from '/imports/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
RollPopup,
|
|
||||||
CardHighlight,
|
CardHighlight,
|
||||||
},
|
AttributeCardContent,
|
||||||
inject: {
|
|
||||||
context: {
|
|
||||||
default: {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
model: {
|
model: {
|
||||||
@@ -68,41 +33,11 @@
|
|||||||
hasClickListener(){
|
hasClickListener(){
|
||||||
return this.$listeners && !!this.$listeners.click
|
return this.$listeners && !!this.$listeners.click
|
||||||
},
|
},
|
||||||
computedValue(){
|
|
||||||
if (this.model.attributeType === 'modifier' || this.model.type === 'skill'){
|
|
||||||
return numberToSignedString(this.model.value);
|
|
||||||
} else {
|
|
||||||
return this.model.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
signed: numberToSignedString,
|
|
||||||
click(e){
|
click(e){
|
||||||
this.$emit('click', e);
|
this.$emit('click', e);
|
||||||
},
|
},
|
||||||
check({advantage}){
|
|
||||||
this.checkLoading = true;
|
|
||||||
doCheck.call({
|
|
||||||
propId: this.model._id,
|
|
||||||
scope: {
|
|
||||||
$checkAdvantage: advantage,
|
|
||||||
},
|
|
||||||
}, error => {
|
|
||||||
this.checkLoading = false;
|
|
||||||
if (error){
|
|
||||||
console.error(error);
|
|
||||||
snackbar({text: error.reason});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
|
||||||
.value {
|
|
||||||
min-width: 72px;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="layout align-center"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@mouseover="$emit('mouseover')"
|
||||||
|
@mouseleave="$emit('mouseleave')"
|
||||||
|
>
|
||||||
|
<roll-popup
|
||||||
|
v-if="model.attributeType === 'modifier' || model.type === 'skill'"
|
||||||
|
button-class="px-0"
|
||||||
|
text
|
||||||
|
height="70"
|
||||||
|
min-width="72"
|
||||||
|
:roll-text="computedValue && computedValue.toString()"
|
||||||
|
:name="model.name"
|
||||||
|
:advantage="model.advantage"
|
||||||
|
:loading="checkLoading"
|
||||||
|
:disabled="!context.editPermission"
|
||||||
|
@roll="check"
|
||||||
|
>
|
||||||
|
<v-card-title class="value text-h4 flex-shrink-0">
|
||||||
|
{{ computedValue }}
|
||||||
|
</v-card-title>
|
||||||
|
</roll-popup>
|
||||||
|
<v-card-title
|
||||||
|
v-else
|
||||||
|
class="value text-h4 flex-shrink-0"
|
||||||
|
>
|
||||||
|
{{ computedValue }}
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-title class="name text-subtitle-1 text-truncate d-block pl-0">
|
||||||
|
{{ model.name }}
|
||||||
|
</v-card-title>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||||
|
import RollPopup from '/imports/ui/components/RollPopup.vue';
|
||||||
|
import doCheck from '/imports/api/engine/actions/doCheck.js';
|
||||||
|
import {snackbar} from '/imports/ui/components/snackbars/SnackbarQueue.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
RollPopup,
|
||||||
|
},
|
||||||
|
inject: {
|
||||||
|
context: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data(){return {
|
||||||
|
checkLoading: false,
|
||||||
|
hovering: false,
|
||||||
|
}},
|
||||||
|
computed: {
|
||||||
|
computedValue(){
|
||||||
|
if (this.model.attributeType === 'modifier' || this.model.type === 'skill'){
|
||||||
|
return numberToSignedString(this.model.value);
|
||||||
|
} else {
|
||||||
|
return this.model.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
signed: numberToSignedString,
|
||||||
|
check({advantage}){
|
||||||
|
this.checkLoading = true;
|
||||||
|
doCheck.call({
|
||||||
|
propId: this.model._id,
|
||||||
|
scope: {
|
||||||
|
$checkAdvantage: advantage,
|
||||||
|
},
|
||||||
|
}, error => {
|
||||||
|
this.checkLoading = false;
|
||||||
|
if (error){
|
||||||
|
console.error(error);
|
||||||
|
snackbar({text: error.reason});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.value {
|
||||||
|
min-width: 72px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
style="min-height: 42px;"
|
style="min-height: 42px;"
|
||||||
:class="{ hover }"
|
:class="{ hover }"
|
||||||
class="my-1 health-bar"
|
class="my-1 health-bar"
|
||||||
:data-id="_id"
|
:data-id="model._id"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="subheading text-truncate pa-2 name"
|
class="subheading text-truncate pa-2 name"
|
||||||
@@ -14,14 +14,10 @@
|
|||||||
@mouseleave="hover = false"
|
@mouseleave="hover = false"
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
>
|
>
|
||||||
{{ name }}
|
{{ model.name }}
|
||||||
</div>
|
</div>
|
||||||
<v-flex
|
<v-flex
|
||||||
style="
|
style="height: 24px; flex-basis: 300px; flex-grow: 100;"
|
||||||
height: 24px;
|
|
||||||
flex-basis: 300px;
|
|
||||||
flex-grow: 100;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
column
|
column
|
||||||
@@ -50,8 +46,7 @@
|
|||||||
'white--text': isTextLight,
|
'white--text': isTextLight,
|
||||||
'black--text': !isTextLight,
|
'black--text': !isTextLight,
|
||||||
}"
|
}"
|
||||||
style="
|
style="font-size: 15px;
|
||||||
font-size: 15px;
|
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -59,30 +54,30 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
text-align: center;
|
text-align: center;"
|
||||||
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ value }} / {{ maxValue }}
|
{{ model.value }} / {{ model.total }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition name="transition">
|
<v-menu
|
||||||
|
v-model="editing"
|
||||||
|
absolute
|
||||||
|
transition="scale-transition"
|
||||||
|
origin="center center"
|
||||||
|
content-class="no-menu-shadow"
|
||||||
|
:position-x="x"
|
||||||
|
:position-y="y"
|
||||||
|
:min-width="305"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
>
|
||||||
<increment-menu
|
<increment-menu
|
||||||
v-show="editing"
|
:value="model.value"
|
||||||
:value="value"
|
|
||||||
:open="editing"
|
:open="editing"
|
||||||
@change="changeIncrementMenu"
|
@change="changeIncrementMenu"
|
||||||
@close="cancelEdit"
|
@close="cancelEdit"
|
||||||
/>
|
/>
|
||||||
</transition>
|
</v-menu>
|
||||||
<transition name="background-transition">
|
|
||||||
<div
|
|
||||||
v-if="editing"
|
|
||||||
class="page-tint"
|
|
||||||
@click="cancelEdit"
|
|
||||||
/>
|
|
||||||
</transition>
|
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
@@ -104,31 +99,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
model: {
|
||||||
type: Number,
|
type: Object,
|
||||||
default: undefined,
|
required: true,
|
||||||
},
|
|
||||||
maxValue: {
|
|
||||||
type: Number,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default() {
|
|
||||||
return this.$vuetify.theme.currentTheme.primary
|
|
||||||
},
|
|
||||||
},
|
|
||||||
midColor: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
lowColor: {
|
|
||||||
type: String,
|
|
||||||
default: undefined,
|
|
||||||
},
|
},
|
||||||
_id: String,
|
_id: String,
|
||||||
},
|
},
|
||||||
@@ -136,24 +109,29 @@ export default {
|
|||||||
return {
|
return {
|
||||||
editing: false,
|
editing: false,
|
||||||
hover: false,
|
hover: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fillFraction() {
|
fillFraction() {
|
||||||
let fraction = this.value / this.maxValue;
|
let fraction = this.model.value / this.model.total;
|
||||||
if (fraction < 0) fraction = 0;
|
if (fraction < 0) fraction = 0;
|
||||||
if (fraction > 1) fraction = 1;
|
if (fraction > 1) fraction = 1;
|
||||||
return fraction;
|
return fraction;
|
||||||
},
|
},
|
||||||
|
color() {
|
||||||
|
return this.model.color || this.$vuetify.theme.currentTheme.primary
|
||||||
|
},
|
||||||
barColor() {
|
barColor() {
|
||||||
const fraction = this.value / this.maxValue;
|
const fraction = this.model.value / this.model.total;
|
||||||
if (!Number.isFinite(fraction)) return this.color;
|
if (!Number.isFinite(fraction)) return this.color;
|
||||||
if (fraction > 0.5) {
|
if (fraction > 0.5) {
|
||||||
return this.color;
|
return this.color;
|
||||||
} else if (this.midColor && this.lowColor) {
|
} else if (this.model.healthBarColorMid && this.model.healthBarColorLow) {
|
||||||
return chroma.mix(this.lowColor, this.midColor, fraction * 2).hex();
|
return chroma.mix(this.model.healthBarColorLow, this.model.healthBarColorMid, fraction * 2).hex();
|
||||||
} else if (this.midColor) {
|
} else if (this.model.healthBarColorMid) {
|
||||||
return this.midColor;
|
return this.model.healthBarColorMid;
|
||||||
}
|
}
|
||||||
return this.color;
|
return this.color;
|
||||||
},
|
},
|
||||||
@@ -166,7 +144,7 @@ export default {
|
|||||||
isTextLight() {
|
isTextLight() {
|
||||||
return isDarkColor(this.barBackgroundColor);
|
return isDarkColor(this.barBackgroundColor);
|
||||||
/* Change color at the halfway mark
|
/* Change color at the halfway mark
|
||||||
const fraction = this.value / this.maxValue;
|
const fraction = this.model.value / this.model.total;
|
||||||
if (fraction >= 0.5){
|
if (fraction >= 0.5){
|
||||||
return isDarkColor(this.barColor);
|
return isDarkColor(this.barColor);
|
||||||
} else {
|
} else {
|
||||||
@@ -176,8 +154,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
edit() {
|
edit(e) {
|
||||||
this.editing = true;
|
e.preventDefault()
|
||||||
|
this.editing = false;
|
||||||
|
this.x = e.clientX - 165;
|
||||||
|
this.y = e.clientY - 24;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.editing = true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
cancelEdit() {
|
cancelEdit() {
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
@@ -199,6 +183,10 @@ export default {
|
|||||||
z-index: 7;
|
z-index: 7;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-menu-shadow {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -3,13 +3,7 @@
|
|||||||
<health-bar
|
<health-bar
|
||||||
v-for="attribute in attributes"
|
v-for="attribute in attributes"
|
||||||
:key="attribute._id"
|
:key="attribute._id"
|
||||||
:value="attribute.value"
|
:model="attribute"
|
||||||
:max-value="attribute.total"
|
|
||||||
:name="attribute.name"
|
|
||||||
:color="attribute.color"
|
|
||||||
:mid-color="attribute.healthBarColorMid"
|
|
||||||
:low-color="attribute.healthBarColorLow"
|
|
||||||
:_id="attribute._id"
|
|
||||||
@change="e => $emit('change', {_id: attribute._id, change: e})"
|
@change="e => $emit('change', {_id: attribute._id, change: e})"
|
||||||
@click="e => $emit('click', {_id: attribute._id})"
|
@click="e => $emit('click', {_id: attribute._id})"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,57 +3,26 @@
|
|||||||
class="resource-card"
|
class="resource-card"
|
||||||
:class="hover ? 'elevation-8': ''"
|
:class="hover ? 'elevation-8': ''"
|
||||||
>
|
>
|
||||||
<v-layout>
|
<resource-card-content
|
||||||
<div class="buttons layout column justify-center pl-3">
|
:model="model"
|
||||||
<v-btn
|
:hover="hover"
|
||||||
icon
|
@mouseover="hover = true"
|
||||||
small
|
@mouseleave="hover = false"
|
||||||
:disabled="(model.value >= model.total && !model.ignoreUpperLimit) || context.editPermission === false"
|
@click="$emit('click')"
|
||||||
@click="increment(1)"
|
@change="e => $emit('change', e)"
|
||||||
>
|
/>
|
||||||
<v-icon>mdi-chevron-up</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
icon
|
|
||||||
small
|
|
||||||
:disabled="(model.value <= 0 && !model.ignoreLowerLimit) || context.editPermission === false"
|
|
||||||
@click="increment(-1)"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-chevron-down</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
</div>
|
|
||||||
<div class="layout align-center value pl-2 pr-3">
|
|
||||||
<div class="text-h4">
|
|
||||||
{{ model.value }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="model.total !== 0"
|
|
||||||
class="text-h6 ml-2 max-value"
|
|
||||||
>
|
|
||||||
/{{ model.total }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="content layout align-center pr-3"
|
|
||||||
@click="click"
|
|
||||||
@mouseover="hover = true"
|
|
||||||
@mouseleave="hover = false"
|
|
||||||
>
|
|
||||||
<div class="text-truncate ">
|
|
||||||
{{ model.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-layout>
|
|
||||||
<card-highlight :active="hover" />
|
<card-highlight :active="hover" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
import ResourceCardContent from '/imports/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
CardHighlight,
|
CardHighlight,
|
||||||
|
ResourceCardContent,
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
context: { default: {} }
|
context: { default: {} }
|
||||||
@@ -69,46 +38,16 @@ export default {
|
|||||||
hover: false,
|
hover: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
click(e) {
|
|
||||||
this.$emit('click', e);
|
|
||||||
},
|
|
||||||
increment(value) {
|
|
||||||
this.$emit('change', { type: 'increment', value })
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css">
|
||||||
.resource-card {
|
.resource-card {
|
||||||
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
transition: box-shadow .4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource-card>div {
|
.resource-card > div {
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons,
|
|
||||||
.value {
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons>.v-btn {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.max-value {
|
|
||||||
color: rgba(0, 0, 0, .54);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme--dark .max-value {
|
|
||||||
color: rgba(255, 255, 255, 0.54);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<v-layout>
|
||||||
|
<div class="buttons layout column justify-center pl-3">
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
small
|
||||||
|
:disabled="(model.value >= model.total && !model.ignoreUpperLimit) || context.editPermission === false"
|
||||||
|
@click="increment(1)"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-chevron-up</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
small
|
||||||
|
:disabled="(model.value <= 0 && !model.ignoreLowerLimit) || context.editPermission === false"
|
||||||
|
@click="increment(-1)"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
<div class="layout align-center value pl-2 pr-3">
|
||||||
|
<div class="text-h4">
|
||||||
|
{{ model.value }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="model.total !== 0"
|
||||||
|
class="text-h6 ml-2 max-value"
|
||||||
|
>
|
||||||
|
/{{ model.total }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="content layout align-center pr-3"
|
||||||
|
@click="click"
|
||||||
|
@mouseover="$emit('mouseover')"
|
||||||
|
@mouseleave="$emit('mouseleave')"
|
||||||
|
>
|
||||||
|
<div class="text-truncate ">
|
||||||
|
{{ model.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: {
|
||||||
|
context: { default: {} }
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
hover: {
|
||||||
|
type: Boolean,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
click(e) {
|
||||||
|
this.$emit('click', e);
|
||||||
|
},
|
||||||
|
increment(value) {
|
||||||
|
this.$emit('change', { type: 'increment', value })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.buttons,
|
||||||
|
.value {
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
.buttons>.v-btn {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.max-value {
|
||||||
|
color: rgba(0, 0, 0, .54);
|
||||||
|
}
|
||||||
|
.theme--dark .max-value {
|
||||||
|
color: rgba(255, 255, 255, 0.54);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -61,7 +61,6 @@ export default {
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
dark: Boolean,
|
dark: Boolean,
|
||||||
hideCastButton: Boolean,
|
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
30
app/imports/ui/properties/components/buffs/BuffListItem.vue
Normal file
30
app/imports/ui/properties/components/buffs/BuffListItem.vue
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<v-list-item
|
||||||
|
@click="$emit('click')"
|
||||||
|
>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ model.name }}
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
<v-list-item-action v-if="!model.hideRemoveButton">
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
@click.stop="$emit('remove')"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-delete</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-item-action>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="model.name || (properties && properties.length)"
|
||||||
|
>
|
||||||
|
<v-card
|
||||||
|
class="folder-group-card pb-2"
|
||||||
|
>
|
||||||
|
<v-subheader v-if="model.name">
|
||||||
|
{{ model.name }}
|
||||||
|
</v-subheader>
|
||||||
|
<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})"
|
||||||
|
@sub-click="_id => $emit('sub-click', _id)"
|
||||||
|
@remove="$emit('remove', prop._id)"
|
||||||
|
/>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import propComponents from '/imports/ui/properties/components/folders/propertyComponentIndex.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
...propComponents,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inactive: { $ne: true }
|
||||||
|
},
|
||||||
|
],
|
||||||
|
$nor: [
|
||||||
|
{ hideWhenTotalZero: true, total: 0 },
|
||||||
|
{ hideWhenValueZero: true, value: 0 },
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
sort: { order: 1 },
|
||||||
|
}).forEach(prop => {
|
||||||
|
if (this.$options.components[prop.type]) {
|
||||||
|
props.push(prop);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return props;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.folder-group-card .v-card {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.folder-group-card .drag-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="model.actionType === 'event'"
|
||||||
|
class="d-flex justify-center"
|
||||||
|
>
|
||||||
|
<event-button
|
||||||
|
class="ma-1"
|
||||||
|
:model="model"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<action-card
|
||||||
|
v-else
|
||||||
|
:model="model"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@sub-click="_id => $emit('sub-click', _id)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import ActionCard from '/imports/ui/properties/components/actions/ActionCard.vue';
|
||||||
|
import EventButton from '/imports/ui/properties/components/actions/EventButton.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ActionCard,
|
||||||
|
EventButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="attribute">
|
||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js">
|
||||||
|
import AbilityListTile from '/imports/ui/properties/components/attributes/AbilityListTile.vue';
|
||||||
|
import HitDiceListTile from '/imports/ui/properties/components/attributes/HitDiceListTile.vue';
|
||||||
|
import HealthBar from '/imports/ui/properties/components/attributes/HealthBar.vue';
|
||||||
|
import SpellSlotListTile from '/imports/ui/properties/components/attributes/SpellSlotListTile.vue';
|
||||||
|
import ResourceCardContent from '/imports/ui/properties/components/attributes/ResourceCardContent.vue';
|
||||||
|
import AttributeCardContent from '/imports/ui/properties/components/attributes/AttributeCardContent.vue';
|
||||||
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
|
||||||
|
import damageProperty from '/imports/api/creature/creatureProperties/methods/damageProperty.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AbilityListTile,
|
||||||
|
HitDiceListTile,
|
||||||
|
HealthBar,
|
||||||
|
SpellSlotListTile,
|
||||||
|
ResourceCardContent,
|
||||||
|
AttributeCardContent,
|
||||||
|
CardHighlight,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hover: false,
|
||||||
|
}},
|
||||||
|
methods: {
|
||||||
|
damageProperty(change) {
|
||||||
|
damageProperty.call({
|
||||||
|
_id: this.model._id,
|
||||||
|
operation: change.type,
|
||||||
|
value: change.value
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.attribute {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import action from '/imports/ui/properties/components/folders/folderGroupComponents/ActionGroupComponent.vue';
|
||||||
|
//import adjustment from '';
|
||||||
|
import attribute from './folderGroupComponents/AttributeGroupComponent.vue';
|
||||||
|
import buff from '/imports/ui/properties/components/buffs/BuffListItem.vue';
|
||||||
|
//import buffRemover from '';
|
||||||
|
//import branch from '';
|
||||||
|
//import constant from '';
|
||||||
|
import container from '/imports/ui/properties/components/inventory/ContainerCard.vue';
|
||||||
|
//import classComponent from '';
|
||||||
|
//import classLevel from '';
|
||||||
|
//import damage from '';
|
||||||
|
//import damageMultiplier from '';
|
||||||
|
//import effect from '';
|
||||||
|
import feature from '/imports/ui/properties/components/features/FeatureCard.vue';
|
||||||
|
// import folder from '';
|
||||||
|
import item from '/imports/ui/properties/components/inventory/ItemListTile.vue';
|
||||||
|
import note from '/imports/ui/properties/components/persona/NoteCard.vue';
|
||||||
|
//import pointBuy from '';
|
||||||
|
//import proficiency from '';
|
||||||
|
//import propertySlot from '';
|
||||||
|
//import reference from '';
|
||||||
|
//import roll from '';
|
||||||
|
//import savingThrow from '';
|
||||||
|
import skill from '/imports/ui/properties/components/skills/SkillListTile.vue';
|
||||||
|
//import slotFiller from '';
|
||||||
|
//import spellList from '';
|
||||||
|
//import spell from '';
|
||||||
|
import toggle from '/imports/ui/properties/components/toggles/ToggleCard.vue';
|
||||||
|
//import trigger from '';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
action,
|
||||||
|
//adjustment,
|
||||||
|
attribute,
|
||||||
|
buff,
|
||||||
|
//buffRemover,
|
||||||
|
//branch,
|
||||||
|
//constant,
|
||||||
|
container,
|
||||||
|
//class: classComponent,
|
||||||
|
//classLevel,
|
||||||
|
//damage,
|
||||||
|
//damageMultiplier,
|
||||||
|
//effect,
|
||||||
|
feature,
|
||||||
|
//folder,
|
||||||
|
item,
|
||||||
|
note,
|
||||||
|
//pointBuy,
|
||||||
|
//proficiency,
|
||||||
|
//propertySlot,
|
||||||
|
//reference,
|
||||||
|
//roll,
|
||||||
|
//savingThrow,
|
||||||
|
skill,
|
||||||
|
//slotFiller,
|
||||||
|
//spellList,
|
||||||
|
//spell,
|
||||||
|
toggle,
|
||||||
|
//trigger,
|
||||||
|
};
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
@change="changeQuantity"
|
@change="changeQuantity"
|
||||||
/>
|
/>
|
||||||
</v-list-item-action>
|
</v-list-item-action>
|
||||||
<v-list-item-action>
|
<v-list-item-action class="drag-handle">
|
||||||
<v-icon
|
<v-icon
|
||||||
:disabled="context.editPermission === false"
|
:disabled="context.editPermission === false"
|
||||||
style="height: 100%; width: 40px; cursor: move;"
|
style="height: 100%; width: 40px; cursor: move;"
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<v-card
|
<v-card
|
||||||
:hover="hasClickListener"
|
:class="hover ? 'elevation-8': ''"
|
||||||
@click="click"
|
@click="click"
|
||||||
|
@mouseover="hover = true"
|
||||||
|
@mouseleave="hover = false"
|
||||||
>
|
>
|
||||||
<div class="layout align-center">
|
<div class="layout align-center">
|
||||||
<div
|
<div
|
||||||
@@ -18,19 +20,29 @@
|
|||||||
{{ model.name }}
|
{{ model.name }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
</div>
|
</div>
|
||||||
|
<card-highlight :active="hover" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import flipToggle from '/imports/api/creature/creatureProperties/methods/flipToggle.js';
|
import flipToggle from '/imports/api/creature/creatureProperties/methods/flipToggle.js';
|
||||||
|
import CardHighlight from '/imports/ui/components/CardHighlight.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
CardHighlight,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
model: {
|
model: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hover: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hasClickListener(){
|
hasClickListener(){
|
||||||
return this.$listeners && !!this.$listeners.click
|
return this.$listeners && !!this.$listeners.click
|
||||||
|
|||||||
@@ -41,6 +41,17 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</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-slide-x-transition mode="out-in">
|
||||||
<v-switch
|
<v-switch
|
||||||
v-if="!isAttack"
|
v-if="!isAttack"
|
||||||
@@ -154,15 +165,10 @@
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<smart-select
|
<reset-selector
|
||||||
label="Reset"
|
|
||||||
clearable
|
|
||||||
hint="When number of uses used should be reset to zero"
|
hint="When number of uses used should be reset to zero"
|
||||||
style="flex-basis: 300px;"
|
|
||||||
:items="resetOptions"
|
|
||||||
:value="model.reset"
|
:value="model.reset"
|
||||||
:error-messages="errors.reset"
|
:error-messages="errors.reset"
|
||||||
:menu-props="{auto: true, lazy: true}"
|
|
||||||
@change="change('reset', ...arguments)"
|
@change="change('reset', ...arguments)"
|
||||||
/>
|
/>
|
||||||
</form-section>
|
</form-section>
|
||||||
@@ -171,77 +177,74 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
||||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||||
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
||||||
|
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ResourcesForm,
|
ResourcesForm,
|
||||||
IconColorMenu,
|
IconColorMenu,
|
||||||
},
|
ResetSelector,
|
||||||
mixins: [propertyFormMixin],
|
},
|
||||||
data(){
|
mixins: [propertyFormMixin],
|
||||||
let data = {
|
data(){
|
||||||
actionTypes: [
|
let data = {
|
||||||
{
|
actionTypes: [
|
||||||
text: 'Action',
|
{
|
||||||
value: 'action',
|
text: 'Action',
|
||||||
}, {
|
value: 'action',
|
||||||
text: 'Bonus action',
|
}, {
|
||||||
value: 'bonus',
|
text: 'Bonus action',
|
||||||
}, {
|
value: 'bonus',
|
||||||
text: 'Attack action',
|
}, {
|
||||||
value: 'attack',
|
text: 'Attack action',
|
||||||
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
|
value: 'attack',
|
||||||
}, {
|
help: 'Attack actions replace a single attack when you choose to use your Action to attack',
|
||||||
text: 'Reaction',
|
}, {
|
||||||
value: 'reaction',
|
text: 'Reaction',
|
||||||
}, {
|
value: 'reaction',
|
||||||
text: 'Free action',
|
}, {
|
||||||
value: 'free',
|
text: 'Free action',
|
||||||
help: 'You can take one free action on your turn without using an action or bonus 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',
|
text: 'Long action',
|
||||||
help: 'Long actions take longer than one turn to complete'
|
value: 'long',
|
||||||
},
|
help: 'Long actions take longer than one turn to complete'
|
||||||
],
|
}, {
|
||||||
targetOptions: [
|
text: 'Event',
|
||||||
{
|
value: 'event',
|
||||||
text: 'Self',
|
help: 'Events are actions that happen to the character like rests or dawn'
|
||||||
value: 'self',
|
},
|
||||||
}, {
|
],
|
||||||
text: 'Single target',
|
targetOptions: [
|
||||||
value: 'singleTarget',
|
{
|
||||||
}, {
|
text: 'Self',
|
||||||
text: 'Multiple targets',
|
value: 'self',
|
||||||
value: 'multipleTargets',
|
}, {
|
||||||
},
|
text: 'Single target',
|
||||||
],
|
value: 'singleTarget',
|
||||||
resetOptions: [
|
}, {
|
||||||
{
|
text: 'Multiple targets',
|
||||||
text: 'Short rest',
|
value: 'multipleTargets',
|
||||||
value: 'shortRest',
|
},
|
||||||
}, {
|
],
|
||||||
text: 'Long rest',
|
attackSwitch: false,
|
||||||
value: 'longRest',
|
};
|
||||||
}
|
data.actionTypeHints = {};
|
||||||
],
|
data.actionTypes.forEach(type => {
|
||||||
attackSwitch: false,
|
data.actionTypeHints[type.value] = type.help;
|
||||||
};
|
});
|
||||||
data.actionTypeHints = {};
|
return data;
|
||||||
data.actionTypes.forEach(type => {
|
},
|
||||||
data.actionTypeHints[type.value] = type.help;
|
computed: {
|
||||||
});
|
isAttack(){
|
||||||
return data;
|
return this.attackSwitch || !!this.model.attackRoll?.calculation
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isAttack(){
|
|
||||||
return this.attackSwitch || !!this.model.attackRoll?.calculation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
|||||||
@@ -250,16 +250,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout wrap">
|
<div class="layout wrap">
|
||||||
<smart-select
|
<reset-selector
|
||||||
v-if="model.attributeType !== 'hitDice'"
|
v-if="model.attributeType !== 'hitDice'"
|
||||||
label="Reset"
|
|
||||||
clearable
|
|
||||||
style="flex-basis: 300px;"
|
|
||||||
hint="When damage should be reset to zero"
|
hint="When damage should be reset to zero"
|
||||||
:items="resetOptions"
|
|
||||||
:value="model.reset"
|
:value="model.reset"
|
||||||
:error-messages="errors.reset"
|
:error-messages="errors.reset"
|
||||||
:menu-props="{auto: true, lazy: true}"
|
|
||||||
@change="change('reset', ...arguments)"
|
@change="change('reset', ...arguments)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</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 FormSections from '/imports/ui/properties/forms/shared/FormSections.vue';
|
||||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||||
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
import ColorPicker from '/imports/ui/components/ColorPicker.vue';
|
||||||
|
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
FormSection,
|
FormSection,
|
||||||
FormSections,
|
FormSections,
|
||||||
ColorPicker,
|
ColorPicker,
|
||||||
|
ResetSelector,
|
||||||
},
|
},
|
||||||
mixins: [propertyFormMixin],
|
mixins: [propertyFormMixin],
|
||||||
inject: {
|
inject: {
|
||||||
|
|||||||
@@ -26,6 +26,12 @@
|
|||||||
:value="model.tags"
|
:value="model.tags"
|
||||||
@change="change('tags', ...arguments)"
|
@change="change('tags', ...arguments)"
|
||||||
/>
|
/>
|
||||||
|
<smart-switch
|
||||||
|
label="Group children on stats tab"
|
||||||
|
:value="model.groupStats"
|
||||||
|
:error-messages="errors.groupStats"
|
||||||
|
@change="change('groupStats', ...arguments)"
|
||||||
|
/>
|
||||||
</form-section>
|
</form-section>
|
||||||
</form-sections>
|
</form-sections>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -278,15 +278,10 @@
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<smart-select
|
<reset-selector
|
||||||
label="Reset"
|
|
||||||
clearable
|
|
||||||
hint="When number of uses used should be reset to zero"
|
hint="When number of uses used should be reset to zero"
|
||||||
style="flex-basis: 300px;"
|
|
||||||
:items="resetOptions"
|
|
||||||
:value="model.reset"
|
:value="model.reset"
|
||||||
:error-messages="errors.reset"
|
:error-messages="errors.reset"
|
||||||
:menu-props="{auto: true, lazy: true}"
|
|
||||||
@change="change('reset', ...arguments)"
|
@change="change('reset', ...arguments)"
|
||||||
/>
|
/>
|
||||||
</form-section>
|
</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 propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||||
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
import IconColorMenu from '/imports/ui/properties/forms/shared/IconColorMenu.vue';
|
||||||
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
import ResourcesForm from '/imports/ui/properties/forms/ResourcesForm.vue';
|
||||||
|
import ResetSelector from '/imports/ui/components/ResetSelector.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -325,6 +321,7 @@ export default {
|
|||||||
FormSection,
|
FormSection,
|
||||||
IconColorMenu,
|
IconColorMenu,
|
||||||
ResourcesForm,
|
ResourcesForm,
|
||||||
|
ResetSelector,
|
||||||
},
|
},
|
||||||
mixins: [propertyFormMixin],
|
mixins: [propertyFormMixin],
|
||||||
data() {
|
data() {
|
||||||
@@ -401,15 +398,6 @@ export default {
|
|||||||
value: 'multipleTargets',
|
value: 'multipleTargets',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
resetOptions: [
|
|
||||||
{
|
|
||||||
text: 'Short rest',
|
|
||||||
value: 'shortRest',
|
|
||||||
}, {
|
|
||||||
text: 'Long rest',
|
|
||||||
value: 'longRest',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
attackSwitch: false,
|
attackSwitch: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,6 +27,15 @@
|
|||||||
$emit('change', {path: ['maxPrepared', ...path], value, ack})"
|
$emit('change', {path: ['maxPrepared', ...path], value, ack})"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<smart-combobox
|
||||||
|
label="Spellcasting ability"
|
||||||
|
:value="model.ability"
|
||||||
|
hint="Which ability is used to cast spells in this spell list"
|
||||||
|
:items="abilityScoreList"
|
||||||
|
:error-messages="errors.ability"
|
||||||
|
@change="changeAbility"
|
||||||
|
/>
|
||||||
|
|
||||||
<computed-field
|
<computed-field
|
||||||
label="Spell save DC"
|
label="Spell save DC"
|
||||||
hint="The spell save DC of spells in this list"
|
hint="The spell save DC of spells in this list"
|
||||||
@@ -67,9 +76,46 @@
|
|||||||
|
|
||||||
<script lang="js">
|
<script lang="js">
|
||||||
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
import propertyFormMixin from '/imports/ui/properties/forms/shared/propertyFormMixin.js';
|
||||||
|
import createListOfProperties from '/imports/ui/properties/forms/shared/lists/createListOfProperties.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [propertyFormMixin],
|
mixins: [propertyFormMixin],
|
||||||
|
meteor: {
|
||||||
|
abilityScoreList() {
|
||||||
|
return createListOfProperties({
|
||||||
|
type: 'attribute',
|
||||||
|
attributeType: 'ability',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeAbility(value, ack) {
|
||||||
|
this.$emit('change', { path: ['ability'], value, ack })
|
||||||
|
const oldValue = this.model.ability;
|
||||||
|
|
||||||
|
const attackRollBonus = this.model.attackRollBonus?.calculation;
|
||||||
|
if (
|
||||||
|
!attackRollBonus ||
|
||||||
|
attackRollBonus === `proficiencyBonus + ${oldValue}.modifier`
|
||||||
|
) {
|
||||||
|
this.$emit('change', {
|
||||||
|
path: ['attackRollBonus', 'calculation'],
|
||||||
|
value: `proficiencyBonus + ${value}.modifier`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const dc = this.model.dc?.calculation;
|
||||||
|
if (
|
||||||
|
!dc ||
|
||||||
|
dc === `8 + proficiencyBonus + ${oldValue}.modifier`
|
||||||
|
) {
|
||||||
|
this.$emit('change', {
|
||||||
|
path: ['dc', 'calculation'],
|
||||||
|
value: `8 + proficiencyBonus + ${value}.modifier`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||||
|
|
||||||
export default function createListOfProperties(filter = {}){
|
export default function createListOfProperties(filter = {}, getNamesWithValues) {
|
||||||
filter.removed = {$ne: true};
|
filter.removed = { $ne: true };
|
||||||
let propertyList = [];
|
let propertyList = [];
|
||||||
let variableNames = new Set();
|
let variableNames = new Set();
|
||||||
function addUniquePropertys(property){
|
function addUniquePropertys(property) {
|
||||||
if (property.variableName && !variableNames.has(property.variableName)){
|
if (property.variableName && !variableNames.has(property.variableName)) {
|
||||||
variableNames.add(property.variableName);
|
variableNames.add(property.variableName);
|
||||||
propertyList.push({
|
propertyList.push({
|
||||||
text: property.name || property.variableName,
|
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);
|
CreatureProperties.find(filter, options).forEach(addUniquePropertys);
|
||||||
LibraryNodes.find(filter, options).forEach(addUniquePropertys);
|
LibraryNodes.find(filter, options).forEach(addUniquePropertys);
|
||||||
|
if (getNamesWithValues) return propertyList;
|
||||||
return Array.from(variableNames);
|
return Array.from(variableNames);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
const ActionForm = () => import('/imports/ui/properties/forms/ActionForm.vue');
|
import ActionForm from '/imports/ui/properties/forms/ActionForm.vue';
|
||||||
const AdjustmentForm = () => import('/imports/ui/properties/forms/AdjustmentForm.vue');
|
import AdjustmentForm from '/imports/ui/properties/forms/AdjustmentForm.vue';
|
||||||
const AttributeForm = () => import('/imports/ui/properties/forms/AttributeForm.vue');
|
import AttributeForm from '/imports/ui/properties/forms/AttributeForm.vue';
|
||||||
const BuffForm = () => import('/imports/ui/properties/forms/BuffForm.vue');
|
import BuffForm from '/imports/ui/properties/forms/BuffForm.vue';
|
||||||
const BuffRemoverForm = () => import('/imports/ui/properties/forms/BuffRemoverForm.vue');
|
import BuffRemoverForm from '/imports/ui/properties/forms/BuffRemoverForm.vue';
|
||||||
const BranchForm = () => import('/imports/ui/properties/forms/BranchForm.vue');
|
import BranchForm from '/imports/ui/properties/forms/BranchForm.vue';
|
||||||
const ClassForm = () => import('/imports/ui/properties/forms/ClassForm.vue');
|
import ClassForm from '/imports/ui/properties/forms/ClassForm.vue';
|
||||||
const ClassLevelForm = () => import('/imports/ui/properties/forms/ClassLevelForm.vue');
|
import ClassLevelForm from '/imports/ui/properties/forms/ClassLevelForm.vue';
|
||||||
const ConstantForm = () => import('/imports/ui/properties/forms/ConstantForm.vue');
|
import ConstantForm from '/imports/ui/properties/forms/ConstantForm.vue';
|
||||||
const ContainerForm = () => import('/imports/ui/properties/forms/ContainerForm.vue');
|
import ContainerForm from '/imports/ui/properties/forms/ContainerForm.vue';
|
||||||
const DamageForm = () => import('/imports/ui/properties/forms/DamageForm.vue');
|
import DamageForm from '/imports/ui/properties/forms/DamageForm.vue';
|
||||||
const DamageMultiplierForm = () => import('/imports/ui/properties/forms/DamageMultiplierForm.vue');
|
import DamageMultiplierForm from '/imports/ui/properties/forms/DamageMultiplierForm.vue';
|
||||||
const EffectForm = () => import('/imports/ui/properties/forms/EffectForm.vue');
|
import EffectForm from '/imports/ui/properties/forms/EffectForm.vue';
|
||||||
const FeatureForm = () => import('/imports/ui/properties/forms/FeatureForm.vue');
|
import FeatureForm from '/imports/ui/properties/forms/FeatureForm.vue';
|
||||||
const FolderForm = () => import('/imports/ui/properties/forms/FolderForm.vue');
|
import FolderForm from '/imports/ui/properties/forms/FolderForm.vue';
|
||||||
const ItemForm = () => import('/imports/ui/properties/forms/ItemForm.vue');
|
import ItemForm from '/imports/ui/properties/forms/ItemForm.vue';
|
||||||
const NoteForm = () => import('/imports/ui/properties/forms/NoteForm.vue');
|
import NoteForm from '/imports/ui/properties/forms/NoteForm.vue';
|
||||||
const PointBuyForm = () => import('/imports/ui/properties/forms/PointBuyForm.vue');
|
import PointBuyForm from '/imports/ui/properties/forms/PointBuyForm.vue';
|
||||||
const ProficiencyForm = () => import('/imports/ui/properties/forms/ProficiencyForm.vue');
|
import ProficiencyForm from '/imports/ui/properties/forms/ProficiencyForm.vue';
|
||||||
const ReferenceForm = () => import('/imports/ui/properties/forms/ReferenceForm.vue');
|
import ReferenceForm from '/imports/ui/properties/forms/ReferenceForm.vue';
|
||||||
const RollForm = () => import('/imports/ui/properties/forms/RollForm.vue');
|
import RollForm from '/imports/ui/properties/forms/RollForm.vue';
|
||||||
const SavingThrowForm = () => import('/imports/ui/properties/forms/SavingThrowForm.vue');
|
import SavingThrowForm from '/imports/ui/properties/forms/SavingThrowForm.vue';
|
||||||
const SkillForm = () => import('/imports/ui/properties/forms/SkillForm.vue');
|
import SkillForm from '/imports/ui/properties/forms/SkillForm.vue';
|
||||||
const SlotForm = () => import('/imports/ui/properties/forms/SlotForm.vue');
|
import SlotForm from '/imports/ui/properties/forms/SlotForm.vue';
|
||||||
const SlotFillerForm = () => import('/imports/ui/properties/forms/SlotFillerForm.vue');
|
import SlotFillerForm from '/imports/ui/properties/forms/SlotFillerForm.vue';
|
||||||
const SpellListForm = () => import('/imports/ui/properties/forms/SpellListForm.vue');
|
import SpellListForm from '/imports/ui/properties/forms/SpellListForm.vue';
|
||||||
const SpellForm = () => import('/imports/ui/properties/forms/SpellForm.vue');
|
import SpellForm from '/imports/ui/properties/forms/SpellForm.vue';
|
||||||
const ToggleForm = () => import('/imports/ui/properties/forms/ToggleForm.vue');
|
import ToggleForm from '/imports/ui/properties/forms/ToggleForm.vue';
|
||||||
const TriggerForm = () => import('/imports/ui/properties/forms/TriggerForm.vue');
|
import TriggerForm from '/imports/ui/properties/forms/TriggerForm.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
action: ActionForm,
|
action: ActionForm,
|
||||||
|
|||||||
@@ -13,6 +13,18 @@
|
|||||||
center
|
center
|
||||||
:calculation="model.maxPrepared"
|
:calculation="model.maxPrepared"
|
||||||
/>
|
/>
|
||||||
|
<property-field
|
||||||
|
name="Spellcasting ability"
|
||||||
|
mono
|
||||||
|
:value="model.ability"
|
||||||
|
/>
|
||||||
|
<property-field
|
||||||
|
name="Spellcasting ability modifier"
|
||||||
|
large
|
||||||
|
center
|
||||||
|
signed
|
||||||
|
:value="model.abilityMod"
|
||||||
|
/>
|
||||||
<property-field
|
<property-field
|
||||||
name="Spell Save DC"
|
name="Spell Save DC"
|
||||||
large
|
large
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<template v-if="value !== undefined">
|
<template v-if="value !== undefined">
|
||||||
{{ value }}
|
{{ valueText }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="calculation !== undefined">
|
<template v-else-if="calculation !== undefined">
|
||||||
{{ calculationText }}
|
{{ calculationText }}
|
||||||
@@ -117,6 +117,13 @@ export default {
|
|||||||
if (!this.calculation) return;
|
if (!this.calculation) return;
|
||||||
return typeof this.calculation.value === 'string'
|
return typeof this.calculation.value === 'string'
|
||||||
},
|
},
|
||||||
|
valueText() {
|
||||||
|
if (this.signed) {
|
||||||
|
return numberToSignedString(this.value);
|
||||||
|
} else {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
calculationText(){
|
calculationText(){
|
||||||
const calculation = this.calculation;
|
const calculation = this.calculation;
|
||||||
if (!calculation) {
|
if (!calculation) {
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
const ActionViewer = () => import ('/imports/ui/properties/viewers/ActionViewer.vue');
|
import ActionViewer from '/imports/ui/properties/viewers/ActionViewer.vue';
|
||||||
const AdjustmentViewer = () => import ('/imports/ui/properties/viewers/AdjustmentViewer.vue');
|
import AdjustmentViewer from '/imports/ui/properties/viewers/AdjustmentViewer.vue';
|
||||||
const AttributeViewer = () => import ('/imports/ui/properties/viewers/AttributeViewer.vue');
|
import AttributeViewer from '/imports/ui/properties/viewers/AttributeViewer.vue';
|
||||||
const BuffViewer = () => import ('/imports/ui/properties/viewers/BuffViewer.vue');
|
import BuffViewer from '/imports/ui/properties/viewers/BuffViewer.vue';
|
||||||
const BuffRemoverViewer = () => import ('/imports/ui/properties/viewers/BuffRemoverViewer.vue');
|
import BuffRemoverViewer from '/imports/ui/properties/viewers/BuffRemoverViewer.vue';
|
||||||
const BranchViewer = () => import ('/imports/ui/properties/viewers/BranchViewer.vue');
|
import BranchViewer from '/imports/ui/properties/viewers/BranchViewer.vue';
|
||||||
const ContainerViewer = () => import ('/imports/ui/properties/viewers/ContainerViewer.vue');
|
import ContainerViewer from '/imports/ui/properties/viewers/ContainerViewer.vue';
|
||||||
const ClassViewer = () => import ('/imports/ui/properties/viewers/ClassViewer.vue');
|
import ClassViewer from '/imports/ui/properties/viewers/ClassViewer.vue';
|
||||||
const ClassLevelViewer = () => import ('/imports/ui/properties/viewers/ClassLevelViewer.vue');
|
import ClassLevelViewer from '/imports/ui/properties/viewers/ClassLevelViewer.vue';
|
||||||
const ConstantViewer = () => import ('/imports/ui/properties/viewers/ConstantViewer.vue');
|
import ConstantViewer from '/imports/ui/properties/viewers/ConstantViewer.vue';
|
||||||
const DamageViewer = () => import ('/imports/ui/properties/viewers/DamageViewer.vue');
|
import DamageViewer from '/imports/ui/properties/viewers/DamageViewer.vue';
|
||||||
const DamageMultiplierViewer = () => import ('/imports/ui/properties/viewers/DamageMultiplierViewer.vue');
|
import DamageMultiplierViewer from '/imports/ui/properties/viewers/DamageMultiplierViewer.vue';
|
||||||
const EffectViewer = () => import ('/imports/ui/properties/viewers/EffectViewer.vue');
|
import EffectViewer from '/imports/ui/properties/viewers/EffectViewer.vue';
|
||||||
const FeatureViewer = () => import ('/imports/ui/properties/viewers/FeatureViewer.vue');
|
import FeatureViewer from '/imports/ui/properties/viewers/FeatureViewer.vue';
|
||||||
const FolderViewer = () => import ('/imports/ui/properties/viewers/FolderViewer.vue');
|
import FolderViewer from '/imports/ui/properties/viewers/FolderViewer.vue';
|
||||||
const ItemViewer = () => import ('/imports/ui/properties/viewers/ItemViewer.vue');
|
import ItemViewer from '/imports/ui/properties/viewers/ItemViewer.vue';
|
||||||
const NoteViewer = () => import ('/imports/ui/properties/viewers/NoteViewer.vue');
|
import NoteViewer from '/imports/ui/properties/viewers/NoteViewer.vue';
|
||||||
const PointBuyViewer = () => import ('/imports/ui/properties/viewers/PointBuyViewer.vue');
|
import PointBuyViewer from '/imports/ui/properties/viewers/PointBuyViewer.vue';
|
||||||
const ProficiencyViewer = () => import ('/imports/ui/properties/viewers/ProficiencyViewer.vue');
|
import ProficiencyViewer from '/imports/ui/properties/viewers/ProficiencyViewer.vue';
|
||||||
const ReferenceViewer = () => import ('/imports/ui/properties/viewers/ReferenceViewer.vue');
|
import ReferenceViewer from '/imports/ui/properties/viewers/ReferenceViewer.vue';
|
||||||
const RollViewer = () => import ('/imports/ui/properties/viewers/RollViewer.vue');
|
import RollViewer from '/imports/ui/properties/viewers/RollViewer.vue';
|
||||||
const SkillViewer = () => import ('/imports/ui/properties/viewers/SkillViewer.vue');
|
import SkillViewer from '/imports/ui/properties/viewers/SkillViewer.vue';
|
||||||
const SavingThrowViewer = () => import ('/imports/ui/properties/viewers/SavingThrowViewer.vue');
|
import SavingThrowViewer from '/imports/ui/properties/viewers/SavingThrowViewer.vue';
|
||||||
const SlotViewer = () => import ('/imports/ui/properties/viewers/SlotViewer.vue');
|
import SlotViewer from '/imports/ui/properties/viewers/SlotViewer.vue';
|
||||||
const SlotFillerViewer = () => import ('/imports/ui/properties/viewers/SlotFillerViewer.vue');
|
import SlotFillerViewer from '/imports/ui/properties/viewers/SlotFillerViewer.vue';
|
||||||
const SpellListViewer = () => import ('/imports/ui/properties/viewers/SpellListViewer.vue');
|
import SpellListViewer from '/imports/ui/properties/viewers/SpellListViewer.vue';
|
||||||
const SpellViewer = () => import ('/imports/ui/properties/viewers/SpellViewer.vue');
|
import SpellViewer from '/imports/ui/properties/viewers/SpellViewer.vue';
|
||||||
const ToggleViewer = () => import ('/imports/ui/properties/viewers/ToggleViewer.vue');
|
import ToggleViewer from '/imports/ui/properties/viewers/ToggleViewer.vue';
|
||||||
const TriggerViewer = () => import ('/imports/ui/properties/viewers/TriggerViewer.vue');
|
import TriggerViewer from '/imports/ui/properties/viewers/TriggerViewer.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
action: ActionViewer,
|
action: ActionViewer,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const LibraryCollectionToolbar = () => import('/imports/ui/library/LibraryCollec
|
|||||||
const CharacterSheetPage = () => import('/imports/ui/pages/CharacterSheetPage.vue');
|
const CharacterSheetPage = () => import('/imports/ui/pages/CharacterSheetPage.vue');
|
||||||
const CharacterSheetToolbar = () => import('/imports/ui/creature/character/CharacterSheetToolbar.vue');
|
const CharacterSheetToolbar = () => import('/imports/ui/creature/character/CharacterSheetToolbar.vue');
|
||||||
const CharacterSheetRightDrawer = () => import('/imports/ui/creature/character/CharacterSheetRightDrawer.vue');
|
const CharacterSheetRightDrawer = () => import('/imports/ui/creature/character/CharacterSheetRightDrawer.vue');
|
||||||
|
const CharacterSheetPrinted = () => import('/imports/ui/creature/character/printedCharacterSheet/CharacterSheetPrinted.vue');
|
||||||
const SignIn = () => import('/imports/ui/pages/SignIn.vue');
|
const SignIn = () => import('/imports/ui/pages/SignIn.vue');
|
||||||
const Register = () => import('/imports/ui/pages/Register.vue');
|
const Register = () => import('/imports/ui/pages/Register.vue');
|
||||||
const IconAdmin = () => import('/imports/ui/icons/IconAdmin.vue');
|
const IconAdmin = () => import('/imports/ui/icons/IconAdmin.vue');
|
||||||
@@ -177,6 +178,16 @@ RouterFactory.configure(router => {
|
|||||||
meta: {
|
meta: {
|
||||||
title: 'Character Sheet',
|
title: 'Character Sheet',
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
name: 'printCharacterSheet',
|
||||||
|
path: '/print-character/:id',
|
||||||
|
alias: '/print-character/:id/:urlName',
|
||||||
|
components: {
|
||||||
|
default: CharacterSheetPrinted,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
title: 'Print Character Sheet',
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
path: '/tabletops',
|
path: '/tabletops',
|
||||||
name: 'tabletops',
|
name: 'tabletops',
|
||||||
|
|||||||
467
app/package-lock.json
generated
467
app/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dicecloud",
|
"name": "dicecloud",
|
||||||
"version": "2.0.42",
|
"version": "2.0.43",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -56,11 +56,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.19.4",
|
"version": "7.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz",
|
||||||
"integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==",
|
"integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@chenfengyuan/vue-countdown": {
|
"@chenfengyuan/vue-countdown": {
|
||||||
@@ -179,22 +179,23 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/semver": {
|
"@types/semver": {
|
||||||
"version": "7.3.12",
|
"version": "7.3.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
|
||||||
"integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==",
|
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.0.tgz",
|
||||||
"integrity": "sha512-FsWboKkWdytGiXT5O1/R9j37YgcjO8MKHSUmWnIEjVaz0krHkplPnYi7mwdb+5+cs0toFNQb0HIrN7zONdIEWg==",
|
"integrity": "sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/scope-manager": "5.40.1",
|
"@typescript-eslint/scope-manager": "5.42.0",
|
||||||
"@typescript-eslint/type-utils": "5.40.1",
|
"@typescript-eslint/type-utils": "5.42.0",
|
||||||
"@typescript-eslint/utils": "5.40.1",
|
"@typescript-eslint/utils": "5.42.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
|
"natural-compare-lite": "^1.4.0",
|
||||||
"regexpp": "^3.2.0",
|
"regexpp": "^3.2.0",
|
||||||
"semver": "^7.3.7",
|
"semver": "^7.3.7",
|
||||||
"tsutils": "^3.21.0"
|
"tsutils": "^3.21.0"
|
||||||
@@ -221,14 +222,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/parser": {
|
"@typescript-eslint/parser": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.0.tgz",
|
||||||
"integrity": "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg==",
|
"integrity": "sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/scope-manager": "5.40.1",
|
"@typescript-eslint/scope-manager": "5.42.0",
|
||||||
"@typescript-eslint/types": "5.40.1",
|
"@typescript-eslint/types": "5.42.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.40.1",
|
"@typescript-eslint/typescript-estree": "5.42.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -244,23 +245,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/scope-manager": {
|
"@typescript-eslint/scope-manager": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz",
|
||||||
"integrity": "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==",
|
"integrity": "sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.40.1",
|
"@typescript-eslint/types": "5.42.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.40.1"
|
"@typescript-eslint/visitor-keys": "5.42.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/type-utils": {
|
"@typescript-eslint/type-utils": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.0.tgz",
|
||||||
"integrity": "sha512-DLAs+AHQOe6n5LRraXiv27IYPhleF0ldEmx6yBqBgBLaNRKTkffhV1RPsjoJBhVup2zHxfaRtan8/YRBgYhU9Q==",
|
"integrity": "sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/typescript-estree": "5.40.1",
|
"@typescript-eslint/typescript-estree": "5.42.0",
|
||||||
"@typescript-eslint/utils": "5.40.1",
|
"@typescript-eslint/utils": "5.42.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"tsutils": "^3.21.0"
|
"tsutils": "^3.21.0"
|
||||||
},
|
},
|
||||||
@@ -277,19 +278,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/types": {
|
"@typescript-eslint/types": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.0.tgz",
|
||||||
"integrity": "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==",
|
"integrity": "sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@typescript-eslint/typescript-estree": {
|
"@typescript-eslint/typescript-estree": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz",
|
||||||
"integrity": "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==",
|
"integrity": "sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.40.1",
|
"@typescript-eslint/types": "5.42.0",
|
||||||
"@typescript-eslint/visitor-keys": "5.40.1",
|
"@typescript-eslint/visitor-keys": "5.42.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"globby": "^11.1.0",
|
"globby": "^11.1.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
@@ -318,16 +319,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/utils": {
|
"@typescript-eslint/utils": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.0.tgz",
|
||||||
"integrity": "sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==",
|
"integrity": "sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json-schema": "^7.0.9",
|
"@types/json-schema": "^7.0.9",
|
||||||
"@types/semver": "^7.3.12",
|
"@types/semver": "^7.3.12",
|
||||||
"@typescript-eslint/scope-manager": "5.40.1",
|
"@typescript-eslint/scope-manager": "5.42.0",
|
||||||
"@typescript-eslint/types": "5.40.1",
|
"@typescript-eslint/types": "5.42.0",
|
||||||
"@typescript-eslint/typescript-estree": "5.40.1",
|
"@typescript-eslint/typescript-estree": "5.42.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"eslint-utils": "^3.0.0",
|
"eslint-utils": "^3.0.0",
|
||||||
"semver": "^7.3.7"
|
"semver": "^7.3.7"
|
||||||
@@ -354,12 +355,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/visitor-keys": {
|
"@typescript-eslint/visitor-keys": {
|
||||||
"version": "5.40.1",
|
"version": "5.42.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz",
|
||||||
"integrity": "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==",
|
"integrity": "sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "5.40.1",
|
"@typescript-eslint/types": "5.42.0",
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -544,9 +545,9 @@
|
|||||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||||
},
|
},
|
||||||
"aws-sdk": {
|
"aws-sdk": {
|
||||||
"version": "2.1234.0",
|
"version": "2.1247.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1234.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1247.0.tgz",
|
||||||
"integrity": "sha512-QFuSeYM8DPiXytspLnWToy4MWJPGYFCgAy4hi+lRd6ueJtCey7MBIgFNHW814uAJzKUDEdJUJZPvDZvtLM1d/Q==",
|
"integrity": "sha512-hBiVzkm5pxGchl+dn+uIApk76n3UOGuDmQBr1H2J25Ls8F7M9sNiumJby/cSjis+U+gAhl7u414SMY+ZTAJAkQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"buffer": "4.9.2",
|
"buffer": "4.9.2",
|
||||||
"events": "1.1.1",
|
"events": "1.1.1",
|
||||||
@@ -594,9 +595,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
},
|
},
|
||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
@@ -893,12 +894,12 @@
|
|||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
|
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||||
},
|
},
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.6.12",
|
"version": "2.6.12",
|
||||||
@@ -958,7 +959,7 @@
|
|||||||
"decamelize": {
|
"decamelize": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
|
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||||
},
|
},
|
||||||
"decompress-response": {
|
"decompress-response": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
@@ -988,15 +989,6 @@
|
|||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"define-properties": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
|
|
||||||
"requires": {
|
|
||||||
"has-property-descriptors": "^1.0.0",
|
|
||||||
"object-keys": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delayed-stream": {
|
"delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
@@ -1005,7 +997,7 @@
|
|||||||
"delegates": {
|
"delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||||
},
|
},
|
||||||
"detect-libc": {
|
"detect-libc": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -1096,47 +1088,6 @@
|
|||||||
"ansi-colors": "^4.1.1"
|
"ansi-colors": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"es-abstract": {
|
|
||||||
"version": "1.20.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
|
|
||||||
"integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"es-to-primitive": "^1.2.1",
|
|
||||||
"function-bind": "^1.1.1",
|
|
||||||
"function.prototype.name": "^1.1.5",
|
|
||||||
"get-intrinsic": "^1.1.3",
|
|
||||||
"get-symbol-description": "^1.0.0",
|
|
||||||
"has": "^1.0.3",
|
|
||||||
"has-property-descriptors": "^1.0.0",
|
|
||||||
"has-symbols": "^1.0.3",
|
|
||||||
"internal-slot": "^1.0.3",
|
|
||||||
"is-callable": "^1.2.7",
|
|
||||||
"is-negative-zero": "^2.0.2",
|
|
||||||
"is-regex": "^1.1.4",
|
|
||||||
"is-shared-array-buffer": "^1.0.2",
|
|
||||||
"is-string": "^1.0.7",
|
|
||||||
"is-weakref": "^1.0.2",
|
|
||||||
"object-inspect": "^1.12.2",
|
|
||||||
"object-keys": "^1.1.1",
|
|
||||||
"object.assign": "^4.1.4",
|
|
||||||
"regexp.prototype.flags": "^1.4.3",
|
|
||||||
"safe-regex-test": "^1.0.0",
|
|
||||||
"string.prototype.trimend": "^1.0.5",
|
|
||||||
"string.prototype.trimstart": "^1.0.5",
|
|
||||||
"unbox-primitive": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"es-to-primitive": {
|
|
||||||
"version": "1.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
|
|
||||||
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
|
|
||||||
"requires": {
|
|
||||||
"is-callable": "^1.1.4",
|
|
||||||
"is-date-object": "^1.0.1",
|
|
||||||
"is-symbol": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"escape-string-regexp": {
|
"escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@@ -1519,28 +1470,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||||
},
|
},
|
||||||
"function.prototype.name": {
|
|
||||||
"version": "1.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
|
|
||||||
"integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.1.3",
|
|
||||||
"es-abstract": "^1.19.0",
|
|
||||||
"functions-have-names": "^1.2.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"functional-red-black-tree": {
|
"functional-red-black-tree": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
|
||||||
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
|
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"functions-have-names": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
|
|
||||||
},
|
|
||||||
"gauge": {
|
"gauge": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
||||||
@@ -1578,15 +1513,6 @@
|
|||||||
"has-symbols": "^1.0.3"
|
"has-symbols": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"get-symbol-description": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"get-intrinsic": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"getpass": {
|
"getpass": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||||
@@ -1645,6 +1571,14 @@
|
|||||||
"slash": "^3.0.0"
|
"slash": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gopd": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||||
|
"requires": {
|
||||||
|
"get-intrinsic": "^1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"har-schema": {
|
"har-schema": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||||
@@ -1680,25 +1614,12 @@
|
|||||||
"function-bind": "^1.1.1"
|
"function-bind": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"has-bigints": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ=="
|
|
||||||
},
|
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"has-property-descriptors": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
|
||||||
"requires": {
|
|
||||||
"get-intrinsic": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"has-symbols": {
|
"has-symbols": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
@@ -1715,7 +1636,7 @@
|
|||||||
"has-unicode": {
|
"has-unicode": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
|
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||||
},
|
},
|
||||||
"http-signature": {
|
"http-signature": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@@ -1792,16 +1713,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||||
},
|
},
|
||||||
"internal-slot": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
|
|
||||||
"requires": {
|
|
||||||
"get-intrinsic": "^1.1.0",
|
|
||||||
"has": "^1.0.3",
|
|
||||||
"side-channel": "^1.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-arguments": {
|
"is-arguments": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||||
@@ -1816,14 +1727,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||||
},
|
},
|
||||||
"is-bigint": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
|
|
||||||
"requires": {
|
|
||||||
"has-bigints": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-binary-path": {
|
"is-binary-path": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
@@ -1833,28 +1736,11 @@
|
|||||||
"binary-extensions": "^2.0.0"
|
"binary-extensions": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-boolean-object": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"has-tostringtag": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-callable": {
|
"is-callable": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
|
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
|
||||||
},
|
},
|
||||||
"is-date-object": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
|
|
||||||
"requires": {
|
|
||||||
"has-tostringtag": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-extglob": {
|
"is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -1883,67 +1769,21 @@
|
|||||||
"is-extglob": "^2.1.1"
|
"is-extglob": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-negative-zero": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
|
|
||||||
},
|
|
||||||
"is-number": {
|
"is-number": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-number-object": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
|
|
||||||
"requires": {
|
|
||||||
"has-tostringtag": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-regex": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"has-tostringtag": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-shared-array-buffer": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-string": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
|
|
||||||
"requires": {
|
|
||||||
"has-tostringtag": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-symbol": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
|
|
||||||
"requires": {
|
|
||||||
"has-symbols": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-typed-array": {
|
"is-typed-array": {
|
||||||
"version": "1.1.9",
|
"version": "1.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
|
||||||
"integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==",
|
"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"available-typed-arrays": "^1.0.5",
|
"available-typed-arrays": "^1.0.5",
|
||||||
"call-bind": "^1.0.2",
|
"call-bind": "^1.0.2",
|
||||||
"es-abstract": "^1.20.0",
|
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1952,14 +1792,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||||
},
|
},
|
||||||
"is-weakref": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"isarray": {
|
"isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
@@ -2090,7 +1922,7 @@
|
|||||||
"lodash.omit": {
|
"lodash.omit": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
|
||||||
},
|
},
|
||||||
"lodash.template": {
|
"lodash.template": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
@@ -2157,9 +1989,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"version": "4.1.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.1.tgz",
|
||||||
"integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw=="
|
"integrity": "sha512-VK1/jNtwqDLvPktNpL0Fdg3qoeUZhmRsuiIjPEy/lHwXW4ouLoZfO4XoWd4ClDt+hupV1VLpkZhEovjU0W/kqA=="
|
||||||
},
|
},
|
||||||
"mem": {
|
"mem": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
@@ -3008,9 +2840,9 @@
|
|||||||
"integrity": "sha1-IBvZSSceGfbgrwodwMzFg95HxjA="
|
"integrity": "sha1-IBvZSSceGfbgrwodwMzFg95HxjA="
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@@ -3073,6 +2905,12 @@
|
|||||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"natural-compare-lite": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"nearley": {
|
"nearley": {
|
||||||
"version": "2.20.1",
|
"version": "2.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
|
||||||
@@ -3156,28 +2994,7 @@
|
|||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||||
},
|
|
||||||
"object-inspect": {
|
|
||||||
"version": "1.12.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
|
|
||||||
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
|
|
||||||
},
|
|
||||||
"object-keys": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
|
||||||
},
|
|
||||||
"object.assign": {
|
|
||||||
"version": "4.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
|
|
||||||
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.1.4",
|
|
||||||
"has-symbols": "^1.0.3",
|
|
||||||
"object-keys": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
@@ -3352,6 +3169,11 @@
|
|||||||
"yargs": "^15.3.1"
|
"yargs": "^15.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"qrcode.vue": {
|
||||||
|
"version": "1.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-1.7.0.tgz",
|
||||||
|
"integrity": "sha512-R7t6Y3fDDtcU7L4rtqwGUDP9xD64gJhIwpfjhRCTKmBoYF6SS49PIJHRJ048cse6OI7iwTwgyy2C46N9Ygoc6g=="
|
||||||
|
},
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.5.2",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||||
@@ -3396,7 +3218,7 @@
|
|||||||
"strip-json-comments": {
|
"strip-json-comments": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||||
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="
|
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3424,16 +3246,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
|
||||||
"integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
|
"integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
|
||||||
},
|
},
|
||||||
"regexp.prototype.flags": {
|
|
||||||
"version": "1.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
|
|
||||||
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.1.3",
|
|
||||||
"functions-have-names": "^1.2.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"regexpp": {
|
"regexpp": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||||
@@ -3470,7 +3282,7 @@
|
|||||||
"require-directory": {
|
"require-directory": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||||
},
|
},
|
||||||
"require-from-string": {
|
"require-from-string": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
@@ -3528,25 +3340,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
},
|
},
|
||||||
"safe-regex-test": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"get-intrinsic": "^1.1.3",
|
|
||||||
"is-regex": "^1.1.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"version": "1.55.0",
|
"version": "1.56.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.56.0.tgz",
|
||||||
"integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
|
"integrity": "sha512-WFJ9XrpkcnqZcYuLRJh5qiV6ibQOR4AezleeEjTjMsCocYW59dEG19U3fwTTXxzi2Ed3yjPBp727hbbj53pHFw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
@@ -3570,7 +3372,7 @@
|
|||||||
"set-blocking": {
|
"set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||||
},
|
},
|
||||||
"setimmediate": {
|
"setimmediate": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
@@ -3617,16 +3419,6 @@
|
|||||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"side-channel": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.0",
|
|
||||||
"get-intrinsic": "^1.0.2",
|
|
||||||
"object-inspect": "^1.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
@@ -3660,7 +3452,7 @@
|
|||||||
"simple-swizzle": {
|
"simple-swizzle": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-arrayish": "^0.3.1"
|
"is-arrayish": "^0.3.1"
|
||||||
}
|
}
|
||||||
@@ -3783,26 +3575,6 @@
|
|||||||
"strip-ansi": "^6.0.1"
|
"strip-ansi": "^6.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string.prototype.trimend": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.1.4",
|
|
||||||
"es-abstract": "^1.19.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"string.prototype.trimstart": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.1.4",
|
|
||||||
"es-abstract": "^1.19.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
@@ -4041,17 +3813,6 @@
|
|||||||
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"unbox-primitive": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
|
|
||||||
"requires": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"has-bigints": "^1.0.2",
|
|
||||||
"has-symbols": "^1.0.3",
|
|
||||||
"which-boxed-primitive": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"underscore": {
|
"underscore": {
|
||||||
"version": "1.13.6",
|
"version": "1.13.6",
|
||||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
|
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
|
||||||
@@ -4096,7 +3857,7 @@
|
|||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
@@ -4191,9 +3952,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vuetify": {
|
"vuetify": {
|
||||||
"version": "2.6.11",
|
"version": "2.6.12",
|
||||||
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.6.11.tgz",
|
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.6.12.tgz",
|
||||||
"integrity": "sha512-SX6BzS068t/RMj0d/sxxS/LsKdk9FpkL7CWShLyOMmJa/hiG63L0bvcopEaWYdRzzuQt7Nx174sk+KB6SvmYBw=="
|
"integrity": "sha512-qe3hcMpWmT1O15tp+p65lOS7UKZ/hQYQktCsw9iXx2u3RwVbX6GR82gY2iROrKsiAzYDvMgrYxWQwY/pUfkekw=="
|
||||||
},
|
},
|
||||||
"vuetify-upload-button": {
|
"vuetify-upload-button": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
@@ -4228,34 +3989,22 @@
|
|||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"which-boxed-primitive": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
|
|
||||||
"requires": {
|
|
||||||
"is-bigint": "^1.0.1",
|
|
||||||
"is-boolean-object": "^1.1.0",
|
|
||||||
"is-number-object": "^1.0.4",
|
|
||||||
"is-string": "^1.0.5",
|
|
||||||
"is-symbol": "^1.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"which-module": {
|
"which-module": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||||
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q=="
|
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||||
},
|
},
|
||||||
"which-typed-array": {
|
"which-typed-array": {
|
||||||
"version": "1.1.8",
|
"version": "1.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
|
||||||
"integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==",
|
"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"available-typed-arrays": "^1.0.5",
|
"available-typed-arrays": "^1.0.5",
|
||||||
"call-bind": "^1.0.2",
|
"call-bind": "^1.0.2",
|
||||||
"es-abstract": "^1.20.0",
|
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
"has-tostringtag": "^1.0.0",
|
"has-tostringtag": "^1.0.0",
|
||||||
"is-typed-array": "^1.1.9"
|
"is-typed-array": "^1.1.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wide-align": {
|
"wide-align": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dicecloud",
|
"name": "dicecloud",
|
||||||
"version": "2.0.43",
|
"version": "2.0.44",
|
||||||
"description": "Unofficial Online Realtime D&D 5e App",
|
"description": "Unofficial Online Realtime D&D 5e App",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
"npm": "6.13.x"
|
"npm": "6.13.x"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.19.4",
|
"@babel/runtime": "^7.20.1",
|
||||||
"@chenfengyuan/vue-countdown": "^1.1.5",
|
"@chenfengyuan/vue-countdown": "^1.1.5",
|
||||||
"@tozd/vue-observer-utils": "^0.5.0",
|
"@tozd/vue-observer-utils": "^0.5.0",
|
||||||
"animejs": "^2.2.0",
|
"animejs": "^2.2.0",
|
||||||
"aws-sdk": "^2.1234.0",
|
"aws-sdk": "^2.1247.0",
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"chroma-js": "^2.4.2",
|
"chroma-js": "^2.4.2",
|
||||||
"core-js": "^2.6.11",
|
"core-js": "^2.6.11",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"ignore-styles": "^5.0.1",
|
"ignore-styles": "^5.0.1",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"marked": "^4.1.1",
|
"marked": "^4.2.1",
|
||||||
"meteor-node-stubs": "^1.2.5",
|
"meteor-node-stubs": "^1.2.5",
|
||||||
"minify-css-string": "^1.0.0",
|
"minify-css-string": "^1.0.0",
|
||||||
"moo": "^0.5.2",
|
"moo": "^0.5.2",
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
"ngraph.path": "^1.4.0",
|
"ngraph.path": "^1.4.0",
|
||||||
"pretty-bytes": "^6.0.0",
|
"pretty-bytes": "^6.0.0",
|
||||||
"qrcode": "^1.5.1",
|
"qrcode": "^1.5.1",
|
||||||
|
"qrcode.vue": "^1.7.0",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"sharp": "^0.30.7",
|
"sharp": "^0.30.7",
|
||||||
"simpl-schema": "^1.13.1",
|
"simpl-schema": "^1.13.1",
|
||||||
@@ -56,20 +57,20 @@
|
|||||||
"vue-reactive-provide": "^0.3.0",
|
"vue-reactive-provide": "^0.3.0",
|
||||||
"vue-router": "^3.6.5",
|
"vue-router": "^3.6.5",
|
||||||
"vuedraggable": "^2.23.2",
|
"vuedraggable": "^2.23.2",
|
||||||
"vuetify": "^2.6.11",
|
"vuetify": "^2.6.12",
|
||||||
"vuetify-upload-button": "^2.0.2",
|
"vuetify-upload-button": "^2.0.2",
|
||||||
"vuex": "^3.1.3"
|
"vuex": "^3.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
||||||
"@typescript-eslint/parser": "^5.40.1",
|
"@typescript-eslint/parser": "^5.42.0",
|
||||||
"@vue/compiler-dom": "^3.2.41",
|
"@vue/compiler-dom": "^3.2.41",
|
||||||
"chai": "^4.3.6",
|
"chai": "^4.3.6",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-vue": "^7.20.0",
|
"eslint-plugin-vue": "^7.20.0",
|
||||||
"eslint-plugin-vuetify": "^1.1.0",
|
"eslint-plugin-vuetify": "^1.1.0",
|
||||||
"mem": "^6.1.1",
|
"mem": "^6.1.1",
|
||||||
"sass": "^1.55.0",
|
"sass": "^1.56.0",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
@@ -120,8 +121,7 @@
|
|||||||
"quotes": [
|
"quotes": [
|
||||||
"error",
|
"error",
|
||||||
"single"
|
"single"
|
||||||
],
|
]
|
||||||
"vuetify/no-deprecated-classes": "error"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,10 @@ Allows [inline calculations](/docs/inline-calculations).
|
|||||||
|
|
||||||
A [computed field](/docs/computed-fields) that determines how many spells can be considered ready to cast in this spell list.
|
A [computed field](/docs/computed-fields) that determines how many spells can be considered ready to cast in this spell list.
|
||||||
|
|
||||||
|
### Spell casting ability
|
||||||
|
|
||||||
|
The spellcasting ablity for this spell list. The variable name of the ability can be accessed using `#spellList.ability` and the ability modifier with `#spellList.abilityMod`. Setting this field will automatically update Spell save DC and Attack roll bonus if they aren't set manually.
|
||||||
|
|
||||||
### Spell save DC
|
### Spell save DC
|
||||||
|
|
||||||
A [computed field](/docs/computed-fields) that determines the DC of saving throws in this spell list. Spells can access the DC of their spell list using `#spellList.dc`
|
A [computed field](/docs/computed-fields) that determines the DC of saving throws in this spell list. Spells can access the DC of their spell list using `#spellList.dc`
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Reference in New Issue
Block a user