diff --git a/daggerheart.mjs b/daggerheart.mjs index 5960c6b1..05b57ac9 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -233,11 +233,6 @@ Hooks.once('init', () => { return handlebarsRegistration(); }); -Hooks.on('i18nInit', () => { - // Setup homebrew resources - game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).refreshConfig(); -}); - Hooks.on('setup', () => { CONFIG.statusEffects = [ ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), diff --git a/lang/en.json b/lang/en.json index fc9d9bac..b5aad2a3 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2285,7 +2285,6 @@ "identify": "Identity", "imagePath": "Image Path", "inactiveEffects": "Inactive Effects", - "initial": "Initial", "inventory": "Inventory", "itemResource": "Item Resource", "itemQuantity": "Item Quantity", @@ -2672,8 +2671,6 @@ "resetMovesText": "Are you sure you want to reset?", "deleteItemTitle": "Delete Homebrew Item", "deleteItemText": "Are you sure you want to delete the item?", - "deleteResourceTitle": "Delete Homebrew Resource", - "deleteResourceText": "Are you sure you want to delete the resource?", "FIELDS": { "maxFear": { "label": "Max Fear" }, "maxHope": { "label": "Max Hope" }, @@ -2682,13 +2679,6 @@ "label": "Max Cards in Loadout", "hint": "Set to blank or 0 for unlimited maximum" }, - "resources": { - "resources": { - "value": { "label": "Icon" }, - "isIcon": { "label": "Font Awesome Icon" }, - "noColorFilter": { "label": "Disable Color Filter" } - } - }, "maxDomains": { "label": "Max Class Domains", "hint": "Max domains you can set on a class" } }, "currency": { @@ -2717,13 +2707,6 @@ "adversaryType": { "title": "Custom Adversary Types", "newType": "Adversary Type" - }, - "resources": { - "typeTitle": "{type} Resources", - "filledIcon": "Filled Icon", - "emptyIcon": "Empty Icon", - "resourceIdentifier": "Resource Identifier", - "setResourceIdentifier": "Set Resource Identifier" } }, "Menu": { diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 9cc0ecb1..083c468f 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -1,5 +1,4 @@ import { DhHomebrew } from '../../data/settings/_module.mjs'; -import { Resource } from '../../data/settings/Homebrew.mjs'; import { slugify } from '../../helpers/utils.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -45,9 +44,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli addAdversaryType: this.addAdversaryType, deleteAdversaryType: this.deleteAdversaryType, selectAdversaryType: this.selectAdversaryType, - addResource: this.addResource, - removeResource: this.removeResource, - resetResourceImage: this.resetResourceImage, save: this.save, resetTokenSizes: this.resetTokenSizes, reset: this.reset @@ -60,10 +56,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli settings: { template: 'systems/daggerheart/templates/settings/homebrew-settings/settings.hbs' }, domains: { template: 'systems/daggerheart/templates/settings/homebrew-settings/domains.hbs' }, types: { template: 'systems/daggerheart/templates/settings/homebrew-settings/types.hbs' }, - resources: { - template: 'systems/daggerheart/templates/settings/homebrew-settings/resources.hbs', - scrollable: ['.resource-types-container'] - }, itemTypes: { template: 'systems/daggerheart/templates/settings/homebrew-settings/itemFeatures.hbs' }, downtime: { template: 'systems/daggerheart/templates/settings/homebrew-settings/downtime.hbs' }, footer: { template: 'systems/daggerheart/templates/settings/homebrew-settings/footer.hbs' } @@ -72,14 +64,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli /** @inheritdoc */ static TABS = { main: { - tabs: [ - { id: 'settings' }, - { id: 'domains' }, - { id: 'types' }, - { id: 'resources' }, - { id: 'itemFeatures' }, - { id: 'downtime' } - ], + tabs: [{ id: 'settings' }, { id: 'domains' }, { id: 'types' }, { id: 'itemFeatures' }, { id: 'downtime' }], initial: 'settings', labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } @@ -92,17 +77,9 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - for (const element of htmlElement.querySelectorAll('.path-field input')) - element.addEventListener('change', this.toggleResourceIsIcon.bind(this)); - } - async _prepareContext(_options) { const context = await super._prepareContext(_options); context.settingFields = this.settings; - context.schemaFields = context.settingFields.schema.fields; return context; } @@ -126,8 +103,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli ? { id: this.selected.adversaryType, ...this.settings.adversaryTypes[this.selected.adversaryType] } : null; break; - case 'resources': - break; case 'downtime': context.restOptions = { shortRest: CONFIG.DH.GENERAL.defaultRestOptions.shortRest(), @@ -149,33 +124,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - async toggleResourceIsIcon(event) { - const element = event.target.closest('.resource-icon-container'); - const { actorType, resourceKey, imageKey } = element.dataset; - - const current = this.settings.resources[actorType].resources[resourceKey].images[imageKey]; - await this.settings.updateSource({ - [`resources.${actorType}.resources.${resourceKey}.images.${imageKey}`]: { - isIcon: !current.isIcon, - value: '' - } - }); - - this.render(); - } - - static async resetResourceImage(_event, button) { - const element = button.closest('.resource-icon-container'); - const { actorType, resourceKey, imageKey } = element.dataset; - - await this.settings.updateSource({ - [`resources.${actorType}.resources.${resourceKey}.images.${imageKey}`]: - Resource.getDefaultImageData(imageKey) - }); - - this.render(); - } - static async changeCurrencyIcon(_, target) { const type = target.dataset.currency; const currentIcon = this.settings.currency[type].icon; @@ -518,58 +466,6 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - static async addResource(_, target) { - const { actorType } = target.dataset; - const content = new foundry.data.fields.StringField({ - label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.resources.resourceIdentifier'), - required: true - }).toFormGroup({}, { name: 'identifier', localize: true }).outerHTML; - - async function callback(_, button) { - const identifier = button.form.elements.identifier.value; - if (!identifier) return; - - const sluggedIdentifier = slugify(identifier); - - await this.settings.updateSource({ - [`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier) - }); - - game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); - this.render(); - } - - await foundry.applications.api.DialogV2.prompt({ - content: content, - rejectClose: false, - modal: true, - ok: { callback: callback.bind(this) }, - window: { - title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.resources.setResourceIdentifier') - }, - position: { width: 400 } - }); - } - - static async removeResource(_, target) { - const confirmed = await foundry.applications.api.DialogV2.confirm({ - window: { - title: game.i18n.localize(`DAGGERHEART.SETTINGS.Homebrew.deleteResourceTitle`) - }, - content: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.deleteResourceText') - }); - - if (!confirmed) return; - - const { actorType, resourceKey } = target.dataset; - await this.settings.updateSource({ - [`resources.${actorType}.resources.-=${resourceKey}`]: null - }); - - game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); - this.render(); - } - static async save() { await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); this.close(); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 14dd1ae7..4ecaeb06 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -33,7 +33,6 @@ export default class CharacterSheet extends DHBaseActorSheet { handleResourceDice: CharacterSheet.#handleResourceDice, advanceResourceDie: CharacterSheet.#advanceResourceDie, cancelBeastform: CharacterSheet.#cancelBeastform, - toggleResourceManagement: CharacterSheet.#toggleResourceManagement, useDowntime: this.useDowntime, viewParty: CharacterSheet.#viewParty }, @@ -227,9 +226,6 @@ export default class CharacterSheet extends DHBaseActorSheet { async _preparePartContext(partId, context, options) { context = await super._preparePartContext(partId, context, options); switch (partId) { - case 'header': - await this._prepareHeaderContext(context, options); - break; case 'loadout': await this._prepareLoadoutContext(context, options); break; @@ -244,12 +240,6 @@ export default class CharacterSheet extends DHBaseActorSheet { return context; } - async _prepareHeaderContext(context, _options) { - context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.character.all).some( - key => !CONFIG.DH.RESOURCE.character.base[key] - ); - } - /** * Prepare render context for the Loadout part. * @param {ApplicationRenderContext} context @@ -952,78 +942,6 @@ export default class CharacterSheet extends DHBaseActorSheet { }); } - static async #toggleResourceManagement(event, button) { - event.stopPropagation(); - const existingTooltip = document.body.querySelector('.locked-tooltip .resource-management-container'); - if (existingTooltip) { - game.tooltip.dismissLockedTooltips(); - return; - } - - const extraResources = Object.values(CONFIG.DH.RESOURCE.character.all).reduce((acc, resource) => { - if (CONFIG.DH.RESOURCE.character.base[resource.id]) return acc; - - const resourceData = this.document.system.resources[resource.id]; - acc[resource.id] = { - id: resource.id, - label: game.i18n.localize(resource.label), - value: resourceData.value, - max: resourceData.max, - fullIcon: resource.images?.full ?? { value: 'fa-solid fa-circle', isIcon: true }, - emptyIcon: resource.images?.empty ?? { value: 'fa-regular fa-circle', isIcon: true } - }; - - return acc; - }, {}); - - const html = document.createElement('div'); - html.innerHTML = await foundry.applications.handlebars.renderTemplate( - `systems/daggerheart/templates/ui/tooltip/resourceManagement.hbs`, - { - resources: extraResources - } - ); - - const target = button.closest('.resource-section'); - - game.tooltip.dismissLockedTooltips(); - game.tooltip.activate(target, { - html, - locked: true, - cssClass: 'bordered-tooltip', - direction: 'DOWN', - noOffset: true - }); - - const resourceManager = target.querySelector('.resource-manager'); - resourceManager.classList.toggle('inverted'); - - Hooks.once(CONFIG.DH.HOOKS.hooksConfig.lockedTooltipDismissed, () => { - resourceManager.classList.toggle('inverted'); - }); - - for (const element of html.querySelectorAll('.resource-value')) - element.addEventListener('click', this.onUpdateResource.bind(this)); - } - - async onUpdateResource(event) { - const target = event.target.closest('.resource-value'); - const { resource, value: textValue } = target.dataset; - - const inputValue = Number.parseInt(textValue); - const decreasing = inputValue <= this.document.system.resources[resource].value; - const value = decreasing ? inputValue - 1 : inputValue; - await this.document.update({ [`system.resources.${resource}.value`]: value }, { render: false }); - - /* Update resource symbols */ - const section = target.closest('.resource-section'); - for (const element of section.querySelectorAll('.resource-value')) { - const showFull = Number.parseInt(element.dataset.value) <= value; - element.querySelector('.full').classList.toggle('hidden', !showFull); - element.querySelector('.empty').classList.toggle('hidden', showFull); - } - } - /** * Open the downtime application. * @type {ApplicationClickAction} diff --git a/module/applications/sheets/api/actor-setting.mjs b/module/applications/sheets/api/actor-setting.mjs index 738f7002..d8cfb40f 100644 --- a/module/applications/sheets/api/actor-setting.mjs +++ b/module/applications/sheets/api/actor-setting.mjs @@ -44,32 +44,8 @@ export default class DHBaseActorSettings extends DHApplicationMixin(DocumentShee const context = await super._prepareContext(options); context.isNPC = this.actor.isNPC; - if (context.systemFields.attack) { + if (context.systemFields.attack) context.systemFields.attack.fields = this.actor.system.attack.schema.fields; - } - - // Create fake fields for actor configurable max resource value. - const resourceConfig = CONFIG.DH.RESOURCE[this.actor.type]?.all; - if (resourceConfig) { - const relevant = ['hitPoints', 'stress'].filter(r => r in resourceConfig); - context.resources = relevant.map(key => { - const data = this.actor._source.system.resources[key]; - const config = resourceConfig[key]; - return { - label: config.label, - name: `system.resources.${key}.max`, - value: data.max ?? config.max, - tooltip: key === 'hitPoints' ? game.i18n.localize('DAGGERHEART.UI.Tooltip.maxHPClassBound') : null, - field: new foundry.data.fields.NumberField({ - initial: config.max, - integer: true, - label: game.i18n.format('DAGGERHEART.GENERAL.maxWithThing', { - thing: game.i18n.localize(config.label) - }) - }) - }; - }); - } return context; } diff --git a/module/config/_module.mjs b/module/config/_module.mjs index 7a725f54..560f3fec 100644 --- a/module/config/_module.mjs +++ b/module/config/_module.mjs @@ -11,4 +11,3 @@ export * as settingsConfig from './settingsConfig.mjs'; export * as systemConfig from './system.mjs'; export * as itemBrowserConfig from './itemBrowserConfig.mjs'; export * as triggerConfig from './triggerConfig.mjs'; -export * as resourceConfig from './resourceConfig.mjs'; diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index aa7c3cf7..ac55117a 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -55,6 +55,24 @@ export const abilities = { } }; +export const scrollingTextResource = { + hitPoints: { + label: 'DAGGERHEART.GENERAL.HitPoints.plural', + reversed: true + }, + stress: { + label: 'DAGGERHEART.GENERAL.stress', + reversed: true + }, + hope: { + label: 'DAGGERHEART.GENERAL.hope' + }, + armor: { + label: 'DAGGERHEART.GENERAL.armor', + reversed: true + } +}; + export const featureProperties = { agility: { name: 'DAGGERHEART.CONFIG.Traits.agility.name', @@ -488,8 +506,8 @@ export const subclassFeatureLabels = { * @property {number[]} damage */ -/** - * @type {Record} +/** + * @type {Record} * Scaling data used to change an adversary's tier. Each rank is applied incrementally. */ export const adversaryScalingData = { @@ -500,7 +518,7 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 1, stress: 2, - attack: 2 + attack: 2, }, 3: { difficulty: 2, @@ -508,7 +526,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 1, stress: 0, - attack: 2 + attack: 2, }, 4: { difficulty: 2, @@ -516,7 +534,7 @@ export const adversaryScalingData = { severeThreshold: 25, hp: 1, stress: 0, - attack: 2 + attack: 2, } }, horde: { @@ -526,7 +544,7 @@ export const adversaryScalingData = { severeThreshold: 8, hp: 2, stress: 0, - attack: 0 + attack: 0, }, 3: { difficulty: 2, @@ -534,7 +552,7 @@ export const adversaryScalingData = { severeThreshold: 12, hp: 0, stress: 1, - attack: 1 + attack: 1, }, 4: { difficulty: 2, @@ -542,7 +560,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 2, stress: 0, - attack: 0 + attack: 0, } }, leader: { @@ -552,7 +570,7 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 0, stress: 0, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -560,7 +578,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 1, stress: 0, - attack: 2 + attack: 2, }, 4: { difficulty: 2, @@ -568,7 +586,7 @@ export const adversaryScalingData = { severeThreshold: 25, hp: 1, stress: 1, - attack: 3 + attack: 3, } }, minion: { @@ -578,7 +596,7 @@ export const adversaryScalingData = { severeThreshold: 0, hp: 0, stress: 0, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -586,7 +604,7 @@ export const adversaryScalingData = { severeThreshold: 0, hp: 0, stress: 1, - attack: 1 + attack: 1, }, 4: { difficulty: 2, @@ -594,7 +612,7 @@ export const adversaryScalingData = { severeThreshold: 0, hp: 0, stress: 0, - attack: 1 + attack: 1, } }, ranged: { @@ -604,7 +622,7 @@ export const adversaryScalingData = { severeThreshold: 6, hp: 1, stress: 0, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -612,7 +630,7 @@ export const adversaryScalingData = { severeThreshold: 14, hp: 1, stress: 1, - attack: 2 + attack: 2, }, 4: { difficulty: 2, @@ -620,7 +638,7 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 1, stress: 1, - attack: 1 + attack: 1, } }, skulk: { @@ -630,7 +648,7 @@ export const adversaryScalingData = { severeThreshold: 8, hp: 1, stress: 1, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -638,7 +656,7 @@ export const adversaryScalingData = { severeThreshold: 12, hp: 1, stress: 1, - attack: 1 + attack: 1, }, 4: { difficulty: 2, @@ -646,7 +664,7 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 1, stress: 1, - attack: 1 + attack: 1, } }, solo: { @@ -656,7 +674,7 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 0, stress: 1, - attack: 2 + attack: 2, }, 3: { difficulty: 2, @@ -664,7 +682,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 2, stress: 1, - attack: 2 + attack: 2, }, 4: { difficulty: 2, @@ -672,7 +690,7 @@ export const adversaryScalingData = { severeThreshold: 25, hp: 0, stress: 1, - attack: 3 + attack: 3, } }, standard: { @@ -682,7 +700,7 @@ export const adversaryScalingData = { severeThreshold: 8, hp: 0, stress: 0, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -690,7 +708,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 1, stress: 1, - attack: 1 + attack: 1, }, 4: { difficulty: 2, @@ -698,7 +716,7 @@ export const adversaryScalingData = { severeThreshold: 15, hp: 0, stress: 1, - attack: 1 + attack: 1, } }, support: { @@ -708,7 +726,7 @@ export const adversaryScalingData = { severeThreshold: 8, hp: 1, stress: 1, - attack: 1 + attack: 1, }, 3: { difficulty: 2, @@ -716,7 +734,7 @@ export const adversaryScalingData = { severeThreshold: 12, hp: 0, stress: 0, - attack: 1 + attack: 1, }, 4: { difficulty: 2, @@ -724,27 +742,27 @@ export const adversaryScalingData = { severeThreshold: 10, hp: 1, stress: 1, - attack: 1 + attack: 1, } } }; -/** +/** * Scaling data used for an adversary's damage. * Tier 4 is missing certain adversary types and therefore skews upwards. * We manually set tier 4 data to hopefully lead to better results */ export const adversaryExpectedDamage = { - basic: { - 1: { mean: 7.321428571428571, deviation: 1.962519002770912 }, - 2: { mean: 12.444444444444445, deviation: 2.0631069425529676 }, - 3: { mean: 15.722222222222221, deviation: 2.486565208464823 }, - 4: { mean: 26, deviation: 5.2 } - }, - minion: { - 1: { mean: 2.142857142857143, deviation: 1.0690449676496976 }, - 2: { mean: 5, deviation: 0.816496580927726 }, - 3: { mean: 6.5, deviation: 2.1213203435596424 }, - 4: { mean: 11, deviation: 1 } - } + basic: { + 1: { mean: 7.321428571428571, deviation: 1.962519002770912 }, + 2: { mean: 12.444444444444445, deviation: 2.0631069425529676 }, + 3: { mean: 15.722222222222221, deviation: 2.486565208464823 }, + 4: { mean: 26, deviation: 5.2 } + }, + minion: { + 1: { mean: 2.142857142857143, deviation: 1.0690449676496976 }, + 2: { mean: 5, deviation: 0.816496580927726 }, + 3: { mean: 6.5, deviation: 2.1213203435596424 }, + 4: { mean: 11, deviation: 1 } + } }; diff --git a/module/config/hooksConfig.mjs b/module/config/hooksConfig.mjs index 61ba594c..9140ea0a 100644 --- a/module/config/hooksConfig.mjs +++ b/module/config/hooksConfig.mjs @@ -1,4 +1,3 @@ export const hooksConfig = { - effectDisplayToggle: 'DHEffectDisplayToggle', - lockedTooltipDismissed: 'DHLockedTooltipDismissed' + effectDisplayToggle: 'DHEffectDisplayToggle' }; diff --git a/module/config/resourceConfig.mjs b/module/config/resourceConfig.mjs deleted file mode 100644 index 56ef6cd5..00000000 --- a/module/config/resourceConfig.mjs +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Full custom typing: - * id - * initial - * max - * reverse - * label - * images { - * full { value, isIcon, noColorFilter } - * empty { value, isIcon noColorFilter } - * } - */ - -const characterBaseResources = Object.freeze({ - hitPoints: { - id: 'hitPoints', - initial: 0, - max: 0, - reverse: true, - label: 'DAGGERHEART.GENERAL.HitPoints.plural', - maxLabel: 'DAGGERHEART.ACTORS.Character.maxHPBonus' - }, - stress: { - id: 'stress', - initial: 0, - max: 6, - reverse: true, - label: 'DAGGERHEART.GENERAL.stress' - }, - hope: { - id: 'hope', - initial: 2, - reverse: false, - label: 'DAGGERHEART.GENERAL.hope' - } -}); - -const adversaryBaseResources = Object.freeze({ - hitPoints: { - id: 'hitPoints', - initial: 0, - max: 0, - reverse: true, - label: 'DAGGERHEART.GENERAL.HitPoints.plural', - maxLabel: 'DAGGERHEART.ACTORS.Character.maxHPBonus' - }, - stress: { - id: 'stress', - initial: 0, - max: 0, - reverse: true, - label: 'DAGGERHEART.GENERAL.stress' - } -}); - -const companionBaseResources = Object.freeze({ - stress: { - id: 'stress', - initial: 0, - max: 0, - reverse: true, - label: 'DAGGERHEART.GENERAL.stress' - }, - hope: { - id: 'hope', - initial: 0, - reverse: false, - label: 'DAGGERHEART.GENERAL.hope' - } -}); - -export const character = { - base: characterBaseResources, - custom: {}, // module stuff goes here - all: { ...characterBaseResources } -}; - -export const adversary = { - base: adversaryBaseResources, - custom: {}, // module stuff goes here - all: { ...adversaryBaseResources } -}; - -export const companion = { - base: companionBaseResources, - custom: {}, // module stuff goes here - all: { ...companionBaseResources } -}; diff --git a/module/config/system.mjs b/module/config/system.mjs index 31dba518..47a41e8d 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -2,7 +2,6 @@ import * as GENERAL from './generalConfig.mjs'; import * as DOMAIN from './domainConfig.mjs'; import * as ENCOUNTER from './encounterConfig.mjs'; import * as ACTOR from './actorConfig.mjs'; -import * as RESOURCE from './resourceConfig.mjs'; import * as ITEM from './itemConfig.mjs'; import * as SETTINGS from './settingsConfig.mjs'; import * as EFFECTS from './effectConfig.mjs'; @@ -20,7 +19,6 @@ export const SYSTEM = { GENERAL, DOMAIN, ACTOR, - RESOURCE, ITEM, SETTINGS, EFFECTS, diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 2053ac99..0a446c15 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -2,7 +2,7 @@ import DHAdversarySettings from '../../applications/sheets-configs/adversary-set import { ActionField } from '../fields/actionField.mjs'; import { commonActorRules } from './base.mjs'; import DhCreature from './creature.mjs'; -import { bonusField } from '../fields/actorField.mjs'; +import { resourceField, bonusField } from '../fields/actorField.mjs'; import { calculateExpectedValue, parseTermsFromSimpleFormula } from '../../helpers/utils.mjs'; import { adversaryExpectedDamage, adversaryScalingData } from '../../config/actorConfig.mjs'; @@ -65,6 +65,10 @@ export default class DhpAdversary extends DhCreature { label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold' }) }), + resources: new fields.SchemaField({ + hitPoints: resourceField(0, 0, 'DAGGERHEART.GENERAL.HitPoints.plural', true), + stress: resourceField(0, 0, 'DAGGERHEART.GENERAL.stress', true) + }), rules: new fields.SchemaField({ ...commonActorRules() }), @@ -187,7 +191,6 @@ export default class DhpAdversary extends DhCreature { } prepareDerivedData() { - super.prepareDerivedData(); this.attack.roll.isStandardAttack = true; } diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index e2f910a0..5e16bac9 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -213,7 +213,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { const textData = Object.keys(changes.system.resources).reduce((acc, key) => { const resource = changes.system.resources[key]; if (resource.value !== undefined && resource.value !== this.resources[key].value) { - acc.push(getScrollTextData(this.parent, resource, key)); + acc.push(getScrollTextData(this.resources, resource, key)); } return acc; diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 68f7f3a8..10fba63c 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -3,7 +3,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import DhLevelData from '../levelData.mjs'; import { commonActorRules } from './base.mjs'; import DhCreature from './creature.mjs'; -import { attributeField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs'; +import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs'; import { ActionField } from '../fields/actionField.mjs'; import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs'; @@ -27,6 +27,28 @@ export default class DhCharacter extends DhCreature { return { ...super.defineSchema(), + resources: new fields.SchemaField({ + hitPoints: resourceField( + 0, + 0, + 'DAGGERHEART.GENERAL.HitPoints.plural', + true, + 'DAGGERHEART.ACTORS.Character.maxHPBonus' + ), + stress: resourceField(6, 0, 'DAGGERHEART.GENERAL.stress', true), + hope: new fields.SchemaField( + { + value: new fields.NumberField({ + initial: 2, + min: 0, + integer: true, + label: 'DAGGERHEART.GENERAL.hope' + }), + isReversed: new fields.BooleanField({ initial: false }) + }, + { label: 'DAGGERHEART.GENERAL.hope' } + ) + }), traits: new fields.SchemaField({ agility: attributeField('DAGGERHEART.CONFIG.Traits.agility.name'), strength: attributeField('DAGGERHEART.CONFIG.Traits.strength.name'), @@ -587,7 +609,6 @@ export default class DhCharacter extends DhCreature { } prepareBaseData() { - super.prepareBaseData(); this.evasion += this.class.value?.system?.evasion ?? 0; const currentLevel = this.levelData.level.current; @@ -659,7 +680,6 @@ export default class DhCharacter extends DhCreature { } prepareDerivedData() { - super.prepareDerivedData(); let baseHope = this.resources.hope.value; if (this.companion) { for (let levelKey in this.companion.system.levelData.levelups) { @@ -679,7 +699,6 @@ export default class DhCharacter extends DhCreature { this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; this.resources.armor = { - label: 'DAGGERHEART.GENERAL.armor', value: this.armor?.system?.marks?.value ?? 0, max: this.armorScore, isReversed: true diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 7a8f0e64..6f51b593 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -4,7 +4,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import { ActionField } from '../fields/actionField.mjs'; import { adjustDice, adjustRange } from '../../helpers/utils.mjs'; import DHCompanionSettings from '../../applications/sheets-configs/companion-settings.mjs'; -import { bonusField } from '../fields/actorField.mjs'; +import { resourceField, bonusField } from '../fields/actorField.mjs'; export default class DhCompanion extends DhCreature { static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Companion']; @@ -26,6 +26,10 @@ export default class DhCompanion extends DhCreature { return { ...super.defineSchema(), partner: new ForeignDocumentUUIDField({ type: 'Actor' }), + resources: new fields.SchemaField({ + stress: resourceField(3, 0, 'DAGGERHEART.GENERAL.stress', true), + hope: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.hope' }) + }), evasion: new fields.NumberField({ required: true, min: 1, @@ -123,7 +127,6 @@ export default class DhCompanion extends DhCreature { } prepareBaseData() { - super.prepareBaseData(); this.attack.roll.bonus = this.partner?.system?.spellcastModifier ?? 0; for (let levelKey in this.levelData.levelups) { @@ -158,7 +161,6 @@ export default class DhCompanion extends DhCreature { } prepareDerivedData() { - super.prepareDerivedData(); /* Partner Related Setup */ if (this.partner) { this.levelData.level.changed = this.partner.system.levelData.level.current; diff --git a/module/data/actor/creature.mjs b/module/data/actor/creature.mjs index 601068ad..c8bf8448 100644 --- a/module/data/actor/creature.mjs +++ b/module/data/actor/creature.mjs @@ -1,4 +1,3 @@ -import { ResourcesField } from '../fields/actorField.mjs'; import BaseDataActor from './base.mjs'; export default class DhCreature extends BaseDataActor { @@ -8,7 +7,6 @@ export default class DhCreature extends BaseDataActor { return { ...super.defineSchema(), - resources: new ResourcesField(this.metadata.type), advantageSources: new fields.ArrayField(new fields.StringField(), { label: 'DAGGERHEART.ACTORS.Character.advantageSources.label', hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint' diff --git a/module/data/fields/actorField.mjs b/module/data/fields/actorField.mjs index 1399fb32..db1faad4 100644 --- a/module/data/fields/actorField.mjs +++ b/module/data/fields/actorField.mjs @@ -6,6 +6,22 @@ const attributeField = label => tierMarked: new fields.BooleanField({ initial: false }) }); +const resourceField = (max = 0, initial = 0, label, reverse = false, maxLabel) => + new fields.SchemaField( + { + value: new fields.NumberField({ initial: initial, min: 0, integer: true, label }), + max: new fields.NumberField({ + initial: max, + integer: true, + label: + maxLabel ?? + game.i18n.format('DAGGERHEART.GENERAL.maxWithThing', { thing: game.i18n.localize(label) }) + }), + isReversed: new fields.BooleanField({ initial: reverse }) + }, + { label } + ); + const stressDamageReductionRule = localizationPath => new fields.SchemaField({ cost: new fields.NumberField({ @@ -21,67 +37,4 @@ const bonusField = label => dice: new fields.ArrayField(new fields.StringField(), { label: `${game.i18n.localize(label)} Dice` }) }); -/** - * Field used for actor resources. It is a resource that validates dynamically based on the config. - * Because "max" may be defined during runtime, we don't attempt to clamp the maximum value. - */ -class ResourcesField extends fields.TypedObjectField { - constructor(actorType) { - super( - new fields.SchemaField({ - value: new fields.NumberField({ min: 0, initial: 0, integer: true }), - // Some resources allow changing max. A null max means its the default - max: new fields.NumberField({ initial: null, integer: true, nullable: true }) - }) - ); - this.actorType = actorType; - } - - getInitialValue() { - const resources = CONFIG.DH.RESOURCE[this.actorType].all; - return Object.values(resources).reduce((result, resource) => { - result[resource.id] = { - value: resource.initial, - max: null - }; - return result; - }, {}); - } - - _validateKey(key) { - return key in CONFIG.DH.RESOURCE[this.actorType].all; - } - - _cleanType(value, options) { - value = super._cleanType(value, options); - - // If not partial, ensure all data exists - if (!options.partial) { - value = foundry.utils.mergeObject(this.getInitialValue(), value); - } - - return value; - } - - /** Initializes the original source data, returning prepared data */ - initialize(...args) { - const data = super.initialize(...args); - const resources = CONFIG.DH.RESOURCE[this.actorType].all; - for (const [key, value] of Object.entries(data)) { - // TypedObjectField only calls _validateKey when persisting, so we also call it here - if (!this._validateKey(key)) { - delete value[key]; - continue; - } - - // Add basic prepared data. - const resource = resources[key]; - value.label = resource.label; - value.isReversed = resources[key].reverse; - value.max = typeof resource.max === 'number' ? (value.max ?? resource.max) : null; - } - return data; - } -} - -export { attributeField, ResourcesField, stressDamageReductionRule, bonusField }; +export { attributeField, resourceField, stressDamageReductionRule, bonusField }; diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 6f3256e3..84f39103 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -224,7 +224,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { const armorChanged = changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value; if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') { - const armorData = getScrollTextData(this.parent.parent, changed.system.marks, 'armor'); + const armorData = getScrollTextData(this.parent.parent.system.resources, changed.system.marks, 'armor'); options.scrollingTextData = [armorData]; } diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index d4b7b03f..b8804fa7 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -145,16 +145,6 @@ export default class DhHomebrew extends foundry.abstract.DataModel { description: new fields.StringField() }) ), - resources: new fields.TypedObjectField( - new fields.SchemaField({ - resources: new fields.TypedObjectField(new fields.EmbeddedDataField(Resource)) - }), - { - initial: { - character: { resources: {} } - } - } - ), itemFeatures: new fields.SchemaField({ weaponFeatures: new fields.TypedObjectField( new fields.SchemaField({ @@ -195,117 +185,4 @@ export default class DhHomebrew extends foundry.abstract.DataModel { } return source; } - - /** Invoked by the setting when data changes */ - handleChange() { - if (this.maxFear) { - if (ui.resources) ui.resources.render({ force: true }); - } - - this.refreshConfig(); - this.#resetActors(); - } - - /** Update config values based on homebrew data. Make sure the references don't change */ - refreshConfig() { - for (const [actorType, actorData] of Object.entries(this.resources)) { - const config = CONFIG.DH.RESOURCE[actorType]; - for (const key of Object.keys(config.all)) { - delete config.all[key]; - } - Object.assign(config.all, { - ...Object.entries(actorData.resources).reduce((result, [key, value]) => { - result[key] = value.toObject(); - result[key].id = key; - return result; - }, {}), - ...config.custom, - ...config.base - }); - } - } - - /** - * Triggers a reset and non-forced re-render on all given actors (if given) - * or all world actors and actors in all scenes to show immediate results for a changed setting. - */ - #resetActors() { - const actors = new Set( - [ - game.actors.contents, - game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) - ].flat() - ); - for (const actor of actors) { - for (const app of Object.values(actor.apps)) { - for (const element of app.element?.querySelectorAll('prose-mirror.active')) { - element.open = false; // This triggers a save - } - } - - actor.reset(); - actor.render(); - } - } } - -export class Resource extends foundry.abstract.DataModel { - static defineSchema() { - const fields = foundry.data.fields; - return { - initial: new fields.NumberField({ - required: true, - integer: true, - initial: 0, - min: 0, - label: 'DAGGERHEART.GENERAL.initial' - }), - max: new fields.NumberField({ - nullable: true, - initial: null, - min: 0, - label: 'DAGGERHEART.GENERAL.max' - }), - label: new fields.StringField({ label: 'DAGGERHEART.GENERAL.label' }), - images: new fields.SchemaField({ - full: imageIconField('fa solid fa-circle'), - empty: imageIconField('fa-regular fa-circle') - }) - }; - } - - static getDefaultResourceData = label => { - const images = Resource.schema.fields.images.getInitialValue(); - return { - initial: 0, - max: 0, - label: label ?? '', - images - }; - }; - - static getDefaultImageData = imageKey => { - return Resource.schema.fields.images.fields[imageKey].getInitialValue(); - }; -} - -const imageIconField = defaultValue => - new foundry.data.fields.SchemaField( - { - value: new foundry.data.fields.StringField({ - initial: defaultValue, - label: 'DAGGERHEART.SETTINGS.Homebrew.FIELDS.resources.resources.value.label' - }), - isIcon: new foundry.data.fields.BooleanField({ - required: true, - initial: true, - label: 'DAGGERHEART.SETTINGS.Homebrew.FIELDS.resources.resources.isIcon.label' - }), - noColorFilter: new foundry.data.fields.BooleanField({ - required: true, - initial: false, - label: 'DAGGERHEART.SETTINGS.Homebrew.FIELDS.resources.resources.noColorFilter.label' - }) - }, - { required: true } - ); diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index 4793f1f7..c4b52bb5 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -3,7 +3,6 @@ import { AdversaryBPPerEncounter, BaseBPPerEncounter } from '../config/encounter export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager { #wide = false; #bordered = false; - #active = false; async activate(element, options = {}) { const { TextEditor } = foundry.applications.ux; @@ -169,100 +168,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti } } - this.baseActivate(element, { ...options, html: html }); - } - - /* Need to pass more options to _setAnchor, so have to copy whole foundry method >_< */ - async baseActivate(element, options) { - let { text, direction, cssClass, locked = false, html, content } = options; - if (content && !html) { - foundry.utils.logCompatibilityWarning( - 'The content option has been deprecated in favor of the html option', - { since: 13, until: 15, once: true } - ); - html = content; - } - if (text && html) throw new Error('Cannot provide both text and html options to TooltipManager#activate.'); - // Deactivate currently active element - this.deactivate(); - // Check if the element still exists in the DOM. - if (!document.body.contains(element)) return; - // Mark the new element as active - this.#active = true; - this.element = element; - element.setAttribute('aria-describedby', 'tooltip'); - html ||= element.dataset.tooltipHtml; - if (html) { - if (typeof html === 'string') this.tooltip.innerHTML = foundry.utils.cleanHTML(html); - else { - this.tooltip.innerHTML = ''; // Clear existing HTML - this.tooltip.appendChild(html); - } - } else { - text ||= element.dataset.tooltipText; - if (text) this.tooltip.textContent = text; - else { - text = element.dataset.tooltip; - // Localized message should be safe - if (game.i18n.has(text)) this.tooltip.innerHTML = game.i18n.localize(text); - else this.tooltip.innerHTML = foundry.utils.cleanHTML(text); - } - } - - // Activate display of the tooltip - this.tooltip.removeAttribute('class'); - this.tooltip.classList.add('active', 'themed', 'theme-dark'); - this.tooltip.showPopover(); - cssClass ??= element.closest('[data-tooltip-class]')?.dataset.tooltipClass; - if (cssClass) this.tooltip.classList.add(...cssClass.split(' ')); - - // Set tooltip position - direction ??= element.closest('[data-tooltip-direction]')?.dataset.tooltipDirection; - if (!direction) direction = this._determineDirection(); - this._setAnchor(direction, options); - - if (locked || element.dataset.hasOwnProperty('locked')) this.lockTooltip(); - } - - _setAnchor(direction, options) { - const directions = this.constructor.TOOLTIP_DIRECTIONS; - const pad = this.constructor.TOOLTIP_MARGIN_PX; - const pos = this.element.getBoundingClientRect(); - - const { innerHeight, innerWidth } = this.tooltip.ownerDocument.defaultView; - const tooltipPadding = 16; - const horizontalOffset = options.noOffset ? tooltipPadding : this.tooltip.offsetWidth / 2 - pos.width / 2; - const verticalOffset = options.noOffset ? tooltipPadding : this.tooltip.offsetHeight / 2 - pos.height / 2; - - const style = {}; - switch (direction) { - case directions.DOWN: - style.textAlign = 'center'; - style.left = pos.left - horizontalOffset; - style.top = pos.bottom + pad; - break; - case directions.LEFT: - style.textAlign = 'left'; - style.right = innerWidth - pos.left + pad; - style.top = pos.top - verticalOffset; - break; - case directions.RIGHT: - style.textAlign = 'right'; - style.left = pos.right + pad; - style.top = pos.top - verticalOffset; - break; - case directions.UP: - style.textAlign = 'center'; - style.left = pos.left - horizontalOffset; - style.bottom = innerHeight - pos.top + pad; - break; - case directions.CENTER: - style.textAlign = 'center'; - style.left = pos.left - horizontalOffset; - style.top = pos.top - verticalOffset; - break; - } - return this._setStyle(style); + super.activate(element, { ...options, html: html }); } _determineItemTooltipDirection(element, prefered = this.constructor.TOOLTIP_DIRECTIONS.LEFT) { @@ -364,12 +270,6 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti return clone; } - /**@inheritdoc */ - dismissLockedTooltips() { - super.dismissLockedTooltips(); - Hooks.callAll(CONFIG.DH.HOOKS.hooksConfig.lockedTooltipDismissed); - } - /** Get HTML for Battlepoints tooltip */ async getBattlepointHTML(combatId) { const combat = game.combats.get(combatId); diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index b49a98ca..86514fd1 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -384,18 +384,17 @@ export const arraysEqual = (a, b) => export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value)); -export function getScrollTextData(actor, resource, key) { +export function getScrollTextData(resources, resource, key) { + const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key]; const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS; - - const resources = actor.system.resources; const increased = resources[key].value < resource.value; const value = -1 * (resources[key].value - resource.value); - const { label, isReversed } = resources[key]; const text = `${game.i18n.localize(label)} ${value.signedString()}`; - const stroke = increased ? (isReversed ? 0xffffff : 0x000000) : isReversed ? 0x000000 : 0xffffff; - const fill = increased ? (isReversed ? 0x0032b1 : 0xffe760) : isReversed ? 0xffe760 : 0x0032b1; - const direction = increased ? (isReversed ? BOTTOM : TOP) : isReversed ? TOP : BOTTOM; + + const stroke = increased ? (reversed ? 0xffffff : 0x000000) : reversed ? 0x000000 : 0xffffff; + const fill = increased ? (reversed ? 0x0032b1 : 0xffe760) : reversed ? 0xffe760 : 0x0032b1; + const direction = increased ? (reversed ? BOTTOM : TOP) : reversed ? TOP : BOTTOM; return { text, stroke, fill, direction }; } diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index 8440e3fe..1cd627af 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -50,7 +50,12 @@ const registerMenuSettings = () => { config: false, type: DhHomebrew, onChange: value => { - value.handleChange(); + if (value.maxFear) { + if (ui.resources) ui.resources.render({ force: true }); + } + + // Some homebrew settings may change sheets in various ways, so trigger a re-render + resetActors(); } }); @@ -161,3 +166,25 @@ const registerNonConfigSettings = () => { type: CompendiumBrowserSettings }); }; + +/** + * Triggers a reset and non-forced re-render on all given actors (if given) + * or all world actors and actors in all scenes to show immediate results for a changed setting. + */ +function resetActors(actors) { + actors ??= [ + game.actors.contents, + game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) + ].flat(); + actors = new Set(actors); + for (const actor of actors) { + for (const app of Object.values(actor.apps)) { + for (const element of app.element?.querySelectorAll('prose-mirror.active')) { + element.open = false; // This triggers a save + } + } + + actor.reset(); + actor.render(); + } +} diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 31fd4256..5e8ef002 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -133,19 +133,8 @@ padding: 0; margin-bottom: 15px; - .resource-section { - display: flex; - align-items: center; - gap: 4px; + .hope-section { margin-right: 20px; - - .resource-manager { - transition: all 0.1s ease; - - &.inverted { - transform: rotate(180deg); - } - } } .downtime-section { diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 31ea8955..567f94db 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -27,7 +27,6 @@ @import './settings/settings.less'; @import './settings/homebrew-settings/domains.less'; @import './settings/homebrew-settings/types.less'; -@import './settings/homebrew-settings/resources.less'; @import './settings/appearance-settings/diceSoNice.less'; @import './sidebar/tabs.less'; diff --git a/styles/less/ui/settings/homebrew-settings/resources.less b/styles/less/ui/settings/homebrew-settings/resources.less deleted file mode 100644 index 5333e54d..00000000 --- a/styles/less/ui/settings/homebrew-settings/resources.less +++ /dev/null @@ -1,87 +0,0 @@ -.daggerheart.dh-style.setting.homebrew-settings .resources.tab { - .resource-types-container { - display: flex; - flex-direction: column; - gap: 16px; - overflow: auto; - max-height: 570px; - - fieldset legend { - display: flex; - align-items: center; - gap: 4px; - } - - .resource-type-container { - width: 100%; - - .resources-container { - display: flex; - flex-direction: column; - gap: 4px; - - .resource-container { - .resource-icons-container { - display: flex; - justify-content: space-between; - gap: 8px; - width: 100%; - - .resource-icon-container { - display: flex; - flex-direction: column; - gap: 4px; - flex: 1; - - .resource-icon-title-container { - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - - &::before, - &::after { - color: @dark-blue; - content: ''; - flex: 1; - height: 2px; - } - - &::before { - background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, @golden 100%); - } - - &::after { - background: linear-gradient(90deg, @golden 0%, rgba(0, 0, 0, 0) 100%); - } - - .resource-icon-title { - font-size: var(--font-size-16); - white-space: nowrap; - display: flex; - align-items: center; - gap: 4px; - color: light-dark(@dark-blue, @golden); - - i { - font-size: 14px; - } - } - } - } - } - } - } - } - } - - .two-columns { - width: 100%; - } - - .form-group.vertical { - > * { - flex: 0 0 100%; - } - } -} diff --git a/styles/less/ux/index.less b/styles/less/ux/index.less index c6c40f78..0bd1b71e 100644 --- a/styles/less/ux/index.less +++ b/styles/less/ux/index.less @@ -4,5 +4,3 @@ @import './tooltip/domain-cards.less'; @import './autocomplete/autocomplete.less'; - -@import './tooltip/resource-management.less'; diff --git a/styles/less/ux/tooltip/resource-management.less b/styles/less/ux/tooltip/resource-management.less deleted file mode 100644 index ff1f4dd2..00000000 --- a/styles/less/ux/tooltip/resource-management.less +++ /dev/null @@ -1,56 +0,0 @@ -.bordered-tooltip.locked-tooltip .daggerheart.resource-management-container, -#tooltip .daggerheart.resource-management-container { - display: flex; - flex-direction: column; - gap: 16px; - - .resource-section { - position: relative; - display: flex; - gap: 10px; - background-color: light-dark(transparent, @dark-blue); - color: light-dark(@dark-blue, @golden); - padding: 5px 10px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - align-items: center; - width: fit-content; - height: 30px; - - h4 { - font-family: var(--dh-font-body, 'Montserrat'), sans-serif; - font-size: var(--font-size-14); - font-weight: bold; - text-transform: uppercase; - color: light-dark(@dark-blue, @golden); - margin: 0; - } - - .resource-value { - display: flex; - cursor: pointer; - - .hidden { - display: none; - } - - img { - width: 14px; - height: 14px; - - &.empty { - opacity: 0.4; - } - - &.filter { - filter: @golden-filter; - } - - &.non-transparent { - border-radius: 50%; - border: 1px solid @golden; - } - } - } - } -} diff --git a/templates/settings/homebrew-settings/resources.hbs b/templates/settings/homebrew-settings/resources.hbs deleted file mode 100644 index 7f3dee3e..00000000 --- a/templates/settings/homebrew-settings/resources.hbs +++ /dev/null @@ -1,78 +0,0 @@ -
-
- {{#each settingFields.resources as |type key|}} -
- - {{localize "DAGGERHEART.SETTINGS.Homebrew.resources.typeTitle" type=(localize (concat "TYPES.Actor." key))}} - - - -
-
- {{#each type.resources as |resource key|}} -
- {{resource.label}} - - {{formField @root.schemaFields.resources.element.fields.resources.element.fields.label value=resource.label name=(concat "resources." @../key ".resources." key ".label") classes="vertical" localize=true }} - -
- {{formField @root.schemaFields.resources.element.fields.resources.element.fields.initial value=resource.initial name=(concat "resources." @../key ".resources." key ".initial") classes="vertical" localize=true }} - {{formField @root.schemaFields.resources.element.fields.resources.element.fields.max value=resource.max name=(concat "resources." @../key ".resources." key ".max") classes="vertical" localize=true }} -
- -
-
- {{#with @root.schemaFields.resources.element.fields.resources.element.fields.images.fields.full.fields}} -
-
- {{localize "DAGGERHEART.SETTINGS.Homebrew.resources.filledIcon"}} - -
-
-
- {{#if ../images.full.isIcon}} - {{formGroup this.value value=../images.full.value name=(concat "resources." @../key ".resources." key ".images.full.value") localize=true }} - {{else}} -
- -
- {{/if}} - {{formGroup this.isIcon value=../images.full.isIcon name="" classes="path-field" localize=true }} - {{formGroup this.noColorFilter value=../images.full.noColorFilter name=(concat "resources." @../key ".resources." key ".images.full.noColorFilter") localize=true }} -
- {{/with}} -
-
- {{#with @root.schemaFields.resources.element.fields.resources.element.fields.images.fields.empty.fields}} -
-
- {{localize "DAGGERHEART.SETTINGS.Homebrew.resources.emptyIcon"}} - -
-
-
- {{#if ../images.empty.isIcon}} - {{formGroup this.value value=../images.empty.value name=(concat "resources." @../key ".resources." key ".images.empty.value") localize=true }} - {{else}} -
- -
- {{/if}} - {{formGroup this.isIcon value=resource.images.empty.isIcon name="" classes="path-field" localize=true }} - {{formGroup this.noColorFilter value=resource.images.empty.noColorFilter name=(concat "resources." @../key ".resources." key ".images.empty.noColorFilter") localize=true }} -
- {{/with}} -
-
-
- {{/each}} -
-
-
- {{/each}} -
-
\ No newline at end of file diff --git a/templates/sheets-settings/adversary-settings/details.hbs b/templates/sheets-settings/adversary-settings/details.hbs index dc2fd386..065ebe74 100644 --- a/templates/sheets-settings/adversary-settings/details.hbs +++ b/templates/sheets-settings/adversary-settings/details.hbs @@ -20,11 +20,15 @@
- {{localize "DAGGERHEART.GENERAL.Resource.plural"}} - {{#each resources as |resource|}} - {{formGroup resource.field value=resource.value name=resource.name}} - {{/each}} -
+ {{localize "DAGGERHEART.GENERAL.HitPoints.plural"}} + {{formGroup systemFields.resources.fields.hitPoints.fields.value value=document._source.system.resources.hitPoints.value label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.resources.hitPoints.value.label")}} + {{formGroup systemFields.resources.fields.hitPoints.fields.max value=document._source.system.resources.hitPoints.max label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.resources.hitPoints.max.label")}} + +
+ {{localize "DAGGERHEART.GENERAL.stress"}} + {{formGroup systemFields.resources.fields.stress.fields.value value=document._source.system.resources.stress.value label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.resources.stress.value.label")}} + {{formGroup systemFields.resources.fields.stress.fields.max value=document._source.system.resources.stress.max label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.resources.stress.max.label")}} +
@@ -32,4 +36,4 @@ {{formGroup systemFields.damageThresholds.fields.major value=document._source.system.damageThresholds.major label=(localize "DAGGERHEART.GENERAL.DamageThresholds.majorThreshold")}} {{formGroup systemFields.damageThresholds.fields.severe value=document._source.system.damageThresholds.severe label=(localize "DAGGERHEART.GENERAL.DamageThresholds.severeThreshold")}}
- + \ No newline at end of file diff --git a/templates/sheets-settings/character-settings/details.hbs b/templates/sheets-settings/character-settings/details.hbs index 4bda501e..3f9247e0 100644 --- a/templates/sheets-settings/character-settings/details.hbs +++ b/templates/sheets-settings/character-settings/details.hbs @@ -22,12 +22,15 @@ {{localize 'DAGGERHEART.GENERAL.basics'}}
- {{#each resources as |resource|}} - - {{formGroup resource.field value=resource.value name=resource.name}} - - {{/each}} + {{formGroup systemFields.resources.fields.hitPoints.fields.value value=document._source.system.resources.hitPoints.value localize=true}} + + {{formGroup systemFields.resources.fields.hitPoints.fields.max value=document._source.system.resources.hitPoints.max localize=true}} + + {{formGroup systemFields.resources.fields.stress.fields.value value=document._source.system.resources.stress.value localize=true}} + {{formGroup systemFields.resources.fields.stress.fields.max value=document._source.system.resources.stress.max localize=true}} + + {{formGroup systemFields.resources.fields.hope.fields.value value=document._source.system.resources.hope.value localize=true}} {{formGroup systemFields.scars value=document._source.system.scars localize=true}} {{formGroup systemFields.proficiency value=document._source.system.proficiency localize=true}} @@ -36,4 +39,4 @@
- + \ No newline at end of file diff --git a/templates/sheets-settings/companion-settings/details.hbs b/templates/sheets-settings/companion-settings/details.hbs index 6a602d38..88878d67 100644 --- a/templates/sheets-settings/companion-settings/details.hbs +++ b/templates/sheets-settings/companion-settings/details.hbs @@ -7,9 +7,8 @@ {{localize 'DAGGERHEART.GENERAL.basics'}}
{{formGroup systemFields.evasion value=document._source.system.evasion localize=true}} - {{#each resources as |resource|}} - {{formGroup resource.field value=resource.value name=resource.name}} - {{/each}} + {{formGroup systemFields.resources.fields.stress.fields.value value=document._source.system.resources.stress.value label='DAGGERHEART.ACTORS.Companion.FIELDS.resources.stress.currentStress.label' localize=true}} + {{formGroup systemFields.resources.fields.stress.fields.max value=document._source.system.resources.stress.max label='DAGGERHEART.ACTORS.Companion.FIELDS.resources.stress.maxStress.label' localize=true}}
@@ -20,4 +19,4 @@
- + \ No newline at end of file diff --git a/templates/sheets/actors/character/header.hbs b/templates/sheets/actors/character/header.hbs index 06f464fa..d2c01f3c 100644 --- a/templates/sheets/actors/character/header.hbs +++ b/templates/sheets/actors/character/header.hbs @@ -65,25 +65,22 @@
-
-
-

{{localize "DAGGERHEART.GENERAL.hope"}}

- {{#times document.system.resources.hope.max}} - - {{#if (gte ../document.system.resources.hope.value (add this 1))}} - - {{else}} - - {{/if}} - - {{/times}} - {{#times document.system.scars}} - - - - {{/times}} - {{#if hasExtraResources}}{{/if}} -
+
+

{{localize "DAGGERHEART.GENERAL.hope"}}

+ {{#times document.system.resources.hope.max}} + + {{#if (gte ../document.system.resources.hope.value (add this 1))}} + + {{else}} + + {{/if}} + + {{/times}} + {{#times document.system.scars}} + + + + {{/times}}
{{#if document.system.class.value}}
diff --git a/templates/ui/tooltip/resourceManagement.hbs b/templates/ui/tooltip/resourceManagement.hbs deleted file mode 100644 index b9817e6e..00000000 --- a/templates/ui/tooltip/resourceManagement.hbs +++ /dev/null @@ -1,21 +0,0 @@ -
- {{#each resources as |resource|}} -
-

{{resource.label}}

- {{#times resource.max}} - - {{#if resource.fullIcon.isIcon}} - - {{else}} - - {{/if}} - {{#if resource.emptyIcon.isIcon}} - - {{else}} - - {{/if}} - - {{/times}} -
- {{/each}} -
\ No newline at end of file