diff --git a/images/icone_parchement_vierge.svg b/images/icone_parchement_vierge.svg
new file mode 100644
index 0000000..035129b
--- /dev/null
+++ b/images/icone_parchement_vierge.svg
@@ -0,0 +1,4998 @@
+
+
diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js
index c2e6f57..3b91093 100644
--- a/module/actor/actor-sheet.js
+++ b/module/actor/actor-sheet.js
@@ -14,6 +14,7 @@ export class BoLActorSheet extends ActorSheet {
template: "systems/bol/templates/actor/actor-sheet.hbs",
width: 600,
height: 600,
+ dragDrop: [{ dragSelector: ".items-list .item", dropSelector: null }],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }]
});
}
diff --git a/module/actor/actor.js b/module/actor/actor.js
index 2cf8116..ae89ba2 100644
--- a/module/actor/actor.js
+++ b/module/actor/actor.js
@@ -304,23 +304,17 @@ export class BoLActor extends Actor {
/*-------------------------------------------- */
getArmorAgiMalus() {
let malusAgi = 0
- for (let armor of this.armors) {
+ for (let armor of this.protections) {
if (armor.data.worn) {
malusAgi += Number(armor.data.properties.modifiers.agility) || 0
}
}
- for (let shield of this.shields) {
- if (shield.data.worn) {
- malusAgi += Number(shield.data.properties.modifiers.agility) || 0
- }
- }
return malusAgi
}
/*-------------------------------------------- */
getArmorInitMalus() {
- let armors = this.armors
let malusInit = 0
- for (let armor of armors) {
+ for (let armor of this.protections) {
if (armor.data.worn) {
malusInit += Number(armor.data.properties.modifiers.init) || 0
}
diff --git a/module/bol.js b/module/bol.js
index 0de91ee..a5c154e 100644
--- a/module/bol.js
+++ b/module/bol.js
@@ -12,6 +12,7 @@ import { Macros } from "./system/macros.js"
import { BoLUtility } from "./system/bol-utility.js"
import { BoLCombatManager } from "./system/bol-combat.js"
import { BoLTokenHud } from "./system/bol-action-hud.js"
+import { BoLHotbar } from "./system/bol-hotbar.js"
/* -------------------------------------------- */
Hooks.once('init', async function () {
@@ -19,6 +20,7 @@ Hooks.once('init', async function () {
game.bol = {
BoLActor,
BoLItem,
+ BoLHotbar,
macros: Macros,
config: BOL
};
@@ -52,6 +54,7 @@ Hooks.once('init', async function () {
// Inot useful stuff
BoLUtility.init()
BoLTokenHud.init()
+ BoLHotbar.init()
// Preload Handlebars Templates
await preloadHandlebarsTemplates();
diff --git a/module/controllers/bol-rolls.js b/module/controllers/bol-rolls.js
index aa96bc7..f683cd0 100644
--- a/module/controllers/bol-rolls.js
+++ b/module/controllers/bol-rolls.js
@@ -32,7 +32,7 @@ export class BoLRoll {
careerBonus: 0,
description: description,
armorAgiMalus: actor.getArmorAgiMalus(),
- armorInitMalus: actor.getArmorAgiMalus(),
+ armorInitMalus: actor.getArmorInitMalus(),
mod: 0
}
return this.displayRollDialog(rollData)
@@ -56,12 +56,12 @@ export class BoLRoll {
attrValue: attribute.value,
aptValue: aptitude.value,
armorAgiMalus: actor.getArmorAgiMalus(),
- armorInitMalus: actor.getArmorAgiMalus(),
+ armorInitMalus: actor.getArmorInitMalus(),
label: label,
careerBonus: 0,
description: description,
mod: 0
- });
+ })
}
/* -------------------------------------------- */
@@ -94,7 +94,7 @@ export class BoLRoll {
attrValue: attribute.value,
aptValue: aptitude.value,
armorAgiMalus: actor.getArmorAgiMalus(),
- armorInitMalus: actor.getArmorAgiMalus(),
+ armorInitMalus: actor.getArmorInitMalus(),
mod: 0,
modRanged: 0,
label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'),
@@ -139,7 +139,7 @@ export class BoLRoll {
pcCostCurrent: Number(alchemyData.properties.pccurrent),
mod: Number(alchemyData.properties.difficulty),
armorAgiMalus: actor.getArmorAgiMalus(),
- armorInitMalus: actor.getArmorAgiMalus(),
+ armorInitMalus: actor.getArmorInitMalus(),
label: alchemy.name,
description: game.i18n.localize('BOL.ui.makeAlchemy') + "+" + alchemy.name,
}
@@ -147,20 +147,9 @@ export class BoLRoll {
return this.displayRollDialog(alchemyDef);
}
-
/* -------------------------------------------- */
- static spellCheck(actor, event) {
- if (actor.data.data.resources.power.value <= 0) {
- ui.notifications.warn("Plus assez de points de Pouvoir !")
- return
- }
- const li = $(event.currentTarget).parents(".item");
- const spell = actor.items.get(li.data("item-id"));
- if (!spell) {
- ui.notifications.warn("Unable to find spell !");
- return;
- }
- let spellData = spell.data.data;
+ static spellCheckWithSpell( actor, spell ) {
+ let spellData = spell.data.data
let spellDef = {
mode: "spell",
actor: actor,
@@ -174,12 +163,27 @@ export class BoLRoll {
ppCost: Number(spell.data.data.properties.ppcost),
mod: Number(spellData.properties.difficulty),
armorAgiMalus: actor.getArmorAgiMalus(),
- armorInitMalus: actor.getArmorAgiMalus(),
+ armorInitMalus: actor.getArmorInitMalus(),
label: spell.name,
description: game.i18n.localize('BOL.ui.focusSpell') + " : " + spell.name,
}
- console.log("SPELL!", spellDef);
- return this.displayRollDialog(spellDef);
+ console.log("SPELL!", spellDef)
+ return this.displayRollDialog(spellDef)
+ }
+
+ /* -------------------------------------------- */
+ static spellCheck(actor, event) {
+ if (actor.data.data.resources.power.value <= 0) {
+ ui.notifications.warn("Plus assez de points de Pouvoir !")
+ return
+ }
+ const li = $(event.currentTarget).parents(".item")
+ const spell = actor.items.get(li.data("item-id"))
+ if (!spell) {
+ ui.notifications.warn("Impossible de trouver ce sort !")
+ return
+ }
+ return this.spellCheckWithSpell( actor, spell)
}
/* -------------------------------------------- */
@@ -347,6 +351,7 @@ export class BoLRoll {
rollData.careers = rollData.actor.careers
rollData.boons = rollData.actor.bonusBoons
rollData.flaws = rollData.actor.malusFlaws
+ rollData.rollOwnerID = rollData.actor.id
rollData.defence = 0
rollData.attackModifier = 0 // Used for fight options
rollData.modArmorMalus = 0 // Used for fight options
@@ -455,6 +460,8 @@ export class BoLDefaultRoll {
this.rollData.isSuccess = (r.total >= 9)
this.rollData.isCritical = (diceTotal === 12)
this.rollData.isRealCritical = (diceTotal === 12)
+ this.rollData.isHeroic = (diceTotal === 12)
+ this.rollData.isLegendary = false
this.rollData.isFumble = (diceTotal === 2)
this.rollData.isFailure = !this.rollData.isSuccess
if (this.rollData.reroll == undefined) {
@@ -479,26 +486,41 @@ export class BoLDefaultRoll {
this._buildChatMessage(this.rollData).then(msgFlavor => {
this.rollData.roll.toMessage({
user: game.user.id,
+ rollMode: game.settings.get("core", "rollMode"),
+ //whisper: BoLUtility.getWhisperRecipientsAndGMs(this.rollData.actor.name),
flavor: msgFlavor,
speaker: ChatMessage.getSpeaker({ actor: this.rollData.actor }),
- flags: { msgType: "default" }
})
- });
+ })
}
/* -------------------------------------------- */
- upgradeToCritical() {
+ upgradeToLegendary() {
// Force to Critical roll
this.rollData.isCritical = true
+ this.rollData.isLegendary = true
this.rollData.isRealCritical = false
this.rollData.isSuccess = true
this.rollData.isFailure = false
- this.rollData.reroll = false
this.rollData.roll = new Roll("12+" + this.rollData.modifiers)
this.rollData.reroll = false
this.sendChatMessage()
}
+ /* -------------------------------------------- */
+ upgradeToHeroic() {
+ // Force to Critical roll
+ this.rollData.isCritical = true
+ this.rollData.isHeroic = true
+ this.rollData.isLegendary = false
+ this.rollData.isRealCritical = false
+ this.rollData.isSuccess = true
+ this.rollData.isFailure = false
+ this.rollData.roll = new Roll("12+" + this.rollData.modifiers)
+ this.rollData.reroll = false
+ this.sendChatMessage()
+ }
+
/* -------------------------------------------- */
setSuccess(flag) {
this.rollData.isSuccess = flag
@@ -510,7 +532,7 @@ export class BoLDefaultRoll {
this.rollData.damageRoll.toMessage({
user: game.user.id,
flavor: msgFlavor,
- speaker: ChatMessage.getSpeaker({ actor: this.rollData.actor }),
+ speaker: ChatMessage.getSpeaker({ actor: this.rollData.actors }),
flags: { msgType: "default" }
})
});
diff --git a/module/item/item-sheet.js b/module/item/item-sheet.js
index 87b7dd2..0b6b9de 100644
--- a/module/item/item-sheet.js
+++ b/module/item/item-sheet.js
@@ -12,7 +12,7 @@ export class BoLItemSheet extends ItemSheet {
classes: ["bol", "sheet", "item"],
template: "systems/bol/templates/item/item-sheet.hbs",
width: 650,
- height: 750,
+ height: 780,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
});
}
diff --git a/module/system/bol-hotbar.js b/module/system/bol-hotbar.js
new file mode 100644
index 0000000..7884153
--- /dev/null
+++ b/module/system/bol-hotbar.js
@@ -0,0 +1,87 @@
+import { BoLRoll } from "../controllers/bol-rolls.js";
+
+export class BoLHotbar {
+
+ /**
+ * Create a macro when dropping an entity on the hotbar
+ * Item - open roll dialog for item
+ * Actor - open actor sheet
+ * Journal - open journal sheet
+ */
+ static init( ) {
+
+ Hooks.on("hotbarDrop", async (bar, documentData, slot) => {
+ // Create item macro if rollable item - weapon, spell, prayer, trait, or skill
+ if (documentData.type == "Item") {
+ console.log("Drop done !!!", bar, documentData, slot)
+ let item = documentData.data
+ let command = `game.bol.BoLHotbar.rollMacro("${item.name}", "${item.type}");`
+ let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command))
+ if (!macro) {
+ macro = await Macro.create({
+ name: item.name,
+ type: "script",
+ img: item.img,
+ command: command
+ }, { displaySheet: false })
+ }
+ game.user.assignHotbarMacro(macro, slot);
+ }
+ // Create a macro to open the actor sheet of the actor dropped on the hotbar
+ else if (documentData.type == "Actor") {
+ let actor = game.actors.get(documentData.id);
+ let command = `game.actors.get("${documentData.id}").sheet.render(true)`
+ let macro = game.macros.contents.find(m => (m.name === actor.name) && (m.command === command));
+ if (!macro) {
+ macro = await Macro.create({
+ name: actor.data.name,
+ type: "script",
+ img: actor.data.img,
+ command: command
+ }, { displaySheet: false })
+ game.user.assignHotbarMacro(macro, slot);
+ }
+ }
+ // Create a macro to open the journal sheet of the journal dropped on the hotbar
+ else if (documentData.type == "JournalEntry") {
+ let journal = game.journal.get(documentData.id);
+ let command = `game.journal.get("${documentData.id}").sheet.render(true)`
+ let macro = game.macros.contents.find(m => (m.name === journal.name) && (m.command === command));
+ if (!macro) {
+ macro = await Macro.create({
+ name: journal.data.name,
+ type: "script",
+ img: "systems/bol/icons/images/icone_parchement_vierge.webp",
+ command: command
+ }, { displaySheet: false })
+ game.user.assignHotbarMacro(macro, slot);
+ }
+ }
+ return false;
+ });
+ }
+
+ /** Roll macro */
+ static rollMacro(itemName, itemType, bypassData) {
+ const speaker = ChatMessage.getSpeaker()
+ let actor
+ if (speaker.token) actor = game.actors.tokens[speaker.token]
+ if (!actor) actor = game.actors.get(speaker.actor)
+ if (!actor) {
+ return ui.notifications.warn(`Selectionnez votre personnage pour utiliser la macro`)
+ }
+
+ let item = actor.items.find(it => it.name === itemName && it.type == itemType)
+ if (!item ) {
+ return ui.notifications.warn(`Impossible de trouver l'objet de cette macro`)
+ }
+ // Trigger the item roll
+ if (item.data.data.category === "equipment" && item.data.data.subtype === "weapon") {
+ return BoLRoll.weaponCheckWithWeapon( actor, item)
+ }
+ if (item.data.data.category === "spell") {
+ return BoLRoll.spellCheckWithSpell( actor, item)
+ }
+ }
+
+}
diff --git a/module/system/bol-utility.js b/module/system/bol-utility.js
index 80a1973..5abaae7 100644
--- a/module/system/bol-utility.js
+++ b/module/system/bol-utility.js
@@ -32,7 +32,6 @@ export class BoLUtility {
this.rollArmor = game.settings.get("bol", "rollArmor") // Roll armor or not
this.useBougette = game.settings.get("bol", "useBougette") // Use optionnal bougette rules
- console.log("UTIL", this)
}
@@ -127,6 +126,17 @@ export class BoLUtility {
}
return undefined;
}
+ /* -------------------------------------------- */
+ static getOtherWhisperRecipients( name) {
+ let users = []
+ for( let user of game.users) {
+ if ( !user.isGM && user.name != name) {
+ users.push( user.data._id)
+ }
+ }
+ return users
+ }
+
/* -------------------------------------------- */
static getWhisperRecipientsAndGMs(name) {
let recep1 = ChatMessage.getWhisperRecipients(name) || [];
@@ -154,9 +164,25 @@ export class BoLUtility {
}
}
+ /* -------------------------------------------- */
+ static async chatMessageHandler(message, html, data) {
+ const chatCard = html.find('.flavor-text')
+ if (chatCard.length > 0) {
+ // If the user is the message author or the actor owner, proceed
+ const actor = game.actors.get(data.message.speaker.actor)
+ console.log("FOUND 1!!! ", actor)
+ if (actor && actor.isOwner) return
+ else if (game.user.isGM || data.author.id === game.user.id) return
+
+ const divButtons = chatCard.find('.actions-section')
+ console.log("FOUND 2!! ", divButtons)
+ divButtons.hide()
+ }
+ }
+
/* -------------------------------------------- */
static async chatListeners(html) {
-
+
// Damage handling
html.on("click", '.chat-damage-apply', event => {
let rollData = BoLUtility.getLastRoll()
@@ -172,13 +198,21 @@ export class BoLUtility {
bolRoll.rollDamage()
});
+ html.on("click", '.transform-legendary-roll', event => {
+ event.preventDefault();
+ let rollData = BoLUtility.getLastRoll()
+ rollData.actor.subHeroPoints(1)
+ let r = new BoLDefaultRoll(rollData)
+ r.upgradeToLegendary()
+ })
+
html.on("click", '.transform-heroic-roll', event => {
event.preventDefault();
let rollData = BoLUtility.getLastRoll()
rollData.actor.subHeroPoints(1)
let r = new BoLDefaultRoll(rollData)
- r.upgradeToCritical();
- });
+ r.upgradeToHeroic()
+ })
html.on("click", '.hero-reroll', event => {
event.preventDefault();
diff --git a/module/system/helpers.js b/module/system/helpers.js
index cc56ba4..4bf38df 100644
--- a/module/system/helpers.js
+++ b/module/system/helpers.js
@@ -1,123 +1,129 @@
export const registerHandlebarsHelpers = function () {
- Handlebars.registerHelper('isNull', function (val) {
- return val == null;
- });
+ Handlebars.registerHelper('isNull', function (val) {
+ return val == null;
+ });
- Handlebars.registerHelper('exists', function (val) {
- return val != null && val != undefined;
- });
+ Handlebars.registerHelper('exists', function (val) {
+ return val != null && val != undefined;
+ });
- Handlebars.registerHelper('isEmpty', function (list) {
- if (list) return list.length == 0;
- else return 0;
- });
+ Handlebars.registerHelper('isEmpty', function (list) {
+ if (list) return list.length == 0;
+ else return 0;
+ });
- Handlebars.registerHelper('notEmpty', function (list) {
- return list.length > 0;
- });
+ Handlebars.registerHelper('notEmpty', function (list) {
+ return list.length > 0;
+ });
- Handlebars.registerHelper('isNegativeOrNull', function (val) {
- return val <= 0;
- });
+ Handlebars.registerHelper('isNegativeOrNull', function (val) {
+ return val <= 0;
+ });
- Handlebars.registerHelper('isNegative', function (val) {
- return val < 0;
- });
+ Handlebars.registerHelper('isNegative', function (val) {
+ return val < 0;
+ });
- Handlebars.registerHelper('isPositive', function (val) {
- return val > 0;
- });
+ Handlebars.registerHelper('isPositive', function (val) {
+ return val > 0;
+ });
- Handlebars.registerHelper('equals', function (val1, val2) {
- return val1 == val2;
- });
+ Handlebars.registerHelper('equals', function (val1, val2) {
+ return val1 == val2;
+ });
- Handlebars.registerHelper('neq', function (val1, val2) {
- return val1 !== val2;
- });
+ Handlebars.registerHelper('neq', function (val1, val2) {
+ return val1 !== val2;
+ });
- Handlebars.registerHelper('gt', function (val1, val2) {
- return val1 > val2;
- })
+ Handlebars.registerHelper('gt', function (val1, val2) {
+ return val1 > val2;
+ })
- Handlebars.registerHelper('lt', function (val1, val2) {
- return val1 < val2;
- })
+ Handlebars.registerHelper('lt', function (val1, val2) {
+ return val1 < val2;
+ })
- Handlebars.registerHelper('gte', function (val1, val2) {
- return val1 >= val2;
- })
+ Handlebars.registerHelper('gte', function (val1, val2) {
+ return val1 >= val2;
+ })
- Handlebars.registerHelper('lte', function (val1, val2) {
- return val1 <= val2;
- })
- Handlebars.registerHelper('and', function (val1, val2) {
- return val1 && val2;
- })
- Handlebars.registerHelper('or', function (val1, val2) {
- return val1 || val2;
- })
+ Handlebars.registerHelper('lte', function (val1, val2) {
+ return val1 <= val2;
+ })
+ Handlebars.registerHelper('and', function (val1, val2) {
+ return val1 && val2;
+ })
+ Handlebars.registerHelper('or', function (val1, val2) {
+ return val1 || val2;
+ })
- Handlebars.registerHelper('or3', function (val1, val2, val3) {
- return val1 || val2 || val3;
- })
-
- Handlebars.registerHelper('for', function(from, to, incr, block) {
- var accum = '';
- for(var i = from; i < to; i += incr)
- accum += block.fn(i);
- return accum;
- })
-
- Handlebars.registerHelper('not', function (cond) {
- return !cond;
- })
- Handlebars.registerHelper('count', function (list) {
- return list.length;
- })
- Handlebars.registerHelper('isEnabled', function (configKey) {
- return game.settings.get("bol", configKey);
- })
- Handlebars.registerHelper('split', function (str, separator, keep) {
- return str.split(separator)[keep];
- })
+ Handlebars.registerHelper('or3', function (val1, val2, val3) {
+ return val1 || val2 || val3;
+ })
- // If you need to add Handlebars helpers, here are a few useful examples:
- Handlebars.registerHelper('concat', function () {
- var outStr = '';
- for (var arg in arguments) {
- if (typeof arguments[arg] != 'object') {
- outStr += arguments[arg];
- }
- }
- return outStr;
- })
+ Handlebars.registerHelper('for', function (from, to, incr, block) {
+ var accum = '';
+ for (var i = from; i < to; i += incr)
+ accum += block.fn(i);
+ return accum;
+ })
- Handlebars.registerHelper('add', function (a, b) {
- return parseInt(a) + parseInt(b);
- });
- Handlebars.registerHelper('mul', function (a, b) {
- return parseInt(a) * parseInt(b);
- })
- Handlebars.registerHelper('sub', function (a, b) {
- return parseInt(a) - parseInt(b);
- })
- Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
- return arr[idx];
- })
- Handlebars.registerHelper('includesKey', function (items, type, key) {
- // console.log(items);
- return items.filter(i => i.type === type).map(i => i.data.key).includes(key);
- })
- Handlebars.registerHelper('includes', function (array, val) {
- return array.includes(val);
- })
- Handlebars.registerHelper('eval', function (expr) {
- return eval(expr);
- })
+ Handlebars.registerHelper('not', function (cond) {
+ return !cond;
+ })
+ Handlebars.registerHelper('count', function (list) {
+ return list.length;
+ })
+ Handlebars.registerHelper('isEnabled', function (configKey) {
+ return game.settings.get("bol", configKey);
+ })
+ Handlebars.registerHelper('split', function (str, separator, keep) {
+ return str.split(separator)[keep];
+ })
+
+ // If you need to add Handlebars helpers, here are a few useful examples:
+ Handlebars.registerHelper('concat', function () {
+ var outStr = '';
+ for (var arg in arguments) {
+ if (typeof arguments[arg] != 'object') {
+ outStr += arguments[arg];
+ }
+ }
+ return outStr;
+ })
+
+ Handlebars.registerHelper('add', function (a, b) {
+ return parseInt(a) + parseInt(b);
+ });
+ Handlebars.registerHelper('mul', function (a, b) {
+ return parseInt(a) * parseInt(b);
+ })
+ Handlebars.registerHelper('sub', function (a, b) {
+ return parseInt(a) - parseInt(b);
+ })
+ Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
+ return arr[idx];
+ })
+ Handlebars.registerHelper('includesKey', function (items, type, key) {
+ // console.log(items);
+ return items.filter(i => i.type === type).map(i => i.data.key).includes(key);
+ })
+ Handlebars.registerHelper('includes', function (array, val) {
+ return array.includes(val);
+ })
+ Handlebars.registerHelper('eval', function (expr) {
+ return eval(expr);
+ })
+ Handlebars.registerHelper('isOwnerOrGM', function (actor) {
+ console.log("Testing actor", actor.isOwner, game.userId)
+ if (actor.isOwner || game.isGM) {
+ return true
+ }
+ return false
+ })
-
}
\ No newline at end of file
diff --git a/module/system/hooks.js b/module/system/hooks.js
index 268c0a4..c50c97f 100644
--- a/module/system/hooks.js
+++ b/module/system/hooks.js
@@ -14,7 +14,8 @@ export default function registerHooks() {
html.find("img").attr("src", "systems/bol/ui/pause2.webp")
}))
- Hooks.on('renderChatLog', (log, html, data) => BoLUtility.chatListeners(html));
+ Hooks.on('renderChatLog', (log, html, data) => BoLUtility.chatListeners(html))
+ Hooks.on('renderChatMessage', (message, html, data) => BoLUtility.chatMessageHandler(message, html, data))
/**
* Create a macro when dropping an entity on the hotbar
diff --git a/system.json b/system.json
index cec1dab..0c5e594 100644
--- a/system.json
+++ b/system.json
@@ -14,7 +14,7 @@
"url": "https://github.com/ZigmundKreud/bol",
"license": "LICENSE.txt",
"flags": {},
- "version": "1.2.7",
+ "version": "1.3.0",
"minimumCoreVersion": "0.8.6",
"compatibleCoreVersion": "9",
"scripts": [],
diff --git a/templates/chat/rolls/aptitude-roll-card.hbs b/templates/chat/rolls/aptitude-roll-card.hbs
deleted file mode 100644
index e69de29..0000000
diff --git a/templates/chat/rolls/attack-roll-card.hbs b/templates/chat/rolls/attack-roll-card.hbs
deleted file mode 100644
index e69de29..0000000
diff --git a/templates/chat/rolls/damage-roll-card.hbs b/templates/chat/rolls/damage-roll-card.hbs
index 7294674..ee87853 100644
--- a/templates/chat/rolls/damage-roll-card.hbs
+++ b/templates/chat/rolls/damage-roll-card.hbs
@@ -1,9 +1,14 @@