From aaf965c78a02509b8cae0839909b2103fb6b9906 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Sun, 8 Mar 2026 11:35:00 +0100 Subject: [PATCH] Item ehnance, fixes on actor sheet --- css/fvtt-oath-hammer.css | 264 ++++++++++++++++-- lang/en.json | 21 +- less/actor-sheet.less | 107 ++++++- less/base.less | 45 ++- less/item-list.less | 134 ++++++++- .../applications/sheets/character-sheet.mjs | 64 ++++- module/models/character.mjs | 10 +- templates/actor/character-combat.hbs | 80 ++++-- templates/actor/character-equipment.hbs | 86 ++++-- templates/actor/character-identity.hbs | 85 ++---- templates/actor/character-magic.hbs | 50 ++-- templates/actor/character-sheet.hbs | 91 +++--- templates/actor/character-skills.hbs | 20 +- 13 files changed, 849 insertions(+), 208 deletions(-) diff --git a/css/fvtt-oath-hammer.css b/css/fvtt-oath-hammer.css index bbd0e60..c9809cb 100644 --- a/css/fvtt-oath-hammer.css +++ b/css/fvtt-oath-hammer.css @@ -111,7 +111,7 @@ .oathhammer .skills-container .skills-header, .oathhammer .skills-container .skill-row { display: grid; - grid-template-columns: 1fr 3rem 3rem; + grid-template-columns: 1fr 2.5rem 2.5rem 2.5rem 5.5rem; align-items: center; gap: 4px; } @@ -124,14 +124,59 @@ margin-bottom: 2px; padding-bottom: 2px; } +.oathhammer .skills-container .skills-header span { + text-align: center; +} +.oathhammer .skills-container .skills-header .skill-name-col { + text-align: left; +} .oathhammer .skills-container .skill-row { margin-bottom: 2px; } .oathhammer .skills-container .skill-row label.skill-name-col { font-size: calc(0.82rem * 0.85); } -.oathhammer .skills-container .skill-row .skill-rank-col input { +.oathhammer .skills-container .skill-row .skill-rank-col select, +.oathhammer .skills-container .skill-row .skill-modifier-col input { + width: 100%; text-align: center; + font-size: calc(0.82rem * 0.85); + padding: 1px 2px; +} +.oathhammer .skills-container .skill-row .skill-color-col { + display: flex; + align-items: center; + gap: 2px; +} +.oathhammer .skills-container .skill-row .skill-color-col .color-dice-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; + border: 1px solid rgba(0, 0, 0, 0.3); +} +.oathhammer .skills-container .skill-row .skill-color-col .color-dice-dot.color-dice-white { + background: #f0f0f0; +} +.oathhammer .skills-container .skill-row .skill-color-col .color-dice-dot.color-dice-red { + background: #d9534f; +} +.oathhammer .skills-container .skill-row .skill-color-col .color-dice-dot.color-dice-black { + background: #222; +} +.oathhammer .skills-container .skill-row .skill-color-col .color-dice-select { + flex: 1; + font-size: calc(0.82rem * 0.85); + padding: 1px 1px; + min-width: 0; +} +.oathhammer .skills-container .skill-row .skill-color-col input[type="number"] { + width: 2.2rem; + text-align: center; + font-size: calc(0.82rem * 0.85); + padding: 1px 2px; + flex-shrink: 0; } .oathhammer .skills-container .skill-row .skill-total { text-align: center; @@ -193,15 +238,105 @@ flex: 1; display: flex; flex-direction: column; - gap: 4px; + gap: 6px; + min-width: 0; } .oathhammer .character-main .character-name { display: flex; align-items: center; gap: 4px; + border-bottom: 1px solid #535128; + padding-bottom: 4px; } .oathhammer .character-main .character-name input { flex: 1; + font-family: "Sherwood", "Palatino Linotype", serif; + font-size: calc(0.82rem * 1.1); +} +.oathhammer .character-main .character-identity-bar { + display: flex; + flex-direction: row; + align-items: center; + gap: 6px; + flex-wrap: wrap; +} +.oathhammer .character-main .character-identity-bar .identity-slot { + display: flex; + align-items: center; + gap: 4px; + padding: 2px 6px; + border: 1px solid #535128; + border-radius: 3px; + background: rgba(0, 0, 0, 0.15); + font-size: calc(0.82rem * 0.85); + min-width: 6rem; + min-height: 1.6rem; +} +.oathhammer .character-main .character-identity-bar .identity-slot.empty { + opacity: 0.6; + font-style: italic; + border-style: dashed; +} +.oathhammer .character-main .character-identity-bar .identity-slot .identity-img { + width: 18px; + height: 18px; + -o-object-fit: cover; + object-fit: cover; + border-radius: 2px; + border: none; +} +.oathhammer .character-main .character-identity-bar .identity-slot .identity-name { + flex: 1; + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.82rem * 0.85); +} +.oathhammer .character-main .character-identity-bar .identity-slot .slot-icon { + font-size: calc(0.82rem * 0.85); + opacity: 0.6; +} +.oathhammer .character-main .character-identity-bar .identity-slot .slot-placeholder { + font-size: calc(0.82rem * 0.85); +} +.oathhammer .character-main .character-identity-bar .identity-slot a { + font-size: calc(0.82rem * 0.85); + opacity: 0.7; +} +.oathhammer .character-main .character-identity-bar .identity-slot a:hover { + opacity: 1; +} +.oathhammer .character-main .character-identity-bar .identity-xp { + display: flex; + align-items: center; + gap: 3px; + margin-left: auto; + font-size: calc(0.82rem * 0.85); +} +.oathhammer .character-main .character-identity-bar .identity-xp .xp-label { + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.82rem * 0.85); + color: #535128; + margin-left: 4px; +} +.oathhammer .character-main .character-identity-bar .identity-xp .xp-sep { + opacity: 0.6; +} +.oathhammer .character-main .character-identity-bar .identity-xp input { + width: 3rem; + text-align: center; + font-size: calc(0.82rem * 0.85); + padding: 1px 2px; +} +.oathhammer .attributes-stress-row { + display: flex; + align-items: flex-start; + gap: 6px; +} +.oathhammer .attributes-stress-row .character-attributes { + flex: 1; +} +.oathhammer .attributes-stress-row .character-arcane-stress { + flex-shrink: 0; + width: auto; } .oathhammer .attributes-grid { display: grid; @@ -294,15 +429,22 @@ flex-direction: column; gap: 2px; } -.oathhammer .character-arcane-stress .flexrow { +.oathhammer .character-arcane-stress .stress-inputs { + display: flex; align-items: center; + justify-content: center; gap: 4px; } +.oathhammer .character-arcane-stress div.form-group { + display: contents; +} .oathhammer .character-arcane-stress input { - min-width: 3rem; - max-width: 3rem; + width: 2.8rem; text-align: center; } +.oathhammer .character-arcane-stress span { + opacity: 0.6; +} .oathhammer .defense-display { min-width: 3rem; max-width: 3rem; @@ -328,50 +470,136 @@ margin: 0; padding: 0; } -.oathhammer .item-entry { - display: flex; +.oathhammer .item-list-header { + display: grid; align-items: center; - gap: 6px; - padding: 3px 4px; + gap: 4px; + padding: 2px 4px 3px; + border-bottom: 1px solid #535128; + margin-bottom: 2px; + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.82rem * 0.9); + color: #084a74; +} +.oathhammer .item-list-header span { + text-align: center; +} +.oathhammer .item-list-header .col-name { + text-align: left; +} +.oathhammer .item-entry { + display: grid; + align-items: center; + gap: 4px; + padding: 2px 4px; border-bottom: 1px solid rgba(83, 81, 40, 0.2); } .oathhammer .item-entry:hover { background-color: rgba(8, 74, 116, 0.08); } .oathhammer .item-entry .item-img { - height: 24px; width: 24px; + height: 24px; border: 1px solid #535128; border-radius: 2px; -o-object-fit: cover; object-fit: cover; + align-self: center; + justify-self: center; + flex-shrink: 0; } .oathhammer .item-entry .item-name { - flex: 1; font-family: "Calibri", "Segoe UI", sans-serif; font-size: 0.82rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-width: 0; } .oathhammer .item-entry .item-detail { font-size: calc(0.82rem * 0.9); color: #535128; - min-width: 4rem; text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .oathhammer .item-entry .item-type { - font-size: calc(0.82rem * 0.85); + font-size: calc(0.82rem * 0.9); color: #084a74; - min-width: 6rem; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } -.oathhammer .item-entry a { +.oathhammer .item-entry .item-equipped { + display: flex; + align-items: center; + justify-content: center; +} +.oathhammer .item-entry .item-equipped input[type="checkbox"] { + width: 0.95rem; + height: 0.95rem; + cursor: pointer; + margin: 0; +} +.oathhammer .item-entry .item-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 4px; +} +.oathhammer .item-entry .item-actions a { opacity: 0.6; transition: opacity 0.2s; + font-size: calc(0.82rem * 0.85); } -.oathhammer .item-entry a:hover { +.oathhammer .item-entry .item-actions a:hover { opacity: 1; } -.oathhammer .item-entry a:hover { +.oathhammer .item-entry .item-actions a:hover { color: #084a74; } +.oathhammer .item-list--weapon .item-list-header, +.oathhammer .item-list--weapon .item-entry { + grid-template-columns: 24px 1fr 5.5rem 3rem 1.8rem 3.5rem; +} +.oathhammer .item-list--armor .item-list-header, +.oathhammer .item-list--armor .item-entry { + grid-template-columns: 24px 1fr 3.5rem 5rem 1.8rem 3.5rem; +} +.oathhammer .item-list--ammo .item-list-header, +.oathhammer .item-list--ammo .item-entry { + grid-template-columns: 24px 1fr 4rem 3.5rem; +} +.oathhammer .item-list--spell .item-list-header, +.oathhammer .item-list--spell .item-entry { + grid-template-columns: 24px 1fr 3rem 6rem 3rem 3.5rem; +} +.oathhammer .item-list--miracle .item-list-header, +.oathhammer .item-list--miracle .item-entry { + grid-template-columns: 24px 1fr 4.5rem 3.5rem; +} +.oathhammer .item-list--equipment .item-list-header, +.oathhammer .item-list--equipment .item-entry { + grid-template-columns: 24px 1fr 5rem 3rem 3.5rem; +} +.oathhammer .item-list--magic-item .item-list-header, +.oathhammer .item-list--magic-item .item-entry { + grid-template-columns: 24px 1fr 5rem 3.5rem; +} +.oathhammer .item-list--condition .item-list-header, +.oathhammer .item-list--condition .item-entry { + grid-template-columns: 24px 1fr 5.5rem 3.5rem; +} +.oathhammer .item-list--ability .item-list-header, +.oathhammer .item-list--ability .item-entry { + grid-template-columns: 24px 1fr 6rem 3.5rem; +} +.oathhammer .item-list--oath .item-list-header, +.oathhammer .item-list--oath .item-entry { + grid-template-columns: 24px 1fr 5.5rem 3.5rem; +} .oathhammer .no-items { color: var(--color-dark-5); font-style: italic; diff --git a/lang/en.json b/lang/en.json index 5a44233..c314dcf 100644 --- a/lang/en.json +++ b/lang/en.json @@ -242,11 +242,28 @@ "Bane": "Bane", "Skill": "Skill", "SkillRank": "Rank", - "TotalDice": "Total Dice", + "SkillModifier": "Mod", + "TotalDice": "Total", + "ColorDice": "Color", "DropLineage": "Drop Lineage Here", "DropClass": "Drop Class Here", "Traits": "Traits", - "Features": "Features" + "Features": "Features", + "Name": "Name", + "Type": "Type", + "Damage": "Damage", + "Tradition": "Tradition", + "Piety": "Piety", + "Quantity": "Qty", + "Rarity": "Rarity", + "Penalty": "Penalty", + "Equipped": "Eq.", + "XPCurrent": "Current XP" + }, + "ColorDice": { + "White": "White (4+)", + "Red": "Red (3+)", + "Black": "Black (2+)" }, "NewItem": { "Weapon": "New Weapon", diff --git a/less/actor-sheet.less b/less/actor-sheet.less index a9e1212..76fe443 100644 --- a/less/actor-sheet.less +++ b/less/actor-sheet.less @@ -67,15 +67,106 @@ flex: 1; display: flex; flex-direction: column; - gap: 4px; + gap: 6px; + min-width: 0; } .character-name { display: flex; align-items: center; gap: 4px; + border-bottom: 1px solid @color-olive; + padding-bottom: 4px; - input { flex: 1; } + input { + flex: 1; + font-family: @font-primary; + font-size: @font-size-lg; + } + } + + .character-identity-bar { + display: flex; + flex-direction: row; + align-items: center; + gap: 6px; + flex-wrap: wrap; + + .identity-slot { + display: flex; + align-items: center; + gap: 4px; + padding: 2px 6px; + border: 1px solid @color-olive; + border-radius: 3px; + background: rgba(0,0,0,0.15); + font-size: @font-size-sm; + min-width: 6rem; + min-height: 1.6rem; + + &.empty { + opacity: 0.6; + font-style: italic; + border-style: dashed; + } + + .identity-img { + width: 18px; + height: 18px; + object-fit: cover; + border-radius: 2px; + border: none; + } + + .identity-name { + flex: 1; + font-family: @font-secondary; + font-size: @font-size-sm; + } + + .slot-icon { font-size: @font-size-sm; opacity: 0.6; } + .slot-placeholder { font-size: @font-size-sm; } + + a { font-size: @font-size-sm; opacity: 0.7; &:hover { opacity: 1; } } + } + + .identity-xp { + display: flex; + align-items: center; + gap: 3px; + margin-left: auto; + font-size: @font-size-sm; + + .xp-label { + font-family: @font-secondary; + font-size: @font-size-sm; + color: @color-olive; + margin-left: 4px; + } + + .xp-sep { opacity: 0.6; } + + input { + width: 3rem; + text-align: center; + font-size: @font-size-sm; + padding: 1px 2px; + } + } + } + } + + // Attributes + Arcane Stress side by side + .attributes-stress-row { + display: flex; + align-items: flex-start; + gap: 6px; + + .character-attributes { flex: 1; } + + .character-arcane-stress { + flex-shrink: 0; + width: auto; } } @@ -186,17 +277,21 @@ gap: 2px; } - // Arcane Stress narrow inputs + // Arcane Stress compact .character-arcane-stress { - .flexrow { + .stress-inputs { + display: flex; align-items: center; + justify-content: center; gap: 4px; } + // formInput renders a
— flatten it + div.form-group { display: contents; } input { - min-width: 3rem; - max-width: 3rem; + width: 2.8rem; text-align: center; } + span { opacity: 0.6; } } // Defense display diff --git a/less/base.less b/less/base.less index f17193d..f44360e 100644 --- a/less/base.less +++ b/less/base.less @@ -122,7 +122,7 @@ .skills-header, .skill-row { display: grid; - grid-template-columns: 1fr 3rem 3rem; + grid-template-columns: 1fr 2.5rem 2.5rem 2.5rem 5.5rem; align-items: center; gap: 4px; } @@ -135,6 +135,9 @@ border-bottom: 1px solid @color-olive; margin-bottom: 2px; padding-bottom: 2px; + + span { text-align: center; } + .skill-name-col { text-align: left; } } .skill-row { @@ -144,8 +147,46 @@ font-size: @font-size-sm; } - .skill-rank-col input { + .skill-rank-col select, + .skill-modifier-col input { + width: 100%; text-align: center; + font-size: @font-size-sm; + padding: 1px 2px; + } + + .skill-color-col { + display: flex; + align-items: center; + gap: 2px; + + .color-dice-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; + border: 1px solid rgba(0,0,0,0.3); + + &.color-dice-white { background: #f0f0f0; } + &.color-dice-red { background: #d9534f; } + &.color-dice-black { background: #222; } + } + + .color-dice-select { + flex: 1; + font-size: @font-size-sm; + padding: 1px 1px; + min-width: 0; + } + + input[type="number"] { + width: 2.2rem; + text-align: center; + font-size: @font-size-sm; + padding: 1px 2px; + flex-shrink: 0; + } } .skill-total { diff --git a/less/item-list.less b/less/item-list.less index 648b680..ccd37b5 100644 --- a/less/item-list.less +++ b/less/item-list.less @@ -10,45 +10,153 @@ padding: 0; } - .item-entry { - display: flex; + // Header row shared by all lists + .item-list-header { + display: grid; align-items: center; - gap: 6px; - padding: 3px 4px; - border-bottom: 1px solid @color-olive-faint; + gap: 4px; + padding: 2px 4px 3px; + border-bottom: 1px solid @color-olive; + margin-bottom: 2px; + font-family: @font-secondary; + font-size: @font-size-xs; + color: @color-blue; + span { text-align: center; } + .col-name { text-align: left; } + } + // Data row + .item-entry { + display: grid; + align-items: center; + gap: 4px; + padding: 2px 4px; + border-bottom: 1px solid @color-olive-faint; &:hover { background-color: @color-blue-hover; } .item-img { - height: @item-img-size; width: @item-img-size; + height: @item-img-size; border: 1px solid @color-olive; border-radius: 2px; object-fit: cover; + align-self: center; + justify-self: center; + flex-shrink: 0; } .item-name { - flex: 1; font-family: @font-body; font-size: @font-size-base; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-width: 0; } .item-detail { font-size: @font-size-xs; color: @color-olive; - min-width: 4rem; text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .item-type { - font-size: @font-size-sm; + font-size: @font-size-xs; color: @color-blue; - min-width: 6rem; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } - a { - .transition-opacity(); - &:hover { color: @color-blue; } + .item-equipped { + display: flex; + align-items: center; + justify-content: center; + input[type="checkbox"] { + width: 0.95rem; + height: 0.95rem; + cursor: pointer; + margin: 0; + } + } + + .item-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 4px; + a { + .transition-opacity(); + font-size: @font-size-sm; + &:hover { color: @color-blue; } + } + } + } + + // ── Per-list grid templates ────────────────────────────── + // Format: [img] [name] [detail cols...] [equipped?] [actions] + + .item-list--weapon { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 5.5rem 3rem 1.8rem 3.5rem; + } + } + + .item-list--armor { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 3.5rem 5rem 1.8rem 3.5rem; + } + } + + .item-list--ammo { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 4rem 3.5rem; + } + } + + .item-list--spell { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 3rem 6rem 3rem 3.5rem; + } + } + + .item-list--miracle { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 4.5rem 3.5rem; + } + } + + .item-list--equipment { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 5rem 3rem 3.5rem; + } + } + + .item-list--magic-item { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 5rem 3.5rem; + } + } + + .item-list--condition { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 5.5rem 3.5rem; + } + } + + .item-list--ability { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 6rem 3.5rem; + } + } + + .item-list--oath { + .item-list-header, .item-entry { + grid-template-columns: @item-img-size 1fr 5.5rem 3.5rem; } } diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 1ca3c47..351b2ad 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -57,6 +57,10 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { async _prepareContext() { const context = await super._prepareContext() context.tabs = this.#getTabs() + // lineage/class/experience available to all parts (header + identity tab) + const doc = this.document + context.lineage = doc.itemTypes.lineage?.[0] ?? null + context.characterClass = doc.itemTypes["class"]?.[0] ?? null return context } @@ -68,8 +72,6 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { break case "identity": context.tab = context.tabs.identity - context.lineage = doc.itemTypes.lineage?.[0] ?? null - context.characterClass = doc.itemTypes["class"]?.[0] ?? null context.abilities = doc.itemTypes.ability context.oaths = doc.itemTypes.oath break @@ -89,14 +91,26 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { attribute: attr, label: `OATHHAMMER.Attribute.${attr.charAt(0).toUpperCase()}${attr.slice(1)}`, attrRank: attrRanks[attr], - skillData: skillKeys.map(skillKey => ({ - key: skillKey, - label: SYSTEM.SKILLS[skillKey].label, - rank: sys.skills[skillKey].rank, - name: `system.skills.${skillKey}.rank`, - total: attrRanks[attr] + sys.skills[skillKey].rank, - field: skillSchemaFields[skillKey].fields.rank, - })) + skillData: skillKeys.map(skillKey => { + const sk = sys.skills[skillKey] + return { + key: skillKey, + label: SYSTEM.SKILLS[skillKey].label, + rank: sk.rank, + modifier: sk.modifier, + colorDice: sk.colorDice, + colorDiceType: sk.colorDiceType, + rankName: `system.skills.${skillKey}.rank`, + modifierName: `system.skills.${skillKey}.modifier`, + colorDiceName: `system.skills.${skillKey}.colorDice`, + colorDiceTypeName: `system.skills.${skillKey}.colorDiceType`, + rankOptions: [0,1,2,3,4].map(v => ({ value: v, label: String(v), selected: v === sk.rank })), + total: attrRanks[attr] + sk.rank, + // legacy - kept for formInput compatibility + name: `system.skills.${skillKey}.rank`, + field: skillSchemaFields[skillKey].fields.rank, + } + }) })) break } @@ -125,6 +139,36 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { return context } + /** Auto-fill colorDice count when color type changes */ + static #COLOR_THRESHOLDS = { white: 4, red: 3, black: 2 } + + _onRender(context, options) { + super._onRender?.(context, options) + + // Color dice auto-fill + this.element.querySelectorAll('select.color-dice-select').forEach(select => { + select.addEventListener('change', event => { + const threshold = OathHammerCharacterSheet.#COLOR_THRESHOLDS[event.target.value] ?? 4 + const countInput = event.target.closest('.skill-color-col')?.querySelector('input[type="number"]') + if (countInput) { + countInput.value = threshold + countInput.dispatchEvent(new Event('change', { bubbles: true })) + } + const dot = event.target.closest('.skill-color-col')?.querySelector('.color-dice-dot') + if (dot) dot.className = `color-dice-dot color-dice-${event.target.value}` + }) + }) + + // Equipped checkbox — directly updates the item + this.element.querySelectorAll('input.item-equipped-cb').forEach(cb => { + cb.addEventListener('change', event => { + const itemId = event.target.dataset.itemId + const item = this.document.items.get(itemId) + if (item) item.update({ 'system.equipped': event.target.checked }) + }) + }) + } + async _onDrop(event) { if (!this.isEditable) return const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) diff --git a/module/models/character.mjs b/module/models/character.mjs index aa79368..0e02a42 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -20,9 +20,15 @@ export default class OathHammerCharacter extends foundry.abstract.TypeDataModel fate: attributeField() }) - // Skills: 26 skills each with a rank (0–4). Grit.max = resilience.rank + toughness.rank. + // Skills: 26 skills each with a rank (0–4), a bonus/penalty modifier, and color dice. + // Total dice = attr rank + skill rank. Modifier = bonus (+) or penalty (-) dice. + // Color dice: type (white 4+, red 3+, black 2+) + count of colored dice in the pool. const skillField = () => new fields.SchemaField({ - rank: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 4 }) + rank: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 4 }), + modifier: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }), + colorDiceType: new fields.StringField({ required: true, nullable: false, initial: "white", + choices: { white: "OATHHAMMER.ColorDice.White", red: "OATHHAMMER.ColorDice.Red", black: "OATHHAMMER.ColorDice.Black" } }), + colorDice: new fields.NumberField({ ...requiredInteger, initial: 4, min: 0 }), }) schema.skills = new fields.SchemaField({ academics: skillField(), diff --git a/templates/actor/character-combat.hbs b/templates/actor/character-combat.hbs index 8cd8ed6..077756b 100644 --- a/templates/actor/character-combat.hbs +++ b/templates/actor/character-combat.hbs @@ -21,18 +21,30 @@ {{#unless isPlayMode}}{{/unless}} {{#if weapons.length}} -
-
- {{localize "OATHHAMMER.Label.Experience"}} -
-
- - {{formInput systemFields.experience.fields.level value=system.experience.level name="system.experience.level" disabled=isPlayMode}} -
-
- - {{formInput systemFields.experience.fields.current value=system.experience.current name="system.experience.current" disabled=isPlayMode}} -
-
- - {{formInput systemFields.experience.fields.total value=system.experience.total name="system.experience.total" disabled=isPlayMode}} -
-
-
{{#if abilities.length}}
{{localize "OATHHAMMER.Label.Abilities"}} -
diff --git a/templates/actor/character-skills.hbs b/templates/actor/character-skills.hbs index 2c9ae2e..548f4fe 100644 --- a/templates/actor/character-skills.hbs +++ b/templates/actor/character-skills.hbs @@ -10,15 +10,33 @@
{{localize "OATHHAMMER.Label.Skill"}} {{localize "OATHHAMMER.Label.SkillRank"}} + {{localize "OATHHAMMER.Label.SkillModifier"}} {{localize "OATHHAMMER.Label.TotalDice"}} + {{localize "OATHHAMMER.Label.ColorDice"}}
{{#each group.skillData as |skill|}}
- {{formInput skill.field value=skill.rank name=skill.name disabled=../../isPlayMode}} + +
+
+
{{skill.total}} +
+ + + +
{{/each}}