From 16cf35aed6e90aaa597236971db1a68bdd13c7ff Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Fri, 6 Mar 2026 08:06:57 +0100 Subject: [PATCH] More tests againts rolls --- adventures-with-emmy.mjs | 3 + lang/en.json | 3 + module/documents/actor.mjs | 18 +- module/documents/chat-message.mjs | 15 +- module/documents/roll.mjs | 126 +++++++--- styles/adventures-with-emmy.less | 392 ++++++++++++++++++++++++++++-- templates/ability.hbs | 39 +-- templates/archetype.hbs | 17 +- templates/background.hbs | 17 +- templates/chat-message.hbs | 42 +++- templates/equipment.hbs | 33 ++- templates/field.hbs | 37 +-- templates/kit.hbs | 22 +- templates/roll-dialog.hbs | 60 ++++- templates/weapon.hbs | 38 +-- 15 files changed, 677 insertions(+), 185 deletions(-) diff --git a/adventures-with-emmy.mjs b/adventures-with-emmy.mjs index 1b42497..9ff70d3 100644 --- a/adventures-with-emmy.mjs +++ b/adventures-with-emmy.mjs @@ -66,6 +66,9 @@ Hooks.once("init", function () { CONFIG.ChatMessage.documentClass = documents.AwEChatMessage CONFIG.Dice.rolls.push(documents.AwERoll) + + // Handlebars helpers + Handlebars.registerHelper("abs", (value) => Math.abs(value ?? 0)) }) Hooks.once("ready", function () { diff --git a/lang/en.json b/lang/en.json index fe23530..1c4bcc6 100644 --- a/lang/en.json +++ b/lang/en.json @@ -49,6 +49,9 @@ "AWEMMY.Roll.Roll": "Roll", "AWEMMY.Roll.DialogTitle": "Roll: {name}", "AWEMMY.Roll.SituationalBonus": "Situational Bonus", + "AWEMMY.Roll.AttributeBonus": "Attribute Bonus", + "AWEMMY.Roll.KnowledgeBonus": "Knowledge Bonus", + "AWEMMY.Roll.Formula": "Formula", "AWEMMY.Roll.DC": "DC", "AWEMMY.Roll.Visibility": "Visibility", "AWEMMY.Roll.Private": "Private Roll", diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index b038bbd..a68f205 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -42,12 +42,20 @@ export default class AwEActor extends Actor { const attribute = this.system.attributes[attributeId] if (!attribute) return null + // Collect knowledge bonuses from embedded Field items + const knowledgeBonuses = this.itemTypes.field?.map(f => ({ + label: f.name, + bonus: f.system.knowledgeBonus ?? "" + })).filter(f => f.bonus !== "") ?? [] + return AwERoll.prompt({ - attributeKey: attributeId, - modifier: attribute.mod ?? 0, - actorId: this.id, - actorName: this.name, - actorImage: this.img, + attributeKey: attributeId, + modifier: attribute.mod ?? 0, + attributeBonus: attribute.bonus ?? 0, + knowledgeBonuses, + actorId: this.id, + actorName: this.name, + actorImage: this.img, ...options }) } diff --git a/module/documents/chat-message.mjs b/module/documents/chat-message.mjs index bcfdf7c..911f43e 100644 --- a/module/documents/chat-message.mjs +++ b/module/documents/chat-message.mjs @@ -5,19 +5,8 @@ export default class AwEChatMessage extends ChatMessage { async _renderRollContent(messageData) { if (this.rolls[0] instanceof AwERoll) { const isPrivate = !this.isContentVisible - const roll = this.rolls[0] - - const html = await foundry.applications.handlebars.renderTemplate( - AwERoll.CHAT_TEMPLATE, - { - flavor: this.flavor, - total: roll.total, - outcome: isPrivate ? null : roll.outcome, - dc: roll.dc, - isPrivate - } - ) - messageData.message.content = html + const rollHTML = await this._renderRollHTML(isPrivate) + messageData.message.content = rollHTML return } return super._renderRollContent(messageData) diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 229a1d7..409c1f3 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -6,15 +6,17 @@ export default class AwERoll extends Roll { // --- Accessors for roll options --- - get attributeKey() { return this.options.attributeKey } - get rollName() { return this.options.rollName } - get modifier() { return this.options.modifier ?? 0 } - get bonus() { return this.options.bonus ?? 0 } - get dc() { return this.options.dc } - get outcome() { return this.options.outcome } - get actorId() { return this.options.actorId } - get actorName() { return this.options.actorName } - get actorImage() { return this.options.actorImage } + get attributeKey() { return this.options.attributeKey } + get rollName() { return this.options.rollName } + get modifier() { return this.options.modifier ?? 0 } + get attributeBonus() { return this.options.attributeBonus ?? 0 } + get bonus() { return this.options.bonus ?? 0 } + get knowledgeBonus() { return this.options.knowledgeBonus ?? 0 } + get dc() { return this.options.dc } + get outcome() { return this.options.outcome } + get actorId() { return this.options.actorId } + get actorName() { return this.options.actorName } + get actorImage() { return this.options.actorImage } // --- Outcome calculation --- @@ -51,38 +53,74 @@ export default class AwERoll extends Roll { * then evaluate and post the roll to chat. * * @param {object} options - * @param {string} options.attributeKey Attribute id (agility | fitness | awareness | influence) - * @param {number} options.modifier Base attribute modifier - * @param {number} [options.dc] Pre-set DC (skips DC field if provided) + * @param {string} options.attributeKey Attribute id (agility | fitness | awareness | influence) + * @param {number} options.modifier Base attribute modifier (level + boostLevel) + * @param {number} [options.attributeBonus] Persistent attribute bonus/penalty from the +/- column + * @param {object[]} [options.knowledgeBonuses] Field knowledge bonuses [{label, bonus}] + * @param {number} [options.dc] Pre-set DC * @param {string} options.actorId * @param {string} options.actorName * @param {string} options.actorImage * @returns {Promise} Resolved roll, or null if dialog was cancelled */ static async prompt(options = {}) { - const attrLabel = options.attributeKey + const attrLabel = options.attributeKey ? game.i18n.localize(SYSTEM.ATTRIBUTES[options.attributeKey]?.label ?? options.attributeKey) : (options.rollName ?? game.i18n.localize("AWEMMY.Roll.Check")) + const mod = options.modifier ?? 0 + const attrBonus = options.attributeBonus ?? 0 + const knowledgeBonuses = options.knowledgeBonuses ?? [] const rollModes = Object.fromEntries( Object.entries(CONFIG.Dice.rollModes).map(([k, v]) => [k, game.i18n.localize(v.label ?? v)]) ) + // Bonus choices: -5 to +5 + const bonusChoices = Array.from({length: 11}, (_, i) => i - 5) + .map(v => ({ value: v, label: v > 0 ? `+${v}` : String(v), selected: v === 0 })) + + // DC choices: blank + 10..30 + const dcChoices = [{ value: "", label: "—", selected: !options.dc }] + .concat(Array.from({length: 21}, (_, i) => i + 10) + .map(v => ({ value: v, label: String(v), selected: v === (options.dc ?? null) }))) + const content = await foundry.applications.handlebars.renderTemplate( "systems/fvtt-adventures-with-emmy/templates/roll-dialog.hbs", { attrLabel, - modifier: options.modifier ?? 0, - dc: options.dc ?? "", + modifier: mod, + attributeBonus: attrBonus, + totalMod: mod + attrBonus, + knowledgeBonuses, + bonusChoices, + dcChoices, rollModes, - visibility: game.settings.get("core", "rollMode") + visibility: game.settings.get("core", "rollMode") } ) const result = await foundry.applications.api.DialogV2.wait({ - window: { title: game.i18n.format("AWEMMY.Roll.DialogTitle", { name: attrLabel }) }, - classes: ["awemmy"], + window: { title: game.i18n.format("AWEMMY.Roll.DialogTitle", { name: attrLabel }) }, + classes: ["awemmy"], content, + render: (event, dialog) => { + const baseMod = mod + attrBonus + const el = dialog.element + const bonusSelect = el.querySelector('#awe-bonus') + const knowledgeSel = el.querySelector('#awe-knowledge') + const preview = el.querySelector('#awe-formula-preview') + function updatePreview() { + const sit = parseInt(bonusSelect?.value) || 0 + const kn = parseInt(knowledgeSel?.value) || 0 + const total = baseMod + sit + kn + const sign = total >= 0 ? '+' : '−' + const abs = Math.abs(total) + preview.textContent = total === 0 ? '1d20' : `1d20 ${sign} ${abs}` + } + bonusSelect?.addEventListener('change', updatePreview) + knowledgeSel?.addEventListener('change', updatePreview) + updatePreview() + }, buttons: [{ label: game.i18n.localize("AWEMMY.Roll.Roll"), callback: (_event, button) => @@ -96,25 +134,28 @@ export default class AwERoll extends Roll { if (!result) return null - const mod = options.modifier ?? 0 - const bonus = parseInt(result.bonus) || 0 - const dc = result.dc !== "" ? parseInt(result.dc) : undefined - const rollMode = result.visibility ?? game.settings.get("core", "rollMode") + const bonus = parseInt(result.bonus) || 0 + const knowledgeBonus = parseInt(result.knowledgeBonus) || 0 + const dc = result.dc !== "" ? parseInt(result.dc) : undefined + const rollMode = result.visibility ?? game.settings.get("core", "rollMode") - // Build formula: 1d20 + mod [± bonus] - let formula = `1d20 + ${mod}` - if (bonus > 0) formula += ` + ${bonus}` - else if (bonus < 0) formula += ` - ${Math.abs(bonus)}` + // Formula: 1d20 + (mod + attrBonus) [± bonus] [± knowledgeBonus] + const totalMod = mod + attrBonus + bonus + knowledgeBonus + let formula = `1d20` + if (totalMod > 0) formula += ` + ${totalMod}` + else if (totalMod < 0) formula += ` - ${Math.abs(totalMod)}` const roll = new this(formula, {}, { - attributeKey: options.attributeKey, - rollName: attrLabel, - modifier: mod, + attributeKey: options.attributeKey, + rollName: attrLabel, + modifier: mod + attrBonus, + attributeBonus: attrBonus, bonus, + knowledgeBonus, dc, - actorId: options.actorId, - actorName: options.actorName, - actorImage: options.actorImage + actorId: options.actorId, + actorName: options.actorName, + actorImage: options.actorImage }) await roll.evaluate() @@ -133,4 +174,25 @@ export default class AwERoll extends Roll { return roll } + + /** @override — render the custom chat message template */ + async render(chatOptions = {}) { + const isPrivate = chatOptions.isPrivate ?? false + return foundry.applications.handlebars.renderTemplate( + AwERoll.CHAT_TEMPLATE, + { + flavor: this.rollName, + total: this.total, + modifier: this.modifier, + bonus: this.bonus, + knowledgeBonus: this.knowledgeBonus, + dice: this.dice, + outcome: isPrivate ? null : this.outcome, + dc: this.dc, + actorName: this.actorName, + actorImage: this.actorImage, + isPrivate + } + ) + } } diff --git a/styles/adventures-with-emmy.less b/styles/adventures-with-emmy.less index 59a1ff3..26d2bb7 100644 --- a/styles/adventures-with-emmy.less +++ b/styles/adventures-with-emmy.less @@ -126,8 +126,8 @@ .attributes-table { width: 100%; border-collapse: collapse; - margin: 0.3rem 0; - font-size: 0.85rem; + margin: 0.1rem 0; + font-size: 0.8rem; // Col widths: name | boost | mod | dc | bonus th:nth-child(1), td:nth-child(1) { width: 30%; } @@ -141,9 +141,9 @@ color: white; th { - padding: 0.25rem 0.4rem; + padding: 0.15rem 0.3rem; text-align: center; - font-size: 0.75rem; + font-size: 0.72rem; text-transform: uppercase; } } @@ -154,15 +154,15 @@ } td { - padding: 0.2rem 0.4rem; + padding: 0.05rem 0.3rem; text-align: center; border-bottom: 1px solid @color-border; select { width: auto; - min-width: 55px; - padding: 0.1rem 0.25rem; - font-size: 0.82rem; + min-width: 50px; + padding: 0 0.2rem; + font-size: 0.78rem; background: white; color: @color-text; border: 1px solid @color-border; @@ -170,10 +170,10 @@ } input { - width: 48px; + width: 44px; text-align: center; - padding: 0.1rem 0.2rem; - font-size: 0.82rem; + padding: 0 0.2rem; + font-size: 0.78rem; background: white; color: @color-text; border: 1px solid @color-border; @@ -372,6 +372,11 @@ // Character Sheet Header // -------------------------------------------------------- .character-content { + fieldset { + padding: 0.3rem 0.5rem; + margin: 0.3rem 0; + } + .actor-header { display: grid; grid-template-columns: 80px 1fr auto auto; @@ -631,18 +636,22 @@ // Item Sheets // ============================================================ +// ============================================================ +// Item Sheets +// ============================================================ + .awemmy.item { .item-header { display: flex; align-items: center; gap: 0.75rem; - padding: 0.5rem; + padding: 0.5rem 0.75rem; background: lighten(@color-primary, 50%); border-bottom: 2px solid @color-border; .item-img { - width: 56px; - height: 56px; + width: 52px; + height: 52px; object-fit: cover; border: 2px solid @color-border; border-radius: 4px; @@ -655,7 +664,7 @@ input[type="text"] { font-family: @font-heading; - font-size: 1.2rem; + font-size: 1.15rem; font-weight: bold; flex: 1; border: none; @@ -669,19 +678,149 @@ } .item-body { - padding: 0.5rem; + padding: 0.6rem 0.75rem; + display: flex; + flex-direction: column; + gap: 0.3rem; + // Single field row: label | input .form-group { display: flex; align-items: center; gap: 0.5rem; - margin-bottom: 0.4rem; + min-height: 28px; label { - min-width: 120px; - font-size: 0.85rem; + width: 38%; + flex-shrink: 0; + font-size: 0.8rem; + font-weight: 600; color: @color-text-light; text-transform: uppercase; + letter-spacing: 0.03em; + } + + input, select { + flex: 1; + min-width: 0; + } + } + + // Two fields side by side + .form-row { + display: flex; + gap: 0.75rem; + + .form-group { + flex: 1; + } + } + + // Charges: value / max inline + .charges-group { + display: flex; + align-items: center; + gap: 0.4rem; + + label { + width: 38%; + flex-shrink: 0; + font-size: 0.8rem; + font-weight: 600; + color: @color-text-light; + text-transform: uppercase; + } + + input { + width: 48px; + text-align: center; + } + + .separator { + color: @color-text-light; + font-weight: bold; + } + } + + // Tags (traits, specializations) + .form-group-tags { + display: flex; + align-items: flex-start; + gap: 0.5rem; + + label { + width: 38%; + flex-shrink: 0; + font-size: 0.8rem; + font-weight: 600; + color: @color-text-light; + text-transform: uppercase; + padding-top: 0.25rem; + } + + .tags-list { + flex: 1; + display: flex; + flex-wrap: wrap; + gap: 0.3rem; + align-items: center; + + .tag { + display: inline-flex; + align-items: center; + gap: 0.2rem; + padding: 0.15rem 0.5rem; + background: lighten(@color-primary, 48%); + border: 1px solid @color-border; + border-radius: 12px; + font-size: 0.78rem; + color: @color-text; + + a { + color: @color-text-light; + cursor: pointer; + font-weight: bold; + line-height: 1; + + &:hover { + color: @color-secondary; + } + } + } + + .new-tag { + width: 110px; + font-size: 0.78rem; + padding: 0.15rem 0.4rem; + border-style: dashed; + } + } + } + + // Divider between properties and description + .section-divider { + border: none; + border-top: 1px solid @color-border; + margin: 0.3rem 0; + } + + // Description fieldset + fieldset { + border: 1px solid @color-border; + border-radius: 4px; + padding: 0.4rem 0.6rem; + margin-top: 0.3rem; + + legend { + font-size: 0.78rem; + font-weight: 600; + color: @color-text-light; + text-transform: uppercase; + padding: 0 0.3rem; + } + + .editor, .prosemirror, textarea { + min-height: 100px; } } } @@ -739,3 +878,218 @@ &.critical-failure { background: @color-critical-failure; color: white; } } } + +// ============================================================ +// Roll Dialog +// ============================================================ + +.awemmy.dialog { + .awemmy-roll-dialog { + padding: 0.5rem 0.25rem; + + .roll-header { + display: flex; + justify-content: space-between; + align-items: baseline; + padding: 0.4rem 0.5rem; + background: lighten(@color-primary, 50%); + border-radius: 4px; + margin-bottom: 0.5rem; + border-left: 4px solid @color-primary; + + .roll-attr-name { + font-family: @font-heading; + font-size: 1.05rem; + font-weight: bold; + color: @color-primary; + } + + .roll-formula-summary { + font-size: 0.85rem; + color: @color-text-light; + + em { + color: @color-secondary; + font-style: normal; + font-weight: bold; + } + } + } + + .dialog-row { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.35rem; + + label { + width: 42%; + flex-shrink: 0; + font-size: 0.8rem; + font-weight: 600; + color: @color-text-light; + text-transform: uppercase; + } + + input, select { + flex: 1; + min-width: 0; + background: white; + color: @color-text; + border: 1px solid @color-border; + border-radius: 3px; + padding: 0.2rem 0.35rem; + font-size: 0.85rem; + } + } + + .hint-row { + justify-content: space-between; + background: lighten(@color-border, 10%); + border-radius: 3px; + padding: 0.15rem 0.5rem; + font-size: 0.8rem; + + .hint-label { color: @color-text-light; font-weight: 600; text-transform: uppercase; } + .hint-value { font-weight: bold; + &.positive { color: @color-success; } + &.negative { color: @color-failure; } + } + } + + .formula-preview { + background: lighten(@color-primary, 52%); + border-radius: 3px; + padding: 0.2rem 0.5rem; + margin-top: 0.2rem; + + .formula-label { + width: 42%; + flex-shrink: 0; + font-size: 0.78rem; + font-weight: 600; + color: @color-text-light; + text-transform: uppercase; + } + + .formula-text { + font-family: monospace; + font-size: 0.95rem; + font-weight: bold; + color: @color-primary; + } + } + } +} + +// ============================================================ +// Chat Message (updated) +// ============================================================ + +.awemmy-chat { + padding: 0.4rem; + + .chat-roll-header { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.4rem; + + .chat-actor-img { + width: 34px; + height: 34px; + border-radius: 50%; + border: 2px solid @color-border; + object-fit: cover; + } + + .chat-roll-info { + display: flex; + flex-direction: column; + gap: 0.1rem; + } + + .chat-actor-name { + font-size: 0.75rem; + color: @color-text-light; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.04em; + } + + .chat-roll-label { + font-family: @font-heading; + font-size: 0.95rem; + font-weight: bold; + color: @color-primary; + } + } + + .roll-breakdown { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.5rem; + background: lighten(@color-primary, 50%); + border-radius: 4px; + margin: 0.35rem 0; + font-size: 1rem; + + .die-result { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-weight: bold; + color: @color-text; + + &.max { color: @color-critical-success; } + &.min { color: @color-critical-failure; } + + i { color: @color-primary; font-size: 1.1rem; } + } + + .roll-mod { + color: @color-text-light; + font-size: 0.9rem; + } + + .roll-equals { + color: @color-text-light; + } + + .roll-total { + font-family: @font-heading; + font-size: 1.4rem; + font-weight: bold; + color: @color-primary; + } + + .roll-dc { + font-size: 0.8rem; + color: @color-text-light; + border-left: 1px solid @color-border; + padding-left: 0.5rem; + } + } + + .outcome-badge { + text-align: center; + padding: 0.25rem 0.75rem; + border-radius: 12px; + font-weight: bold; + font-size: 0.88rem; + + &.criticalSuccess { background: @color-critical-success; color: white; } + &.success { background: @color-success; color: white; } + &.failure { background: @color-failure; color: white; } + &.criticalFailure { background: @color-critical-failure; color: white; } + } + + .private-result { + text-align: center; + color: @color-text-light; + font-size: 0.85rem; + padding: 0.5rem; + } +} diff --git a/templates/ability.hbs b/templates/ability.hbs index c4a5efb..81913eb 100644 --- a/templates/ability.hbs +++ b/templates/ability.hbs @@ -4,27 +4,34 @@ {{formInput fields.name value=source.name}}
-
- - {{formField systemFields.abilityType value=system.abilityType localize=true}} -
-
- - {{formField systemFields.cost value=system.cost localize=true}} + +
+
+ + {{formField systemFields.abilityType value=system.abilityType localize=true}} +
+
+ + {{formField systemFields.cost value=system.cost localize=true}} +
+
{{formInput systemFields.frequency value=system.frequency}}
+
{{formInput systemFields.requirements value=system.requirements}}
+
{{formInput systemFields.trigger value=system.trigger}}
-
+ +
{{#each system.traits}} @@ -33,15 +40,11 @@
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/archetype.hbs b/templates/archetype.hbs index 84c9887..f4470a5 100644 --- a/templates/archetype.hbs +++ b/templates/archetype.hbs @@ -4,19 +4,16 @@ {{formInput fields.name value=source.name}}
+
{{formInput systemFields.prerequisiteLevel value=system.prerequisiteLevel}}
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/background.hbs b/templates/background.hbs index 3edb02a..78dd0f5 100644 --- a/templates/background.hbs +++ b/templates/background.hbs @@ -4,19 +4,16 @@ {{formInput fields.name value=source.name}}
+
{{formInput systemFields.bonus value=system.bonus}}
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/chat-message.hbs b/templates/chat-message.hbs index 9c1cfe8..98c21c8 100644 --- a/templates/chat-message.hbs +++ b/templates/chat-message.hbs @@ -1,14 +1,48 @@
+ + {{!-- Header: portrait + actor name + attribute --}}
-
{{flavor}}
+ {{#if actorImage}} + {{actorName}} + {{/if}} +
+ {{#if actorName}}
{{actorName}}
{{/if}} +
{{flavor}}
+
{{#unless isPrivate}} -
- {{total}} + + {{!-- Dice breakdown --}} +
+ {{#each dice}} + {{#each results}} + + {{result}} + + {{/each}} + {{/each}} + {{#if modifier}} + + {{#if (gt modifier 0)}}+ {{modifier}}{{else if (lt modifier 0)}}− {{abs modifier}}{{/if}} + + {{/if}} + {{#if bonus}} + + {{#if (gt bonus 0)}}+ {{bonus}}{{else if (lt bonus 0)}}− {{abs bonus}}{{/if}} + + {{/if}} + {{#if knowledgeBonus}} + + {{#if (gt knowledgeBonus 0)}}+ {{knowledgeBonus}}{{else if (lt knowledgeBonus 0)}}− {{abs knowledgeBonus}}{{/if}} + + {{/if}} + = + {{total}} {{#if dc}}/ DC {{dc}}{{/if}}
+ {{!-- Outcome badge --}} {{#if outcome}}
{{#if (eq outcome "criticalSuccess")}} @@ -22,9 +56,11 @@ {{/if}}
{{/if}} + {{else}}
{{localize "AWEMMY.Roll.Private"}}
{{/unless}} +
diff --git a/templates/equipment.hbs b/templates/equipment.hbs index c3fe5d6..6443ec3 100644 --- a/templates/equipment.hbs +++ b/templates/equipment.hbs @@ -4,23 +4,22 @@ {{formInput fields.name value=source.name}}
-
- - {{formInput systemFields.quantity value=system.quantity}} -
-
- - {{formInput systemFields.weight value=system.weight}} + +
+
+ + {{formInput systemFields.quantity value=system.quantity}} +
+
+ + {{formInput systemFields.weight value=system.weight}} +
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/field.hbs b/templates/field.hbs index 717430d..629ce45 100644 --- a/templates/field.hbs +++ b/templates/field.hbs @@ -4,19 +4,24 @@ {{formInput fields.name value=source.name}}
-
- - {{formField systemFields.keyAttribute value=system.keyAttribute localize=true}} -
-
- - {{formField systemFields.keyAttribute2 value=system.keyAttribute2 localize=true}} + +
+
+ + {{formField systemFields.keyAttribute value=system.keyAttribute localize=true}} +
+
+ + {{formField systemFields.keyAttribute2 value=system.keyAttribute2 localize=true}} +
+
{{formInput systemFields.knowledgeBonus value=system.knowledgeBonus}}
-
+ +
{{#each system.specializations}} @@ -25,15 +30,11 @@
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/kit.hbs b/templates/kit.hbs index 35b542f..497b71a 100644 --- a/templates/kit.hbs +++ b/templates/kit.hbs @@ -4,25 +4,23 @@ {{formInput fields.name value=source.name}}
+
{{formInput systemFields.fieldName value=system.fieldName}}
-
+ +
{{formInput systemFields.charges.fields.value value=system.charges.value}} - / + / {{formInput systemFields.charges.fields.max value=system.charges.max}}
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -
diff --git a/templates/roll-dialog.hbs b/templates/roll-dialog.hbs index 04a46ba..c156059 100644 --- a/templates/roll-dialog.hbs +++ b/templates/roll-dialog.hbs @@ -1,26 +1,65 @@
- {{! Attribute name + base modifier (read-only) }} -
- {{attrLabel}} - - {{#if (gt modifier 0)}}+{{modifier}}{{else}}{{modifier}}{{/if}} + {{!-- Attribute name + modifier breakdown --}} +
+ {{attrLabel}} + + 1d20 + {{#if (gt modifier 0)}} + {{modifier}}{{else if (lt modifier 0)}} − {{abs modifier}}{{/if}} + {{#if (gt attributeBonus 0)}} + {{attributeBonus}}{{else if (lt attributeBonus 0)}} − {{abs attributeBonus}}{{/if}}
- {{! Situational bonus / penalty }} + {{!-- Attribute persistent bonus/penalty (read-only if non-zero) --}} + {{#if attributeBonus}} +
+ {{localize "AWEMMY.Roll.AttributeBonus"}} + + {{#if (gt attributeBonus 0)}}+{{/if}}{{attributeBonus}} + +
+ {{/if}} + + {{!-- Situational bonus / penalty --}}
- +
- {{! DC (optional) }} + {{!-- Knowledge bonus (field items) --}} + {{#if knowledgeBonuses.length}} +
+ + +
+ {{/if}} + + {{!-- DC --}}
- +
- {{! Roll visibility }} + {{!-- Formula preview --}} +
+ {{localize "AWEMMY.Roll.Formula"}} + 1d20 + {{totalMod}} +
+ + {{!-- Roll visibility --}}
+ +
+ Description + {{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}} +
+
-
- Description - {{formInput - systemFields.description - enriched=enrichedDescription - value=system.description - name="system.description" - toggled=true - }} -