From fb04448ab0e10dc2145e5e96eae9412da1bbf801 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Mon, 30 Mar 2026 23:38:45 +0200 Subject: [PATCH] Various fixes and add rune support --- css/fvtt-oath-hammer.css | 139 ++++++++++++++++++ lang/en.json | 17 ++- less/actor-sheet.less | 19 +++ less/item-sheets.less | 110 +++++++++++++- less/party-sheet.less | 15 ++ .../applications/sheets/base-item-sheet.mjs | 131 ++++++++++++++++- .../applications/sheets/character-sheet.mjs | 8 + module/models/armor.mjs | 7 +- module/models/magic-item.mjs | 7 +- module/models/party.mjs | 1 + module/models/weapon.mjs | 3 + oath-hammer.mjs | 5 + templates/actor/character-sheet.hbs | 6 +- templates/actor/party-sheet.hbs | 4 +- templates/item/armor-sheet.hbs | 1 + templates/item/magic-item-sheet.hbs | 3 + templates/item/rune-zone.hbs | 38 +++++ templates/item/weapon-sheet.hbs | 1 + 18 files changed, 506 insertions(+), 9 deletions(-) create mode 100644 templates/item/rune-zone.hbs diff --git a/css/fvtt-oath-hammer.css b/css/fvtt-oath-hammer.css index 235ac44..f67919b 100644 --- a/css/fvtt-oath-hammer.css +++ b/css/fvtt-oath-hammer.css @@ -570,6 +570,26 @@ .oathhammer .character-main .character-stats-band .character-resources .character-resource.character-resource--luck .luck-btn:hover { color: #2a1a0a; } +.oathhammer .character-main .character-stats-band .character-resources .character-resource .grit-stepper { + display: flex; + align-items: center; + gap: 1px; +} +.oathhammer .character-main .character-stats-band .character-resources .character-resource .grit-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.2rem; + height: 1.4rem; + font-size: calc(0.86rem * 0.85); + font-weight: bold; + color: #535128; + cursor: pointer; + line-height: 1; +} +.oathhammer .character-main .character-stats-band .character-resources .character-resource .grit-btn:hover { + color: #2a1a0a; +} .oathhammer .character-main .character-stats-band .character-resources .resource-label { min-width: 4.2rem; font-family: "BlueDragon", "Palatino Linotype", serif; @@ -1419,6 +1439,110 @@ .oathhammer .item-sheet-common .enchantment-fieldset .enchant-cursed-label input[type="checkbox"] { margin: 0; } +.oathhammer .item-sheet-common .rune-zone { + margin-top: 6px; + border-color: #084a74; +} +.oathhammer .item-sheet-common .rune-zone legend { + color: #084a74; +} +.oathhammer .item-sheet-common .rune-zone legend i { + margin-right: 4px; +} +.oathhammer .item-sheet-common .rune-zone .rune-list { + list-style: none; + margin: 0 0 6px; + padding: 0; + display: flex; + flex-direction: column; + gap: 4px; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry { + display: flex; + align-items: center; + gap: 6px; + padding: 3px 6px; + border-radius: 3px; + background: rgba(0, 0, 0, 0.06); + border: 1px solid #535128; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry.rune-exalted { + border-color: #084a74; + background: rgba(8, 74, 116, 0.08); +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-img { + width: 24px; + height: 24px; + border-radius: 3px; + border: 1px solid #535128; + -o-object-fit: cover; + object-fit: cover; + flex-shrink: 0; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-name { + flex: 1; + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: 0.86rem; + font-weight: bold; + color: #2a1a0a; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-badge-exalted { + color: #084a74; + font-size: calc(0.86rem * 0.85); + font-weight: bold; + flex-shrink: 0; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-dv { + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.86rem * 0.9); + color: #535128; + flex-shrink: 0; + white-space: nowrap; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-duration { + font-family: "Calibri", "Segoe UI", sans-serif; + font-size: calc(0.86rem * 0.9); + color: #2a1a0a; + opacity: 0.7; + flex-shrink: 0; + white-space: nowrap; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-effect-toggle { + color: #535128; + flex-shrink: 0; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-effect-toggle:hover { + color: #084a74; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-remove { + color: #2a1a0a; + opacity: 0.4; + flex-shrink: 0; + margin-left: auto; +} +.oathhammer .item-sheet-common .rune-zone .rune-entry .rune-remove:hover { + color: #c0392b; + opacity: 1; +} +.oathhammer .item-sheet-common .rune-zone .rune-drop-zone { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 6px 8px; + border: 1px dashed #535128; + border-radius: 3px; + color: #535128; + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.86rem * 0.85); + font-style: italic; + opacity: 0.7; + pointer-events: none; +} .oathhammer .item-sheet-common .proficiency-section { display: flex; gap: 8px; @@ -2624,6 +2748,21 @@ font-family: "BlueDragon", "Palatino Linotype", serif; font-size: calc(0.86rem * 0.85); } +.oathhammer .party-main .party-slots .party-renown-label { + font-weight: bold; + color: #535128; + margin-left: 0.8rem; + margin-right: 0.3rem; + text-transform: uppercase; + font-size: calc(0.86rem * 0.9); + letter-spacing: 0.04em; +} +.oathhammer .party-main .party-slots .party-renown-value { + width: 3.5rem; + text-align: center; + font-family: "BlueDragon", "Palatino Linotype", serif; + font-size: calc(0.86rem * 0.85); +} .oathhammer .item-list--party-member .item-list-header, .oathhammer .item-list--party-member .item-entry { grid-template-columns: 1.8rem 24px 1fr 7rem 5rem 3rem 5.5rem; diff --git a/lang/en.json b/lang/en.json index 49af425..d378af4 100644 --- a/lang/en.json +++ b/lang/en.json @@ -373,7 +373,13 @@ "Mercenary": "Mercenary", "CurrentXP": "XP", "CarriesLight": "Carries Light", - "Slots": "Slots" + "Slots": "Slots", + "Runes": "Runes", + "DropRuneHint": "Drop a runic spell here to attach it…", + "RemoveRune": "Remove rune", + "OpenRune": "Open spell sheet", + "DifficultyValue": "Difficulty Value", + "Exalted": "Exalted" }, "ColorDice": { "White": "White (4+)", @@ -540,6 +546,15 @@ "MagicSpells": "spells" } }, + "Rune": { + "Attached": "Rune \"{name}\" attached.", + "NotRunic": "Only runic tradition spells can be attached as runes.", + "WrongType": "This item only accepts {expected} runes.", + "MaxRunes": "This item already has 2 runes (maximum).", + "Duplicate": "This rune is already attached to this item.", + "MaxExalted": "This item already bears an exalted rune (maximum 1).", + "SourceNotFound": "Source spell not found — it may have been deleted." + }, "FreeRoll": { "Label": "Free Roll", "PoolTitle": "Number of dice (1–20)", diff --git a/less/actor-sheet.less b/less/actor-sheet.less index 5765a0b..016c3dd 100644 --- a/less/actor-sheet.less +++ b/less/actor-sheet.less @@ -189,6 +189,25 @@ &:hover { color: @color-dark; } } } + + .grit-stepper { + display: flex; + align-items: center; + gap: 1px; + } + .grit-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.2rem; + height: 1.4rem; + font-size: @font-size-sm; + font-weight: bold; + color: @color-olive; + cursor: pointer; + line-height: 1; + &:hover { color: @color-dark; } + } } .resource-label { diff --git a/less/item-sheets.less b/less/item-sheets.less index f7c1852..dff2cab 100644 --- a/less/item-sheets.less +++ b/less/item-sheets.less @@ -134,7 +134,115 @@ } } - // ── Class proficiency checkboxes ──────────────────────────── + // ── Rune zone ────────────────────────────────────────────────── + .rune-zone { + margin-top: 6px; + border-color: @color-blue; + + legend { + color: @color-blue; + i { margin-right: 4px; } + } + + .rune-list { + list-style: none; + margin: 0 0 6px; + padding: 0; + display: flex; + flex-direction: column; + gap: 4px; + } + + .rune-entry { + display: flex; + align-items: center; + gap: 6px; + padding: 3px 6px; + border-radius: 3px; + background: rgba(0,0,0,0.06); + border: 1px solid @color-olive; + + &.rune-exalted { + border-color: @color-blue; + background: fade(@color-blue, 8%); + } + + .rune-img { + width: 24px; + height: 24px; + border-radius: 3px; + border: 1px solid @color-olive; + object-fit: cover; + flex-shrink: 0; + } + + .rune-name { + flex: 1; + font-family: @font-secondary; + font-size: @font-size-base; + font-weight: bold; + color: @color-dark; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .rune-badge-exalted { + color: @color-blue; + font-size: @font-size-sm; + font-weight: bold; + flex-shrink: 0; + } + + .rune-dv { + font-family: @font-secondary; + font-size: @font-size-xs; + color: @color-olive; + flex-shrink: 0; + white-space: nowrap; + } + + .rune-duration { + font-family: @font-body; + font-size: @font-size-xs; + color: @color-dark; + opacity: 0.7; + flex-shrink: 0; + white-space: nowrap; + } + + .rune-effect-toggle { + color: @color-olive; + flex-shrink: 0; + &:hover { color: @color-blue; } + } + + .rune-remove { + color: @color-dark; + opacity: 0.4; + flex-shrink: 0; + margin-left: auto; + &:hover { color: #c0392b; opacity: 1; } + } + } + + .rune-drop-zone { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 6px 8px; + border: 1px dashed @color-olive; + border-radius: 3px; + color: @color-olive; + font-family: @font-secondary; + font-size: @font-size-sm; + font-style: italic; + opacity: 0.7; + pointer-events: none; + } + } .proficiency-section { display: flex; gap: 8px; diff --git a/less/party-sheet.less b/less/party-sheet.less index e6b98f2..ad88ba9 100644 --- a/less/party-sheet.less +++ b/less/party-sheet.less @@ -161,6 +161,21 @@ font-family: @font-secondary; font-size: @font-size-sm; } + .party-renown-label { + font-weight: bold; + color: @color-olive; + margin-left: 0.8rem; + margin-right: 0.3rem; + text-transform: uppercase; + font-size: @font-size-xs; + letter-spacing: 0.04em; + } + .party-renown-value { + width: 3.5rem; + text-align: center; + font-family: @font-secondary; + font-size: @font-size-sm; + } } } diff --git a/module/applications/sheets/base-item-sheet.mjs b/module/applications/sheets/base-item-sheet.mjs index 438e3f8..2e1e8f2 100644 --- a/module/applications/sheets/base-item-sheet.mjs +++ b/module/applications/sheets/base-item-sheet.mjs @@ -30,10 +30,19 @@ export default class OathHammerItemSheet extends HandlebarsApplicationMixin(foun toggleSheet: OathHammerItemSheet.#onToggleSheet, editImage: OathHammerItemSheet.#onEditImage, rollRarity: OathHammerItemSheet.#onRollRarity, + removeRune: OathHammerItemSheet.#onRemoveRune, + openRune: OathHammerItemSheet.#onOpenRune, }, } _sheetMode = this.constructor.SHEET_MODES.PLAY + _lockedReadOnly = false + + /** @override — prevent form submissions when this sheet is opened in read-only mode */ + get isEditable() { + if (this._lockedReadOnly) return false + return super.isEditable + } get isPlayMode() { return this._sheetMode === this.constructor.SHEET_MODES.PLAY @@ -85,13 +94,49 @@ export default class OathHammerItemSheet extends HandlebarsApplicationMixin(foun // Class proficiency choices (for class-sheet checkboxes) context.armorTypeChoices = ARMOR_TYPE_CHOICES context.weaponGroupChoices = WEAPON_PROFICIENCY_GROUPS + + // Rune context — enrich effect HTML for each attached rune + if (Array.isArray(this.document.system.runes)) { + context.enrichedRunes = await Promise.all( + this.document.system.runes.map(async (rune, idx) => ({ + ...rune, + idx, + enrichedEffect: await foundry.applications.ux.TextEditor.implementation.enrichHTML(rune.effect ?? "", { async: true }), + })) + ) + } + context.acceptsRunes = this.#acceptsRunes() + return context } + /** Returns true if this item type can have runic spells attached. */ + #acceptsRunes() { + const type = this.document.type + if (type === "armor" || type === "weapon") return true + if (type === "magic-item" && this.document.system.itemType === "talisman") return true + return false + } + + /** Map runeType expected for each item type. */ + static #EXPECTED_RUNE_TYPE = { + armor: "armor", + weapon: "weapon", + "magic-item": "talisman", + } + /** @override */ _onRender(context, options) { super._onRender(context, options) this.#dragDrop.forEach((d) => d.bind(this.element)) + if (this._lockedReadOnly) { + this.element.querySelector('[data-action="toggleSheet"]')?.remove() + for (const el of this.element.querySelectorAll( + '.window-content input, .window-content select, .window-content textarea, .window-content button' + )) { + el.disabled = true + } + } for (const pm of this.element.querySelectorAll("prose-mirror[name]")) { pm.addEventListener("change", async (event) => { event.stopPropagation() @@ -129,9 +174,93 @@ export default class OathHammerItemSheet extends HandlebarsApplicationMixin(foun _onDragOver(event) {} - async _onDrop(event) {} + async _onDrop(event) { + if (!this.#acceptsRunes()) return + let dragData + try { dragData = JSON.parse(event.dataTransfer.getData("text/plain")) } catch { return } + if (dragData?.type !== "Item") return + + let spell + try { spell = await fromUuid(dragData.uuid) } catch { return } + if (!spell || spell.type !== "spell") return + + const sys = spell.system + if (sys.tradition !== "runic") { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.NotRunic")) + return + } + + const expectedType = OathHammerItemSheet.#EXPECTED_RUNE_TYPE[this.document.type] + if (sys.runeType !== expectedType) { + ui.notifications.warn(game.i18n.format("OATHHAMMER.Rune.WrongType", { + expected: game.i18n.localize(`OATHHAMMER.RuneType.${expectedType.charAt(0).toUpperCase() + expectedType.slice(1)}`), + })) + return + } + + const current = this.document.system.runes ?? [] + if (current.length >= 2) { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.MaxRunes")) + return + } + if (current.some(r => r.name === spell.name)) { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.Duplicate")) + return + } + if (sys.isExalted && current.some(r => r.isExalted)) { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.MaxExalted")) + return + } + + const snapshot = { + sourceUuid: spell.uuid, + name: spell.name, + img: spell.img, + runeType: sys.runeType, + isExalted: sys.isExalted, + difficultyValue: sys.difficultyValue, + effect: sys.effect ?? "", + duration: sys.duration ?? "", + range: sys.range ?? "", + spellSave: sys.spellSave ?? "", + } + await this.document.update({ "system.runes": [...current, snapshot] }) + ui.notifications.info(game.i18n.format("OATHHAMMER.Rune.Attached", { name: spell.name })) + } + + static async #onRemoveRune(event, target) { + const idx = parseInt(target.dataset.runeIndex, 10) + if (isNaN(idx)) return + const runes = [...(this.document.system.runes ?? [])] + runes.splice(idx, 1) + await this.document.update({ "system.runes": runes }) + } + + static async #onOpenRune(event, target) { + const uuid = target.dataset.sourceUuid + if (!uuid) return + try { + const spell = await fromUuid(uuid) + if (!spell) { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.SourceNotFound")) + return + } + // Use a unique ID so this read-only instance never conflicts with the + // document's normal sheet (which uses {ClassName}-{documentId} as its ID). + const SheetClass = spell.sheet.constructor + const sheet = new SheetClass({ + document: spell, + id: `${SheetClass.name}-rune-view-${spell.id}`, + }) + sheet._lockedReadOnly = true + sheet.render(true) + } catch { + ui.notifications.warn(game.i18n.localize("OATHHAMMER.Rune.SourceNotFound")) + } + } static #onToggleSheet(event, target) { + if (this._lockedReadOnly) return const modes = this.constructor.SHEET_MODES this._sheetMode = this.isEditMode ? modes.PLAY : modes.EDIT this.render() diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 1ad6327..404f05d 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -38,6 +38,7 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { adjustQty: OathHammerCharacterSheet.#onAdjustQty, adjustCurrency: OathHammerCharacterSheet.#onAdjustCurrency, adjustLuck: OathHammerCharacterSheet.#onAdjustLuck, + adjustGrit: OathHammerCharacterSheet.#onAdjustGrit, clearStress: OathHammerCharacterSheet.#onClearStress, }, } @@ -417,6 +418,13 @@ export default class OathHammerCharacterSheet extends OathHammerActorSheet { await this.document.update({ "system.luck.value": Math.max(0, current + delta) }) } + static async #onAdjustGrit(event, target) { + const delta = parseInt(target.dataset.delta, 10) + const current = this.document.system.grit.value ?? 0 + const max = this.document.system.grit.max ?? 0 + await this.document.update({ "system.grit.value": Math.max(0, Math.min(max, current + delta)) }) + } + static async #onAdjustStress(event, target) { const delta = parseInt(target.dataset.delta, 10) const current = this.document.system.arcaneStress.value ?? 0 diff --git a/module/models/armor.mjs b/module/models/armor.mjs index 4799343..c1b0922 100644 --- a/module/models/armor.mjs +++ b/module/models/armor.mjs @@ -1,4 +1,4 @@ -import { SYSTEM } from "../config/system.mjs" +import { CLASS_RESTRICTION_CHOICES, SYSTEM } from "../config/system.mjs" export default class OathHammerArmor extends foundry.abstract.TypeDataModel { static defineSchema() { @@ -39,7 +39,10 @@ export default class OathHammerArmor extends foundry.abstract.TypeDataModel { schema.isCursed = new fields.BooleanField({ initial: false }) schema.magicEffect = new fields.HTMLField({ required: false, textSearch: true }) // Class/lineage restriction, e.g. "Dwarves only" (empty = no restriction) - schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" }) + schema.classRestriction = new fields.StringField({ required: false, nullable: true, initial: null, choices: CLASS_RESTRICTION_CHOICES }) + + // Attached runic spells (max 2; each is a snapshot of the spell item) + schema.runes = new fields.ArrayField(new fields.ObjectField(), { required: true, initial: [] }) return schema } diff --git a/module/models/magic-item.mjs b/module/models/magic-item.mjs index 1696fdd..720b3bb 100644 --- a/module/models/magic-item.mjs +++ b/module/models/magic-item.mjs @@ -1,4 +1,4 @@ -import { SYSTEM } from "../config/system.mjs" +import { CLASS_RESTRICTION_CHOICES, SYSTEM } from "../config/system.mjs" export default class OathHammerMagicItem extends foundry.abstract.TypeDataModel { static defineSchema() { @@ -27,7 +27,7 @@ export default class OathHammerMagicItem extends foundry.abstract.TypeDataModel schema.isBonded = new fields.BooleanField({ initial: false }) // Class/lineage restriction printed in the item's type line, e.g. "Troubadour Only" - schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" }) + schema.classRestriction = new fields.StringField({ required: false, nullable: true, initial: null, choices: CLASS_RESTRICTION_CHOICES }) // Limited-use items (e.g. "once per day"); none = always active schema.usagePeriod = new fields.StringField({ @@ -39,6 +39,9 @@ export default class OathHammerMagicItem extends foundry.abstract.TypeDataModel schema.equipped = new fields.BooleanField({ initial: false }) + // Attached runic spells — only for talisman subtype (max 2; snapshot of spell item) + schema.runes = new fields.ArrayField(new fields.ObjectField(), { required: true, initial: [] }) + return schema } diff --git a/module/models/party.mjs b/module/models/party.mjs index 8a99759..3ad24f1 100644 --- a/module/models/party.mjs +++ b/module/models/party.mjs @@ -21,6 +21,7 @@ export default class OathHammerParty extends foundry.abstract.TypeDataModel { }) schema.maxSlots = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) + schema.renown = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) return schema } diff --git a/module/models/weapon.mjs b/module/models/weapon.mjs index 37338b6..ec920d7 100644 --- a/module/models/weapon.mjs +++ b/module/models/weapon.mjs @@ -64,6 +64,9 @@ export default class OathHammerWeapon extends foundry.abstract.TypeDataModel { // Use this for abilities like Magic Bolt that roll Magic+Willpower instead. schema.skillOverride = new fields.StringField({ required: false, nullable: true, initial: null }) + // Attached runic spells (max 2; each is a snapshot of the spell item) + schema.runes = new fields.ArrayField(new fields.ObjectField(), { required: true, initial: [] }) + return schema } diff --git a/oath-hammer.mjs b/oath-hammer.mjs index ddcce8a..01b7720 100644 --- a/oath-hammer.mjs +++ b/oath-hammer.mjs @@ -98,6 +98,11 @@ Hooks.once("init", function () { OathHammerUtils.registerHandlebarsHelpers() + // Pre-register Handlebars partials so {{> "path"}} works in item templates + foundry.applications.handlebars.loadTemplates([ + "systems/fvtt-oath-hammer/templates/item/rune-zone.hbs", + ]) + console.info("Oath Hammer | System Initialized") }) diff --git a/templates/actor/character-sheet.hbs b/templates/actor/character-sheet.hbs index ed676d2..131a3e7 100644 --- a/templates/actor/character-sheet.hbs +++ b/templates/actor/character-sheet.hbs @@ -50,7 +50,11 @@
{{localize "OATHHAMMER.Label.Grit"}} - {{formInput systemFields.grit.fields.value value=system.grit.value name="system.grit.value" disabled=isPlayMode}} +
+ + {{formInput systemFields.grit.fields.value value=system.grit.value name="system.grit.value"}} + + +
/ {{formInput systemFields.grit.fields.max value=system.grit.max name="system.grit.max" disabled=isPlayMode}}
diff --git a/templates/actor/party-sheet.hbs b/templates/actor/party-sheet.hbs index 8d7d3fd..dc8ebf8 100644 --- a/templates/actor/party-sheet.hbs +++ b/templates/actor/party-sheet.hbs @@ -49,12 +49,14 @@ - +
{{localize "OATHHAMMER.Label.Slots"}} {{currentSlots}} / + {{localize "OATHHAMMER.Label.Renown"}} +
diff --git a/templates/item/armor-sheet.hbs b/templates/item/armor-sheet.hbs index 536f4ef..c98c863 100644 --- a/templates/item/armor-sheet.hbs +++ b/templates/item/armor-sheet.hbs @@ -108,4 +108,5 @@ }}
{{/if}} + {{> "systems/fvtt-oath-hammer/templates/item/rune-zone.hbs"}} \ No newline at end of file diff --git a/templates/item/magic-item-sheet.hbs b/templates/item/magic-item-sheet.hbs index e0fec24..776d08f 100644 --- a/templates/item/magic-item-sheet.hbs +++ b/templates/item/magic-item-sheet.hbs @@ -24,4 +24,7 @@ {{localize "OATHHAMMER.Label.Effect"}} {{formInput systemFields.effect enriched=enrichedEffect value=system.effect name="system.effect" toggled=true}} + {{#if (eq system.itemType "talisman")}} + {{> "systems/fvtt-oath-hammer/templates/item/rune-zone.hbs"}} + {{/if}} diff --git a/templates/item/rune-zone.hbs b/templates/item/rune-zone.hbs new file mode 100644 index 0000000..a26c541 --- /dev/null +++ b/templates/item/rune-zone.hbs @@ -0,0 +1,38 @@ +{{!-- Runic attachment zone — included in armor, weapon, magic-item (talisman) sheets --}} +
+ {{localize "OATHHAMMER.Label.Runes"}} + + {{#if enrichedRunes.length}} + + {{/if}} + +
+ + {{localize "OATHHAMMER.Label.DropRuneHint"}} +
+
diff --git a/templates/item/weapon-sheet.hbs b/templates/item/weapon-sheet.hbs index 02b226c..d41dfc8 100644 --- a/templates/item/weapon-sheet.hbs +++ b/templates/item/weapon-sheet.hbs @@ -78,4 +78,5 @@ {{formInput systemFields.magicEffect enriched=enrichedMagicEffect value=system.magicEffect name="system.magicEffect" toggled=true}} {{/if}} + {{> "systems/fvtt-oath-hammer/templates/item/rune-zone.hbs"}}