From d01965e5b93ef843acbbce4d66f2e03bc5413186 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Wed, 6 Aug 2025 10:56:21 +0200 Subject: [PATCH] . --- lang/en.json | 2 +- .../dialogs/multiclassChoiceDialog.mjs | 2 +- .../applications/levelup/characterLevelup.mjs | 10 ++-- module/applications/levelup/levelup.mjs | 10 ++-- .../settings/homebrewSettings.mjs | 38 ++++++++++++++- module/applications/sheets/items/class.mjs | 2 +- .../applications/sheets/items/domainCard.mjs | 8 ++++ module/applications/ux/filter-menu.mjs | 2 +- module/config/domainConfig.mjs | 13 +++++- module/data/item/domainCard.mjs | 2 +- module/helpers/utils.mjs | 11 +++-- styles/less/global/elements.less | 33 +++++++------ styles/less/global/item-header.less | 4 +- .../settings/homebrew-settings/domains.less | 46 +++++++++++-------- styles/less/ui/settings/settings.less | 1 + styles/less/utils/colors.less | 7 +++ .../settings/homebrew-settings/domains.hbs | 12 +++-- .../settings/homebrew-settings/settings.hbs | 2 +- templates/sheets/items/domainCard/header.hbs | 6 +-- .../sheets/items/domainCard/settings.hbs | 2 +- 20 files changed, 146 insertions(+), 67 deletions(-) diff --git a/lang/en.json b/lang/en.json index 206965e7..0a9b091b 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2148,7 +2148,7 @@ "newDomain": "New Domain", "editDomain": "Active Domain", "deleteDomain": "Delete Domain", - "deleteDomainText": "Are you sure you want to delete the {name} domain?" + "deleteDomainText": "Are you sure you want to delete the {name} domain? It will be removed from all Actors in this world where it's currently used." } }, "Menu": { diff --git a/module/applications/dialogs/multiclassChoiceDialog.mjs b/module/applications/dialogs/multiclassChoiceDialog.mjs index 12f2629b..6d3fcf74 100644 --- a/module/applications/dialogs/multiclassChoiceDialog.mjs +++ b/module/applications/dialogs/multiclassChoiceDialog.mjs @@ -34,7 +34,7 @@ export default class MulticlassChoiceDialog extends HandlebarsApplicationMixin(A const context = await super._prepareContext(_options); context.multiclass = this.multiclass; context.domainChoices = this.multiclass.domains.map(value => { - const domain = CONFIG.DH.DOMAIN.domains[value]; + const domain = CONFIG.DH.DOMAIN.allDomains()[value]; return { value: value, label: game.i18n.localize(domain.label), diff --git a/module/applications/levelup/characterLevelup.mjs b/module/applications/levelup/characterLevelup.mjs index 8e17a907..1ce2bceb 100644 --- a/module/applications/levelup/characterLevelup.mjs +++ b/module/applications/levelup/characterLevelup.mjs @@ -1,6 +1,5 @@ import LevelUpBase from './levelup.mjs'; import { DhLevelup } from '../../data/levelup.mjs'; -import { domains } from '../../config/domainConfig.mjs'; import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs'; export default class DhCharacterLevelUp extends LevelUpBase { @@ -113,7 +112,7 @@ export default class DhCharacterLevelUp extends LevelUpBase { : levelBase; return game.i18n.format('DAGGERHEART.APPLICATIONS.Levelup.selections.emptyDomainCardHint', { - domain: game.i18n.localize(domains[domain.domain].label), + domain: game.i18n.localize(CONFIG.DH.DOMAIN.allDomains()[domain.domain].label), level: levelMax }); }), @@ -170,7 +169,7 @@ export default class DhCharacterLevelUp extends LevelUpBase { uuid: multiclass.uuid, domains: multiclass?.system?.domains.map(key => { - const domain = domains[key]; + const domain = CONFIG.DH.DOMAIN.allDomains()[key]; const alreadySelected = this.actor.system.class.value.system.domains.includes(key); return { @@ -315,7 +314,10 @@ export default class DhCharacterLevelUp extends LevelUpBase { ? { ...multiclassItem.toObject(), domain: checkbox.secondaryData.domain - ? game.i18n.localize(domains[checkbox.secondaryData.domain].label) + ? game.i18n.localize( + CONFIG.DH.DOMAIN.allDomains()[checkbox.secondaryData.domain] + .label + ) : null, subclass: subclass ? subclass.name : null } diff --git a/module/applications/levelup/levelup.mjs b/module/applications/levelup/levelup.mjs index f025c131..53fa4bf4 100644 --- a/module/applications/levelup/levelup.mjs +++ b/module/applications/levelup/levelup.mjs @@ -1,5 +1,4 @@ import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs'; -import { domains } from '../../config/domainConfig.mjs'; import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -249,7 +248,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) ? { ...multiclassItem.toObject(), domain: checkbox.secondaryData.domain - ? game.i18n.localize(domains[checkbox.secondaryData.domain].label) + ? game.i18n.localize( + CONFIG.DH.DOMAIN.allDomains()[checkbox.secondaryData.domain] + .label + ) : null, subclass: subclass ? subclass.name : null } @@ -353,10 +355,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) experienceIncreaseTagify, Object.keys(this.actor.system.experiences).reduce((acc, id) => { const experience = this.actor.system.experiences[id]; - acc[id] = { label: experience.name }; + acc.push({ id: id, label: experience.name }); return acc; - }, {}), + }, []), this.tagifyUpdate('experience').bind(this) ); } diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 7fce08aa..f0c645bd 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -83,7 +83,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli return context; } - static async updateData(event, element, formData) { + static async updateData(_event, _element, formData) { const updatedSettings = foundry.utils.expandObject(formData.object); await this.settings.updateSource({ @@ -199,7 +199,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - static async addDomain(_, target) { + static async addDomain() { const id = foundry.utils.randomID(); this.settings.updateSource({ [`domains.${id}`]: { @@ -219,6 +219,40 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli } static async deleteDomain() { + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.deleteDomain') + }, + content: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.domains.deleteDomainText', { + name: this.settings.domains[this.selected.domain].label + }) + }); + + if (!confirmed) return; + + const updateClasses = game.items.filter( + x => x.type === 'class' && x.system.domains.includes(this.selected.domain) + ); + for (let actor of game.actors) { + updateClasses.push( + ...actor.items.filter(x => x.type === 'class' && x.system.domains.includes(this.selected.domain)) + ); + } + + for (let c of updateClasses) { + const newDomains = c.system.domains.map(x => + x === this.selected.domain ? CONFIG.DH.DOMAIN.domains.arcana.id : x + ); + await c.update({ 'system.domains': newDomains }); + } + + const updateDomainCards = game.items.filter( + x => x.type === 'domainCard' && x.system.domain === this.selected.domain + ); + for (let d of updateDomainCards) { + await d.update({ 'system.domain': CONFIG.DH.DOMAIN.domains.arcana.id }); + } + await this.settings.updateSource({ [`domains.-=${this.selected.domain}`]: null }); diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index f858b2c5..79a689d8 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -14,7 +14,7 @@ export default class ClassSheet extends DHBaseItemSheet { tagifyConfigs: [ { selector: '.domain-input', - options: () => CONFIG.DH.DOMAIN.domains, + options: () => CONFIG.DH.DOMAIN.orderedDomains(), callback: ClassSheet.#onDomainSelect, tagifyOptions: { maxTags: () => game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxDomains diff --git a/module/applications/sheets/items/domainCard.mjs b/module/applications/sheets/items/domainCard.mjs index 7820fa0e..ce2d305c 100644 --- a/module/applications/sheets/items/domainCard.mjs +++ b/module/applications/sheets/items/domainCard.mjs @@ -34,4 +34,12 @@ export default class DomainCardSheet extends DHBaseItemSheet { scrollable: ['.effects'] } }; + + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.domain = CONFIG.DH.DOMAIN.allDomains()[this.document.system.domain]; + context.domainChoices = CONFIG.DH.DOMAIN.orderedDomains(); + + return context; + } } diff --git a/module/applications/ux/filter-menu.mjs b/module/applications/ux/filter-menu.mjs index b62e884b..065d08f9 100644 --- a/module/applications/ux/filter-menu.mjs +++ b/module/applications/ux/filter-menu.mjs @@ -219,7 +219,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { } })); - const domainFilter = Object.values(CONFIG.DH.DOMAIN.domains).map(({ id, label }) => ({ + const domainFilter = Object.values(CONFIG.DH.DOMAIN.allDomains()).map(({ id, label }) => ({ group: game.i18n.localize('DAGGERHEART.GENERAL.Domain.single'), name: game.i18n.localize(label), filter: { diff --git a/module/config/domainConfig.mjs b/module/config/domainConfig.mjs index 2387e00f..9574fd50 100644 --- a/module/config/domainConfig.mjs +++ b/module/config/domainConfig.mjs @@ -55,8 +55,17 @@ export const domains = { } }; -export const classDomainMap = { - rogue: [domains.midnight, domains.grace] +export const allDomains = () => ({ + ...domains, + ...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).domains +}); + +export const orderedDomains = () => { + const all = { + ...domains, + ...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).domains + }; + return Object.values(all).sort((a, b) => game.i18n.localize(a.label).localeCompare(game.i18n.localize(b.label))); }; export const subclassMap = { diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index 67c3ab04..463b73a7 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -18,7 +18,7 @@ export default class DHDomainCard extends BaseDataItem { return { ...super.defineSchema(), domain: new fields.StringField({ - choices: CONFIG.DH.DOMAIN.domains, + choices: CONFIG.DH.DOMAIN.allDomains(), required: true, initial: CONFIG.DH.DOMAIN.domains.arcana.id }), diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 83935356..f6cbb387 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -83,15 +83,16 @@ export const chunkify = (array, chunkSize, mappingFunc) => { return chunkifiedArray; }; -export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => { +export const tagifyElement = (element, baseOptions, onChange, tagifyOptions = {}) => { const { maxTags } = tagifyOptions; + const options = typeof baseOptions === 'object' ? Object.values(baseOptions) : baseOptions; + const tagifyElement = new Tagify(element, { tagTextProp: 'name', enforceWhitelist: true, - whitelist: Object.keys(options).map(key => { - const option = options[key]; + whitelist: options.map(option => { return { - value: key, + value: option.id, name: game.i18n.localize(option.label), src: option.src, description: option.description @@ -100,7 +101,7 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => maxTags: typeof maxTags === 'function' ? maxTags() : maxTags, dropdown: { mapValueTo: 'name', - searchKeys: ['name'], + searchKeys: ['value'], enabled: 0, maxItems: 100, closeOnSelect: true, diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 4b638748..e2e0b81f 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -619,6 +619,7 @@ margin-left: 8px; height: 20px; width: 20px; + filter: @dark-filter; } } } @@ -651,23 +652,25 @@ } } -.theme-light .application { - &.sheet.dh-style { - button.glow { - animation: glow-dark 0.75s infinite alternate; - } - } - - .component.dh-style.card-preview-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); - - .preview-text-container { - background-image: url(../assets/parchments/dh-parchment-dark.png); +.theme-light { + .application { + &.sheet.dh-style { + button.glow { + animation: glow-dark 0.75s infinite alternate; + } } - .preview-selected-icon-container { - background-image: url(../assets/parchments/dh-parchment-dark.png); - color: var(--color-light-5); + .component.dh-style.card-preview-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); + + .preview-text-container { + background-image: url(../assets/parchments/dh-parchment-dark.png); + } + + .preview-selected-icon-container { + background-image: url(../assets/parchments/dh-parchment-dark.png); + color: var(--color-light-5); + } } } } diff --git a/styles/less/global/item-header.less b/styles/less/global/item-header.less index 1fb27325..7b2c907f 100755 --- a/styles/less/global/item-header.less +++ b/styles/less/global/item-header.less @@ -3,11 +3,11 @@ .appTheme({ .item-card-header .item-icons-list .item-icon img { - filter: invert(88%) sepia(98%) saturate(1784%) hue-rotate(311deg) brightness(104%) contrast(91%); + filter: @golden-filter; } }, { .item-card-header .item-icons-list .item-icon img { - filter: invert(87%) sepia(15%) saturate(343%) hue-rotate(333deg) brightness(110%) contrast(87%); + filter: @bright-beige-filter; } }); diff --git a/styles/less/ui/settings/homebrew-settings/domains.less b/styles/less/ui/settings/homebrew-settings/domains.less index e41ad9bd..15eabd7a 100644 --- a/styles/less/ui/settings/homebrew-settings/domains.less +++ b/styles/less/ui/settings/homebrew-settings/domains.less @@ -1,8 +1,12 @@ -.theme-light .daggerheart.dh-style.setting.homebrew-settings .domains-tab { +.theme-light .daggerheart.dh-style.setting.homebrew-settings .domains.tab { .domains-container .domain-container { .domain-label { background-image: url('../assets/parchments/dh-parchment-light.png'); } + + img { + filter: @dark-filter; + } } } @@ -11,20 +15,33 @@ .title-wrapper { width: 100%; display: flex; + align-items: center; justify-content: center; + gap: 12px; - &:not(:first-child) { - margin-top: 16px; + &:first-child { + h2 { + margin-top: 0; + } } - h4 { + .top-lines { + position: relative; + bottom: 8px; + } + + h2 { + display: flex; + align-items: center; + font-family: @font-subtitle; position: relative; width: auto; + white-space: nowrap; + margin-top: 16px; + gap: 8px; + color: light-dark(@dark, @beige); .add-button { - position: absolute; - top: 0; - right: -28px; border-radius: 50%; width: 24px; height: 24px; @@ -66,22 +83,12 @@ white-space: nowrap; text-wrap: auto; text-align: center; + z-index: 2; } - .domain-icon { - &:before { - content: ' '; - position: absolute; - width: 100%; - height: 100%; - z-index: -1; - mask: var(--domain-icon) no-repeat center; - mask-size: contain; - background: linear-gradient(139.01deg, #efe6d8 3.51%, #372e1f 96.49%); - } - } img { border-radius: 6px; + filter: @beige-filter; } } } @@ -133,6 +140,7 @@ textarea { width: 100%; height: 120px; + margin-top: 4px; } } } diff --git a/styles/less/ui/settings/settings.less b/styles/less/ui/settings/settings.less index 3033b4e7..8062ff73 100644 --- a/styles/less/ui/settings/settings.less +++ b/styles/less/ui/settings/settings.less @@ -119,6 +119,7 @@ top: -7px; font-size: 12px; font-variant: petite-caps; + z-index: 2; } input { diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less index 0b87e18c..aed3b7dc 100755 --- a/styles/less/utils/colors.less +++ b/styles/less/utils/colors.less @@ -5,6 +5,8 @@ @golden-10: #f3c26710; @golden-40: #f3c26740; @golden-bg: #f3c2671a; +@golden-filter: brightness(0) saturate(100%) invert(89%) sepia(13%) saturate(2008%) hue-rotate(332deg) brightness(99%) + contrast(92%); @chat-blue: #8f87ee; @chat-blue-10: #8f87ee10; @@ -49,6 +51,7 @@ @dark: #222; @dark-15: #22222215; @dark-40: #22222240; +@dark-filter: brightness(0) saturate(100%); @deep-black: #0e0d15; @@ -56,6 +59,10 @@ @beige-15: #efe6d815; @beige-50: #efe6d850; @beige-80: #efe6d880; +@beige-filter: brightness(0) saturate(100%) invert(87%) sepia(25%) saturate(164%) hue-rotate(339deg) brightness(106%) + contrast(87%); +@bright-beige-filter: brightness(0) saturate(100%) invert(87%) sepia(15%) saturate(343%) hue-rotate(333deg) + brightness(110%) contrast(87%); @soft-white-shadow: rgba(255, 255, 255, 0.05); diff --git a/templates/settings/homebrew-settings/domains.hbs b/templates/settings/homebrew-settings/domains.hbs index 33e03bd5..b88e44fe 100644 --- a/templates/settings/homebrew-settings/domains.hbs +++ b/templates/settings/homebrew-settings/domains.hbs @@ -4,22 +4,26 @@ data-group="{{tabs.domains.group}}" >
-

{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.domainsTitle"}}

+ +

{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.domainsTitle"}}

+
{{#each configDomains as | domain |}}
{{localize domain.label}}
- +
{{/each}}
-

+ +

{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.homebrewDomains"}} -

+ +
{{#each homebrewDomains as | domain id |}} diff --git a/templates/settings/homebrew-settings/settings.hbs b/templates/settings/homebrew-settings/settings.hbs index c367b4e7..be408353 100644 --- a/templates/settings/homebrew-settings/settings.hbs +++ b/templates/settings/homebrew-settings/settings.hbs @@ -1,6 +1,6 @@
diff --git a/templates/sheets/items/domainCard/header.hbs b/templates/sheets/items/domainCard/header.hbs index dd048236..7d3b73e2 100644 --- a/templates/sheets/items/domainCard/header.hbs +++ b/templates/sheets/items/domainCard/header.hbs @@ -7,8 +7,8 @@ - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' source.system.domain '.label')}} - + {{localize @root.domain.label}} +
@@ -18,7 +18,7 @@

{{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' source.system.type)}} - - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' source.system.domain '.label')}} + {{localize @root.domain.label}} - {{localize "DAGGERHEART.GENERAL.level"}}: {{source.system.level}} diff --git a/templates/sheets/items/domainCard/settings.hbs b/templates/sheets/items/domainCard/settings.hbs index 5518b4c3..ae20624d 100644 --- a/templates/sheets/items/domainCard/settings.hbs +++ b/templates/sheets/items/domainCard/settings.hbs @@ -9,7 +9,7 @@ {{localize "DAGGERHEART.GENERAL.type"}} {{formField systemFields.type value=source.system.type localize=true}} {{localize "DAGGERHEART.GENERAL.Domain.single"}} - {{formField systemFields.domain value=source.system.domain localize=true}} + {{formField systemFields.domain value=source.system.domain choices=domainChoices valueAttr="id" labelAttr="label" localize=true}} {{localize "DAGGERHEART.GENERAL.level"}} {{formField systemFields.level value=source.system.level data-dtype="Number"}} {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}