From 61f04df765102dfb9b25d7d11042dfdbc160ae51 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 8 Jul 2025 20:04:54 +0200 Subject: [PATCH 01/58] 289 - Confirm Delete Dialogs (#298) * Added confirm dialogs to delete * Localization fix --- lang/en.json | 4 +++ .../sheets-configs/adversary-settings.mjs | 12 +++++++++ .../sheets-configs/environment-settings.mjs | 22 ++++++++++++--- .../applications/sheets/actors/character.mjs | 22 ++++++++++++--- .../applications/sheets/api/actor-setting.mjs | 5 +++- .../sheets/api/application-mixin.mjs | 19 +++++++++++-- module/applications/sheets/api/base-item.mjs | 27 +++++++++++++++++++ 7 files changed, 101 insertions(+), 10 deletions(-) diff --git a/lang/en.json b/lang/en.json index 857a9387..75c8cfa7 100755 --- a/lang/en.json +++ b/lang/en.json @@ -213,6 +213,10 @@ "encounter": "Encounter" } }, + "DeleteConfirmation": { + "title": "Delete {type} - {name}", + "text": "Are you sure you want to delete {name}?" + }, "DamageReduction": { "armorMarks": "Armor Marks", "armorWithStress": "Spend 1 stress to use an extra mark", diff --git a/module/applications/sheets-configs/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs index d95e6129..57deea25 100644 --- a/module/applications/sheets-configs/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -70,6 +70,18 @@ export default class DHAdversarySettings extends DHBaseActorSettings { * @type {ApplicationClickAction} */ static async #removeExperience(_, target) { + const experience = this.actor.system.experiences[target.dataset.experience]; + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize(`DAGGERHEART.GENERAL.Experience.single`), + name: experience.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: experience.name }) + }); + if (!confirmed) return; + await this.actor.update({ [`system.experiences.-=${target.dataset.experience}`]: null }); } diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index d0ca897a..7422f5fc 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -82,10 +82,24 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { static async #deleteAdversary(event, target) { const adversaryKey = target.dataset.adversary; const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries`; - console.log(target.dataset.potentialAdversar); - const newAdversaries = foundry.utils - .getProperty(this.actor, path) - .filter(x => x && (x?.uuid ?? x) !== adversaryKey); + const property = foundry.utils.getProperty(this.actor, path); + const adversary = property.find(x => (x?.uuid ?? x) === adversaryKey); + + if (adversary) { + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize('TYPES.Actor.adversary'), + name: adversary.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: adversary.name }) + }); + + if (!confirmed) return; + } + + const newAdversaries = property.filter(x => x && (x?.uuid ?? x) !== adversaryKey); await this.actor.update({ [path]: newAdversaries }); } diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 02e693d7..a77fe71f 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -249,7 +249,23 @@ export default class CharacterSheet extends DHBaseActorSheet { { name: 'DAGGERHEART.Sheets.PC.ContextMenu.Delete', icon: '', - callback: el => getItem(el).delete() + callback: async el => { + const item = getItem(el); + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize(`TYPES.${item.documentName}.${item.type}`), + name: item.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { + name: item.name + }) + }); + if (!confirmed) return; + + item.delete(); + } } ]; } @@ -372,7 +388,7 @@ export default class CharacterSheet extends DHBaseActorSheet { li.hidden = !(menu.has(item.id) && matchesSearch); } } - + /* -------------------------------------------- */ /* Filter Menus */ /* -------------------------------------------- */ @@ -495,7 +511,7 @@ export default class CharacterSheet extends DHBaseActorSheet { const config = { event: event, title: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${this.actor.name}`, - headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilitychecktitle', { + headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }), roll: { diff --git a/module/applications/sheets/api/actor-setting.mjs b/module/applications/sheets/api/actor-setting.mjs index 50e2b0a9..79aa1c37 100644 --- a/module/applications/sheets/api/actor-setting.mjs +++ b/module/applications/sheets/api/actor-setting.mjs @@ -42,9 +42,12 @@ export default class DHBaseActorSettings extends DHApplicationMixin(DocumentShee /**@inheritdoc */ async _prepareContext(options) { const context = await super._prepareContext(options); - context.systemFields.attack.fields = this.actor.system.attack.schema.fields; context.isNPC = this.actor.isNPC; + if (context.systemFields.attack) { + context.systemFields.attack.fields = this.actor.system.attack.schema.fields; + } + return context; } } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index d0ef63d6..0e5f211d 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -218,7 +218,6 @@ export default function DHApplicationMixin(Base) { */ static async #createDoc(event, button) { const { documentClass, type } = button.dataset; - console.log(documentClass, type); const parent = this.document; const cls = getDocumentClass(documentClass); @@ -250,7 +249,23 @@ export default function DHApplicationMixin(Base) { */ static async #deleteDoc(_event, button) { const { type, docId } = button.dataset; - await this.document.getEmbeddedDocument(type, docId, { strict: true }).delete(); + const document = this.document.getEmbeddedDocument(type, docId, { strict: true }); + const typeName = game.i18n.localize( + document.type === 'base' ? `DOCUMENT.${type}` : `TYPES.${type}.${document.type}` + ); + + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: typeName, + name: document.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: document.name }) + }); + if (!confirmed) return; + + await document.delete(); } } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index f9d52025..d624acc6 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -139,6 +139,19 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { static async #removeAction(event, button) { event.stopPropagation(); const actionIndex = button.closest('[data-index]').dataset.index; + const action = this.document.system.actions[actionIndex]; + + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize(`DAGGERHEART.GENERAL.Action.single`), + name: action.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: action.name }) + }); + if (!confirmed) return; + await this.document.update({ 'system.actions': this.document.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) }); @@ -180,6 +193,20 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { static async #removeFeature(event, button) { event.stopPropagation(); const target = button.closest('.feature-item'); + const feature = this.document.system.features.find(x => x && x.id === target.id); + + if (feature) { + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize(`TYPES.Item.feature`), + name: feature.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: feature.name }) + }); + if (!confirmed) return; + } await this.document.update({ 'system.features': this.document.system.features From 861dfd977dbae69ccd840196ea4e8902e2ce1f02 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 8 Jul 2025 21:01:28 +0200 Subject: [PATCH 02/58] Beastform Improvements (#294) * BeastformEffect is editable. Added SubjectTexture field. * Using handlebars disabled helper --- lang/en.json | 1 + .../applications/sheets/actors/character.mjs | 12 +++- .../applications/sheets/items/beastform.mjs | 13 +++- module/data/activeEffect/beastformEffect.mjs | 10 +++ module/data/item/beastform.mjs | 65 ++++++++++++------- templates/sheets/global/tabs/tab-effects.hbs | 2 +- templates/sheets/items/beastform/settings.hbs | 10 +-- 7 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lang/en.json b/lang/en.json index 75c8cfa7..797781d8 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1129,6 +1129,7 @@ "examples": { "label": "Examples" }, "advantageOn": { "label": "Gain Advantage On" }, "tokenImg": { "label": "Token Image" }, + "tokenRingImg": { "label": "Subject Texture" }, "tokenSize": { "placeholder": "Using character dimensions", "height": { "label": "Height" }, diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index a77fe71f..c24bcfec 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -188,7 +188,17 @@ export default class CharacterSheet extends DHBaseActorSheet { * @param {HTMLElement} el * @returns {foundry.documents.Item?} */ - const getItem = el => this.actor.items.get(el.closest('[data-item-id]')?.dataset.itemId); + const getItem = element => { + const listElement = (element.target ?? element).closest('[data-item-id]'); + const itemId = listElement.dataset.itemId; + + switch (listElement.dataset.type) { + case 'effect': + return this.document.effects.get(itemId); + default: + return this.document.items.get(itemId); + } + }; return [ { diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index e3b72d01..194f3ab1 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -30,8 +30,17 @@ export default class BeastformSheet extends DHBaseItemSheet { }; /**@inheritdoc */ - async _preparePartContext(partId, context) { - await super._preparePartContext(partId, context); + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + + context.document = context.document.toObject(); + context.document.effects = this.document.effects.map(effect => { + const data = effect.toObject(); + data.id = effect.id; + if (effect.type === 'beastform') data.mandatory = true; + + return data; + }); return context; } diff --git a/module/data/activeEffect/beastformEffect.mjs b/module/data/activeEffect/beastformEffect.mjs index 3aa25bef..6445f65d 100644 --- a/module/data/activeEffect/beastformEffect.mjs +++ b/module/data/activeEffect/beastformEffect.mjs @@ -10,6 +10,11 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel { base64: false, nullable: true }), + tokenRingImg: new fields.FilePathField({ + initial: 'icons/svg/mystery-man.svg', + categories: ['IMAGE'], + base64: false + }), tokenSize: new fields.SchemaField({ height: new fields.NumberField({ integer: true, nullable: true }), width: new fields.NumberField({ integer: true, nullable: true }) @@ -28,6 +33,11 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel { width: this.characterTokenData.tokenSize.width, texture: { src: this.characterTokenData.tokenImg + }, + ring: { + subject: { + texture: this.characterTokenData.tokenRingImg + } } }; diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index 2eb871ec..b7ea5cb9 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -3,7 +3,7 @@ import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayFie import BaseDataItem from './base.mjs'; export default class DHBeastform extends BaseDataItem { - static LOCALIZATION_PREFIXES = ['DAGGERHEART.Sheets.Beastform']; + static LOCALIZATION_PREFIXES = ['DAGGERHEART.ITEMS.Beastform']; /** @inheritDoc */ static get metadata() { @@ -29,12 +29,17 @@ export default class DHBeastform extends BaseDataItem { categories: ['IMAGE'], base64: false }), + tokenRingImg: new fields.FilePathField({ + initial: 'icons/svg/mystery-man.svg', + categories: ['IMAGE'], + base64: false + }), tokenSize: new fields.SchemaField({ height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }), width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }) }), examples: new fields.StringField(), - advantageOn: new fields.ArrayField(new fields.StringField()), + advantageOn: new fields.StringField(), features: new ForeignDocumentUUIDArrayField({ type: 'Item' }) }; } @@ -56,40 +61,54 @@ export default class DHBeastform extends BaseDataItem { 'Item', this.features.map(x => x.toObject()) ); - const effects = await this.parent.parent.createEmbeddedDocuments( + + const extraEffects = await this.parent.parent.createEmbeddedDocuments( 'ActiveEffect', - this.parent.effects.map(x => x.toObject()) + this.parent.effects.filter(x => x.type !== 'beastform').map(x => x.toObject()) ); - await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [ - { - type: 'beastform', - name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'), - img: 'icons/creatures/abilities/paw-print-pair-purple.webp', - system: { - isBeastform: true, - characterTokenData: { - tokenImg: this.parent.parent.prototypeToken.texture.src, - tokenSize: { - height: this.parent.parent.prototypeToken.height, - width: this.parent.parent.prototypeToken.width - } - }, - advantageOn: this.advantageOn, - featureIds: features.map(x => x.id), - effectIds: effects.map(x => x.id) - } + const beastformEffect = this.parent.effects.find(x => x.type === 'beastform'); + await beastformEffect.updateSource({ + system: { + characterTokenData: { + tokenImg: this.parent.parent.prototypeToken.texture.src, + tokenRingImg: this.parent.parent.prototypeToken.ring.subject.texture, + tokenSize: { + height: this.parent.parent.prototypeToken.height, + width: this.parent.parent.prototypeToken.width + } + }, + advantageOn: this.advantageOn, + featureIds: features.map(x => x.id), + effectIds: extraEffects.map(x => x.id) } - ]); + }); + + await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [beastformEffect.toObject()]); await updateActorTokens(this.parent.parent, { height: this.tokenSize.height, width: this.tokenSize.width, texture: { src: this.tokenImg + }, + ring: { + subject: { + texture: this.tokenRingImg + } } }); return false; } + + _onCreate() { + this.parent.createEmbeddedDocuments('ActiveEffect', [ + { + type: 'beastform', + name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'), + img: 'icons/creatures/abilities/paw-print-pair-purple.webp' + } + ]); + } } diff --git a/templates/sheets/global/tabs/tab-effects.hbs b/templates/sheets/global/tabs/tab-effects.hbs index 744ef8e1..a75f1b0b 100644 --- a/templates/sheets/global/tabs/tab-effects.hbs +++ b/templates/sheets/global/tabs/tab-effects.hbs @@ -17,7 +17,7 @@ {{effect.name}}
- +
{{/each}} diff --git a/templates/sheets/items/beastform/settings.hbs b/templates/sheets/items/beastform/settings.hbs index 78af825f..dec7d134 100644 --- a/templates/sheets/items/beastform/settings.hbs +++ b/templates/sheets/items/beastform/settings.hbs @@ -8,11 +8,7 @@ {{formGroup systemFields.examples value=source.system.examples localize=true}} -
- {{localize "DAGGERHEART.ITEMS.Beastform.FIELDS.advantageOn.label"}} - - {{!-- {{formGroup systemFields.examples value=source.system.examples localize=true}} --}} -
+ {{formGroup systemFields.advantageOn value=source.system.advantageOn localize=true}}
{{localize "DAGGERHEART.ITEMS.Beastform.tokenTitle"}} @@ -21,6 +17,10 @@ {{formGroup systemFields.tokenImg value=source.system.tokenImg localize=true}} +
+ {{formGroup systemFields.tokenRingImg value=source.system.tokenRingImg localize=true}} +
+ {{formGroup systemFields.tokenSize.fields.height value=source.system.tokenSize.height localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder") }} {{formGroup systemFields.tokenSize.fields.width value=source.system.tokenSize.width localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")}}
From 059b814fdf853ce5a6ef09f2274e76fa0560bf4e Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Tue, 8 Jul 2025 21:06:46 +0200 Subject: [PATCH 03/58] Feature/armor stack uses on damage (#300) * ArmorStack use as User query * Remove unnecessart args * Fixes --- daggerheart.mjs | 2 + .../dialogs/damageReductionDialog.mjs | 14 ++- module/applications/ui/chatLog.mjs | 4 +- module/documents/actor.mjs | 99 ++++++++++++------- module/systemRegistration/socket.mjs | 37 ++++--- templates/ui/chat/adversary-roll.hbs | 2 +- templates/ui/chat/duality-roll.hbs | 2 +- 7 files changed, 103 insertions(+), 57 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index a6676f19..153c2f84 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -18,6 +18,7 @@ import { } from './module/systemRegistration/_module.mjs'; import { placeables } from './module/canvas/_module.mjs'; import { registerRollDiceHooks } from './module/dice/dhRoll.mjs'; +import { registerDHActorHooks } from './module/documents/actor.mjs'; Hooks.once('init', () => { CONFIG.DH = SYSTEM; @@ -154,6 +155,7 @@ Hooks.on('ready', () => { socketRegistration.registerSocketHooks(); registerCountdownApplicationHooks(); registerRollDiceHooks(); + registerDHActorHooks(); }); Hooks.once('dicesoniceready', () => {}); diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 8a67ef98..3d33f2a3 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -1,6 +1,6 @@ import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs'; -const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; +const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) { constructor(resolve, reject, actor, damage) { @@ -122,7 +122,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap getDamageInfo = () => { const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected); const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected); - const stressReductions = Object.values(this.availableStressReductions).filter(red => red.selected); + const stressReductions = Object.values(this.availableStressReductions ?? {}).filter(red => red.selected); const currentMarks = this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length; @@ -210,9 +210,17 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap async close(fromSave) { if (!fromSave) { - this.reject(); + this.resolve(); } await super.close({}); } + + static async armorStackQuery({actorId, damage}) { + return new Promise(async (resolve, reject) => { + const actor = await fromUuid(actorId); + if(!actor || !actor?.isOwner) reject(); + new DamageReductionDialog(resolve, reject, actor, damage).render({ force: true }); + }) + } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index d17c26dc..0e2242d7 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -215,7 +215,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); - await target.actor.takeDamage(damage, message.system.roll.type); + target.actor.takeDamage(damage, message.system.roll.type); } }; @@ -227,7 +227,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); for (var target of targets) { - await target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]); + target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]); } }; diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index b48d8c26..1fab0f71 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -1,10 +1,19 @@ import DamageSelectionDialog from '../applications/dialogs/damageSelectionDialog.mjs'; -import { GMUpdateEvent, socketEvent } from '../systemRegistration/socket.mjs'; +import { emitAsGM, emitAsOwner, GMUpdateEvent, socketEvent } from '../systemRegistration/socket.mjs'; import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs'; import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; -export default class DhpActor extends foundry.documents.Actor { +export default class DhpActor extends Actor { + + /** + * Return the first Actor active owner. + */ + get owner() { + const user = this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, "OWNER") && u.active);; + if(!user) return game.user.isGM ? game.user : null; + return user; + } /** * Whether this actor is an NPC. @@ -440,49 +449,40 @@ export default class DhpActor extends foundry.documents.Actor { } async takeDamage(damage, type) { + if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damage, type) === false) return null; + if (this.type === 'companion') { await this.modifyResource([{ value: 1, type: 'stress' }]); return; } - const hpDamage = - damage >= this.system.damageThresholds.severe - ? 3 - : damage >= this.system.damageThresholds.major - ? 2 - : damage >= this.system.damageThresholds.minor - ? 1 - : 0; + const hpDamage = this.convertDamageToThreshold(damage); + + if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null; + + if(!hpDamage) return; + + const updates = [{ value: hpDamage, type: 'hitPoints' }]; if ( this.type === 'character' && this.system.armor && this.system.armor.system.marks.value < this.system.armorScore ) { - new Promise((resolve, reject) => { - new DamageReductionDialog(resolve, reject, this, hpDamage).render(true); - }) - .then(async ({ modifiedDamage, armorSpent, stressSpent }) => { - const resources = [ - { value: modifiedDamage, type: 'hitPoints' }, - ...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : []), - ...(stressSpent ? [{ value: stressSpent, type: 'stress' }] : []) - ]; - await this.modifyResource(resources); - }) - .catch(() => { - const cls = getDocumentClass('ChatMessage'); - const msg = new cls({ - user: game.user.id, - content: game.i18n.format('DAGGERHEART.UI.Notifications.damageIgnore', { - character: this.name - }) - }); - cls.create(msg.toObject()); - }); - } else { - await this.modifyResource([{ value: hpDamage, type: 'hitPoints' }]); + const armorStackResult = await this.owner.query('armorStack', {actorId: this.uuid, damage: hpDamage}); + if(armorStackResult) { + const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; + updates.find(u => u.type === 'hitPoints').value = modifiedDamage; + updates.push( + ...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : []), + ...(stressSpent ? [{ value: stressSpent, type: 'stress' }] : []) + ); + } } + + await this.modifyResource(updates); + + if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null; } async takeHealing(resources) { @@ -492,6 +492,8 @@ export default class DhpActor extends foundry.documents.Actor { async modifyResource(resources) { if (!resources.length) return; + + if(resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources); let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } }; resources.forEach(r => { switch (r.type) { @@ -519,7 +521,8 @@ export default class DhpActor extends foundry.documents.Actor { }); Object.values(updates).forEach(async u => { if (Object.keys(u.resources).length > 0) { - if (game.user.isGM) { + await emitAsGM(GMUpdateEvent.UpdateDocument, u.target.update.bind(u.target), u.resources, u.target.uuid); + /* if (game.user.isGM) { await u.target.update(u.resources); } else { await game.socket.emit(`system.${CONFIG.DH.id}`, { @@ -530,8 +533,34 @@ export default class DhpActor extends foundry.documents.Actor { update: u.resources } }); - } + } */ } }); } + + convertDamageToThreshold(damage) { + return damage >= this.system.damageThresholds.severe + ? 3 + : damage >= this.system.damageThresholds.major + ? 2 + : damage >= this.system.damageThresholds.minor + ? 1 + : 0; + } + + convertStressDamageToHP(resources) { + const stressDamage = resources.find(r => r.type === 'stress'), + newValue = this.system.resources.stress.value + stressDamage.value; + if(newValue <= this.system.resources.stress.maxTotal) return; + const hpDamage = resources.find(r => r.type === 'hitPoints'); + if(hpDamage) hpDamage.value++; + else resources.push({ + type: 'hitPoints', + value: 1 + }) + } } + +export const registerDHActorHooks = () => { + CONFIG.queries.armorStack = DamageReductionDialog.armorStackQuery; +} \ No newline at end of file diff --git a/module/systemRegistration/socket.mjs b/module/systemRegistration/socket.mjs index d7f79df9..b336a012 100644 --- a/module/systemRegistration/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -63,21 +63,28 @@ export const registerSocketHooks = () => { }); }; -export const emitAsGM = async (eventName, callback, args) => { +export const emitAsGM = async (eventName, callback, update, uuid = null) => { if(!game.user.isGM) { - return new Promise(async (resolve, reject) => { - try { - const response = await game.socket.emit(`system.${CONFIG.DH.id}`, { - action: socketEvent.GMUpdate, - data: { - action: eventName, - update: args - } - }); - resolve(response); - } catch (error) { - reject(error); + return await game.socket.emit(`system.${CONFIG.DH.id}`, { + action: socketEvent.GMUpdate, + data: { + action: eventName, + uuid, + update } - }) - } else return callback(args); + }); + } else return callback(update); } + +export const emitAsOwner = (eventName, userId, args) => { + if(userId === game.user.id) return; + if(!eventName || !userId) return false; + game.socket.emit(`system.${CONFIG.DH.id}`, { + action: eventName, + data: { + userId, + ...args + } + }); + return false; +} \ No newline at end of file diff --git a/templates/ui/chat/adversary-roll.hbs b/templates/ui/chat/adversary-roll.hbs index 1f97fefe..a8918062 100644 --- a/templates/ui/chat/adversary-roll.hbs +++ b/templates/ui/chat/adversary-roll.hbs @@ -49,7 +49,7 @@
{{#if damage.roll}}
- +
{{else}}
diff --git a/templates/ui/chat/duality-roll.hbs b/templates/ui/chat/duality-roll.hbs index 4242c515..66d32e95 100644 --- a/templates/ui/chat/duality-roll.hbs +++ b/templates/ui/chat/duality-roll.hbs @@ -134,7 +134,7 @@
{{#if hasDamage}} {{#if damage.roll}} - + {{else}} {{/if}} From 4150de757b3e3e4d813f74c7cfa0d9ec8f26ee57 Mon Sep 17 00:00:00 2001 From: Murilo Brito <91566541+moliloo@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:39:00 -0300 Subject: [PATCH 04/58] refactor styles folder (#302) --- styles/application.less | 561 -- styles/class.less | 5 - styles/daggerheart.css | 7389 ++++++----------- styles/daggerheart.less | 202 +- styles/dialog.less | 12 - styles/item.less | 59 - styles/less/actors/adversary.less | 5 - styles/less/actors/character.less | 11 - styles/less/actors/environment.less | 27 - .../beastform/beastform-container.less} | 105 +- styles/less/dialog/beastform/sheet.less | 21 + .../creation-action-footer.less | 13 + .../selections-container.less} | 742 +- .../less/dialog/character-creation/sheet.less | 27 + .../character-creation/tab-navigation.less | 62 + .../damage-reduction-container.less} | 6 +- .../less/dialog/damage-reduction/sheets.less | 7 + .../dialog/downtime/downtime-container.less | 81 + styles/less/dialog/index.less | 19 + .../dialog/level-up/navigation-container.less | 30 + .../dialog/level-up/selections-container.less | 108 + styles/less/dialog/level-up/sheet.less | 37 + .../dialog/level-up/summary-container.less | 37 + .../less/dialog/level-up/tiers-container.less | 65 + styles/less/global/index.less | 14 + styles/less/items/class.css | 132 - .../adversary-settings/experiences.less | 0 .../adversary-settings/features.less | 0 .../adversary-settings/sheet.less | 0 .../environment-settings/adversaries.less | 0 .../environment-settings/features.less | 0 .../header.less | 0 styles/less/sheets-settings/index.less | 7 + .../actors/adversary/actions.less | 4 +- .../{ => sheets}/actors/adversary/header.less | 4 +- .../{ => sheets}/actors/adversary/sheet.less | 4 +- .../actors/adversary/sidebar.less | 24 +- .../actors/character/biography.less | 4 +- .../actors/character/features.less | 4 +- .../{ => sheets}/actors/character/header.less | 5 +- .../actors/character/inventory.less | 4 +- .../actors/character/loadout.less | 4 +- .../{ => sheets}/actors/character/sheet.less | 4 +- .../actors/character/sidebar.less | 5 +- .../actors/companion/details.less | 4 +- .../{ => sheets}/actors/companion/header.less | 4 +- .../{ => sheets}/actors/companion/sheet.less | 14 +- .../actors/environment/header.less | 4 +- .../actors/environment/sheet.less | 5 +- styles/less/sheets/index.less | 23 + styles/less/{ => sheets}/items/class.less | 4 +- .../items/domain-card.less} | 4 +- styles/less/{ => sheets}/items/feature.less | 4 +- styles/{ => less/ui/chat}/chat.less | 226 +- styles/less/ui/chat/sheet.less | 33 + styles/less/ui/chat/theme-colorful.less | 193 + .../ui/combat-sidebar/combat-sidebar.less | 6 + .../ui/combat-sidebar/combatant-controls.less | 5 + .../ui/combat-sidebar/encounter-controls.less | 48 + .../ui/combat-sidebar/spotlight-control.less | 19 + .../less/ui/combat-sidebar/token-actions.less | 48 + styles/less/ui/countdown/countdown.less | 61 + .../ui/countdown/sheet.less} | 229 +- styles/less/ui/index.less | 18 + .../ownership-selection.less} | 2 + styles/{ => less/ui/resources}/resources.less | 0 styles/{ => less/ui/settings}/settings.less | 2 + styles/less/utils/colors.less | 15 + .../values.less => less/utils/spacing.less} | 0 styles/levelup.less | 271 - styles/pc.less | 1519 ---- styles/sheets/activeEffect.less | 5 - styles/sheets/class.less | 65 - styles/sheets/heritage.less | 5 - styles/sheets/sheets.less | 185 - styles/ui.less | 122 - styles/variables/colors.less | 37 - styles/variables/variables.less | 2 - 78 files changed, 4208 insertions(+), 8824 deletions(-) delete mode 100644 styles/application.less delete mode 100644 styles/class.less delete mode 100644 styles/dialog.less delete mode 100755 styles/item.less delete mode 100644 styles/less/actors/adversary.less delete mode 100644 styles/less/actors/character.less delete mode 100644 styles/less/actors/environment.less rename styles/less/{applications/beastform.less => dialog/beastform/beastform-container.less} (78%) create mode 100644 styles/less/dialog/beastform/sheet.less create mode 100644 styles/less/dialog/character-creation/creation-action-footer.less rename styles/{characterCreation.less => less/dialog/character-creation/selections-container.less} (78%) create mode 100644 styles/less/dialog/character-creation/sheet.less create mode 100644 styles/less/dialog/character-creation/tab-navigation.less rename styles/{damageReduction.less => less/dialog/damage-reduction/damage-reduction-container.less} (98%) create mode 100644 styles/less/dialog/damage-reduction/sheets.less create mode 100644 styles/less/dialog/downtime/downtime-container.less create mode 100644 styles/less/dialog/index.less create mode 100644 styles/less/dialog/level-up/navigation-container.less create mode 100644 styles/less/dialog/level-up/selections-container.less create mode 100644 styles/less/dialog/level-up/sheet.less create mode 100644 styles/less/dialog/level-up/summary-container.less create mode 100644 styles/less/dialog/level-up/tiers-container.less create mode 100644 styles/less/global/index.less delete mode 100644 styles/less/items/class.css rename styles/less/{applications => sheets-settings}/adversary-settings/experiences.less (100%) rename styles/less/{applications => sheets-settings}/adversary-settings/features.less (100%) rename styles/less/{applications => sheets-settings}/adversary-settings/sheet.less (100%) rename styles/less/{applications => sheets-settings}/environment-settings/adversaries.less (100%) rename styles/less/{applications => sheets-settings}/environment-settings/features.less (100%) rename styles/less/{applications => sheets-settings}/header.less (100%) create mode 100644 styles/less/sheets-settings/index.less rename styles/less/{ => sheets}/actors/adversary/actions.less (87%) rename styles/less/{ => sheets}/actors/adversary/header.less (92%) rename styles/less/{ => sheets}/actors/adversary/sheet.less (84%) rename styles/less/{ => sheets}/actors/adversary/sidebar.less (93%) rename styles/less/{ => sheets}/actors/character/biography.less (87%) rename styles/less/{ => sheets}/actors/character/features.less (87%) rename styles/less/{ => sheets}/actors/character/header.less (98%) rename styles/less/{ => sheets}/actors/character/inventory.less (96%) rename styles/less/{ => sheets}/actors/character/loadout.less (97%) rename styles/less/{ => sheets}/actors/character/sheet.less (88%) rename styles/less/{ => sheets}/actors/character/sidebar.less (98%) rename styles/less/{ => sheets}/actors/companion/details.less (95%) rename styles/less/{ => sheets}/actors/companion/header.less (98%) rename styles/less/{ => sheets}/actors/companion/sheet.less (52%) rename styles/less/{ => sheets}/actors/environment/header.less (95%) rename styles/less/{ => sheets}/actors/environment/sheet.less (80%) create mode 100644 styles/less/sheets/index.less rename styles/less/{ => sheets}/items/class.less (94%) rename styles/less/{items/domainCard.less => sheets/items/domain-card.less} (77%) rename styles/less/{ => sheets}/items/feature.less (84%) mode change 100755 => 100644 rename styles/{ => less/ui/chat}/chat.less (60%) create mode 100644 styles/less/ui/chat/sheet.less create mode 100644 styles/less/ui/chat/theme-colorful.less create mode 100644 styles/less/ui/combat-sidebar/combat-sidebar.less create mode 100644 styles/less/ui/combat-sidebar/combatant-controls.less create mode 100644 styles/less/ui/combat-sidebar/encounter-controls.less create mode 100644 styles/less/ui/combat-sidebar/spotlight-control.less create mode 100644 styles/less/ui/combat-sidebar/token-actions.less create mode 100644 styles/less/ui/countdown/countdown.less rename styles/{countdown.less => less/ui/countdown/sheet.less} (64%) create mode 100644 styles/less/ui/index.less rename styles/{ownershipSelection.less => less/ui/ownership-selection/ownership-selection.less} (94%) rename styles/{ => less/ui/resources}/resources.less (100%) rename styles/{ => less/ui/settings}/settings.less (98%) rename styles/{variables/values.less => less/utils/spacing.less} (100%) delete mode 100644 styles/levelup.less delete mode 100644 styles/pc.less delete mode 100644 styles/sheets/activeEffect.less delete mode 100644 styles/sheets/class.less delete mode 100644 styles/sheets/heritage.less delete mode 100644 styles/sheets/sheets.less delete mode 100644 styles/ui.less delete mode 100644 styles/variables/colors.less delete mode 100644 styles/variables/variables.less diff --git a/styles/application.less b/styles/application.less deleted file mode 100644 index 412d41e7..00000000 --- a/styles/application.less +++ /dev/null @@ -1,561 +0,0 @@ -form.daggerheart.views.downtime { - // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto' - height: auto !important; -} - -div.daggerheart.views.death-move { - // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto' - height: auto !important; -} - -div.daggerheart.views.multiclass { - // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto' - height: auto !important; -} - -.daggerheart.views { - &.levelup { - .levelup-title-container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 32px; - margin-bottom: 4px; - - .level-title { - text-decoration: underline; - } - - .level-display { - display: flex; - align-items: center; - - i { - margin: 0 @halfMargin; - } - } - } - - .levelup-section { - display: flex; - align-items: flex-start; - margin-bottom: 8px; - font-size: 11px; - - .levelup-container { - flex: 1; - - &:nth-of-type(2) { - padding: 0 4px; - } - - &.disabled { - opacity: 0.2; - } - - .levelup-inner-container { - height: 700px; - padding: 24px 58px 0; - display: flex; - flex-direction: column; - align-items: center; - position: relative; - - .levelup-legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - z-index: 1; - } - - .levelup-info { - background: @primaryAccent; - width: 100%; - text-align: center; - position: absolute; - top: -6px; - padding: 8px 0; - } - - .levelup-pretext { - padding: 8px 0; - } - - .levelup-body { - display: flex; - flex-direction: column; - - .levelup-choice-row { - display: flex; - align-items: center; - padding: 4px; - - .levelup-choice-row-inner { - display: flex; - align-items: center; - } - - .levelup-choice-input-container { - position: relative; - display: flex; - align-items: center; - - input { - &:disabled:checked::before { - opacity: 0.4; - color: var(--color-warm-1); - } - } - - i.fa-link { - transform: rotate(45deg); - position: relative; - top: 2px; - margin: 0 -3px; - } - - i.fa-lock { - position: absolute; - top: 0; - left: 0; - font-size: 8px; - } - } - } - } - - .levelup-posttext { - padding: 8px 0; - } - } - } - } - } - - .downtime-container { - .downtime-header { - margin: 0; - color: light-dark(@dark-blue, @golden); - text-align: center; - } - - .activity-container { - display: flex; - align-items: center; - padding: 8px; - - .activity-title { - flex: 1; - display: flex; - align-items: center; - - .activity-title-text { - font-size: 24px; - font-weight: bold; - } - - .activity-image { - width: 80px; - position: relative; - display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; - - .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; - } - - img { - border-radius: 50%; - } - - &:hover, - &.selected { - filter: drop-shadow(0 0 6px gold); - } - } - - .custom-name-input { - font-size: 24px; - font-weight: bold; - padding: 0; - background: transparent; - color: rgb(239, 230, 216); - } - } - - .activity-body { - flex: 1; - font-style: italic; - } - } - } - - &.downtime { - .activity-text-area { - resize: none; - } - } - - .range-reset { - flex: 0; - width: 21px; - height: 21px; - margin: 3px 4px; - border: 1px solid black; - display: flex; - align-items: center; - justify-content: center; - } - - &.roll-selection { - .roll-selection-container { - i { - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%); - } - } - - #roll-selection-costSelection footer { - display: none; - } - - .roll-dialog-container { - .hope-container { - display: flex; - gap: @fullMargin; - align-items: center; - font-size: 18px; - } - } - } - - &.npc-roll-selection { - .npc-roll-dialog-container { - display: flex; - flex-direction: column; - - .selection-container { - display: flex; - align-items: center; - margin-bottom: @fullMargin; - gap: 16px; - - .dice-container { - display: flex; - align-items: center; - flex: 1; - - .dice-inner-container { - position: relative; - display: flex; - align-items: center; - justify-content: center; - - i { - font-size: 18px; - } - - img { - border: 0; - position: relative; - left: 1px; - } - - .dice-number { - position: absolute; - font-size: 24px; - font-weight: bold; - } - } - - .advantage-container { - display: flex; - flex-direction: column; - gap: 2px; - flex: 1; - - .advantage-button { - &.active, - &:hover { - background: var(--button-hover-background-color); - } - } - } - } - } - } - } - - &.multiclass { - .multiclass-container { - margin-bottom: @largeMargin; - - .multiclass-category-title { - margin-top: @largeMargin; - } - - .multiclass-class-choices { - display: flex; - width: 100%; - height: 100%; - flex-wrap: wrap; - } - - .multiclass-spaced-choices { - display: flex; - justify-content: space-around; - width: 100%; - height: 100%; - } - - .multiclass-class-choice { - display: flex; - align-items: center; - flex-basis: 33.33%; - font-weight: bold; - font-size: 24px; - cursor: pointer; - - &.selected:not(.disabled), - &:hover:not(.disabled) { - filter: drop-shadow(0 0 3px gold); - } - - &.inactive, - &.disabled { - cursor: initial; - opacity: 0.4; - } - - img { - width: 80px; - height: 80px; - margin-right: @largeMargin; - } - } - } - } - - &.damage-selection { - .hope-container { - display: flex; - gap: @fullMargin; - align-items: center; - font-size: 18px; - } - } - - &.action { - .action-category { - display: flex; - flex-direction: column; - - .action-category-label { - display: flex; - align-items: center; - justify-content: space-between; - border-radius: 6px; - cursor: pointer; - padding: 0 @fullPadding; - margin: 0 auto @halfMargin; - - &:hover { - background-color: darkgray; - } - } - - .action-category-data { - max-height: 0; - transition: max-height 0.2s ease-in-out; - overflow: hidden; - - &.open { - max-height: initial; - } - - .multi-display { - display: flex; - gap: 1rem; - align-items: center; - .form-group { - flex: 1; - } - } - - .form-group { - display: flex; - align-items: center; - margin-bottom: 0.5rem; - label { - flex: 2; - } - .form-fields { - flex: 3; - } - img { - width: 1.5rem; - height: 1.5rem; - } - } - - .hint-group { - display: flex; - flex-direction: column; - align-items: end; - - .form-fields { - width: 100%; - display: flex; - align-items: center; - - label { - flex: 1; - } - - input, - select { - flex: 3; - } - } - - .hint { - margin: 4px 0 0 0; - font-size: 12px; - font-style: italic; - opacity: 0.6; - } - } - - .data-form-array { - border: 1px solid var(--color-fieldset-border); - padding: 0.5rem; - margin-bottom: 0.5rem; - } - } - } - } - - &.ancestry-selection { - .ancestry-section { - display: flex; - flex-direction: column; - align-items: center; - margin-bottom: @fullMargin; - - .ancestry-container { - width: 100%; - display: flex; - flex-wrap: wrap; - - .ancestry-inner-container { - flex-basis: 25%; - display: flex; - flex-direction: column; - align-items: center; - - .image-container { - img { - width: 120px; - border: 4px solid black; - border-radius: 50%; - - &.selected { - border-color: @secondaryShadow; - } - - &:hover:not(.selected) { - filter: drop-shadow(0 0 3px @secondaryShadow); - } - - &.disabled { - opacity: 0.3; - } - } - } - - .name-container { - div { - font-size: 18px; - font-weight: bold; - cursor: help; - } - } - } - } - - .mixed-ancestry-container { - width: 100%; - display: flex; - gap: @fullMargin; - - > div { - flex: 1; - } - - .mixed-ancestry-name { - text-align: center; - div { - font-size: 24px; - } - } - - .mixed-ancestry-images { - display: flex; - align-items: center; - gap: @halfMargin; - - .mixed-ancestry-image { - position: relative; - max-width: 33%; - - &:hover i { - opacity: 1; - } - - i { - position: absolute; - font-size: 32px; - top: calc(50% - 20px); - left: calc(50% - 20px); - padding: @fullPadding; - background-color: grey; - opacity: 0; - cursor: pointer; - - &:hover { - filter: drop-shadow(0 0 3px @secondaryShadow); - } - } - - img { - max-width: 100%; - } - } - - img { - max-width: 33%; - border: 4px solid black; - border-radius: 50%; - - &.selected { - border-color: @secondaryShadow; - } - } - } - } - } - } -} diff --git a/styles/class.less b/styles/class.less deleted file mode 100644 index ec1b1bd5..00000000 --- a/styles/class.less +++ /dev/null @@ -1,5 +0,0 @@ -.daggerheart.sheet.class { - .editor { - height: 500px; - } -} diff --git a/styles/daggerheart.css b/styles/daggerheart.css index b64cd424..43d91e4f 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -1,4240 +1,5 @@ -/* Base Value */ -/* Margins */ -/* Borders */ -/* Padding */ -/* Inputs */ -/* General */ -/* Drop Shadows */ -/* Background */ -/* Duality */ -/* Fear */ @import '../node_modules/@yaireo/tagify/dist/tagify.css'; -.daggerheart.sheet.class .editor { - height: 500px; -} -.daggerheart.sheet.pc { - width: 810px !important; -} -.daggerheart.sheet.pc div[data-application-part] { - display: flex; - flex-direction: column; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header { - display: flex; - gap: 4px; - height: 120px; - margin-bottom: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .portrait { - border: 0; - border-right: 1px solid var(--color-underline-header); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info { - flex: 1; - background: #778899; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .portrait { - max-width: 120px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .class-title { - text-align: center; - display: flex; - justify-content: space-between; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .class-title span:hover { - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .class-title .domain-container { - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .class-add-container { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .class-add-container button { - height: 22px; - width: 22px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - margin-left: 4px; - background: #778899; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .domain-title { - text-transform: uppercase; - display: flex; - flex-direction: column; - align-items: center; - line-height: 23px; - font-weight: bold; - font-style: italic; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .class-info .domain-image { - height: 30px; - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info { - flex: 2; - display: flex; - flex-direction: column; - justify-content: space-between; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .general-input { - position: relative; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .general-input .general-title { - position: absolute; - left: 4px; - text-align: center; - font-weight: bold; - text-transform: uppercase; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .pc-tabs { - flex: 1; - margin: 0; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .rest-container { - flex-wrap: nowrap; - display: flex; - height: var(--form-field-height); - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .rest-container button { - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - width: var(--form-field-height); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .rest-container button i { - font-size: 13px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container { - position: relative; - bottom: 4px; - flex: none; - width: 40px; - border: none; - outline: none; - margin-left: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container.levelup { - filter: drop-shadow(0px 0px 3px gold); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container img { - height: 40px; - width: 40px; - border: none; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container { - width: 48px; - position: absolute; - top: calc(50% - 17px); - left: calc(50% - 23px); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container .level-value { - font-weight: bold; - font-size: 20px; - text-align: center; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container .level-value:not(:hover), -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container .level-value:not(:focus) { - border: none; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container .levelup-marker { - position: absolute; - top: 0; - right: calc(50% - 12px); - color: gold; - filter: drop-shadow(0px 0px 3px black); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-value-container .levelup-marker.double-digit { - right: calc(50% - 20px); -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-title { - position: absolute; - bottom: 2px; - width: 42px; - background-color: black; - color: white; - left: calc(50% - 21px); - text-align: center; - border-radius: 5px; - font-size: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-title.levelup { - color: gold; - filter: drop-shadow(0px 0px 3px orange); - font-weight: bold; - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .pc-sheet-header .general-info .level-container .level-title.levelup:hover { - background-color: aliceblue; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body { - display: flex; - flex-direction: column; - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .tab-container { - height: 100%; - display: flex; - flex-direction: column; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .tab-container .tab-inner-container { - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .tab-container .tab-inner-container .body-section { - display: flex; - flex-direction: column; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .tab-container .tab-inner-container .body-section fieldset { - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .system-info { - font-size: 12px; - font-style: italic; - font-weight: bold; - margin-top: -4px; - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .feature-sheet-body { - gap: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container { - position: relative; - display: flex; - flex-wrap: wrap; - border-radius: 6px; - padding-left: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - text-transform: uppercase; - padding: 0 8px; - position: relative; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attributes-menu { - position: absolute; - bottom: calc(50% - 12px); - font-size: 24px; - left: -8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute { - position: relative; - padding: 0 0 4px; - display: flex; - flex-direction: column; - align-items: center; - flex-basis: 33.33%; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-banner { - position: relative; - top: 8px; - z-index: 2; - background: black; - color: white; - text-transform: uppercase; - padding: 2px; - border-radius: 6px; - display: flex; - align-items: center; - overflow: hidden; - min-width: 96px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-banner .attribute-roll { - position: absolute; - width: 16px; - transition: transform 0.2s; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-banner .attribute-roll:hover { - transform: rotate(30deg); - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-banner .attribute-text { - width: 100%; - margin-left: 16px; - font-size: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark { - height: 23px; - width: 23px; - position: absolute; - right: -5px; - top: 6px; - border: 2px solid black; - border-radius: 50%; - background: white; - z-index: 2; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark.selectable { - border-color: gold; - filter: drop-shadow(0 0 3px black); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark.selectable:hover i { - opacity: 0.3; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark i.selected, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark:hover i.selected { - color: green; - opacity: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-mark i { - color: black; - font-size: 17px; - opacity: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image { - position: relative; - width: fit-content; - display: flex; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image img { - height: 80px; - width: 80px; - border: none; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image .attribute-value { - width: 55px; - padding-right: 10px; - position: absolute; - top: calc(50% - 18px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - line-height: 30px; - text-align: center; - border: none; - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image .attribute-value.negative { - left: calc(50% - 29px); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image .attribute-value.unselected { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image .attribute-text { - width: 47px; - position: absolute; - top: calc(50% - 22px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - text-align: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-image .attribute-text.negative { - left: calc(50% - 29px); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-container .attribute .attribute-verb { - font-variant: petite-caps; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row { - height: 100%; - width: 100%; - display: flex; - align-items: baseline; - justify-content: space-evenly; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section { - display: flex; - align-items: center; - margin-right: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container { - position: relative; - padding: 4px; - max-width: 100px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container img { - border: none; - max-width: 80px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container .defense-value { - width: 47px; - position: absolute; - top: calc(50% - 22px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - text-align: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container .defense-value:not(:hover), -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container .defense-value:not(:focus) { - border: none; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .defense-section .defense-container .defense-banner { - position: absolute; - bottom: 20px; - left: calc(50% - 42px); - z-index: 2; - background-color: black; - color: white; - width: 84px; - text-align: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .armor-marks { - max-width: 67px; - padding: 4px; - align-self: end; - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .armor-marks .mark { - width: 16px; - height: 16px; - margin: 0px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .defense-row .armor-marks .disabled-mark { - opacity: 0.6; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .left-main-container { - position: relative; - display: flex; - flex-direction: column; - align-items: flex-start; - border-radius: 6px; - height: 100px; - width: 100px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .left-main-container .legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - text-transform: uppercase; - padding: 0 4px; - position: relative; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapon-section { - padding-top: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .threshold-container { - position: relative; - display: flex; - align-items: center; - align-self: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .threshold-container .threshold-box { - position: relative; - width: 30px; - height: 30px; - border: 2px solid black; - display: flex; - align-items: center; - justify-content: center; - font-size: 20px; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .threshold-container .threshold-spacer { - position: relative; - z-index: 2; - width: 70px; - height: 18px; - background-color: darkgray; - color: white; - display: flex; - justify-content: center; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .resource-label { - text-transform: uppercase; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .death-save { - position: absolute; - right: -22px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .death-save:hover:not(.disabled) { - filter: drop-shadow(0 0 3px red); - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .death-save.disabled { - opacity: 0.4; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .resource-box { - width: 20px; - height: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .resource-box.stress:nth-child(even) { - position: relative; - right: 1px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .resource-box .disabled { - opacity: 0.6; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-text { - font-size: 11.7px; - margin-right: 6px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-container { - background: darkgray; - border-radius: 6px; - display: flex; - padding: 2px 0px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-container .vertical-separator { - border-left: 2px solid white; - height: auto; - margin: 4px 0; - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-container .hope-inner-container { - position: relative; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-container .hope-inner-container .hope-value { - width: 16px; - height: 16px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .hope-container .hope-inner-container .hope-scar { - position: absolute; - top: calc(50% - 6px); - left: calc(50% - 7px); - opacity: 0.4; - font-size: 12px; - -webkit-transform: scaleX(-1); - transform: scaleX(-1); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row { - width: 100%; - display: flex; - align-items: flex-end; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .experience-selector { - font-size: 18px; - cursor: pointer; - margin-right: 4px; - opacity: 0.5; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .experience-selector:hover:not(.selected) { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .experience-selector.selected { - filter: drop-shadow(0 0 3px gold); - opacity: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .experience-value { - margin-left: 8px; - width: 30px; - border-bottom: 2px solid black; - border-radius: 4px; - text-align: center; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .experience-value.empty { - border: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .experience-row .disabled-experience { - border: 1px solid #7a7971; - background: rgba(0, 0, 0, 0.2); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section { - width: calc(100% - 8px); - display: flex; - justify-content: space-between; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset { - padding-right: 0; - padding-left: 0; - padding-bottom: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset legend { - margin-left: auto; - margin-right: auto; - font-size: 15px; - font-variant: all-petite-caps; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100%; - gap: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row { - display: flex; - align-items: center; - justify-content: center; - padding: 0 4px; - gap: 2px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row img, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column img { - min-width: 14px; - min-height: 14px; - height: 14px; - border: 0; - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row img:hover, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column img:hover { - cursor: pointer; - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%) drop-shadow(0 0 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row i:hover, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column i:hover { - cursor: pointer; - filter: drop-shadow(0 0 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row img:not(.owned), -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column img:not(.owned), -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-row i:not(.owned), -.daggerheart.sheet.pc div[data-application-part] .sheet-body .gold-section fieldset.gold-fieldset .gold-column i:not(.owned) { - opacity: 0.4; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .health-category { - text-transform: uppercase; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .class-feature-selectable { - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .class-feature-selectable:hover { - filter: drop-shadow(0 0 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .class-feature-selectable.inactive { - opacity: 0.5; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container { - width: 100%; - min-height: 136px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-container { - display: flex; - align-items: center; - justify-content: space-between; - padding: 4px; - margin-bottom: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-container .feature-img { - max-width: 42px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-container .feature-label { - font-weight: bold; - font-size: 30px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-container button { - flex: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container { - flex: 0; - min-width: 56px; - display: flex; - flex-wrap: wrap; - gap: 8px; - margin: 0 24px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick { - position: relative; - border: 2px solid #7a7971; - height: 24px; - border-radius: 50%; - width: 24px; - background: rgba(0, 0, 0, 0.05); - display: flex; - justify-content: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick:hover:not(.disabled):not(.used) { - cursor: pointer; - filter: drop-shadow(0 0 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick.disabled { - opacity: 0.3; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick img { - border: 0; - width: 24px; - height: 24px; - filter: invert(17%) sepia(0%) saturate(0%) hue-rotate(19deg) brightness(102%) contrast(84%); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick .feature-dice-value { - font-size: 18px; - align-self: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .features-container .feature-tick-container .feature-tick.used::after { - position: absolute; - content: '/'; - color: #7a7971; - font-weight: 700; - font-size: 1.7em; - left: 4px; - top: -5px; - transform: rotate(25deg); - font-size: 24.5px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .feature-input { - border: 0; - border-bottom: 1px solid #7a7971; - text-align: center; - height: min-content; - background: inherit; - font-size: 20px; - position: relative; - bottom: 3px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .editor { - height: 400px; - width: 100%; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title { - position: relative; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title .proficiency-container { - width: 176px; - height: 20px; - position: absolute; - bottom: -15px; - left: calc(50% - 88px); - text-transform: uppercase; - display: flex; - align-items: center; - justify-content: center; - z-index: 1; - clip-path: polygon(11% 100%, 89% 100%, 100% 0%, 0% 0%); - font-size: 10px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title .proficiency-container span { - margin-right: 2px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title .proficiency-container .proficiency-dot { - background: white; - color: white; - font-size: 10px; - padding: 1px; - border-radius: 50%; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title .proficiency-container .proficiency-dot.marked { - color: black; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-title .proficiency-container .proficiency-dot:not(:last-of-type) { - margin-right: 2px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-burden { - position: absolute; - top: -4px; - right: -56px; - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-burden .weapons-burden-icon { - color: white; - font-size: 22px; - -webkit-text-stroke-width: 1px; - -webkit-text-stroke-color: black; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-burden .weapons-burden-icon.active { - -webkit-text-stroke-color: rgba(0, 0, 0, 0.05); - color: black; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-burden .weapons-burden-icon.left { - -webkit-transform: scaleX(-1) rotate(20deg); - transform: scaleX(-1) rotate(20deg); - margin-right: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .weapons-burden .weapons-burden-icon.right { - transform: rotate(20deg); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .armor-container { - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .armor-container .active-item-label-chip { - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-container { - display: flex; - flex-direction: column; - width: 100%; - padding: 2px 0px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-container .weapons-label-row { - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-container .weapons-label-row .damage-roll { - width: 24px; - border: none; - margin-left: 4px; - transition: transform 0.2s; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-container .weapons-label-row .damage-roll:hover { - transform: rotate(30deg); - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-label-chip { - width: 62px; - border: 2px solid black; - border-radius: 6px; - background-color: #778899; - display: flex; - align-items: center; - justify-content: space-around; - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-label-chip img { - height: 20px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-label-chip button { - height: 17px; - width: 17px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - background: #7a7971; - border-color: black; - margin: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-label-chip button:hover { - background: red; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .item-section .active-item-label-chip button i { - font-size: 10px; - color: black; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-armor-section, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-weapon-section { - width: 100%; - margin-bottom: 8px; - text-transform: uppercase; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-armor-section h2, -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-weapon-section h2 { - width: 100%; - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-legend { - display: flex; - align-items: center; - margin-bottom: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-legend .page-selector { - margin-left: 4px; - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-legend .page-selector i:hover:not(.disabled) { - cursor: pointer; - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-legend .page-selector i.disabled { - opacity: 0.4; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-add-button { - position: absolute; - border-radius: 50%; - height: 15px; - width: 15px; - top: -20px; - background: grey; - border-color: black; - right: 6px; - display: flex; - font-size: 13px; - align-items: center; - justify-content: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory { - width: 100%; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row { - height: 26px; - border-bottom: 1px solid #7a7971; - display: flex; - margin-bottom: 8px; - border-radius: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container { - flex-basis: 25%; - margin: 0 4px 8px; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container:hover { - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container .inventory-item { - background: #778899; - padding: 4px; - border: 1px solid black; - border-radius: 6px; - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container .inventory-item .inventory-item-text { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container .inventory-item button { - height: 16px; - width: 16px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - flex: 0; - background: #7a7971; - border-color: black; - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .inventory-row .item-container .inventory-item button i { - font-size: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory .editor { - height: 100px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-items { - width: 100%; - flex: 1; - display: flex; - flex-direction: column; - justify-content: space-between; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab { - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body { - height: 100%; - width: 100%; - padding: 8px; - display: flex; - flex-direction: column; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .card-row { - flex: 1; - display: flex; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .domain-card { - flex: 0; - flex-basis: 33.33%; - margin: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .loadout-body { - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .loadout-body .loadout-container { - height: 100%; - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .loadout-body .loadout-container .top-card-row { - flex: 1; - display: flex; - justify-content: space-around; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .loadout-body .loadout-container .domain-card.outlined { - border: 2px dotted black; - padding: 0; - margin: 8px; - height: calc(100% - 16px); - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-evenly; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .vault-container { - display: flex; - flex-wrap: wrap; - overflow-y: auto; - height: 100%; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .vault-container .vault-card { - flex: 0; - flex-basis: calc(33.33% - 16px); - margin: 8px; - height: calc(50% - 16px); - min-height: calc(50% - 16px); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .domain-card-menu { - flex: 0; - width: 120px; - height: 100%; - border-width: 2px 0 2px 2px; - border-color: black; - border-style: solid; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .domain-card-tab .domain-card-body .domain-card-menu button { - margin-bottom: 2px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .loadout-tabs { - border-top: 1px solid #b5b3a4; - border-bottom: 1px solid #b5b3a4; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card { - position: relative; - border: 4px solid #708090; - border-radius: 6px; - display: flex; - flex-direction: column; - height: 100%; - font-size: 14px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-image-container { - position: relative; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-image { - width: 100%; - height: 100%; - aspect-ratio: 2; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-text-container { - flex: 1; - position: relative; - height: 50%; - display: flex; - flex-direction: column; - overflow-y: auto; - padding: 12px 4px 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-level { - position: absolute; - top: 0; - left: 12px; - color: black; - height: 60px; - border: 2px solid orange; - border-top-width: 0; - width: 30px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-evenly; - background: grey; - font-size: 20px; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-level img { - border: 0; - width: 20px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-refresh-cost { - position: absolute; - top: 12px; - right: 12px; - color: white; - width: 30px; - height: 30px; - border: 2px solid orange; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - background: black; - font-size: 14px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-refresh-cost i { - font-size: 11px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-type { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-weight: bold; - position: absolute; - left: 0; - text-align: center; - width: 100%; - bottom: -9px; - z-index: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-type .abilities-card-type-text { - padding: 0px 4px; - border: 1px solid black; - border-radius: 6px; - background: gold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-title { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-weight: bold; - font-size: 18px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-sub-title { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-style: italic; - font-size: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-spellcast { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - text-transform: uppercase; - font-size: 12px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-spellcast .title { - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-description { - flex: 0; - font-size: 12px; - margin-bottom: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-effect { - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-effect:hover { - background: rgba(47, 79, 79, 0.25); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-effect > * { - margin-top: 0; - margin-bottom: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-abilities { - flex: 1; - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-abilities .abilities-card-ability { - font-size: 12px; - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-abilities .abilities-card-ability:hover { - background: rgba(47, 79, 79, 0.25); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-abilities .abilities-card-ability > * { - margin: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card:hover .abilities-card-menu { - height: 40px; - left: 0px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-menu { - display: flex; - justify-content: center; - align-items: center; - height: 0; - transition: height 0.2s; - overflow: hidden; - position: absolute; - bottom: 0; - z-index: 2; - width: 100%; - background: grey; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .abilities-card .abilities-card-menu button { - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .heritage-container { - height: 100%; - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .heritage-container .card-row { - height: 50%; - display: flex; - justify-content: space-around; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .heritage-container .heritage-card { - flex-basis: 33.33%; - margin: 8px; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .heritage-container .heritage-card.outlined { - border: 2px dotted black; - font-size: 25px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .empty-ability-container { - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - font-size: 25px; - opacity: 0.7; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .empty-ability-container .empty-ability-inner-container { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .empty-ability-container .empty-ability-inner-container i { - font-size: 48px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .story-container { - gap: 16px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .story-container .story-fieldset { - border-radius: 6px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .story-container .story-legend { - margin-left: auto; - margin-right: auto; - padding: 0 8px; - font-size: 30px; - font-weight: bold; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .story-container .scars-container .editor { - height: 240px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container { - height: 100%; - overflow: auto; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list { - list-style-type: none; - padding: 0 8px; - margin-top: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list.inventory-item-header { - margin-bottom: 0; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-title-row-container { - display: flex; - align-items: center; - width: 100%; - border-bottom: 4px ridge slategrey; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-title-row-container .inventory-title-row { - justify-content: space-between; - flex: 1; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-title-row-container .inventory-item-title-container { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-start; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-title-row-container .inventory-item-quantity { - width: 48px; - display: flex; - align-items: center; - margin-right: 96px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item { - background: crimson; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item:not(:last-of-type) { - border-bottom: 2px ridge slategrey; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-title-container { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-start; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-title-container .inventory-item-title { - display: flex; - align-items: center; - cursor: pointer; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-title-container .inventory-item-title:hover { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-quantity { - width: 60px; - display: flex; - align-items: center; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-quantity.spaced { - margin-right: 56px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-quantity input { - margin: 0 2px; - border: 0; - border-bottom: 2px solid black; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-item .inventory-item-quantity i { - font-size: 20px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-title-row { - font-size: 20px; - font-weight: bold; - display: flex; - align-items: center; - padding: 0 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-row { - display: flex; - align-items: center; - padding: 4px; - font-size: 24px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-row .row-icon { - margin-left: 4px; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-row .active-item { - position: absolute; - font-size: 16px; - left: calc(50% - 8px); - top: calc(50% - 8px); - margin-left: 2px; - color: crimson; -} -.daggerheart.sheet.pc div[data-application-part] .sheet-body .inventory-container .inventory-item-list .inventory-row img { - width: 32px; -} -.combat-sidebar .encounter-controls.combat { - justify-content: space-between; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls { - display: flex; - align-items: center; - gap: 8px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container { - display: flex; - gap: 2px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container { - display: flex; - position: relative; - align-items: center; - justify-content: center; - color: black; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .dice { - height: 22px; - width: 22px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-fear { - position: absolute; - font-size: 16px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-counter { - position: absolute; - right: -10px; - color: var(--color-text-secondary); -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-countdowns { - color: var(--content-link-icon-color); -} -.combat-sidebar .encounter-controls.combat .control-buttons { - width: min-content; -} -.combat-sidebar .combatant-controls { - flex: 0; -} -.combat-sidebar .token-actions { - align-self: stretch; - display: flex; - align-items: top; - justify-content: center; - gap: 16px; -} -.combat-sidebar .token-actions .action-tokens { - display: flex; - gap: 4px; -} -.combat-sidebar .token-actions .action-tokens .action-token { - height: 22px; - width: 22px; - border: 1px solid; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 10px; - padding: 8px; - --button-size: 0; -} -.combat-sidebar .token-actions .action-tokens .action-token.used { - opacity: 0.5; - background: transparent; -} -.combat-sidebar .token-actions button { - font-size: 22px; - height: 24px; - width: 24px; -} -.combat-sidebar .token-actions button.main { - background: var(--button-hover-background-color); - color: var(--button-hover-text-color); - border-color: var(--button-hover-border-color); -} -.combat-sidebar .token-actions button.main:hover { - filter: drop-shadow(0 0 3px var(--button-hover-text-color)); -} -.combat-sidebar .spotlight-control { - font-size: 26px; -} -.combat-sidebar .spotlight-control:focus { - outline: none; - box-shadow: none; -} -.combat-sidebar .spotlight-control.discrete:hover { - background: inherit; -} -.combat-sidebar .spotlight-control.requesting { - filter: drop-shadow(0 0 3px gold); - color: var(--button-hover-text-color); -} -.combat-sidebar h4 { - margin: 0; - text-align: center; -} -.chat-message .duality-modifiers, -.chat-message .duality-result, -.chat-message .dice-title { - display: none; -} -fieldset.daggerheart.chat { - padding: 0; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; -} -fieldset.daggerheart.chat legend { - display: flex; - align-items: center; - gap: 5px; -} -fieldset.daggerheart.chat legend:before, -fieldset.daggerheart.chat legend:after { - content: '\f0d8'; - font-family: 'Font Awesome 6 Pro'; -} -fieldset.daggerheart.chat.expanded legend:before, -fieldset.daggerheart.chat.expanded legend:after { - content: '\f0d7'; -} -fieldset.daggerheart.chat .daggerheart.chat { - margin-top: 5px; -} -.daggerheart.chat.downtime { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.downtime .downtime-title-container { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.downtime .downtime-title-container .downtime-subtitle { - font-size: 17px; -} -.daggerheart.chat.downtime .downtime-image { - width: 80px; -} -.daggerheart.chat.downtime .downtime-refresh-container { - margin-top: 8px; - width: 100%; -} -.daggerheart.chat.downtime .downtime-refresh-container .refresh-title { - font-weight: bold; -} -.daggerheart.chat.roll .dice-flavor { - text-align: center; - font-weight: bold; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality { - display: flex; - gap: 0.25rem; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll { - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - margin-bottom: 4px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container { - display: flex; - flex-direction: column; - gap: 2px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-title { - color: var(--color-light-1); - text-shadow: 0 0 1px black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container { - display: flex; - align-items: center; - justify-content: center; - position: relative; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper, -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { - clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper { - height: 24px; - width: 24px; - position: relative; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper .dice { - height: 26px; - width: 26px; - max-width: unset; - position: absolute; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-value { - position: absolute; - font-weight: bold; - font-size: 16px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper { - background: black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(79%) sepia(79%) saturate(333%) hue-rotate(352deg) brightness(102%) contrast(103%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-value { - color: var(--color-dark-1); - text-shadow: 0 0 4px white; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { - background: white; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(12%) sepia(88%) saturate(4321%) hue-rotate(221deg) brightness(92%) contrast(110%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-value { - color: var(--color-light-1); - text-shadow: 0 0 4px black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.advantage .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(18%) sepia(92%) saturate(4133%) hue-rotate(96deg) brightness(104%) contrast(107%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.disadvantage .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(9%) sepia(78%) saturate(6903%) hue-rotate(11deg) brightness(93%) contrast(117%); -} -.daggerheart.chat.roll .dice-total.duality.hope { - border-color: #ffe760; - border-width: 3px; - background: rgba(255, 231, 96, 0.5); -} -.daggerheart.chat.roll .dice-total.duality.fear { - border-color: #0032b1; - border-width: 3px; - background: rgba(0, 50, 177, 0.5); -} -.daggerheart.chat.roll .dice-total.duality.critical { - border-color: #430070; - border-width: 3px; - background: rgba(67, 0, 112, 0.5); -} -.daggerheart.chat.roll .dice-total .dice-total-value .hope { - color: #ffe760; -} -.daggerheart.chat.roll .dice-total .dice-total-value .fear { - color: #0032b1; -} -.daggerheart.chat.roll .dice-total .dice-total-value .critical { - color: #430070; -} -.daggerheart.chat.roll .dice-total-label { - font-size: 12px; - font-weight: bold; - font-variant: all-small-caps; - margin: -8px 0; -} -.daggerheart.chat.roll .target-selection { - display: flex; - justify-content: space-around; -} -.daggerheart.chat.roll .target-selection input[type='radio'] { - display: none; -} -.daggerheart.chat.roll .target-selection input[type='radio']:checked + label { - text-shadow: 0px 0px 4px #ce5937; -} -.daggerheart.chat.roll .target-selection input[type='radio']:not(:checked) + label { - opacity: 0.75; -} -.daggerheart.chat.roll .target-selection label { - cursor: pointer; - opacity: 0.75; -} -.daggerheart.chat.roll .target-selection label.target-selected { - text-shadow: 0px 0px 4px #ce5937; - opacity: 1; -} -.daggerheart.chat.roll .target-section { - margin-top: 5px; -} -.daggerheart.chat.roll .target-section .target-container { - display: flex; - transition: all 0.2s ease-in-out; -} -.daggerheart.chat.roll .target-section .target-container:hover { - filter: drop-shadow(0 0 3px gold); - border-color: gold; -} -.daggerheart.chat.roll .target-section .target-container.hidden { - display: none; - border: 0; -} -.daggerheart.chat.roll .target-section .target-container.hit { - background: #008000; -} -.daggerheart.chat.roll .target-section .target-container.miss { - background: #ff0000; -} -.daggerheart.chat.roll .target-section .target-container img, -.daggerheart.chat.roll .target-section .target-container .target-save-container { - width: 22px; - height: 22px; - align-self: center; - border-color: transparent; -} -.daggerheart.chat.roll .target-section .target-container img { - flex: 0; - margin-left: 8px; -} -.daggerheart.chat.roll .target-section .target-container .target-save-container { - margin-right: 8px; - justify-content: center; - display: flex; - align-items: center; - min-height: unset; - border: 1px solid black; -} -.daggerheart.chat.roll .target-section .target-container .target-inner-container { - flex: 1; - display: flex; - justify-content: center; - font-size: var(--font-size-16); -} -.daggerheart.chat.roll .target-section .target-container:not(:has(.target-save-container)) .target-inner-container { - margin-right: 32px; -} -.daggerheart.chat.roll .dice-actions { - display: flex; - gap: 4px; -} -.daggerheart.chat.roll .dice-actions button { - flex: 1; -} -.daggerheart.chat.roll .dice-result .roll-damage-button, -.daggerheart.chat.roll .dice-result .damage-button, -.daggerheart.chat.roll .dice-result .duality-action { - margin-top: 5px; -} -.daggerheart.chat.roll:not(.expanded) .dice-tooltip { - grid-template-rows: 0fr; -} -.daggerheart.chat.domain-card { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.domain-card .domain-card-title { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.domain-card .domain-card-title div { - font-size: 20px; - font-variant: small-caps; - font-weight: bold; -} -.daggerheart.chat.domain-card .domain-card-title h2 { - width: 100%; - text-align: center; - margin: 0; -} -.daggerheart.chat.domain-card .ability-card-footer { - display: flex; - width: 100%; - margin-top: 8px; - flex-wrap: wrap; -} -.daggerheart.chat.domain-card .ability-card-footer button { - border-radius: 6px; - background: #699969; - border-color: black; - flex-basis: calc(50% - 2px); -} -.daggerheart.chat.domain-card .ability-card-footer button:nth-of-type(n + 3) { - margin-top: 2px; -} -.daggerheart.chat.domain-card .ability-card-footer .ability-card-action-cost { - margin: auto; - font-size: 1.5em; -} -.daggerheart.chat.domain-card img { - width: 80px; -} -.daggerheart.chat button.inner-button { - --button-size: 1.25rem; - --input-height: 1.25rem; - padding: 0 0.25rem; - margin: 5px 1px -4px auto; -} -.daggerheart.chat button.inner-button.inner-button-right { - margin-left: auto; -} -.daggerheart.chat [data-use-perm='false'] { - pointer-events: none; - border-color: transparent; -} -.daggerheart.chat [data-view-perm='false'] > * { - display: none; -} -.daggerheart.chat [data-view-perm='false']::after { - content: '??'; -} -.theme-colorful .chat-message.duality { - border-color: black; - padding: 8px 0 0 0; -} -.theme-colorful .chat-message.duality fieldset.daggerheart.chat { - border-top-width: 0; - display: contents; -} -.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:before, -.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:after { - display: none; -} -.theme-colorful .chat-message.duality .message-header { - color: var(--color-light-3); - padding: 0 8px; -} -.theme-colorful .chat-message.duality.hope { - background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); -} -.theme-colorful .chat-message.duality.fear { - background: linear-gradient(0, rgba(0, 0, 255, 0.6), rgba(15, 15, 97, 0.6)); -} -.theme-colorful .chat-message.duality.critical { - background: linear-gradient(0, rgba(128, 0, 128, 0.6), rgba(37, 8, 37, 0.6)); -} -.theme-colorful .chat-message.duality .chat-message header { - color: var(--color-light-3); -} -.theme-colorful .chat-message.duality > * { - padding: 0 8px; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers, -.theme-colorful .chat-message.duality .message-content .duality-result, -.theme-colorful .chat-message.duality .message-content .dice-title { - display: flex; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; -} -.theme-colorful .chat-message.duality .message-content .dice-flavor { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - border-bottom: 1px solid; - display: flex; - align-items: end; - justify-content: space-between; - padding: 0 8px; - margin: 0 -8px 2px; - font-weight: unset; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-formula, -.theme-colorful .chat-message.duality .message-content .dice-result > .dice-total, -.theme-colorful .chat-message.duality .message-content .dice-result .part-header { - display: none; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip { - grid-template-rows: 1fr; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part { - display: flex; - align-items: end; - gap: 0.25rem; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls { - margin-bottom: 0; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls.duality li { - display: flex; - align-items: center; - justify-content: center; - position: relative; - background: unset; - line-height: unset; - font-weight: unset; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .duality-modifier { - display: flex; - margin-bottom: 6px; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-size: var(--font-size-16); -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-selection label { - color: var(--color-light-1); -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-section { - margin: 4px 0; - border: 2px solid; - margin-top: 5px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-section .dice-total { - box-shadow: unset; - border: unset; - border-radius: unset; - font-size: var(--font-size-18); -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions { - justify-content: space-between; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions.duality-alone { - justify-content: end; - margin-top: -20px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions > * { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action { - border-radius: 0 6px 0 0; - margin-left: -8px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action.duality-action-effect { - border-top-left-radius: 6px; - margin-left: initial; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-result { - border-radius: 6px 0 0 0; - margin-right: -8px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-result { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - margin-left: auto; - align-self: center; - border-radius: 6px; -} -.theme-colorful .chat-message.duality button.inner-button { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - border-color: black; -} -.daggerheart.sheet.feature .editable { - display: flex; - flex-direction: column; -} -.daggerheart.sheet.feature .sheet-body { - flex: 1; - display: flex; - flex-direction: column; -} -.daggerheart.sheet.feature .feature-description { - flex: 1; - display: flex; - flex-direction: column; -} -.daggerheart.sheet.class .class-feature { - display: flex; -} -.daggerheart.sheet.class .class-feature img { - width: 40px; -} -.daggerheart.sheet.class .class-feature button { - width: 40px; -} -.daggerheart.sheet .domain-card-description .editor { - height: 300px; -} -.daggerheart.sheet .item-container { - margin-top: 4px; - gap: 4px; - align-items: baseline; -} -.daggerheart.sheet .item-sidebar { - min-width: 160px; - flex: 0; - padding: 4px; -} -.daggerheart.sheet .item-sidebar label { - margin-right: 8px; - font-weight: bold; -} -.daggerheart.sheet .item-sidebar input[type='checkbox'] { - margin: 0; -} -form.daggerheart.views.downtime { - height: auto !important; -} -div.daggerheart.views.death-move { - height: auto !important; -} -div.daggerheart.views.multiclass { - height: auto !important; -} -.daggerheart.views.levelup .levelup-title-container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 32px; - margin-bottom: 4px; -} -.daggerheart.views.levelup .levelup-title-container .level-title { - text-decoration: underline; -} -.daggerheart.views.levelup .levelup-title-container .level-display { - display: flex; - align-items: center; -} -.daggerheart.views.levelup .levelup-title-container .level-display i { - margin: 0 4px; -} -.daggerheart.views.levelup .levelup-section { - display: flex; - align-items: flex-start; - margin-bottom: 8px; - font-size: 11px; -} -.daggerheart.views.levelup .levelup-section .levelup-container { - flex: 1; -} -.daggerheart.views.levelup .levelup-section .levelup-container:nth-of-type(2) { - padding: 0 4px; -} -.daggerheart.views.levelup .levelup-section .levelup-container.disabled { - opacity: 0.2; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container { - height: 700px; - padding: 24px 58px 0; - display: flex; - flex-direction: column; - align-items: center; - position: relative; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - z-index: 1; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-info { - background: #778899; - width: 100%; - text-align: center; - position: absolute; - top: -6px; - padding: 8px 0; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-pretext { - padding: 8px 0; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body { - display: flex; - flex-direction: column; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row { - display: flex; - align-items: center; - padding: 4px; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row .levelup-choice-row-inner { - display: flex; - align-items: center; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row .levelup-choice-input-container { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row .levelup-choice-input-container input:disabled:checked::before { - opacity: 0.4; - color: var(--color-warm-1); -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row .levelup-choice-input-container i.fa-link { - transform: rotate(45deg); - position: relative; - top: 2px; - margin: 0 -3px; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-body .levelup-choice-row .levelup-choice-input-container i.fa-lock { - position: absolute; - top: 0; - left: 0; - font-size: 8px; -} -.daggerheart.views.levelup .levelup-section .levelup-container .levelup-inner-container .levelup-posttext { - padding: 8px 0; -} -.daggerheart.views .downtime-container .downtime-header { - margin: 0; - color: light-dark(#18162e, #f3c267); - text-align: center; -} -.daggerheart.views .downtime-container .activity-container { - display: flex; - align-items: center; - padding: 8px; -} -.daggerheart.views .downtime-container .activity-container .activity-title { - flex: 1; - display: flex; - align-items: center; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-title-text { - font-size: 24px; - font-weight: bold; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image { - width: 80px; - position: relative; - display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image img { - border-radius: 50%; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image:hover, -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image.selected { - filter: drop-shadow(0 0 6px gold); -} -.daggerheart.views .downtime-container .activity-container .activity-title .custom-name-input { - font-size: 24px; - font-weight: bold; - padding: 0; - background: transparent; - color: #efe6d8; -} -.daggerheart.views .downtime-container .activity-container .activity-body { - flex: 1; - font-style: italic; -} -.daggerheart.views.downtime .activity-text-area { - resize: none; -} -.daggerheart.views .range-reset { - flex: 0; - width: 21px; - height: 21px; - margin: 3px 4px; - border: 1px solid black; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.views.roll-selection .roll-selection-container i { - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%); -} -.daggerheart.views.roll-selection #roll-selection-costSelection footer { - display: none; -} -.daggerheart.views.roll-selection .roll-dialog-container .hope-container { - display: flex; - gap: 8px; - align-items: center; - font-size: 18px; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container { - display: flex; - flex-direction: column; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container { - display: flex; - align-items: center; - margin-bottom: 8px; - gap: 16px; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container { - display: flex; - align-items: center; - flex: 1; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .dice-inner-container { - position: relative; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .dice-inner-container i { - font-size: 18px; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .dice-inner-container img { - border: 0; - position: relative; - left: 1px; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .dice-inner-container .dice-number { - position: absolute; - font-size: 24px; - font-weight: bold; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .advantage-container { - display: flex; - flex-direction: column; - gap: 2px; - flex: 1; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .advantage-container .advantage-button.active, -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .advantage-container .advantage-button:hover { - background: var(--button-hover-background-color); -} -.daggerheart.views.multiclass .multiclass-container { - margin-bottom: 16px; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-category-title { - margin-top: 16px; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choices { - display: flex; - width: 100%; - height: 100%; - flex-wrap: wrap; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-spaced-choices { - display: flex; - justify-content: space-around; - width: 100%; - height: 100%; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice { - display: flex; - align-items: center; - flex-basis: 33.33%; - font-weight: bold; - font-size: 24px; - cursor: pointer; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice.selected:not(.disabled), -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice:hover:not(.disabled) { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice.inactive, -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice.disabled { - cursor: initial; - opacity: 0.4; -} -.daggerheart.views.multiclass .multiclass-container .multiclass-class-choice img { - width: 80px; - height: 80px; - margin-right: 16px; -} -.daggerheart.views.damage-selection .hope-container { - display: flex; - gap: 8px; - align-items: center; - font-size: 18px; -} -.daggerheart.views.action .action-category { - display: flex; - flex-direction: column; -} -.daggerheart.views.action .action-category .action-category-label { - display: flex; - align-items: center; - justify-content: space-between; - border-radius: 6px; - cursor: pointer; - padding: 0 4px; - margin: 0 auto 4px; -} -.daggerheart.views.action .action-category .action-category-label:hover { - background-color: darkgray; -} -.daggerheart.views.action .action-category .action-category-data { - max-height: 0; - transition: max-height 0.2s ease-in-out; - overflow: hidden; -} -.daggerheart.views.action .action-category .action-category-data.open { - max-height: initial; -} -.daggerheart.views.action .action-category .action-category-data .multi-display { - display: flex; - gap: 1rem; - align-items: center; -} -.daggerheart.views.action .action-category .action-category-data .multi-display .form-group { - flex: 1; -} -.daggerheart.views.action .action-category .action-category-data .form-group { - display: flex; - align-items: center; - margin-bottom: 0.5rem; -} -.daggerheart.views.action .action-category .action-category-data .form-group label { - flex: 2; -} -.daggerheart.views.action .action-category .action-category-data .form-group .form-fields { - flex: 3; -} -.daggerheart.views.action .action-category .action-category-data .form-group img { - width: 1.5rem; - height: 1.5rem; -} -.daggerheart.views.action .action-category .action-category-data .hint-group { - display: flex; - flex-direction: column; - align-items: end; -} -.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields { - width: 100%; - display: flex; - align-items: center; -} -.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields label { - flex: 1; -} -.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields input, -.daggerheart.views.action .action-category .action-category-data .hint-group .form-fields select { - flex: 3; -} -.daggerheart.views.action .action-category .action-category-data .hint-group .hint { - margin: 4px 0 0 0; - font-size: 12px; - font-style: italic; - opacity: 0.6; -} -.daggerheart.views.action .action-category .action-category-data .data-form-array { - border: 1px solid var(--color-fieldset-border); - padding: 0.5rem; - margin-bottom: 0.5rem; -} -.daggerheart.views.ancestry-selection .ancestry-section { - display: flex; - flex-direction: column; - align-items: center; - margin-bottom: 8px; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container { - width: 100%; - display: flex; - flex-wrap: wrap; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container { - flex-basis: 25%; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container .image-container img { - width: 120px; - border: 4px solid black; - border-radius: 50%; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container .image-container img.selected { - border-color: gold; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container .image-container img:hover:not(.selected) { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container .image-container img.disabled { - opacity: 0.3; -} -.daggerheart.views.ancestry-selection .ancestry-section .ancestry-container .ancestry-inner-container .name-container div { - font-size: 18px; - font-weight: bold; - cursor: help; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container { - width: 100%; - display: flex; - gap: 8px; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container > div { - flex: 1; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-name { - text-align: center; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-name div { - font-size: 24px; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images { - display: flex; - align-items: center; - gap: 4px; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images .mixed-ancestry-image { - position: relative; - max-width: 33%; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images .mixed-ancestry-image:hover i { - opacity: 1; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images .mixed-ancestry-image i { - position: absolute; - font-size: 32px; - top: calc(50% - 20px); - left: calc(50% - 20px); - padding: 4px; - background-color: grey; - opacity: 0; - cursor: pointer; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images .mixed-ancestry-image i:hover { - filter: drop-shadow(0 0 3px gold); -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images .mixed-ancestry-image img { - max-width: 100%; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images img { - max-width: 33%; - border: 4px solid black; - border-radius: 50%; -} -.daggerheart.views.ancestry-selection .ancestry-section .mixed-ancestry-container .mixed-ancestry-images img.selected { - border-color: gold; -} -.daggerheart.sheet.heritage .editor { - height: 200px; -} -.daggerheart.sheet.class .guide .drop-section { - width: 100%; -} -.daggerheart.sheet.class .guide .drop-section legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; -} -.daggerheart.sheet.class .guide .drop-section .drop-section-body { - min-height: 40px; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.sheet.class .guide .trait-input { - text-align: center; - min-width: 24px; -} -.daggerheart.sheet.class .guide .suggested-item { - border-radius: 6px; - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; -} -.daggerheart.sheet.class .guide .suggested-item img { - width: 30px; -} -.daggerheart.sheet.class .guide .suggested-item div { - text-align: center; -} -.daggerheart.sheet.class .guide .suggested-item i { - border-radius: 50%; - margin-right: 4px; - font-size: 11px; -} -.daggerheart.sheet.class .guide .extra-section { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.sheet.class .guide .extra-section .extra-title { - font-size: 14px; - font-weight: bold; -} -.daggerheart.sheet.class .guide-section-title-centered { - font-weight: bold; - font-size: 18px; -} -.daggerheart.sheet.class .inventory-section { - width: 100%; - border: 2px solid black; - border-style: dotted; - min-height: 80px; -} -.daggerheart.sheet.class .inventory-section .inventory-title { - font-weight: bold; - font-size: 14px; - text-align: center; -} -.daggerheart.sheet.class .domain-section { - display: flex; - align-items: center; - gap: 5px; -} -.application.sheet.daggerheart.dh-style.active-effect-config label { - white-space: nowrap; -} -.daggerheart.sheet .title-container { - display: flex; - gap: 8px; -} -.daggerheart.sheet .title-container div { - flex: 1; - align-items: baseline; -} -.daggerheart.sheet .editor-form-group { - display: flex; - flex-direction: column; -} -.daggerheart.sheet .editor-form-group label { - font-weight: bold; - text-align: center; -} -.daggerheart.sheet .option-select { - position: absolute; - top: calc(50% - 10px); - right: 8px; - height: 20px; - width: 20px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; -} -.daggerheart.sheet .option-select.deeper { - right: 32px; -} -.daggerheart.sheet .option-select:hover:not(:disabled) { - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; -} -.daggerheart.sheet .option-select i { - margin: 0; - font-size: 11px; -} -.daggerheart.sheet .ability-title { - width: 100%; - display: flex; -} -.daggerheart.sheet .ability-title h2 { - flex: 1; -} -.daggerheart.sheet .ability-title i { - cursor: pointer; -} -.daggerheart.sheet .ability-title i:hover { - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.sheet .ability-choices { - display: flex; - align-items: center; - flex-wrap: wrap; -} -.daggerheart.sheet .ability-chip { - border: 2px solid #708090; - border-radius: 6px; - display: flex; - align-items: center; - padding: 4px; - margin-bottom: 6px; - flex: calc(33% - 4px); - max-width: calc(33% - 4px); -} -.daggerheart.sheet .ability-chip.selected { - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.sheet .ability-chip:nth-of-type(3n-1) { - margin-left: 6px; - margin-right: 6px; -} -.daggerheart.sheet .ability-chip input { - border: 0; -} -.daggerheart.sheet .ability-chip button { - flex: 0; - border-radius: 50%; - height: 20px; - width: 20px; - display: flex; - align-items: center; - justify-content: center; - margin: 2px 0 2px 4px; - padding: 12px; -} -.daggerheart.sheet .ability-chip button i { - margin: 0; -} -.daggerheart.sheet .object-select-display { - position: relative; - width: calc(100% - 2px); - background: rgba(0, 0, 0, 0.05); - height: var(--form-field-height); - display: flex; - border: 1px solid #7a7971; - border-radius: 3px; -} -.daggerheart.sheet .object-select-display .object-select-title { - position: absolute; - left: 4px; - text-align: center; - font-weight: bold; - text-transform: uppercase; -} -.daggerheart.sheet .object-select-display .object-select-text { - align-self: center; -} -.daggerheart.sheet .object-select-display .object-select-item { - cursor: pointer; -} -.daggerheart.sheet .object-select-display .object-select-item:hover { - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.sheet .feature-container { - display: flex; - align-items: center; - justify-content: space-between; - background: #778899; - padding: 8px; - border: 2px solid black; - border-radius: 6px; -} -.daggerheart.sheet .feature-container:not(:last-child) { - margin-bottom: 8px; -} -.daggerheart.sheet .feature-container .feature-inner-container { - display: flex; - align-items: center; -} -.daggerheart.sheet .feature-container .feature-inner-container img { - height: 40px; - width: 40px; - margin-right: 8px; -} -.daggerheart.sheet .feature-container .feature-inner-container .feature-title { - font-size: 22px; - font-weight: bold; - font-style: italic; -} -.daggerheart.sheet .feature-container button { - height: 40px; - width: 40px; - background: inherit; - border: 0; -} -.item-button.checked { - background: green; -} -.item-button .item-icon { - opacity: 0; - transition: opacity 0.2s; -} -.item-button .item-icon.checked { - opacity: 1; -} -.theme-light .daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .descriptor { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.theme-light .daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, -.theme-light .daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, -.theme-light .daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.dh-style.dialog.character-creation .window-content { - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .window-content .tab { - overflow-y: auto; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav { - flex: 1; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a.disabled { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .nav-section-text { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker { - position: absolute; - align-self: center; - top: -8px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 16px; - width: 16px; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker.active { - background-color: var(--color-warm-2); -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container { - width: 140px; - display: flex; - flex-direction: column; - text-align: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container .card-preview-container { - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-outer-container { - display: flex; - justify-content: space-evenly; - height: 210px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container { - border-radius: 8px; - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container { - position: relative; - border-radius: 8px; - border-color: light-dark(#18162e, #f3c267); - display: flex; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container legend { - font-size: 20px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button { - position: absolute; - bottom: -8px; - height: 16px; - width: 110px; - min-height: unset; - border: 1px solid light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #efe6d8); - background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button:hover { - background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); - filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container { - text-align: center; - display: flex; - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container { - display: flex; - flex-wrap: wrap; - width: 176px; - gap: 4px; - margin-bottom: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container { - width: 56px; - white-space: nowrap; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container { - display: flex; - justify-content: space-evenly; - gap: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container .trait-container { - border: 1px solid light-dark(#18162e, #f3c267); - padding: 0 4px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container { - display: flex; - justify-content: space-evenly; - text-align: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-description { - border-color: light-dark(#18162e, #f3c267); - padding-right: 24px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-value { - position: absolute; - right: 0; - width: 22px; - border-left: 1px solid light-dark(#18162e, #f3c267); - height: 100%; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav { - flex: 1; - gap: 8px; - border: 0; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .nav-section-text { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker { - position: absolute; - align-self: center; - top: -10px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 20px; - width: 20px; - font-size: 14px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker.finished { - background-color: var(--color-warm-2); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section button { - flex: 1; - height: 100%; - white-space: nowrap; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection.triple { - grid-template-columns: 1fr 1fr 1fr; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - white-space: nowrap; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-subsection { - display: flex; - align-items: start; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container { - display: flex; - flex-direction: column; - justify-content: space-evenly; - gap: 8px; - height: 100%; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment { - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 8px; - position: relative; - display: flex; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.selectable { - cursor: pointer; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.inactive { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { - position: absolute; - top: -8px; - font-size: 12px; - white-space: nowrap; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); - padding: 0 2px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment img { - width: 60px; - height: 60px; - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container { - position: relative; - display: flex; - justify-content: center; - height: min-content; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container { - position: relative; - display: flex; - justify-content: center; - align-items: center; - padding: 6px; - cursor: grab; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container.taken { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container label { - position: absolute; - top: -2px; - font-size: 12px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container img { - width: 120px; -} -.daggerheart.dh-style.dialog.character-creation .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .creation-action-footer button { - flex: 1; - height: 100%; - white-space: nowrap; -} -.theme-light .daggerheart.levelup .tiers-container .tier-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.daggerheart.levelup .window-content { - max-height: 960px; - overflow: auto; -} -.daggerheart.levelup div[data-application-part='form'] { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup section .section-container { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: 8px; -} -.daggerheart.levelup .levelup-navigation-container { - display: flex; - align-items: center; - gap: 22px; - height: 36px; -} -.daggerheart.levelup .levelup-navigation-container nav { - flex: 1; -} -.daggerheart.levelup .levelup-navigation-container nav .levelup-tab-container { - display: flex; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions { - width: 306px; - display: flex; - justify-content: end; - gap: 16px; - margin-right: 4px; -} -.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions * { - width: calc(50% - 8px); -} -.daggerheart.levelup .tiers-container { - display: flex; - gap: 16px; -} -.daggerheart.levelup .tiers-container .tier-container { - flex: 1; - display: flex; - flex-direction: column; - gap: 8px; - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.levelup .tiers-container .tier-container.inactive { - opacity: 0.4; - pointer-events: none; -} -.daggerheart.levelup .tiers-container .tier-container legend { - margin-left: auto; - margin-right: auto; - font-size: 22px; - font-weight: bold; - padding: 0 12px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container { - display: grid; - grid-template-columns: 1fr 3fr; - gap: 4px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container { - display: flex; - justify-content: end; - gap: 4px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer { - display: flex; - height: min-content; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi { - border: 2px solid grey; - padding: 2.4px 2.5px 0; - border-radius: 4px; - gap: 2px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi .selection-checkbox { - margin-left: 0; - margin-right: 0; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer .selection-checkbox { - margin: 0; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkbox-group-label { - font-size: 14px; - font-style: italic; -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card { - border: 1px solid; - border-radius: 4px; - padding-right: 4px; - font-size: 18px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card .achievement-experience-marker { - border: 1px solid; - border-radius: 50%; - height: 18px; - width: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection { - display: flex; - flex-wrap: wrap; - gap: 40px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .card-preview-container { - width: calc(100% * (1 / 5)); -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container { - display: flex; - flex-direction: column; - align-items: center; - flex: 1; - position: relative; - cursor: pointer; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container.disabled { - pointer-events: none; - opacity: 0.4; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-label { - position: absolute; - text-align: center; - top: 4px; - background: grey; - padding: 0 12px; - border-radius: 6px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container img { - height: 124px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected { - position: absolute; - height: 54px; - width: 54px; - border-radius: 50%; - border: 2px solid; - font-size: 48px; - display: flex; - align-items: center; - justify-content: center; - background-image: url(../assets/parchments/dh-parchment-light.png); - color: var(--color-dark-5); - top: calc(50% - 29px); -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected i { - position: relative; - right: 2px; -} -.daggerheart.levelup .levelup-selections-container .levelup-selections-title { - display: flex; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-selections-container .levelup-radio-choices { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .levelup-radio-choices label { - flex: 0; -} -.daggerheart.levelup .levelup-summary-container .level-achievements-container, -.daggerheart.levelup .levelup-summary-container .level-advancements-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup .levelup-summary-container .level-achievements-container h2, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h2, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h3, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h3, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h4, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h4, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h5, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h5 { - margin: 0; - color: var(--color-text-secondary); -} -.daggerheart.levelup .levelup-summary-container .increase-container { - display: flex; - align-items: center; - gap: 4px; - font-size: 20px; -} -.daggerheart.levelup .levelup-summary-container .summary-selection-container { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-summary-container .summary-selection-container .summary-selection { - border: 2px solid; - border-radius: 6px; - padding: 0 4px; - font-size: 18px; -} -.daggerheart.levelup .levelup-footer { - display: flex; -} -.daggerheart.views.ownership-selection .ownership-outer-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container { - display: flex; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - padding: 0 4px 0 0; - align-items: center; - gap: 8px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container img { - height: 40px; - width: 40px; - border-radius: 6px 0 0 6px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container select { - margin: 4px 0; -} -.daggerheart.views.damage-reduction .window-content { - padding: 8px 0; -} -.daggerheart.views.damage-reduction .damage-reduction-container { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .section-container { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .padded { - padding: 0 8px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .armor-title { - margin: 0; - white-space: nowrap; -} -.daggerheart.views.damage-reduction .damage-reduction-container .resources-container { - display: flex; - gap: 8px; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .resources-container .resource-container { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection { - display: flex; - align-items: center; - width: 100%; - margin: 0; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner { - display: flex; - gap: 2px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner:not(:last-child) { - margin-right: 8px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container { - cursor: pointer; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - height: 26px; - padding: 0 1px; - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - opacity: 0.4; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.selected { - opacity: 1; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.inactive { - cursor: initial; - opacity: 0.2; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container .fa-shield { - position: relative; - right: 0.5px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container { - margin: 0; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction { - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - height: 26px; - padding: 0 4px; - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - opacity: 0.4; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.active { - opacity: 1; - cursor: pointer; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.selected { - opacity: 1; - background: var(--color-warm-2); - color: white; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction .stress-reduction-cost { - display: flex; - align-items: center; -} -.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle { - margin: -4px 0 0 0; -} -.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle.bold { - font-variant: all-small-caps; - font-weight: bold; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer { - display: flex; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button { - flex: 1; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value { - font-weight: bold; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value.reduced-value { - opacity: 0.4; - text-decoration: line-through; -} -:root { - --shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; - --fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease; -} -#resources { - min-height: calc(var(--header-height) + 4rem); - min-width: 4rem; - color: #d3d3d3; - transition: var(--fear-animation); -} -#resources header, -#resources .controls, -#resources .window-resize-handle { - transition: var(--fear-animation); -} -#resources .window-content { - padding: 0.5rem; -} -#resources .window-content #resource-fear { - display: flex; - flex-direction: row; - gap: 0.5rem 0.25rem; - flex-wrap: wrap; -} -#resources .window-content #resource-fear i { - font-size: var(--font-size-18); - border: 1px solid rgba(0, 0, 0, 0.5); - border-radius: 50%; - aspect-ratio: 1; - display: flex; - justify-content: center; - align-items: center; - width: 3rem; - background-color: rgba(9, 71, 179, 0.75); - -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); - box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); - color: #d3d3d3; - flex-grow: 0; -} -#resources .window-content #resource-fear i.inactive { - filter: grayscale(1) !important; - opacity: 0.5; -} -#resources .window-content #resource-fear .controls, -#resources .window-content #resource-fear .resource-bar { - border: 2px solid #997a4f; - background-color: #18162e; -} -#resources .window-content #resource-fear .controls { - display: flex; - align-self: center; - border-radius: 50%; - align-items: center; - justify-content: center; - width: 30px; - height: 30px; - font-size: var(--font-size-20); - cursor: pointer; -} -#resources .window-content #resource-fear .controls:hover { - font-size: 1.5rem; -} -#resources .window-content #resource-fear .controls.disabled { - opacity: 0.5; -} -#resources .window-content #resource-fear .resource-bar { - display: flex; - justify-content: center; - border-radius: 6px; - font-size: var(--font-size-20); - overflow: hidden; - position: relative; - padding: 0.25rem 0.5rem; - flex: 1; - text-shadow: var(--shadow-text-stroke); -} -#resources .window-content #resource-fear .resource-bar:before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: var(--fear-percent); - max-width: 100%; - background: linear-gradient(90deg, #020026 0%, #c701fc 100%); - z-index: 0; - border-radius: 4px; -} -#resources .window-content #resource-fear .resource-bar span { - position: inherit; - z-index: 1; -} -#resources .window-content #resource-fear.isGM i { - cursor: pointer; -} -#resources .window-content #resource-fear.isGM i:hover { - font-size: var(--font-size-20); -} -#resources button[data-action='close'] { - display: none; -} -#resources:not(:hover):not(.minimized) { - background: transparent; - box-shadow: unset; - border-color: transparent; -} -#resources:not(:hover):not(.minimized) header, -#resources:not(:hover):not(.minimized) .controls, -#resources:not(:hover):not(.minimized) .window-resize-handle { - opacity: 0; -} -#resources:has(.fear-bar) { - min-width: 200px; -} -.theme-light .daggerheart.dh-style.countdown .minimized-view .mini-countdown-container { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.dh-style.countdown { - overflow: hidden; -} -.daggerheart.dh-style.countdown fieldset { - align-items: center; - margin-top: 5px; - border-radius: 6px; - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.countdown fieldset legend { - font-family: 'Montserrat', sans-serif; - font-weight: bold; - color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.countdown fieldset legend a { - text-shadow: none; -} -.daggerheart.dh-style.countdown .minimized-view { - display: flex; - gap: 8px; - flex-wrap: wrap; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container { - width: fit-content; - display: flex; - align-items: center; - gap: 8px; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - padding: 0 4px 0 0; - background-image: url('../assets/parchments/dh-parchment-light.png'); - color: light-dark(#efe6d8, #222); - cursor: pointer; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container.disabled { - cursor: initial; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container img { - width: 30px; - height: 30px; - border-radius: 6px 0 0 6px; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container .mini-countdown-name { - white-space: nowrap; -} -.daggerheart.dh-style.countdown .hidden { - display: none; -} -.daggerheart.dh-style.countdown .window-content > div { - height: 100%; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view { - height: 100%; - display: flex; - flex-direction: column; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu { - display: flex; - gap: 8px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu .flex { - flex: 1; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container { - display: flex; - gap: 8px; - flex-wrap: wrap; - overflow: auto; - max-height: 100%; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset { - width: 340px; - height: min-content; - position: relative; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .ownership-button { - position: absolute; - top: 8px; - right: 8px; - font-size: 18px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container { - display: flex; - align-items: center; - gap: 16px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img { - width: 150px; - height: 150px; - cursor: pointer; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img.disabled { - cursor: initial; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container { - display: flex; - gap: 4px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container input { - max-width: 80px; -} -.daggerheart.dh-style.setting fieldset { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.setting fieldset.two-columns { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 10px; -} -.daggerheart.dh-style.setting fieldset.two-columns.even { - grid-template-columns: 1fr 1fr; -} -.daggerheart.dh-style.setting .setting-group-field { - white-space: nowrap; - display: flex; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item { - display: flex; - align-items: center; - justify-content: space-between; - border: 1px solid; - border-radius: 8px; - padding: 0 8px 0 0; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item { - display: flex; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item img { - width: 60px; - border-radius: 8px 0 0 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item i { - font-size: 18px; -} -.daggerheart.dh-style.setting .settings-item-header { - display: flex; - align-items: center; -} -.daggerheart.dh-style.setting .settings-item-header .profile { - height: 100px; - width: 100px; - object-fit: cover; - box-sizing: border-box; - cursor: pointer; -} -.daggerheart.dh-style.setting .settings-item-header .item-info { - display: flex; - flex-direction: column; - align-items: center; - gap: 5px; - text-align: center; - width: 80%; -} -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: center; - width: 90%; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; -} -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:hover[type='text'], -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.setting .settings-col { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.setting .trait-array-container { - display: flex; - justify-content: space-evenly; - gap: 8px; - margin-bottom: 16px; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item { - position: relative; - display: flex; - justify-content: center; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item label { - position: absolute; - top: -7px; - font-size: 12px; - font-variant: petite-caps; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item input { - text-align: center; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-header-sheet .trait, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-header-sheet .trait, -body.theme-dark .application.daggerheart .character-header-sheet .trait, -body.theme-dark.application.daggerheart .character-header-sheet .trait { - background: url(../assets/svg/trait-shield.svg) no-repeat; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-header-sheet .trait, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-header-sheet .trait, -body.theme-light .application.daggerheart .character-header-sheet .trait, -body.theme-light.application.daggerheart .character-header-sheet .trait { - background: url('../assets/svg/trait-shield-light.svg') no-repeat; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet { - padding: 0 15px; - padding-top: 36px; - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row { - display: flex; - gap: 5px; - align-items: center; - justify-content: space-between; - padding: 0; - padding-top: 5px; - flex: 1; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - border: 1px solid transparent; - outline: 2px solid transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text']:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div { - white-space: nowrap; - display: flex; - justify-content: end; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .label { - display: flex; - align-items: center; - gap: 4px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div input { - width: 40px; - padding: 0; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button { - color: light-dark(#222, #efe6d8); - font-size: 18px; - line-height: 1; - min-height: unset; - height: min-content; - padding: 4px; - font-family: 'Cinzel', serif; - margin: 0; - font-weight: normal; - border-color: light-dark(#18162e, #f3c267); - background-color: light-dark(transparent, #0e0d15); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button:hover { - background-image: none; - background-color: var(--color-warm-2); - filter: drop-shadow(0 0 3px lightgray); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details { - display: flex; - justify-content: space-between; - padding: 5px 0; - margin-bottom: 10px; - font-size: 12px; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span { - padding: 3px; - border-radius: 3px; - transition: all 0.3s ease; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span:hover { - background: light-dark(#18162e40, #f3c26740); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span.dot { - background: transparent; - cursor: default; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row { - display: flex; - gap: 20px; - align-items: center; - justify-content: space-between; - padding: 0; - margin-bottom: 15px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section { - position: relative; - display: flex; - gap: 10px; - background-color: light-dark(transparent, #18162e); - color: light-dark(#18162e, #f3c267); - padding: 5px 10px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - align-items: center; - width: fit-content; - height: 30px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4 { - font-size: 14px; - font-weight: bold; - text-transform: uppercase; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4.threshold-value, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4.threshold-value { - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .threshold-legend, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .threshold-legend { - position: absolute; - bottom: -21px; - color: light-dark(#f3c267, #18162e); - background-color: light-dark(#18162e, #f3c267); - padding: 3px; - justify-self: anchor-center; - border-radius: 0 0 3px 3px; - text-transform: capitalize; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .hope-value, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .hope-value { - display: flex; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits { - display: flex; - justify-content: space-between; - padding: 0; - margin-bottom: 15px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait { - height: 60px; - width: 60px; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name { - display: flex; - padding-top: 5px; - color: light-dark(#18162e, #f3c267); - font-size: 14px; - font-weight: 600; - align-items: center; - justify-content: center; - gap: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name i { - line-height: 17px; - font-size: 10px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-value { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 20px; - text-align: center; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet, -body.theme-dark .application.daggerheart .character-sidebar-sheet, -body.theme-dark.application.daggerheart .character-sidebar-sheet { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-dark .application.daggerheart .character-sidebar-sheet .experience-value, -body.theme-dark.application.daggerheart .character-sidebar-sheet .experience-value { - background: url(../assets/svg/experience-shield.svg) no-repeat; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet, -body.theme-light .application.daggerheart .character-sidebar-sheet, -body.theme-light.application.daggerheart .character-sidebar-sheet { - background: transparent; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-light .application.daggerheart .character-sidebar-sheet .experience-value, -body.theme-light.application.daggerheart .character-sidebar-sheet .experience-value { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; -} -.application.sheet.dh-style .character-sidebar-sheet { - width: 275px; - min-width: 275px; - border-right: 1px solid light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .portrait { - position: relative; - border-bottom: 1px solid light-dark(#18162e, #f3c267); - cursor: pointer; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait img { - height: 235px; - width: 275px; - object-fit: cover; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait .death-roll-btn { - display: none; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll { - filter: grayscale(1); -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn { - display: flex; - position: absolute; - top: 30%; - right: 30%; - font-size: 6rem; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn:hover { - text-shadow: 0 0 8px #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section { - position: relative; - display: flex; - flex-direction: column; - top: -20px; - gap: 30px; - margin-bottom: -10px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section { - display: flex; - justify-content: space-evenly; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar { - position: relative; - width: 100px; - height: 40px; - justify-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input { - padding: 0; - color: #efe6d8; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:hover, -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:focus { - background: rgba(24, 22, 46, 0.33); - backdrop-filter: blur(9.5px); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value .bar-label { - width: 40px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - z-index: 1; - background: #18162e; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-bar { - border: none; - background: #18162e; - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-value { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-webkit-progress-value { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-moz-progress-bar { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section { - display: flex; - flex-wrap: wrap; - gap: 5px; - justify-content: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number { - justify-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(#18162e, #f3c267); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, #18162e); - z-index: 2; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value.armor-slots { - width: 80px; - height: 30px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list { - display: flex; - flex-direction: column; - gap: 5px; -} -.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list .inventory-item { - padding: 0 10px; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text'] { - height: 32px; - width: 180px; - border: 1px solid transparent; - outline: 2px solid transparent; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - transition: all 0.3s ease; - color: light-dark(#222, #efe6d8); -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text']:hover { - outline: 2px solid light-dark(#222, #efe6d8); -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); - align-content: center; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content { - display: grid; - grid-template-columns: 275px 1fr; - grid-template-rows: auto 1fr; - gap: 15px 0; - height: 100%; - width: 100%; - overflow: auto; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .character-sidebar-sheet { - grid-row: 1 / span 2; - grid-column: 1; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .character-header-sheet { - grid-row: 1; - grid-column: 2; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .tab { - grid-row: 2; - grid-column: 2; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section { - display: flex; - gap: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar { - position: relative; - color: light-dark(#18162e50, #efe6d850); - width: 100%; - padding-top: 5px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input { - border-radius: 50px; - font-family: 'Montserrat', sans-serif; - background: light-dark(#18162e10, #f3c26710); - border: none; - outline: 2px solid transparent; - transition: all 0.3s ease; - padding: 0 20px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder { - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input::-webkit-search-cancel-button { - -webkit-appearance: none; - display: none; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon { - align-content: center; - height: 32px; - position: absolute; - right: 20px; - font-size: 16px; - z-index: 1; - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .items-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - padding: 20px 0; - height: 80%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .currency-section { - display: flex; - gap: 10px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section { - display: flex; - align-items: center; - justify-content: space-between; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar { - position: relative; - color: light-dark(#18162e50, #efe6d850); - width: 80%; - padding-top: 5px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input { - border-radius: 50px; - font-family: 'Montserrat', sans-serif; - background: light-dark(#18162e10, #f3c26710); - border: none; - outline: 2px solid transparent; - transition: all 0.3s ease; - padding: 0 20px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:placeholder { - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input::-webkit-search-cancel-button { - -webkit-appearance: none; - display: none; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar .icon { - align-content: center; - height: 32px; - position: absolute; - right: 20px; - font-size: 16px; - z-index: 1; - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view { - background: light-dark(#18162e10, #18162e); - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 15px; - padding: 0; - gap: 0; - width: 62px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span { - margin: 1px; - width: 26px; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-icon i { - margin-left: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-icon i { - margin-right: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-active { - border-radius: 32px 3px 3px 32px; - background-color: light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #18162e); - padding: 2px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-active { - border-radius: 3px 32px 32px 3px; - background-color: light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #18162e); - padding: 2px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .items-section { - display: flex; - flex-direction: column; - gap: 10px; - height: 100%; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); - padding: 20px 0; - height: 90%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.biography .items-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); - padding-bottom: 40px; - height: 100%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.features .features-sections { +.application.sheet.daggerheart.actor.dh-style.adversary .tab.features .feature-section { display: flex; flex-direction: column; gap: 10px; @@ -4331,14 +96,27 @@ body.theme-light.application.daggerheart .character-sidebar-sheet .experience-va grid-row: 2; grid-column: 2; } +/** + * Applies theme-specific styles. + * @param {Rules} @darkRules - Styles to apply when `.theme-dark` is present + * @param {Rules} @lightRules - Styles to apply when `.theme-light` is present + */ +.themed.theme-dark .application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, +.themed.theme-dark.application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, +body.theme-dark .application.daggerheart.adversary .adversary-sidebar-sheet, +body.theme-dark.application.daggerheart.adversary .adversary-sidebar-sheet { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.themed.theme-light .application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, +.themed.theme-light.application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, +body.theme-light .application.daggerheart.adversary .adversary-sidebar-sheet, +body.theme-light.application.daggerheart.adversary .adversary-sidebar-sheet { + background: transparent; +} .application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet { width: 275px; min-width: 275px; border-right: 1px solid light-dark(#18162e, #f3c267); - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.theme-light .application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet { - background: transparent; } .application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait { position: relative; @@ -4623,61 +401,525 @@ body.theme-light.application.daggerheart .character-sidebar-sheet .experience-va .application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .reaction-section button { width: 100%; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet { +.application.sheet.daggerheart.actor.dh-style.character .tab.biography .items-section { display: flex; flex-direction: column; - justify-content: start; + gap: 10px; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); + padding-bottom: 40px; + height: 100%; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.features .features-sections { + display: flex; + flex-direction: column; + gap: 10px; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); + padding: 20px 0; + padding-top: 10px; + height: 95%; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-header-sheet .trait, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-header-sheet .trait, +body.theme-dark .application.daggerheart .character-header-sheet .trait, +body.theme-dark.application.daggerheart .character-header-sheet .trait { + background: url(../assets/svg/trait-shield.svg) no-repeat; +} +.themed.theme-light .application.daggerheart.sheet.dh-style .character-header-sheet .trait, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-header-sheet .trait, +body.theme-light .application.daggerheart .character-header-sheet .trait, +body.theme-light.application.daggerheart .character-header-sheet .trait { + background: url('../assets/svg/trait-shield-light.svg') no-repeat; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet { + padding: 0 15px; + padding-top: 36px; + width: 100%; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row { + display: flex; + gap: 5px; + align-items: center; + justify-content: space-between; + padding: 0; + padding-top: 5px; + flex: 1; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text'] { + font-size: 32px; + height: 42px; + text-align: start; + border: 1px solid transparent; + outline: 2px solid transparent; + transition: all 0.3s ease; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text']:hover { + outline: 2px solid light-dark(#222, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div { + white-space: nowrap; + display: flex; + justify-content: end; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .label { + display: flex; + align-items: center; + gap: 4px; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div input { + width: 40px; + padding: 0; text-align: center; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .profile { - width: 100%; - height: 235px; - object-fit: cover; - mask-image: linear-gradient(0deg, transparent 0%, black 10%); +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button { + color: light-dark(#222, #efe6d8); + font-size: 18px; + line-height: 1; + min-height: unset; + height: min-content; + padding: 4px; + font-family: 'Cinzel', serif; + margin: 0; + font-weight: normal; + border-color: light-dark(#18162e, #f3c267); + background-color: light-dark(transparent, #0e0d15); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button:hover { + background-image: none; + background-color: var(--color-warm-2); + filter: drop-shadow(0 0 3px lightgray); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details { + display: flex; + justify-content: space-between; + padding: 5px 0; + margin-bottom: 10px; + font-size: 12px; + color: light-dark(#18162e, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span { + padding: 3px; + border-radius: 3px; + transition: all 0.3s ease; cursor: pointer; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container { +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span:hover { + background: light-dark(#18162e40, #f3c26740); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span.dot { + background: transparent; + cursor: default; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row { display: flex; - align-items: center; - position: relative; - top: -45px; gap: 20px; - padding: 0 20px; - margin-bottom: -30px; + align-items: center; + justify-content: space-between; + padding: 0; + margin-bottom: 15px; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info { - display: flex; - flex-direction: column; - gap: 8px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags { +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section, +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section { + position: relative; display: flex; gap: 10px; - padding-bottom: 0; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .tag { - display: flex; - flex-direction: row; - justify-content: center; + background-color: light-dark(transparent, #18162e); + color: light-dark(#18162e, #f3c267); + padding: 5px 10px; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; align-items: center; - padding: 3px 5px; - font-size: 12px; - font: 'Montserrat', sans-serif; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; + width: fit-content; + height: 30px; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .label { +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4, +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4 { + font-size: 14px; + font-weight: bold; + text-transform: uppercase; + color: light-dark(#18162e, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4.threshold-value, +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4.threshold-value { + color: light-dark(#222, #efe6d8); +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .threshold-legend, +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .threshold-legend { + position: absolute; + bottom: -21px; + color: light-dark(#f3c267, #18162e); + background-color: light-dark(#18162e, #f3c267); + padding: 3px; + justify-self: anchor-center; + border-radius: 0 0 3px 3px; + text-transform: capitalize; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .hope-value, +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .hope-value { display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; + cursor: pointer; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number { +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits { + display: flex; + justify-content: space-between; + padding: 0; + margin-bottom: 15px; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait { + height: 60px; + width: 60px; + cursor: pointer; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name { + display: flex; + padding-top: 5px; + color: light-dark(#18162e, #f3c267); + font-size: 14px; + font-weight: 600; + align-items: center; + justify-content: center; + gap: 3px; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name i { + line-height: 17px; + font-size: 10px; +} +.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-value { + font-family: 'Montserrat', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 20px; + text-align: center; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section { + display: flex; + gap: 10px; + align-items: center; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar { + position: relative; + color: light-dark(#18162e50, #efe6d850); + width: 100%; + padding-top: 5px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input { + border-radius: 50px; + font-family: 'Montserrat', sans-serif; + background: light-dark(#18162e10, #f3c26710); + border: none; + outline: 2px solid transparent; + transition: all 0.3s ease; + padding: 0 20px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:hover { + outline: 2px solid light-dark(#222, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder { + color: light-dark(#18162e50, #efe6d850); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input::-webkit-search-cancel-button { + -webkit-appearance: none; + display: none; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon { + align-content: center; + height: 32px; + position: absolute; + right: 20px; + font-size: 16px; + z-index: 1; + color: light-dark(#18162e50, #efe6d850); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .items-section { + display: flex; + flex-direction: column; + gap: 10px; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); + padding: 20px 0; + height: 80%; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .currency-section { + display: flex; + gap: 10px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section { + display: flex; + align-items: center; + justify-content: space-between; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar { + position: relative; + color: light-dark(#18162e50, #efe6d850); + width: 80%; + padding-top: 5px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input { + border-radius: 50px; + font-family: 'Montserrat', sans-serif; + background: light-dark(#18162e10, #f3c26710); + border: none; + outline: 2px solid transparent; + transition: all 0.3s ease; + padding: 0 20px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:hover { + outline: 2px solid light-dark(#222, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:placeholder { + color: light-dark(#18162e50, #efe6d850); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input::-webkit-search-cancel-button { + -webkit-appearance: none; + display: none; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar .icon { + align-content: center; + height: 32px; + position: absolute; + right: 20px; + font-size: 16px; + z-index: 1; + color: light-dark(#18162e50, #efe6d850); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view { + background: light-dark(#18162e10, #18162e); + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 15px; + padding: 0; + gap: 0; + width: 62px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span { + margin: 1px; + width: 26px; + color: light-dark(#18162e, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-icon i { + margin-left: 3px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-icon i { + margin-right: 3px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-active { + border-radius: 32px 3px 3px 32px; + background-color: light-dark(#18162e, #f3c267); + color: light-dark(#efe6d8, #18162e); + padding: 2px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-active { + border-radius: 3px 32px 32px 3px; + background-color: light-dark(#18162e, #f3c267); + color: light-dark(#efe6d8, #18162e); + padding: 2px; +} +.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .items-section { + display: flex; + flex-direction: column; + gap: 10px; + height: 100%; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); + padding: 20px 0; + height: 90%; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.sheet.daggerheart.actor.dh-style.character .window-content { + display: grid; + grid-template-columns: 275px 1fr; + grid-template-rows: auto 1fr; + gap: 15px 0; + height: 100%; + width: 100%; + overflow: auto; +} +.application.sheet.daggerheart.actor.dh-style.character .window-content .character-sidebar-sheet { + grid-row: 1 / span 2; + grid-column: 1; +} +.application.sheet.daggerheart.actor.dh-style.character .window-content .character-header-sheet { + grid-row: 1; + grid-column: 2; +} +.application.sheet.daggerheart.actor.dh-style.character .window-content .tab { + grid-row: 2; + grid-column: 2; +} +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet, +body.theme-dark .application.daggerheart .character-sidebar-sheet, +body.theme-dark.application.daggerheart .character-sidebar-sheet { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +body.theme-dark .application.daggerheart .character-sidebar-sheet .experience-value, +body.theme-dark.application.daggerheart .character-sidebar-sheet .experience-value { + background: url(../assets/svg/experience-shield.svg) no-repeat; +} +.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet, +body.theme-light .application.daggerheart .character-sidebar-sheet, +body.theme-light.application.daggerheart .character-sidebar-sheet { + background: transparent; +} +.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +body.theme-light .application.daggerheart .character-sidebar-sheet .experience-value, +body.theme-light.application.daggerheart .character-sidebar-sheet .experience-value { + background: url('../assets/svg/experience-shield-light.svg') no-repeat; +} +.application.sheet.dh-style .character-sidebar-sheet { + width: 275px; + min-width: 275px; + border-right: 1px solid light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style .character-sidebar-sheet .portrait { + position: relative; + border-bottom: 1px solid light-dark(#18162e, #f3c267); + cursor: pointer; +} +.application.sheet.dh-style .character-sidebar-sheet .portrait img { + height: 235px; + width: 275px; + object-fit: cover; +} +.application.sheet.dh-style .character-sidebar-sheet .portrait .death-roll-btn { + display: none; +} +.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll { + filter: grayscale(1); +} +.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn { + display: flex; + position: absolute; + top: 30%; + right: 30%; + font-size: 6rem; + color: #efe6d8; +} +.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn:hover { + text-shadow: 0 0 8px #efe6d8; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section { + position: relative; + display: flex; + flex-direction: column; + top: -20px; + gap: 30px; + margin-bottom: -10px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section { + display: flex; + justify-content: space-evenly; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar { + position: relative; + width: 100px; + height: 40px; justify-items: center; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value { +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label { + position: relative; + top: 40px; + height: 22px; + width: 79px; + clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); + background: light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + color: light-dark(#efe6d8, #18162e); +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value { + position: absolute; + display: flex; + padding: 0 6px; + font-size: 1.5rem; + align-items: center; + width: 100px; + height: 40px; + justify-content: center; + text-align: center; + z-index: 2; + color: #efe6d8; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'] { + background: transparent; + font-size: 1.5rem; + width: 40px; + height: 30px; + text-align: center; + border: none; + outline: 2px solid transparent; + color: #efe6d8; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input { + padding: 0; + color: #efe6d8; + backdrop-filter: none; + background: transparent; + transition: all 0.3s ease; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:hover, +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:focus { + background: rgba(24, 22, 46, 0.33); + backdrop-filter: blur(9.5px); +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value .bar-label { + width: 40px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar { + position: absolute; + appearance: none; + width: 100px; + height: 40px; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + z-index: 1; + background: #18162e; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-bar { + border: none; + background: #18162e; + border-radius: 6px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-value { + background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); + border-radius: 6px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-webkit-progress-value { + background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); + border-radius: 6px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar { + background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); + border-radius: 6px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-moz-progress-bar { + background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); + border-radius: 6px; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section { + display: flex; + flex-wrap: wrap; + gap: 5px; + justify-content: center; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number { + justify-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value { position: relative; display: flex; width: 50px; @@ -4692,272 +934,162 @@ body.theme-light.application.daggerheart .character-sidebar-sheet .experience-va background: light-dark(transparent, #18162e); z-index: 2; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value.armor-slots { +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value.armor-slots { width: 80px; height: 30px; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label { +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label { padding: 2px 10px; width: 100%; border-radius: 3px; background: light-dark(#18162e, #f3c267); } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label h4 { +.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label h4 { font-weight: bold; text-align: center; line-height: 18px; font-size: 12px; color: light-dark(#efe6d8, #18162e); } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - transition: all 0.3s ease; - outline: 2px solid transparent; +.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list { + display: flex; + flex-direction: column; + gap: 5px; +} +.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list .inventory-item { + padding: 0 10px; +} +.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title { + display: flex; + gap: 15px; + align-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title h3 { + font-size: 20px; +} +.application.sheet.dh-style .character-sidebar-sheet .equipment-section .items-list { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title { + display: flex; + gap: 15px; + align-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title h3 { + font-size: 20px; +} +.application.sheet.dh-style .character-sidebar-sheet .experience-section .title { + display: flex; + gap: 15px; + align-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .experience-section .title h3 { + font-size: 20px; +} +.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list { + display: flex; + flex-direction: column; + gap: 5px; + width: 100%; + margin-top: 10px; + align-items: center; +} +.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row { + display: flex; + gap: 5px; + width: 250px; + align-items: center; + justify-content: space-between; +} +.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text'] { + height: 32px; + width: 180px; border: 1px solid transparent; + outline: 2px solid transparent; + font-size: 14px; + font-family: 'Montserrat', sans-serif; + transition: all 0.3s ease; + color: light-dark(#222, #efe6d8); } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:hover[type='text'], -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); +.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text']:hover { + outline: 2px solid light-dark(#222, #efe6d8); } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info { +.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-value { + height: 25px; + width: 35px; + font-size: 14px; + font-family: 'Montserrat', sans-serif; + color: light-dark(#222, #efe6d8); + align-content: center; + text-align: center; +} +.application.sheet.daggerheart.actor.dh-style.companion .partner-section, +.application.sheet.daggerheart.actor.dh-style.companion .attack-section { display: flex; flex-direction: column; - gap: 12px; - padding: 10px 20px; + align-items: center; } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .description, -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .impulses { +.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title, +.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title { + display: flex; + gap: 15px; + align-items: center; +} +.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title h3, +.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title h3 { + font-size: 20px; +} +.application.sheet.daggerheart.actor.dh-style.companion .partner-section .items-list, +.application.sheet.daggerheart.actor.dh-style.companion .attack-section .items-list { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} +.application.sheet.daggerheart.actor.dh-style.companion .partner-placeholder { + display: flex; + opacity: 0.6; + text-align: center; + font-style: italic; + justify-content: center; +} +.application.sheet.daggerheart.actor.dh-style.companion .experience-list { + display: flex; + flex-direction: column; + gap: 5px; + width: 100%; + margin-top: 10px; + align-items: center; +} +.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row { + display: flex; + gap: 5px; + width: 250px; + align-items: center; + justify-content: space-between; +} +.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row .experience-name { + width: 180px; text-align: start; + font-size: 14px; font-family: 'Montserrat', sans-serif; + color: light-dark(#222, #efe6d8); } -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-navigation { - display: flex; - gap: 20px; - align-items: center; - padding: 0 20px; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style.environment, -.themed.theme-dark.application.daggerheart.sheet.dh-style.environment, -body.theme-dark .application.daggerheart.environment, -body.theme-dark.application.daggerheart.environment { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-light .application.daggerheart.sheet.dh-style.environment, -.themed.theme-light.application.daggerheart.sheet.dh-style.environment, -body.theme-light .application.daggerheart.environment, -body.theme-light.application.daggerheart.environment { - background: url('../assets/parchments/dh-parchment-light.png'); -} -.application.sheet.daggerheart.actor.dh-style.environment .tab { - max-height: 300px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .window-content .dialog-header { - width: 100%; - padding-bottom: 16px; -} -.application.daggerheart.dh-style.dialog .window-content .dialog-header h1 { - font-family: 'Cinzel', serif; - font-style: normal; - font-weight: 700; - font-size: 24px; - margin: 0; - text-align: center; - color: light-dark(#18162e, #f3c267); -} -.application.daggerheart.dh-style.dialog .tab.details.active, -.application.daggerheart.dh-style.dialog .tab.attack.active { - display: flex; - flex-direction: column; - gap: 16px; -} -.application.daggerheart.dh-style.dialog .tab .fieldsets-section { - display: flex; - gap: 16px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .add-experience-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item { - display: grid; - grid-template-columns: 3fr 1fr 30px; - align-items: center; - gap: 5px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item a { - text-align: center; -} -.application.daggerheart.dh-style.dialog .tab.features { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .tab.features .add-feature-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item img { - height: 40px; - width: 40px; - object-fit: cover; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .label { +.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { + height: 25px; + width: 35px; + font-size: 14px; font-family: 'Montserrat', sans-serif; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls { - display: flex; - gap: 5px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls a { + color: light-dark(#222, #efe6d8); + align-content: center; text-align: center; + background: url(../assets/svg/experience-shield.svg) no-repeat; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.features { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .add-feature-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item img { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .label { - font-family: 'Montserrat', sans-serif; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls { - display: flex; - gap: 5px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls a { - text-align: center; -} -.application.daggerheart.dh-style.dialog .tab.adversaries { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .add-action-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container { - display: flex; - flex-direction: column; - align-items: start; - gap: 8px; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .category-name { - display: flex; - align-items: center; - gap: 10px; - width: 100%; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .adversaries-container { - display: flex; - flex-direction: column; - gap: 6px; - width: 100%; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .adversaries-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - border: 1px dashed light-dark(#18162e50, #efe6d850); - border-radius: 3px; - color: light-dark(#18162e50, #efe6d850); - font-family: 'Montserrat', sans-serif; -} -.theme-light .application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - gap: 4px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container { - position: relative; - display: flex; - justify-content: center; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - cursor: pointer; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container.inactive { - opacity: 0.4; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container img { - width: 100%; - border-radius: 6px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { - position: absolute; - top: 4px; - display: flex; - flex-wrap: wrap; - font-size: 16px; - margin: 0 4px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.application.daggerheart.dh-style.views.beastform-selection footer { - margin-top: 8px; - display: flex; -} -.application.daggerheart.dh-style.views.beastform-selection footer button { - flex: 1; +.theme-light .application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { + background: url('../assets/svg/experience-shield-light.svg') no-repeat; } .application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet { display: flex; @@ -5131,71 +1263,6 @@ body.theme-light.application.daggerheart.environment { align-items: center; width: 100%; } -.application.sheet.daggerheart.actor.dh-style.companion .partner-section, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section { - display: flex; - flex-direction: column; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title h3, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title h3 { - font-size: 20px; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .items-list, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-placeholder { - display: flex; - opacity: 0.6; - text-align: center; - font-style: italic; - justify-content: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row .experience-name { - width: 180px; - text-align: start; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); - align-content: center; - text-align: center; - background: url(../assets/svg/experience-shield.svg) no-repeat; -} -.theme-light .application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; -} .themed.theme-dark .application.daggerheart.sheet.dh-style.companion, .themed.theme-dark.application.daggerheart.sheet.dh-style.companion, body.theme-dark .application.daggerheart.companion, @@ -5208,46 +1275,136 @@ body.theme-light .application.daggerheart.companion, body.theme-light.application.daggerheart.companion { background: url('../assets/parchments/dh-parchment-light.png'); } -.application.sheet.daggerheart.actor.dh-style.adversary .window-content { - overflow: auto; -} -.daggerheart.sheet.actor.environment .potential-adversary-container { - width: 100%; - height: 50px; -} -.daggerheart.sheet.actor.environment .potential-adversary-container .adversary-placeholder { - font-style: italic; - text-align: center; - opacity: 0.6; -} -.daggerheart.sheet.actor.environment .potential-adversary-container .adversaries-container { +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet { display: flex; + flex-direction: column; + justify-content: start; + text-align: center; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .profile { + width: 100%; + height: 235px; + object-fit: cover; + mask-image: linear-gradient(0deg, transparent 0%, black 10%); + cursor: pointer; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container { + display: flex; + align-items: center; + position: relative; + top: -45px; + gap: 20px; + padding: 0 20px; + margin-bottom: -30px; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info { + display: flex; + flex-direction: column; gap: 8px; } -.daggerheart.sheet.actor.environment .potential-adversary-container .adversaries-container .adversary-container { - border: 1px solid var(--color-dark-5); - border-radius: 6px; - padding: 0 2px; - font-weight: bold; - cursor: pointer; - background-image: url(../assets/parchments/dh-parchment-dark.png); - color: var(--color-light-3); -} -.application.sheet.daggerheart.dh-style.feature .item-sheet-header { +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags { display: flex; + gap: 10px; + padding-bottom: 0; } -.application.sheet.daggerheart.dh-style.feature .item-sheet-header .profile { - height: 130px; - width: 130px; +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .tag { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 3px 5px; + font-size: 12px; + font: 'Montserrat', sans-serif; + background: light-dark(#22222215, #efe6d815); + border: 1px solid light-dark(#222, #efe6d8); + border-radius: 3px; } -.application.sheet.daggerheart.dh-style.feature section.tab { - height: 400px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .label { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + font-size: 12px; } -.application.sheet.daggerheart.dh-style.domain-card section.tab { - height: 400px; +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number { + justify-items: center; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value { + position: relative; + display: flex; + width: 50px; + height: 30px; + border: 1px solid light-dark(#18162e, #f3c267); + border-bottom: none; + border-radius: 6px 6px 0 0; + padding: 0 6px; + font-size: 1.2rem; + align-items: center; + justify-content: center; + background: light-dark(transparent, #18162e); + z-index: 2; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value.armor-slots { + width: 80px; + height: 30px; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label { + padding: 2px 10px; + width: 100%; + border-radius: 3px; + background: light-dark(#18162e, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + font-size: 12px; + color: light-dark(#efe6d8, #18162e); +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text'] { + font-size: 32px; + height: 42px; + text-align: start; + transition: all 0.3s ease; + outline: 2px solid transparent; + border: 1px solid transparent; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:hover[type='text'], +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:focus[type='text'] { + box-shadow: none; + outline: 2px solid light-dark(#18162e, #f3c267); +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info { + display: flex; + flex-direction: column; + gap: 12px; + padding: 10px 20px; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .description, +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .impulses { + text-align: start; + font-family: 'Montserrat', sans-serif; +} +.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-navigation { + display: flex; + gap: 20px; + align-items: center; + padding: 0 20px; +} +.themed.theme-dark .application.daggerheart.sheet.dh-style.environment, +.themed.theme-dark.application.daggerheart.sheet.dh-style.environment, +body.theme-dark .application.daggerheart.environment, +body.theme-dark.application.daggerheart.environment { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.themed.theme-light .application.daggerheart.sheet.dh-style.environment, +.themed.theme-light.application.daggerheart.sheet.dh-style.environment, +body.theme-light .application.daggerheart.environment, +body.theme-light.application.daggerheart.environment { + background: url('../assets/parchments/dh-parchment-light.png'); +} +.application.sheet.daggerheart.actor.dh-style.environment .tab { + max-height: 300px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: light-dark(#18162e, #f3c267) transparent; @@ -5290,6 +1447,883 @@ body.theme-light.application.daggerheart.companion { justify-content: center; gap: 10px; } +.application.sheet.daggerheart.dh-style.domain-card section.tab { + height: 400px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.sheet.daggerheart.dh-style.feature .item-sheet-header { + display: flex; +} +.application.sheet.daggerheart.dh-style.feature .item-sheet-header .profile { + height: 130px; + width: 130px; +} +.application.sheet.daggerheart.dh-style.feature section.tab { + height: 400px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.daggerheart.dh-style.dialog .window-content .dialog-header { + width: 100%; + padding-bottom: 16px; +} +.application.daggerheart.dh-style.dialog .window-content .dialog-header h1 { + font-family: 'Cinzel', serif; + font-style: normal; + font-weight: 700; + font-size: 24px; + margin: 0; + text-align: center; + color: light-dark(#18162e, #f3c267); +} +.application.daggerheart.dh-style.dialog .tab.details.active, +.application.daggerheart.dh-style.dialog .tab.attack.active { + display: flex; + flex-direction: column; + gap: 16px; +} +.application.daggerheart.dh-style.dialog .tab .fieldsets-section { + display: flex; + gap: 16px; +} +.application.daggerheart.dh-style.dialog .tab.experiences .add-experience-btn { + width: 100%; + margin-bottom: 12px; +} +.application.daggerheart.dh-style.dialog .tab.experiences .experience-list { + display: flex; + flex-direction: column; + gap: 10px; +} +.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item { + display: grid; + grid-template-columns: 3fr 1fr 30px; + align-items: center; + gap: 5px; +} +.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item a { + text-align: center; +} +.application.daggerheart.dh-style.dialog .tab.features { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.daggerheart.dh-style.dialog .tab.features .add-feature-btn { + width: 100%; + margin-bottom: 12px; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list { + display: flex; + flex-direction: column; + gap: 10px; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item { + display: grid; + grid-template-columns: 40px 1fr auto; + align-items: center; + gap: 5px; + border-radius: 3px; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item img { + height: 40px; + width: 40px; + object-fit: cover; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .label { + font-family: 'Montserrat', sans-serif; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls { + display: flex; + gap: 5px; +} +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls a { + text-align: center; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .add-feature-btn { + width: 100%; + margin-bottom: 12px; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list { + display: flex; + flex-direction: column; + gap: 10px; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item { + display: grid; + grid-template-columns: 40px 1fr auto; + align-items: center; + gap: 5px; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item img { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 3px; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .label { + font-family: 'Montserrat', sans-serif; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls { + display: flex; + gap: 5px; +} +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls a { + text-align: center; +} +.application.daggerheart.dh-style.dialog .tab.adversaries { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(#18162e, #f3c267) transparent; +} +.application.daggerheart.dh-style.dialog .tab.adversaries .add-action-btn { + width: 100%; + margin-bottom: 12px; +} +.application.daggerheart.dh-style.dialog .tab.adversaries .category-container { + display: flex; + flex-direction: column; + align-items: start; + gap: 8px; +} +.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .category-name { + display: flex; + align-items: center; + gap: 10px; + width: 100%; +} +.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .adversaries-container { + display: flex; + flex-direction: column; + gap: 6px; + width: 100%; +} +.application.daggerheart.dh-style.dialog .tab.adversaries .adversaries-dragger { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + border: 1px dashed light-dark(#18162e50, #efe6d850); + border-radius: 3px; + color: light-dark(#18162e50, #efe6d850); + font-family: 'Montserrat', sans-serif; +} +.daggerheart.levelup .levelup-navigation-container { + display: flex; + align-items: center; + gap: 22px; + height: 36px; +} +.daggerheart.levelup .levelup-navigation-container nav { + flex: 1; +} +.daggerheart.levelup .levelup-navigation-container nav .levelup-tab-container { + display: flex; + align-items: center; + gap: 4px; +} +.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions { + width: 306px; + display: flex; + justify-content: end; + gap: 16px; + margin-right: 4px; +} +.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions * { + width: calc(50% - 8px); +} +.daggerheart.levelup .levelup-selections-container .achievement-experience-cards { + display: flex; + gap: 8px; +} +.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card { + border: 1px solid; + border-radius: 4px; + padding-right: 4px; + font-size: 18px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; +} +.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card .achievement-experience-marker { + border: 1px solid; + border-radius: 50%; + height: 18px; + width: 18px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection { + display: flex; + flex-wrap: wrap; + gap: 40px; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .card-preview-container { + width: calc(100% * (1 / 5)); +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container { + display: flex; + flex-direction: column; + gap: 8px; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container { + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + position: relative; + cursor: pointer; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container.disabled { + pointer-events: none; + opacity: 0.4; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-label { + position: absolute; + text-align: center; + top: 4px; + background: grey; + padding: 0 12px; + border-radius: 6px; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container img { + height: 124px; +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected { + position: absolute; + height: 54px; + width: 54px; + border-radius: 50%; + border: 2px solid; + font-size: 48px; + display: flex; + align-items: center; + justify-content: center; + background-image: url(../assets/parchments/dh-parchment-light.png); + color: var(--color-dark-5); + top: calc(50% - 29px); +} +.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected i { + position: relative; + right: 2px; +} +.daggerheart.levelup .levelup-selections-container .levelup-selections-title { + display: flex; + align-items: center; + gap: 4px; +} +.daggerheart.levelup .levelup-selections-container .levelup-radio-choices { + display: flex; + gap: 8px; +} +.daggerheart.levelup .levelup-selections-container .levelup-radio-choices label { + flex: 0; +} +.themed.theme-light .application.daggerheart.sheet.dh-style.levelup .tiers-container .tier-container, +.themed.theme-light.application.daggerheart.sheet.dh-style.levelup .tiers-container .tier-container, +body.theme-light .application.daggerheart.levelup .tiers-container .tier-container, +body.theme-light.application.daggerheart.levelup .tiers-container .tier-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); +} +.daggerheart.levelup .window-content { + max-height: 960px; + overflow: auto; +} +.daggerheart.levelup div[data-application-part='form'] { + display: flex; + flex-direction: column; + gap: 8px; +} +.daggerheart.levelup section .section-container { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 8px; +} +.daggerheart.levelup .levelup-footer { + display: flex; +} +.daggerheart.levelup .levelup-summary-container .level-achievements-container, +.daggerheart.levelup .levelup-summary-container .level-advancements-container { + display: flex; + flex-direction: column; + gap: 8px; +} +.daggerheart.levelup .levelup-summary-container .level-achievements-container h2, +.daggerheart.levelup .levelup-summary-container .level-advancements-container h2, +.daggerheart.levelup .levelup-summary-container .level-achievements-container h3, +.daggerheart.levelup .levelup-summary-container .level-advancements-container h3, +.daggerheart.levelup .levelup-summary-container .level-achievements-container h4, +.daggerheart.levelup .levelup-summary-container .level-advancements-container h4, +.daggerheart.levelup .levelup-summary-container .level-achievements-container h5, +.daggerheart.levelup .levelup-summary-container .level-advancements-container h5 { + margin: 0; + color: var(--color-text-secondary); +} +.daggerheart.levelup .levelup-summary-container .increase-container { + display: flex; + align-items: center; + gap: 4px; + font-size: 20px; +} +.daggerheart.levelup .levelup-summary-container .summary-selection-container { + display: flex; + gap: 8px; +} +.daggerheart.levelup .levelup-summary-container .summary-selection-container .summary-selection { + border: 2px solid; + border-radius: 6px; + padding: 0 4px; + font-size: 18px; +} +.daggerheart.levelup .tiers-container { + display: flex; + gap: 16px; +} +.daggerheart.levelup .tiers-container .tier-container { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.daggerheart.levelup .tiers-container .tier-container.inactive { + opacity: 0.4; + pointer-events: none; +} +.daggerheart.levelup .tiers-container .tier-container legend { + margin-left: auto; + margin-right: auto; + font-size: 22px; + font-weight: bold; + padding: 0 12px; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container { + display: grid; + grid-template-columns: 1fr 3fr; + gap: 4px; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container { + display: flex; + justify-content: end; + gap: 4px; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer { + display: flex; + height: min-content; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi { + border: 2px solid grey; + padding: 2.4px 2.5px 0; + border-radius: 4px; + gap: 2px; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi .selection-checkbox { + margin-left: 0; + margin-right: 0; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer .selection-checkbox { + margin: 0; +} +.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkbox-group-label { + font-size: 14px; + font-style: italic; +} +/* Base Value */ +/* Margins */ +/* Borders */ +/* Padding */ +/* Inputs */ +.daggerheart.views .downtime-container .downtime-header { + margin: 0; + color: light-dark(#18162e, #f3c267); + text-align: center; +} +.daggerheart.views .downtime-container .activity-container { + display: flex; + align-items: center; + padding: 8px; +} +.daggerheart.views .downtime-container .activity-container .activity-title { + flex: 1; + display: flex; + align-items: center; +} +.daggerheart.views .downtime-container .activity-container .activity-title .activity-title-text { + font-size: 24px; + font-weight: bold; +} +.daggerheart.views .downtime-container .activity-container .activity-title .activity-image { + width: 80px; + position: relative; + display: flex; + justify-content: center; + margin-right: 8px; + border: 2px solid black; + border-radius: 50%; + cursor: pointer; +} +.daggerheart.views .downtime-container .activity-container .activity-title .activity-image .activity-select-label { + position: absolute; + top: -9px; + font-size: 14px; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url(../assets/parchments/dh-parchment-light.png); + padding: 0 8px; + line-height: 1; + font-weight: bold; +} +.daggerheart.views .downtime-container .activity-container .activity-title .activity-image img { + border-radius: 50%; +} +.daggerheart.views .downtime-container .activity-container .activity-title .activity-image:hover, +.daggerheart.views .downtime-container .activity-container .activity-title .activity-image.selected { + filter: drop-shadow(0 0 6px gold); +} +.daggerheart.views .downtime-container .activity-container .activity-title .custom-name-input { + font-size: 24px; + font-weight: bold; + padding: 0; + background: transparent; + color: #efe6d8; +} +.daggerheart.views .downtime-container .activity-container .activity-body { + flex: 1; + font-style: italic; +} +.daggerheart.views.downtime .activity-text-area { + resize: none; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container { + display: flex; + flex-direction: column; + gap: 4px; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + gap: 4px; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container { + position: relative; + display: flex; + justify-content: center; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + cursor: pointer; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container.inactive { + opacity: 0.4; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container img { + width: 100%; + border-radius: 6px; +} +.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { + position: absolute; + top: 4px; + display: flex; + flex-wrap: wrap; + font-size: 16px; + margin: 0 4px; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url('../assets/parchments/dh-parchment-light.png'); +} +.themed.theme-dark .application.daggerheart.sheet.dh-style.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, +.themed.theme-dark.application.daggerheart.sheet.dh-style.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, +body.theme-dark .application.daggerheart.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, +body.theme-dark.application.daggerheart.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.application.daggerheart.dh-style.views.beastform-selection footer { + margin-top: 8px; + display: flex; +} +.application.daggerheart.dh-style.views.beastform-selection footer button { + flex: 1; +} +.daggerheart.dh-style.dialog.character-creation .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; +} +.daggerheart.dh-style.dialog.character-creation .creation-action-footer button { + flex: 1; + height: 100%; + white-space: nowrap; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container { + display: flex; + flex-direction: column; + gap: 4px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container { + width: 140px; + display: flex; + flex-direction: column; + text-align: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container .card-preview-container { + border-color: light-dark(#18162e, #f3c267); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-outer-container { + display: flex; + justify-content: space-evenly; + height: 210px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container { + border-radius: 8px; + border-color: light-dark(#18162e, #f3c267); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container { + position: relative; + border-radius: 8px; + border-color: light-dark(#18162e, #f3c267); + display: flex; + justify-content: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container legend { + font-size: 20px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button { + position: absolute; + bottom: -8px; + height: 16px; + width: 110px; + min-height: unset; + border: 1px solid light-dark(#18162e, #f3c267); + color: light-dark(#efe6d8, #efe6d8); + background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button:hover { + background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); + filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container { + text-align: center; + display: flex; + gap: 16px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container { + display: flex; + flex-wrap: wrap; + width: 176px; + gap: 4px; + margin-bottom: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container { + width: 56px; + white-space: nowrap; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url('../assets/parchments/dh-parchment-light.png'); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container { + display: flex; + justify-content: space-evenly; + gap: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container .trait-container { + border: 1px solid light-dark(#18162e, #f3c267); + padding: 0 4px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container { + display: flex; + justify-content: space-evenly; + text-align: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container { + position: relative; + display: flex; + align-items: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-description { + border-color: light-dark(#18162e, #f3c267); + padding-right: 24px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-value { + position: absolute; + right: 0; + width: 22px; + border-left: 1px solid light-dark(#18162e, #f3c267); + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section { + display: flex; + align-items: center; + gap: 32px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav { + flex: 1; + gap: 8px; + border: 0; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .nav-section-text { + position: relative; + display: flex; + align-items: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker { + position: absolute; + align-self: center; + top: -10px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 20px; + width: 20px; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker.finished { + background-color: var(--color-warm-2); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url(../assets/parchments/dh-parchment-light.png); +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section button { + flex: 1; + height: 100%; + white-space: nowrap; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 16px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection.triple { + grid-template-columns: 1fr 1fr 1fr; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + border: 2px solid light-dark(#18162e, #f3c267); + border-radius: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; + white-space: nowrap; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-subsection { + display: flex; + align-items: start; + gap: 32px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container { + display: flex; + flex-direction: column; + justify-content: space-evenly; + gap: 8px; + height: 100%; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment { + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 8px; + position: relative; + display: flex; + justify-content: center; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.selectable { + cursor: pointer; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.inactive { + opacity: 0.4; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { + position: absolute; + top: -8px; + font-size: 12px; + white-space: nowrap; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url('../assets/parchments/dh-parchment-light.png'); + padding: 0 2px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment img { + width: 60px; + height: 60px; + border-radius: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container { + position: relative; + display: flex; + justify-content: center; + height: min-content; + border: 2px solid light-dark(#18162e, #f3c267); + border-radius: 8px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container legend { + margin-left: auto; + margin-right: auto; + font-size: 12px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container { + position: relative; + display: flex; + justify-content: center; + align-items: center; + padding: 6px; + cursor: grab; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container.taken { + opacity: 0.4; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container label { + position: absolute; + top: -2px; + font-size: 12px; +} +.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container img { + width: 120px; +} +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .tab-navigation nav a .descriptor, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .tab-navigation nav a .descriptor, +body.theme-dark .application.daggerheart .character-creation .tab-navigation nav a .descriptor, +body.theme-dark.application.daggerheart .character-creation .tab-navigation nav a .descriptor { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, +body.theme-dark .application.daggerheart .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, +body.theme-dark.application.daggerheart .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, +body.theme-dark .application.daggerheart .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, +body.theme-dark.application.daggerheart .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, +body.theme-dark .application.daggerheart .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, +body.theme-dark.application.daggerheart .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.daggerheart.dh-style.dialog.character-creation .window-content { + gap: 16px; +} +.daggerheart.dh-style.dialog.character-creation .window-content .tab { + overflow-y: auto; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav { + flex: 1; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a.disabled { + opacity: 0.4; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .nav-section-text { + position: relative; + display: flex; + align-items: center; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker { + position: absolute; + align-self: center; + top: -8px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 16px; + width: 16px; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker.active { + background-color: var(--color-warm-2); +} +.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + color: light-dark(#efe6d8, #222); + background-image: url(../assets/parchments/dh-parchment-light.png); +} .application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container { display: flex; flex-direction: column; @@ -5395,6 +2429,125 @@ body.theme-light.application.daggerheart.companion { line-height: 17px; color: light-dark(#222, #efe6d8); } +.daggerheart.views.damage-reduction .damage-reduction-container { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; +} +.daggerheart.views.damage-reduction .damage-reduction-container .section-container { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} +.daggerheart.views.damage-reduction .damage-reduction-container .padded { + padding: 0 8px; +} +.daggerheart.views.damage-reduction .damage-reduction-container .armor-title { + margin: 0; + white-space: nowrap; +} +.daggerheart.views.damage-reduction .damage-reduction-container .resources-container { + display: flex; + gap: 8px; + width: 100%; +} +.daggerheart.views.damage-reduction .damage-reduction-container .resources-container .resource-container { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection { + display: flex; + align-items: center; + width: 100%; + margin: 0; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner { + display: flex; + gap: 2px; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner:not(:last-child) { + margin-right: 8px; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container { + cursor: pointer; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + height: 26px; + padding: 0 1px; + font-size: 18px; + display: flex; + align-items: center; + justify-content: center; + opacity: 0.4; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.selected { + opacity: 1; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.inactive { + cursor: initial; + opacity: 0.2; +} +.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container .fa-shield { + position: relative; + right: 0.5px; +} +.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container { + margin: 0; + width: 100%; +} +.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction { + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + height: 26px; + padding: 0 4px; + font-size: 18px; + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + opacity: 0.4; +} +.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.active { + opacity: 1; + cursor: pointer; +} +.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.selected { + opacity: 1; + background: var(--color-warm-2); + color: white; +} +.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction .stress-reduction-cost { + display: flex; + align-items: center; +} +.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle { + margin: -4px 0 0 0; +} +.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle.bold { + font-variant: all-small-caps; + font-weight: bold; +} +.daggerheart.views.damage-reduction .damage-reduction-container footer { + display: flex; + width: 100%; +} +.daggerheart.views.damage-reduction .damage-reduction-container footer button { + flex: 1; +} +.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value { + font-weight: bold; +} +.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value.reduced-value { + opacity: 0.4; + text-decoration: line-through; +} +.daggerheart.views.damage-reduction .window-content { + padding: 8px 0; +} @keyframes glow { 0% { box-shadow: 0 0 1px 1px #f3c267; @@ -5483,11 +2636,6 @@ body.theme-light.application.daggerheart.companion { font-family: 'Montserrat', sans-serif; opacity: 0.8; } -/** - * Applies theme-specific styles. - * @param {Rules} @darkRules - Styles to apply when `.theme-dark` is present - * @param {Rules} @lightRules - Styles to apply when `.theme-light` is present - */ .themed.theme-dark .application.daggerheart.sheet.dh-style, .themed.theme-dark.application.daggerheart.sheet.dh-style, body.theme-dark .application.daggerheart, @@ -6526,103 +3674,930 @@ body.theme-light.application.daggerheart.dialog { .filter-menu fieldset.filter-section .filter-buttons button.active { animation: glow 0.75s infinite alternate; } -.daggerheart { - /* Flex */ - /****/ -} -.daggerheart .vertical-separator { - border-left: 2px solid black; - height: 56px; - flex: 0; - align-self: center; -} -.daggerheart .flex-centered { - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart .flex-col-centered { +.daggerheart.chat.downtime { display: flex; flex-direction: column; align-items: center; } -.daggerheart .flex-spaced { +.daggerheart.chat.downtime .downtime-title-container { display: flex; - justify-content: space-between; + flex-direction: column; align-items: center; +} +.daggerheart.chat.downtime .downtime-title-container .downtime-subtitle { + font-size: 17px; +} +.daggerheart.chat.downtime .downtime-image { + width: 80px; +} +.daggerheart.chat.downtime .downtime-refresh-container { + margin-top: 8px; width: 100%; } -.daggerheart .flex-min { - display: flex; - flex: 0; -} -.daggerheart img[data-edit='img'] { - min-width: 64px; - min-height: 64px; -} -.daggerheart .editor { - height: 200px; -} -.daggerheart button i { - margin: 0; -} -.daggerheart .icon-button.spaced { - margin-left: 4px; -} -.daggerheart .icon-button.disabled { - opacity: 0.6; -} -.daggerheart .icon-button:hover:not(.disabled) { - cursor: pointer; -} -#players h3 { - display: flex; - align-items: center; - justify-content: space-between; - flex-wrap: nowrap; -} -#players h3 .players-container { - display: flex; - align-items: center; -} -#players h3 .fear-control { - font-size: 10px; -} -#players h3 .fear-control.disabled { - opacity: 0.4; -} -#players h3 .fear-control:hover:not(.disabled) { - cursor: pointer; - filter: drop-shadow(0 0 3px red); -} -.unlist { - list-style: none; - padding-inline-start: 0; -} -.list-select { - margin: 1rem; -} -.list-select li:not(:last-child) { - border-bottom: 1px solid #bbb; -} -.list-select li label { - padding: 4px 8px; - display: flex; - align-items: center; - gap: 1rem; - cursor: pointer; -} -.list-select li label > span { - flex: 1; +.daggerheart.chat.downtime .downtime-refresh-container .refresh-title { font-weight: bold; - font-size: var(--font-size-16); } -dh-icon, -dh-icon > img { - width: 32px; - height: 32px; +.daggerheart.chat.roll .dice-flavor { + text-align: center; + font-weight: bold; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality { + display: flex; + gap: 0.25rem; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll { display: flex; align-items: center; justify-content: center; - font-size: x-large; + gap: 4px; + margin-bottom: 4px; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container { + display: flex; + flex-direction: column; + gap: 2px; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-title { + color: var(--color-light-1); + text-shadow: 0 0 1px black; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container { + display: flex; + align-items: center; + justify-content: center; + position: relative; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper, +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { + clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%); +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper { + height: 24px; + width: 24px; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper .dice { + height: 26px; + width: 26px; + max-width: unset; + position: absolute; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-value { + position: absolute; + font-weight: bold; + font-size: 16px; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper { + background: black; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper .dice { + filter: brightness(0) saturate(100%) invert(79%) sepia(79%) saturate(333%) hue-rotate(352deg) brightness(102%) contrast(103%); +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-value { + color: var(--color-dark-1); + text-shadow: 0 0 4px white; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { + background: white; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper .dice { + filter: brightness(0) saturate(100%) invert(12%) sepia(88%) saturate(4321%) hue-rotate(221deg) brightness(92%) contrast(110%); +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-value { + color: var(--color-light-1); + text-shadow: 0 0 4px black; +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.advantage .dice-wrapper .dice { + filter: brightness(0) saturate(100%) invert(18%) sepia(92%) saturate(4133%) hue-rotate(96deg) brightness(104%) contrast(107%); +} +.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.disadvantage .dice-wrapper .dice { + filter: brightness(0) saturate(100%) invert(9%) sepia(78%) saturate(6903%) hue-rotate(11deg) brightness(93%) contrast(117%); +} +.daggerheart.chat.roll .dice-total.duality.hope { + border-color: #ffe760; + border-width: 3px; + background: rgba(255, 231, 96, 0.5); +} +.daggerheart.chat.roll .dice-total.duality.fear { + border-color: #0032b1; + border-width: 3px; + background: rgba(0, 50, 177, 0.5); +} +.daggerheart.chat.roll .dice-total.duality.critical { + border-color: #430070; + border-width: 3px; + background: rgba(67, 0, 112, 0.5); +} +.daggerheart.chat.roll .dice-total .dice-total-value .hope { + color: #ffe760; +} +.daggerheart.chat.roll .dice-total .dice-total-value .fear { + color: #0032b1; +} +.daggerheart.chat.roll .dice-total .dice-total-value .critical { + color: #430070; +} +.daggerheart.chat.roll .dice-total-label { + font-size: 12px; + font-weight: bold; + font-variant: all-small-caps; + margin: -8px 0; +} +.daggerheart.chat.roll .target-selection { + display: flex; + justify-content: space-around; +} +.daggerheart.chat.roll .target-selection input[type='radio'] { + display: none; +} +.daggerheart.chat.roll .target-selection input[type='radio']:checked + label { + text-shadow: 0px 0px 4px #ce5937; +} +.daggerheart.chat.roll .target-selection input[type='radio']:not(:checked) + label { + opacity: 0.75; +} +.daggerheart.chat.roll .target-selection label { + cursor: pointer; + opacity: 0.75; +} +.daggerheart.chat.roll .target-selection label.target-selected { + text-shadow: 0px 0px 4px #ce5937; + opacity: 1; +} +.daggerheart.chat.roll .target-section { + margin-top: 5px; +} +.daggerheart.chat.roll .target-section .target-container { + display: flex; + transition: all 0.2s ease-in-out; +} +.daggerheart.chat.roll .target-section .target-container:hover { + filter: drop-shadow(0 0 3px gold); + border-color: gold; +} +.daggerheart.chat.roll .target-section .target-container.hidden { + display: none; + border: 0; +} +.daggerheart.chat.roll .target-section .target-container.hit { + background: #008000; +} +.daggerheart.chat.roll .target-section .target-container.miss { + background: #ff0000; +} +.daggerheart.chat.roll .target-section .target-container img, +.daggerheart.chat.roll .target-section .target-container .target-save-container { + width: 22px; + height: 22px; + align-self: center; + border-color: transparent; +} +.daggerheart.chat.roll .target-section .target-container img { + flex: 0; + margin-left: 8px; +} +.daggerheart.chat.roll .target-section .target-container .target-save-container { + margin-right: 8px; + justify-content: center; + display: flex; + align-items: center; + min-height: unset; + border: 1px solid black; +} +.daggerheart.chat.roll .target-section .target-container .target-inner-container { + flex: 1; + display: flex; + justify-content: center; + font-size: var(--font-size-16); +} +.daggerheart.chat.roll .target-section .target-container:not(:has(.target-save-container)) .target-inner-container { + margin-right: 32px; +} +.daggerheart.chat.roll .dice-actions { + display: flex; + gap: 4px; +} +.daggerheart.chat.roll .dice-actions button { + flex: 1; +} +.daggerheart.chat.roll .dice-result .roll-damage-button, +.daggerheart.chat.roll .dice-result .damage-button, +.daggerheart.chat.roll .dice-result .duality-action { + margin-top: 5px; +} +.daggerheart.chat.roll:not(.expanded) .dice-tooltip { + grid-template-rows: 0fr; +} +.daggerheart.chat.domain-card { + display: flex; + flex-direction: column; + align-items: center; +} +.daggerheart.chat.domain-card .domain-card-title { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} +.daggerheart.chat.domain-card .domain-card-title div { + font-size: 20px; + font-variant: small-caps; + font-weight: bold; +} +.daggerheart.chat.domain-card .domain-card-title h2 { + width: 100%; + text-align: center; + margin: 0; +} +.daggerheart.chat.domain-card .ability-card-footer { + display: flex; + width: 100%; + margin-top: 8px; + flex-wrap: wrap; +} +.daggerheart.chat.domain-card .ability-card-footer button { + border-radius: 6px; + background: #699969; + border-color: black; + flex-basis: calc(50% - 2px); +} +.daggerheart.chat.domain-card .ability-card-footer button:nth-of-type(n + 3) { + margin-top: 2px; +} +.daggerheart.chat.domain-card .ability-card-footer .ability-card-action-cost { + margin: auto; + font-size: 1.5em; +} +.daggerheart.chat.domain-card img { + width: 80px; +} +.daggerheart.chat button.inner-button { + --button-size: 1.25rem; + --input-height: 1.25rem; + padding: 0 0.25rem; + margin: 5px 1px -4px auto; +} +.daggerheart.chat button.inner-button.inner-button-right { + margin-left: auto; +} +.daggerheart.chat [data-use-perm='false'] { + pointer-events: none; + border-color: transparent; +} +.daggerheart.chat [data-view-perm='false'] > * { + display: none; +} +.daggerheart.chat [data-view-perm='false']::after { + content: '??'; +} +.chat-message .duality-modifiers, +.chat-message .duality-result, +.chat-message .dice-title { + display: none; +} +fieldset.daggerheart.chat { + padding: 0; + border-left-width: 0; + border-right-width: 0; + border-bottom-width: 0; +} +fieldset.daggerheart.chat legend { + display: flex; + align-items: center; + gap: 5px; +} +fieldset.daggerheart.chat legend:before, +fieldset.daggerheart.chat legend:after { + content: '\f0d8'; + font-family: 'Font Awesome 6 Pro'; +} +fieldset.daggerheart.chat.expanded legend:before, +fieldset.daggerheart.chat.expanded legend:after { + content: '\f0d7'; +} +fieldset.daggerheart.chat .daggerheart.chat { + margin-top: 5px; +} +.theme-colorful .chat-message.duality { + border-color: black; + padding: 8px 0 0 0; +} +.theme-colorful .chat-message.duality fieldset.daggerheart.chat { + border-top-width: 0; + display: contents; +} +.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:before, +.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:after { + display: none; +} +.theme-colorful .chat-message.duality .message-header { + color: var(--color-light-3); + padding: 0 8px; +} +.theme-colorful .chat-message.duality.hope { + background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); +} +.theme-colorful .chat-message.duality.fear { + background: linear-gradient(0, rgba(0, 0, 255, 0.6), rgba(15, 15, 97, 0.6)); +} +.theme-colorful .chat-message.duality.critical { + background: linear-gradient(0, rgba(128, 0, 128, 0.6), rgba(37, 8, 37, 0.6)); +} +.theme-colorful .chat-message.duality .chat-message header { + color: var(--color-light-3); +} +.theme-colorful .chat-message.duality > * { + padding: 0 8px; +} +.theme-colorful .chat-message.duality .message-content .duality-modifiers, +.theme-colorful .chat-message.duality .message-content .duality-result, +.theme-colorful .chat-message.duality .message-content .dice-title { + display: flex; +} +.theme-colorful .chat-message.duality .message-content .duality-modifiers { + display: flex; + gap: 2px; + margin-bottom: 4px; +} +.theme-colorful .chat-message.duality .message-content .duality-modifiers .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; +} +.theme-colorful .chat-message.duality .message-content .dice-flavor { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + border-bottom: 1px solid; + display: flex; + align-items: end; + justify-content: space-between; + padding: 0 8px; + margin: 0 -8px 2px; + font-weight: unset; +} +.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers { + display: flex; + gap: 2px; + margin-bottom: 4px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-formula, +.theme-colorful .chat-message.duality .message-content .dice-result > .dice-total, +.theme-colorful .chat-message.duality .message-content .dice-result .part-header { + display: none; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip { + grid-template-rows: 1fr; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part { + display: flex; + align-items: end; + gap: 0.25rem; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls { + margin-bottom: 0; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls.duality li { + display: flex; + align-items: center; + justify-content: center; + position: relative; + background: unset; + line-height: unset; + font-weight: unset; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .duality-modifier { + display: flex; + margin-bottom: 6px; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-size: var(--font-size-16); +} +.theme-colorful .chat-message.duality .message-content .dice-result .target-selection label { + color: var(--color-light-1); +} +.theme-colorful .chat-message.duality .message-content .dice-result .target-section { + margin: 4px 0; + border: 2px solid; + margin-top: 5px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .target-section .dice-total { + box-shadow: unset; + border: unset; + border-radius: unset; + font-size: var(--font-size-18); +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions { + justify-content: space-between; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions.duality-alone { + justify-content: end; + margin-top: -20px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions > * { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action { + border-radius: 0 6px 0 0; + margin-left: -8px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action.duality-action-effect { + border-top-left-radius: 6px; + margin-left: initial; +} +.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-result { + border-radius: 6px 0 0 0; + margin-right: -8px; +} +.theme-colorful .chat-message.duality .message-content .dice-result .duality-result { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; + margin-left: auto; + align-self: center; + border-radius: 6px; +} +.theme-colorful .chat-message.duality button.inner-button { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + border-color: black; +} +.combat-sidebar h4 { + margin: 0; + text-align: center; +} +.combat-sidebar .combatant-controls { + flex: 0; +} +.combat-sidebar .encounter-controls.combat { + justify-content: space-between; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls { + display: flex; + align-items: center; + gap: 8px; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container { + display: flex; + gap: 2px; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container { + display: flex; + position: relative; + align-items: center; + justify-content: center; + color: black; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .dice { + height: 22px; + width: 22px; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-fear { + position: absolute; + font-size: 16px; +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-counter { + position: absolute; + right: -10px; + color: var(--color-text-secondary); +} +.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-countdowns { + color: var(--content-link-icon-color); +} +.combat-sidebar .encounter-controls.combat .control-buttons { + width: min-content; +} +.combat-sidebar .spotlight-control { + font-size: 26px; +} +.combat-sidebar .spotlight-control:focus { + outline: none; + box-shadow: none; +} +.combat-sidebar .spotlight-control.discrete:hover { + background: inherit; +} +.combat-sidebar .spotlight-control.requesting { + filter: drop-shadow(0 0 3px gold); + color: var(--button-hover-text-color); +} +.combat-sidebar .token-actions { + align-self: stretch; + display: flex; + align-items: top; + justify-content: center; + gap: 16px; +} +.combat-sidebar .token-actions .action-tokens { + display: flex; + gap: 4px; +} +.combat-sidebar .token-actions .action-tokens .action-token { + height: 22px; + width: 22px; + border: 1px solid; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 10px; + padding: 8px; + --button-size: 0; +} +.combat-sidebar .token-actions .action-tokens .action-token.used { + opacity: 0.5; + background: transparent; +} +.combat-sidebar .token-actions button { + font-size: 22px; + height: 24px; + width: 24px; +} +.combat-sidebar .token-actions button.main { + background: var(--button-hover-background-color); + color: var(--button-hover-text-color); + border-color: var(--button-hover-border-color); +} +.combat-sidebar .token-actions button.main:hover { + filter: drop-shadow(0 0 3px var(--button-hover-text-color)); +} +.daggerheart.dh-style.countdown fieldset { + align-items: center; + margin-top: 5px; + border-radius: 6px; + border-color: light-dark(#18162e, #f3c267); +} +.daggerheart.dh-style.countdown fieldset legend { + font-family: 'Montserrat', sans-serif; + font-weight: bold; + color: light-dark(#18162e, #f3c267); +} +.daggerheart.dh-style.countdown fieldset legend a { + text-shadow: none; +} +.daggerheart.dh-style.countdown .minimized-view { + display: flex; + gap: 8px; + flex-wrap: wrap; +} +.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container { + width: fit-content; + display: flex; + align-items: center; + gap: 8px; + border: 2px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + padding: 0 4px 0 0; + background-image: url('../assets/parchments/dh-parchment-light.png'); + color: light-dark(#efe6d8, #222); + cursor: pointer; +} +.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container.disabled { + cursor: initial; +} +.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container img { + width: 30px; + height: 30px; + border-radius: 6px 0 0 6px; +} +.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container .mini-countdown-name { + white-space: nowrap; +} +.daggerheart.dh-style.countdown .hidden { + display: none; +} +.themed.theme-light .application.daggerheart.sheet.dh-style.countdown .minimized-view .mini-countdown-container, +.themed.theme-light.application.daggerheart.sheet.dh-style.countdown .minimized-view .mini-countdown-container, +body.theme-light .application.daggerheart.countdown .minimized-view .mini-countdown-container, +body.theme-light.application.daggerheart.countdown .minimized-view .mini-countdown-container { + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.daggerheart.dh-style.countdown { + overflow: hidden; +} +.daggerheart.dh-style.countdown .window-content > div { + height: 100%; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view { + height: 100%; + display: flex; + flex-direction: column; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu { + display: flex; + gap: 8px; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu .flex { + flex: 1; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container { + display: flex; + gap: 8px; + flex-wrap: wrap; + overflow: auto; + max-height: 100%; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset { + width: 340px; + height: min-content; + position: relative; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .ownership-button { + position: absolute; + top: 8px; + right: 8px; + font-size: 18px; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container { + display: flex; + align-items: center; + gap: 16px; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img { + width: 150px; + height: 150px; + cursor: pointer; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img.disabled { + cursor: initial; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container { + display: flex; + flex-direction: column; + gap: 4px; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container { + display: flex; + gap: 4px; +} +.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container input { + max-width: 80px; +} +.daggerheart.views.ownership-selection .ownership-outer-container { + display: flex; + flex-direction: column; + gap: 8px; +} +.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container { + display: flex; + border: 2px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + padding: 0 4px 0 0; + align-items: center; + gap: 8px; +} +.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container img { + height: 40px; + width: 40px; + border-radius: 6px 0 0 6px; +} +.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container select { + margin: 4px 0; +} +:root { + --shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; + --fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease; +} +#resources { + min-height: calc(var(--header-height) + 4rem); + min-width: 4rem; + color: #d3d3d3; + transition: var(--fear-animation); +} +#resources header, +#resources .controls, +#resources .window-resize-handle { + transition: var(--fear-animation); +} +#resources .window-content { + padding: 0.5rem; +} +#resources .window-content #resource-fear { + display: flex; + flex-direction: row; + gap: 0.5rem 0.25rem; + flex-wrap: wrap; +} +#resources .window-content #resource-fear i { + font-size: var(--font-size-18); + border: 1px solid rgba(0, 0, 0, 0.5); + border-radius: 50%; + aspect-ratio: 1; + display: flex; + justify-content: center; + align-items: center; + width: 3rem; + background-color: rgba(9, 71, 179, 0.75); + -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); + box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); + color: #d3d3d3; + flex-grow: 0; +} +#resources .window-content #resource-fear i.inactive { + filter: grayscale(1) !important; + opacity: 0.5; +} +#resources .window-content #resource-fear .controls, +#resources .window-content #resource-fear .resource-bar { + border: 2px solid #997a4f; + background-color: #18162e; +} +#resources .window-content #resource-fear .controls { + display: flex; + align-self: center; + border-radius: 50%; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + font-size: var(--font-size-20); + cursor: pointer; +} +#resources .window-content #resource-fear .controls:hover { + font-size: 1.5rem; +} +#resources .window-content #resource-fear .controls.disabled { + opacity: 0.5; +} +#resources .window-content #resource-fear .resource-bar { + display: flex; + justify-content: center; + border-radius: 6px; + font-size: var(--font-size-20); + overflow: hidden; + position: relative; + padding: 0.25rem 0.5rem; + flex: 1; + text-shadow: var(--shadow-text-stroke); +} +#resources .window-content #resource-fear .resource-bar:before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: var(--fear-percent); + max-width: 100%; + background: linear-gradient(90deg, #020026 0%, #c701fc 100%); + z-index: 0; + border-radius: 4px; +} +#resources .window-content #resource-fear .resource-bar span { + position: inherit; + z-index: 1; +} +#resources .window-content #resource-fear.isGM i { + cursor: pointer; +} +#resources .window-content #resource-fear.isGM i:hover { + font-size: var(--font-size-20); +} +#resources button[data-action='close'] { + display: none; +} +#resources:not(:hover):not(.minimized) { + background: transparent; + box-shadow: unset; + border-color: transparent; +} +#resources:not(:hover):not(.minimized) header, +#resources:not(:hover):not(.minimized) .controls, +#resources:not(:hover):not(.minimized) .window-resize-handle { + opacity: 0; +} +#resources:has(.fear-bar) { + min-width: 200px; +} +.daggerheart.dh-style.setting fieldset { + display: flex; + flex-direction: column; + gap: 4px; +} +.daggerheart.dh-style.setting fieldset.two-columns { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 10px; +} +.daggerheart.dh-style.setting fieldset.two-columns.even { + grid-template-columns: 1fr 1fr; +} +.daggerheart.dh-style.setting .setting-group-field { + white-space: nowrap; + display: flex; + align-items: center; + gap: 8px; +} +.daggerheart.dh-style.setting .settings-items { + display: flex; + flex-direction: column; + gap: 8px; +} +.daggerheart.dh-style.setting .settings-items .settings-item { + display: flex; + align-items: center; + justify-content: space-between; + border: 1px solid; + border-radius: 8px; + padding: 0 8px 0 0; +} +.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item { + display: flex; + align-items: center; + gap: 8px; +} +.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item img { + width: 60px; + border-radius: 8px 0 0 8px; +} +.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item i { + font-size: 18px; +} +.daggerheart.dh-style.setting .settings-item-header { + display: flex; + align-items: center; +} +.daggerheart.dh-style.setting .settings-item-header .profile { + height: 100px; + width: 100px; + object-fit: cover; + box-sizing: border-box; + cursor: pointer; +} +.daggerheart.dh-style.setting .settings-item-header .item-info { + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; + text-align: center; + width: 80%; +} +.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text'] { + font-size: 32px; + height: 42px; + text-align: center; + width: 90%; + transition: all 0.3s ease; + outline: 2px solid transparent; + border: 1px solid transparent; +} +.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:hover[type='text'], +.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:focus[type='text'] { + box-shadow: none; + outline: 2px solid light-dark(#18162e, #f3c267); +} +.daggerheart.dh-style.setting .settings-col { + display: flex; + flex-direction: column; + gap: 4px; +} +.daggerheart.dh-style.setting .trait-array-container { + display: flex; + justify-content: space-evenly; + gap: 8px; + margin-bottom: 16px; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item { + position: relative; + display: flex; + justify-content: center; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item label { + position: absolute; + top: -7px; + font-size: 12px; + font-variant: petite-caps; +} +.daggerheart.dh-style.setting .trait-array-container .trait-array-item input { + text-align: center; } diff --git a/styles/daggerheart.less b/styles/daggerheart.less index ebecdc95..86b504b2 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -1,203 +1,13 @@ -@import './variables/variables.less'; -@import './variables/colors.less'; -@import './class.less'; -@import './pc.less'; -@import './ui.less'; -@import './chat.less'; -@import './item.less'; -@import './application.less'; -@import './sheets/sheets.less'; -@import './dialog.less'; -@import './characterCreation.less'; -@import './levelup.less'; -@import './ownershipSelection.less'; -@import './damageReduction.less'; -@import './resources.less'; -@import './countdown.less'; -@import './settings.less'; +@import './less/sheets/index.less'; +@import './less/sheets-settings/index.less'; -// new styles imports -@import './less/actors/character/header.less'; -@import './less/actors/character/sidebar.less'; -@import './less/actors/character/sheet.less'; -@import './less/actors/character/inventory.less'; -@import './less/actors/character/loadout.less'; -@import './less/actors/character/biography.less'; -@import './less/actors/character/features.less'; - -@import './less/actors/adversary/header.less'; -@import './less/actors/adversary/sheet.less'; -@import './less/actors/adversary/sidebar.less'; - -@import './less/actors/environment/header.less'; -@import './less/actors/environment/sheet.less'; - -@import './less/applications/header.less'; -@import './less/applications/adversary-settings/sheet.less'; -@import './less/applications/adversary-settings/experiences.less'; -@import './less/applications/adversary-settings/features.less'; - -@import './less/applications/environment-settings/features.less'; -@import './less/applications/environment-settings/adversaries.less'; - -@import './less/applications//beastform.less'; - -@import './less/actors/companion/header.less'; -@import './less/actors/companion/details.less'; -@import './less/actors/companion/sheet.less'; - -@import './less/actors/adversary.less'; -@import './less/actors/environment.less'; - -@import './less/items/feature.less'; -@import './less/items/domainCard.less'; -@import './less/items/class.less'; - -@import './less/dialog/dice-roll/roll-selection.less'; +@import './less/dialog/index.less'; @import './less/utils/colors.less'; @import './less/utils/fonts.less'; -@import './less/global/sheet.less'; -@import './less/global/dialog.less'; -@import './less/global/elements.less'; -@import './less/global/tab-navigation.less'; -@import './less/global/tab-form-footer.less'; -@import './less/global/tab-actions.less'; -@import './less/global/tab-features.less'; -@import './less/global/tab-effects.less'; -@import './less/global/item-header.less'; -@import './less/global/feature-section.less'; -@import './less/global/inventory-item.less'; -@import './less/global/inventory-fieldset-items.less'; -@import './less/global/prose-mirror.less'; -@import './less/global/filter-menu.less'; +@import './less/global/index.less'; + +@import './less/ui/index.less'; @import '../node_modules/@yaireo/tagify/dist/tagify.css'; - -.daggerheart { - .vertical-separator { - border-left: 2px solid black; - height: 56px; - flex: 0; - align-self: center; - } - - /* Flex */ - .flex-centered { - display: flex; - align-items: center; - justify-content: center; - } - - .flex-col-centered { - display: flex; - flex-direction: column; - align-items: center; - } - - .flex-spaced { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - } - - .flex-min { - display: flex; - flex: 0; - } - - /****/ - img[data-edit='img'] { - min-width: 64px; - min-height: 64px; - } - - .editor { - height: 200px; - } - - button { - i { - margin: 0; - } - } - - .icon-button { - &.spaced { - margin-left: @halfMargin; - } - - &.disabled { - opacity: 0.6; - } - - &:hover:not(.disabled) { - cursor: pointer; - } - } -} - -#players { - h3 { - display: flex; - align-items: center; - justify-content: space-between; - flex-wrap: nowrap; - - .players-container { - display: flex; - align-items: center; - } - - .fear-control { - font-size: 10px; - - &.disabled { - opacity: 0.4; - } - - &:hover:not(.disabled) { - cursor: pointer; - filter: drop-shadow(0 0 3px @mainShadow); - } - } - } -} - -.unlist { - list-style: none; - padding-inline-start: 0; -} - -.list-select { - margin: 1rem; - li { - &:not(:last-child) { - border-bottom: 1px solid #bbb; - } - label { - padding: 4px 8px; - display: flex; - align-items: center; - gap: 1rem; - cursor: pointer; - > span { - flex: 1; - font-weight: bold; - font-size: var(--font-size-16); - } - } - } -} - -dh-icon, -dh-icon > img { - width: 32px; - height: 32px; - display: flex; - align-items: center; - justify-content: center; - font-size: x-large; -} diff --git a/styles/dialog.less b/styles/dialog.less deleted file mode 100644 index 0a9f31e3..00000000 --- a/styles/dialog.less +++ /dev/null @@ -1,12 +0,0 @@ -.item-button { - &.checked { - background: green; - } - .item-icon { - opacity: 0; - transition: opacity 0.2s; - &.checked { - opacity: 1; - } - } -} diff --git a/styles/item.less b/styles/item.less deleted file mode 100755 index 964d69fc..00000000 --- a/styles/item.less +++ /dev/null @@ -1,59 +0,0 @@ -.daggerheart.sheet { - &.feature { - .editable { - display: flex; - flex-direction: column; - } - - .sheet-body { - flex: 1; - display: flex; - flex-direction: column; - } - .feature-description { - flex: 1; - display: flex; - flex-direction: column; - } - } - - &.class { - .class-feature { - display: flex; - img { - width: 40px; - } - button { - width: 40px; - } - } - } - - .domain-card-description { - .editor { - height: 300px; - } - } - - .item-container { - margin-top: @halfMargin; - gap: @halfMargin; - align-items: baseline; - } - - .item-sidebar { - // border-right: @thinBorder groove darkgray; - min-width: 160px; - flex: 0; - padding: @fullPadding; - - label { - margin-right: @fullMargin; - font-weight: bold; - } - - input[type='checkbox'] { - margin: 0; - } - } -} diff --git a/styles/less/actors/adversary.less b/styles/less/actors/adversary.less deleted file mode 100644 index 5b4feb26..00000000 --- a/styles/less/actors/adversary.less +++ /dev/null @@ -1,5 +0,0 @@ -.application.sheet.daggerheart.actor.dh-style.adversary { - .window-content { - overflow: auto; - } -} diff --git a/styles/less/actors/character.less b/styles/less/actors/character.less deleted file mode 100644 index e3833e3b..00000000 --- a/styles/less/actors/character.less +++ /dev/null @@ -1,11 +0,0 @@ -@import '../utils/colors.less'; -@import '../utils/fonts.less'; - -.application.sheet.daggerheart.actor.dh-style.character { - .window-content { - display: flex; - flex-direction: row; - height: 100%; - width: 100%; - } -} diff --git a/styles/less/actors/environment.less b/styles/less/actors/environment.less deleted file mode 100644 index d534de38..00000000 --- a/styles/less/actors/environment.less +++ /dev/null @@ -1,27 +0,0 @@ -.daggerheart.sheet.actor.environment { - .potential-adversary-container { - width: 100%; - height: 50px; - - .adversary-placeholder { - font-style: italic; - text-align: center; - opacity: 0.6; - } - - .adversaries-container { - display: flex; - gap: 8px; - - .adversary-container { - border: 1px solid var(--color-dark-5); - border-radius: 6px; - padding: 0 2px; - font-weight: bold; - cursor: pointer; - background-image: url(../assets/parchments/dh-parchment-dark.png); - color: var(--color-light-3); - } - } - } -} diff --git a/styles/less/applications/beastform.less b/styles/less/dialog/beastform/beastform-container.less similarity index 78% rename from styles/less/applications/beastform.less rename to styles/less/dialog/beastform/beastform-container.less index 37069bdb..df930532 100644 --- a/styles/less/applications/beastform.less +++ b/styles/less/dialog/beastform/beastform-container.less @@ -1,59 +1,46 @@ -.theme-light .application.daggerheart.dh-style.views.beastform-selection { - .beastforms-container .beastforms-tier .beastform-container .beastform-title { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } -} - -.application.daggerheart.dh-style.views.beastform-selection { - .beastforms-container { - display: flex; - flex-direction: column; - gap: 4px; - - .beastforms-tier { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - gap: 4px; - - .beastform-container { - position: relative; - display: flex; - justify-content: center; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - cursor: pointer; - - &.inactive { - opacity: 0.4; - } - - img { - width: 100%; - border-radius: 6px; - } - - .beastform-title { - position: absolute; - top: 4px; - display: flex; - flex-wrap: wrap; - font-size: 16px; - margin: 0 4px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - } - } - - footer { - margin-top: 8px; - display: flex; - - button { - flex: 1; - } - } -} +@import '../../utils/colors.less'; + +.application.daggerheart.dh-style.views.beastform-selection { + .beastforms-container { + display: flex; + flex-direction: column; + gap: 4px; + + .beastforms-tier { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + gap: 4px; + + .beastform-container { + position: relative; + display: flex; + justify-content: center; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + cursor: pointer; + + &.inactive { + opacity: 0.4; + } + + img { + width: 100%; + border-radius: 6px; + } + + .beastform-title { + position: absolute; + top: 4px; + display: flex; + flex-wrap: wrap; + font-size: 16px; + margin: 0 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + } + } +} diff --git a/styles/less/dialog/beastform/sheet.less b/styles/less/dialog/beastform/sheet.less new file mode 100644 index 00000000..dd1dff24 --- /dev/null +++ b/styles/less/dialog/beastform/sheet.less @@ -0,0 +1,21 @@ +@import '../../utils/colors.less'; +@import '../../utils/mixin.less'; + +.appTheme({ + &.beastform-selection { + .beastforms-container .beastforms-tier .beastform-container .beastform-title { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}, {}); + +.application.daggerheart.dh-style.views.beastform-selection { + footer { + margin-top: 8px; + display: flex; + + button { + flex: 1; + } + } +} diff --git a/styles/less/dialog/character-creation/creation-action-footer.less b/styles/less/dialog/character-creation/creation-action-footer.less new file mode 100644 index 00000000..29e08440 --- /dev/null +++ b/styles/less/dialog/character-creation/creation-action-footer.less @@ -0,0 +1,13 @@ +.daggerheart.dh-style.dialog.character-creation { + .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; + + button { + flex: 1; + height: 100%; + white-space: nowrap; + } + } +} diff --git a/styles/characterCreation.less b/styles/less/dialog/character-creation/selections-container.less similarity index 78% rename from styles/characterCreation.less rename to styles/less/dialog/character-creation/selections-container.less index e6548d21..0a610435 100644 --- a/styles/characterCreation.less +++ b/styles/less/dialog/character-creation/selections-container.less @@ -1,417 +1,325 @@ -@import './less/utils/colors.less'; - -.theme-light .daggerheart.dh-style.dialog.character-creation { - .tab-navigation nav a .descriptor { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - .main-selections-container { - .traits-container .suggested-traits-container .suggested-trait-container, - .creation-action-footer .footer-section nav a .descriptor, - .equipment-selection .simple-equipment-container .simple-equipment label { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -} - -.daggerheart.dh-style.dialog.character-creation { - .window-content { - gap: 16px; - - .tab { - overflow-y: auto; - } - } - - .tab-navigation { - nav { - flex: 1; - - a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - - &.disabled { - opacity: 0.4; - } - - .nav-section-text { - position: relative; - display: flex; - align-items: center; - } - - .finish-marker { - position: absolute; - align-self: center; - top: -8px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 16px; - width: 16px; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; - - &.active { - background-color: var(--color-warm-2); - } - } - - .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - } - } - } - } - - .main-selections-container { - display: flex; - flex-direction: column; - gap: 4px; - - .selections-container { - width: 140px; - display: flex; - flex-direction: column; - text-align: center; - - .card-preview-container { - border-color: light-dark(@dark-blue, @golden); - } - } - - .selections-outer-container { - display: flex; - justify-content: space-evenly; - height: 210px; - } - - .section-container { - border-radius: 8px; - border-color: light-dark(@dark-blue, @golden); - - legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - } - - .section-inner-container { - position: relative; - border-radius: 8px; - border-color: light-dark(@dark-blue, @golden); - display: flex; - justify-content: center; - - legend { - font-size: 20px; - } - - .action-button { - position: absolute; - bottom: -8px; - height: 16px; - width: 110px; - min-height: unset; - border: 1px solid light-dark(@dark-blue, @golden); - color: light-dark(@beige, @beige); - background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); - - &:hover { - background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); - filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); - } - } - } - } - - .traits-container { - text-align: center; - display: flex; - gap: 16px; - - .suggested-traits-container { - display: flex; - flex-wrap: wrap; - width: 176px; - gap: 4px; - margin-bottom: 8px; - - .suggested-trait-container { - width: 56px; - white-space: nowrap; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - - .traits-inner-container { - display: flex; - justify-content: space-evenly; - gap: 8px; - - .trait-container { - border: 1px solid light-dark(@dark-blue, @golden); - padding: 0 4px; - } - } - } - - .experiences-inner-container { - display: flex; - justify-content: space-evenly; - text-align: center; - - .experience-container { - position: relative; - display: flex; - align-items: center; - - .experience-description { - border-color: light-dark(@dark-blue, @golden); - padding-right: 24px; - } - - .experience-value { - position: absolute; - right: 0; - width: 22px; - border-left: 1px solid light-dark(@dark-blue, @golden); - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - } - } - - .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; - - .footer-section { - display: flex; - align-items: center; - gap: 32px; - - nav { - flex: 1; - gap: 8px; - border: 0; - - a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - - .nav-section-text { - position: relative; - display: flex; - align-items: center; - } - - .finish-marker { - position: absolute; - align-self: center; - top: -10px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 20px; - width: 20px; - font-size: 14px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; - - &.finished { - background-color: var(--color-warm-2); - } - } - - .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - } - } - } - - button { - flex: 1; - height: 100%; - white-space: nowrap; - } - } - } - - .main-equipment-selection { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 16px; - - &.triple { - grid-template-columns: 1fr 1fr 1fr; - } - } - - .equipment-selection { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - border: 2px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - white-space: nowrap; - } - - .equipment-subsection { - display: flex; - align-items: start; - gap: 32px; - } - - .equipment-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - } - - .simple-equipment-container { - display: flex; - flex-direction: column; - justify-content: space-evenly; - gap: 8px; - height: 100%; - - .simple-equipment { - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - position: relative; - display: flex; - justify-content: center; - - &.selectable { - cursor: pointer; - } - - &.inactive { - opacity: 0.4; - } - - label { - position: absolute; - top: -8px; - font-size: 12px; - white-space: nowrap; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - padding: 0 2px; - } - - img { - width: 60px; - height: 60px; - border-radius: 8px; - } - } - } - - .suggestion-container { - position: relative; - display: flex; - justify-content: center; - height: min-content; - border: 2px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; - } - - .suggestion-inner-container { - position: relative; - display: flex; - justify-content: center; - align-items: center; - padding: 6px; - cursor: grab; - - &.taken { - opacity: 0.4; - } - - label { - position: absolute; - top: -2px; - font-size: 12px; - } - - img { - width: 120px; - } - } - } - } - } - - .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; - - button { - flex: 1; - height: 100%; - white-space: nowrap; - } - } -} +@import '../../utils/colors.less'; + +.daggerheart.dh-style.dialog.character-creation { + .main-selections-container { + display: flex; + flex-direction: column; + gap: 4px; + + .selections-container { + width: 140px; + display: flex; + flex-direction: column; + text-align: center; + + .card-preview-container { + border-color: light-dark(@dark-blue, @golden); + } + } + + .selections-outer-container { + display: flex; + justify-content: space-evenly; + height: 210px; + } + + .section-container { + border-radius: 8px; + border-color: light-dark(@dark-blue, @golden); + + legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; + } + + .section-inner-container { + position: relative; + border-radius: 8px; + border-color: light-dark(@dark-blue, @golden); + display: flex; + justify-content: center; + + legend { + font-size: 20px; + } + + .action-button { + position: absolute; + bottom: -8px; + height: 16px; + width: 110px; + min-height: unset; + border: 1px solid light-dark(@dark-blue, @golden); + color: light-dark(@beige, @beige); + background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); + + &:hover { + background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); + filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); + } + } + } + } + + .traits-container { + text-align: center; + display: flex; + gap: 16px; + + .suggested-traits-container { + display: flex; + flex-wrap: wrap; + width: 176px; + gap: 4px; + margin-bottom: 8px; + + .suggested-trait-container { + width: 56px; + white-space: nowrap; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + + .traits-inner-container { + display: flex; + justify-content: space-evenly; + gap: 8px; + + .trait-container { + border: 1px solid light-dark(@dark-blue, @golden); + padding: 0 4px; + } + } + } + + .experiences-inner-container { + display: flex; + justify-content: space-evenly; + text-align: center; + + .experience-container { + position: relative; + display: flex; + align-items: center; + + .experience-description { + border-color: light-dark(@dark-blue, @golden); + padding-right: 24px; + } + + .experience-value { + position: absolute; + right: 0; + width: 22px; + border-left: 1px solid light-dark(@dark-blue, @golden); + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + } + } + + .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; + + .footer-section { + display: flex; + align-items: center; + gap: 32px; + + nav { + flex: 1; + gap: 8px; + border: 0; + + a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + + .nav-section-text { + position: relative; + display: flex; + align-items: center; + } + + .finish-marker { + position: absolute; + align-self: center; + top: -10px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 20px; + width: 20px; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; + + &.finished { + background-color: var(--color-warm-2); + } + } + + .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + } + } + } + + button { + flex: 1; + height: 100%; + white-space: nowrap; + } + } + } + + .main-equipment-selection { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 16px; + + &.triple { + grid-template-columns: 1fr 1fr 1fr; + } + } + + .equipment-selection { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + border: 2px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + + legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; + white-space: nowrap; + } + + .equipment-subsection { + display: flex; + align-items: start; + gap: 32px; + } + + .equipment-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + } + + .simple-equipment-container { + display: flex; + flex-direction: column; + justify-content: space-evenly; + gap: 8px; + height: 100%; + + .simple-equipment { + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + position: relative; + display: flex; + justify-content: center; + + &.selectable { + cursor: pointer; + } + + &.inactive { + opacity: 0.4; + } + + label { + position: absolute; + top: -8px; + font-size: 12px; + white-space: nowrap; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + padding: 0 2px; + } + + img { + width: 60px; + height: 60px; + border-radius: 8px; + } + } + } + + .suggestion-container { + position: relative; + display: flex; + justify-content: center; + height: min-content; + border: 2px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + + legend { + margin-left: auto; + margin-right: auto; + font-size: 12px; + } + + .suggestion-inner-container { + position: relative; + display: flex; + justify-content: center; + align-items: center; + padding: 6px; + cursor: grab; + + &.taken { + opacity: 0.4; + } + + label { + position: absolute; + top: -2px; + font-size: 12px; + } + + img { + width: 120px; + } + } + } + } + } +} diff --git a/styles/less/dialog/character-creation/sheet.less b/styles/less/dialog/character-creation/sheet.less new file mode 100644 index 00000000..5ee3f9b2 --- /dev/null +++ b/styles/less/dialog/character-creation/sheet.less @@ -0,0 +1,27 @@ +@import '../../utils/colors.less'; +@import '../../utils/mixin.less'; + +.appTheme({ + .character-creation { + .tab-navigation nav a .descriptor { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + .main-selections-container { + .traits-container .suggested-traits-container .suggested-trait-container, + .creation-action-footer .footer-section nav a .descriptor, + .equipment-selection .simple-equipment-container .simple-equipment label { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +} +}, {}); + +.daggerheart.dh-style.dialog.character-creation { + .window-content { + gap: 16px; + + .tab { + overflow-y: auto; + } + } +} diff --git a/styles/less/dialog/character-creation/tab-navigation.less b/styles/less/dialog/character-creation/tab-navigation.less new file mode 100644 index 00000000..d951a7b2 --- /dev/null +++ b/styles/less/dialog/character-creation/tab-navigation.less @@ -0,0 +1,62 @@ +@import '../../utils/colors.less'; + +.daggerheart.dh-style.dialog.character-creation { + .tab-navigation { + nav { + flex: 1; + + a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; + + &.disabled { + opacity: 0.4; + } + + .nav-section-text { + position: relative; + display: flex; + align-items: center; + } + + .finish-marker { + position: absolute; + align-self: center; + top: -8px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 16px; + width: 16px; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; + + &.active { + background-color: var(--color-warm-2); + } + } + + .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + } + } + } + } +} diff --git a/styles/damageReduction.less b/styles/less/dialog/damage-reduction/damage-reduction-container.less similarity index 98% rename from styles/damageReduction.less rename to styles/less/dialog/damage-reduction/damage-reduction-container.less index e3ffc2e9..25ca5ff9 100644 --- a/styles/damageReduction.less +++ b/styles/less/dialog/damage-reduction/damage-reduction-container.less @@ -1,8 +1,6 @@ -.daggerheart.views.damage-reduction { - .window-content { - padding: 8px 0; - } +@import '../../utils/colors.less'; +.daggerheart.views.damage-reduction { .damage-reduction-container { display: flex; flex-direction: column; diff --git a/styles/less/dialog/damage-reduction/sheets.less b/styles/less/dialog/damage-reduction/sheets.less new file mode 100644 index 00000000..836a2b2f --- /dev/null +++ b/styles/less/dialog/damage-reduction/sheets.less @@ -0,0 +1,7 @@ +@import '../../utils/colors.less'; + +.daggerheart.views.damage-reduction { + .window-content { + padding: 8px 0; + } +} diff --git a/styles/less/dialog/downtime/downtime-container.less b/styles/less/dialog/downtime/downtime-container.less new file mode 100644 index 00000000..9b2c842c --- /dev/null +++ b/styles/less/dialog/downtime/downtime-container.less @@ -0,0 +1,81 @@ +@import '../../utils/spacing.less'; +@import '../../utils/colors.less'; + +.daggerheart.views { + .downtime-container { + .downtime-header { + margin: 0; + color: light-dark(@dark-blue, @golden); + text-align: center; + } + + .activity-container { + display: flex; + align-items: center; + padding: 8px; + + .activity-title { + flex: 1; + display: flex; + align-items: center; + + .activity-title-text { + font-size: 24px; + font-weight: bold; + } + + .activity-image { + width: 80px; + position: relative; + display: flex; + justify-content: center; + margin-right: 8px; + border: 2px solid black; + border-radius: 50%; + cursor: pointer; + + .activity-select-label { + position: absolute; + top: -9px; + font-size: 14px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + padding: 0 8px; + line-height: 1; + font-weight: bold; + } + + img { + border-radius: 50%; + } + + &:hover, + &.selected { + filter: drop-shadow(0 0 6px gold); + } + } + + .custom-name-input { + font-size: 24px; + font-weight: bold; + padding: 0; + background: transparent; + color: rgb(239, 230, 216); + } + } + + .activity-body { + flex: 1; + font-style: italic; + } + } + } + + &.downtime { + .activity-text-area { + resize: none; + } + } +} diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less new file mode 100644 index 00000000..ec3ef200 --- /dev/null +++ b/styles/less/dialog/index.less @@ -0,0 +1,19 @@ +@import './level-up/navigation-container.less'; +@import './level-up/selections-container.less'; +@import './level-up/sheet.less'; +@import './level-up/summary-container.less'; +@import './level-up/tiers-container.less'; + +@import './downtime/downtime-container.less'; + +@import './beastform/beastform-container.less'; +@import './beastform/sheet.less'; + +@import './character-creation/creation-action-footer.less'; +@import './character-creation/selections-container.less'; +@import './character-creation/sheet.less'; +@import './character-creation/tab-navigation.less'; + +@import './dice-roll/roll-selection.less'; +@import './damage-reduction/damage-reduction-container.less'; +@import './damage-reduction/sheets.less'; diff --git a/styles/less/dialog/level-up/navigation-container.less b/styles/less/dialog/level-up/navigation-container.less new file mode 100644 index 00000000..b52abf20 --- /dev/null +++ b/styles/less/dialog/level-up/navigation-container.less @@ -0,0 +1,30 @@ +.daggerheart.levelup { + .levelup-navigation-container { + display: flex; + align-items: center; + gap: 22px; + height: 36px; + + nav { + flex: 1; + + .levelup-tab-container { + display: flex; + align-items: center; + gap: 4px; + } + } + + .levelup-navigation-actions { + width: 306px; + display: flex; + justify-content: end; + gap: 16px; + margin-right: 4px; + + * { + width: calc(50% - 8px); + } + } + } +} diff --git a/styles/less/dialog/level-up/selections-container.less b/styles/less/dialog/level-up/selections-container.less new file mode 100644 index 00000000..b04a6182 --- /dev/null +++ b/styles/less/dialog/level-up/selections-container.less @@ -0,0 +1,108 @@ +.daggerheart.levelup { + .levelup-selections-container { + .achievement-experience-cards { + display: flex; + gap: 8px; + + .achievement-experience-card { + border: 1px solid; + border-radius: 4px; + padding-right: 4px; + font-size: 18px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; + + .achievement-experience-marker { + border: 1px solid; + border-radius: 50%; + height: 18px; + width: 18px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + } + } + } + + .levelup-card-selection { + display: flex; + flex-wrap: wrap; + gap: 40px; + + .card-preview-container { + width: calc(100% * (1 / 5)); + } + + .levelup-domains-selection-container { + display: flex; + flex-direction: column; + gap: 8px; + + .levelup-domain-selection-container { + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + position: relative; + cursor: pointer; + + &.disabled { + pointer-events: none; + opacity: 0.4; + } + + .levelup-domain-label { + position: absolute; + text-align: center; + top: 4px; + background: grey; + padding: 0 12px; + border-radius: 6px; + } + + img { + height: 124px; + } + + .levelup-domain-selected { + position: absolute; + height: 54px; + width: 54px; + border-radius: 50%; + border: 2px solid; + font-size: 48px; + display: flex; + align-items: center; + justify-content: center; + background-image: url(../assets/parchments/dh-parchment-light.png); + color: var(--color-dark-5); + top: calc(50% - 29px); + + i { + position: relative; + right: 2px; + } + } + } + } + } + + .levelup-selections-title { + display: flex; + align-items: center; + gap: 4px; + } + + .levelup-radio-choices { + display: flex; + gap: 8px; + + label { + flex: 0; + } + } + } +} diff --git a/styles/less/dialog/level-up/sheet.less b/styles/less/dialog/level-up/sheet.less new file mode 100644 index 00000000..77e7244d --- /dev/null +++ b/styles/less/dialog/level-up/sheet.less @@ -0,0 +1,37 @@ +@import '../../utils/mixin.less'; + +.appTheme({}, { + &.levelup { + .tiers-container { + .tier-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + } +}); + +.daggerheart.levelup { + .window-content { + max-height: 960px; + overflow: auto; + } + + div[data-application-part='form'] { + display: flex; + flex-direction: column; + gap: 8px; + } + + section { + .section-container { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 8px; + } + } + + .levelup-footer { + display: flex; + } +} diff --git a/styles/less/dialog/level-up/summary-container.less b/styles/less/dialog/level-up/summary-container.less new file mode 100644 index 00000000..fb221b07 --- /dev/null +++ b/styles/less/dialog/level-up/summary-container.less @@ -0,0 +1,37 @@ +.daggerheart.levelup { + .levelup-summary-container { + .level-achievements-container, + .level-advancements-container { + display: flex; + flex-direction: column; + gap: 8px; + + h2, + h3, + h4, + h5 { + margin: 0; + color: var(--color-text-secondary); + } + } + + .increase-container { + display: flex; + align-items: center; + gap: 4px; + font-size: 20px; + } + + .summary-selection-container { + display: flex; + gap: 8px; + + .summary-selection { + border: 2px solid; + border-radius: 6px; + padding: 0 4px; + font-size: 18px; + } + } + } +} diff --git a/styles/less/dialog/level-up/tiers-container.less b/styles/less/dialog/level-up/tiers-container.less new file mode 100644 index 00000000..e666b128 --- /dev/null +++ b/styles/less/dialog/level-up/tiers-container.less @@ -0,0 +1,65 @@ +.daggerheart.levelup { + .tiers-container { + display: flex; + gap: 16px; + + .tier-container { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; + background-image: url('../assets/parchments/dh-parchment-dark.png'); + + &.inactive { + opacity: 0.4; + pointer-events: none; + } + + legend { + margin-left: auto; + margin-right: auto; + font-size: 22px; + font-weight: bold; + padding: 0 12px; + } + + .checkbox-group-container { + display: grid; + grid-template-columns: 1fr 3fr; + gap: 4px; + + .checkboxes-container { + display: flex; + justify-content: end; + gap: 4px; + + .checkbox-grouping-coontainer { + display: flex; + height: min-content; + + &.multi { + border: 2px solid grey; + padding: 2.4px 2.5px 0; + border-radius: 4px; + gap: 2px; + + .selection-checkbox { + margin-left: 0; + margin-right: 0; + } + } + + .selection-checkbox { + margin: 0; + } + } + } + + .checkbox-group-label { + font-size: 14px; + font-style: italic; + } + } + } + } +} diff --git a/styles/less/global/index.less b/styles/less/global/index.less new file mode 100644 index 00000000..461813c1 --- /dev/null +++ b/styles/less/global/index.less @@ -0,0 +1,14 @@ +@import './sheet.less'; +@import './dialog.less'; +@import './elements.less'; +@import './tab-navigation.less'; +@import './tab-form-footer.less'; +@import './tab-actions.less'; +@import './tab-features.less'; +@import './tab-effects.less'; +@import './item-header.less'; +@import './feature-section.less'; +@import './inventory-item.less'; +@import './inventory-fieldset-items.less'; +@import './prose-mirror.less'; +@import './filter-menu.less'; diff --git a/styles/less/items/class.css b/styles/less/items/class.css deleted file mode 100644 index 19f17576..00000000 --- a/styles/less/items/class.css +++ /dev/null @@ -1,132 +0,0 @@ -@font-face { - font-family: 'Cinzel'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype'); -} -@font-face { - font-family: 'Cinzel'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype'); -} -@font-face { - font-family: 'Cinzel Decorative'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzeldecorative/v17/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf) - format('truetype'); -} -@font-face { - font-family: 'Montserrat'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); -} -@font-face { - font-family: 'Montserrat'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); -} -.application.sheet.daggerheart.dh-style h1 { - font-family: 'Cinzel Decorative', serif; - margin: 0; - border: none; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h2, -.application.sheet.daggerheart.dh-style h3 { - font-family: 'Cinzel', serif; - margin: 0; - border: none; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h4 { - font-family: 'Montserrat', sans-serif; - font-size: 14px; - border: none; - font-weight: 700; - margin: 0; - text-shadow: none; - color: #f3c267; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h5 { - font-size: 14px; - color: #f3c267; - margin: 0; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style p, -.application.sheet.daggerheart.dh-style span { - font-family: 'Montserrat', sans-serif; -} -.application.sheet.daggerheart.dh-style small { - font-family: 'Montserrat', sans-serif; - opacity: 0.8; -} -.application.sheet.daggerheart.dh-style.class .tagify { - background: light-dark(transparent, transparent); - border: 1px solid light-dark(#222, #efe6d8); - height: 34px; - border-radius: 3px; - margin-right: 1px; -} -.application.sheet.daggerheart.dh-style.class .tagify tag div { - display: flex; - justify-content: space-between; - align-items: center; - height: 22px; -} -.application.sheet.daggerheart.dh-style.class .tagify tag div span { - font-weight: 400; -} -.application.sheet.daggerheart.dh-style.class .tagify tag div img { - margin-left: 8px; - height: 20px; - width: 20px; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section { - display: grid; - gap: 10px; - grid-template-columns: 1fr 1.5fr 1.5fr; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items { - margin-bottom: 10px; - width: 100%; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child { - margin-bottom: 0px; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line { - display: grid; - align-items: center; - gap: 10px; - grid-template-columns: 1fr 3fr 1fr; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a { - text-shadow: none; -} diff --git a/styles/less/applications/adversary-settings/experiences.less b/styles/less/sheets-settings/adversary-settings/experiences.less similarity index 100% rename from styles/less/applications/adversary-settings/experiences.less rename to styles/less/sheets-settings/adversary-settings/experiences.less diff --git a/styles/less/applications/adversary-settings/features.less b/styles/less/sheets-settings/adversary-settings/features.less similarity index 100% rename from styles/less/applications/adversary-settings/features.less rename to styles/less/sheets-settings/adversary-settings/features.less diff --git a/styles/less/applications/adversary-settings/sheet.less b/styles/less/sheets-settings/adversary-settings/sheet.less similarity index 100% rename from styles/less/applications/adversary-settings/sheet.less rename to styles/less/sheets-settings/adversary-settings/sheet.less diff --git a/styles/less/applications/environment-settings/adversaries.less b/styles/less/sheets-settings/environment-settings/adversaries.less similarity index 100% rename from styles/less/applications/environment-settings/adversaries.less rename to styles/less/sheets-settings/environment-settings/adversaries.less diff --git a/styles/less/applications/environment-settings/features.less b/styles/less/sheets-settings/environment-settings/features.less similarity index 100% rename from styles/less/applications/environment-settings/features.less rename to styles/less/sheets-settings/environment-settings/features.less diff --git a/styles/less/applications/header.less b/styles/less/sheets-settings/header.less similarity index 100% rename from styles/less/applications/header.less rename to styles/less/sheets-settings/header.less diff --git a/styles/less/sheets-settings/index.less b/styles/less/sheets-settings/index.less new file mode 100644 index 00000000..77fa6d94 --- /dev/null +++ b/styles/less/sheets-settings/index.less @@ -0,0 +1,7 @@ +@import './header.less'; +@import './adversary-settings/sheet.less'; +@import './adversary-settings/experiences.less'; +@import './adversary-settings/features.less'; + +@import './environment-settings/features.less'; +@import './environment-settings/adversaries.less'; \ No newline at end of file diff --git a/styles/less/actors/adversary/actions.less b/styles/less/sheets/actors/adversary/actions.less similarity index 87% rename from styles/less/actors/adversary/actions.less rename to styles/less/sheets/actors/adversary/actions.less index 6ca46e90..8370abc3 100644 --- a/styles/less/actors/adversary/actions.less +++ b/styles/less/sheets/actors/adversary/actions.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.adversary { .tab.features { diff --git a/styles/less/actors/adversary/header.less b/styles/less/sheets/actors/adversary/header.less similarity index 92% rename from styles/less/actors/adversary/header.less rename to styles/less/sheets/actors/adversary/header.less index 4b962466..9ba00355 100644 --- a/styles/less/actors/adversary/header.less +++ b/styles/less/sheets/actors/adversary/header.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.adversary { .adversary-header-sheet { diff --git a/styles/less/actors/adversary/sheet.less b/styles/less/sheets/actors/adversary/sheet.less similarity index 84% rename from styles/less/actors/adversary/sheet.less rename to styles/less/sheets/actors/adversary/sheet.less index f5507f36..baa80bb3 100644 --- a/styles/less/actors/adversary/sheet.less +++ b/styles/less/sheets/actors/adversary/sheet.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.adversary { .window-content { diff --git a/styles/less/actors/adversary/sidebar.less b/styles/less/sheets/actors/adversary/sidebar.less similarity index 93% rename from styles/less/actors/adversary/sidebar.less rename to styles/less/sheets/actors/adversary/sidebar.less index df2ca161..1dabf5ae 100644 --- a/styles/less/actors/adversary/sidebar.less +++ b/styles/less/sheets/actors/adversary/sidebar.less @@ -1,16 +1,26 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; + +.appTheme({ + &.adversary { + .adversary-sidebar-sheet { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}, { + &.adversary { + .adversary-sidebar-sheet { + background: transparent; + } + } +}); .application.sheet.daggerheart.actor.dh-style.adversary { .adversary-sidebar-sheet { width: 275px; min-width: 275px; border-right: 1px solid light-dark(@dark-blue, @golden); - background-image: url('../assets/parchments/dh-parchment-dark.png'); - - .theme-light & { - background: transparent; - } .portrait { position: relative; diff --git a/styles/less/actors/character/biography.less b/styles/less/sheets/actors/character/biography.less similarity index 87% rename from styles/less/actors/character/biography.less rename to styles/less/sheets/actors/character/biography.less index 635cf8d5..e07d7080 100644 --- a/styles/less/actors/character/biography.less +++ b/styles/less/sheets/actors/character/biography.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.character { .tab.biography { diff --git a/styles/less/actors/character/features.less b/styles/less/sheets/actors/character/features.less similarity index 87% rename from styles/less/actors/character/features.less rename to styles/less/sheets/actors/character/features.less index 6fc86ac3..767544c1 100644 --- a/styles/less/actors/character/features.less +++ b/styles/less/sheets/actors/character/features.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.character { .tab.features { diff --git a/styles/less/actors/character/header.less b/styles/less/sheets/actors/character/header.less similarity index 98% rename from styles/less/actors/character/header.less rename to styles/less/sheets/actors/character/header.less index 300314da..6110fcc6 100644 --- a/styles/less/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -1,5 +1,6 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; // Theme header backgrounds .appTheme({ diff --git a/styles/less/actors/character/inventory.less b/styles/less/sheets/actors/character/inventory.less similarity index 96% rename from styles/less/actors/character/inventory.less rename to styles/less/sheets/actors/character/inventory.less index 516b01b0..43669d7f 100644 --- a/styles/less/actors/character/inventory.less +++ b/styles/less/sheets/actors/character/inventory.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.character { .tab.inventory { diff --git a/styles/less/actors/character/loadout.less b/styles/less/sheets/actors/character/loadout.less similarity index 97% rename from styles/less/actors/character/loadout.less rename to styles/less/sheets/actors/character/loadout.less index 72393597..cdf0e2e4 100644 --- a/styles/less/actors/character/loadout.less +++ b/styles/less/sheets/actors/character/loadout.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.character { .tab.loadout { diff --git a/styles/less/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less similarity index 88% rename from styles/less/actors/character/sheet.less rename to styles/less/sheets/actors/character/sheet.less index f3e0cd74..f2c9bb1a 100644 --- a/styles/less/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.character { .window-content { diff --git a/styles/less/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less similarity index 98% rename from styles/less/actors/character/sidebar.less rename to styles/less/sheets/actors/character/sidebar.less index 4c637839..d6ceab46 100644 --- a/styles/less/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -1,5 +1,6 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; // Theme sidebar backgrounds .appTheme({ diff --git a/styles/less/actors/companion/details.less b/styles/less/sheets/actors/companion/details.less similarity index 95% rename from styles/less/actors/companion/details.less rename to styles/less/sheets/actors/companion/details.less index 4da8d126..4edf8aa9 100644 --- a/styles/less/actors/companion/details.less +++ b/styles/less/sheets/actors/companion/details.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.companion { .partner-section, diff --git a/styles/less/actors/companion/header.less b/styles/less/sheets/actors/companion/header.less similarity index 98% rename from styles/less/actors/companion/header.less rename to styles/less/sheets/actors/companion/header.less index daa20e93..fac32ea5 100644 --- a/styles/less/actors/companion/header.less +++ b/styles/less/sheets/actors/companion/header.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.companion { .companion-header-sheet { diff --git a/styles/less/actors/companion/sheet.less b/styles/less/sheets/actors/companion/sheet.less similarity index 52% rename from styles/less/actors/companion/sheet.less rename to styles/less/sheets/actors/companion/sheet.less index 22c5fc0b..f31679ba 100644 --- a/styles/less/actors/companion/sheet.less +++ b/styles/less/sheets/actors/companion/sheet.less @@ -1,3 +1,5 @@ +@import '../../../utils/mixin.less'; + // Theme header backgrounds .appTheme({ &.companion { @@ -8,15 +10,3 @@ background: url('../assets/parchments/dh-parchment-light.png'); } }); - -.application.sheet.daggerheart.actor.dh-style.companion { - // .profile { - // height: 80px; - // width: 80px; - // } - - // .temp-container { - // position: relative; - // top: 32px; - // } -} diff --git a/styles/less/actors/environment/header.less b/styles/less/sheets/actors/environment/header.less similarity index 95% rename from styles/less/actors/environment/header.less rename to styles/less/sheets/actors/environment/header.less index fce7943f..87be3314 100644 --- a/styles/less/actors/environment/header.less +++ b/styles/less/sheets/actors/environment/header.less @@ -1,5 +1,5 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; .application.sheet.daggerheart.actor.dh-style.environment { .environment-header-sheet { diff --git a/styles/less/actors/environment/sheet.less b/styles/less/sheets/actors/environment/sheet.less similarity index 80% rename from styles/less/actors/environment/sheet.less rename to styles/less/sheets/actors/environment/sheet.less index 733f105e..74cec028 100644 --- a/styles/less/actors/environment/sheet.less +++ b/styles/less/sheets/actors/environment/sheet.less @@ -1,5 +1,6 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; .appTheme({ &.environment { diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less new file mode 100644 index 00000000..cbee35ac --- /dev/null +++ b/styles/less/sheets/index.less @@ -0,0 +1,23 @@ +@import './actors/adversary/actions.less'; +@import './actors/adversary/header.less'; +@import './actors/adversary/sheet.less'; +@import './actors/adversary/sidebar.less'; + +@import './actors/character/biography.less'; +@import './actors/character/features.less'; +@import './actors/character/header.less'; +@import './actors/character/inventory.less'; +@import './actors/character/loadout.less'; +@import './actors/character/sheet.less'; +@import './actors/character/sidebar.less'; + +@import './actors/companion/details.less'; +@import './actors/companion/header.less'; +@import './actors/companion/sheet.less'; + +@import './actors/environment/header.less'; +@import './actors/environment/sheet.less'; + +@import './items/class.less'; +@import './items/domain-card.less'; +@import './items/feature.less'; diff --git a/styles/less/items/class.less b/styles/less/sheets/items/class.less similarity index 94% rename from styles/less/items/class.less rename to styles/less/sheets/items/class.less index f8004d31..d32f60d6 100644 --- a/styles/less/items/class.less +++ b/styles/less/sheets/items/class.less @@ -1,5 +1,5 @@ -@import '../utils/colors.less'; -@import '../utils/fonts.less'; +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; .application.sheet.daggerheart.dh-style.class { .tab.settings { diff --git a/styles/less/items/domainCard.less b/styles/less/sheets/items/domain-card.less similarity index 77% rename from styles/less/items/domainCard.less rename to styles/less/sheets/items/domain-card.less index 93c00558..a784b3a2 100644 --- a/styles/less/items/domainCard.less +++ b/styles/less/sheets/items/domain-card.less @@ -1,5 +1,5 @@ -@import '../utils/colors.less'; -@import '../utils/fonts.less'; +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; .application.sheet.daggerheart.dh-style.domain-card { section.tab { diff --git a/styles/less/items/feature.less b/styles/less/sheets/items/feature.less old mode 100755 new mode 100644 similarity index 84% rename from styles/less/items/feature.less rename to styles/less/sheets/items/feature.less index c27cfb65..b7493f15 --- a/styles/less/items/feature.less +++ b/styles/less/sheets/items/feature.less @@ -1,5 +1,5 @@ -@import '../utils/colors.less'; -@import '../utils/fonts.less'; +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; .application.sheet.daggerheart.dh-style.feature { .item-sheet-header { diff --git a/styles/chat.less b/styles/less/ui/chat/chat.less similarity index 60% rename from styles/chat.less rename to styles/less/ui/chat/chat.less index f454bec7..945bda3f 100644 --- a/styles/chat.less +++ b/styles/less/ui/chat/chat.less @@ -1,36 +1,5 @@ -.chat-message { - .duality-modifiers, - .duality-result, - .dice-title { - display: none; - } -} - -fieldset.daggerheart.chat { - padding: 0; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - legend { - display: flex; - align-items: center; - gap: 5px; - &:before, - &:after { - content: '\f0d8'; - font-family: 'Font Awesome 6 Pro'; - } - } - &.expanded { - legend:before, - legend:after { - content: '\f0d7'; - } - } - .daggerheart.chat { - margin-top: 5px; - } -} +@import '../../utils/colors.less'; +@import '../../utils/spacing.less'; .daggerheart.chat { &.downtime { @@ -408,194 +377,3 @@ fieldset.daggerheart.chat { } } } - -.theme-colorful { - .chat-message.duality { - border-color: black; - padding: 8px 0 0 0; - fieldset.daggerheart.chat { - border-top-width: 0; - display: contents; - legend { - &:before, - &:after { - display: none; - } - } - } - .message-header { - color: var(--color-light-3); - padding: 0 8px; - } - &.hope { - background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); - } - &.fear { - background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart); - } - &.critical { - background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart); - } - .chat-message header { - color: var(--color-light-3); - } - > * { - padding: 0 8px; - } - .message-content { - .duality-modifiers, - .duality-result, - .dice-title { - display: flex; - } - .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; - .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; - } - } - .dice-flavor { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - border-bottom: 1px solid; - display: flex; - align-items: end; - justify-content: space-between; - padding: 0 8px; - margin: 0 -8px 2px; - font-weight: unset; - } - .dice-result { - .duality-modifiers { - display: flex; // Default => display: none; - gap: 2px; - margin-bottom: 4px; - .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; - } - } - .dice-formula, - > .dice-total, - .part-header { - display: none; - } - .dice-tooltip { - grid-template-rows: 1fr; - .wrapper { - .tooltip-part { - display: flex; - align-items: end; - gap: 0.25rem; - .dice { - .dice-rolls { - margin-bottom: 0; - &.duality { - li { - display: flex; - align-items: center; - justify-content: center; - position: relative; - background: unset; - line-height: unset; - font-weight: unset; - } - } - } - } - .duality-modifier { - display: flex; - margin-bottom: 6px; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-size: var(--font-size-16); - } - } - } - } - .target-selection { - label { - color: var(--color-light-1); - } - } - .target-section { - margin: 4px 0; - border: 2px solid; - margin-top: 5px; - .dice-total { - box-shadow: unset; - border: unset; - border-radius: unset; - font-size: var(--font-size-18); - } - } - .dice-actions { - justify-content: space-between; - &.duality-alone { - justify-content: end; - margin-top: -20px; - } - > * { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - } - .duality-action { - border-radius: 0 6px 0 0; - margin-left: -8px; - &.duality-action-effect { - border-top-left-radius: 6px; - margin-left: initial; - } - } - .duality-result { - border-radius: 6px 0 0 0; - margin-right: -8px; - } - } - .duality-result { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - margin-left: auto; - align-self: center; - border-radius: 6px; - } - } - } - button { - &.inner-button { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - border-color: black; - } - } - } -} diff --git a/styles/less/ui/chat/sheet.less b/styles/less/ui/chat/sheet.less new file mode 100644 index 00000000..683b91f1 --- /dev/null +++ b/styles/less/ui/chat/sheet.less @@ -0,0 +1,33 @@ +.chat-message { + .duality-modifiers, + .duality-result, + .dice-title { + display: none; + } +} + +fieldset.daggerheart.chat { + padding: 0; + border-left-width: 0; + border-right-width: 0; + border-bottom-width: 0; + legend { + display: flex; + align-items: center; + gap: 5px; + &:before, + &:after { + content: '\f0d8'; + font-family: 'Font Awesome 6 Pro'; + } + } + &.expanded { + legend:before, + legend:after { + content: '\f0d7'; + } + } + .daggerheart.chat { + margin-top: 5px; + } +} diff --git a/styles/less/ui/chat/theme-colorful.less b/styles/less/ui/chat/theme-colorful.less new file mode 100644 index 00000000..adbbc5ca --- /dev/null +++ b/styles/less/ui/chat/theme-colorful.less @@ -0,0 +1,193 @@ +@import '../../utils/colors.less'; +@import '../../utils/spacing.less'; + +.theme-colorful { + .chat-message.duality { + border-color: black; + padding: 8px 0 0 0; + fieldset.daggerheart.chat { + border-top-width: 0; + display: contents; + legend { + &:before, + &:after { + display: none; + } + } + } + .message-header { + color: var(--color-light-3); + padding: 0 8px; + } + &.hope { + background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); + } + &.fear { + background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart); + } + &.critical { + background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart); + } + .chat-message header { + color: var(--color-light-3); + } + > * { + padding: 0 8px; + } + .message-content { + .duality-modifiers, + .duality-result, + .dice-title { + display: flex; + } + .duality-modifiers { + display: flex; + gap: 2px; + margin-bottom: 4px; + .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; + } + } + .dice-flavor { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + border-bottom: 1px solid; + display: flex; + align-items: end; + justify-content: space-between; + padding: 0 8px; + margin: 0 -8px 2px; + font-weight: unset; + } + .dice-result { + .duality-modifiers { + display: flex; // Default => display: none; + gap: 2px; + margin-bottom: 4px; + .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; + } + } + .dice-formula, + > .dice-total, + .part-header { + display: none; + } + .dice-tooltip { + grid-template-rows: 1fr; + .wrapper { + .tooltip-part { + display: flex; + align-items: end; + gap: 0.25rem; + .dice { + .dice-rolls { + margin-bottom: 0; + &.duality { + li { + display: flex; + align-items: center; + justify-content: center; + position: relative; + background: unset; + line-height: unset; + font-weight: unset; + } + } + } + } + .duality-modifier { + display: flex; + margin-bottom: 6px; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-size: var(--font-size-16); + } + } + } + } + .target-selection { + label { + color: var(--color-light-1); + } + } + .target-section { + margin: 4px 0; + border: 2px solid; + margin-top: 5px; + .dice-total { + box-shadow: unset; + border: unset; + border-radius: unset; + font-size: var(--font-size-18); + } + } + .dice-actions { + justify-content: space-between; + &.duality-alone { + justify-content: end; + margin-top: -20px; + } + > * { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; + } + .duality-action { + border-radius: 0 6px 0 0; + margin-left: -8px; + &.duality-action-effect { + border-top-left-radius: 6px; + margin-left: initial; + } + } + .duality-result { + border-radius: 6px 0 0 0; + margin-right: -8px; + } + } + .duality-result { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; + margin-left: auto; + align-self: center; + border-radius: 6px; + } + } + } + button { + &.inner-button { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + border-color: black; + } + } + } +} diff --git a/styles/less/ui/combat-sidebar/combat-sidebar.less b/styles/less/ui/combat-sidebar/combat-sidebar.less new file mode 100644 index 00000000..e247e5b4 --- /dev/null +++ b/styles/less/ui/combat-sidebar/combat-sidebar.less @@ -0,0 +1,6 @@ +.combat-sidebar { + h4 { + margin: 0; + text-align: center; + } +} diff --git a/styles/less/ui/combat-sidebar/combatant-controls.less b/styles/less/ui/combat-sidebar/combatant-controls.less new file mode 100644 index 00000000..4a3329d6 --- /dev/null +++ b/styles/less/ui/combat-sidebar/combatant-controls.less @@ -0,0 +1,5 @@ +.combat-sidebar { + .combatant-controls { + flex: 0; + } +} diff --git a/styles/less/ui/combat-sidebar/encounter-controls.less b/styles/less/ui/combat-sidebar/encounter-controls.less new file mode 100644 index 00000000..8a2981b5 --- /dev/null +++ b/styles/less/ui/combat-sidebar/encounter-controls.less @@ -0,0 +1,48 @@ +.combat-sidebar { + .encounter-controls.combat { + justify-content: space-between; + + .encounter-fear-controls { + display: flex; + align-items: center; + gap: 8px; + + .encounter-fear-dice-container { + display: flex; + gap: 2px; + + .encounter-control-fear-container { + display: flex; + position: relative; + align-items: center; + justify-content: center; + color: black; + + .dice { + height: 22px; + width: 22px; + } + + .encounter-control-fear { + position: absolute; + font-size: 16px; + } + + .encounter-control-counter { + position: absolute; + right: -10px; + color: var(--color-text-secondary); + } + } + } + + .encounter-countdowns { + color: var(--content-link-icon-color); + } + } + + .control-buttons { + width: min-content; + } + } +} diff --git a/styles/less/ui/combat-sidebar/spotlight-control.less b/styles/less/ui/combat-sidebar/spotlight-control.less new file mode 100644 index 00000000..2659cc90 --- /dev/null +++ b/styles/less/ui/combat-sidebar/spotlight-control.less @@ -0,0 +1,19 @@ +.combat-sidebar { + .spotlight-control { + font-size: 26px; + + &:focus { + outline: none; + box-shadow: none; + } + + &.discrete:hover { + background: inherit; + } + + &.requesting { + filter: drop-shadow(0 0 3px gold); + color: var(--button-hover-text-color); + } + } +} diff --git a/styles/less/ui/combat-sidebar/token-actions.less b/styles/less/ui/combat-sidebar/token-actions.less new file mode 100644 index 00000000..23be22e8 --- /dev/null +++ b/styles/less/ui/combat-sidebar/token-actions.less @@ -0,0 +1,48 @@ +.combat-sidebar { + .token-actions { + align-self: stretch; + display: flex; + align-items: top; + justify-content: center; + gap: 16px; + + .action-tokens { + display: flex; + gap: 4px; + + .action-token { + height: 22px; + width: 22px; + border: 1px solid; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 10px; + padding: 8px; + --button-size: 0; + + &.used { + opacity: 0.5; + background: transparent; + } + } + } + + button { + font-size: 22px; + height: 24px; + width: 24px; + + &.main { + background: var(--button-hover-background-color); + color: var(--button-hover-text-color); + border-color: var(--button-hover-border-color); + + &:hover { + filter: drop-shadow(0 0 3px var(--button-hover-text-color)); + } + } + } + } +} diff --git a/styles/less/ui/countdown/countdown.less b/styles/less/ui/countdown/countdown.less new file mode 100644 index 00000000..ecc9f1b8 --- /dev/null +++ b/styles/less/ui/countdown/countdown.less @@ -0,0 +1,61 @@ +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.daggerheart.dh-style.countdown { + fieldset { + align-items: center; + margin-top: 5px; + border-radius: 6px; + border-color: light-dark(@dark-blue, @golden); + + legend { + font-family: @font-body; + font-weight: bold; + color: light-dark(@dark-blue, @golden); + + a { + text-shadow: none; + } + } + } + + .minimized-view { + display: flex; + gap: 8px; + flex-wrap: wrap; + + .mini-countdown-container { + width: fit-content; + display: flex; + align-items: center; + gap: 8px; + border: 2px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + padding: 0 4px 0 0; + background-image: url('../assets/parchments/dh-parchment-light.png'); + color: light-dark(@beige, @dark); + cursor: pointer; + + &.disabled { + cursor: initial; + } + + img { + width: 30px; + height: 30px; + border-radius: 6px 0 0 6px; + } + + .mini-countdown-name { + white-space: nowrap; + } + + .mini-countdown-value { + } + } + } + + .hidden { + display: none; + } +} diff --git a/styles/countdown.less b/styles/less/ui/countdown/sheet.less similarity index 64% rename from styles/countdown.less rename to styles/less/ui/countdown/sheet.less index 336805a9..6a1d2394 100644 --- a/styles/countdown.less +++ b/styles/less/ui/countdown/sheet.less @@ -1,141 +1,88 @@ -.theme-light { - .daggerheart.dh-style.countdown { - .minimized-view .mini-countdown-container { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -} - -.daggerheart.dh-style.countdown { - overflow: hidden; - - fieldset { - align-items: center; - margin-top: 5px; - border-radius: 6px; - border-color: light-dark(@dark-blue, @golden); - - legend { - font-family: @font-body; - font-weight: bold; - color: light-dark(@dark-blue, @golden); - - a { - text-shadow: none; - } - } - } - - .minimized-view { - display: flex; - gap: 8px; - flex-wrap: wrap; - - .mini-countdown-container { - width: fit-content; - display: flex; - align-items: center; - gap: 8px; - border: 2px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - padding: 0 4px 0 0; - background-image: url('../assets/parchments/dh-parchment-light.png'); - color: light-dark(@beige, @dark); - cursor: pointer; - - &.disabled { - cursor: initial; - } - - img { - width: 30px; - height: 30px; - border-radius: 6px 0 0 6px; - } - - .mini-countdown-name { - white-space: nowrap; - } - - .mini-countdown-value { - } - } - } - - .hidden { - display: none; - } - - .window-content { - > div { - height: 100%; - - .expanded-view { - height: 100%; - display: flex; - flex-direction: column; - - .countdowns-menu { - display: flex; - gap: 8px; - - .flex { - flex: 1; - } - } - - .countdowns-container { - display: flex; - gap: 8px; - flex-wrap: wrap; - overflow: auto; - max-height: 100%; - - .countdown-fieldset { - width: 340px; - height: min-content; - position: relative; - - .ownership-button { - position: absolute; - top: 8px; - right: 8px; - font-size: 18px; - } - - .countdown-container { - display: flex; - align-items: center; - gap: 16px; - - img { - width: 150px; - height: 150px; - cursor: pointer; - - &.disabled { - cursor: initial; - } - } - - .countdown-inner-container { - display: flex; - flex-direction: column; - gap: 4px; - - .countdown-value-container { - display: flex; - gap: 4px; - - input { - max-width: 80px; - } - } - } - } - } - } - } - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; +@import '../../utils/mixin.less'; + +.appTheme({}, { + &.countdown { + .minimized-view .mini-countdown-container { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}); + +.daggerheart.dh-style.countdown { + overflow: hidden; + + .window-content { + > div { + height: 100%; + + .expanded-view { + height: 100%; + display: flex; + flex-direction: column; + + .countdowns-menu { + display: flex; + gap: 8px; + + .flex { + flex: 1; + } + } + + .countdowns-container { + display: flex; + gap: 8px; + flex-wrap: wrap; + overflow: auto; + max-height: 100%; + + .countdown-fieldset { + width: 340px; + height: min-content; + position: relative; + + .ownership-button { + position: absolute; + top: 8px; + right: 8px; + font-size: 18px; + } + + .countdown-container { + display: flex; + align-items: center; + gap: 16px; + + img { + width: 150px; + height: 150px; + cursor: pointer; + + &.disabled { + cursor: initial; + } + } + + .countdown-inner-container { + display: flex; + flex-direction: column; + gap: 4px; + + .countdown-value-container { + display: flex; + gap: 4px; + + input { + max-width: 80px; + } + } + } + } + } + } + } + } + } +} diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less new file mode 100644 index 00000000..0227c26b --- /dev/null +++ b/styles/less/ui/index.less @@ -0,0 +1,18 @@ +@import './chat/chat.less'; +@import './chat/sheet.less'; +@import './chat/theme-colorful.less'; + +@import './combat-sidebar/combat-sidebar.less'; +@import './combat-sidebar/combatant-controls.less'; +@import './combat-sidebar/encounter-controls.less'; +@import './combat-sidebar/spotlight-control.less'; +@import './combat-sidebar/token-actions.less'; + +@import './countdown/countdown.less'; +@import './countdown/sheet.less'; + +@import './ownership-selection/ownership-selection.less'; + +@import './resources/resources.less'; + +@import './settings/settings.less'; diff --git a/styles/ownershipSelection.less b/styles/less/ui/ownership-selection/ownership-selection.less similarity index 94% rename from styles/ownershipSelection.less rename to styles/less/ui/ownership-selection/ownership-selection.less index f0b05937..56fddd4f 100644 --- a/styles/ownershipSelection.less +++ b/styles/less/ui/ownership-selection/ownership-selection.less @@ -1,3 +1,5 @@ +@import '../../utils/colors.less'; + .daggerheart.views.ownership-selection { .ownership-outer-container { display: flex; diff --git a/styles/resources.less b/styles/less/ui/resources/resources.less similarity index 100% rename from styles/resources.less rename to styles/less/ui/resources/resources.less diff --git a/styles/settings.less b/styles/less/ui/settings/settings.less similarity index 98% rename from styles/settings.less rename to styles/less/ui/settings/settings.less index d3e63a2d..3bd200a2 100644 --- a/styles/settings.less +++ b/styles/less/ui/settings/settings.less @@ -1,3 +1,5 @@ +@import '../../utils/colors.less'; + .daggerheart.dh-style.setting { fieldset { display: flex; diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less index 57a6b018..3e72b743 100755 --- a/styles/less/utils/colors.less +++ b/styles/less/utils/colors.less @@ -45,6 +45,21 @@ @gradient-hp: linear-gradient(15deg, rgb(70, 20, 10) 0%, rgb(190, 0, 0) 42%, rgb(252, 176, 69) 100%); @gradient-stress: linear-gradient(15deg, rgb(130, 59, 1) 0%, rgb(252, 142, 69) 65%, rgb(190, 0, 0) 100%); +// TODO: Remove this colors section once new chat layout is done +@miss: rgb(255, 0, 0); +@hit: rgb(0, 128, 0); +@positive: #699969; +@secondaryShadow: gold; +@primaryAccent: #778899; +@hope: #ffe760; +@fear: #0032b1; +@fearBackgroundStart: rgba(15, 15, 97, 0.6); +@fearBackgroundEnd: rgba(0, 0, 255, 0.6); +@critical: #430070; +@criticalBackgroundStart: rgba(37, 8, 37, 0.6); +@criticalBackgroundEnd: rgba(128, 0, 128, 0.6); +@primary-color-fear: rgba(9, 71, 179, 0.75); + @keyframes glow { 0% { box-shadow: 0 0 1px 1px @golden; diff --git a/styles/variables/values.less b/styles/less/utils/spacing.less similarity index 100% rename from styles/variables/values.less rename to styles/less/utils/spacing.less diff --git a/styles/levelup.less b/styles/levelup.less deleted file mode 100644 index 0f7949ba..00000000 --- a/styles/levelup.less +++ /dev/null @@ -1,271 +0,0 @@ -.theme-light { - .daggerheart.levelup { - .tiers-container { - .tier-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - } -} - -.daggerheart.levelup { - .window-content { - max-height: 960px; - overflow: auto; - } - - div[data-application-part='form'] { - display: flex; - flex-direction: column; - gap: 8px; - } - - section { - .section-container { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: 8px; - } - } - - .levelup-navigation-container { - display: flex; - align-items: center; - gap: 22px; - height: 36px; - - nav { - flex: 1; - - .levelup-tab-container { - display: flex; - align-items: center; - gap: 4px; - } - } - - .levelup-navigation-actions { - width: 306px; - display: flex; - justify-content: end; - gap: 16px; - margin-right: 4px; - - * { - width: calc(50% - 8px); - } - } - } - - .tiers-container { - display: flex; - gap: 16px; - - .tier-container { - flex: 1; - display: flex; - flex-direction: column; - gap: 8px; - background-image: url('../assets/parchments/dh-parchment-dark.png'); - - &.inactive { - opacity: 0.4; - pointer-events: none; - } - - legend { - margin-left: auto; - margin-right: auto; - font-size: 22px; - font-weight: bold; - padding: 0 12px; - } - - .checkbox-group-container { - display: grid; - grid-template-columns: 1fr 3fr; - gap: 4px; - - .checkboxes-container { - display: flex; - justify-content: end; - gap: 4px; - - .checkbox-grouping-coontainer { - display: flex; - height: min-content; - - &.multi { - border: 2px solid grey; - padding: 2.4px 2.5px 0; - border-radius: 4px; - gap: 2px; - - .selection-checkbox { - margin-left: 0; - margin-right: 0; - } - } - - .selection-checkbox { - margin: 0; - } - } - } - - .checkbox-group-label { - font-size: 14px; - font-style: italic; - } - } - } - } - - .levelup-selections-container { - .achievement-experience-cards { - display: flex; - gap: 8px; - - .achievement-experience-card { - border: 1px solid; - border-radius: 4px; - padding-right: 4px; - font-size: 18px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 4px; - - .achievement-experience-marker { - border: 1px solid; - border-radius: 50%; - height: 18px; - width: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; - } - } - } - - .levelup-card-selection { - display: flex; - flex-wrap: wrap; - gap: 40px; - - .card-preview-container { - width: calc(100% * (1 / 5)); - } - - .levelup-domains-selection-container { - display: flex; - flex-direction: column; - gap: 8px; - - .levelup-domain-selection-container { - display: flex; - flex-direction: column; - align-items: center; - flex: 1; - position: relative; - cursor: pointer; - - &.disabled { - pointer-events: none; - opacity: 0.4; - } - - .levelup-domain-label { - position: absolute; - text-align: center; - top: 4px; - background: grey; - padding: 0 12px; - border-radius: 6px; - } - - img { - height: 124px; - } - - .levelup-domain-selected { - position: absolute; - height: 54px; - width: 54px; - border-radius: 50%; - border: 2px solid; - font-size: 48px; - display: flex; - align-items: center; - justify-content: center; - background-image: url(../assets/parchments/dh-parchment-light.png); - color: var(--color-dark-5); - top: calc(50% - 29px); - - i { - position: relative; - right: 2px; - } - } - } - } - } - - .levelup-selections-title { - display: flex; - align-items: center; - gap: 4px; - } - - .levelup-radio-choices { - display: flex; - gap: 8px; - - label { - flex: 0; - } - } - } - - .levelup-summary-container { - .level-achievements-container, - .level-advancements-container { - display: flex; - flex-direction: column; - gap: 8px; - - h2, - h3, - h4, - h5 { - margin: 0; - color: var(--color-text-secondary); - } - } - - .increase-container { - display: flex; - align-items: center; - gap: 4px; - font-size: 20px; - } - - .summary-selection-container { - display: flex; - gap: 8px; - - .summary-selection { - border: 2px solid; - border-radius: 6px; - padding: 0 4px; - font-size: 18px; - } - } - } - - .levelup-footer { - display: flex; - } -} diff --git a/styles/pc.less b/styles/pc.less deleted file mode 100644 index c9abd821..00000000 --- a/styles/pc.less +++ /dev/null @@ -1,1519 +0,0 @@ -@import 'variables/values.less'; -@import 'variables/colors.less'; - -.daggerheart.sheet.pc { - width: 810px !important; // Form won't apply height for some reason - - div[data-application-part] { - display: flex; - flex-direction: column; - - .pc-sheet-header { - display: flex; - gap: @halfMargin; - height: 120px; - margin-bottom: @halfMargin; - - .portrait { - border: 0; - border-right: @thinBorder solid var(--color-underline-header); - } - - .class-info { - flex: 1; - background: @primaryAccent; - // -webkit-clip-path: polygon(0 0, 100% 0, calc(100% - 55px) 100%, 0px 100%); - // clip-path: polygon(0 0, 100% 0, calc(100% - 75px) 100%, 0px 100%); - - .portrait { - max-width: 120px; - } - - .class-title { - text-align: center; - display: flex; - justify-content: space-between; - - span:hover { - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; - } - - .domain-container { - margin-left: @halfMargin; - } - } - - .class-add-container { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - flex: 0; - - button { - height: 22px; - width: 22px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - margin-left: @halfMargin; - background: @primaryAccent; - } - } - - .domain-title { - text-transform: uppercase; - display: flex; - flex-direction: column; - align-items: center; - line-height: 23px; - font-weight: bold; - font-style: italic; - } - - .domain-image { - height: 30px; - flex: 0; - } - } - .general-info { - flex: 2; - display: flex; - flex-direction: column; - justify-content: space-between; - - .general-input { - position: relative; - - .general-title { - position: absolute; - left: 4px; - // height: 100%; - text-align: center; - font-weight: bold; - text-transform: uppercase; - } - } - - .pc-tabs { - flex: 1; - margin: 0; - } - - .rest-container { - flex-wrap: nowrap; - display: flex; - height: var(--form-field-height); - flex: 0; - - button { - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - width: var(--form-field-height); - - i { - font-size: 13px; - } - } - } - - .level-container { - position: relative; - bottom: 4px; - flex: none; - width: 40px; - border: none; - outline: none; - margin-left: @fullMargin; - - &.levelup { - filter: drop-shadow(0px 0px 3px gold); - } - - img { - height: 40px; - width: 40px; - border: none; - } - - .level-value-container { - width: 48px; - position: absolute; - top: calc(50% - 17px); - left: calc(50% - 23px); - - .level-value { - font-weight: bold; - font-size: 20px; - text-align: center; - &:not(:hover), - &:not(:focus) { - border: none; - } - } - - .levelup-marker { - position: absolute; - top: 0; - right: calc(50% - 12px); - color: gold; - filter: drop-shadow(0px 0px 3px black); - - &.double-digit { - right: calc(50% - 20px); - } - } - } - - .level-title { - position: absolute; - bottom: 2px; - width: 42px; - background-color: black; - color: white; - left: calc(50% - 21px); - text-align: center; - border-radius: 5px; - font-size: 12px; - - &.levelup { - color: gold; - filter: drop-shadow(0px 0px 3px orange); - font-weight: bold; - cursor: pointer; - &:hover { - background-color: aliceblue; - } - } - } - } - } - } - - .sheet-body { - display: flex; - flex-direction: column; - flex: 1; - - .tab-container { - height: 100%; - display: flex; - flex-direction: column; - - .tab-inner-container { - flex: 1; - - .body-section { - display: flex; - flex-direction: column; - - fieldset { - flex: 0; - } - } - } - } - - .system-info { - font-size: 12px; - font-style: italic; - font-weight: bold; - margin-top: -@halfMargin; - flex: 0; - } - - .feature-sheet-body { - gap: @halfMargin; - } - - .abilities-container { - position: relative; - display: flex; - flex-wrap: wrap; - border-radius: 6px; - padding-left: 0; - // flex: 2.5; - - legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - text-transform: uppercase; - padding: 0 @fullMargin; - position: relative; - } - - .attributes-menu { - position: absolute; - bottom: calc(50% - 12px); - font-size: 24px; - left: -8px; - } - - .attribute { - position: relative; - padding: 0 0 @fullPadding; - display: flex; - flex-direction: column; - align-items: center; - flex-basis: 33.33%; - // flex: 1; - - .attribute-banner { - position: relative; - top: 8px; - z-index: 2; - background: black; - color: white; - text-transform: uppercase; - padding: @smallPadding; - border-radius: 6px; - display: flex; - align-items: center; - overflow: hidden; - min-width: 96px; - - .attribute-roll { - position: absolute; - width: 16px; - transition: transform 0.2s; - - &:hover { - transform: rotate(30deg); - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; - } - } - - .attribute-text { - width: 100%; - margin-left: @largeMargin; - font-size: 12px; - } - } - - .attribute-mark { - height: 23px; - width: 23px; - position: absolute; - right: -5px; - top: 6px; - border: 2px solid black; - border-radius: 50%; - background: white; - z-index: 2; - display: flex; - align-items: center; - justify-content: center; - - &.selectable { - border-color: gold; - filter: drop-shadow(0 0 3px black); - - &:hover i { - opacity: 0.3; - } - } - - & i.selected, - &:hover i.selected { - color: green; - opacity: 1; - } - - i { - color: black; - font-size: 17px; - opacity: 0; - } - } - - .attribute-image { - position: relative; - width: fit-content; - display: flex; - - img { - height: 80px; - width: 80px; - border: none; - } - - .attribute-value { - width: 55px; - padding-right: 10px; - position: absolute; - top: calc(50% - 18px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - line-height: 30px; - text-align: center; - border: none; - appearance: none; - -moz-appearance: none; - -webkit-appearance: none; - &.negative { - left: calc(50% - 29px); - } - &.unselected { - filter: drop-shadow(0 0 3px @secondaryShadow); - } - } - - .attribute-text { - width: 47px; - position: absolute; - top: calc(50% - 22px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - text-align: center; - - &.negative { - left: calc(50% - 29px); - } - } - } - - .attribute-verb { - font-variant: petite-caps; - } - } - } - - .defense-row { - height: 100%; - width: 100%; - display: flex; - align-items: baseline; - justify-content: space-evenly; - - .defense-section { - display: flex; - align-items: center; - margin-right: @fullMargin; - - .defense-container { - position: relative; - padding: @fullPadding; - max-width: 100px; - - img { - border: none; - max-width: 80px; - } - - .defense-value { - width: 47px; - position: absolute; - top: calc(50% - 22px); - left: calc(50% - 24px); - font-weight: bold; - font-size: 30px; - text-align: center; - &:not(:hover), - &:not(:focus) { - border: none; - } - } - - .defense-banner { - position: absolute; - bottom: 20px; - left: calc(50% - 42px); - z-index: 2; - background-color: black; - color: white; - width: 84px; - text-align: center; - } - } - } - - .armor-marks { - max-width: 67px; - padding: @fullPadding; - align-self: end; - margin-left: @halfMargin; - - .mark { - width: 16px; - height: 16px; - margin: 0px; - } - - .disabled-mark { - opacity: 0.6; - } - } - } - - .left-main-container { - position: relative; - display: flex; - flex-direction: column; - align-items: flex-start; - border-radius: @normalRadius; - - height: 100px; - width: 100px; - - .legend { - margin-left: auto; - margin-right: auto; - font-weight: bold; - text-transform: uppercase; - padding: 0 @fullPadding; - position: relative; - } - } - - .weapon-section { - padding-top: 8px; - } - - .threshold-container { - position: relative; - display: flex; - align-items: center; - align-self: center; - - .threshold-box { - position: relative; - width: 30px; - height: 30px; - border: @normalBorder solid black; - display: flex; - align-items: center; - justify-content: center; - font-size: 20px; - font-weight: bold; - } - - .threshold-spacer { - position: relative; - z-index: 2; - width: 70px; - height: 18px; - background-color: darkgray; - color: white; - display: flex; - justify-content: center; - align-items: center; - } - } - - .resource-label { - text-transform: uppercase; - font-weight: bold; - } - - .death-save { - position: absolute; - right: -22px; - - &:hover:not(.disabled) { - filter: drop-shadow(0 0 3px @mainShadow); - cursor: pointer; - } - - &.disabled { - opacity: 0.4; - } - } - - .resource-box { - width: 20px; - height: 12px; - - &.stress:nth-child(even) { - position: relative; - right: 1px; - } - - .disabled { - opacity: 0.6; - } - } - - .hope-text { - font-size: 11.7px; - margin-right: 6px; - } - - .hope-container { - background: darkgray; - border-radius: 6px; - display: flex; - padding: @smallPadding 0px; - - .vertical-separator { - border-left: 2px solid white; - height: auto; - margin: @halfMargin 0; - flex: 0; - } - - .hope-inner-container { - position: relative; - - .hope-value { - width: 16px; - height: 16px; - } - - .hope-scar { - position: absolute; - top: calc(50% - 6px); - left: calc(50% - 7px); - opacity: 0.4; - font-size: 12px; - -webkit-transform: scaleX(-1); - transform: scaleX(-1); - } - } - } - - .experience-row { - width: 100%; - display: flex; - align-items: flex-end; - - .experience-selector { - font-size: 18px; - cursor: pointer; - margin-right: @halfMargin; - opacity: 0.5; - - &:hover:not(.selected) { - filter: drop-shadow(0 0 3px gold); - } - - &.selected { - filter: drop-shadow(0 0 3px gold); - opacity: 1; - } - } - - .experience-value { - margin-left: @fullMargin; - width: 30px; - border-bottom: @normalBorder solid black; - border-radius: 4px; - text-align: center; - font-weight: bold; - - &.empty { - border: 0; - } - } - - .disabled-experience { - border: @thinBorder solid @borderTertiary; - background: rgba(0, 0, 0, 0.2); - } - } - .gold-section { - width: calc(100% - 8px); - display: flex; - justify-content: space-between; - - fieldset.gold-fieldset { - padding-right: 0; - padding-left: 0; - padding-bottom: @fullPadding; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 15px; - font-variant: all-petite-caps; - font-weight: bold; - } - - .gold-column { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100%; - gap: @halfMargin; - } - - .gold-row { - display: flex; - align-items: center; - justify-content: center; - padding: 0 @fullPadding; - gap: @tinyMargin; - } - - .gold-row, - .gold-column { - img { - min-width: 14px; - min-height: 14px; - height: 14px; - border: 0; - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%); - - &:hover { - cursor: pointer; - filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) - contrast(103%) drop-shadow(0 0 3px @mainShadow); - } - } - - i:hover { - cursor: pointer; - filter: drop-shadow(0 0 3px @mainShadow); - } - - img:not(.owned), - i:not(.owned) { - opacity: 0.4; - } - } - } - } - - .health-category { - text-transform: uppercase; - } - - .class-feature-selectable { - cursor: pointer; - - &:hover { - filter: drop-shadow(0 0 3px @mainShadow); - } - - &.inactive { - opacity: 0.5; - } - } - - .features-container { - width: 100%; - min-height: 136px; - - .feature-container { - display: flex; - align-items: center; - justify-content: space-between; - padding: @fullPadding; - margin-bottom: 0; - - .feature-img { - max-width: 42px; - } - - .feature-label { - font-weight: bold; - font-size: 30px; - } - - button { - flex: 0; - } - } - - .feature-tick-container { - flex: 0; - min-width: 56px; - display: flex; - flex-wrap: wrap; - gap: @fullMargin; - margin: 0 @threeQuarterMargin; - - .feature-tick { - position: relative; - border: @normalBorder solid @borderTertiary; - height: 24px; - border-radius: 50%; - width: 24px; - background: rgba(0, 0, 0, 0.05); - display: flex; - justify-content: center; - - &:hover:not(.disabled):not(.used) { - cursor: pointer; - filter: drop-shadow(0 0 3px @mainShadow); - } - - &.disabled { - opacity: 0.3; - } - - img { - border: 0; - width: 24px; - height: 24px; - filter: invert(17%) sepia(0%) saturate(0%) hue-rotate(19deg) brightness(102%) contrast(84%); - } - - .feature-dice-value { - font-size: 18px; - align-self: center; - } - - &.used::after { - position: absolute; - content: '/'; - color: @borderTertiary; - font-weight: 700; - font-size: 1.7em; - left: 4px; - top: -5px; - transform: rotate(25deg); - font-size: 24.5px; - } - } - } - } - - .feature-input { - border: 0; - border-bottom: @thinBorder solid @borderTertiary; - text-align: center; - height: min-content; - background: inherit; - font-size: 20px; - position: relative; - bottom: 3px; - } - - .editor { - height: 400px; - width: 100%; - } - - .weapons-title { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - - .proficiency-container { - width: 176px; - height: 20px; - position: absolute; - bottom: -15px; - left: calc(50% - 88px); - text-transform: uppercase; - display: flex; - align-items: center; - justify-content: center; - z-index: 1; - clip-path: polygon(11% 100%, 89% 100%, 100% 0%, 0% 0%); - font-size: 10px; - - span { - margin-right: @tinyMargin; - } - - .proficiency-dot { - background: white; - color: white; - font-size: 10px; - padding: 1px; - border-radius: 50%; - - &.marked { - color: black; - } - - &:not(:last-of-type) { - margin-right: @tinyMargin; - } - } - } - } - - .weapons-burden { - position: absolute; - top: -4px; - right: -56px; - display: flex; - align-items: center; - - .weapons-burden-icon { - color: white; - font-size: 22px; - -webkit-text-stroke-width: 1px; - -webkit-text-stroke-color: black; - - &.active { - -webkit-text-stroke-color: rgba(0, 0, 0, 0.05); - color: black; - } - - &.left { - -webkit-transform: scaleX(-1) rotate(20deg); - transform: scaleX(-1) rotate(20deg); - margin-right: 4px; - } - - &.right { - transform: rotate(20deg); - } - } - } - - .armor-container { - display: flex; - align-items: center; - - .active-item-label-chip { - margin-left: @halfMargin; - } - } - - .item-section { - .active-item-container { - display: flex; - flex-direction: column; - width: 100%; - padding: @smallPadding 0px; - - .weapons-label-row { - display: flex; - align-items: center; - - .damage-roll { - width: 24px; - border: none; - margin-left: @halfMargin; - transition: transform 0.2s; - - &:hover { - transform: rotate(30deg); - filter: drop-shadow(0px 0px 3px red); - cursor: pointer; - } - } - } - } - - .active-item-label-chip { - width: 62px; - border: @normalBorder solid black; - border-radius: 6px; - background-color: @primaryAccent; - display: flex; - align-items: center; - justify-content: space-around; - margin-left: @fullPadding; - - img { - height: 20px; - } - - button { - height: 17px; - width: 17px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - background: rgb(122, 121, 113); - border-color: black; - margin: 0; - - &:hover { - background: red; - } - - i { - font-size: 10px; - color: black; - } - } - } - } - - .inventory-armor-section, - .inventory-weapon-section { - width: 100%; - margin-bottom: @fullMargin; - text-transform: uppercase; - - h2 { - width: 100%; - display: flex; - align-items: center; - } - } - - .inventory-legend { - display: flex; - align-items: center; - margin-bottom: @halfMargin; - - .page-selector { - margin-left: 4px; - display: flex; - align-items: center; - - i { - &:hover:not(.disabled) { - cursor: pointer; - filter: drop-shadow(0px 0px 3px red); - } - - &.disabled { - opacity: 0.4; - } - } - } - } - - .inventory-add-button { - position: absolute; - border-radius: 50%; - height: 15px; - width: 15px; - top: -20px; - background: grey; - border-color: black; - right: 6px; - display: flex; - font-size: 13px; - align-items: center; - justify-content: center; - } - - .inventory { - width: 100%; - - .inventory-row { - height: 26px; - border-bottom: @thinBorder solid @borderTertiary; - display: flex; - margin-bottom: @fullMargin; - border-radius: 8px; - - .item-container { - flex-basis: 25%; - margin: 0 @halfMargin @fullMargin; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - - &:hover { - filter: drop-shadow(0px 0px 3px red); - } - - .inventory-item { - background: @primaryAccent; - padding: @fullPadding; - border: @thinBorder solid black; - border-radius: 6px; - display: flex; - align-items: center; - - .inventory-item-text { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - flex: 1; - } - - button { - height: 16px; - width: 16px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - flex: 0; - background: @secondaryBackground; - border-color: black; - margin-left: @halfMargin; - - i { - font-size: 12px; - } - } - } - } - } - - .editor { - height: 100px; - } - } - - .inventory-items { - width: 100%; - flex: 1; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .domain-card-tab { - flex: 1; - - .domain-card-body { - height: 100%; - width: 100%; - padding: @largePadding; - display: flex; - flex-direction: column; - - .card-row { - flex: 1; - display: flex; - } - - .domain-card { - flex: 0; - flex-basis: 33.33%; - margin: @fullMargin; - } - - .loadout-body { - flex: 1; - - .loadout-container { - height: 100%; - display: flex; - flex-direction: column; - gap: @fullMargin; - - .top-card-row { - flex: 1; - display: flex; - justify-content: space-around; - } - - .domain-card.outlined { - border: @normalBorder dotted black; - padding: 0; - margin: @fullMargin; - height: calc(100% - 16px); - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-evenly; - } - } - } - - .vault-container { - display: flex; - flex-wrap: wrap; - overflow-y: auto; - height: 100%; - - .vault-card { - flex: 0; - flex-basis: calc(33.33% - 16px); - margin: 8px; - height: calc(50% - 16px); - min-height: calc(50% - 16px); - } - } - - .domain-card-menu { - flex: 0; - width: 120px; - height: 100%; - border-width: @normalBorder 0 @normalBorder @normalBorder; - border-color: black; - border-style: solid; - - button { - margin-bottom: @tinyMargin; - } - } - } - } - - .loadout-tabs { - border-top: @thinBorder solid @borderPrimary; - border-bottom: @thinBorder solid @borderPrimary; - } - - .abilities-card { - position: relative; - border: @thickBorder solid @secondaryAccent; - border-radius: 6px; - display: flex; - flex-direction: column; - height: 100%; - font-size: 14px; - - .abilities-card-image-container { - position: relative; - // height: 50%; - } - - .abilities-card-image { - width: 100%; - height: 100%; - aspect-ratio: 2; - } - - .abilities-text-container { - flex: 1; - position: relative; - height: 50%; - display: flex; - flex-direction: column; - overflow-y: auto; - padding: 12px 4px 4px; - } - - .abilities-card-level { - position: absolute; - top: 0; - left: 12px; - color: black; - height: 60px; - border: @normalBorder solid orange; - border-top-width: 0; - width: 30px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-evenly; - background: grey; - font-size: 20px; - font-weight: bold; - - img { - border: 0; - width: 20px; - } - } - .abilities-card-refresh-cost { - position: absolute; - top: 12px; - right: 12px; - color: white; - width: 30px; - height: 30px; - border: @normalBorder solid orange; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - background: black; - font-size: 14px; - i { - font-size: 11px; - } - } - - .abilities-card-type { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-weight: bold; - position: absolute; - left: 0; - text-align: center; - width: 100%; - bottom: -9px; - z-index: 1; - - .abilities-card-type-text { - padding: 0px 4px; - border: 1px solid black; - border-radius: 6px; - background: gold; - } - } - - .abilities-card-title { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-weight: bold; - font-size: 18px; - } - - .abilities-card-sub-title { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - font-style: italic; - font-size: 12px; - } - - .abilities-card-spellcast { - flex: 0; - display: flex; - justify-content: center; - align-items: center; - text-transform: uppercase; - font-size: 12px; - - .title { - font-weight: bold; - } - } - - .abilities-card-description { - flex: 0; - font-size: 12px; - margin-bottom: 4px; - } - - .abilities-card-effect { - cursor: pointer; - - &:hover { - background: rgb(47 79 79 / 25%); - } - - > * { - margin-top: 0; - margin-bottom: 0; - } - } - - .abilities-card-abilities { - flex: 1; - display: flex; - flex-direction: column; - gap: 4px; - - .abilities-card-ability { - font-size: 12px; - cursor: pointer; - - &:hover { - background: rgb(47 79 79 / 25%); - } - - > * { - margin: 0; - } - } - } - - &:hover .abilities-card-menu { - height: 40px; - left: 0px; - } - - .abilities-card-menu { - display: flex; - justify-content: center; - align-items: center; - height: 0; - transition: height 0.2s; - overflow: hidden; - position: absolute; - bottom: 0; - z-index: 2; - width: 100%; - background: grey; - - button { - font-weight: bold; - } - } - } - - .heritage-container { - height: 100%; - display: flex; - flex-direction: column; - gap: @fullMargin; - - .card-row { - height: 50%; - display: flex; - justify-content: space-around; - } - - .heritage-card { - flex-basis: 33.33%; - margin: @fullMargin; - display: flex; - align-items: center; - justify-content: center; - - &.outlined { - border: @normalBorder dotted black; - font-size: 25px; - } - } - } - - .empty-ability-container { - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - font-size: 25px; - opacity: 0.7; - - .empty-ability-inner-container { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - i { - font-size: 48px; - } - } - } - - .story-container { - gap: @largeMargin; - - .story-fieldset { - border-radius: 6px; - } - - .story-legend { - margin-left: auto; - margin-right: auto; - padding: 0 8px; - font-size: 30px; - font-weight: bold; - } - - .scars-container { - .editor { - height: 240px; - } - } - } - - .inventory-container { - height: 100%; - overflow: auto; - - .inventory-item-list { - list-style-type: none; - padding: 0 @largePadding; - margin-top: 0; - - &.inventory-item-header { - margin-bottom: 0; - } - - .inventory-title-row-container { - display: flex; - align-items: center; - width: 100%; - border-bottom: @thickBorder ridge slategrey; - - .inventory-title-row { - justify-content: space-between; - flex: 1; - } - - .inventory-item-title-container { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-start; - } - - .inventory-item-quantity { - width: 48px; - display: flex; - align-items: center; - margin-right: 96px; // Icon toolbar spacing - } - } - - .inventory-item { - background: crimson; - - &:not(:last-of-type) { - border-bottom: @normalBorder ridge slategrey; - } - - .inventory-item-title-container { - flex: 1; - display: flex; - align-items: center; - justify-content: flex-start; - - .inventory-item-title { - display: flex; - align-items: center; - cursor: pointer; - - &:hover { - filter: drop-shadow(0 0 3px @secondaryShadow); - } - } - } - - .inventory-item-quantity { - width: 60px; - display: flex; - align-items: center; - - &.spaced { - margin-right: 56px; - } - - input { - margin: 0 @tinyMargin; - border: 0; - border-bottom: 2px solid black; - } - - i { - font-size: 20px; - } - } - } - - .inventory-title-row { - font-size: 20px; - font-weight: bold; - display: flex; - align-items: center; - padding: 0 @fullPadding; - } - - .inventory-row { - display: flex; - align-items: center; - padding: @fullPadding; - font-size: 24px; - - .row-icon { - margin-left: @halfMargin; - } - - .active-item { - position: absolute; - font-size: 16px; - left: calc(50% - 8px); - top: calc(50% - 8px); - margin-left: @tinyMargin; - color: crimson; - } - - img { - width: 32px; - } - } - } - } - } - } -} diff --git a/styles/sheets/activeEffect.less b/styles/sheets/activeEffect.less deleted file mode 100644 index 86a29244..00000000 --- a/styles/sheets/activeEffect.less +++ /dev/null @@ -1,5 +0,0 @@ -.application.sheet.daggerheart.dh-style.active-effect-config { - label { - white-space: nowrap; - } -} diff --git a/styles/sheets/class.less b/styles/sheets/class.less deleted file mode 100644 index 09dafcff..00000000 --- a/styles/sheets/class.less +++ /dev/null @@ -1,65 +0,0 @@ -.daggerheart.sheet.class .guide .drop-section { - width: 100%; -} -.daggerheart.sheet.class .guide .drop-section legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; -} -.daggerheart.sheet.class .guide .drop-section .drop-section-body { - min-height: 40px; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.sheet.class .guide .trait-input { - text-align: center; - min-width: 24px; -} -.daggerheart.sheet.class .guide .suggested-item { - border-radius: 6px; - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; -} -.daggerheart.sheet.class .guide .suggested-item img { - width: 30px; -} -.daggerheart.sheet.class .guide .suggested-item div { - text-align: center; -} -.daggerheart.sheet.class .guide .suggested-item i { - border-radius: 50%; - margin-right: 4px; - font-size: 11px; -} -.daggerheart.sheet.class .guide .extra-section { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.sheet.class .guide .extra-section .extra-title { - font-size: 14px; - font-weight: bold; -} -.daggerheart.sheet.class .guide-section-title-centered { - font-weight: bold; - font-size: 18px; -} -.daggerheart.sheet.class .inventory-section { - width: 100%; - border: 2px solid black; - border-style: dotted; - min-height: 80px; -} -.daggerheart.sheet.class .inventory-section .inventory-title { - font-weight: bold; - font-size: 14px; - text-align: center; -} -.daggerheart.sheet.class .domain-section { - display: flex; - align-items: center; - gap: 5px; -} diff --git a/styles/sheets/heritage.less b/styles/sheets/heritage.less deleted file mode 100644 index 84af64bc..00000000 --- a/styles/sheets/heritage.less +++ /dev/null @@ -1,5 +0,0 @@ -.daggerheart.sheet.heritage { - .editor { - height: 200px; - } -} diff --git a/styles/sheets/sheets.less b/styles/sheets/sheets.less deleted file mode 100644 index 5c9b43a1..00000000 --- a/styles/sheets/sheets.less +++ /dev/null @@ -1,185 +0,0 @@ -@import './heritage.less'; -@import './class.less'; -@import './activeEffect.less'; - -.daggerheart.sheet { - .title-container { - display: flex; - gap: @fullMargin; - - div { - flex: 1; - align-items: baseline; - } - } - - .editor-form-group { - display: flex; - flex-direction: column; - - label { - font-weight: bold; - text-align: center; - } - } - - .option-select { - position: absolute; - top: calc(50% - 10px); - right: 8px; - height: 20px; - width: 20px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; - - &.deeper { - right: 32px; - } - - &:hover:not(:disabled) { - filter: drop-shadow(0px 0px 3px @mainShadow); - cursor: pointer; - } - - i { - margin: 0; - font-size: 11px; - } - } - - .ability-title { - width: 100%; - display: flex; - - h2 { - flex: 1; - } - - i { - cursor: pointer; - - &:hover { - filter: drop-shadow(0px 0px 3px @mainShadow); - } - } - } - - .ability-choices { - display: flex; - align-items: center; - flex-wrap: wrap; - } - - .ability-chip { - border: 2px solid @secondaryAccent; - border-radius: 6px; - display: flex; - align-items: center; - padding: 4px; - margin-bottom: 6px; - flex: calc(33% - 4px); - max-width: calc(33% - 4px); - - &.selected { - filter: drop-shadow(0px 0px 3px @mainShadow); - } - - &:nth-of-type(3n-1) { - margin-left: 6px; - margin-right: 6px; - } - - input { - border: 0; - } - - button { - flex: 0; - border-radius: 50%; - height: 20px; - width: 20px; - display: flex; - align-items: center; - justify-content: center; - margin: 2px 0 2px 4px; - padding: 12px; - - i { - margin: 0; - } - } - } - - .object-select-display { - position: relative; - width: calc(100% - 2px); - background: rgba(0, 0, 0, 0.05); - height: var(--form-field-height); - display: flex; - border: 1px solid rgb(122, 121, 113); - border-radius: 3px; - - .object-select-title { - position: absolute; - left: 4px; - text-align: center; - font-weight: bold; - text-transform: uppercase; - } - - .object-select-text { - align-self: center; - } - - .object-select-item { - cursor: pointer; - &:hover { - filter: drop-shadow(0px 0px 3px red); - } - } - } - - .feature-container { - display: flex; - align-items: center; - justify-content: space-between; - background: @primaryAccent; - padding: 8px; - border: 2px solid black; - border-radius: 6px; - - &:not(:last-child) { - margin-bottom: 8px; - } - - .feature-inner-container { - display: flex; - align-items: center; - - img { - height: 40px; - width: 40px; - margin-right: 8px; - } - - .feature-title { - font-size: 22px; - font-weight: bold; - font-style: italic; - } - } - - button { - height: 40px; - width: 40px; - background: inherit; - border: 0; - - i { - } - } - } -} diff --git a/styles/ui.less b/styles/ui.less deleted file mode 100644 index 09a3511f..00000000 --- a/styles/ui.less +++ /dev/null @@ -1,122 +0,0 @@ -.combat-sidebar { - .encounter-controls.combat { - justify-content: space-between; - - .encounter-fear-controls { - display: flex; - align-items: center; - gap: 8px; - - .encounter-fear-dice-container { - display: flex; - gap: 2px; - - .encounter-control-fear-container { - display: flex; - position: relative; - align-items: center; - justify-content: center; - color: black; - - .dice { - height: 22px; - width: 22px; - } - - .encounter-control-fear { - position: absolute; - font-size: 16px; - } - - .encounter-control-counter { - position: absolute; - right: -10px; - color: var(--color-text-secondary); - } - } - } - - .encounter-countdowns { - color: var(--content-link-icon-color); - } - } - - .control-buttons { - width: min-content; - } - } - - .combatant-controls { - flex: 0; - } - - .token-actions { - align-self: stretch; - display: flex; - align-items: top; - justify-content: center; - gap: 16px; - - .action-tokens { - display: flex; - gap: 4px; - - .action-token { - height: 22px; - width: 22px; - border: 1px solid; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 10px; - padding: 8px; - --button-size: 0; - - &.used { - opacity: 0.5; - background: transparent; - } - } - } - - button { - font-size: 22px; - height: 24px; - width: 24px; - - &.main { - background: var(--button-hover-background-color); - color: var(--button-hover-text-color); - border-color: var(--button-hover-border-color); - - &:hover { - filter: drop-shadow(0 0 3px var(--button-hover-text-color)); - } - } - } - } - - .spotlight-control { - font-size: 26px; - - &:focus { - outline: none; - box-shadow: none; - } - - &.discrete:hover { - background: inherit; - } - - &.requesting { - filter: drop-shadow(0 0 3px gold); - color: var(--button-hover-text-color); - } - } - - h4 { - margin: 0; - text-align: center; - } -} diff --git a/styles/variables/colors.less b/styles/variables/colors.less deleted file mode 100644 index 0468c1e6..00000000 --- a/styles/variables/colors.less +++ /dev/null @@ -1,37 +0,0 @@ -/* General */ -@advantage: #008000; -@disadvantage: #b30000; -@miss: rgb(255, 0, 0); -@hit: rgb(0, 128, 0); -@positive: #699969; -@negative: #ff7f7f; - -@borderPrimary: #b5b3a4; -@borderTertiary: #7a7971; - -/* Drop Shadows */ -@mainShadow: red; -@secondaryShadow: gold; - -/* Background */ -@secondaryBackground: #7a7971; -@primaryAccent: #778899; -@secondaryAccent: #708090; -@formBackground: #782e22; -@hoverBackground: #2f4f4f40; - -/* Duality */ -@hope: #ffe760; -@hopeBackgroundStart: rgba(0, 0, 0, 0.6); -@hopeBackgroundEnd: rgba(165, 42, 42, 0.6); -@fear: #0032b1; -@fearAccent: #2555cd; -@fearBackgroundStart: rgba(15, 15, 97, 0.6); -@fearBackgroundEnd: rgba(0, 0, 255, 0.6); -@critical: #430070; -@criticalAccent: #66159c; -@criticalBackgroundStart: rgba(37, 8, 37, 0.6); -@criticalBackgroundEnd: rgba(128, 0, 128, 0.6); - -/* Fear */ -@primary-color-fear: rgba(9, 71, 179, 0.75); diff --git a/styles/variables/variables.less b/styles/variables/variables.less deleted file mode 100644 index ef536475..00000000 --- a/styles/variables/variables.less +++ /dev/null @@ -1,2 +0,0 @@ -@import './colors.less'; -@import './values.less'; From 99e41ec6f76e4ba5547db58433227bd1a8e50562 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:14:43 +0200 Subject: [PATCH 05/58] Removed git index for daggerheart.css (#306) --- styles/daggerheart.css | 4603 ---------------------------------------- 1 file changed, 4603 deletions(-) delete mode 100755 styles/daggerheart.css diff --git a/styles/daggerheart.css b/styles/daggerheart.css deleted file mode 100755 index 43d91e4f..00000000 --- a/styles/daggerheart.css +++ /dev/null @@ -1,4603 +0,0 @@ -@import '../node_modules/@yaireo/tagify/dist/tagify.css'; -.application.sheet.daggerheart.actor.dh-style.adversary .tab.features .feature-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - padding: 20px 0; - padding-top: 10px; - height: 95%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet { - padding: 0 15px; - padding-top: 36px; - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .name-row { - display: flex; - gap: 5px; - align-items: center; - justify-content: space-between; - padding: 0; - padding-top: 5px; - padding-bottom: 8px; - flex: 1; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .name-row input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - border: 1px solid transparent; - outline: 2px solid transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .name-row input[type='text']:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .tags { - display: flex; - gap: 10px; - padding-bottom: 16px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .tags .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - font: 'Montserrat', sans-serif; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .tags .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .adversary-info { - display: flex; - flex-direction: column; - gap: 12px; - padding: 16px 0; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .adversary-info .description, -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .adversary-info .motives-and-tatics { - font-family: 'Montserrat', sans-serif; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-header-sheet .adversary-navigation { - display: flex; - gap: 8px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .window-content { - display: grid; - grid-template-columns: 275px 1fr; - grid-template-rows: auto 1fr; - gap: 15px 0; - height: 100%; - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.adversary .window-content .adversary-sidebar-sheet { - grid-row: 1 / span 2; - grid-column: 1; -} -.application.sheet.daggerheart.actor.dh-style.adversary .window-content .adversary-header-sheet { - grid-row: 1; - grid-column: 2; -} -.application.sheet.daggerheart.actor.dh-style.adversary .window-content .tab { - grid-row: 2; - grid-column: 2; -} -/** - * Applies theme-specific styles. - * @param {Rules} @darkRules - Styles to apply when `.theme-dark` is present - * @param {Rules} @lightRules - Styles to apply when `.theme-light` is present - */ -.themed.theme-dark .application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, -.themed.theme-dark.application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, -body.theme-dark .application.daggerheart.adversary .adversary-sidebar-sheet, -body.theme-dark.application.daggerheart.adversary .adversary-sidebar-sheet { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-light .application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, -.themed.theme-light.application.daggerheart.sheet.dh-style.adversary .adversary-sidebar-sheet, -body.theme-light .application.daggerheart.adversary .adversary-sidebar-sheet, -body.theme-light.application.daggerheart.adversary .adversary-sidebar-sheet { - background: transparent; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet { - width: 275px; - min-width: 275px; - border-right: 1px solid light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait { - position: relative; - border-bottom: 1px solid light-dark(#18162e, #f3c267); - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait img { - height: 235px; - width: 275px; - object-fit: cover; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait .death-roll-btn { - display: none; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait.death-roll { - filter: grayscale(1); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait.death-roll .death-roll-btn { - display: flex; - position: absolute; - top: 30%; - right: 30%; - font-size: 6rem; - color: #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .portrait.death-roll .death-roll-btn:hover { - text-shadow: 0 0 8px #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .threshold-section { - position: relative; - display: flex; - gap: 10px; - background-color: light-dark(transparent, #18162e); - color: light-dark(#18162e, #f3c267); - padding: 5px 10px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - align-items: center; - width: fit-content; - height: 30px; - margin-top: 16px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .threshold-section h4 { - font-size: 14px; - font-weight: bold; - text-transform: uppercase; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .threshold-section h4.threshold-value { - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .threshold-section .threshold-legend { - position: absolute; - bottom: -21px; - color: light-dark(#f3c267, #18162e); - background-color: light-dark(#18162e, #f3c267); - padding: 3px; - justify-self: anchor-center; - border-radius: 0 0 3px 3px; - text-transform: capitalize; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .threshold-section .hope-value { - display: flex; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section { - position: relative; - display: flex; - flex-direction: column; - top: -20px; - gap: 16px; - margin-bottom: -10px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section { - display: flex; - justify-content: space-evenly; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar { - position: relative; - width: 100px; - height: 40px; - justify-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input { - padding: 0; - color: #efe6d8; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:hover, -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:focus { - background: rgba(24, 22, 46, 0.33); - backdrop-filter: blur(9.5px); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .status-value .bar-label { - width: 40px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - z-index: 1; - background: #18162e; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-bar { - border: none; - background: #18162e; - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-value { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-webkit-progress-value { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-moz-progress-bar { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section { - display: flex; - flex-wrap: wrap; - gap: 10px; - justify-content: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section .status-number { - justify-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section .status-number .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(#18162e, #f3c267); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, #18162e); - z-index: 2; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section .status-number .status-value.armor-slots { - width: 80px; - height: 30px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section .status-number .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .info-section .status-section .status-number .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .items-sidebar-list { - display: flex; - flex-direction: column; - gap: 5px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .items-sidebar-list .inventory-item { - padding: 0 10px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .attack-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .attack-section .title h3 { - font-size: 20px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .attack-section .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section { - margin-bottom: 20px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .title h3 { - font-size: 20px; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .experience-list .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .experience-list .experience-row .experience-name { - width: 180px; - text-align: start; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .experience-list .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); - align-content: center; - text-align: center; - background: url(../assets/svg/experience-shield.svg) no-repeat; -} -.theme-light .application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .experience-section .experience-list .experience-value { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .reaction-section { - display: flex; - padding: 0 10px; - margin-top: 20px; - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.adversary .adversary-sidebar-sheet .reaction-section button { - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.biography .items-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); - padding-bottom: 40px; - height: 100%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.features .features-sections { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - padding: 20px 0; - padding-top: 10px; - height: 95%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-header-sheet .trait, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-header-sheet .trait, -body.theme-dark .application.daggerheart .character-header-sheet .trait, -body.theme-dark.application.daggerheart .character-header-sheet .trait { - background: url(../assets/svg/trait-shield.svg) no-repeat; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-header-sheet .trait, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-header-sheet .trait, -body.theme-light .application.daggerheart .character-header-sheet .trait, -body.theme-light.application.daggerheart .character-header-sheet .trait { - background: url('../assets/svg/trait-shield-light.svg') no-repeat; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet { - padding: 0 15px; - padding-top: 36px; - width: 100%; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row { - display: flex; - gap: 5px; - align-items: center; - justify-content: space-between; - padding: 0; - padding-top: 5px; - flex: 1; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - border: 1px solid transparent; - outline: 2px solid transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text']:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div { - white-space: nowrap; - display: flex; - justify-content: end; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .label { - display: flex; - align-items: center; - gap: 4px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div input { - width: 40px; - padding: 0; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button { - color: light-dark(#222, #efe6d8); - font-size: 18px; - line-height: 1; - min-height: unset; - height: min-content; - padding: 4px; - font-family: 'Cinzel', serif; - margin: 0; - font-weight: normal; - border-color: light-dark(#18162e, #f3c267); - background-color: light-dark(transparent, #0e0d15); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div .level-button:hover { - background-image: none; - background-color: var(--color-warm-2); - filter: drop-shadow(0 0 3px lightgray); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details { - display: flex; - justify-content: space-between; - padding: 5px 0; - margin-bottom: 10px; - font-size: 12px; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span { - padding: 3px; - border-radius: 3px; - transition: all 0.3s ease; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span:hover { - background: light-dark(#18162e40, #f3c26740); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span.dot { - background: transparent; - cursor: default; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row { - display: flex; - gap: 20px; - align-items: center; - justify-content: space-between; - padding: 0; - margin-bottom: 15px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section { - position: relative; - display: flex; - gap: 10px; - background-color: light-dark(transparent, #18162e); - color: light-dark(#18162e, #f3c267); - padding: 5px 10px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - align-items: center; - width: fit-content; - height: 30px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4 { - font-size: 14px; - font-weight: bold; - text-transform: uppercase; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4.threshold-value, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4.threshold-value { - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .threshold-legend, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .threshold-legend { - position: absolute; - bottom: -21px; - color: light-dark(#f3c267, #18162e); - background-color: light-dark(#18162e, #f3c267); - padding: 3px; - justify-self: anchor-center; - border-radius: 0 0 3px 3px; - text-transform: capitalize; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .hope-value, -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .hope-value { - display: flex; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits { - display: flex; - justify-content: space-between; - padding: 0; - margin-bottom: 15px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait { - height: 60px; - width: 60px; - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name { - display: flex; - padding-top: 5px; - color: light-dark(#18162e, #f3c267); - font-size: 14px; - font-weight: 600; - align-items: center; - justify-content: center; - gap: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name i { - line-height: 17px; - font-size: 10px; -} -.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-value { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 20px; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section { - display: flex; - gap: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar { - position: relative; - color: light-dark(#18162e50, #efe6d850); - width: 100%; - padding-top: 5px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input { - border-radius: 50px; - font-family: 'Montserrat', sans-serif; - background: light-dark(#18162e10, #f3c26710); - border: none; - outline: 2px solid transparent; - transition: all 0.3s ease; - padding: 0 20px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder { - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input::-webkit-search-cancel-button { - -webkit-appearance: none; - display: none; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon { - align-content: center; - height: 32px; - position: absolute; - right: 20px; - font-size: 16px; - z-index: 1; - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .items-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - padding: 20px 0; - height: 80%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .currency-section { - display: flex; - gap: 10px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section { - display: flex; - align-items: center; - justify-content: space-between; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar { - position: relative; - color: light-dark(#18162e50, #efe6d850); - width: 80%; - padding-top: 5px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input { - border-radius: 50px; - font-family: 'Montserrat', sans-serif; - background: light-dark(#18162e10, #f3c26710); - border: none; - outline: 2px solid transparent; - transition: all 0.3s ease; - padding: 0 20px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:placeholder { - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input::-webkit-search-cancel-button { - -webkit-appearance: none; - display: none; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar .icon { - align-content: center; - height: 32px; - position: absolute; - right: 20px; - font-size: 16px; - z-index: 1; - color: light-dark(#18162e50, #efe6d850); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view { - background: light-dark(#18162e10, #18162e); - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 15px; - padding: 0; - gap: 0; - width: 62px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span { - margin: 1px; - width: 26px; - color: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-icon i { - margin-left: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-icon i { - margin-right: 3px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.list-active { - border-radius: 32px 3px 3px 32px; - background-color: light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #18162e); - padding: 2px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toggle-view span.grid-active { - border-radius: 3px 32px 32px 3px; - background-color: light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #18162e); - padding: 2px; -} -.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .items-section { - display: flex; - flex-direction: column; - gap: 10px; - height: 100%; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); - padding: 20px 0; - height: 90%; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content { - display: grid; - grid-template-columns: 275px 1fr; - grid-template-rows: auto 1fr; - gap: 15px 0; - height: 100%; - width: 100%; - overflow: auto; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .character-sidebar-sheet { - grid-row: 1 / span 2; - grid-column: 1; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .character-header-sheet { - grid-row: 1; - grid-column: 2; -} -.application.sheet.daggerheart.actor.dh-style.character .window-content .tab { - grid-row: 2; - grid-column: 2; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet, -body.theme-dark .application.daggerheart .character-sidebar-sheet, -body.theme-dark.application.daggerheart .character-sidebar-sheet { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-dark .application.daggerheart .character-sidebar-sheet .experience-value, -body.theme-dark.application.daggerheart .character-sidebar-sheet .experience-value { - background: url(../assets/svg/experience-shield.svg) no-repeat; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet, -body.theme-light .application.daggerheart .character-sidebar-sheet, -body.theme-light.application.daggerheart .character-sidebar-sheet { - background: transparent; -} -.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-light .application.daggerheart .character-sidebar-sheet .experience-value, -body.theme-light.application.daggerheart .character-sidebar-sheet .experience-value { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; -} -.application.sheet.dh-style .character-sidebar-sheet { - width: 275px; - min-width: 275px; - border-right: 1px solid light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .portrait { - position: relative; - border-bottom: 1px solid light-dark(#18162e, #f3c267); - cursor: pointer; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait img { - height: 235px; - width: 275px; - object-fit: cover; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait .death-roll-btn { - display: none; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll { - filter: grayscale(1); -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn { - display: flex; - position: absolute; - top: 30%; - right: 30%; - font-size: 6rem; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .portrait.death-roll .death-roll-btn:hover { - text-shadow: 0 0 8px #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section { - position: relative; - display: flex; - flex-direction: column; - top: -20px; - gap: 30px; - margin-bottom: -10px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section { - display: flex; - justify-content: space-evenly; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar { - position: relative; - width: 100px; - height: 40px; - justify-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: #efe6d8; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input { - padding: 0; - color: #efe6d8; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:hover, -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:focus { - background: rgba(24, 22, 46, 0.33); - backdrop-filter: blur(9.5px); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .status-value .bar-label { - width: 40px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - z-index: 1; - background: #18162e; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-bar { - border: none; - background: #18162e; - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-value { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-webkit-progress-value { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-moz-progress-bar { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section { - display: flex; - flex-wrap: wrap; - gap: 5px; - justify-content: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number { - justify-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(#18162e, #f3c267); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, #18162e); - z-index: 2; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-value.armor-slots { - width: 80px; - height: 30px; -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .character-sidebar-sheet .info-section .status-section .status-number .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list { - display: flex; - flex-direction: column; - gap: 5px; -} -.application.sheet.dh-style .character-sidebar-sheet .items-sidebar-list .inventory-item { - padding: 0 10px; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .equipment-section .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .loadout-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .title h3 { - font-size: 20px; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text'] { - height: 32px; - width: 180px; - border: 1px solid transparent; - outline: 2px solid transparent; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - transition: all 0.3s ease; - color: light-dark(#222, #efe6d8); -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text']:hover { - outline: 2px solid light-dark(#222, #efe6d8); -} -.application.sheet.dh-style .character-sidebar-sheet .experience-section .experience-list .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); - align-content: center; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section { - display: flex; - flex-direction: column; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title { - display: flex; - gap: 15px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title h3, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title h3 { - font-size: 20px; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-section .items-list, -.application.sheet.daggerheart.actor.dh-style.companion .attack-section .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .partner-placeholder { - display: flex; - opacity: 0.6; - text-align: center; - font-style: italic; - justify-content: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row .experience-name { - width: 180px; - text-align: start; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: 'Montserrat', sans-serif; - color: light-dark(#222, #efe6d8); - align-content: center; - text-align: center; - background: url(../assets/svg/experience-shield.svg) no-repeat; -} -.theme-light .application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .profile { - height: 235px; - width: 100%; - object-fit: cover; - cursor: pointer; - mask-image: linear-gradient(0deg, transparent 0%, black 10%); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name { - display: flex; - align-items: center; - position: relative; - top: -30px; - gap: 20px; - padding: 0 20px; - margin-bottom: -30px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name input[type='text'] { - font-size: 24px; - height: 32px; - text-align: center; - border: 1px solid transparent; - outline: 2px solid transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name input[type='text']:hover { - outline: 2px solid light-dark(#222, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section { - display: flex; - gap: 5px; - justify-content: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number { - justify-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-value { - position: relative; - display: flex; - width: 50px; - height: 40px; - border: 1px solid light-dark(#18162e, #f3c267); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, #18162e); - z-index: 2; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-value.armor-slots { - width: 80px; - height: 30px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar { - position: relative; - width: 100px; - height: 40px; - justify-items: center; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: #efe6d8; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value input[type='number'].bar-input { - padding: 0; - color: #efe6d8; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value input[type='number'].bar-input:hover, -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value input[type='number'].bar-input:focus { - background: rgba(24, 22, 46, 0.33); - backdrop-filter: blur(9.5px); -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .status-value .bar-label { - width: 40px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - z-index: 1; - background: #18162e; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar::-webkit-progress-bar { - border: none; - background: #18162e; - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar::-webkit-progress-value { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar.stress-color::-webkit-progress-value { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar::-moz-progress-bar { - background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar.stress-color::-moz-progress-bar { - background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%); - border-radius: 6px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .level-up-label { - font-size: 24px; - padding-top: 8px; -} -.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .companion-navigation { - display: flex; - gap: 8px; - align-items: center; - width: 100%; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style.companion, -.themed.theme-dark.application.daggerheart.sheet.dh-style.companion, -body.theme-dark .application.daggerheart.companion, -body.theme-dark.application.daggerheart.companion { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-light .application.daggerheart.sheet.dh-style.companion, -.themed.theme-light.application.daggerheart.sheet.dh-style.companion, -body.theme-light .application.daggerheart.companion, -body.theme-light.application.daggerheart.companion { - background: url('../assets/parchments/dh-parchment-light.png'); -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet { - display: flex; - flex-direction: column; - justify-content: start; - text-align: center; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .profile { - width: 100%; - height: 235px; - object-fit: cover; - mask-image: linear-gradient(0deg, transparent 0%, black 10%); - cursor: pointer; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container { - display: flex; - align-items: center; - position: relative; - top: -45px; - gap: 20px; - padding: 0 20px; - margin-bottom: -30px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info { - display: flex; - flex-direction: column; - gap: 8px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags { - display: flex; - gap: 10px; - padding-bottom: 0; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - font: 'Montserrat', sans-serif; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-info .tags .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number { - justify-items: center; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(#18162e, #f3c267); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, #18162e); - z-index: 2; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-value.armor-slots { - width: 80px; - height: 30px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .status-number .status-label h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(#efe6d8, #18162e); -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:hover[type='text'], -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .item-container .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info { - display: flex; - flex-direction: column; - gap: 12px; - padding: 10px 20px; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .description, -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-info .impulses { - text-align: start; - font-family: 'Montserrat', sans-serif; -} -.application.sheet.daggerheart.actor.dh-style.environment .environment-header-sheet .environment-navigation { - display: flex; - gap: 20px; - align-items: center; - padding: 0 20px; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style.environment, -.themed.theme-dark.application.daggerheart.sheet.dh-style.environment, -body.theme-dark .application.daggerheart.environment, -body.theme-dark.application.daggerheart.environment { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-light .application.daggerheart.sheet.dh-style.environment, -.themed.theme-light.application.daggerheart.sheet.dh-style.environment, -body.theme-light .application.daggerheart.environment, -body.theme-light.application.daggerheart.environment { - background: url('../assets/parchments/dh-parchment-light.png'); -} -.application.sheet.daggerheart.actor.dh-style.environment .tab { - max-height: 300px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section { - display: grid; - gap: 10px; - grid-template-columns: 1fr 1.5fr 1.5fr; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section .drop-section { - width: 100%; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items { - margin-bottom: 10px; - width: 100%; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child { - margin-bottom: 0px; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line { - display: grid; - align-items: center; - gap: 10px; - grid-template-columns: 1fr 3fr 1fr; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: light-dark(#222, #efe6d8); -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.application.sheet.daggerheart.dh-style.domain-card section.tab { - height: 400px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.sheet.daggerheart.dh-style.feature .item-sheet-header { - display: flex; -} -.application.sheet.daggerheart.dh-style.feature .item-sheet-header .profile { - height: 130px; - width: 130px; -} -.application.sheet.daggerheart.dh-style.feature section.tab { - height: 400px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .window-content .dialog-header { - width: 100%; - padding-bottom: 16px; -} -.application.daggerheart.dh-style.dialog .window-content .dialog-header h1 { - font-family: 'Cinzel', serif; - font-style: normal; - font-weight: 700; - font-size: 24px; - margin: 0; - text-align: center; - color: light-dark(#18162e, #f3c267); -} -.application.daggerheart.dh-style.dialog .tab.details.active, -.application.daggerheart.dh-style.dialog .tab.attack.active { - display: flex; - flex-direction: column; - gap: 16px; -} -.application.daggerheart.dh-style.dialog .tab .fieldsets-section { - display: flex; - gap: 16px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .add-experience-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item { - display: grid; - grid-template-columns: 3fr 1fr 30px; - align-items: center; - gap: 5px; -} -.application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item a { - text-align: center; -} -.application.daggerheart.dh-style.dialog .tab.features { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .tab.features .add-feature-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item img { - height: 40px; - width: 40px; - object-fit: cover; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .label { - font-family: 'Montserrat', sans-serif; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls { - display: flex; - gap: 5px; -} -.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls a { - text-align: center; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .add-feature-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item img { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .label { - font-family: 'Montserrat', sans-serif; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls { - display: flex; - gap: 5px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls a { - text-align: center; -} -.application.daggerheart.dh-style.dialog .tab.adversaries { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .add-action-btn { - width: 100%; - margin-bottom: 12px; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container { - display: flex; - flex-direction: column; - align-items: start; - gap: 8px; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .category-name { - display: flex; - align-items: center; - gap: 10px; - width: 100%; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .category-container .adversaries-container { - display: flex; - flex-direction: column; - gap: 6px; - width: 100%; -} -.application.daggerheart.dh-style.dialog .tab.adversaries .adversaries-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - border: 1px dashed light-dark(#18162e50, #efe6d850); - border-radius: 3px; - color: light-dark(#18162e50, #efe6d850); - font-family: 'Montserrat', sans-serif; -} -.daggerheart.levelup .levelup-navigation-container { - display: flex; - align-items: center; - gap: 22px; - height: 36px; -} -.daggerheart.levelup .levelup-navigation-container nav { - flex: 1; -} -.daggerheart.levelup .levelup-navigation-container nav .levelup-tab-container { - display: flex; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions { - width: 306px; - display: flex; - justify-content: end; - gap: 16px; - margin-right: 4px; -} -.daggerheart.levelup .levelup-navigation-container .levelup-navigation-actions * { - width: calc(50% - 8px); -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card { - border: 1px solid; - border-radius: 4px; - padding-right: 4px; - font-size: 18px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-selections-container .achievement-experience-cards .achievement-experience-card .achievement-experience-marker { - border: 1px solid; - border-radius: 50%; - height: 18px; - width: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection { - display: flex; - flex-wrap: wrap; - gap: 40px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .card-preview-container { - width: calc(100% * (1 / 5)); -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container { - display: flex; - flex-direction: column; - align-items: center; - flex: 1; - position: relative; - cursor: pointer; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container.disabled { - pointer-events: none; - opacity: 0.4; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-label { - position: absolute; - text-align: center; - top: 4px; - background: grey; - padding: 0 12px; - border-radius: 6px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container img { - height: 124px; -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected { - position: absolute; - height: 54px; - width: 54px; - border-radius: 50%; - border: 2px solid; - font-size: 48px; - display: flex; - align-items: center; - justify-content: center; - background-image: url(../assets/parchments/dh-parchment-light.png); - color: var(--color-dark-5); - top: calc(50% - 29px); -} -.daggerheart.levelup .levelup-selections-container .levelup-card-selection .levelup-domains-selection-container .levelup-domain-selection-container .levelup-domain-selected i { - position: relative; - right: 2px; -} -.daggerheart.levelup .levelup-selections-container .levelup-selections-title { - display: flex; - align-items: center; - gap: 4px; -} -.daggerheart.levelup .levelup-selections-container .levelup-radio-choices { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-selections-container .levelup-radio-choices label { - flex: 0; -} -.themed.theme-light .application.daggerheart.sheet.dh-style.levelup .tiers-container .tier-container, -.themed.theme-light.application.daggerheart.sheet.dh-style.levelup .tiers-container .tier-container, -body.theme-light .application.daggerheart.levelup .tiers-container .tier-container, -body.theme-light.application.daggerheart.levelup .tiers-container .tier-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.daggerheart.levelup .window-content { - max-height: 960px; - overflow: auto; -} -.daggerheart.levelup div[data-application-part='form'] { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup section .section-container { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: 8px; -} -.daggerheart.levelup .levelup-footer { - display: flex; -} -.daggerheart.levelup .levelup-summary-container .level-achievements-container, -.daggerheart.levelup .levelup-summary-container .level-advancements-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.levelup .levelup-summary-container .level-achievements-container h2, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h2, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h3, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h3, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h4, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h4, -.daggerheart.levelup .levelup-summary-container .level-achievements-container h5, -.daggerheart.levelup .levelup-summary-container .level-advancements-container h5 { - margin: 0; - color: var(--color-text-secondary); -} -.daggerheart.levelup .levelup-summary-container .increase-container { - display: flex; - align-items: center; - gap: 4px; - font-size: 20px; -} -.daggerheart.levelup .levelup-summary-container .summary-selection-container { - display: flex; - gap: 8px; -} -.daggerheart.levelup .levelup-summary-container .summary-selection-container .summary-selection { - border: 2px solid; - border-radius: 6px; - padding: 0 4px; - font-size: 18px; -} -.daggerheart.levelup .tiers-container { - display: flex; - gap: 16px; -} -.daggerheart.levelup .tiers-container .tier-container { - flex: 1; - display: flex; - flex-direction: column; - gap: 8px; - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.levelup .tiers-container .tier-container.inactive { - opacity: 0.4; - pointer-events: none; -} -.daggerheart.levelup .tiers-container .tier-container legend { - margin-left: auto; - margin-right: auto; - font-size: 22px; - font-weight: bold; - padding: 0 12px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container { - display: grid; - grid-template-columns: 1fr 3fr; - gap: 4px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container { - display: flex; - justify-content: end; - gap: 4px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer { - display: flex; - height: min-content; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi { - border: 2px solid grey; - padding: 2.4px 2.5px 0; - border-radius: 4px; - gap: 2px; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer.multi .selection-checkbox { - margin-left: 0; - margin-right: 0; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkboxes-container .checkbox-grouping-coontainer .selection-checkbox { - margin: 0; -} -.daggerheart.levelup .tiers-container .tier-container .checkbox-group-container .checkbox-group-label { - font-size: 14px; - font-style: italic; -} -/* Base Value */ -/* Margins */ -/* Borders */ -/* Padding */ -/* Inputs */ -.daggerheart.views .downtime-container .downtime-header { - margin: 0; - color: light-dark(#18162e, #f3c267); - text-align: center; -} -.daggerheart.views .downtime-container .activity-container { - display: flex; - align-items: center; - padding: 8px; -} -.daggerheart.views .downtime-container .activity-container .activity-title { - flex: 1; - display: flex; - align-items: center; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-title-text { - font-size: 24px; - font-weight: bold; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image { - width: 80px; - position: relative; - display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image img { - border-radius: 50%; -} -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image:hover, -.daggerheart.views .downtime-container .activity-container .activity-title .activity-image.selected { - filter: drop-shadow(0 0 6px gold); -} -.daggerheart.views .downtime-container .activity-container .activity-title .custom-name-input { - font-size: 24px; - font-weight: bold; - padding: 0; - background: transparent; - color: #efe6d8; -} -.daggerheart.views .downtime-container .activity-container .activity-body { - flex: 1; - font-style: italic; -} -.daggerheart.views.downtime .activity-text-area { - resize: none; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - gap: 4px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container { - position: relative; - display: flex; - justify-content: center; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - cursor: pointer; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container.inactive { - opacity: 0.4; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container img { - width: 100%; - border-radius: 6px; -} -.application.daggerheart.dh-style.views.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { - position: absolute; - top: 4px; - display: flex; - flex-wrap: wrap; - font-size: 16px; - margin: 0 4px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.themed.theme-dark .application.daggerheart.sheet.dh-style.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, -.themed.theme-dark.application.daggerheart.sheet.dh-style.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, -body.theme-dark .application.daggerheart.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title, -body.theme-dark.application.daggerheart.beastform-selection .beastforms-container .beastforms-tier .beastform-container .beastform-title { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.application.daggerheart.dh-style.views.beastform-selection footer { - margin-top: 8px; - display: flex; -} -.application.daggerheart.dh-style.views.beastform-selection footer button { - flex: 1; -} -.daggerheart.dh-style.dialog.character-creation .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .creation-action-footer button { - flex: 1; - height: 100%; - white-space: nowrap; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container { - width: 140px; - display: flex; - flex-direction: column; - text-align: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-container .card-preview-container { - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .selections-outer-container { - display: flex; - justify-content: space-evenly; - height: 210px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container { - border-radius: 8px; - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container { - position: relative; - border-radius: 8px; - border-color: light-dark(#18162e, #f3c267); - display: flex; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container legend { - font-size: 20px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button { - position: absolute; - bottom: -8px; - height: 16px; - width: 110px; - min-height: unset; - border: 1px solid light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #efe6d8); - background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .section-container .section-inner-container .action-button:hover { - background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); - filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container { - text-align: center; - display: flex; - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container { - display: flex; - flex-wrap: wrap; - width: 176px; - gap: 4px; - margin-bottom: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container { - width: 56px; - white-space: nowrap; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container { - display: flex; - justify-content: space-evenly; - gap: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .traits-container .traits-inner-container .trait-container { - border: 1px solid light-dark(#18162e, #f3c267); - padding: 0 4px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container { - display: flex; - justify-content: space-evenly; - text-align: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-description { - border-color: light-dark(#18162e, #f3c267); - padding-right: 24px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .experiences-inner-container .experience-container .experience-value { - position: absolute; - right: 0; - width: 22px; - border-left: 1px solid light-dark(#18162e, #f3c267); - height: 100%; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section { - display: flex; - align-items: center; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav { - flex: 1; - gap: 8px; - border: 0; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .nav-section-text { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker { - position: absolute; - align-self: center; - top: -10px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 20px; - width: 20px; - font-size: 14px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .finish-marker.finished { - background-color: var(--color-warm-2); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .creation-action-footer .footer-section button { - flex: 1; - height: 100%; - white-space: nowrap; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .main-equipment-selection.triple { - grid-template-columns: 1fr 1fr 1fr; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - white-space: nowrap; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-subsection { - display: flex; - align-items: start; - gap: 32px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .equipment-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container { - display: flex; - flex-direction: column; - justify-content: space-evenly; - gap: 8px; - height: 100%; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment { - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 8px; - position: relative; - display: flex; - justify-content: center; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.selectable { - cursor: pointer; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment.inactive { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { - position: absolute; - top: -8px; - font-size: 12px; - white-space: nowrap; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url('../assets/parchments/dh-parchment-light.png'); - padding: 0 2px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment img { - width: 60px; - height: 60px; - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container { - position: relative; - display: flex; - justify-content: center; - height: min-content; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 8px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container { - position: relative; - display: flex; - justify-content: center; - align-items: center; - padding: 6px; - cursor: grab; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container.taken { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container label { - position: absolute; - top: -2px; - font-size: 12px; -} -.daggerheart.dh-style.dialog.character-creation .main-selections-container .equipment-selection .suggestion-container .suggestion-inner-container img { - width: 120px; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .tab-navigation nav a .descriptor, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .tab-navigation nav a .descriptor, -body.theme-dark .application.daggerheart .character-creation .tab-navigation nav a .descriptor, -body.theme-dark.application.daggerheart .character-creation .tab-navigation nav a .descriptor { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, -body.theme-dark .application.daggerheart .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, -body.theme-dark.application.daggerheart .character-creation .main-selections-container .traits-container .suggested-traits-container .suggested-trait-container, -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, -body.theme-dark .application.daggerheart .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, -body.theme-dark.application.daggerheart .character-creation .main-selections-container .creation-action-footer .footer-section nav a .descriptor, -.themed.theme-dark .application.daggerheart.sheet.dh-style .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, -.themed.theme-dark.application.daggerheart.sheet.dh-style .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, -body.theme-dark .application.daggerheart .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label, -body.theme-dark.application.daggerheart .character-creation .main-selections-container .equipment-selection .simple-equipment-container .simple-equipment label { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.dh-style.dialog.character-creation .window-content { - gap: 16px; -} -.daggerheart.dh-style.dialog.character-creation .window-content .tab { - overflow-y: auto; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav { - flex: 1; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a.disabled { - opacity: 0.4; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .nav-section-text { - position: relative; - display: flex; - align-items: center; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker { - position: absolute; - align-self: center; - top: -8px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 16px; - width: 16px; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .finish-marker.active { - background-color: var(--color-warm-2); -} -.daggerheart.dh-style.dialog.character-creation .tab-navigation nav a .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - color: light-dark(#efe6d8, #222); - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container { - display: flex; - flex-direction: column; - gap: 12px; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section { - display: flex; - gap: 60px; - justify-content: center; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; - width: 120px; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-icon { - width: 70px; - height: 70px; - object-fit: contain; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select { - display: flex; - align-items: center; - gap: 10px; - height: 32px; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select .label { - font-family: 'Cinzel', serif; - font-style: normal; - font-weight: 700; - font-size: 16px; - line-height: 19px; - color: light-dark(#222, #efe6d8); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container { - display: flex; - gap: 10px; - flex-wrap: wrap; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip { - display: flex; - align-items: center; - border-radius: 5px; - width: fit-content; - gap: 5px; - cursor: pointer; - padding: 5px; - background: light-dark(#18162e10, #f3c26710); - color: light-dark(#18162e, #f3c267); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip .label { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 17px; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip.selected { - background: light-dark(#18162e40, #f3c26740); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip, -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip { - display: flex; - align-items: center; - border-radius: 5px; - width: fit-content; - gap: 5px; - cursor: pointer; - padding: 5px; - transition: all 0.3s ease; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip .label, -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip .label { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 17px; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip { - background: #40a64010; - color: #40a640; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip.selected { - color: #efe6d8; - background: linear-gradient(151.21deg, #40a640 7.21%, #011b01 92.79%); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip { - background: #e54e4e10; - color: #e54e4e; -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip.selected { - color: #efe6d8; - background: linear-gradient(151.21deg, #e54e4e 7.21%, #3c0000 92.79%); -} -.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .formula-label { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 17px; - color: light-dark(#222, #efe6d8); -} -.daggerheart.views.damage-reduction .damage-reduction-container { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .section-container { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .padded { - padding: 0 8px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .armor-title { - margin: 0; - white-space: nowrap; -} -.daggerheart.views.damage-reduction .damage-reduction-container .resources-container { - display: flex; - gap: 8px; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .resources-container .resource-container { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection { - display: flex; - align-items: center; - width: 100%; - margin: 0; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner { - display: flex; - gap: 2px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner:not(:last-child) { - margin-right: 8px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container { - cursor: pointer; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - height: 26px; - padding: 0 1px; - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - opacity: 0.4; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.selected { - opacity: 1; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container.inactive { - cursor: initial; - opacity: 0.2; -} -.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-selection-inner .mark-container .fa-shield { - position: relative; - right: 0.5px; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container { - margin: 0; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction { - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - height: 26px; - padding: 0 4px; - font-size: 18px; - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - opacity: 0.4; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.active { - opacity: 1; - cursor: pointer; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.selected { - opacity: 1; - background: var(--color-warm-2); - color: white; -} -.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction .stress-reduction-cost { - display: flex; - align-items: center; -} -.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle { - margin: -4px 0 0 0; -} -.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle.bold { - font-variant: all-small-caps; - font-weight: bold; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer { - display: flex; - width: 100%; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button { - flex: 1; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value { - font-weight: bold; -} -.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value.reduced-value { - opacity: 0.4; - text-decoration: line-through; -} -.daggerheart.views.damage-reduction .window-content { - padding: 8px 0; -} -@keyframes glow { - 0% { - box-shadow: 0 0 1px 1px #f3c267; - } - 100% { - box-shadow: 0 0 2px 2px #f3c267; - } -} -@keyframes glow-dark { - 0% { - box-shadow: 0 0 1px 1px #18162e; - } - 100% { - box-shadow: 0 0 2px 2px #18162e; - } -} -@font-face { - font-family: 'Cinzel'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzel/v25/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype'); -} -@font-face { - font-family: 'Cinzel'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzel/v25/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype'); -} -@font-face { - font-family: 'Cinzel Decorative'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url(https://fonts.gstatic.com/s/cinzeldecorative/v18/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf) format('truetype'); -} -@font-face { - font-family: 'Montserrat'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); -} -@font-face { - font-family: 'Montserrat'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); -} -.application.sheet.daggerheart.dh-style h1 { - font-family: 'Cinzel Decorative', serif; - margin: 0; - border: none; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h2, -.application.sheet.daggerheart.dh-style h3 { - font-family: 'Cinzel', serif; - margin: 0; - border: none; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h4 { - font-family: 'Montserrat', sans-serif; - font-size: 14px; - border: none; - font-weight: 700; - margin: 0; - text-shadow: none; - color: #f3c267; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style h5 { - font-size: 14px; - color: #f3c267; - margin: 0; - font-weight: normal; -} -.application.sheet.daggerheart.dh-style p, -.application.sheet.daggerheart.dh-style span { - font-family: 'Montserrat', sans-serif; -} -.application.sheet.daggerheart.dh-style small { - font-family: 'Montserrat', sans-serif; - opacity: 0.8; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style, -.themed.theme-dark.application.daggerheart.sheet.dh-style, -body.theme-dark .application.daggerheart, -body.theme-dark.application.daggerheart { - background: rgba(24, 22, 46, 0.33); - backdrop-filter: blur(9px); -} -.themed.theme-light .application.daggerheart.sheet.dh-style, -.themed.theme-light.application.daggerheart.sheet.dh-style, -body.theme-light .application.daggerheart, -body.theme-light.application.daggerheart { - background: url('../assets/parchments/dh-parchment-light.png') no-repeat center; -} -.application.sheet.dh-style { - border-radius: 10px; -} -.application.sheet.dh-style .window-header { - background: transparent; - border-bottom: none; - justify-content: end; -} -.application.sheet.dh-style .window-header h1 { - color: light-dark(#18162e, #efe6d8); - font-family: 'Montserrat', sans-serif; -} -.application.sheet.dh-style .window-header button { - background: light-dark(transparent, #0e0d15); - color: light-dark(#18162e, #efe6d8); - border: 1px solid light-dark(#18162e, transparent); - padding: 0; -} -.application.sheet.dh-style .window-header button:hover { - border-color: light-dark(#18162e, #f3c267); - color: light-dark(#18162e, #f3c267); -} -.application.sheet.dh-style .window-content { - padding: 0; - position: relative; - top: -36px; - min-height: -webkit-fill-available; - transition: opacity 0.3s ease; -} -.application.sheet.dh-style .window-content .tab { - padding: 0 10px; -} -.application.sheet.dh-style.minimized .window-content { - opacity: 0; - transition-duration: 0.1s; -} -.application.sheet.dh-style:not(.minimized) .window-title, -.application.sheet.dh-style:not(.minimized) .window-icon { - display: none; - opacity: 0; - transition: opacity 0.3s ease; -} -.application.sheet.dh-style:not(.minimized) .window-content { - opacity: 1; -} -.themed.theme-dark .application.daggerheart.sheet.dh-style.dialog, -.themed.theme-dark.application.daggerheart.sheet.dh-style.dialog, -body.theme-dark .application.daggerheart.dialog, -body.theme-dark.application.daggerheart.dialog { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - background-repeat: no-repeat; - background-position: center; -} -.themed.theme-light .application.daggerheart.sheet.dh-style.dialog, -.themed.theme-light.application.daggerheart.sheet.dh-style.dialog, -body.theme-light .application.daggerheart.dialog, -body.theme-light.application.daggerheart.dialog { - background-image: url('../assets/parchments/dh-parchment-light.png'); - background-repeat: no-repeat; - background-position: center; -} -.application.dialog.dh-style { - border: none; -} -.application.dialog.dh-style .window-header { - background: transparent; - border-bottom: none; - color: light-dark(#18162e, #efe6d8); -} -.application.dialog.dh-style .window-header h1 { - color: light-dark(#18162e, #efe6d8); - font-family: 'Montserrat', sans-serif; -} -.application.dialog.dh-style .window-header button { - color: light-dark(#18162e, #efe6d8); - background: light-dark(transparent, #0e0d15); - border: 1px solid light-dark(#18162e, transparent); - padding: 0; -} -.application.dialog.dh-style .window-header button:hover { - border: 1px solid light-dark(#18162e, #f3c267); - color: light-dark(#18162e, #f3c267); -} -.application.dh-style { - border: 1px solid light-dark(#18162e, #f3c267); -} -.application.dh-style input[type='text'], -.application.dh-style input[type='number'] { - background: light-dark(transparent, transparent); - border-radius: 6px; - box-shadow: 0 4px 30px rgba(0, 0, 0, 0.05); - backdrop-filter: blur(9.5px); - -webkit-backdrop-filter: blur(9.5px); - outline: none; - color: light-dark(#18162e, #f3c267); - border: 1px solid light-dark(#222, #efe6d8); -} -.application.dh-style input[type='text']:hover[type='text'], -.application.dh-style input[type='number']:hover[type='text'], -.application.dh-style input[type='text']:hover[type='number'], -.application.dh-style input[type='number']:hover[type='number'], -.application.dh-style input[type='text']:focus[type='text'], -.application.dh-style input[type='number']:focus[type='text'], -.application.dh-style input[type='text']:focus[type='number'], -.application.dh-style input[type='number']:focus[type='number'] { - background: light-dark(rgba(0, 0, 0, 0.05), rgba(24, 22, 46, 0.33)); - box-shadow: none; - outline: 2px solid light-dark(#222, #efe6d8); -} -.application.dh-style input[type='text']:disabled[type='text'], -.application.dh-style input[type='number']:disabled[type='text'], -.application.dh-style input[type='text']:disabled[type='number'], -.application.dh-style input[type='number']:disabled[type='number'] { - outline: 2px solid transparent; - cursor: not-allowed; -} -.application.dh-style input[type='text']:disabled[type='text']:hover, -.application.dh-style input[type='number']:disabled[type='text']:hover, -.application.dh-style input[type='text']:disabled[type='number']:hover, -.application.dh-style input[type='number']:disabled[type='number']:hover { - background: transparent; -} -.application.dh-style input[type='checkbox']:checked::after { - color: light-dark(#222, #f3c267); -} -.application.dh-style input[type='checkbox']:checked::before { - color: light-dark(transparent, #18162e); -} -.application.dh-style input[type='checkbox']::before { - color: light-dark(#222, #efe6d8); -} -.application.dh-style button { - background: light-dark(transparent, #f3c267); - border: 1px solid light-dark(#18162e, #18162e); - color: light-dark(#18162e, #18162e); - outline: none; - box-shadow: none; -} -.application.dh-style button:hover { - background: light-dark(rgba(0, 0, 0, 0.3), #18162e); - color: light-dark(#18162e, #f3c267); -} -.application.dh-style button.glow { - animation: glow 0.75s infinite alternate; -} -.application.dh-style button:disabled { - background: light-dark(transparent, #f3c267); - color: light-dark(#18162e, #18162e); - opacity: 0.6; - cursor: not-allowed; -} -.application.dh-style button:disabled:hover { - background: light-dark(transparent, #f3c267); - color: light-dark(#18162e, #18162e); -} -.application.dh-style select { - background: light-dark(transparent, transparent); - color: light-dark(#222, #efe6d8); - font-family: 'Montserrat', sans-serif; - outline: 2px solid transparent; - border: 1px solid light-dark(#222, #efe6d8); -} -.application.dh-style select:focus, -.application.dh-style select:hover { - outline: 2px solid light-dark(#222, #efe6d8); - box-shadow: none; -} -.application.dh-style select option, -.application.dh-style select optgroup { - color: #efe6d8; - background-color: #18162e; - border-radius: 6px; -} -.application.dh-style select:disabled { - opacity: 0.6; - outline: 2px solid transparent; - cursor: not-allowed; -} -.application.dh-style p { - margin: 0; -} -.application.dh-style ul { - margin: 0; - padding: 0; - list-style: none; -} -.application.dh-style li { - margin: 0; -} -.application.dh-style a:hover, -.application.dh-style a.active { - font-weight: bold; - text-shadow: 0 0 8px light-dark(#18162e, #f3c267); -} -.application.dh-style fieldset { - align-items: center; - margin-top: 5px; - border-radius: 6px; - border-color: light-dark(#18162e, #f3c267); -} -.application.dh-style fieldset.glassy { - background-color: light-dark(#18162e10, #f3c26710); - border-color: transparent; -} -.application.dh-style fieldset.glassy legend { - padding: 2px 12px; - border-radius: 3px; - background-color: light-dark(#18162e, #f3c267); - color: light-dark(#efe6d8, #18162e); -} -.application.dh-style fieldset.fit-height { - height: 95%; -} -.application.dh-style fieldset.flex { - display: flex; - gap: 20px; -} -.application.dh-style fieldset.flex.wrap { - flex-wrap: wrap; - gap: 10px 20px; -} -.application.dh-style fieldset.flex .inline-child { - flex: 1; -} -.application.dh-style fieldset .list-w-img { - padding: 5px; -} -.application.dh-style fieldset .list-w-img label { - flex: 1; -} -.application.dh-style fieldset .list-w-img img { - width: 2rem; - height: 2rem; -} -.application.dh-style fieldset.one-column { - display: flex; - flex-direction: column; - align-items: start; - gap: 10px; - min-height: 64px; - flex: 1; -} -.application.dh-style fieldset.one-column > .one-column { - width: 100%; -} -.application.dh-style fieldset.two-columns { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 10px; -} -.application.dh-style fieldset.two-columns.even { - grid-template-columns: 1fr 1fr; -} -.application.dh-style fieldset.two-columns .full-width { - grid-column: span 2; -} -.application.dh-style fieldset legend { - font-family: 'Montserrat', sans-serif; - font-weight: bold; - color: light-dark(#18162e, #f3c267); -} -.application.dh-style fieldset input[type='text'], -.application.dh-style fieldset input[type='number'] { - color: light-dark(#222, #efe6d8); - font-family: 'Montserrat', sans-serif; - transition: all 0.3s ease; - outline: 2px solid transparent; -} -.application.dh-style fieldset input[type='text']:focus, -.application.dh-style fieldset input[type='number']:focus, -.application.dh-style fieldset input[type='text']:hover, -.application.dh-style fieldset input[type='number']:hover { - outline: 2px solid light-dark(#222, #efe6d8); -} -.application.dh-style fieldset[disabled], -.application.dh-style fieldset.child-disabled .form-group, -.application.dh-style fieldset select[disabled], -.application.dh-style fieldset input[disabled] { - opacity: 0.5; -} -.application.dh-style fieldset.child-disabled .form-group { - pointer-events: none; -} -.application.dh-style fieldset .nest-inputs { - display: flex; - align-items: center; - width: 100%; - gap: 5px; -} -.application.dh-style fieldset .nest-inputs .btn { - padding-top: 15px; -} -.application.dh-style fieldset .nest-inputs .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.application.dh-style fieldset .nest-inputs > .checkbox { - align-self: end; -} -.application.dh-style fieldset .form-group { - width: 100%; -} -.application.dh-style fieldset .form-group label { - font-family: 'Montserrat', sans-serif; - font-weight: bold; - font-size: smaller; -} -.application.dh-style fieldset .form-group.checkbox { - width: fit-content; - display: flex; - align-items: center; -} -.application.dh-style fieldset .form-group.checkbox .form-fields { - height: 32px; - align-content: center; -} -.application.dh-style fieldset:has(.list-w-img) { - gap: 0; -} -.application.dh-style .two-columns { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 10px; -} -.application.dh-style .two-columns.even { - grid-template-columns: 1fr 1fr; -} -.application.dh-style line-div { - display: block; - height: 1px; - width: 100%; - border-bottom: 1px solid light-dark(#18162e, #f3c267); - mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%); -} -.application.dh-style side-line-div { - display: block; - height: 1px; - width: 100%; - border-bottom: 1px solid light-dark(#18162e, #f3c267); - mask-image: linear-gradient(270deg, transparent 0%, black 100%); -} -.application.dh-style side-line-div.invert { - mask-image: linear-gradient(270deg, black 0%, transparent 100%); -} -.application.dh-style .item-description { - opacity: 1; - transform: translateY(0); - grid-column: 1/-1; - transition: opacity 0.3s ease-out, transform 0.3s ease-out; -} -.application.dh-style .item-description.invisible { - height: 0; - opacity: 0; - overflow: hidden; - transform: translateY(-20px); - transform-origin: top; -} -.application.setting.dh-style fieldset h2, -.application.setting.dh-style fieldset h3, -.application.setting.dh-style fieldset h4 { - margin: 8px 0 4px; - text-align: center; -} -.application.setting.dh-style fieldset .title-hint { - font-size: 12px; - font-variant: small-caps; - text-align: center; -} -.application.setting.dh-style fieldset .field-section .split-section { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} -.application.setting.dh-style fieldset .label-container { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} -.application.setting.dh-style fieldset .label-container label { - align-self: center; - text-align: center; -} -.application.setting.dh-style footer { - margin-top: 8px; - display: flex; - gap: 8px; -} -.application.setting.dh-style footer button { - flex: 1; -} -.application.setting.dh-style .form-group { - display: flex; - justify-content: space-between; - align-items: center; -} -.application.setting.dh-style .form-group label { - font-size: 16px; -} -.application.setting.dh-style .form-group .form-fields { - display: flex; - gap: 4px; - align-items: center; -} -.system-daggerheart .tagify { - background: light-dark(transparent, transparent); - border: 1px solid light-dark(#222, #efe6d8); - height: 34px; - border-radius: 3px; - margin-right: 1px; -} -.system-daggerheart .tagify tag div { - display: flex; - justify-content: space-between; - align-items: center; - height: 22px; -} -.system-daggerheart .tagify tag div span { - font-weight: 400; -} -.system-daggerheart .tagify tag div img { - margin-left: 8px; - height: 20px; - width: 20px; -} -.system-daggerheart .tagify__dropdown { - border: 1px solid light-dark(#222, #efe6d8) !important; -} -.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper { - background-image: url(../assets/parchments/dh-parchment-dark.png); - background-color: transparent; - border: 0; -} -.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper .tagify__dropdown__item--active { - background-color: light-dark(#222, #efe6d8); - color: var(--color-dark-3); -} -.system-daggerheart.theme-light .tagify__dropdown { - color: black; -} -.system-daggerheart.theme-light .tagify__dropdown .tagify__dropdown__wrapper { - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.system-daggerheart.theme-light .tagify__dropdown .tagify__dropdown__item--active { - color: #efe6d8; -} -.theme-light .application.sheet.dh-style button.glow { - animation: glow-dark 0.75s infinite alternate; -} -.theme-light .application .component.dh-style.card-preview-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); -} -.theme-light .application .component.dh-style.card-preview-container .preview-text-container { - background-image: url(../assets/parchments/dh-parchment-dark.png); -} -.theme-light .application .component.dh-style.card-preview-container .preview-selected-icon-container { - background-image: url(../assets/parchments/dh-parchment-dark.png); - color: var(--color-light-5); -} -.application .component.dh-style.card-preview-container { - position: relative; - border-radius: 6px; - border: 2px solid var(--color-tabs-border); - display: flex; - flex-direction: column; - aspect-ratio: 0.75; - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.application .component.dh-style.card-preview-container.selectable { - cursor: pointer; -} -.application .component.dh-style.card-preview-container.disabled { - pointer-events: none; - opacity: 0.4; -} -.application .component.dh-style.card-preview-container .preview-image-outer-container { - position: relative; - display: flex; - align-items: center; - justify-content: center; -} -.application .component.dh-style.card-preview-container .preview-image-container { - flex: 1; - border-radius: 4px 4px 0 0; -} -.application .component.dh-style.card-preview-container .preview-text-container { - flex: 1; - border-radius: 0 0 4px 4px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 18px; - text-align: center; - color: var(--color-text-selection-bg); - background-image: url(../assets/parchments/dh-parchment-light.png); -} -.application .component.dh-style.card-preview-container .preview-empty-container { - pointer-events: none; - position: relative; - display: flex; - align-items: center; - justify-content: center; - flex: 1; -} -.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container { - width: 100%; - display: flex; - justify-content: center; -} -.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-add-icon { - font-size: 48px; -} -.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-empty-subtext { - position: absolute; - top: 10%; - font-size: 18px; - font-variant: small-caps; - text-align: center; -} -.application .component.dh-style.card-preview-container .preview-selected-icon-container { - position: absolute; - height: 54px; - width: 54px; - border-radius: 50%; - border: 2px solid; - font-size: 48px; - display: flex; - align-items: center; - justify-content: center; - background-image: url(../assets/parchments/dh-parchment-light.png); - color: var(--color-dark-5); -} -.application .component.dh-style.card-preview-container .preview-selected-icon-container i { - position: relative; - right: 2px; -} -.daggerheart.dh-style .tab-navigation { - margin: 5px 0; - height: 40px; - width: 100%; -} -.daggerheart.dh-style .tab-navigation .feature-tab { - border: none; -} -.daggerheart.dh-style .tab-navigation .feature-tab a { - color: light-dark(#18162e, #f3c267); - font-family: 'Montserrat', sans-serif; -} -.sheet.daggerheart.dh-style .tab-form-footer { - display: flex; - padding: 0 10px; -} -.sheet.daggerheart.dh-style .tab-form-footer button { - flex: 1; - border-width: 2px; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list { - display: flex; - flex-direction: column; - list-style: none; - padding: 0; - margin: 0; - width: 100%; - gap: 5px; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item { - display: grid; - align-items: center; - grid-template-columns: 1fr 4fr 1fr; - cursor: pointer; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item img { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 3px; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: #efe6d8; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.sheet.daggerheart.dh-style .tab.features .features-list { - display: flex; - flex-direction: column; - list-style: none; - padding: 0; - margin: 0; - width: 100%; - gap: 5px; -} -.sheet.daggerheart.dh-style .tab.features .features-list .feature-item { - display: grid; - align-items: center; - grid-template-columns: 1fr 4fr 1fr; - cursor: pointer; -} -.sheet.daggerheart.dh-style .tab.features .features-list .feature-item img { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 3px; -} -.sheet.daggerheart.dh-style .tab.features .features-list .feature-item h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: #efe6d8; -} -.sheet.daggerheart.dh-style .tab.features .features-list .feature-item .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.sheet.daggerheart.dh-style .tab.features .features-list .feature-item .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.sheet.daggerheart.dh-style .tab.effects .effects-list { - display: flex; - flex-direction: column; - list-style: none; - padding: 0; - margin: 0; - width: 100%; - gap: 5px; -} -.sheet.daggerheart.dh-style .tab.effects .effects-list .effect-item { - display: grid; - align-items: center; - grid-template-columns: 1fr 4fr 1fr; - cursor: pointer; -} -.sheet.daggerheart.dh-style .tab.effects .effects-list .effect-item h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: #efe6d8; -} -.sheet.daggerheart.dh-style .tab.effects .effects-list .effect-item .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.sheet.daggerheart.dh-style .tab.effects .effects-list .effect-item .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.application.sheet.daggerheart.dh-style .item-sheet-header { - display: flex; -} -.application.sheet.daggerheart.dh-style .item-sheet-header .profile { - height: 150px; - width: 150px; - object-fit: cover; - border-right: 1px solid light-dark(#18162e, #f3c267); - border-bottom: 1px solid light-dark(#18162e, #f3c267); - box-sizing: border-box; - cursor: pointer; -} -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info { - display: flex; - flex-direction: column; - align-items: center; - gap: 5px; - margin-top: 36px; - text-align: center; - width: 80%; -} -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: center; - width: 90%; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; -} -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info .item-name input[type='text']:hover[type='text'], -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info .item-description { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.sheet.daggerheart.dh-style .item-sheet-header .item-info h3 { - font-size: 1rem; -} -.application.sheet.daggerheart.dh-style .item-card-header { - display: flex; - flex-direction: column; - justify-content: start; - text-align: center; -} -.application.sheet.daggerheart.dh-style .item-card-header .profile { - height: 300px; - width: 100%; - object-fit: cover; - mask-image: linear-gradient(0deg, transparent 0%, black 10%); - cursor: pointer; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list { - position: absolute; - display: flex; - align-items: center; - justify-content: center; - top: 50px; - right: 10px; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list .item-icon { - display: flex; - align-items: center; - justify-content: end; - text-align: center; - padding-right: 8px; - max-width: 50px; - height: 50px; - font-size: 1.2rem; - background: light-dark(rgba(0, 0, 0, 0.3), rgba(24, 22, 46, 0.33)); - border: 4px double light-dark(#efe6d8, #f3c267); - color: light-dark(#efe6d8, #f3c267); - border-radius: 999px; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list .item-icon .recall-label { - font-size: 14px; - opacity: 0; - margin-right: 0.3rem; - transition: all 0.3s ease; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list .item-icon i { - font-size: 0.8rem; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list .item-icon:hover { - max-width: 300px; - padding: 0 10px; - border-radius: 60px; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-icons-list .item-icon:hover .recall-label { - opacity: 1; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-info { - display: flex; - flex-direction: column; - align-items: center; - position: relative; - top: -25px; - gap: 5px; - margin-bottom: -20px; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-info .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: center; - width: 90%; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-info .item-name input[type='text']:hover[type='text'], -.application.sheet.daggerheart.dh-style .item-card-header .item-info .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); -} -.application.sheet.daggerheart.dh-style .item-card-header .item-info .item-description { - display: flex; - flex-direction: column; - gap: 10px; -} -.application.sheet.daggerheart.dh-style .item-card-header .item-info h3 { - font-size: 1rem; -} -.sheet.daggerheart.dh-style.item .tab.features { - padding: 0 10px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list { - display: flex; - flex-direction: column; - list-style: none; - padding: 0; - margin: 0; - width: 100%; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item { - margin-bottom: 10px; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item:last-child { - margin-bottom: 0px; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line { - display: grid; - align-items: center; - grid-template-columns: 1fr 4fr 1fr; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line h4 { - font-family: 'Montserrat', sans-serif; - font-weight: lighter; - color: light-dark(#222, #efe6d8); -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line .image { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 6px; - border: none; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line .controls { - display: flex; - justify-content: center; - gap: 10px; -} -.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line .controls a { - text-shadow: none; -} -.application.daggerheart.dh-style .inventory-item { - display: grid; - grid-template-columns: 40px 1fr 60px; - gap: 10px; - width: 100%; -} -.application.daggerheart.dh-style .inventory-item .item-img { - height: 40px; - width: 40px; - border-radius: 3px; - border: none; - cursor: pointer; - object-fit: cover; -} -.application.daggerheart.dh-style .inventory-item .item-img.actor-img { - border-radius: 50%; -} -.application.daggerheart.dh-style .inventory-item .item-label { - font-family: 'Montserrat', sans-serif; - align-self: center; -} -.application.daggerheart.dh-style .inventory-item .item-label .item-name { - font-size: 14px; -} -.application.daggerheart.dh-style .inventory-item .item-label .item-tags, -.application.daggerheart.dh-style .inventory-item .item-label .item-labels { - display: flex; - gap: 10px; -} -.application.daggerheart.dh-style .inventory-item .item-label .item-tags .tag, -.application.daggerheart.dh-style .inventory-item .item-label .item-labels .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; -} -.application.daggerheart.dh-style .inventory-item .item-label .item-tags .label, -.application.daggerheart.dh-style .inventory-item .item-label .item-labels .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; - gap: 4px; -} -.application.daggerheart.dh-style .inventory-item .controls { - display: flex; - align-items: center; - justify-content: end; - gap: 8px; -} -.application.daggerheart.dh-style .inventory-item .controls a { - text-align: center; -} -.application.daggerheart.dh-style .inventory-item .controls a.unequipped { - opacity: 0.4; -} -.application.daggerheart.dh-style .card-item { - position: relative; - height: 120px; - width: 100px; - border: 1px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - cursor: pointer; -} -.application.daggerheart.dh-style .card-item:hover .card-label { - padding-top: 15px; -} -.application.daggerheart.dh-style .card-item:hover .card-label .controls { - opacity: 1; - visibility: visible; - transition: all 0.3s ease; - max-height: 16px; -} -.application.daggerheart.dh-style .card-item .card-img { - height: 100%; - width: 100%; - object-fit: cover; -} -.application.daggerheart.dh-style .card-item .card-label { - display: flex; - flex-direction: column; - height: fit-content; - align-items: center; - gap: 5px; - padding-top: 5px; - padding-bottom: 5px; - width: 100%; - position: absolute; - background-color: #18162e; - bottom: 0; - mask-image: linear-gradient(180deg, transparent 0%, black 20%); -} -.application.daggerheart.dh-style .card-item .card-label .card-name { - font-family: 'Montserrat', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 12px; - line-height: 15px; - color: #efe6d8; -} -.application.daggerheart.dh-style .card-item .card-label .controls { - display: flex; - gap: 15px; - align-items: center; - max-height: 0px; - opacity: 0; - visibility: collapse; - transition: all 0.3s ease; - color: #efe6d8; -} -.application.daggerheart.dh-style .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; - width: 100%; -} -.application.daggerheart.dh-style .card-list { - display: flex; - flex-direction: row; - gap: 10px; - align-items: center; -} -.application prose-mirror { - height: 100% !important; -} -.application prose-mirror .editor-menu { - background-color: transparent; -} -.application prose-mirror .editor-content { - scrollbar-width: thin; - scrollbar-color: light-dark(#18162e, #f3c267) transparent; -} -.application prose-mirror .editor-content h1 { - font-size: 36px; -} -.application prose-mirror .editor-content h2 { - font-size: 32px; -} -.application prose-mirror .editor-content h3 { - font-size: 24px; -} -.filter-menu { - width: auto; -} -.filter-menu fieldset.filter-section { - align-items: center; - margin: 5px; - border-radius: 6px; - border-color: light-dark(#18162e, #f3c267); - padding: 5px; -} -.filter-menu fieldset.filter-section legend { - font-family: 'Montserrat', sans-serif; - font-weight: bold; - color: light-dark(#18162e, #f3c267); - font-size: var(--font-size-12); -} -.filter-menu fieldset.filter-section .filter-buttons { - display: flex; - flex-wrap: wrap; - justify-content: space-evenly; - gap: 5px; -} -.filter-menu fieldset.filter-section .filter-buttons button { - background: light-dark(rgba(0, 0, 0, 0.3), #18162e); - color: light-dark(#18162e, #f3c267); - outline: none; - box-shadow: none; - border: 1px solid light-dark(#18162e, #18162e); - padding: 0 0.2rem; - font-size: var(--font-size-12); -} -.filter-menu fieldset.filter-section .filter-buttons button:hover { - background: light-dark(transparent, #f3c267); - color: light-dark(#18162e, #18162e); -} -.filter-menu fieldset.filter-section .filter-buttons button.active { - animation: glow 0.75s infinite alternate; -} -.daggerheart.chat.downtime { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.downtime .downtime-title-container { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.downtime .downtime-title-container .downtime-subtitle { - font-size: 17px; -} -.daggerheart.chat.downtime .downtime-image { - width: 80px; -} -.daggerheart.chat.downtime .downtime-refresh-container { - margin-top: 8px; - width: 100%; -} -.daggerheart.chat.downtime .downtime-refresh-container .refresh-title { - font-weight: bold; -} -.daggerheart.chat.roll .dice-flavor { - text-align: center; - font-weight: bold; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls.duality { - display: flex; - gap: 0.25rem; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll { - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - margin-bottom: 4px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container { - display: flex; - flex-direction: column; - gap: 2px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-title { - color: var(--color-light-1); - text-shadow: 0 0 1px black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container { - display: flex; - align-items: center; - justify-content: center; - position: relative; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper, -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { - clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper { - height: 24px; - width: 24px; - position: relative; - display: flex; - align-items: center; - justify-content: center; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-wrapper .dice { - height: 26px; - width: 26px; - max-width: unset; - position: absolute; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container .dice-value { - position: absolute; - font-weight: bold; - font-size: 16px; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper { - background: black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(79%) sepia(79%) saturate(333%) hue-rotate(352deg) brightness(102%) contrast(103%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.hope .dice-value { - color: var(--color-dark-1); - text-shadow: 0 0 4px white; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper { - background: white; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(12%) sepia(88%) saturate(4321%) hue-rotate(221deg) brightness(92%) contrast(110%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.fear .dice-value { - color: var(--color-light-1); - text-shadow: 0 0 4px black; -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.advantage .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(18%) sepia(92%) saturate(4133%) hue-rotate(96deg) brightness(104%) contrast(107%); -} -.daggerheart.chat.roll .dice-tooltip .dice-rolls > .roll .dice-container .dice-inner-container.disadvantage .dice-wrapper .dice { - filter: brightness(0) saturate(100%) invert(9%) sepia(78%) saturate(6903%) hue-rotate(11deg) brightness(93%) contrast(117%); -} -.daggerheart.chat.roll .dice-total.duality.hope { - border-color: #ffe760; - border-width: 3px; - background: rgba(255, 231, 96, 0.5); -} -.daggerheart.chat.roll .dice-total.duality.fear { - border-color: #0032b1; - border-width: 3px; - background: rgba(0, 50, 177, 0.5); -} -.daggerheart.chat.roll .dice-total.duality.critical { - border-color: #430070; - border-width: 3px; - background: rgba(67, 0, 112, 0.5); -} -.daggerheart.chat.roll .dice-total .dice-total-value .hope { - color: #ffe760; -} -.daggerheart.chat.roll .dice-total .dice-total-value .fear { - color: #0032b1; -} -.daggerheart.chat.roll .dice-total .dice-total-value .critical { - color: #430070; -} -.daggerheart.chat.roll .dice-total-label { - font-size: 12px; - font-weight: bold; - font-variant: all-small-caps; - margin: -8px 0; -} -.daggerheart.chat.roll .target-selection { - display: flex; - justify-content: space-around; -} -.daggerheart.chat.roll .target-selection input[type='radio'] { - display: none; -} -.daggerheart.chat.roll .target-selection input[type='radio']:checked + label { - text-shadow: 0px 0px 4px #ce5937; -} -.daggerheart.chat.roll .target-selection input[type='radio']:not(:checked) + label { - opacity: 0.75; -} -.daggerheart.chat.roll .target-selection label { - cursor: pointer; - opacity: 0.75; -} -.daggerheart.chat.roll .target-selection label.target-selected { - text-shadow: 0px 0px 4px #ce5937; - opacity: 1; -} -.daggerheart.chat.roll .target-section { - margin-top: 5px; -} -.daggerheart.chat.roll .target-section .target-container { - display: flex; - transition: all 0.2s ease-in-out; -} -.daggerheart.chat.roll .target-section .target-container:hover { - filter: drop-shadow(0 0 3px gold); - border-color: gold; -} -.daggerheart.chat.roll .target-section .target-container.hidden { - display: none; - border: 0; -} -.daggerheart.chat.roll .target-section .target-container.hit { - background: #008000; -} -.daggerheart.chat.roll .target-section .target-container.miss { - background: #ff0000; -} -.daggerheart.chat.roll .target-section .target-container img, -.daggerheart.chat.roll .target-section .target-container .target-save-container { - width: 22px; - height: 22px; - align-self: center; - border-color: transparent; -} -.daggerheart.chat.roll .target-section .target-container img { - flex: 0; - margin-left: 8px; -} -.daggerheart.chat.roll .target-section .target-container .target-save-container { - margin-right: 8px; - justify-content: center; - display: flex; - align-items: center; - min-height: unset; - border: 1px solid black; -} -.daggerheart.chat.roll .target-section .target-container .target-inner-container { - flex: 1; - display: flex; - justify-content: center; - font-size: var(--font-size-16); -} -.daggerheart.chat.roll .target-section .target-container:not(:has(.target-save-container)) .target-inner-container { - margin-right: 32px; -} -.daggerheart.chat.roll .dice-actions { - display: flex; - gap: 4px; -} -.daggerheart.chat.roll .dice-actions button { - flex: 1; -} -.daggerheart.chat.roll .dice-result .roll-damage-button, -.daggerheart.chat.roll .dice-result .damage-button, -.daggerheart.chat.roll .dice-result .duality-action { - margin-top: 5px; -} -.daggerheart.chat.roll:not(.expanded) .dice-tooltip { - grid-template-rows: 0fr; -} -.daggerheart.chat.domain-card { - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.domain-card .domain-card-title { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; -} -.daggerheart.chat.domain-card .domain-card-title div { - font-size: 20px; - font-variant: small-caps; - font-weight: bold; -} -.daggerheart.chat.domain-card .domain-card-title h2 { - width: 100%; - text-align: center; - margin: 0; -} -.daggerheart.chat.domain-card .ability-card-footer { - display: flex; - width: 100%; - margin-top: 8px; - flex-wrap: wrap; -} -.daggerheart.chat.domain-card .ability-card-footer button { - border-radius: 6px; - background: #699969; - border-color: black; - flex-basis: calc(50% - 2px); -} -.daggerheart.chat.domain-card .ability-card-footer button:nth-of-type(n + 3) { - margin-top: 2px; -} -.daggerheart.chat.domain-card .ability-card-footer .ability-card-action-cost { - margin: auto; - font-size: 1.5em; -} -.daggerheart.chat.domain-card img { - width: 80px; -} -.daggerheart.chat button.inner-button { - --button-size: 1.25rem; - --input-height: 1.25rem; - padding: 0 0.25rem; - margin: 5px 1px -4px auto; -} -.daggerheart.chat button.inner-button.inner-button-right { - margin-left: auto; -} -.daggerheart.chat [data-use-perm='false'] { - pointer-events: none; - border-color: transparent; -} -.daggerheart.chat [data-view-perm='false'] > * { - display: none; -} -.daggerheart.chat [data-view-perm='false']::after { - content: '??'; -} -.chat-message .duality-modifiers, -.chat-message .duality-result, -.chat-message .dice-title { - display: none; -} -fieldset.daggerheart.chat { - padding: 0; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; -} -fieldset.daggerheart.chat legend { - display: flex; - align-items: center; - gap: 5px; -} -fieldset.daggerheart.chat legend:before, -fieldset.daggerheart.chat legend:after { - content: '\f0d8'; - font-family: 'Font Awesome 6 Pro'; -} -fieldset.daggerheart.chat.expanded legend:before, -fieldset.daggerheart.chat.expanded legend:after { - content: '\f0d7'; -} -fieldset.daggerheart.chat .daggerheart.chat { - margin-top: 5px; -} -.theme-colorful .chat-message.duality { - border-color: black; - padding: 8px 0 0 0; -} -.theme-colorful .chat-message.duality fieldset.daggerheart.chat { - border-top-width: 0; - display: contents; -} -.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:before, -.theme-colorful .chat-message.duality fieldset.daggerheart.chat legend:after { - display: none; -} -.theme-colorful .chat-message.duality .message-header { - color: var(--color-light-3); - padding: 0 8px; -} -.theme-colorful .chat-message.duality.hope { - background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); -} -.theme-colorful .chat-message.duality.fear { - background: linear-gradient(0, rgba(0, 0, 255, 0.6), rgba(15, 15, 97, 0.6)); -} -.theme-colorful .chat-message.duality.critical { - background: linear-gradient(0, rgba(128, 0, 128, 0.6), rgba(37, 8, 37, 0.6)); -} -.theme-colorful .chat-message.duality .chat-message header { - color: var(--color-light-3); -} -.theme-colorful .chat-message.duality > * { - padding: 0 8px; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers, -.theme-colorful .chat-message.duality .message-content .duality-result, -.theme-colorful .chat-message.duality .message-content .dice-title { - display: flex; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; -} -.theme-colorful .chat-message.duality .message-content .duality-modifiers .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; -} -.theme-colorful .chat-message.duality .message-content .dice-flavor { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - border-bottom: 1px solid; - display: flex; - align-items: end; - justify-content: space-between; - padding: 0 8px; - margin: 0 -8px 2px; - font-weight: unset; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-modifiers .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-formula, -.theme-colorful .chat-message.duality .message-content .dice-result > .dice-total, -.theme-colorful .chat-message.duality .message-content .dice-result .part-header { - display: none; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip { - grid-template-rows: 1fr; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part { - display: flex; - align-items: end; - gap: 0.25rem; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls { - margin-bottom: 0; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .dice .dice-rolls.duality li { - display: flex; - align-items: center; - justify-content: center; - position: relative; - background: unset; - line-height: unset; - font-weight: unset; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-tooltip .wrapper .tooltip-part .duality-modifier { - display: flex; - margin-bottom: 6px; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-size: var(--font-size-16); -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-selection label { - color: var(--color-light-1); -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-section { - margin: 4px 0; - border: 2px solid; - margin-top: 5px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .target-section .dice-total { - box-shadow: unset; - border: unset; - border-radius: unset; - font-size: var(--font-size-18); -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions { - justify-content: space-between; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions.duality-alone { - justify-content: end; - margin-top: -20px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions > * { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action { - border-radius: 0 6px 0 0; - margin-left: -8px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-action.duality-action-effect { - border-top-left-radius: 6px; - margin-left: initial; -} -.theme-colorful .chat-message.duality .message-content .dice-result .dice-actions .duality-result { - border-radius: 6px 0 0 0; - margin-right: -8px; -} -.theme-colorful .chat-message.duality .message-content .dice-result .duality-result { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - margin-left: auto; - align-self: center; - border-radius: 6px; -} -.theme-colorful .chat-message.duality button.inner-button { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - border-color: black; -} -.combat-sidebar h4 { - margin: 0; - text-align: center; -} -.combat-sidebar .combatant-controls { - flex: 0; -} -.combat-sidebar .encounter-controls.combat { - justify-content: space-between; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls { - display: flex; - align-items: center; - gap: 8px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container { - display: flex; - gap: 2px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container { - display: flex; - position: relative; - align-items: center; - justify-content: center; - color: black; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .dice { - height: 22px; - width: 22px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-fear { - position: absolute; - font-size: 16px; -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-fear-dice-container .encounter-control-fear-container .encounter-control-counter { - position: absolute; - right: -10px; - color: var(--color-text-secondary); -} -.combat-sidebar .encounter-controls.combat .encounter-fear-controls .encounter-countdowns { - color: var(--content-link-icon-color); -} -.combat-sidebar .encounter-controls.combat .control-buttons { - width: min-content; -} -.combat-sidebar .spotlight-control { - font-size: 26px; -} -.combat-sidebar .spotlight-control:focus { - outline: none; - box-shadow: none; -} -.combat-sidebar .spotlight-control.discrete:hover { - background: inherit; -} -.combat-sidebar .spotlight-control.requesting { - filter: drop-shadow(0 0 3px gold); - color: var(--button-hover-text-color); -} -.combat-sidebar .token-actions { - align-self: stretch; - display: flex; - align-items: top; - justify-content: center; - gap: 16px; -} -.combat-sidebar .token-actions .action-tokens { - display: flex; - gap: 4px; -} -.combat-sidebar .token-actions .action-tokens .action-token { - height: 22px; - width: 22px; - border: 1px solid; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 10px; - padding: 8px; - --button-size: 0; -} -.combat-sidebar .token-actions .action-tokens .action-token.used { - opacity: 0.5; - background: transparent; -} -.combat-sidebar .token-actions button { - font-size: 22px; - height: 24px; - width: 24px; -} -.combat-sidebar .token-actions button.main { - background: var(--button-hover-background-color); - color: var(--button-hover-text-color); - border-color: var(--button-hover-border-color); -} -.combat-sidebar .token-actions button.main:hover { - filter: drop-shadow(0 0 3px var(--button-hover-text-color)); -} -.daggerheart.dh-style.countdown fieldset { - align-items: center; - margin-top: 5px; - border-radius: 6px; - border-color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.countdown fieldset legend { - font-family: 'Montserrat', sans-serif; - font-weight: bold; - color: light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.countdown fieldset legend a { - text-shadow: none; -} -.daggerheart.dh-style.countdown .minimized-view { - display: flex; - gap: 8px; - flex-wrap: wrap; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container { - width: fit-content; - display: flex; - align-items: center; - gap: 8px; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - padding: 0 4px 0 0; - background-image: url('../assets/parchments/dh-parchment-light.png'); - color: light-dark(#efe6d8, #222); - cursor: pointer; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container.disabled { - cursor: initial; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container img { - width: 30px; - height: 30px; - border-radius: 6px 0 0 6px; -} -.daggerheart.dh-style.countdown .minimized-view .mini-countdown-container .mini-countdown-name { - white-space: nowrap; -} -.daggerheart.dh-style.countdown .hidden { - display: none; -} -.themed.theme-light .application.daggerheart.sheet.dh-style.countdown .minimized-view .mini-countdown-container, -.themed.theme-light.application.daggerheart.sheet.dh-style.countdown .minimized-view .mini-countdown-container, -body.theme-light .application.daggerheart.countdown .minimized-view .mini-countdown-container, -body.theme-light.application.daggerheart.countdown .minimized-view .mini-countdown-container { - background-image: url('../assets/parchments/dh-parchment-dark.png'); -} -.daggerheart.dh-style.countdown { - overflow: hidden; -} -.daggerheart.dh-style.countdown .window-content > div { - height: 100%; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view { - height: 100%; - display: flex; - flex-direction: column; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu { - display: flex; - gap: 8px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-menu .flex { - flex: 1; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container { - display: flex; - gap: 8px; - flex-wrap: wrap; - overflow: auto; - max-height: 100%; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset { - width: 340px; - height: min-content; - position: relative; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .ownership-button { - position: absolute; - top: 8px; - right: 8px; - font-size: 18px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container { - display: flex; - align-items: center; - gap: 16px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img { - width: 150px; - height: 150px; - cursor: pointer; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container img.disabled { - cursor: initial; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container { - display: flex; - gap: 4px; -} -.daggerheart.dh-style.countdown .window-content > div .expanded-view .countdowns-container .countdown-fieldset .countdown-container .countdown-inner-container .countdown-value-container input { - max-width: 80px; -} -.daggerheart.views.ownership-selection .ownership-outer-container { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container { - display: flex; - border: 2px solid light-dark(#18162e, #f3c267); - border-radius: 6px; - padding: 0 4px 0 0; - align-items: center; - gap: 8px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container img { - height: 40px; - width: 40px; - border-radius: 6px 0 0 6px; -} -.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container select { - margin: 4px 0; -} -:root { - --shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; - --fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease; -} -#resources { - min-height: calc(var(--header-height) + 4rem); - min-width: 4rem; - color: #d3d3d3; - transition: var(--fear-animation); -} -#resources header, -#resources .controls, -#resources .window-resize-handle { - transition: var(--fear-animation); -} -#resources .window-content { - padding: 0.5rem; -} -#resources .window-content #resource-fear { - display: flex; - flex-direction: row; - gap: 0.5rem 0.25rem; - flex-wrap: wrap; -} -#resources .window-content #resource-fear i { - font-size: var(--font-size-18); - border: 1px solid rgba(0, 0, 0, 0.5); - border-radius: 50%; - aspect-ratio: 1; - display: flex; - justify-content: center; - align-items: center; - width: 3rem; - background-color: rgba(9, 71, 179, 0.75); - -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); - box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75); - color: #d3d3d3; - flex-grow: 0; -} -#resources .window-content #resource-fear i.inactive { - filter: grayscale(1) !important; - opacity: 0.5; -} -#resources .window-content #resource-fear .controls, -#resources .window-content #resource-fear .resource-bar { - border: 2px solid #997a4f; - background-color: #18162e; -} -#resources .window-content #resource-fear .controls { - display: flex; - align-self: center; - border-radius: 50%; - align-items: center; - justify-content: center; - width: 30px; - height: 30px; - font-size: var(--font-size-20); - cursor: pointer; -} -#resources .window-content #resource-fear .controls:hover { - font-size: 1.5rem; -} -#resources .window-content #resource-fear .controls.disabled { - opacity: 0.5; -} -#resources .window-content #resource-fear .resource-bar { - display: flex; - justify-content: center; - border-radius: 6px; - font-size: var(--font-size-20); - overflow: hidden; - position: relative; - padding: 0.25rem 0.5rem; - flex: 1; - text-shadow: var(--shadow-text-stroke); -} -#resources .window-content #resource-fear .resource-bar:before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: var(--fear-percent); - max-width: 100%; - background: linear-gradient(90deg, #020026 0%, #c701fc 100%); - z-index: 0; - border-radius: 4px; -} -#resources .window-content #resource-fear .resource-bar span { - position: inherit; - z-index: 1; -} -#resources .window-content #resource-fear.isGM i { - cursor: pointer; -} -#resources .window-content #resource-fear.isGM i:hover { - font-size: var(--font-size-20); -} -#resources button[data-action='close'] { - display: none; -} -#resources:not(:hover):not(.minimized) { - background: transparent; - box-shadow: unset; - border-color: transparent; -} -#resources:not(:hover):not(.minimized) header, -#resources:not(:hover):not(.minimized) .controls, -#resources:not(:hover):not(.minimized) .window-resize-handle { - opacity: 0; -} -#resources:has(.fear-bar) { - min-width: 200px; -} -.daggerheart.dh-style.setting fieldset { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.setting fieldset.two-columns { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 10px; -} -.daggerheart.dh-style.setting fieldset.two-columns.even { - grid-template-columns: 1fr 1fr; -} -.daggerheart.dh-style.setting .setting-group-field { - white-space: nowrap; - display: flex; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items { - display: flex; - flex-direction: column; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item { - display: flex; - align-items: center; - justify-content: space-between; - border: 1px solid; - border-radius: 8px; - padding: 0 8px 0 0; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item { - display: flex; - align-items: center; - gap: 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item img { - width: 60px; - border-radius: 8px 0 0 8px; -} -.daggerheart.dh-style.setting .settings-items .settings-item .settings-sub-item i { - font-size: 18px; -} -.daggerheart.dh-style.setting .settings-item-header { - display: flex; - align-items: center; -} -.daggerheart.dh-style.setting .settings-item-header .profile { - height: 100px; - width: 100px; - object-fit: cover; - box-sizing: border-box; - cursor: pointer; -} -.daggerheart.dh-style.setting .settings-item-header .item-info { - display: flex; - flex-direction: column; - align-items: center; - gap: 5px; - text-align: center; - width: 80%; -} -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text'] { - font-size: 32px; - height: 42px; - text-align: center; - width: 90%; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; -} -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:hover[type='text'], -.daggerheart.dh-style.setting .settings-item-header .item-info .item-name input[type='text']:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(#18162e, #f3c267); -} -.daggerheart.dh-style.setting .settings-col { - display: flex; - flex-direction: column; - gap: 4px; -} -.daggerheart.dh-style.setting .trait-array-container { - display: flex; - justify-content: space-evenly; - gap: 8px; - margin-bottom: 16px; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item { - position: relative; - display: flex; - justify-content: center; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item label { - position: absolute; - top: -7px; - font-size: 12px; - font-variant: petite-caps; -} -.daggerheart.dh-style.setting .trait-array-container .trait-array-item input { - text-align: center; -} From 9189a95ea3b150919e0a5e24e6cc291aa2d284c7 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:18:26 +0200 Subject: [PATCH 06/58] Bugfix - Companion Levelup Features (#303) * Fixed so that features gained from companion levleup are granted properly to its partner * Fixed localization error I noticed --- lang/en.json | 3 +- module/applications/levelup/levelup.mjs | 2 +- .../applications/sheets/actors/character.mjs | 16 +-- module/data/levelData.mjs | 11 ++- module/data/levelTier.mjs | 9 +- module/dice/dhRoll.mjs | 1 + module/documents/actor.mjs | 97 +++++++++++-------- 7 files changed, 79 insertions(+), 60 deletions(-) diff --git a/lang/en.json b/lang/en.json index 797781d8..b5ed3b3f 100755 --- a/lang/en.json +++ b/lang/en.json @@ -107,7 +107,8 @@ "sendToChat": "Send To Chat", "toLoadout": "Send to Loadout", "toVault": "Send to Vault", - "unequip": "Unequip" + "unequip": "Unequip", + "useItem": "Use Item" }, "faith": "Faith", "levelUp": "You can level up", diff --git a/module/applications/levelup/levelup.mjs b/module/applications/levelup/levelup.mjs index eb120ac5..93910fe7 100644 --- a/module/applications/levelup/levelup.mjs +++ b/module/applications/levelup/levelup.mjs @@ -128,7 +128,7 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) context.tabs.advancements.progress = { selected: selections, max: currentLevel.maxSelections }; context.showTabs = this.tabGroups.primary !== 'summary'; break; - const { current: currentActorLevel, changed: changedActorLevel } = this.actor.system.levelData.level; + const actorArmor = this.actor.system.armor; const levelKeys = Object.keys(this.levelup.levels); let achivementProficiency = 0; diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index c24bcfec..e70774f5 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -202,7 +202,7 @@ export default class CharacterSheet extends DHBaseActorSheet { return [ { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.UseItem', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.useItem', icon: '', condition: el => { const item = getItem(el); @@ -211,7 +211,7 @@ export default class CharacterSheet extends DHBaseActorSheet { callback: (button, event) => CharacterSheet.useItem.call(this, event, button) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.Equip', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.equip', icon: '', condition: el => { const item = getItem(el); @@ -220,7 +220,7 @@ export default class CharacterSheet extends DHBaseActorSheet { callback: CharacterSheet.#toggleEquipItem.bind(this) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.Unequip', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.unequip', icon: '', condition: el => { const item = getItem(el); @@ -229,7 +229,7 @@ export default class CharacterSheet extends DHBaseActorSheet { callback: CharacterSheet.#toggleEquipItem.bind(this) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.ToLoadout', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.toLoadout', icon: '', condition: el => { const item = getItem(el); @@ -238,7 +238,7 @@ export default class CharacterSheet extends DHBaseActorSheet { callback: target => getItem(target).update({ 'system.inVault': false }) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.ToVault', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.toVault', icon: '', condition: el => { const item = getItem(el); @@ -247,17 +247,17 @@ export default class CharacterSheet extends DHBaseActorSheet { callback: target => getItem(target).update({ 'system.inVault': true }) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.SendToChat', + name: 'DAGGERHEART.ACTORS.Character.contextMenu.sendToChat', icon: '', callback: CharacterSheet.toChat.bind(this) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.Edit', + name: 'CONTROLS.CommonEdit', icon: '', callback: target => getItem(target).sheet.render({ force: true }) }, { - name: 'DAGGERHEART.Sheets.PC.ContextMenu.Delete', + name: 'CONTROLS.CommonDelete', icon: '', callback: async el => { const item = getItem(el); diff --git a/module/data/levelData.mjs b/module/data/levelData.mjs index 2432a313..669077ee 100644 --- a/module/data/levelData.mjs +++ b/module/data/levelData.mjs @@ -43,7 +43,12 @@ export default class DhLevelData extends foundry.abstract.DataModel { data: new fields.ArrayField(new fields.StringField({ required: true })), secondaryData: new fields.TypedObjectField(new fields.StringField({ required: true })), itemUuid: new fields.DocumentUUIDField({ required: true }), - featureIds: new fields.ArrayField(new fields.StringField()) + features: new fields.ArrayField( + new fields.SchemaField({ + onPartner: new fields.BooleanField(), + id: new fields.StringField() + }) + ) }) ) }) @@ -51,10 +56,6 @@ export default class DhLevelData extends foundry.abstract.DataModel { }; } - get actions() { - return Object.values(this.levelups).flatMap(level => level.selections.flatMap(s => s.actions)); - } - get canLevelUp() { return this.level.current < this.level.changed; } diff --git a/module/data/levelTier.mjs b/module/data/levelTier.mjs index b037d921..e9e8d47b 100644 --- a/module/data/levelTier.mjs +++ b/module/data/levelTier.mjs @@ -70,7 +70,8 @@ export const CompanionLevelOptionType = { { name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.name', img: 'icons/magic/life/heart-cross-purple-orange.webp', - description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.description' + description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.description', + toPartner: true } ] }, @@ -81,7 +82,8 @@ export const CompanionLevelOptionType = { { name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.name', img: 'icons/equipment/shield/kite-wooden-oak-glow.webp', - description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.description' + description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.description', + toPartner: true } ] }, @@ -100,7 +102,8 @@ export const CompanionLevelOptionType = { { name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.name', img: 'icons/magic/life/heart-red-blue.webp', - description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.description' + description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.description', + toPartner: true } ] }, diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index c3918a13..13246ac9 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -139,6 +139,7 @@ export default class DHRoll extends Roll { export const registerRollDiceHooks = () => { Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => { if ( + !config.source?.actor || !game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope || config.roll.type === 'reaction' ) diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 1fab0f71..cfe101fa 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -5,13 +5,13 @@ import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; export default class DhpActor extends Actor { - /** * Return the first Actor active owner. */ get owner() { - const user = this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, "OWNER") && u.active);; - if(!user) return game.user.isGM ? game.user : null; + const user = + this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, 'OWNER') && u.active); + if (!user) return game.user.isGM ? game.user : null; return user; } @@ -61,7 +61,7 @@ export default class DhpActor extends Actor { return acc; }, {}); - const featureIds = []; + const features = []; const domainCards = []; const experiences = []; const subclassFeatureState = { class: null, multiclass: null }; @@ -74,7 +74,7 @@ export default class DhpActor extends Actor { const advancementCards = level.selections.filter(x => x.type === 'domainCard').map(x => x.itemUuid); domainCards.push(...achievementCards, ...advancementCards); experiences.push(...Object.keys(level.achievements.experiences)); - featureIds.push(...level.selections.flatMap(x => x.featureIds)); + features.push(...level.selections.flatMap(x => x.features)); const subclass = level.selections.find(x => x.type === 'subclass'); if (subclass) { @@ -88,8 +88,11 @@ export default class DhpActor extends Actor { multiclass = level.selections.find(x => x.type === 'multiclass'); }); - for (let featureId of featureIds) { - this.items.get(featureId).delete(); + for (let feature of features) { + if (feature.onPartner && !this.system.partner) continue; + + const document = feature.onPartner ? this.system.partner : this; + document.items.get(feature.id)?.delete(); } if (experiences.length > 0) { @@ -153,7 +156,6 @@ export default class DhpActor extends Actor { } async levelUp(levelupData) { - const actions = []; const levelups = {}; for (var levelKey of Object.keys(levelupData)) { const level = levelupData[levelKey]; @@ -237,7 +239,9 @@ export default class DhpActor extends Actor { ...featureData, description: game.i18n.localize(featureData.description) }); - const embeddedItem = await this.createEmbeddedDocuments('Item', [ + + const document = featureData.toPartner && this.system.partner ? this.system.partner : this; + const embeddedItem = await document.createEmbeddedDocuments('Item', [ { ...featureData, name: game.i18n.localize(featureData.name), @@ -245,9 +249,13 @@ export default class DhpActor extends Actor { system: feature } ]); - addition.checkbox.featureIds = !addition.checkbox.featureIds - ? [embeddedItem[0].id] - : [...addition.checkbox.featureIds, embeddedItem[0].id]; + const newFeature = { + onPartner: Boolean(featureData.toPartner && this.system.partner), + id: embeddedItem[0].id + }; + addition.checkbox.features = !addition.checkbox.features + ? [newFeature] + : [...addition.checkbox.features, newFeature]; } selections.push(addition.checkbox); @@ -317,7 +325,6 @@ export default class DhpActor extends Actor { await this.update({ system: { - actions: [...this.system.actions, ...actions], levelData: { level: { current: this.system.levelData.level.changed @@ -369,16 +376,16 @@ export default class DhpActor extends Actor { const modifier = roll.modifier !== null ? Number.parseInt(roll.modifier) : null; return modifier !== null ? [ - { - value: modifier, - label: roll.label - ? modifier >= 0 - ? `${roll.label} +${modifier}` - : `${roll.label} ${modifier}` - : null, - title: roll.label - } - ] + { + value: modifier, + label: roll.label + ? modifier >= 0 + ? `${roll.label} +${modifier}` + : `${roll.label} ${modifier}` + : null, + title: roll.label + } + ] : []; } @@ -460,7 +467,7 @@ export default class DhpActor extends Actor { if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null; - if(!hpDamage) return; + if (!hpDamage) return; const updates = [{ value: hpDamage, type: 'hitPoints' }]; @@ -469,8 +476,8 @@ export default class DhpActor extends Actor { this.system.armor && this.system.armor.system.marks.value < this.system.armorScore ) { - const armorStackResult = await this.owner.query('armorStack', {actorId: this.uuid, damage: hpDamage}); - if(armorStackResult) { + const armorStackResult = await this.owner.query('armorStack', { actorId: this.uuid, damage: hpDamage }); + if (armorStackResult) { const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; updates.find(u => u.type === 'hitPoints').value = modifiedDamage; updates.push( @@ -479,7 +486,7 @@ export default class DhpActor extends Actor { ); } } - + await this.modifyResource(updates); if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null; @@ -493,7 +500,7 @@ export default class DhpActor extends Actor { async modifyResource(resources) { if (!resources.length) return; - if(resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources); + if (resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources); let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } }; resources.forEach(r => { switch (r.type) { @@ -521,7 +528,12 @@ export default class DhpActor extends Actor { }); Object.values(updates).forEach(async u => { if (Object.keys(u.resources).length > 0) { - await emitAsGM(GMUpdateEvent.UpdateDocument, u.target.update.bind(u.target), u.resources, u.target.uuid); + await emitAsGM( + GMUpdateEvent.UpdateDocument, + u.target.update.bind(u.target), + u.resources, + u.target.uuid + ); /* if (game.user.isGM) { await u.target.update(u.resources); } else { @@ -540,27 +552,28 @@ export default class DhpActor extends Actor { convertDamageToThreshold(damage) { return damage >= this.system.damageThresholds.severe - ? 3 - : damage >= this.system.damageThresholds.major - ? 2 - : damage >= this.system.damageThresholds.minor - ? 1 - : 0; + ? 3 + : damage >= this.system.damageThresholds.major + ? 2 + : damage >= this.system.damageThresholds.minor + ? 1 + : 0; } convertStressDamageToHP(resources) { const stressDamage = resources.find(r => r.type === 'stress'), newValue = this.system.resources.stress.value + stressDamage.value; - if(newValue <= this.system.resources.stress.maxTotal) return; + if (newValue <= this.system.resources.stress.maxTotal) return; const hpDamage = resources.find(r => r.type === 'hitPoints'); - if(hpDamage) hpDamage.value++; - else resources.push({ - type: 'hitPoints', - value: 1 - }) + if (hpDamage) hpDamage.value++; + else + resources.push({ + type: 'hitPoints', + value: 1 + }); } } export const registerDHActorHooks = () => { CONFIG.queries.armorStack = DamageReductionDialog.armorStackQuery; -} \ No newline at end of file +}; From e6ec4860720b79f83507356874d85dc4d0ec6baa Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:40:24 +0200 Subject: [PATCH 07/58] In Front Template (#299) * Added confirm dialogs to delete * Localization fix * Changed Cone template to be 'In Front', acting as a 180 degree cone * Changed to keep the original Cone function --- daggerheart.mjs | 1 + lang/en.json | 3 + module/canvas/placeables/_module.mjs | 1 + module/canvas/placeables/templateLayer.mjs | 116 +++++++++++++++++++++ module/data/actor/character.mjs | 3 +- module/documents/tooltipManager.mjs | 2 +- 6 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 module/canvas/placeables/templateLayer.mjs diff --git a/daggerheart.mjs b/daggerheart.mjs index 153c2f84..4f411b0f 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -120,6 +120,7 @@ Hooks.once('init', () => { CONFIG.ChatMessage.documentClass = documents.DhChatMessage; CONFIG.Canvas.rulerClass = placeables.DhRuler; + CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer; CONFIG.Combat.documentClass = documents.DhpCombat; CONFIG.ui.combat = applications.ui.DhCombatTracker; CONFIG.ui.chat = applications.ui.DhChatLog; diff --git a/lang/en.json b/lang/en.json index b5ed3b3f..b1441032 100755 --- a/lang/en.json +++ b/lang/en.json @@ -20,6 +20,9 @@ "environment": "Environment" } }, + "CONTROLS": { + "inFront": "In Front" + }, "DAGGERHEART": { "ACTIONS": { "Config": { diff --git a/module/canvas/placeables/_module.mjs b/module/canvas/placeables/_module.mjs index 1da3a1e9..3610559c 100644 --- a/module/canvas/placeables/_module.mjs +++ b/module/canvas/placeables/_module.mjs @@ -1,3 +1,4 @@ export { default as DhMeasuredTemplate } from './measuredTemplate.mjs'; export { default as DhRuler } from './ruler.mjs'; +export { default as DhTemplateLayer } from './templateLayer.mjs'; export { default as DhTokenRuler } from './tokenRuler.mjs'; diff --git a/module/canvas/placeables/templateLayer.mjs b/module/canvas/placeables/templateLayer.mjs new file mode 100644 index 00000000..551a06cc --- /dev/null +++ b/module/canvas/placeables/templateLayer.mjs @@ -0,0 +1,116 @@ +export default class DhTemplateLayer extends foundry.canvas.layers.TemplateLayer { + static prepareSceneControls() { + const sc = foundry.applications.ui.SceneControls; + return { + name: 'templates', + order: 2, + title: 'CONTROLS.GroupMeasure', + icon: 'fa-solid fa-ruler-combined', + visible: game.user.can('TEMPLATE_CREATE'), + onChange: (event, active) => { + if (active) canvas.templates.activate(); + }, + onToolChange: () => canvas.templates.setAllRenderFlags({ refreshState: true }), + tools: { + circle: { + name: 'circle', + order: 1, + title: 'CONTROLS.MeasureCircle', + icon: 'fa-regular fa-circle', + toolclip: { + src: 'toolclips/tools/measure-circle.webm', + heading: 'CONTROLS.MeasureCircle', + items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete']) + } + }, + cone: { + name: 'cone', + order: 2, + title: 'CONTROLS.MeasureCone', + icon: 'fa-solid fa-angle-left', + toolclip: { + src: 'toolclips/tools/measure-cone.webm', + heading: 'CONTROLS.MeasureCone', + items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate']) + } + }, + inFront: { + name: 'inFront', + order: 3, + title: 'CONTROLS.inFront', + icon: 'fa-solid fa-eye', + toolclip: { + src: 'toolclips/tools/measure-cone.webm', + heading: 'CONTROLS.inFront', + items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate']) + } + }, + rect: { + name: 'rect', + order: 4, + title: 'CONTROLS.MeasureRect', + icon: 'fa-regular fa-square', + toolclip: { + src: 'toolclips/tools/measure-rect.webm', + heading: 'CONTROLS.MeasureRect', + items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate']) + } + }, + ray: { + name: 'ray', + order: 5, + title: 'CONTROLS.MeasureRay', + icon: 'fa-solid fa-up-down', + toolclip: { + src: 'toolclips/tools/measure-ray.webm', + heading: 'CONTROLS.MeasureRay', + items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate']) + } + }, + clear: { + name: 'clear', + order: 6, + title: 'CONTROLS.MeasureClear', + icon: 'fa-solid fa-trash', + visible: game.user.isGM, + onChange: () => canvas.templates.deleteAll(), + button: true + } + }, + activeTool: 'circle' + }; + } + + _onDragLeftStart(event) { + const interaction = event.interactionData; + + // Snap the origin to the grid + if (!event.shiftKey) interaction.origin = this.getSnappedPoint(interaction.origin); + + // Create a pending MeasuredTemplateDocument + const tool = game.activeTool === 'inFront' ? 'cone' : game.activeTool; + const previewData = { + user: game.user.id, + t: tool, + x: interaction.origin.x, + y: interaction.origin.y, + sort: Math.max(this.getMaxSort() + 1, 0), + distance: 1, + direction: 0, + fillColor: game.user.color || '#FF0000', + hidden: event.altKey + }; + const defaults = CONFIG.MeasuredTemplate.defaults; + if (game.activeTool === 'cone') previewData.angle = defaults.angle; + else if (game.activeTool === 'inFront') previewData.angle = 180; + else if (game.activeTool === 'ray') previewData.width = defaults.width * canvas.dimensions.distance; + const cls = foundry.utils.getDocumentClass('MeasuredTemplate'); + const doc = new cls(previewData, { parent: canvas.scene }); + + // Create a preview MeasuredTemplate object + const template = new this.constructor.placeableClass(doc); + doc._object = template; + interaction.preview = this.preview.addChild(template); + template.draw(); + } +} diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 1dfbd015..daf63a79 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -1,5 +1,4 @@ import { burden } from '../../config/generalConfig.mjs'; -import ActionField from '../fields/actionField.mjs'; import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import DhLevelData from '../levelData.mjs'; import BaseDataActor from './base.mjs'; @@ -29,7 +28,7 @@ export default class DhCharacter extends BaseDataActor { return foundry.utils.mergeObject(super.metadata, { label: 'TYPES.Actor.character', type: 'character', - isNPC: false, + isNPC: false }); } diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index b780dfa9..2e660cff 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -1,7 +1,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager { async activate(element, options = {}) { let html = options.html; - if (element.dataset.tooltip.startsWith('#item#')) { + if (element.dataset.tooltip?.startsWith('#item#')) { const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6)); if (item) { html = await foundry.applications.handlebars.renderTemplate( From eae4f1291037155199774b74347f10aacd1a2a05 Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Wed, 9 Jul 2025 13:02:05 +0200 Subject: [PATCH 08/58] Fix Roll Dialog Button check (#309) --- module/applications/dialogs/d20RollDialog.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index db15a7a3..d1196459 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -63,6 +63,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio const context = await super._prepareContext(_options); context.rollConfig = this.config; context.hasRoll = !!this.config.roll; + context.canRoll = true; if (this.config.costs?.length) { const updatedCosts = this.action.calcCosts(this.config.costs); context.costs = updatedCosts; @@ -84,7 +85,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio context.advantage = this.config.roll?.advantage; context.disadvantage = this.config.roll?.disadvantage; context.diceOptions = CONFIG.DH.GENERAL.diceTypes; - context.canRoll = true; context.isLite = this.config.roll?.lite; context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); From b3e7c6b9b2f56a729c7fa10d282987a95b268173 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 9 Jul 2025 13:06:49 +0200 Subject: [PATCH 09/58] 284 - Armor/Weapon Feature Improvements (#292) * Added parsing of effect values from Item data model. Almost finished with itemConfig. * Added the last to itemConfig * Fixed armor * ContextMenu localization fixes * Better tooltips for tagify * Corrected resource logic --- lang/en.json | 12 +- .../dialogs/damageReductionDialog.mjs | 75 +- module/applications/sheets/items/armor.mjs | 4 +- module/applications/sheets/items/weapon.mjs | 4 +- module/applications/ui/chatLog.mjs | 4 +- module/config/generalConfig.mjs | 4 +- module/config/itemConfig.mjs | 804 ++++++++++++++++-- module/data/action/attackAction.mjs | 4 +- module/data/action/baseAction.mjs | 19 +- module/data/actor/character.mjs | 60 +- module/data/item/armor.mjs | 23 +- module/data/item/weapon.mjs | 61 +- module/documents/activeEffect.mjs | 6 +- module/documents/actor.mjs | 35 +- module/documents/item.mjs | 8 +- module/helpers/utils.mjs | 22 +- module/systemRegistration/socket.mjs | 18 +- .../dialog/beastform/beastform-container.less | 92 +- styles/less/dialog/beastform/sheet.less | 42 +- .../creation-action-footer.less | 26 +- .../selections-container.less | 650 +++++++------- .../less/dialog/character-creation/sheet.less | 54 +- .../character-creation/tab-navigation.less | 124 +-- .../less/dialog/damage-reduction/sheets.less | 14 +- .../dialog/downtime/downtime-container.less | 162 ++-- styles/less/dialog/index.less | 38 +- .../dialog/level-up/navigation-container.less | 60 +- .../dialog/level-up/selections-container.less | 216 ++--- styles/less/dialog/level-up/sheet.less | 74 +- .../dialog/level-up/summary-container.less | 74 +- .../less/dialog/level-up/tiers-container.less | 130 +-- styles/less/global/index.less | 28 +- .../adversary-settings/experiences.less | 56 +- .../adversary-settings/sheet.less | 36 +- .../environment-settings/adversaries.less | 100 +-- styles/less/sheets-settings/header.less | 40 +- styles/less/sheets-settings/index.less | 14 +- .../less/sheets/actors/adversary/header.less | 160 ++-- .../less/sheets/actors/adversary/sheet.less | 56 +- .../less/sheets/actors/adversary/sidebar.less | 702 +++++++-------- .../sheets/actors/environment/header.less | 280 +++--- styles/less/sheets/index.less | 46 +- styles/less/ui/chat/sheet.less | 66 +- styles/less/ui/chat/theme-colorful.less | 386 ++++----- .../ui/combat-sidebar/combat-sidebar.less | 12 +- .../ui/combat-sidebar/combatant-controls.less | 10 +- .../ui/combat-sidebar/encounter-controls.less | 96 +-- .../ui/combat-sidebar/spotlight-control.less | 38 +- .../less/ui/combat-sidebar/token-actions.less | 96 +-- styles/less/ui/countdown/sheet.less | 176 ++-- styles/less/ui/index.less | 36 +- 51 files changed, 3043 insertions(+), 2310 deletions(-) diff --git a/lang/en.json b/lang/en.json index b1441032..02ea41eb 100755 --- a/lang/en.json +++ b/lang/en.json @@ -486,14 +486,10 @@ "name": "Impenetrable", "description": "Once per short rest, when you would mark your last Hit Point, you can instead mark a Stress." }, - "magic": { - "name": "Magic", + "magical": { + "name": "Magical", "description": "You can't mark an Armor Slot to reduce physical damage." }, - "painful": { - "name": "Painful", - "description": "Each time you mark an Armor Slot, you must mark a Stress." - }, "physical": { "name": "Physical", "description": "You can't mark an Armor Slot to reduce magic damage." @@ -897,6 +893,10 @@ "name": "Scary", "description": "On a successful attack, the target must mark a Stress." }, + "selfCorrecting": { + "name": "Self Correcting", + "description": "When you roll a 1 on a damage die, it deals 6 damage instead." + }, "serrated": { "name": "Serrated", "description": "When you roll a 1 on a damage die, it deals 8 damage instead." diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 3d33f2a3..0612089d 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -3,7 +3,7 @@ import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs'; const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(resolve, reject, actor, damage) { + constructor(resolve, reject, actor, damage, damageType) { super({}); this.resolve = resolve; @@ -11,37 +11,46 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.actor = actor; this.damage = damage; - const maxArmorMarks = Math.min( - actor.system.armorScore - actor.system.armor.system.marks.value, - actor.system.rules.maxArmorMarked.total - ); + const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType]; + const maxArmorMarks = canApplyArmor + ? Math.min( + actor.system.armorScore - actor.system.armor.system.marks.value, + actor.system.rules.damageReduction.maxArmorMarked.total + ) + : 0; const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => { acc[foundry.utils.randomID()] = { selected: false }; return acc; }, {}); - const stress = [...Array(actor.system.rules.maxArmorMarked.stressExtra ?? 0).keys()].reduce((acc, _) => { - acc[foundry.utils.randomID()] = { selected: false }; - return acc; - }, {}); + const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce( + (acc, _) => { + acc[foundry.utils.randomID()] = { selected: false }; + return acc; + }, + {} + ); this.marks = { armor, stress }; - this.availableStressReductions = Object.keys(actor.system.rules.stressDamageReduction).reduce((acc, key) => { - const dr = actor.system.rules.stressDamageReduction[key]; - if (dr.enabled) { - if (acc === null) acc = {}; + this.availableStressReductions = Object.keys(actor.system.rules.damageReduction.stressDamageReduction).reduce( + (acc, key) => { + const dr = actor.system.rules.damageReduction.stressDamageReduction[key]; + if (dr.enabled) { + if (acc === null) acc = {}; - const damage = damageKeyToNumber(key); - acc[damage] = { - cost: dr.cost, - selected: false, - from: getDamageLabel(damage), - to: getDamageLabel(damage - 1) - }; - } + const damage = damageKeyToNumber(key); + acc[damage] = { + cost: dr.cost, + selected: false, + from: getDamageLabel(damage), + to: getDamageLabel(damage - 1) + }; + } - return acc; - }, null); + return acc; + }, + null + ); } get title() { @@ -90,7 +99,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap context.armorScore = this.actor.system.armorScore; context.armorMarks = currentMarks; - context.basicMarksUsed = selectedArmorMarks.length === this.actor.system.rules.maxArmorMarked.total; + context.basicMarksUsed = + selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total; const stressReductionStress = this.availableStressReductions ? stressReductions.reduce((acc, red) => acc + red.cost, 0) @@ -122,12 +132,15 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap getDamageInfo = () => { const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected); const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected); - const stressReductions = Object.values(this.availableStressReductions ?? {}).filter(red => red.selected); + const stressReductions = this.availableStressReductions + ? Object.values(this.availableStressReductions).filter(red => red.selected) + : []; const currentMarks = this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length; - const currentDamage = - this.damage - selectedArmorMarks.length - selectedStressMarks.length - stressReductions.length; + const armorMarkReduction = + selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark; + const currentDamage = this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length; return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage }; }; @@ -216,11 +229,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap await super.close({}); } - static async armorStackQuery({actorId, damage}) { + static async armorStackQuery({ actorId, damage, type }) { return new Promise(async (resolve, reject) => { const actor = await fromUuid(actorId); - if(!actor || !actor?.isOwner) reject(); - new DamageReductionDialog(resolve, reject, actor, damage).render({ force: true }); - }) + if (!actor || !actor?.isOwner) reject(); + new DamageReductionDialog(resolve, reject, actor, damage, type).render({ force: true }); + }); } } diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index bb98c8c3..21fbfea8 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -35,7 +35,7 @@ export default class ArmorSheet extends DHBaseItemSheet { switch (partId) { case 'settings': - context.features = this.document.system.features.map(x => x.value); + context.features = this.document.system.armorFeatures.map(x => x.value); break; } @@ -47,6 +47,6 @@ export default class ArmorSheet extends DHBaseItemSheet { * @param {Array} selectedOptions - The currently selected tag objects. */ static async #onFeatureSelect(selectedOptions) { - await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); + await this.document.update({ 'system.armorFeatures': selectedOptions.map(x => ({ value: x.value })) }); } } diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index d5d09dab..77396998 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -33,7 +33,7 @@ export default class WeaponSheet extends DHBaseItemSheet { super._preparePartContext(partId, context); switch (partId) { case 'settings': - context.features = this.document.system.features.map(x => x.value); + context.features = this.document.system.weaponFeatures.map(x => x.value); context.systemFields.attack.fields = this.document.system.attack.schema.fields; break; } @@ -45,6 +45,6 @@ export default class WeaponSheet extends DHBaseItemSheet { * @param {Array} selectedOptions - The currently selected tag objects. */ static async #onFeatureSelect(selectedOptions) { - await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); + await this.document.update({ 'system.weaponFeatures': selectedOptions.map(x => ({ value: x.value })) }); } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 0e2242d7..71532733 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -80,8 +80,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo actor.system.attack?._id === actionId ? actor.system.attack : item.system.attack?._id === actionId - ? item.system.attack - : item?.system?.actions?.find(a => a._id === actionId); + ? item.system.attack + : item?.system?.actions?.find(a => a._id === actionId); return action; } diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 64b856a0..282a8c9c 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -59,13 +59,13 @@ export const damageTypes = { id: 'physical', label: 'DAGGERHEART.CONFIG.DamageType.physical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.physical.abbreviation', - icon: ["fa-hand-fist"] + icon: ['fa-hand-fist'] }, magical: { id: 'magical', label: 'DAGGERHEART.CONFIG.DamageType.magical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.magical.abbreviation', - icon: ["fa-wand-sparkles"] + icon: ['fa-wand-sparkles'] } }; diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index 4cdd8125..cdc8a235 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -1,16 +1,29 @@ export const armorFeatures = { burning: { label: 'DAGGERHEART.CONFIG.ArmorFeature.burning.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.burning.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description', + img: 'icons/magic/fire/flame-burning-embers-yellow.webp' + } + ] }, channeling: { label: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.description', + img: 'icons/magic/symbols/rune-sigil-horned-blue.webp', changes: [ { - key: 'system.bonuses.spellcast', + key: 'system.bonuses.roll.spellcast', mode: 2, value: '1' } @@ -23,6 +36,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.description', + img: 'icons/magic/control/buff-flight-wings-red.webp', changes: [ { key: 'system.traits.agility.bonus', @@ -68,6 +84,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.description', + img: 'icons/magic/movement/abstract-ribbons-red-orange.webp', changes: [ { key: 'system.evasion.bonus', @@ -80,13 +99,30 @@ export const armorFeatures = { }, fortified: { label: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description', + img: 'icons/magic/defensive/shield-barrier-glowing-blue.webp', + changes: [ + { + key: 'system.rules.damageReduction.increasePerArmorMark', + mode: 5, + value: '2' + } + ] + } + ] }, gilded: { label: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.description', + img: 'icons/magic/control/control-influence-crown-gold.webp', changes: [ { key: 'system.traits.presence.bonus', @@ -102,6 +138,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.description', + img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { key: 'system.evasion.bonus', @@ -114,57 +153,223 @@ export const armorFeatures = { }, hopeful: { label: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description', + img: 'icons/magic/holy/barrier-shield-winged-blue.webp' + } + ] }, impenetrable: { label: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description', + img: 'icons/magic/defensive/shield-barrier-flaming-pentagon-purple-orange.webp', + uses: { + max: 1, + recovery: 'shortRest', + value: 0 + }, + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, - magic: { - label: 'DAGGERHEART.CONFIG.ArmorFeature.magic.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.magic.description' - }, - painful: { - label: 'DAGGERHEART.CONFIG.ArmorFeature.painful.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.painful.description' + magical: { + label: 'DAGGERHEART.CONFIG.ArmorFeature.magical.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.magical.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.magical.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.magical.description', + img: 'icons/magic/defensive/barrier-shield-dome-blue-purple.webp', + changes: [ + { + key: 'system.rules.damageReduction.magical', + mode: 5, + value: 1 + } + ] + } + ] }, physical: { label: 'DAGGERHEART.CONFIG.ArmorFeature.physical.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.physical.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.physical.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.physical.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.physical.description', + img: 'icons/commodities/stone/ore-pile-tan.webp', + changes: [ + { + key: 'system.rules.damageReduction.physical', + mode: 5, + value: 1 + } + ] + } + ] }, quiet: { label: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.description', + img: 'icons/magic/perception/silhouette-stealth-shadow.webp' + } + ] }, reinforced: { label: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.description', + img: 'icons/magic/defensive/shield-barrier-glowing-triangle-green.webp', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.reinforced.description', + img: 'icons/magic/defensive/shield-barrier-glowing-triangle-green.webp', + changes: [ + { + key: 'system.bunuses.damageThresholds.major', + mode: 2, + value: '2' + }, + { + key: 'system.bunuses.damageThresholds.severe', + mode: 2, + value: '2' + } + ] + } + ] + } + ] }, resilient: { label: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.description', + img: 'icons/magic/life/heart-cross-purple-orange.webp' + } + ] }, sharp: { label: 'DAGGERHEART.CONFIG.ArmorFeature.sharp.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.sharp.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.sharp.description', + actions: [ + { + type: 'damage', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.sharp.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.sharp.description', + img: 'icons/skills/melee/blade-tips-triple-bent-white.webp', + damage: { + parts: [ + { + type: 'physical', + value: { + custom: { + enabled: true, + formula: '1d4' + } + } + } + ] + } + } + ] }, shifting: { label: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.description', + img: 'icons/magic/defensive/illusion-evasion-echo-purple.webp', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, timeslowing: { label: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.description', + img: 'icons/magic/time/hourglass-brown-orange.webp' + } + ] }, truthseeking: { label: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.description', + img: 'icons/magic/perception/orb-crystal-ball-scrying-blue.webp' + } + ] }, veryheavy: { label: 'DAGGERHEART.CONFIG.ArmorFeature.veryHeavy.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.veryHeavy.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.veryHeavy.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.veryHeavy.description', + img: 'icons/commodities/metal/ingot-stamped-steel.webp', changes: [ { key: 'system.evasion.bonus', @@ -182,7 +387,21 @@ export const armorFeatures = { }, warded: { label: 'DAGGERHEART.CONFIG.ArmorFeature.warded.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.warded.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.warded.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.warded.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.warded.description', + img: 'icons/magic/defensive/barrier-shield-dome-pink.webp', + changes: [ + { + key: 'system.bonuses.damageReduction.magical', + mode: 2, + value: '@system.armorScore' + } + ] + } + ] } }; @@ -196,7 +415,7 @@ export const weaponFeatures = { { key: 'system.bonuses.armorScore', mode: 2, - value: '@system.tier + 1' + value: 'ITEM.@system.tier + 1' } ] }, @@ -218,9 +437,9 @@ export const weaponFeatures = { { changes: [ { - key: 'system.bonuses.damage', + key: 'system.bonuses.damage.primaryWeapon.bonus', mode: 2, - value: 'system.levelData.levels.current' + value: '@system.levelData.levels.current' } ] } @@ -228,7 +447,25 @@ export const weaponFeatures = { }, bouncing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description', + img: 'icons/skills/movement/ball-spinning-blue.webp', + cost: [ + { + type: 'stress', + value: 1, + scalable: true, + step: 1 + } + ] + } + ] }, brave: { label: 'DAGGERHEART.CONFIG.WeaponFeature.brave.name', @@ -248,7 +485,7 @@ export const weaponFeatures = { { key: 'system.damageThresholds.severe', mode: 2, - value: '3' + value: 'ITEM.@system.tier' } ] } @@ -256,7 +493,17 @@ export const weaponFeatures = { }, brutal: { label: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description', + img: 'icons/skills/melee/strike-dagger-blood-red.webp' + } + ] }, charged: { label: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', @@ -264,16 +511,31 @@ export const weaponFeatures = { actions: [ { type: 'effect', - name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', - img: 'icons/skills/melee/shield-damaged-broken-brown.webp', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.description', + img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp', cost: [ { type: 'stress', value: 1 } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.description', + img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp', + changes: [ + { + key: 'system.proficiency.bonus', + mode: 2, + value: '1' + } + ] + } ] - // Should add an effect with path system.proficiency.bonus +1 } ] }, @@ -282,10 +544,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', - img: 'icons/skills/melee/shield-damaged-broken-brown.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.description', + img: 'icons/skills/melee/shield-block-bash-yellow.webp', cost: [ { type: 'hope', @@ -300,6 +564,9 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.description', + img: 'icons/commodities/metal/mail-plate-steel.webp', changes: [ { key: 'system.traits.finesse.bonus', @@ -312,27 +579,70 @@ export const weaponFeatures = { }, deadly: { label: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description', + img: 'icons/skills/melee/strike-sword-dagger-runes-red.webp' + } + ] }, deflecting: { label: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description' - // actions: [{ - // type: 'effect', - // name: 'DAGGERHEART.CONFIG.WeaponFeature.Deflecting.Name', - // img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', - // actionType: 'reaction', - // cost: [{ - // type: 'armorSlot', // Needs armorSlot as type - // value: 1 - // }], - // }], + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp', + cost: [ + { + type: 'armorStack', + value: 1 + } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp', + changes: [ + { + key: 'system.evasion.bonus', + mode: 2, + value: '@system.armorScore' + } + ] + } + ] + } + ] }, destructive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + img: 'icons/skills/melee/strike-flail-spiked-pink.webp' + } + ], effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + img: 'icons/skills/melee/strike-flail-spiked-pink.webp', changes: [ { key: 'system.traits.agility.bonus', @@ -348,10 +658,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.name', - img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.description', + img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', cost: [ { type: 'stress', @@ -366,11 +678,19 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.description', + img: 'icons/skills/melee/sword-shield-stylized-white.webp', changes: [ { key: 'system.bonuses.armorScore', mode: 2, value: '1' + }, + { + key: 'system.bonuses.damage.primaryWeapon.bonus', + mode: 2, + value: '1' } ] } @@ -378,28 +698,60 @@ export const weaponFeatures = { }, doubledup: { label: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description', + img: 'icons/skills/melee/strike-slashes-orange.webp' + } + ] }, dueling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description', + img: 'icons/skills/melee/weapons-crossed-swords-pink.webp' + } + ] }, eruptive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description', + actions: [ + { + type: 'effect', // Should prompt a dc 14 reaction save on adversaries + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description', + img: 'icons/skills/melee/strike-hammer-destructive-blue.webp' + } + ] }, grappling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', - img: 'icons/magic/control/debuff-chains-ropes-net-white.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.description', + img: 'icons/magic/control/debuff-chains-ropes-net-white.webp', cost: [ { - type: 'stress', + type: 'hope', value: 1 } ] @@ -408,7 +760,32 @@ export const weaponFeatures = { }, greedy: { label: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + img: 'icons/commodities/currency/coins-crown-stack-gold.webp', + // Should cost handfull of gold, + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + img: 'icons/commodities/currency/coins-crown-stack-gold.webp', + changes: [ + { + key: 'system.proficiency.bonus', + mode: 2, + value: '1' + } + ] + } + ] + } + ] }, healing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.healing.name', @@ -416,9 +793,10 @@ export const weaponFeatures = { actions: [ { type: 'healing', + actionType: 'action', + chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.healing.name', img: 'icons/magic/life/cross-beam-green.webp', - actionType: 'action', healing: { type: 'health', value: { @@ -436,6 +814,9 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.description', + img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { key: 'system.evasion.bonus', @@ -448,37 +829,99 @@ export const weaponFeatures = { }, hooked: { label: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description', + img: 'icons/skills/melee/strike-chain-whip-blue.webp' + } + ] }, hot: { label: 'DAGGERHEART.CONFIG.WeaponFeature.hot.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.hot.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description', + img: 'icons/magic/fire/dagger-rune-enchant-flame-red.webp' + } + ] }, invigorating: { label: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description', + img: 'icons/magic/life/heart-cross-green.webp' + } + ] }, lifestealing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description', + img: 'icons/magic/unholy/hand-claw-fire-blue.webp' + } + ] }, lockedon: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description', + img: 'icons/skills/targeting/crosshair-arrowhead-blue.webp' + } + ] }, long: { label: 'DAGGERHEART.CONFIG.WeaponFeature.long.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.long.description' + // actions: [ + // { + // type: 'effect', + // actionType: 'action', + // chatDisplay: true, + // name: 'DAGGERHEART.CONFIG.WeaponFeature.long.name', + // description: 'DAGGERHEART.CONFIG.WeaponFeature.long.description', + // img: 'icons/skills/melee/strike-weapon-polearm-ice-blue.webp', + // } + // ] }, lucky: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', - img: 'icons/magic/control/buff-luck-fortune-green.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.description', + img: 'icons/magic/control/buff-luck-fortune-green.webp', cost: [ { type: 'stress', @@ -493,11 +936,24 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.massive.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.massive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.massive.description', + img: '', changes: [ { key: 'system.evasion.bonus', mode: 2, value: '-1' + }, + { + key: 'system.bonuses.damage.primaryWeapon.extraDice', + mode: 2, + value: '1' + }, + { + key: 'system.rules.weapon.dropLowestDamageDice', + mode: 5, + value: '1' } ] } @@ -508,10 +964,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.name', - img: 'icons/skills/wounds/injury-face-impact-orange.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.description', + img: 'icons/skills/wounds/injury-face-impact-orange.webp', cost: [ { type: 'stress', @@ -524,17 +982,64 @@ export const weaponFeatures = { paired: { label: 'DAGGERHEART.CONFIG.WeaponFeature.paired.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.paired.description', - override: { - bonusDamage: 1 - } + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.paired.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.paired.description', + img: 'icons/skills/melee/strike-flail-spiked-red.webp' + } + ] }, parry: { label: 'DAGGERHEART.CONFIG.WeaponFeature.parry.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.parry.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description', + img: 'icons/skills/melee/shield-block-fire-orange.webp' + } + ] }, persuasive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + img: 'icons/magic/control/hypnosis-mesmerism-eye.webp', + cost: [ + { + type: 'stress', + value: 1 + } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + img: 'icons/magic/control/hypnosis-mesmerism-eye.webp', + changes: [ + { + key: 'system.traits.presence.bonus', + mode: 2, + value: '2' + } + ] + } + ] + } + ] }, pompous: { label: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.name', @@ -542,18 +1047,50 @@ export const weaponFeatures = { }, powerful: { label: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + img: 'icons/magic/control/buff-flight-wings-runes-red-yellow.webp', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + img: 'icons/magic/control/buff-flight-wings-runes-red-yellow.webp', + changes: [ + { + key: 'system.bonuses.damage.primaryWeapon.extraDice', + mode: 2, + value: '1' + }, + { + key: 'system.rules.weapon.dropLowestDamageDice', + mode: 5, + value: '1' + } + ] + } + ] + } + ] }, protective: { label: 'DAGGERHEART.CONFIG.WeaponFeature.protective.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.protective.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description', + img: 'icons/skills/melee/shield-block-gray-orange.webp', changes: [ { key: 'system.bonuses.armorScore', mode: 2, - value: '@system.tier' + value: '1' } ] } @@ -564,10 +1101,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.name', - img: 'icons/skills/movement/arrow-upward-yellow.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.description', + img: 'icons/skills/movement/arrow-upward-yellow.webp', cost: [ { type: 'stress', @@ -582,9 +1121,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.description', + img: 'icons/skills/melee/strike-sword-slashing-red.webp', changes: [ { - key: 'system.bonuses.attack', + key: 'system.bonuses.roll.primaryWeapon.attack', mode: 2, value: 1 } @@ -594,7 +1136,17 @@ export const weaponFeatures = { }, reloading: { label: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description', + img: 'icons/weapons/ammunition/shot-round-blue.webp' + } + ] }, retractable: { label: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.name', @@ -604,21 +1156,87 @@ export const weaponFeatures = { label: 'DAGGERHEART.CONFIG.WeaponFeature.returning.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.returning.description' }, + selfCorrecting: { + label: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.description', + img: 'icons/weapons/ammunition/arrow-broadhead-glowing-orange.webp', + changes: [ + { + key: 'system.rules.damage.flipMinDiceValue', + mode: 5, + value: 1 + } + ] + } + ] + }, scary: { label: 'DAGGERHEART.CONFIG.WeaponFeature.scary.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.scary.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description', + img: 'icons/magic/death/skull-energy-light-purple.webp' + } + ] }, serrated: { label: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description', + img: 'icons/weapons/ammunition/arrow-broadhead-glowing-orange.webp', + changes: [ + { + key: 'system.rules.damage.flipMinDiceValue', + mode: 5, + value: 1 + } + ] + } + ] }, sharpwing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description', + img: 'icons/weapons/swords/sword-winged-pink.webp', + changes: [ + { + key: 'system.bonuses.damage.primaryWeapon.bonus', + mode: 2, + value: '@system.traits.agility.total' + } + ] + } + ] }, sheltering: { label: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description', + img: 'icons/skills/melee/shield-block-gray-yellow.webp' + } + ] }, startling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', @@ -626,9 +1244,11 @@ export const weaponFeatures = { actions: [ { type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', - img: 'icons/magic/control/fear-fright-mask-orange.webp', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.startling.description', + img: 'icons/magic/control/fear-fright-mask-orange.webp', cost: [ { type: 'stress', @@ -644,12 +1264,12 @@ export const weaponFeatures = { }, versatile: { label: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.description', - versatile: { - characterTrait: '', - range: '', - damage: '' - } + description: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.description' + // versatile: { + // characterTrait: '', + // range: '', + // damage: '' + // } } }; diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index 9c1c49f8..d953416a 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -14,12 +14,12 @@ export default class DHAttackAction extends DHDamageAction { prepareData() { super.prepareData(); - if(!!this.item?.system?.attack) { + if (!!this.item?.system?.attack) { if (this.damage.includeBase) { const baseDamage = this.getParentDamage(); this.damage.parts.unshift(new DHDamageData(baseDamage)); } - if(this.roll.useDefault) { + if (this.roll.useDefault) { this.roll.trait = this.item.system.attack.roll.trait; this.roll.type = 'weapon'; } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index ae0b7ccc..e193aefe 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -161,7 +161,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { updateSource['range'] = parent?.system?.attack?.range; updateSource['roll'] = { useDefault: true - } + }; } else { if (parent?.system?.trait) { updateSource['roll'] = { @@ -295,7 +295,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } prepareTarget() { - if(!this.target?.type) return []; + if (!this.target?.type) return []; let targets; if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id) targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken); @@ -337,7 +337,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const resources = config.costs .filter(c => c.enabled !== false) .map(c => { - return { type: c.type, value: (c.total ?? c.value) * -1 }; + const resource = this.actor.system.resources[c.type]; + return { type: c.type, value: (c.total ?? c.value) * (resource.hasOwnProperty('maxTotal') ? 1 : -1) }; }); await this.actor.modifyResource(resources); @@ -382,15 +383,21 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const realCosts = this.getRealCosts(costs), hasFearCost = realCosts.findIndex(c => c.type === 'fear'); if (hasFearCost > -1) { - const fearCost = realCosts.splice(hasFearCost, 1); + const fearCost = realCosts.splice(hasFearCost, 1)[0]; if ( !game.user.isGM || - fearCost[0].total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) + fearCost.total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) ) return false; } + + /* maxTotal is a sign that the resource is inverted, IE it counts upwards instead of down */ + const resources = this.actor.system.resources; return realCosts.reduce( - (a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), + (a, c) => + a && resources[c.type].hasOwnProperty('maxTotal') + ? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].maxTotal + : resources[c.type]?.value >= (c.total ?? c.value), true ); } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index daf63a79..93926d9a 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -100,12 +100,19 @@ export default class DhCharacter extends BaseDataActor { levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ armorScore: new fields.NumberField({ integer: true, initial: 0 }), + damageReduction: new fields.SchemaField({ + physical: new fields.NumberField({ integer: true, initial: 0 }), + magical: new fields.NumberField({ integer: true, initial: 0 }) + }), damageThresholds: new fields.SchemaField({ severe: new fields.NumberField({ integer: true, initial: 0 }), major: new fields.NumberField({ integer: true, initial: 0 }) }), roll: new fields.SchemaField({ attack: new fields.NumberField({ integer: true, initial: 0 }), + primaryWeapon: new fields.SchemaField({ + attack: new fields.NumberField({ integer: true, initial: 0 }) + }), spellcast: new fields.NumberField({ integer: true, initial: 0 }), action: new fields.NumberField({ integer: true, initial: 0 }), hopeOrFear: new fields.NumberField({ integer: true, initial: 0 }) @@ -113,20 +120,29 @@ export default class DhCharacter extends BaseDataActor { damage: new fields.SchemaField({ all: new fields.NumberField({ integer: true, initial: 0 }), physical: new fields.NumberField({ integer: true, initial: 0 }), - magic: new fields.NumberField({ integer: true, initial: 0 }) + magic: new fields.NumberField({ integer: true, initial: 0 }), + primaryWeapon: new fields.SchemaField({ + bonus: new fields.NumberField({ integer: true }), + extraDice: new fields.NumberField({ integer: true }) + }) }) }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), rules: new fields.SchemaField({ - maxArmorMarked: new fields.SchemaField({ - value: new fields.NumberField({ required: true, integer: true, initial: 1 }), - bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }), - stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 }) - }), - stressDamageReduction: new fields.SchemaField({ - severe: stressDamageReductionRule(), - major: stressDamageReductionRule(), - minor: stressDamageReductionRule() + damageReduction: new fields.SchemaField({ + maxArmorMarked: new fields.SchemaField({ + value: new fields.NumberField({ required: true, integer: true, initial: 1 }), + bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }), + stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 }) + }), + stressDamageReduction: new fields.SchemaField({ + severe: stressDamageReductionRule(), + major: stressDamageReductionRule(), + minor: stressDamageReductionRule() + }), + increasePerArmorMark: new fields.NumberField({ integer: true, initial: 1 }), + magical: new fields.BooleanField({ initial: false }), + physical: new fields.BooleanField({ initial: false }) }), strangePatterns: new fields.NumberField({ integer: true, @@ -135,6 +151,18 @@ export default class DhCharacter extends BaseDataActor { nullable: true, initial: null }), + weapon: new fields.SchemaField({ + /* Unimplemented + -> Should remove the lowest damage dice from weapon damage + -> Reflect this in the chat message somehow so players get feedback that their choice is helping them. + */ + dropLowestDamageDice: new fields.BooleanField({ initial: false }), + /* Unimplemented + -> Should flip any lowest possible dice rolls for weapon damage to highest + -> Reflect this in the chat message somehow so players get feedback that their choice is helping them. + */ + flipMinDiceValue: new fields.BooleanField({ intial: false }) + }), runeWard: new fields.BooleanField({ initial: false }) }) }; @@ -282,6 +310,13 @@ export default class DhCharacter extends BaseDataActor { ); } + get armorApplicableDamageTypes() { + return { + physical: !this.rules.damageReduction.magical, + magical: !this.rules.damageReduction.physical + }; + } + static async unequipBeforeEquip(itemToEquip) { const primary = this.primaryWeapon, secondary = this.secondaryWeapon; @@ -348,6 +383,7 @@ export default class DhCharacter extends BaseDataActor { } const armor = this.armor; + this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; // Bonuses to armorScore won't have been applied yet. Need to solve in documentPreparation somehow this.damageThresholds = { major: armor ? armor.system.baseThresholds.major + this.levelData.level.current @@ -372,9 +408,9 @@ export default class DhCharacter extends BaseDataActor { experience.total = experience.value + experience.bonus; } - this.rules.maxArmorMarked.total = this.rules.maxArmorMarked.value + this.rules.maxArmorMarked.bonus; + this.rules.damageReduction.maxArmorMarked.total = + this.rules.damageReduction.maxArmorMarked.value + this.rules.damageReduction.maxArmorMarked.bonus; - this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + this.resources.hitPoints.bonus; this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus; this.evasion.total = (this.class?.evasion ?? 0) + this.evasion.bonus; diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 4e5a26e6..696a95a2 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -22,7 +22,7 @@ export default class DHArmor extends BaseDataItem { tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }), equipped: new fields.BooleanField({ initial: false }), baseScore: new fields.NumberField({ integer: true, initial: 0 }), - features: new fields.ArrayField( + armorFeatures: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ required: true, @@ -44,25 +44,22 @@ export default class DHArmor extends BaseDataItem { }; } - get featureInfo() { - return this.feature ? CONFIG.DH.ITEM.armorFeatures[this.feature] : null; - } - async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - if (changes.system.features) { - const removed = this.features.filter(x => !changes.system.features.includes(x)); - const added = changes.system.features.filter(x => !this.features.includes(x)); + if (changes.system.armorFeatures) { + const removed = this.armorFeatures.filter(x => !changes.system.armorFeatures.includes(x)); + const added = changes.system.armorFeatures.filter(x => !this.armorFeatures.includes(x)); + const effectIds = []; + const actionIds = []; for (var feature of removed) { - for (var effectId of feature.effectIds) { - await this.parent.effects.get(effectId).delete(); - } - - changes.system.actions = this.actions.filter(x => !feature.actionIds.includes(x._id)); + effectIds.push(...feature.effectIds); + actionIds.push(...feature.actionIds); } + await this.parent.deleteEmbeddedDocuments('ActiveEffect', effectIds); + changes.system.actions = this.actions.filter(x => !actionIds.includes(x._id)); for (var feature of added) { const featureData = armorFeatures[feature.value]; diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 3fb562e0..e1370395 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -10,7 +10,7 @@ export default class DHWeapon extends BaseDataItem { type: 'weapon', hasDescription: true, isQuantifiable: true, - isInventoryItem: true, + isInventoryItem: true // hasInitialAction: true }); } @@ -26,8 +26,7 @@ export default class DHWeapon extends BaseDataItem { //SETTINGS secondary: new fields.BooleanField({ initial: false }), burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded' }), - - features: new fields.ArrayField( + weaponFeatures: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ required: true, @@ -59,7 +58,7 @@ export default class DHWeapon extends BaseDataItem { { value: { multiplier: 'prof', - dice: "d8" + dice: 'd8' } } ] @@ -78,18 +77,20 @@ export default class DHWeapon extends BaseDataItem { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - if (changes.system?.features) { - const removed = this.features.filter(x => !changes.system.features.includes(x)); - const added = changes.system.features.filter(x => !this.features.includes(x)); + if (changes.system?.weaponFeatures) { + const removed = this.weaponFeatures.filter(x => !changes.system.weaponFeatures.includes(x)); + const added = changes.system.weaponFeatures.filter(x => !this.weaponFeatures.includes(x)); + const removedEffectsUpdate = []; + const removedActionsUpdate = []; for (let weaponFeature of removed) { - for (var effectId of weaponFeature.effectIds) { - await this.parent.effects.get(effectId).delete(); - } - - changes.system.actions = this.actions.filter(x => !weaponFeature.actionIds.includes(x._id)); + removedEffectsUpdate.push(...weaponFeature.effectIds); + removedActionsUpdate.push(...weaponFeature.actionIds); } + await this.parent.deleteEmbeddedDocuments('ActiveEffect', removedEffectsUpdate); + changes.system.actions = this.actions.filter(x => !removedActionsUpdate.includes(x._id)); + for (let weaponFeature of added) { const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value]; if (featureData.effects?.length > 0) { @@ -102,17 +103,37 @@ export default class DHWeapon extends BaseDataItem { ]); weaponFeature.effectIds = embeddedItems.map(x => x.id); } + + const newActions = []; if (featureData.actions?.length > 0) { - const newActions = featureData.actions.map(action => { - const cls = actionsTypes[action.type]; - return new cls( - { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, - { parent: this } + for (let action of featureData.actions) { + const embeddedEffects = await this.parent.createEmbeddedDocuments( + 'ActiveEffect', + (action.effects ?? []).map(effect => ({ + ...effect, + transfer: false, + name: game.i18n.localize(effect.name), + description: game.i18n.localize(effect.description) + })) ); - }); - changes.system.actions = [...this.actions, ...newActions]; - weaponFeature.actionIds = newActions.map(x => x._id); + const cls = actionsTypes[action.type]; + newActions.push( + new cls( + { + ...action, + _id: foundry.utils.randomID(), + name: game.i18n.localize(action.name), + description: game.i18n.localize(action.description), + effects: embeddedEffects.map(x => ({ _id: x.id })) + }, + { parent: this } + ) + ); + } } + + changes.system.actions = [...this.actions, ...newActions]; + weaponFeature.actionIds = newActions.map(x => x._id); } } } diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 65610e7c..1abc2d17 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -25,7 +25,11 @@ export default class DhActiveEffect extends ActiveEffect { } static applyField(model, change, field) { - change.value = Roll.safeEval(Roll.replaceFormulaData(change.value, change.effect.parent)); + const isItemTarget = change.value.toLowerCase().startsWith('item.'); + change.value = isItemTarget ? change.value.slice(5) : change.value; + change.value = Roll.safeEval( + Roll.replaceFormulaData(change.value, isItemTarget ? change.effect.parent : model) + ); super.applyField(model, change, field); } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index cfe101fa..aba0e0fa 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -3,6 +3,7 @@ import { emitAsGM, emitAsOwner, GMUpdateEvent, socketEvent } from '../systemRegi import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs'; import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; +import { damageKeyToNumber, getDamageKey } from '../helpers/utils.mjs'; export default class DhpActor extends Actor { /** @@ -455,14 +456,32 @@ export default class DhpActor extends Actor { cls.create(msg.toObject()); } - async takeDamage(damage, type) { - if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damage, type) === false) return null; + #canReduceDamage(hpDamage, type) { + const availableStress = this.system.resources.stress.maxTotal - this.system.resources.stress.value; + + const canUseArmor = + this.system.armor && + this.system.armor.system.marks.value < this.system.armorScore && + this.system.armorApplicableDamageTypes[type]; + const canUseStress = Object.keys(this.system.rules.damageReduction.stressDamageReduction).reduce((acc, x) => { + const rule = this.system.rules.damageReduction.stressDamageReduction[x]; + if (damageKeyToNumber(x) <= hpDamage) return acc || (rule.enabled && availableStress >= rule.cost); + return acc; + }, false); + + return canUseArmor || canUseStress; + } + + async takeDamage(baseDamage, type) { + if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, baseDamage, type) === false) return null; if (this.type === 'companion') { await this.modifyResource([{ value: 1, type: 'stress' }]); return; } + const flatReduction = this.system.bonuses.damageReduction[type]; + const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); const hpDamage = this.convertDamageToThreshold(damage); if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null; @@ -471,12 +490,12 @@ export default class DhpActor extends Actor { const updates = [{ value: hpDamage, type: 'hitPoints' }]; - if ( - this.type === 'character' && - this.system.armor && - this.system.armor.system.marks.value < this.system.armorScore - ) { - const armorStackResult = await this.owner.query('armorStack', { actorId: this.uuid, damage: hpDamage }); + if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage, type)) { + const armorStackResult = await this.owner.query('armorStack', { + actorId: this.uuid, + damage: hpDamage, + type: type + }); if (armorStackResult) { const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; updates.find(u => u.type === 'hitPoints').value = modifiedDamage; diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 35b9e32f..db34fa49 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -90,10 +90,12 @@ export default class DHItem extends foundry.documents.Item { ok: { label: title, callback: (event, button, dialog) => { - Object.defineProperty(prevEvent, "shiftKey", { - get() { return event.shiftKey; }, + Object.defineProperty(prevEvent, 'shiftKey', { + get() { + return event.shiftKey; + } }); - return this.system.actionsList.find(a => a._id === button.form.elements.actionId.value) + return this.system.actionsList.find(a => a._id === button.form.elements.actionId.value); } } }); diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index e719b25e..0bb2088e 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -159,7 +159,8 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => return { value: key, name: game.i18n.localize(option.label), - src: option.src + src: option.src, + description: option.description }; }), maxTags: maxTags, @@ -173,11 +174,12 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => }, templates: { tag(tagData) { - return `
@@ -190,6 +192,8 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => }); tagifyElement.on('add', event => { + if (event.detail.data.__isValid === 'not allowed') return; + const input = event.detail.tagify.DOM.originalInput; const currentList = input.value ? JSON.parse(input.value) : []; onChange([...currentList, event.detail.data], { option: event.detail.data.value, removed: false }, input); @@ -233,19 +237,23 @@ Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false return nativeReplaceFormulaData(formula, data, { missing, warn }); }; -export const getDamageLabel = damage => { +export const getDamageKey = damage => { switch (damage) { case 3: - return game.i18n.localize('DAGGERHEART.GENERAL.Damage.severe'); + return 'severe'; case 2: - return game.i18n.localize('DAGGERHEART.GENERAL.Damage.major'); + return 'major'; case 1: - return game.i18n.localize('DAGGERHEART.GENERAL.Damage.minor'); + return 'minor'; case 0: - return game.i18n.localize('DAGGERHEART.GENERAL.Damage.none'); + return 'none'; } }; +export const getDamageLabel = damage => { + return game.i18n.localize(`DAGGERHEART.GENERAL.Damage.${getDamageKey(damage)}`); +}; + export const damageKeyToNumber = key => { switch (key) { case 'severe': diff --git a/module/systemRegistration/socket.mjs b/module/systemRegistration/socket.mjs index b336a012..0037d99d 100644 --- a/module/systemRegistration/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -45,7 +45,13 @@ export const registerSocketHooks = () => { await game.settings.set( CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, - Math.max(0, Math.min(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear, data.update)) + Math.max( + 0, + Math.min( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear, + data.update + ) + ) ); /* Hooks.callAll(socketEvent.DhpFearUpdate); await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.DhpFearUpdate }); */ @@ -64,7 +70,7 @@ export const registerSocketHooks = () => { }; export const emitAsGM = async (eventName, callback, update, uuid = null) => { - if(!game.user.isGM) { + if (!game.user.isGM) { return await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.GMUpdate, data: { @@ -74,11 +80,11 @@ export const emitAsGM = async (eventName, callback, update, uuid = null) => { } }); } else return callback(update); -} +}; export const emitAsOwner = (eventName, userId, args) => { - if(userId === game.user.id) return; - if(!eventName || !userId) return false; + if (userId === game.user.id) return; + if (!eventName || !userId) return false; game.socket.emit(`system.${CONFIG.DH.id}`, { action: eventName, data: { @@ -87,4 +93,4 @@ export const emitAsOwner = (eventName, userId, args) => { } }); return false; -} \ No newline at end of file +}; diff --git a/styles/less/dialog/beastform/beastform-container.less b/styles/less/dialog/beastform/beastform-container.less index df930532..bf0d0cae 100644 --- a/styles/less/dialog/beastform/beastform-container.less +++ b/styles/less/dialog/beastform/beastform-container.less @@ -1,46 +1,46 @@ -@import '../../utils/colors.less'; - -.application.daggerheart.dh-style.views.beastform-selection { - .beastforms-container { - display: flex; - flex-direction: column; - gap: 4px; - - .beastforms-tier { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - gap: 4px; - - .beastform-container { - position: relative; - display: flex; - justify-content: center; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - cursor: pointer; - - &.inactive { - opacity: 0.4; - } - - img { - width: 100%; - border-radius: 6px; - } - - .beastform-title { - position: absolute; - top: 4px; - display: flex; - flex-wrap: wrap; - font-size: 16px; - margin: 0 4px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - } - } -} +@import '../../utils/colors.less'; + +.application.daggerheart.dh-style.views.beastform-selection { + .beastforms-container { + display: flex; + flex-direction: column; + gap: 4px; + + .beastforms-tier { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + gap: 4px; + + .beastform-container { + position: relative; + display: flex; + justify-content: center; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + cursor: pointer; + + &.inactive { + opacity: 0.4; + } + + img { + width: 100%; + border-radius: 6px; + } + + .beastform-title { + position: absolute; + top: 4px; + display: flex; + flex-wrap: wrap; + font-size: 16px; + margin: 0 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + } + } +} diff --git a/styles/less/dialog/beastform/sheet.less b/styles/less/dialog/beastform/sheet.less index dd1dff24..bd757b87 100644 --- a/styles/less/dialog/beastform/sheet.less +++ b/styles/less/dialog/beastform/sheet.less @@ -1,21 +1,21 @@ -@import '../../utils/colors.less'; -@import '../../utils/mixin.less'; - -.appTheme({ - &.beastform-selection { - .beastforms-container .beastforms-tier .beastform-container .beastform-title { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -}, {}); - -.application.daggerheart.dh-style.views.beastform-selection { - footer { - margin-top: 8px; - display: flex; - - button { - flex: 1; - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/mixin.less'; + +.appTheme({ + &.beastform-selection { + .beastforms-container .beastforms-tier .beastform-container .beastform-title { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}, {}); + +.application.daggerheart.dh-style.views.beastform-selection { + footer { + margin-top: 8px; + display: flex; + + button { + flex: 1; + } + } +} diff --git a/styles/less/dialog/character-creation/creation-action-footer.less b/styles/less/dialog/character-creation/creation-action-footer.less index 29e08440..88a9b3c8 100644 --- a/styles/less/dialog/character-creation/creation-action-footer.less +++ b/styles/less/dialog/character-creation/creation-action-footer.less @@ -1,13 +1,13 @@ -.daggerheart.dh-style.dialog.character-creation { - .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; - - button { - flex: 1; - height: 100%; - white-space: nowrap; - } - } -} +.daggerheart.dh-style.dialog.character-creation { + .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; + + button { + flex: 1; + height: 100%; + white-space: nowrap; + } + } +} diff --git a/styles/less/dialog/character-creation/selections-container.less b/styles/less/dialog/character-creation/selections-container.less index 0a610435..643a5c29 100644 --- a/styles/less/dialog/character-creation/selections-container.less +++ b/styles/less/dialog/character-creation/selections-container.less @@ -1,325 +1,325 @@ -@import '../../utils/colors.less'; - -.daggerheart.dh-style.dialog.character-creation { - .main-selections-container { - display: flex; - flex-direction: column; - gap: 4px; - - .selections-container { - width: 140px; - display: flex; - flex-direction: column; - text-align: center; - - .card-preview-container { - border-color: light-dark(@dark-blue, @golden); - } - } - - .selections-outer-container { - display: flex; - justify-content: space-evenly; - height: 210px; - } - - .section-container { - border-radius: 8px; - border-color: light-dark(@dark-blue, @golden); - - legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - } - - .section-inner-container { - position: relative; - border-radius: 8px; - border-color: light-dark(@dark-blue, @golden); - display: flex; - justify-content: center; - - legend { - font-size: 20px; - } - - .action-button { - position: absolute; - bottom: -8px; - height: 16px; - width: 110px; - min-height: unset; - border: 1px solid light-dark(@dark-blue, @golden); - color: light-dark(@beige, @beige); - background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); - - &:hover { - background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); - filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); - } - } - } - } - - .traits-container { - text-align: center; - display: flex; - gap: 16px; - - .suggested-traits-container { - display: flex; - flex-wrap: wrap; - width: 176px; - gap: 4px; - margin-bottom: 8px; - - .suggested-trait-container { - width: 56px; - white-space: nowrap; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - - .traits-inner-container { - display: flex; - justify-content: space-evenly; - gap: 8px; - - .trait-container { - border: 1px solid light-dark(@dark-blue, @golden); - padding: 0 4px; - } - } - } - - .experiences-inner-container { - display: flex; - justify-content: space-evenly; - text-align: center; - - .experience-container { - position: relative; - display: flex; - align-items: center; - - .experience-description { - border-color: light-dark(@dark-blue, @golden); - padding-right: 24px; - } - - .experience-value { - position: absolute; - right: 0; - width: 22px; - border-left: 1px solid light-dark(@dark-blue, @golden); - height: 100%; - display: flex; - align-items: center; - justify-content: center; - } - } - } - - .creation-action-footer { - display: flex; - align-items: center; - gap: 32px; - - .footer-section { - display: flex; - align-items: center; - gap: 32px; - - nav { - flex: 1; - gap: 8px; - border: 0; - - a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - - .nav-section-text { - position: relative; - display: flex; - align-items: center; - } - - .finish-marker { - position: absolute; - align-self: center; - top: -10px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 20px; - width: 20px; - font-size: 14px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; - - &.finished { - background-color: var(--color-warm-2); - } - } - - .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - } - } - } - - button { - flex: 1; - height: 100%; - white-space: nowrap; - } - } - } - - .main-equipment-selection { - display: grid; - grid-template-columns: 1fr 2fr; - gap: 16px; - - &.triple { - grid-template-columns: 1fr 1fr 1fr; - } - } - - .equipment-selection { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - border: 2px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 28px; - font-weight: bold; - padding: 0 8px; - white-space: nowrap; - } - - .equipment-subsection { - display: flex; - align-items: start; - gap: 32px; - } - - .equipment-wrapper { - display: flex; - flex-direction: column; - align-items: center; - gap: 8px; - } - - .simple-equipment-container { - display: flex; - flex-direction: column; - justify-content: space-evenly; - gap: 8px; - height: 100%; - - .simple-equipment { - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - position: relative; - display: flex; - justify-content: center; - - &.selectable { - cursor: pointer; - } - - &.inactive { - opacity: 0.4; - } - - label { - position: absolute; - top: -8px; - font-size: 12px; - white-space: nowrap; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - padding: 0 2px; - } - - img { - width: 60px; - height: 60px; - border-radius: 8px; - } - } - } - - .suggestion-container { - position: relative; - display: flex; - justify-content: center; - height: min-content; - border: 2px solid light-dark(@dark-blue, @golden); - border-radius: 8px; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; - } - - .suggestion-inner-container { - position: relative; - display: flex; - justify-content: center; - align-items: center; - padding: 6px; - cursor: grab; - - &.taken { - opacity: 0.4; - } - - label { - position: absolute; - top: -2px; - font-size: 12px; - } - - img { - width: 120px; - } - } - } - } - } -} +@import '../../utils/colors.less'; + +.daggerheart.dh-style.dialog.character-creation { + .main-selections-container { + display: flex; + flex-direction: column; + gap: 4px; + + .selections-container { + width: 140px; + display: flex; + flex-direction: column; + text-align: center; + + .card-preview-container { + border-color: light-dark(@dark-blue, @golden); + } + } + + .selections-outer-container { + display: flex; + justify-content: space-evenly; + height: 210px; + } + + .section-container { + border-radius: 8px; + border-color: light-dark(@dark-blue, @golden); + + legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; + } + + .section-inner-container { + position: relative; + border-radius: 8px; + border-color: light-dark(@dark-blue, @golden); + display: flex; + justify-content: center; + + legend { + font-size: 20px; + } + + .action-button { + position: absolute; + bottom: -8px; + height: 16px; + width: 110px; + min-height: unset; + border: 1px solid light-dark(@dark-blue, @golden); + color: light-dark(@beige, @beige); + background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); + + &:hover { + background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); + filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); + } + } + } + } + + .traits-container { + text-align: center; + display: flex; + gap: 16px; + + .suggested-traits-container { + display: flex; + flex-wrap: wrap; + width: 176px; + gap: 4px; + margin-bottom: 8px; + + .suggested-trait-container { + width: 56px; + white-space: nowrap; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + + .traits-inner-container { + display: flex; + justify-content: space-evenly; + gap: 8px; + + .trait-container { + border: 1px solid light-dark(@dark-blue, @golden); + padding: 0 4px; + } + } + } + + .experiences-inner-container { + display: flex; + justify-content: space-evenly; + text-align: center; + + .experience-container { + position: relative; + display: flex; + align-items: center; + + .experience-description { + border-color: light-dark(@dark-blue, @golden); + padding-right: 24px; + } + + .experience-value { + position: absolute; + right: 0; + width: 22px; + border-left: 1px solid light-dark(@dark-blue, @golden); + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + } + } + + .creation-action-footer { + display: flex; + align-items: center; + gap: 32px; + + .footer-section { + display: flex; + align-items: center; + gap: 32px; + + nav { + flex: 1; + gap: 8px; + border: 0; + + a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + + .nav-section-text { + position: relative; + display: flex; + align-items: center; + } + + .finish-marker { + position: absolute; + align-self: center; + top: -10px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 20px; + width: 20px; + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; + + &.finished { + background-color: var(--color-warm-2); + } + } + + .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + } + } + } + + button { + flex: 1; + height: 100%; + white-space: nowrap; + } + } + } + + .main-equipment-selection { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 16px; + + &.triple { + grid-template-columns: 1fr 1fr 1fr; + } + } + + .equipment-selection { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + border: 2px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + + legend { + margin-left: auto; + margin-right: auto; + font-size: 28px; + font-weight: bold; + padding: 0 8px; + white-space: nowrap; + } + + .equipment-subsection { + display: flex; + align-items: start; + gap: 32px; + } + + .equipment-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + } + + .simple-equipment-container { + display: flex; + flex-direction: column; + justify-content: space-evenly; + gap: 8px; + height: 100%; + + .simple-equipment { + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + position: relative; + display: flex; + justify-content: center; + + &.selectable { + cursor: pointer; + } + + &.inactive { + opacity: 0.4; + } + + label { + position: absolute; + top: -8px; + font-size: 12px; + white-space: nowrap; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url('../assets/parchments/dh-parchment-light.png'); + padding: 0 2px; + } + + img { + width: 60px; + height: 60px; + border-radius: 8px; + } + } + } + + .suggestion-container { + position: relative; + display: flex; + justify-content: center; + height: min-content; + border: 2px solid light-dark(@dark-blue, @golden); + border-radius: 8px; + + legend { + margin-left: auto; + margin-right: auto; + font-size: 12px; + } + + .suggestion-inner-container { + position: relative; + display: flex; + justify-content: center; + align-items: center; + padding: 6px; + cursor: grab; + + &.taken { + opacity: 0.4; + } + + label { + position: absolute; + top: -2px; + font-size: 12px; + } + + img { + width: 120px; + } + } + } + } + } +} diff --git a/styles/less/dialog/character-creation/sheet.less b/styles/less/dialog/character-creation/sheet.less index 5ee3f9b2..ce12d056 100644 --- a/styles/less/dialog/character-creation/sheet.less +++ b/styles/less/dialog/character-creation/sheet.less @@ -1,27 +1,27 @@ -@import '../../utils/colors.less'; -@import '../../utils/mixin.less'; - -.appTheme({ - .character-creation { - .tab-navigation nav a .descriptor { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - .main-selections-container { - .traits-container .suggested-traits-container .suggested-trait-container, - .creation-action-footer .footer-section nav a .descriptor, - .equipment-selection .simple-equipment-container .simple-equipment label { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -} -}, {}); - -.daggerheart.dh-style.dialog.character-creation { - .window-content { - gap: 16px; - - .tab { - overflow-y: auto; - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/mixin.less'; + +.appTheme({ + .character-creation { + .tab-navigation nav a .descriptor { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + .main-selections-container { + .traits-container .suggested-traits-container .suggested-trait-container, + .creation-action-footer .footer-section nav a .descriptor, + .equipment-selection .simple-equipment-container .simple-equipment label { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +} +}, {}); + +.daggerheart.dh-style.dialog.character-creation { + .window-content { + gap: 16px; + + .tab { + overflow-y: auto; + } + } +} diff --git a/styles/less/dialog/character-creation/tab-navigation.less b/styles/less/dialog/character-creation/tab-navigation.less index d951a7b2..dbf285f6 100644 --- a/styles/less/dialog/character-creation/tab-navigation.less +++ b/styles/less/dialog/character-creation/tab-navigation.less @@ -1,62 +1,62 @@ -@import '../../utils/colors.less'; - -.daggerheart.dh-style.dialog.character-creation { - .tab-navigation { - nav { - flex: 1; - - a { - flex: 1; - text-align: center; - display: flex; - justify-content: center; - position: relative; - - &.disabled { - opacity: 0.4; - } - - .nav-section-text { - position: relative; - display: flex; - align-items: center; - } - - .finish-marker { - position: absolute; - align-self: center; - top: -8px; - padding: 4px; - border: 1px solid; - border-radius: 50%; - height: 16px; - width: 16px; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-cool-4); - content: ''; - - &.active { - background-color: var(--color-warm-2); - } - } - - .descriptor { - position: absolute; - bottom: -8px; - font-size: 12px; - border-radius: 8px; - width: 56px; - text-align: center; - line-height: 1; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - } - } - } - } -} +@import '../../utils/colors.less'; + +.daggerheart.dh-style.dialog.character-creation { + .tab-navigation { + nav { + flex: 1; + + a { + flex: 1; + text-align: center; + display: flex; + justify-content: center; + position: relative; + + &.disabled { + opacity: 0.4; + } + + .nav-section-text { + position: relative; + display: flex; + align-items: center; + } + + .finish-marker { + position: absolute; + align-self: center; + top: -8px; + padding: 4px; + border: 1px solid; + border-radius: 50%; + height: 16px; + width: 16px; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-cool-4); + content: ''; + + &.active { + background-color: var(--color-warm-2); + } + } + + .descriptor { + position: absolute; + bottom: -8px; + font-size: 12px; + border-radius: 8px; + width: 56px; + text-align: center; + line-height: 1; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + } + } + } + } +} diff --git a/styles/less/dialog/damage-reduction/sheets.less b/styles/less/dialog/damage-reduction/sheets.less index 836a2b2f..b73d7518 100644 --- a/styles/less/dialog/damage-reduction/sheets.less +++ b/styles/less/dialog/damage-reduction/sheets.less @@ -1,7 +1,7 @@ -@import '../../utils/colors.less'; - -.daggerheart.views.damage-reduction { - .window-content { - padding: 8px 0; - } -} +@import '../../utils/colors.less'; + +.daggerheart.views.damage-reduction { + .window-content { + padding: 8px 0; + } +} diff --git a/styles/less/dialog/downtime/downtime-container.less b/styles/less/dialog/downtime/downtime-container.less index 9b2c842c..4e785e7b 100644 --- a/styles/less/dialog/downtime/downtime-container.less +++ b/styles/less/dialog/downtime/downtime-container.less @@ -1,81 +1,81 @@ -@import '../../utils/spacing.less'; -@import '../../utils/colors.less'; - -.daggerheart.views { - .downtime-container { - .downtime-header { - margin: 0; - color: light-dark(@dark-blue, @golden); - text-align: center; - } - - .activity-container { - display: flex; - align-items: center; - padding: 8px; - - .activity-title { - flex: 1; - display: flex; - align-items: center; - - .activity-title-text { - font-size: 24px; - font-weight: bold; - } - - .activity-image { - width: 80px; - position: relative; - display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; - - .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; - } - - img { - border-radius: 50%; - } - - &:hover, - &.selected { - filter: drop-shadow(0 0 6px gold); - } - } - - .custom-name-input { - font-size: 24px; - font-weight: bold; - padding: 0; - background: transparent; - color: rgb(239, 230, 216); - } - } - - .activity-body { - flex: 1; - font-style: italic; - } - } - } - - &.downtime { - .activity-text-area { - resize: none; - } - } -} +@import '../../utils/spacing.less'; +@import '../../utils/colors.less'; + +.daggerheart.views { + .downtime-container { + .downtime-header { + margin: 0; + color: light-dark(@dark-blue, @golden); + text-align: center; + } + + .activity-container { + display: flex; + align-items: center; + padding: 8px; + + .activity-title { + flex: 1; + display: flex; + align-items: center; + + .activity-title-text { + font-size: 24px; + font-weight: bold; + } + + .activity-image { + width: 80px; + position: relative; + display: flex; + justify-content: center; + margin-right: 8px; + border: 2px solid black; + border-radius: 50%; + cursor: pointer; + + .activity-select-label { + position: absolute; + top: -9px; + font-size: 14px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@beige, @dark); + background-image: url(../assets/parchments/dh-parchment-light.png); + padding: 0 8px; + line-height: 1; + font-weight: bold; + } + + img { + border-radius: 50%; + } + + &:hover, + &.selected { + filter: drop-shadow(0 0 6px gold); + } + } + + .custom-name-input { + font-size: 24px; + font-weight: bold; + padding: 0; + background: transparent; + color: rgb(239, 230, 216); + } + } + + .activity-body { + flex: 1; + font-style: italic; + } + } + } + + &.downtime { + .activity-text-area { + resize: none; + } + } +} diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index ec3ef200..40280270 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -1,19 +1,19 @@ -@import './level-up/navigation-container.less'; -@import './level-up/selections-container.less'; -@import './level-up/sheet.less'; -@import './level-up/summary-container.less'; -@import './level-up/tiers-container.less'; - -@import './downtime/downtime-container.less'; - -@import './beastform/beastform-container.less'; -@import './beastform/sheet.less'; - -@import './character-creation/creation-action-footer.less'; -@import './character-creation/selections-container.less'; -@import './character-creation/sheet.less'; -@import './character-creation/tab-navigation.less'; - -@import './dice-roll/roll-selection.less'; -@import './damage-reduction/damage-reduction-container.less'; -@import './damage-reduction/sheets.less'; +@import './level-up/navigation-container.less'; +@import './level-up/selections-container.less'; +@import './level-up/sheet.less'; +@import './level-up/summary-container.less'; +@import './level-up/tiers-container.less'; + +@import './downtime/downtime-container.less'; + +@import './beastform/beastform-container.less'; +@import './beastform/sheet.less'; + +@import './character-creation/creation-action-footer.less'; +@import './character-creation/selections-container.less'; +@import './character-creation/sheet.less'; +@import './character-creation/tab-navigation.less'; + +@import './dice-roll/roll-selection.less'; +@import './damage-reduction/damage-reduction-container.less'; +@import './damage-reduction/sheets.less'; diff --git a/styles/less/dialog/level-up/navigation-container.less b/styles/less/dialog/level-up/navigation-container.less index b52abf20..142cf089 100644 --- a/styles/less/dialog/level-up/navigation-container.less +++ b/styles/less/dialog/level-up/navigation-container.less @@ -1,30 +1,30 @@ -.daggerheart.levelup { - .levelup-navigation-container { - display: flex; - align-items: center; - gap: 22px; - height: 36px; - - nav { - flex: 1; - - .levelup-tab-container { - display: flex; - align-items: center; - gap: 4px; - } - } - - .levelup-navigation-actions { - width: 306px; - display: flex; - justify-content: end; - gap: 16px; - margin-right: 4px; - - * { - width: calc(50% - 8px); - } - } - } -} +.daggerheart.levelup { + .levelup-navigation-container { + display: flex; + align-items: center; + gap: 22px; + height: 36px; + + nav { + flex: 1; + + .levelup-tab-container { + display: flex; + align-items: center; + gap: 4px; + } + } + + .levelup-navigation-actions { + width: 306px; + display: flex; + justify-content: end; + gap: 16px; + margin-right: 4px; + + * { + width: calc(50% - 8px); + } + } + } +} diff --git a/styles/less/dialog/level-up/selections-container.less b/styles/less/dialog/level-up/selections-container.less index b04a6182..182e2962 100644 --- a/styles/less/dialog/level-up/selections-container.less +++ b/styles/less/dialog/level-up/selections-container.less @@ -1,108 +1,108 @@ -.daggerheart.levelup { - .levelup-selections-container { - .achievement-experience-cards { - display: flex; - gap: 8px; - - .achievement-experience-card { - border: 1px solid; - border-radius: 4px; - padding-right: 4px; - font-size: 18px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 4px; - - .achievement-experience-marker { - border: 1px solid; - border-radius: 50%; - height: 18px; - width: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 12px; - } - } - } - - .levelup-card-selection { - display: flex; - flex-wrap: wrap; - gap: 40px; - - .card-preview-container { - width: calc(100% * (1 / 5)); - } - - .levelup-domains-selection-container { - display: flex; - flex-direction: column; - gap: 8px; - - .levelup-domain-selection-container { - display: flex; - flex-direction: column; - align-items: center; - flex: 1; - position: relative; - cursor: pointer; - - &.disabled { - pointer-events: none; - opacity: 0.4; - } - - .levelup-domain-label { - position: absolute; - text-align: center; - top: 4px; - background: grey; - padding: 0 12px; - border-radius: 6px; - } - - img { - height: 124px; - } - - .levelup-domain-selected { - position: absolute; - height: 54px; - width: 54px; - border-radius: 50%; - border: 2px solid; - font-size: 48px; - display: flex; - align-items: center; - justify-content: center; - background-image: url(../assets/parchments/dh-parchment-light.png); - color: var(--color-dark-5); - top: calc(50% - 29px); - - i { - position: relative; - right: 2px; - } - } - } - } - } - - .levelup-selections-title { - display: flex; - align-items: center; - gap: 4px; - } - - .levelup-radio-choices { - display: flex; - gap: 8px; - - label { - flex: 0; - } - } - } -} +.daggerheart.levelup { + .levelup-selections-container { + .achievement-experience-cards { + display: flex; + gap: 8px; + + .achievement-experience-card { + border: 1px solid; + border-radius: 4px; + padding-right: 4px; + font-size: 18px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; + + .achievement-experience-marker { + border: 1px solid; + border-radius: 50%; + height: 18px; + width: 18px; + display: flex; + align-items: center; + justify-content: center; + font-size: 12px; + } + } + } + + .levelup-card-selection { + display: flex; + flex-wrap: wrap; + gap: 40px; + + .card-preview-container { + width: calc(100% * (1 / 5)); + } + + .levelup-domains-selection-container { + display: flex; + flex-direction: column; + gap: 8px; + + .levelup-domain-selection-container { + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + position: relative; + cursor: pointer; + + &.disabled { + pointer-events: none; + opacity: 0.4; + } + + .levelup-domain-label { + position: absolute; + text-align: center; + top: 4px; + background: grey; + padding: 0 12px; + border-radius: 6px; + } + + img { + height: 124px; + } + + .levelup-domain-selected { + position: absolute; + height: 54px; + width: 54px; + border-radius: 50%; + border: 2px solid; + font-size: 48px; + display: flex; + align-items: center; + justify-content: center; + background-image: url(../assets/parchments/dh-parchment-light.png); + color: var(--color-dark-5); + top: calc(50% - 29px); + + i { + position: relative; + right: 2px; + } + } + } + } + } + + .levelup-selections-title { + display: flex; + align-items: center; + gap: 4px; + } + + .levelup-radio-choices { + display: flex; + gap: 8px; + + label { + flex: 0; + } + } + } +} diff --git a/styles/less/dialog/level-up/sheet.less b/styles/less/dialog/level-up/sheet.less index 77e7244d..2f89034c 100644 --- a/styles/less/dialog/level-up/sheet.less +++ b/styles/less/dialog/level-up/sheet.less @@ -1,37 +1,37 @@ -@import '../../utils/mixin.less'; - -.appTheme({}, { - &.levelup { - .tiers-container { - .tier-container { - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - } -}); - -.daggerheart.levelup { - .window-content { - max-height: 960px; - overflow: auto; - } - - div[data-application-part='form'] { - display: flex; - flex-direction: column; - gap: 8px; - } - - section { - .section-container { - display: flex; - flex-direction: column; - gap: 8px; - margin-top: 8px; - } - } - - .levelup-footer { - display: flex; - } -} +@import '../../utils/mixin.less'; + +.appTheme({}, { + &.levelup { + .tiers-container { + .tier-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + } +}); + +.daggerheart.levelup { + .window-content { + max-height: 960px; + overflow: auto; + } + + div[data-application-part='form'] { + display: flex; + flex-direction: column; + gap: 8px; + } + + section { + .section-container { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 8px; + } + } + + .levelup-footer { + display: flex; + } +} diff --git a/styles/less/dialog/level-up/summary-container.less b/styles/less/dialog/level-up/summary-container.less index fb221b07..fbaa783e 100644 --- a/styles/less/dialog/level-up/summary-container.less +++ b/styles/less/dialog/level-up/summary-container.less @@ -1,37 +1,37 @@ -.daggerheart.levelup { - .levelup-summary-container { - .level-achievements-container, - .level-advancements-container { - display: flex; - flex-direction: column; - gap: 8px; - - h2, - h3, - h4, - h5 { - margin: 0; - color: var(--color-text-secondary); - } - } - - .increase-container { - display: flex; - align-items: center; - gap: 4px; - font-size: 20px; - } - - .summary-selection-container { - display: flex; - gap: 8px; - - .summary-selection { - border: 2px solid; - border-radius: 6px; - padding: 0 4px; - font-size: 18px; - } - } - } -} +.daggerheart.levelup { + .levelup-summary-container { + .level-achievements-container, + .level-advancements-container { + display: flex; + flex-direction: column; + gap: 8px; + + h2, + h3, + h4, + h5 { + margin: 0; + color: var(--color-text-secondary); + } + } + + .increase-container { + display: flex; + align-items: center; + gap: 4px; + font-size: 20px; + } + + .summary-selection-container { + display: flex; + gap: 8px; + + .summary-selection { + border: 2px solid; + border-radius: 6px; + padding: 0 4px; + font-size: 18px; + } + } + } +} diff --git a/styles/less/dialog/level-up/tiers-container.less b/styles/less/dialog/level-up/tiers-container.less index e666b128..bf270fe9 100644 --- a/styles/less/dialog/level-up/tiers-container.less +++ b/styles/less/dialog/level-up/tiers-container.less @@ -1,65 +1,65 @@ -.daggerheart.levelup { - .tiers-container { - display: flex; - gap: 16px; - - .tier-container { - flex: 1; - display: flex; - flex-direction: column; - gap: 8px; - background-image: url('../assets/parchments/dh-parchment-dark.png'); - - &.inactive { - opacity: 0.4; - pointer-events: none; - } - - legend { - margin-left: auto; - margin-right: auto; - font-size: 22px; - font-weight: bold; - padding: 0 12px; - } - - .checkbox-group-container { - display: grid; - grid-template-columns: 1fr 3fr; - gap: 4px; - - .checkboxes-container { - display: flex; - justify-content: end; - gap: 4px; - - .checkbox-grouping-coontainer { - display: flex; - height: min-content; - - &.multi { - border: 2px solid grey; - padding: 2.4px 2.5px 0; - border-radius: 4px; - gap: 2px; - - .selection-checkbox { - margin-left: 0; - margin-right: 0; - } - } - - .selection-checkbox { - margin: 0; - } - } - } - - .checkbox-group-label { - font-size: 14px; - font-style: italic; - } - } - } - } -} +.daggerheart.levelup { + .tiers-container { + display: flex; + gap: 16px; + + .tier-container { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; + background-image: url('../assets/parchments/dh-parchment-dark.png'); + + &.inactive { + opacity: 0.4; + pointer-events: none; + } + + legend { + margin-left: auto; + margin-right: auto; + font-size: 22px; + font-weight: bold; + padding: 0 12px; + } + + .checkbox-group-container { + display: grid; + grid-template-columns: 1fr 3fr; + gap: 4px; + + .checkboxes-container { + display: flex; + justify-content: end; + gap: 4px; + + .checkbox-grouping-coontainer { + display: flex; + height: min-content; + + &.multi { + border: 2px solid grey; + padding: 2.4px 2.5px 0; + border-radius: 4px; + gap: 2px; + + .selection-checkbox { + margin-left: 0; + margin-right: 0; + } + } + + .selection-checkbox { + margin: 0; + } + } + } + + .checkbox-group-label { + font-size: 14px; + font-style: italic; + } + } + } + } +} diff --git a/styles/less/global/index.less b/styles/less/global/index.less index 461813c1..0559c7ff 100644 --- a/styles/less/global/index.less +++ b/styles/less/global/index.less @@ -1,14 +1,14 @@ -@import './sheet.less'; -@import './dialog.less'; -@import './elements.less'; -@import './tab-navigation.less'; -@import './tab-form-footer.less'; -@import './tab-actions.less'; -@import './tab-features.less'; -@import './tab-effects.less'; -@import './item-header.less'; -@import './feature-section.less'; -@import './inventory-item.less'; -@import './inventory-fieldset-items.less'; -@import './prose-mirror.less'; -@import './filter-menu.less'; +@import './sheet.less'; +@import './dialog.less'; +@import './elements.less'; +@import './tab-navigation.less'; +@import './tab-form-footer.less'; +@import './tab-actions.less'; +@import './tab-features.less'; +@import './tab-effects.less'; +@import './item-header.less'; +@import './feature-section.less'; +@import './inventory-item.less'; +@import './inventory-fieldset-items.less'; +@import './prose-mirror.less'; +@import './filter-menu.less'; diff --git a/styles/less/sheets-settings/adversary-settings/experiences.less b/styles/less/sheets-settings/adversary-settings/experiences.less index 36fe85cb..89a7c2d9 100644 --- a/styles/less/sheets-settings/adversary-settings/experiences.less +++ b/styles/less/sheets-settings/adversary-settings/experiences.less @@ -1,28 +1,28 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog { - .tab.experiences { - .add-experience-btn { - width: 100%; - margin-bottom: 12px; - } - - .experience-list { - display: flex; - flex-direction: column; - gap: 10px; - - .experience-item { - display: grid; - grid-template-columns: 3fr 1fr 30px; - align-items: center; - gap: 5px; - - a { - text-align: center; - } - } - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog { + .tab.experiences { + .add-experience-btn { + width: 100%; + margin-bottom: 12px; + } + + .experience-list { + display: flex; + flex-direction: column; + gap: 10px; + + .experience-item { + display: grid; + grid-template-columns: 3fr 1fr 30px; + align-items: center; + gap: 5px; + + a { + text-align: center; + } + } + } + } +} diff --git a/styles/less/sheets-settings/adversary-settings/sheet.less b/styles/less/sheets-settings/adversary-settings/sheet.less index 5fd80b60..b4b0683b 100644 --- a/styles/less/sheets-settings/adversary-settings/sheet.less +++ b/styles/less/sheets-settings/adversary-settings/sheet.less @@ -1,18 +1,18 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog { - .tab { - &.details.active, - &.attack.active { - display: flex; - flex-direction: column; - gap: 16px; - } - - .fieldsets-section { - display: flex; - gap: 16px; - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog { + .tab { + &.details.active, + &.attack.active { + display: flex; + flex-direction: column; + gap: 16px; + } + + .fieldsets-section { + display: flex; + gap: 16px; + } + } +} diff --git a/styles/less/sheets-settings/environment-settings/adversaries.less b/styles/less/sheets-settings/environment-settings/adversaries.less index a60314ff..ba8cc8e4 100644 --- a/styles/less/sheets-settings/environment-settings/adversaries.less +++ b/styles/less/sheets-settings/environment-settings/adversaries.less @@ -1,50 +1,50 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog { - .tab.adversaries { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(@dark-blue, @golden) transparent; - - .add-action-btn { - width: 100%; - margin-bottom: 12px; - } - - .category-container { - display: flex; - flex-direction: column; - align-items: start; - gap: 8px; - - .category-name { - display: flex; - align-items: center; - gap: 10px; - width: 100%; - } - - .adversaries-container { - display: flex; - flex-direction: column; - gap: 6px; - width: 100%; - } - } - - .adversaries-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - border: 1px dashed light-dark(@dark-blue-50, @beige-50); - border-radius: 3px; - color: light-dark(@dark-blue-50, @beige-50); - font-family: @font-body; - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog { + .tab.adversaries { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; + + .add-action-btn { + width: 100%; + margin-bottom: 12px; + } + + .category-container { + display: flex; + flex-direction: column; + align-items: start; + gap: 8px; + + .category-name { + display: flex; + align-items: center; + gap: 10px; + width: 100%; + } + + .adversaries-container { + display: flex; + flex-direction: column; + gap: 6px; + width: 100%; + } + } + + .adversaries-dragger { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + border: 1px dashed light-dark(@dark-blue-50, @beige-50); + border-radius: 3px; + color: light-dark(@dark-blue-50, @beige-50); + font-family: @font-body; + } + } +} diff --git a/styles/less/sheets-settings/header.less b/styles/less/sheets-settings/header.less index 209037ef..6ac2663f 100644 --- a/styles/less/sheets-settings/header.less +++ b/styles/less/sheets-settings/header.less @@ -1,20 +1,20 @@ -@import '../utils/colors.less'; -@import '../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog { - .window-content { - .dialog-header { - width: 100%; - padding-bottom: 16px; - h1 { - font-family: @font-subtitle; - font-style: normal; - font-weight: 700; - font-size: 24px; - margin: 0; - text-align: center; - color: light-dark(@dark-blue, @golden); - } - } - } -} +@import '../utils/colors.less'; +@import '../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog { + .window-content { + .dialog-header { + width: 100%; + padding-bottom: 16px; + h1 { + font-family: @font-subtitle; + font-style: normal; + font-weight: 700; + font-size: 24px; + margin: 0; + text-align: center; + color: light-dark(@dark-blue, @golden); + } + } + } +} diff --git a/styles/less/sheets-settings/index.less b/styles/less/sheets-settings/index.less index 77fa6d94..e7818326 100644 --- a/styles/less/sheets-settings/index.less +++ b/styles/less/sheets-settings/index.less @@ -1,7 +1,7 @@ -@import './header.less'; -@import './adversary-settings/sheet.less'; -@import './adversary-settings/experiences.less'; -@import './adversary-settings/features.less'; - -@import './environment-settings/features.less'; -@import './environment-settings/adversaries.less'; \ No newline at end of file +@import './header.less'; +@import './adversary-settings/sheet.less'; +@import './adversary-settings/experiences.less'; +@import './adversary-settings/features.less'; + +@import './environment-settings/features.less'; +@import './environment-settings/adversaries.less'; diff --git a/styles/less/sheets/actors/adversary/header.less b/styles/less/sheets/actors/adversary/header.less index 9ba00355..a8646a0a 100644 --- a/styles/less/sheets/actors/adversary/header.less +++ b/styles/less/sheets/actors/adversary/header.less @@ -1,80 +1,80 @@ -@import '../../../utils/colors.less'; -@import '../../../utils/fonts.less'; - -.application.sheet.daggerheart.actor.dh-style.adversary { - .adversary-header-sheet { - padding: 0 15px; - padding-top: 36px; - width: 100%; - - .name-row { - display: flex; - gap: 5px; - align-items: center; - justify-content: space-between; - padding: 0; - padding-top: 5px; - padding-bottom: 8px; - flex: 1; - - input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - border: 1px solid transparent; - outline: 2px solid transparent; - transition: all 0.3s ease; - - &:hover { - outline: 2px solid light-dark(@dark, @golden); - } - } - } - - .tags { - display: flex; - gap: 10px; - padding-bottom: 16px; - - .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - font: @font-body; - - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; - } - } - - .adversary-info { - display: flex; - flex-direction: column; - gap: 12px; - padding: 16px 0; - - .description, - .motives-and-tatics { - font-family: @font-body; - } - } - - .adversary-navigation { - display: flex; - gap: 8px; - align-items: center; - } - } -} +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; + +.application.sheet.daggerheart.actor.dh-style.adversary { + .adversary-header-sheet { + padding: 0 15px; + padding-top: 36px; + width: 100%; + + .name-row { + display: flex; + gap: 5px; + align-items: center; + justify-content: space-between; + padding: 0; + padding-top: 5px; + padding-bottom: 8px; + flex: 1; + + input[type='text'] { + font-size: 32px; + height: 42px; + text-align: start; + border: 1px solid transparent; + outline: 2px solid transparent; + transition: all 0.3s ease; + + &:hover { + outline: 2px solid light-dark(@dark, @golden); + } + } + } + + .tags { + display: flex; + gap: 10px; + padding-bottom: 16px; + + .tag { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 3px 5px; + font-size: 12px; + font: @font-body; + + background: light-dark(@dark-15, @beige-15); + border: 1px solid light-dark(@dark, @beige); + border-radius: 3px; + } + + .label { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + font-size: 12px; + } + } + + .adversary-info { + display: flex; + flex-direction: column; + gap: 12px; + padding: 16px 0; + + .description, + .motives-and-tatics { + font-family: @font-body; + } + } + + .adversary-navigation { + display: flex; + gap: 8px; + align-items: center; + } + } +} diff --git a/styles/less/sheets/actors/adversary/sheet.less b/styles/less/sheets/actors/adversary/sheet.less index baa80bb3..af7918c6 100644 --- a/styles/less/sheets/actors/adversary/sheet.less +++ b/styles/less/sheets/actors/adversary/sheet.less @@ -1,28 +1,28 @@ -@import '../../../utils/colors.less'; -@import '../../../utils/fonts.less'; - -.application.sheet.daggerheart.actor.dh-style.adversary { - .window-content { - display: grid; - grid-template-columns: 275px 1fr; - grid-template-rows: auto 1fr; - gap: 15px 0; - height: 100%; - width: 100%; - - .adversary-sidebar-sheet { - grid-row: 1 / span 2; - grid-column: 1; - } - - .adversary-header-sheet { - grid-row: 1; - grid-column: 2; - } - - .tab { - grid-row: 2; - grid-column: 2; - } - } -} +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; + +.application.sheet.daggerheart.actor.dh-style.adversary { + .window-content { + display: grid; + grid-template-columns: 275px 1fr; + grid-template-rows: auto 1fr; + gap: 15px 0; + height: 100%; + width: 100%; + + .adversary-sidebar-sheet { + grid-row: 1 / span 2; + grid-column: 1; + } + + .adversary-header-sheet { + grid-row: 1; + grid-column: 2; + } + + .tab { + grid-row: 2; + grid-column: 2; + } + } +} diff --git a/styles/less/sheets/actors/adversary/sidebar.less b/styles/less/sheets/actors/adversary/sidebar.less index 1dabf5ae..e50ba0c9 100644 --- a/styles/less/sheets/actors/adversary/sidebar.less +++ b/styles/less/sheets/actors/adversary/sidebar.less @@ -1,351 +1,351 @@ -@import '../../../utils/colors.less'; -@import '../../../utils/fonts.less'; -@import '../../../utils/mixin.less'; - -.appTheme({ - &.adversary { - .adversary-sidebar-sheet { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -}, { - &.adversary { - .adversary-sidebar-sheet { - background: transparent; - } - } -}); - -.application.sheet.daggerheart.actor.dh-style.adversary { - .adversary-sidebar-sheet { - width: 275px; - min-width: 275px; - border-right: 1px solid light-dark(@dark-blue, @golden); - - .portrait { - position: relative; - border-bottom: 1px solid light-dark(@dark-blue, @golden); - cursor: pointer; - - img { - height: 235px; - width: 275px; - object-fit: cover; - } - - .death-roll-btn { - display: none; - } - - &.death-roll { - filter: grayscale(1); - - .death-roll-btn { - display: flex; - position: absolute; - top: 30%; - right: 30%; - font-size: 6rem; - color: @beige; - - &:hover { - text-shadow: 0 0 8px @beige; - } - } - } - } - - .threshold-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; - margin-top: 16px; - - h4 { - font-size: 14px; - font-weight: bold; - text-transform: uppercase; - color: light-dark(@dark-blue, @golden); - - &.threshold-value { - color: light-dark(@dark, @beige); - } - } - - .threshold-legend { - position: absolute; - bottom: -21px; - color: light-dark(@golden, @dark-blue); - background-color: light-dark(@dark-blue, @golden); - padding: 3px; - justify-self: anchor-center; - border-radius: 0 0 3px 3px; - text-transform: capitalize; - } - - .hope-value { - display: flex; - cursor: pointer; - } - } - - .info-section { - position: relative; - display: flex; - flex-direction: column; - top: -20px; - gap: 16px; - margin-bottom: -10px; - - .resources-section { - display: flex; - justify-content: space-evenly; - - .status-bar { - position: relative; - width: 100px; - height: 40px; - justify-items: center; - - .status-label { - position: relative; - top: 40px; - height: 22px; - width: 79px; - clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - color: light-dark(@beige, @dark-blue); - } - } - .status-value { - position: absolute; - display: flex; - padding: 0 6px; - font-size: 1.5rem; - align-items: center; - width: 100px; - height: 40px; - justify-content: center; - text-align: center; - z-index: 2; - color: @beige; - - input[type='number'] { - background: transparent; - font-size: 1.5rem; - width: 40px; - height: 30px; - text-align: center; - border: none; - outline: 2px solid transparent; - color: @beige; - - &.bar-input { - padding: 0; - color: @beige; - backdrop-filter: none; - background: transparent; - transition: all 0.3s ease; - - &:hover, - &:focus { - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9.5px); - } - } - } - - .bar-label { - width: 40px; - } - } - .progress-bar { - position: absolute; - appearance: none; - width: 100px; - height: 40px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - z-index: 1; - background: @dark-blue; - - &::-webkit-progress-bar { - border: none; - background: @dark-blue; - border-radius: 6px; - } - &::-webkit-progress-value { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-webkit-progress-value { - background: @gradient-stress; - border-radius: 6px; - } - &::-moz-progress-bar { - background: @gradient-hp; - border-radius: 6px; - } - &.stress-color::-moz-progress-bar { - background: @gradient-stress; - border-radius: 6px; - } - } - } - } - - .status-section { - display: flex; - flex-wrap: wrap; - gap: 10px; - justify-content: center; - - .status-number { - justify-items: center; - - .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(@dark-blue, @golden); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, @dark-blue); - z-index: 2; - - &.armor-slots { - width: 80px; - height: 30px; - } - } - - .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(@beige, @dark-blue); - } - } - } - } - } - - .items-sidebar-list { - display: flex; - flex-direction: column; - gap: 5px; - - .inventory-item { - padding: 0 10px; - } - } - - .attack-section { - .title { - display: flex; - gap: 15px; - align-items: center; - - h3 { - font-size: 20px; - } - } - .items-list { - display: flex; - flex-direction: column; - gap: 10px; - align-items: center; - } - } - - .experience-section { - margin-bottom: 20px; - - .title { - display: flex; - gap: 15px; - align-items: center; - - h3 { - font-size: 20px; - } - } - - .experience-list { - display: flex; - flex-direction: column; - gap: 5px; - width: 100%; - margin-top: 10px; - align-items: center; - - .experience-row { - display: flex; - gap: 5px; - width: 250px; - align-items: center; - justify-content: space-between; - - .experience-name { - width: 180px; - text-align: start; - font-size: 14px; - font-family: @font-body; - color: light-dark(@dark, @beige); - } - } - - .experience-value { - height: 25px; - width: 35px; - font-size: 14px; - font-family: @font-body; - color: light-dark(@dark, @beige); - align-content: center; - text-align: center; - background: url(../assets/svg/experience-shield.svg) no-repeat; - - .theme-light & { - background: url('../assets/svg/experience-shield-light.svg') no-repeat; - } - } - } - } - - .reaction-section { - display: flex; - padding: 0 10px; - margin-top: 20px; - width: 100%; - - button { - width: 100%; - } - } - } -} +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; + +.appTheme({ + &.adversary { + .adversary-sidebar-sheet { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}, { + &.adversary { + .adversary-sidebar-sheet { + background: transparent; + } + } +}); + +.application.sheet.daggerheart.actor.dh-style.adversary { + .adversary-sidebar-sheet { + width: 275px; + min-width: 275px; + border-right: 1px solid light-dark(@dark-blue, @golden); + + .portrait { + position: relative; + border-bottom: 1px solid light-dark(@dark-blue, @golden); + cursor: pointer; + + img { + height: 235px; + width: 275px; + object-fit: cover; + } + + .death-roll-btn { + display: none; + } + + &.death-roll { + filter: grayscale(1); + + .death-roll-btn { + display: flex; + position: absolute; + top: 30%; + right: 30%; + font-size: 6rem; + color: @beige; + + &:hover { + text-shadow: 0 0 8px @beige; + } + } + } + } + + .threshold-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; + margin-top: 16px; + + h4 { + font-size: 14px; + font-weight: bold; + text-transform: uppercase; + color: light-dark(@dark-blue, @golden); + + &.threshold-value { + color: light-dark(@dark, @beige); + } + } + + .threshold-legend { + position: absolute; + bottom: -21px; + color: light-dark(@golden, @dark-blue); + background-color: light-dark(@dark-blue, @golden); + padding: 3px; + justify-self: anchor-center; + border-radius: 0 0 3px 3px; + text-transform: capitalize; + } + + .hope-value { + display: flex; + cursor: pointer; + } + } + + .info-section { + position: relative; + display: flex; + flex-direction: column; + top: -20px; + gap: 16px; + margin-bottom: -10px; + + .resources-section { + display: flex; + justify-content: space-evenly; + + .status-bar { + position: relative; + width: 100px; + height: 40px; + justify-items: center; + + .status-label { + position: relative; + top: 40px; + height: 22px; + width: 79px; + clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); + background: light-dark(@dark-blue, @golden); + + h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + color: light-dark(@beige, @dark-blue); + } + } + .status-value { + position: absolute; + display: flex; + padding: 0 6px; + font-size: 1.5rem; + align-items: center; + width: 100px; + height: 40px; + justify-content: center; + text-align: center; + z-index: 2; + color: @beige; + + input[type='number'] { + background: transparent; + font-size: 1.5rem; + width: 40px; + height: 30px; + text-align: center; + border: none; + outline: 2px solid transparent; + color: @beige; + + &.bar-input { + padding: 0; + color: @beige; + backdrop-filter: none; + background: transparent; + transition: all 0.3s ease; + + &:hover, + &:focus { + background: @semi-transparent-dark-blue; + backdrop-filter: blur(9.5px); + } + } + } + + .bar-label { + width: 40px; + } + } + .progress-bar { + position: absolute; + appearance: none; + width: 100px; + height: 40px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + z-index: 1; + background: @dark-blue; + + &::-webkit-progress-bar { + border: none; + background: @dark-blue; + border-radius: 6px; + } + &::-webkit-progress-value { + background: @gradient-hp; + border-radius: 6px; + } + &.stress-color::-webkit-progress-value { + background: @gradient-stress; + border-radius: 6px; + } + &::-moz-progress-bar { + background: @gradient-hp; + border-radius: 6px; + } + &.stress-color::-moz-progress-bar { + background: @gradient-stress; + border-radius: 6px; + } + } + } + } + + .status-section { + display: flex; + flex-wrap: wrap; + gap: 10px; + justify-content: center; + + .status-number { + justify-items: center; + + .status-value { + position: relative; + display: flex; + width: 50px; + height: 30px; + border: 1px solid light-dark(@dark-blue, @golden); + border-bottom: none; + border-radius: 6px 6px 0 0; + padding: 0 6px; + font-size: 1.2rem; + align-items: center; + justify-content: center; + background: light-dark(transparent, @dark-blue); + z-index: 2; + + &.armor-slots { + width: 80px; + height: 30px; + } + } + + .status-label { + padding: 2px 10px; + width: 100%; + border-radius: 3px; + background: light-dark(@dark-blue, @golden); + + h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + font-size: 12px; + color: light-dark(@beige, @dark-blue); + } + } + } + } + } + + .items-sidebar-list { + display: flex; + flex-direction: column; + gap: 5px; + + .inventory-item { + padding: 0 10px; + } + } + + .attack-section { + .title { + display: flex; + gap: 15px; + align-items: center; + + h3 { + font-size: 20px; + } + } + .items-list { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + } + } + + .experience-section { + margin-bottom: 20px; + + .title { + display: flex; + gap: 15px; + align-items: center; + + h3 { + font-size: 20px; + } + } + + .experience-list { + display: flex; + flex-direction: column; + gap: 5px; + width: 100%; + margin-top: 10px; + align-items: center; + + .experience-row { + display: flex; + gap: 5px; + width: 250px; + align-items: center; + justify-content: space-between; + + .experience-name { + width: 180px; + text-align: start; + font-size: 14px; + font-family: @font-body; + color: light-dark(@dark, @beige); + } + } + + .experience-value { + height: 25px; + width: 35px; + font-size: 14px; + font-family: @font-body; + color: light-dark(@dark, @beige); + align-content: center; + text-align: center; + background: url(../assets/svg/experience-shield.svg) no-repeat; + + .theme-light & { + background: url('../assets/svg/experience-shield-light.svg') no-repeat; + } + } + } + } + + .reaction-section { + display: flex; + padding: 0 10px; + margin-top: 20px; + width: 100%; + + button { + width: 100%; + } + } + } +} diff --git a/styles/less/sheets/actors/environment/header.less b/styles/less/sheets/actors/environment/header.less index 87be3314..e3ca0eec 100644 --- a/styles/less/sheets/actors/environment/header.less +++ b/styles/less/sheets/actors/environment/header.less @@ -1,140 +1,140 @@ -@import '../../../utils/colors.less'; -@import '../../../utils/fonts.less'; - -.application.sheet.daggerheart.actor.dh-style.environment { - .environment-header-sheet { - display: flex; - flex-direction: column; - justify-content: start; - text-align: center; - - .profile { - width: 100%; - height: 235px; - object-fit: cover; - mask-image: linear-gradient(0deg, transparent 0%, black 10%); - cursor: pointer; - } - - .item-container { - display: flex; - align-items: center; - position: relative; - top: -45px; - gap: 20px; - padding: 0 20px; - margin-bottom: -30px; - - .item-info { - display: flex; - flex-direction: column; - gap: 8px; - - .tags { - display: flex; - gap: 10px; - padding-bottom: 0; - - .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - font: @font-body; - - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; - } - } - } - - .status-number { - justify-items: center; - - .status-value { - position: relative; - display: flex; - width: 50px; - height: 30px; - border: 1px solid light-dark(@dark-blue, @golden); - border-bottom: none; - border-radius: 6px 6px 0 0; - padding: 0 6px; - font-size: 1.2rem; - align-items: center; - justify-content: center; - background: light-dark(transparent, @dark-blue); - z-index: 2; - - &.armor-slots { - width: 80px; - height: 30px; - } - } - - .status-label { - padding: 2px 10px; - width: 100%; - border-radius: 3px; - background: light-dark(@dark-blue, @golden); - - h4 { - font-weight: bold; - text-align: center; - line-height: 18px; - font-size: 12px; - color: light-dark(@beige, @dark-blue); - } - } - } - - .item-name { - input[type='text'] { - font-size: 32px; - height: 42px; - text-align: start; - transition: all 0.3s ease; - outline: 2px solid transparent; - border: 1px solid transparent; - - &:hover[type='text'], - &:focus[type='text'] { - box-shadow: none; - outline: 2px solid light-dark(@dark-blue, @golden); - } - } - } - } - - .environment-info { - display: flex; - flex-direction: column; - gap: 12px; - padding: 10px 20px; - - .description, - .impulses { - text-align: start; - font-family: @font-body; - } - } - - .environment-navigation { - display: flex; - gap: 20px; - align-items: center; - padding: 0 20px; - } - } -} +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; + +.application.sheet.daggerheart.actor.dh-style.environment { + .environment-header-sheet { + display: flex; + flex-direction: column; + justify-content: start; + text-align: center; + + .profile { + width: 100%; + height: 235px; + object-fit: cover; + mask-image: linear-gradient(0deg, transparent 0%, black 10%); + cursor: pointer; + } + + .item-container { + display: flex; + align-items: center; + position: relative; + top: -45px; + gap: 20px; + padding: 0 20px; + margin-bottom: -30px; + + .item-info { + display: flex; + flex-direction: column; + gap: 8px; + + .tags { + display: flex; + gap: 10px; + padding-bottom: 0; + + .tag { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 3px 5px; + font-size: 12px; + font: @font-body; + + background: light-dark(@dark-15, @beige-15); + border: 1px solid light-dark(@dark, @beige); + border-radius: 3px; + } + + .label { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + font-size: 12px; + } + } + } + + .status-number { + justify-items: center; + + .status-value { + position: relative; + display: flex; + width: 50px; + height: 30px; + border: 1px solid light-dark(@dark-blue, @golden); + border-bottom: none; + border-radius: 6px 6px 0 0; + padding: 0 6px; + font-size: 1.2rem; + align-items: center; + justify-content: center; + background: light-dark(transparent, @dark-blue); + z-index: 2; + + &.armor-slots { + width: 80px; + height: 30px; + } + } + + .status-label { + padding: 2px 10px; + width: 100%; + border-radius: 3px; + background: light-dark(@dark-blue, @golden); + + h4 { + font-weight: bold; + text-align: center; + line-height: 18px; + font-size: 12px; + color: light-dark(@beige, @dark-blue); + } + } + } + + .item-name { + input[type='text'] { + font-size: 32px; + height: 42px; + text-align: start; + transition: all 0.3s ease; + outline: 2px solid transparent; + border: 1px solid transparent; + + &:hover[type='text'], + &:focus[type='text'] { + box-shadow: none; + outline: 2px solid light-dark(@dark-blue, @golden); + } + } + } + } + + .environment-info { + display: flex; + flex-direction: column; + gap: 12px; + padding: 10px 20px; + + .description, + .impulses { + text-align: start; + font-family: @font-body; + } + } + + .environment-navigation { + display: flex; + gap: 20px; + align-items: center; + padding: 0 20px; + } + } +} diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index cbee35ac..89370ec6 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -1,23 +1,23 @@ -@import './actors/adversary/actions.less'; -@import './actors/adversary/header.less'; -@import './actors/adversary/sheet.less'; -@import './actors/adversary/sidebar.less'; - -@import './actors/character/biography.less'; -@import './actors/character/features.less'; -@import './actors/character/header.less'; -@import './actors/character/inventory.less'; -@import './actors/character/loadout.less'; -@import './actors/character/sheet.less'; -@import './actors/character/sidebar.less'; - -@import './actors/companion/details.less'; -@import './actors/companion/header.less'; -@import './actors/companion/sheet.less'; - -@import './actors/environment/header.less'; -@import './actors/environment/sheet.less'; - -@import './items/class.less'; -@import './items/domain-card.less'; -@import './items/feature.less'; +@import './actors/adversary/actions.less'; +@import './actors/adversary/header.less'; +@import './actors/adversary/sheet.less'; +@import './actors/adversary/sidebar.less'; + +@import './actors/character/biography.less'; +@import './actors/character/features.less'; +@import './actors/character/header.less'; +@import './actors/character/inventory.less'; +@import './actors/character/loadout.less'; +@import './actors/character/sheet.less'; +@import './actors/character/sidebar.less'; + +@import './actors/companion/details.less'; +@import './actors/companion/header.less'; +@import './actors/companion/sheet.less'; + +@import './actors/environment/header.less'; +@import './actors/environment/sheet.less'; + +@import './items/class.less'; +@import './items/domain-card.less'; +@import './items/feature.less'; diff --git a/styles/less/ui/chat/sheet.less b/styles/less/ui/chat/sheet.less index 683b91f1..58281690 100644 --- a/styles/less/ui/chat/sheet.less +++ b/styles/less/ui/chat/sheet.less @@ -1,33 +1,33 @@ -.chat-message { - .duality-modifiers, - .duality-result, - .dice-title { - display: none; - } -} - -fieldset.daggerheart.chat { - padding: 0; - border-left-width: 0; - border-right-width: 0; - border-bottom-width: 0; - legend { - display: flex; - align-items: center; - gap: 5px; - &:before, - &:after { - content: '\f0d8'; - font-family: 'Font Awesome 6 Pro'; - } - } - &.expanded { - legend:before, - legend:after { - content: '\f0d7'; - } - } - .daggerheart.chat { - margin-top: 5px; - } -} +.chat-message { + .duality-modifiers, + .duality-result, + .dice-title { + display: none; + } +} + +fieldset.daggerheart.chat { + padding: 0; + border-left-width: 0; + border-right-width: 0; + border-bottom-width: 0; + legend { + display: flex; + align-items: center; + gap: 5px; + &:before, + &:after { + content: '\f0d8'; + font-family: 'Font Awesome 6 Pro'; + } + } + &.expanded { + legend:before, + legend:after { + content: '\f0d7'; + } + } + .daggerheart.chat { + margin-top: 5px; + } +} diff --git a/styles/less/ui/chat/theme-colorful.less b/styles/less/ui/chat/theme-colorful.less index adbbc5ca..d9c4e08e 100644 --- a/styles/less/ui/chat/theme-colorful.less +++ b/styles/less/ui/chat/theme-colorful.less @@ -1,193 +1,193 @@ -@import '../../utils/colors.less'; -@import '../../utils/spacing.less'; - -.theme-colorful { - .chat-message.duality { - border-color: black; - padding: 8px 0 0 0; - fieldset.daggerheart.chat { - border-top-width: 0; - display: contents; - legend { - &:before, - &:after { - display: none; - } - } - } - .message-header { - color: var(--color-light-3); - padding: 0 8px; - } - &.hope { - background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); - } - &.fear { - background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart); - } - &.critical { - background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart); - } - .chat-message header { - color: var(--color-light-3); - } - > * { - padding: 0 8px; - } - .message-content { - .duality-modifiers, - .duality-result, - .dice-title { - display: flex; - } - .duality-modifiers { - display: flex; - gap: 2px; - margin-bottom: 4px; - .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; - } - } - .dice-flavor { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - border-bottom: 1px solid; - display: flex; - align-items: end; - justify-content: space-between; - padding: 0 8px; - margin: 0 -8px 2px; - font-weight: unset; - } - .dice-result { - .duality-modifiers { - display: flex; // Default => display: none; - gap: 2px; - margin-bottom: 4px; - .duality-modifier { - padding: 2px; - border-radius: 6px; - border: 1px solid; - background: var(--color-dark-6); - font-size: 12px; - } - } - .dice-formula, - > .dice-total, - .part-header { - display: none; - } - .dice-tooltip { - grid-template-rows: 1fr; - .wrapper { - .tooltip-part { - display: flex; - align-items: end; - gap: 0.25rem; - .dice { - .dice-rolls { - margin-bottom: 0; - &.duality { - li { - display: flex; - align-items: center; - justify-content: center; - position: relative; - background: unset; - line-height: unset; - font-weight: unset; - } - } - } - } - .duality-modifier { - display: flex; - margin-bottom: 6px; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-size: var(--font-size-16); - } - } - } - } - .target-selection { - label { - color: var(--color-light-1); - } - } - .target-section { - margin: 4px 0; - border: 2px solid; - margin-top: 5px; - .dice-total { - box-shadow: unset; - border: unset; - border-radius: unset; - font-size: var(--font-size-18); - } - } - .dice-actions { - justify-content: space-between; - &.duality-alone { - justify-content: end; - margin-top: -20px; - } - > * { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - } - .duality-action { - border-radius: 0 6px 0 0; - margin-left: -8px; - &.duality-action-effect { - border-top-left-radius: 6px; - margin-left: initial; - } - } - .duality-result { - border-radius: 6px 0 0 0; - margin-right: -8px; - } - } - .duality-result { - display: flex; - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - padding: 4px; - border-color: black; - min-height: unset; - height: 26px; - flex: unset; - margin: 0; - margin-left: auto; - align-self: center; - border-radius: 6px; - } - } - } - button { - &.inner-button { - color: var(--color-light-1); - text-shadow: 0 0 1px black; - font-weight: bold; - background: var(--color-dark-1); - border-color: black; - } - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/spacing.less'; + +.theme-colorful { + .chat-message.duality { + border-color: black; + padding: 8px 0 0 0; + fieldset.daggerheart.chat { + border-top-width: 0; + display: contents; + legend { + &:before, + &:after { + display: none; + } + } + } + .message-header { + color: var(--color-light-3); + padding: 0 8px; + } + &.hope { + background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); + } + &.fear { + background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart); + } + &.critical { + background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart); + } + .chat-message header { + color: var(--color-light-3); + } + > * { + padding: 0 8px; + } + .message-content { + .duality-modifiers, + .duality-result, + .dice-title { + display: flex; + } + .duality-modifiers { + display: flex; + gap: 2px; + margin-bottom: 4px; + .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; + } + } + .dice-flavor { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + border-bottom: 1px solid; + display: flex; + align-items: end; + justify-content: space-between; + padding: 0 8px; + margin: 0 -8px 2px; + font-weight: unset; + } + .dice-result { + .duality-modifiers { + display: flex; // Default => display: none; + gap: 2px; + margin-bottom: 4px; + .duality-modifier { + padding: 2px; + border-radius: 6px; + border: 1px solid; + background: var(--color-dark-6); + font-size: 12px; + } + } + .dice-formula, + > .dice-total, + .part-header { + display: none; + } + .dice-tooltip { + grid-template-rows: 1fr; + .wrapper { + .tooltip-part { + display: flex; + align-items: end; + gap: 0.25rem; + .dice { + .dice-rolls { + margin-bottom: 0; + &.duality { + li { + display: flex; + align-items: center; + justify-content: center; + position: relative; + background: unset; + line-height: unset; + font-weight: unset; + } + } + } + } + .duality-modifier { + display: flex; + margin-bottom: 6px; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-size: var(--font-size-16); + } + } + } + } + .target-selection { + label { + color: var(--color-light-1); + } + } + .target-section { + margin: 4px 0; + border: 2px solid; + margin-top: 5px; + .dice-total { + box-shadow: unset; + border: unset; + border-radius: unset; + font-size: var(--font-size-18); + } + } + .dice-actions { + justify-content: space-between; + &.duality-alone { + justify-content: end; + margin-top: -20px; + } + > * { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; + } + .duality-action { + border-radius: 0 6px 0 0; + margin-left: -8px; + &.duality-action-effect { + border-top-left-radius: 6px; + margin-left: initial; + } + } + .duality-result { + border-radius: 6px 0 0 0; + margin-right: -8px; + } + } + .duality-result { + display: flex; + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + padding: 4px; + border-color: black; + min-height: unset; + height: 26px; + flex: unset; + margin: 0; + margin-left: auto; + align-self: center; + border-radius: 6px; + } + } + } + button { + &.inner-button { + color: var(--color-light-1); + text-shadow: 0 0 1px black; + font-weight: bold; + background: var(--color-dark-1); + border-color: black; + } + } + } +} diff --git a/styles/less/ui/combat-sidebar/combat-sidebar.less b/styles/less/ui/combat-sidebar/combat-sidebar.less index e247e5b4..62da7233 100644 --- a/styles/less/ui/combat-sidebar/combat-sidebar.less +++ b/styles/less/ui/combat-sidebar/combat-sidebar.less @@ -1,6 +1,6 @@ -.combat-sidebar { - h4 { - margin: 0; - text-align: center; - } -} +.combat-sidebar { + h4 { + margin: 0; + text-align: center; + } +} diff --git a/styles/less/ui/combat-sidebar/combatant-controls.less b/styles/less/ui/combat-sidebar/combatant-controls.less index 4a3329d6..ee63a197 100644 --- a/styles/less/ui/combat-sidebar/combatant-controls.less +++ b/styles/less/ui/combat-sidebar/combatant-controls.less @@ -1,5 +1,5 @@ -.combat-sidebar { - .combatant-controls { - flex: 0; - } -} +.combat-sidebar { + .combatant-controls { + flex: 0; + } +} diff --git a/styles/less/ui/combat-sidebar/encounter-controls.less b/styles/less/ui/combat-sidebar/encounter-controls.less index 8a2981b5..58deaae8 100644 --- a/styles/less/ui/combat-sidebar/encounter-controls.less +++ b/styles/less/ui/combat-sidebar/encounter-controls.less @@ -1,48 +1,48 @@ -.combat-sidebar { - .encounter-controls.combat { - justify-content: space-between; - - .encounter-fear-controls { - display: flex; - align-items: center; - gap: 8px; - - .encounter-fear-dice-container { - display: flex; - gap: 2px; - - .encounter-control-fear-container { - display: flex; - position: relative; - align-items: center; - justify-content: center; - color: black; - - .dice { - height: 22px; - width: 22px; - } - - .encounter-control-fear { - position: absolute; - font-size: 16px; - } - - .encounter-control-counter { - position: absolute; - right: -10px; - color: var(--color-text-secondary); - } - } - } - - .encounter-countdowns { - color: var(--content-link-icon-color); - } - } - - .control-buttons { - width: min-content; - } - } -} +.combat-sidebar { + .encounter-controls.combat { + justify-content: space-between; + + .encounter-fear-controls { + display: flex; + align-items: center; + gap: 8px; + + .encounter-fear-dice-container { + display: flex; + gap: 2px; + + .encounter-control-fear-container { + display: flex; + position: relative; + align-items: center; + justify-content: center; + color: black; + + .dice { + height: 22px; + width: 22px; + } + + .encounter-control-fear { + position: absolute; + font-size: 16px; + } + + .encounter-control-counter { + position: absolute; + right: -10px; + color: var(--color-text-secondary); + } + } + } + + .encounter-countdowns { + color: var(--content-link-icon-color); + } + } + + .control-buttons { + width: min-content; + } + } +} diff --git a/styles/less/ui/combat-sidebar/spotlight-control.less b/styles/less/ui/combat-sidebar/spotlight-control.less index 2659cc90..b5efed7a 100644 --- a/styles/less/ui/combat-sidebar/spotlight-control.less +++ b/styles/less/ui/combat-sidebar/spotlight-control.less @@ -1,19 +1,19 @@ -.combat-sidebar { - .spotlight-control { - font-size: 26px; - - &:focus { - outline: none; - box-shadow: none; - } - - &.discrete:hover { - background: inherit; - } - - &.requesting { - filter: drop-shadow(0 0 3px gold); - color: var(--button-hover-text-color); - } - } -} +.combat-sidebar { + .spotlight-control { + font-size: 26px; + + &:focus { + outline: none; + box-shadow: none; + } + + &.discrete:hover { + background: inherit; + } + + &.requesting { + filter: drop-shadow(0 0 3px gold); + color: var(--button-hover-text-color); + } + } +} diff --git a/styles/less/ui/combat-sidebar/token-actions.less b/styles/less/ui/combat-sidebar/token-actions.less index 23be22e8..072381dd 100644 --- a/styles/less/ui/combat-sidebar/token-actions.less +++ b/styles/less/ui/combat-sidebar/token-actions.less @@ -1,48 +1,48 @@ -.combat-sidebar { - .token-actions { - align-self: stretch; - display: flex; - align-items: top; - justify-content: center; - gap: 16px; - - .action-tokens { - display: flex; - gap: 4px; - - .action-token { - height: 22px; - width: 22px; - border: 1px solid; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-size: 10px; - padding: 8px; - --button-size: 0; - - &.used { - opacity: 0.5; - background: transparent; - } - } - } - - button { - font-size: 22px; - height: 24px; - width: 24px; - - &.main { - background: var(--button-hover-background-color); - color: var(--button-hover-text-color); - border-color: var(--button-hover-border-color); - - &:hover { - filter: drop-shadow(0 0 3px var(--button-hover-text-color)); - } - } - } - } -} +.combat-sidebar { + .token-actions { + align-self: stretch; + display: flex; + align-items: top; + justify-content: center; + gap: 16px; + + .action-tokens { + display: flex; + gap: 4px; + + .action-token { + height: 22px; + width: 22px; + border: 1px solid; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 10px; + padding: 8px; + --button-size: 0; + + &.used { + opacity: 0.5; + background: transparent; + } + } + } + + button { + font-size: 22px; + height: 24px; + width: 24px; + + &.main { + background: var(--button-hover-background-color); + color: var(--button-hover-text-color); + border-color: var(--button-hover-border-color); + + &:hover { + filter: drop-shadow(0 0 3px var(--button-hover-text-color)); + } + } + } + } +} diff --git a/styles/less/ui/countdown/sheet.less b/styles/less/ui/countdown/sheet.less index 6a1d2394..1692773e 100644 --- a/styles/less/ui/countdown/sheet.less +++ b/styles/less/ui/countdown/sheet.less @@ -1,88 +1,88 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; -@import '../../utils/mixin.less'; - -.appTheme({}, { - &.countdown { - .minimized-view .mini-countdown-container { - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - } -}); - -.daggerheart.dh-style.countdown { - overflow: hidden; - - .window-content { - > div { - height: 100%; - - .expanded-view { - height: 100%; - display: flex; - flex-direction: column; - - .countdowns-menu { - display: flex; - gap: 8px; - - .flex { - flex: 1; - } - } - - .countdowns-container { - display: flex; - gap: 8px; - flex-wrap: wrap; - overflow: auto; - max-height: 100%; - - .countdown-fieldset { - width: 340px; - height: min-content; - position: relative; - - .ownership-button { - position: absolute; - top: 8px; - right: 8px; - font-size: 18px; - } - - .countdown-container { - display: flex; - align-items: center; - gap: 16px; - - img { - width: 150px; - height: 150px; - cursor: pointer; - - &.disabled { - cursor: initial; - } - } - - .countdown-inner-container { - display: flex; - flex-direction: column; - gap: 4px; - - .countdown-value-container { - display: flex; - gap: 4px; - - input { - max-width: 80px; - } - } - } - } - } - } - } - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; +@import '../../utils/mixin.less'; + +.appTheme({}, { + &.countdown { + .minimized-view .mini-countdown-container { + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + } +}); + +.daggerheart.dh-style.countdown { + overflow: hidden; + + .window-content { + > div { + height: 100%; + + .expanded-view { + height: 100%; + display: flex; + flex-direction: column; + + .countdowns-menu { + display: flex; + gap: 8px; + + .flex { + flex: 1; + } + } + + .countdowns-container { + display: flex; + gap: 8px; + flex-wrap: wrap; + overflow: auto; + max-height: 100%; + + .countdown-fieldset { + width: 340px; + height: min-content; + position: relative; + + .ownership-button { + position: absolute; + top: 8px; + right: 8px; + font-size: 18px; + } + + .countdown-container { + display: flex; + align-items: center; + gap: 16px; + + img { + width: 150px; + height: 150px; + cursor: pointer; + + &.disabled { + cursor: initial; + } + } + + .countdown-inner-container { + display: flex; + flex-direction: column; + gap: 4px; + + .countdown-value-container { + display: flex; + gap: 4px; + + input { + max-width: 80px; + } + } + } + } + } + } + } + } + } +} diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 0227c26b..13e578b0 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -1,18 +1,18 @@ -@import './chat/chat.less'; -@import './chat/sheet.less'; -@import './chat/theme-colorful.less'; - -@import './combat-sidebar/combat-sidebar.less'; -@import './combat-sidebar/combatant-controls.less'; -@import './combat-sidebar/encounter-controls.less'; -@import './combat-sidebar/spotlight-control.less'; -@import './combat-sidebar/token-actions.less'; - -@import './countdown/countdown.less'; -@import './countdown/sheet.less'; - -@import './ownership-selection/ownership-selection.less'; - -@import './resources/resources.less'; - -@import './settings/settings.less'; +@import './chat/chat.less'; +@import './chat/sheet.less'; +@import './chat/theme-colorful.less'; + +@import './combat-sidebar/combat-sidebar.less'; +@import './combat-sidebar/combatant-controls.less'; +@import './combat-sidebar/encounter-controls.less'; +@import './combat-sidebar/spotlight-control.less'; +@import './combat-sidebar/token-actions.less'; + +@import './countdown/countdown.less'; +@import './countdown/sheet.less'; + +@import './ownership-selection/ownership-selection.less'; + +@import './resources/resources.less'; + +@import './settings/settings.less'; From 70239ec06a506558672859ccb17749bb4a449e95 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 10 Jul 2025 13:28:51 +0200 Subject: [PATCH 10/58] [BUG] DiceSoNice fix (#312) * Fixed DiceSoNice integration again * PR fixes * Improved with tertiary --- module/dice/d20Roll.mjs | 8 +------- module/dice/dhRoll.mjs | 2 +- module/dice/dualityRoll.mjs | 4 +++- module/helpers/utils.mjs | 10 ++++------ 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index c344231f..9c784084 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -1,5 +1,4 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; -import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; import DHRoll from './dhRoll.mjs'; export default class D20Roll extends DHRoll { @@ -137,12 +136,7 @@ export default class D20Roll extends DHRoll { static async buildEvaluate(roll, config = {}, message = {}) { if (config.evaluate !== false) await roll.evaluate(); - const advantageState = - config.roll.advantage == this.ADV_MODE.ADVANTAGE - ? true - : config.roll.advantage == this.ADV_MODE.DISADVANTAGE - ? false - : null; + this.postEvaluate(roll, config); } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 13246ac9..46e7374e 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -154,7 +154,7 @@ export const registerRollDiceHooks = () => { if (updates.length) actor.modifyResource(updates); - if (!config.roll.hasOwnProperty('success') && !config.targets.length) return; + if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return; const rollResult = config.roll.success || config.targets.some(t => t.hit), looseSpotlight = !rollResult || config.roll.result.duality === -1; diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 4d0e99a3..6c1d0fe4 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -1,5 +1,6 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; import D20Roll from './d20Roll.mjs'; +import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; export default class DualityRoll extends D20Roll { _advantageFaces = 6; @@ -80,7 +81,6 @@ export default class DualityRoll extends D20Roll { } static getHooks(hooks) { - return [...(hooks ?? []), 'Duality']; } @@ -142,5 +142,7 @@ export default class DualityRoll extends D20Roll { total: roll.dHope.total + roll.dFear.total, label: roll.totalLabel }; + + setDiceSoNiceForDualityRoll(roll, config.roll.advantage.type); } } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 0bb2088e..8156736d 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -126,12 +126,10 @@ export const setDiceSoNiceForDualityRoll = (rollResult, advantageState) => { const diceSoNicePresets = getDiceSoNicePresets(); rollResult.dice[0].options = { appearance: diceSoNicePresets.hope }; rollResult.dice[1].options = { appearance: diceSoNicePresets.fear }; //diceSoNicePresets.fear; - if (rollResult.dice[2]) { - if (advantageState === true) { - rollResult.dice[2].options = { appearance: diceSoNicePresets.advantage }; - } else if (advantageState === false) { - rollResult.dice[2].options = { appearance: diceSoNicePresets.disadvantage }; - } + if (rollResult.dice[2] && advantageState) { + rollResult.dice[2].options = { + appearance: advantageState === 1 ? diceSoNicePresets.advantage : diceSoNicePresets.disadvantage + }; } }; From e6126d81045a85eebd37c52fe9ba77027b8e24d7 Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Fri, 11 Jul 2025 17:36:51 +0200 Subject: [PATCH 11/58] Fix to make Cosmo happy (#318) --- module/data/action/baseAction.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index e193aefe..e2eafbf2 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -180,8 +180,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const actorData = this.actor.getRollData(false); // Remove when included directly in Actor getRollData - actorData.prof = actorData.proficiency?.value ?? 1; - actorData.cast = actorData.spellcast?.value ?? 1; + actorData.prof = actorData.proficiency?.total ?? 1; + actorData.cast = actorData.spellcast?.total ?? 1; actorData.result = data.roll?.total ?? 1; /* actorData.scale = data.costs?.length ? data.costs.reduce((a, c) => { From 85ca0e6b603659a4ba53cc9a6b334e433e34ce16 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 11 Jul 2025 18:09:06 +0200 Subject: [PATCH 12/58] Fixed so companion damage uses partner proficiency for scaling (#319) --- module/data/actor/companion.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 1203cc96..88b149e3 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -66,10 +66,9 @@ export default class DhCompanion extends BaseDataActor { damage: { parts: [ { - multiplier: 'flat', value: { dice: 'd6', - multiplier: 'flat' + multiplier: 'prof' } } ] @@ -87,6 +86,12 @@ export default class DhCompanion extends BaseDataActor { }; } + get proficiency() { + return { + total: this.partner?.system?.proficiency?.total ?? 1 + }; + } + prepareBaseData() { const partnerSpellcastingModifier = this.partner?.system?.spellcastingModifiers?.main; const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.total; From d4cc8e5a49e3d574d70b9df49dff9e164ad1c8e4 Mon Sep 17 00:00:00 2001 From: IrkTheImp <41175833+IrkTheImp@users.noreply.github.com> Date: Fri, 11 Jul 2025 14:50:08 -0500 Subject: [PATCH 13/58] set to use dh ranges by default and made setting world, not client. (#323) --- module/data/settings/RangeMeasurement.mjs | 2 +- module/systemRegistration/settings.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/data/settings/RangeMeasurement.mjs b/module/data/settings/RangeMeasurement.mjs index 71fb7787..552963f0 100644 --- a/module/data/settings/RangeMeasurement.mjs +++ b/module/data/settings/RangeMeasurement.mjs @@ -2,7 +2,7 @@ export default class DhRangeMeasurement extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { - enabled: new fields.BooleanField({ required: true, initial: false, label: 'DAGGERHEART.GENERAL.enabled' }), + enabled: new fields.BooleanField({ required: true, initial: true, label: 'DAGGERHEART.GENERAL.enabled' }), melee: new fields.NumberField({ required: true, initial: 5, label: 'DAGGERHEART.CONFIG.Range.melee.name' }), veryClose: new fields.NumberField({ required: true, diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index a4ed05c8..fea12acd 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -60,7 +60,7 @@ const registerMenuSettings = () => { }); game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement, { - scope: 'client', + scope: 'world', config: false, type: DhRangeMeasurement }); From 5b9db88d501f4ee664a269ee7a33967727788cc0 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:53:22 +0200 Subject: [PATCH 14/58] Added a separation of system effects and generic effects on token status effects. Can be turned off in settings. (#317) --- daggerheart.mjs | 14 ++-- lang/en.json | 8 ++- module/applications/_module.mjs | 1 + module/applications/hud/_module.mjs | 1 + module/applications/hud/tokenHUD.mjs | 84 ++++++++++++++++++++++ module/data/settings/Appearance.mjs | 4 ++ styles/daggerheart.less | 2 + styles/less/hud/index.less | 1 + styles/less/hud/token-hud/token-hud.less | 10 +++ templates/hud/tokenHUD.hbs | 78 ++++++++++++++++++++ templates/settings/appearance-settings.hbs | 1 + 11 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 module/applications/hud/_module.mjs create mode 100644 module/applications/hud/tokenHUD.mjs create mode 100644 styles/less/hud/index.less create mode 100644 styles/less/hud/token-hud/token-hud.less create mode 100644 templates/hud/tokenHUD.hbs diff --git a/daggerheart.mjs b/daggerheart.mjs index 4f411b0f..5a6d8193 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -41,10 +41,14 @@ Hooks.once('init', () => { ] ); - CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({ - ...x, - name: game.i18n.localize(x.name) - })); + CONFIG.statusEffects = [ + ...CONFIG.statusEffects, + ...Object.values(SYSTEM.GENERAL.conditions).map(x => ({ + ...x, + name: game.i18n.localize(x.name), + systemEffect: true + })) + ]; CONFIG.Dice.daggerheart = { DualityDie: DualityDie, @@ -108,6 +112,8 @@ Hooks.once('init', () => { } ); + CONFIG.Token.hudClass = applications.hud.DHTokenHUD; + CONFIG.Combat.dataModels = { base: models.DhCombat }; diff --git a/lang/en.json b/lang/en.json index 02ea41eb..db420652 100755 --- a/lang/en.json +++ b/lang/en.json @@ -279,6 +279,11 @@ } } }, + "HUD": { + "tokenHUD": { + "genericEffects": "Foundry Effects" + } + }, "Levelup": { "actions": { "creatureComfort": { @@ -1180,7 +1185,8 @@ "SETTINGS": { "Appearance": { "FIELDS": { - "displayFear": { "label": "Fear Display" } + "displayFear": { "label": "Fear Display" }, + "showGenericStatusEffects": { "label": "Show Foundry Status Effects" } }, "fearDisplay": { "token": "Tokens", diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 82c2866c..d4ceb229 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -1,5 +1,6 @@ export * as characterCreation from './characterCreation/_module.mjs'; export * as dialogs from './dialogs/_module.mjs'; +export * as hud from './hud/_module.mjs'; export * as levelup from './levelup/_module.mjs'; export * as settings from './settings/_module.mjs'; export * as sheets from './sheets/_module.mjs'; diff --git a/module/applications/hud/_module.mjs b/module/applications/hud/_module.mjs new file mode 100644 index 00000000..70edaf8f --- /dev/null +++ b/module/applications/hud/_module.mjs @@ -0,0 +1 @@ +export { default as DHTokenHUD } from './tokenHud.mjs'; diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs new file mode 100644 index 00000000..9a58bab2 --- /dev/null +++ b/module/applications/hud/tokenHUD.mjs @@ -0,0 +1,84 @@ +export default class DHTokenHUD extends TokenHUD { + static DEFAULT_OPTIONS = { + classes: ['daggerheart'] + }; + + /** @override */ + static PARTS = { + hud: { + root: true, + template: 'systems/daggerheart/templates/hud/tokenHUD.hbs' + } + }; + + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => { + const effect = context.statusEffects[key]; + if (effect.systemEffect) acc[key] = effect; + + return acc; + }, {}); + + const useGeneric = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.appearance + ).showGenericStatusEffects; + context.genericStatusEffects = useGeneric + ? Object.keys(context.statusEffects).reduce((acc, key) => { + const effect = context.statusEffects[key]; + if (!effect.systemEffect) acc[key] = effect; + + return acc; + }, {}) + : null; + + return context; + } + + _getStatusEffectChoices() { + // Include all HUD-enabled status effects + const choices = {}; + for (const status of CONFIG.statusEffects) { + if ( + status.hud === false || + (foundry.utils.getType(status.hud) === 'Object' && + status.hud.actorTypes?.includes(this.document.actor.type) === false) + ) { + continue; + } + choices[status.id] = { + _id: status._id, + id: status.id, + systemEffect: status.systemEffect, + title: game.i18n.localize(status.name ?? /** @deprecated since v12 */ status.label), + src: status.img ?? /** @deprecated since v12 */ status.icon, + isActive: false, + isOverlay: false + }; + } + + // Update the status of effects which are active for the token actor + const activeEffects = this.actor?.effects || []; + for (const effect of activeEffects) { + for (const statusId of effect.statuses) { + const status = choices[statusId]; + if (!status) continue; + if (status._id) { + if (status._id !== effect.id) continue; + } else { + if (effect.statuses.size !== 1) continue; + } + status.isActive = true; + if (effect.getFlag('core', 'overlay')) status.isOverlay = true; + break; + } + } + + // Flag status CSS class + for (const status of Object.values(choices)) { + status.cssClass = [status.isActive ? 'active' : null, status.isOverlay ? 'overlay' : null].filterJoin(' '); + } + return choices; + } +} diff --git a/module/data/settings/Appearance.mjs b/module/data/settings/Appearance.mjs index 8b04f558..d8b4c687 100644 --- a/module/data/settings/Appearance.mjs +++ b/module/data/settings/Appearance.mjs @@ -40,6 +40,10 @@ export default class DhAppearance extends foundry.abstract.DataModel { outline: new fields.ColorField({ required: true, initial: '#ffffff' }), edge: new fields.ColorField({ required: true, initial: '#000000' }) }) + }), + showGenericStatusEffects: new fields.BooleanField({ + initial: true, + label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.showGenericStatusEffects.label' }) }; } diff --git a/styles/daggerheart.less b/styles/daggerheart.less index 86b504b2..a48131c3 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -3,6 +3,8 @@ @import './less/dialog/index.less'; +@import './less//hud/index.less'; + @import './less/utils/colors.less'; @import './less/utils/fonts.less'; diff --git a/styles/less/hud/index.less b/styles/less/hud/index.less new file mode 100644 index 00000000..459f8fd7 --- /dev/null +++ b/styles/less/hud/index.less @@ -0,0 +1 @@ +@import './token-hud/token-hud.less'; diff --git a/styles/less/hud/token-hud/token-hud.less b/styles/less/hud/token-hud/token-hud.less new file mode 100644 index 00000000..7d231e8c --- /dev/null +++ b/styles/less/hud/token-hud/token-hud.less @@ -0,0 +1,10 @@ +.daggerheart.placeable-hud { + .col.right { + .palette { + .palette-category-title { + grid-column: span var(--effect-columns); + font-weight: bold; + } + } + } +} diff --git a/templates/hud/tokenHUD.hbs b/templates/hud/tokenHUD.hbs new file mode 100644 index 00000000..58d13267 --- /dev/null +++ b/templates/hud/tokenHUD.hbs @@ -0,0 +1,78 @@ +
+
+ + +
+ + + + + + {{#if canConfigure}} + + {{/if}} +
+ +
+
+ {{#if displayBar2}} + + {{/if}} +
+ +
+ {{#if displayBar1}} + + {{/if}} +
+
+ +
+ {{#if isGM}} + + {{/if}} + + +
+ {{#each systemStatusEffects as |status|}} + + {{/each}} + {{#if genericStatusEffects}} + + {{#each genericStatusEffects as |status|}} + + {{/each}} + {{/if}} +
+ + +
+ {{#each movementActions as |action|}} + + {{#if action.icon}}{{/if}} {{action.label}} + + {{/each}} +
+ + + + {{#if canToggleCombat}} + + {{/if}} +
diff --git a/templates/settings/appearance-settings.hbs b/templates/settings/appearance-settings.hbs index 5aa6d28d..da435c75 100644 --- a/templates/settings/appearance-settings.hbs +++ b/templates/settings/appearance-settings.hbs @@ -1,5 +1,6 @@
{{formGroup settingFields.schema.fields.displayFear value=settingFields._source.displayFear localize=true}} + {{formGroup settingFields.schema.fields.showGenericStatusEffects value=settingFields._source.showGenericStatusEffects localize=true}}
{{localize "DAGGERHEART.SETTINGS.Menu.appearance.duality"}} From 72436478c1f7bf13c8581f274b92fe5680799613 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:54:18 +0200 Subject: [PATCH 15/58] Added buttons to features on characters, and actions on adversary/environment (#316) --- module/applications/sheets/actors/adversary.mjs | 1 + module/applications/sheets/actors/character.mjs | 15 +++++++++++++++ module/applications/sheets/actors/environment.mjs | 1 + styles/less/global/elements.less | 11 +++++++++++ .../global/partials/inventory-fieldset-items.hbs | 2 +- .../sheets/global/partials/inventory-item.hbs | 8 ++++++++ 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 67f57781..0b01ebee 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -10,6 +10,7 @@ export default class AdversarySheet extends DHBaseActorSheet { actions: { reactionRoll: AdversarySheet.#reactionRoll, useItem: this.useItem, + useAction: this.useItem, toChat: this.toChat }, window: { diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index e70774f5..ae7ffbf9 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -24,6 +24,7 @@ export default class CharacterSheet extends DHBaseActorSheet { levelManagement: CharacterSheet.#levelManagement, toggleEquipItem: CharacterSheet.#toggleEquipItem, useItem: this.useItem, //TODO Fix this + useAction: this.useAction, toChat: this.toChat }, window: { @@ -620,6 +621,20 @@ export default class CharacterSheet extends DHBaseActorSheet { } } + /** + * Use an action + * @type {ApplicationClickAction} + */ + static async useAction(event, button) { + const item = this.getItem(button); + if (!item) return; + + const action = item.system.actions.find(x => x.id === button.dataset.actionId); + if (!action) return; + + action.use(event); + } + /** * Send item to Chat * @type {ApplicationClickAction} diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs index 188d24b4..05958cf5 100644 --- a/module/applications/sheets/actors/environment.mjs +++ b/module/applications/sheets/actors/environment.mjs @@ -11,6 +11,7 @@ export default class DhpEnvironment extends DHBaseActorSheet { }, actions: { useItem: this.useItem, + useAction: this.useItem, toChat: this.toChat }, dragDrop: [{ dragSelector: '.action-section .inventory-item', dropSelector: null }] diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 03772bfb..7466ae8b 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -319,6 +319,17 @@ transform: translateY(-20px); transform-origin: top; } + + .item-buttons { + grid-column: span 3; + display: flex; + gap: 8px; + flex-wrap: wrap; + + button { + white-space: nowrap; + } + } } .application.setting.dh-style { diff --git a/templates/sheets/global/partials/inventory-fieldset-items.hbs b/templates/sheets/global/partials/inventory-fieldset-items.hbs index 92d3a8a6..65c52736 100644 --- a/templates/sheets/global/partials/inventory-fieldset-items.hbs +++ b/templates/sheets/global/partials/inventory-fieldset-items.hbs @@ -17,7 +17,7 @@ {{/each}} {{else}} {{#each values}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls }} + {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls featureType=true }} {{/each}} {{#each adversaries as |adversary|}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index 135c3e3c..eae3dd5f 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -171,4 +171,12 @@ {{/unless}}
{{#unless isSidebar}}{{{item.system.description}}}{{/unless}}
+ + {{#if featureType}} +
+ {{#each item.system.actions as | action |}} + + {{/each}} +
+ {{/if}} \ No newline at end of file From b6195127fe629d0dd299eb579a1255774f59aa89 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 11 Jul 2025 22:26:56 +0200 Subject: [PATCH 16/58] 199 - Tooltips (#311) * Set up templates for all 'advanced' tooltips * Fixed ItemFeature Header label * Fixed less import --- lang/en.json | 21 +++- module/config/actorConfig.mjs | 2 +- module/data/item/armor.mjs | 6 + module/data/item/weapon.mjs | 6 + module/documents/tooltipManager.mjs | 24 +++- module/helpers/handlebarsHelper.mjs | 56 ++++----- module/systemRegistration/handlebars.mjs | 3 +- styles/daggerheart.less | 2 + styles/less/ux/index.less | 1 + styles/less/ux/tooltip/tooltip.less | 106 ++++++++++++++++++ templates/sheets/global/tabs/tab-actions.hbs | 1 + templates/sheets/global/tabs/tab-features.hbs | 2 +- templates/sheets/items/feature/header.hbs | 2 +- templates/ui/tooltip/action.hbs | 83 ++++++++++++++ templates/ui/tooltip/adversary.hbs | 64 +++++++++++ templates/ui/tooltip/armor.hbs | 40 ++++++- templates/ui/tooltip/beastform.hbs | 6 - templates/ui/tooltip/consumable.hbs | 14 +++ templates/ui/tooltip/domainCard.hbs | 34 +++++- templates/ui/tooltip/feature.hbs | 8 ++ templates/ui/tooltip/miscellaneous.hbs | 7 ++ templates/ui/tooltip/parts/tooltipTags.hbs | 12 ++ templates/ui/tooltip/weapon.hbs | 59 +++++++++- 23 files changed, 505 insertions(+), 54 deletions(-) create mode 100644 styles/less/ux/index.less create mode 100644 styles/less/ux/tooltip/tooltip.less create mode 100644 templates/ui/tooltip/action.hbs create mode 100644 templates/ui/tooltip/adversary.hbs delete mode 100644 templates/ui/tooltip/beastform.hbs create mode 100644 templates/ui/tooltip/consumable.hbs create mode 100644 templates/ui/tooltip/feature.hbs create mode 100644 templates/ui/tooltip/miscellaneous.hbs create mode 100644 templates/ui/tooltip/parts/tooltipTags.hbs diff --git a/lang/en.json b/lang/en.json index db420652..f58cba35 100755 --- a/lang/en.json +++ b/lang/en.json @@ -973,6 +973,10 @@ "singular": "Character", "plural": "Characters" }, + "Cost": { + "single": "Cost", + "plural": "Costs" + }, "Damage": { "severe": "Severe", "major": "Major", @@ -1078,6 +1082,7 @@ "specialization": "Specialization", "mastery": "Mastery", "optional": "Optional", + "recovery": "Recovery", "setup": "Setup", "equipment": "Equipment" }, @@ -1099,6 +1104,8 @@ "burden": "Burden", "check": "{check} Check", "criticalSuccess": "Critical Success", + "damage": "Damage", + "damageType": "Damage Type", "description": "Description", "duality": "Duality", "dualityRoll": "Duality Roll", @@ -1111,17 +1118,25 @@ "inactiveEffects": "Inactive Effects", "inventory": "Inventory", "level": "Level", + "max": "Max", "modifier": "Modifier", "multiclass": "Multiclass", + "none": "None", "quantity": "Quantity", "range": "Range", + "recovery": "Recovery", + "scalable": "Scalable", "stress": "Stress", "take": "Take", "target": "Target", "title": "Title", + "true": "True", "type": "Type", "unarmored": "Unarmored", - "use": "Use" + "use": "Use", + "used": "Used", + "uses": "Uses", + "value": "Value" }, "ITEMS": { "Armor": { @@ -1178,6 +1193,7 @@ "spellcastingTrait": "Spellcasting Trait" }, "Weapon": { + "weaponType": "Weapon Type", "primaryWeapon": "Primary Weapon", "secondaryWeapon": "Secondary Weapon" } @@ -1386,7 +1402,8 @@ "unequip": "Unequip", "sendToVault": "Send to Vault", "sendToLoadout": "Send to Loadout", - "makeDeathMove": "Make a Death Move" + "makeDeathMove": "Make a Death Move", + "rangeAndTarget": "Range & Target" } } } diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 7a179308..02cfd4a9 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -113,7 +113,7 @@ export const adversaryTypes = { }, social: { id: 'social', - label: 'DAGGERHEART.CONFIG.AdversaryTypee.social.label', + label: 'DAGGERHEART.CONFIG.AdversaryType.social.label', description: 'DAGGERHEART.ACTORS.Adversary.social.description' }, solo: { diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 696a95a2..bf2bf73e 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -44,6 +44,12 @@ export default class DHArmor extends BaseDataItem { }; } + get customActions() { + return this.actions.filter( + action => !this.armorFeatures.some(feature => feature.actionIds.includes(action.id)) + ); + } + async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index e1370395..80c8271d 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -73,6 +73,12 @@ export default class DHWeapon extends BaseDataItem { return [this.attack, ...this.actions]; } + get customActions() { + return this.actions.filter( + action => !this.weaponFeatures.some(feature => feature.actionIds.includes(action.id)) + ); + } + async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index 2e660cff..d9444207 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -2,15 +2,33 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti async activate(element, options = {}) { let html = options.html; if (element.dataset.tooltip?.startsWith('#item#')) { - const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6)); + const splitValues = element.dataset.tooltip.slice(6).split('#action#'); + const itemUuid = splitValues[0]; + const actionId = splitValues.length > 1 ? splitValues[1] : null; + + const baseItem = await foundry.utils.fromUuid(itemUuid); + const item = actionId ? baseItem.system.actions.find(x => x.id === actionId) : baseItem; if (item) { + const type = actionId ? 'action' : item.type; html = await foundry.applications.handlebars.renderTemplate( - `systems/daggerheart/templates/ui/tooltip/${item.type}.hbs`, - item + `systems/daggerheart/templates/ui/tooltip/${type}.hbs`, + { + item: item, + config: CONFIG.DH + } ); + + this.tooltip.innerHTML = html; + options.direction = this._determineItemTooltipDirection(element); } } super.activate(element, { ...options, html: html }); } + + _determineItemTooltipDirection(element) { + const pos = element.getBoundingClientRect(); + const dirs = this.constructor.TOOLTIP_DIRECTIONS; + return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT']; + } } diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 6db51225..feeebbd2 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -1,47 +1,49 @@ -import { getWidthOfText } from './utils.mjs'; - export default class RegisterHandlebarsHelpers { static registerHelpers() { Handlebars.registerHelper({ - times: this.times, - join: this.join, add: this.add, - subtract: this.subtract, includes: this.includes, - case: this.case + times: this.times, + damageFormula: this.damageFormula, + damageSymbols: this.damageSymbols, + tertiary: this.tertiary, + signedNumber: this.signedNumber }); } - static times(nr, block) { - var accum = ''; - for (var i = 0; i < nr; ++i) accum += block.fn(i); - return accum; - } - - static join(...options) { - return options.slice(0, options.length - 1); - } - static add(a, b) { const aNum = Number.parseInt(a); const bNum = Number.parseInt(b); return (Number.isNaN(aNum) ? 0 : aNum) + (Number.isNaN(bNum) ? 0 : bNum); } - static subtract(a, b) { - const aNum = Number.parseInt(a); - const bNum = Number.parseInt(b); - return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum); - } - static includes(list, item) { return list.includes(item); } - static case(value, options) { - if (value == this.switch_value) { - this.switch_break = true; - return options.fn(this); - } + static times(nr, block) { + var accum = ''; + for (var i = 0; i < nr; ++i) accum += block.fn(i); + return accum; + } + + static damageFormula(attack, actor) { + const traitTotal = actor.system.traits?.[attack.roll.trait]?.total; + const instances = [ + attack.damage.parts.map(x => Roll.replaceFormulaData(x.value.getFormula(), actor)).join(' + '), + traitTotal + ].filter(x => x); + + return instances.join(traitTotal > 0 ? ' + ' : ' - '); + } + + static damageSymbols(damageParts) { + const symbols = new Set(); + damageParts.forEach(part => symbols.add(...CONFIG.DH.GENERAL.damageTypes[part.type].icon)); + return new Handlebars.SafeString(Array.from(symbols).map(symbol => ``)); + } + + static tertiary(a, b) { + return a ?? b; } } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 75a5aff6..e4cc1a2c 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -22,6 +22,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/actionTypes/beastform.hbs', 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', 'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs', - 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs' + 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs', + 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs' ]); }; diff --git a/styles/daggerheart.less b/styles/daggerheart.less index a48131c3..c2127681 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -12,4 +12,6 @@ @import './less/ui/index.less'; +@import './less/ux/index.less'; + @import '../node_modules/@yaireo/tagify/dist/tagify.css'; diff --git a/styles/less/ux/index.less b/styles/less/ux/index.less new file mode 100644 index 00000000..ff645288 --- /dev/null +++ b/styles/less/ux/index.less @@ -0,0 +1 @@ +@import './tooltip/tooltip.less'; diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less new file mode 100644 index 00000000..38502d09 --- /dev/null +++ b/styles/less/ux/tooltip/tooltip.less @@ -0,0 +1,106 @@ +.daggerheart.dh-style.tooltip { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + + .tooltip-title { + margin: 0; + text-align: center; + } + + .tooltip-image { + height: 180px; + width: 180px; + } + + .tooltip-description { + font-style: italic; + } + + .tooltip-sub-title { + margin: 0; + color: light-dark(@dark-blue, @beige); + } + + .tooltip-information-section { + width: 100%; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 4px; + + &.triple { + grid-template-columns: 1fr 1fr 1fr; + } + + &.border { + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + padding: 2px; + } + + .tooltip-information { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + + &.full-width { + grid-column: span 2; + } + + label { + font-weight: bold; + } + + label, + div { + white-space: nowrap; + } + } + } + + .tooltip-tags { + width: 100%; + display: flex; + flex-direction: column; + gap: 4px; + + .tooltip-tag { + width: 100%; + display: grid; + grid-template-columns: 80px 1fr; + align-items: start; + gap: 8px; + padding: 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + + .tooltip-tag-label-container { + display: flex; + align-items: center; + flex-direction: column; + gap: 2px; + + .tooltip-tag-image { + width: 40px; + height: 40px; + } + } + + .tooltip-tag-label { + font-weight: bold; + text-align: center; + } + + .tooltip-tag-description { + display: flex; + flex-wrap: wrap; + } + } + } + + .spaced { + margin-bottom: 4px; + } +} diff --git a/templates/sheets/global/tabs/tab-actions.hbs b/templates/sheets/global/tabs/tab-actions.hbs index 54345bed..ed71c45f 100644 --- a/templates/sheets/global/tabs/tab-actions.hbs +++ b/templates/sheets/global/tabs/tab-actions.hbs @@ -10,6 +10,7 @@
{{action.name}} diff --git a/templates/sheets/global/tabs/tab-features.hbs b/templates/sheets/global/tabs/tab-features.hbs index 71f6f1f1..eced83d7 100644 --- a/templates/sheets/global/tabs/tab-features.hbs +++ b/templates/sheets/global/tabs/tab-features.hbs @@ -11,7 +11,7 @@ data-action="editFeature" id="{{feature.id}}" > - + {{feature.name}}
diff --git a/templates/sheets/items/feature/header.hbs b/templates/sheets/items/feature/header.hbs index e6a11503..e603c0f7 100755 --- a/templates/sheets/items/feature/header.hbs +++ b/templates/sheets/items/feature/header.hbs @@ -4,7 +4,7 @@

-

{{localize (concat 'TYPES.Item.feature' source.system.type)}}

+

{{localize 'TYPES.Item.feature'}}

\ No newline at end of file diff --git a/templates/ui/tooltip/action.hbs b/templates/ui/tooltip/action.hbs new file mode 100644 index 00000000..c101ee68 --- /dev/null +++ b/templates/ui/tooltip/action.hbs @@ -0,0 +1,83 @@ +
+

{{item.name}}

+ +
{{{item.description}}}
+ + {{#if item.uses.max}} +

{{localize "DAGGERHEART.GENERAL.uses"}}

+
+
+ +
{{item.uses.value}}
+
+
+ +
{{item.uses.max}}
+
+
+ + {{#with (lookup config.GENERAL.refreshTypes item.uses.recovery) as | type |}} +
{{localize type.label}}
+ {{/with}} +
+
+ {{/if}} + + {{#if (gt item.cost.length 0)}} +

{{localize "DAGGERHEART.GENERAL.Cost.plural"}}

+ {{#each item.cost as | cost |}} +
+
+ + {{#with (lookup @root.config.GENERAL.abilityCosts cost.type) as | type |}} +
{{localize type.label}}
+ {{/with}} +
+
+ +
{{cost.value}}
+
+ {{#if cost.scalable}} +
+ +
{{localize "DAGGERHEART.GENERAL.true"}}
+
+
+ +
{{cost.step}}
+
+ {{/if}} +
+ {{/each}} + {{/if}} + + {{#if (or item.range item.target)}} +

{{localize "DAGGERHEART.UI.Tooltip.rangeAndTarget"}}

+
+
+ +
+ {{#if item.range}} + {{#with (lookup @root.config.GENERAL.range item.range) as | range |}} +
{{localize range.label}}
+ {{/with}} + {{else}} +
{{localize "DAGGERHEART.GENERAL.none"}}
+ {{/if}} +
+
+
+ +
+ {{#if item.target.type}} + {{#with (lookup @root.config.ACTIONS.targetTypes item.target.type) as | target |}} +
{{@root.item.target.amount}} {{localize target.label}}
+ {{/with}} + {{else}} +
{{localize "DAGGERHEART.GENERAL.none"}}
+ {{/if}} +
+
+
+ {{/if}} +
\ No newline at end of file diff --git a/templates/ui/tooltip/adversary.hbs b/templates/ui/tooltip/adversary.hbs new file mode 100644 index 00000000..5fa559ff --- /dev/null +++ b/templates/ui/tooltip/adversary.hbs @@ -0,0 +1,64 @@ +
+

{{item.name}}

+ +
{{{item.system.description}}}
+ +
+
+ + {{#with (lookup config.GENERAL.tiers item.system.tier) as | tier |}} +
{{localize tier.label}}
+ {{/with}} +
+
+ + {{#with (lookup config.ACTOR.adversaryTypes item.system.type) as | type |}} +
{{localize type.label}}
+ {{/with}} +
+
+ +
{{item.system.difficulty}}
+
+
+
+
+ +
{{item.system.resources.hitPoints.max}}
+
+
+ +
{{item.system.resources.stress.max}}
+
+
+ +
{{item.system.damageThresholds.major}}
+
+
+ +
{{item.system.damageThresholds.severe}}
+
+
+ +
{{numberFormat item.system.attack.roll.bonus sign=true}}
+
+
+ +
{{damageFormula item.system.attack item}}
+
+
+ + {{localize "DAGGERHEART.GENERAL.Experience.plural"}} + {{#each item.system.experiences as | experience |}} +
{{experience.name}} {{numberFormat experience.total sign=true}}
+ {{/each}} + +
+
+ +
{{item.system.motivesAndTactics}}
+
+
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.features }} +
\ No newline at end of file diff --git a/templates/ui/tooltip/armor.hbs b/templates/ui/tooltip/armor.hbs index c2972700..456fb226 100644 --- a/templates/ui/tooltip/armor.hbs +++ b/templates/ui/tooltip/armor.hbs @@ -1,5 +1,37 @@ -
-
{{name}}
- -
{{{system.description}}}
+
+

{{item.name}}

+ +
{{{item.system.description}}}
+ +
+
+ +
{{item.system.baseScore}}
+
+ +
+ +
{{item.system.baseThresholds.major}}
+
+
+ +
{{item.system.baseThresholds.severe}}
+
+
+ + {{#if (gt item.system.armorFeatures.length 0)}}

{{localize "DAGGERHEART.GENERAL.features"}}

{{/if}} +
+ {{#each item.system.armorFeatures}} + {{#with (lookup ../config.ITEM.armorFeatures this.value) as | feature | }} +
+
+
{{localize feature.label}}
+
+
{{{localize feature.description}}}
+
+ {{/with}} + {{/each}} +
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.customActions label=(localize "DAGGERHEART.GENERAL.Action.plural")}}
\ No newline at end of file diff --git a/templates/ui/tooltip/beastform.hbs b/templates/ui/tooltip/beastform.hbs deleted file mode 100644 index 3af49969..00000000 --- a/templates/ui/tooltip/beastform.hbs +++ /dev/null @@ -1,6 +0,0 @@ -
-
{{name}}
- -
{{{system.examples}}}
-
{{system.advantageOn}}
-
\ No newline at end of file diff --git a/templates/ui/tooltip/consumable.hbs b/templates/ui/tooltip/consumable.hbs new file mode 100644 index 00000000..2c998b1d --- /dev/null +++ b/templates/ui/tooltip/consumable.hbs @@ -0,0 +1,14 @@ +
+

{{item.name}}

+ +
{{{item.system.description}}}
+ +
+
+ +
{{item.system.quantity}}
+
+
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }} +
\ No newline at end of file diff --git a/templates/ui/tooltip/domainCard.hbs b/templates/ui/tooltip/domainCard.hbs index c2972700..dad00b1b 100644 --- a/templates/ui/tooltip/domainCard.hbs +++ b/templates/ui/tooltip/domainCard.hbs @@ -1,5 +1,31 @@ -
-
{{name}}
- -
{{{system.description}}}
+
+

{{item.name}}

+ +
{{{item.system.description}}}
+ +
+
+ + {{#with (lookup config.DOMAIN.domains item.system.domain) as | domain |}} +
{{localize domain.label}}
+ {{/with}} +
+ +
+ + {{#with (lookup config.DOMAIN.cardTypes item.system.type) as | type |}} +
{{localize type.label}}
+ {{/with}} +
+
+ +
{{item.system.level}}
+
+
+ +
{{item.system.recallCost}}
+
+
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
\ No newline at end of file diff --git a/templates/ui/tooltip/feature.hbs b/templates/ui/tooltip/feature.hbs new file mode 100644 index 00000000..17ff2db6 --- /dev/null +++ b/templates/ui/tooltip/feature.hbs @@ -0,0 +1,8 @@ +
+

{{item.name}}

+ +
{{{item.system.description}}}
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }} + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.effects label=(localize "DAGGERHEART.GENERAL.Effect.plural") }} +
\ No newline at end of file diff --git a/templates/ui/tooltip/miscellaneous.hbs b/templates/ui/tooltip/miscellaneous.hbs new file mode 100644 index 00000000..83014a88 --- /dev/null +++ b/templates/ui/tooltip/miscellaneous.hbs @@ -0,0 +1,7 @@ +
+

{{item.name}}

+ +
{{{item.system.description}}}
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }} +
\ No newline at end of file diff --git a/templates/ui/tooltip/parts/tooltipTags.hbs b/templates/ui/tooltip/parts/tooltipTags.hbs new file mode 100644 index 00000000..a02a729a --- /dev/null +++ b/templates/ui/tooltip/parts/tooltipTags.hbs @@ -0,0 +1,12 @@ +{{#if (gt features.length 0)}}

{{label}}

{{/if}} +
+ {{#each features as | feature |}} +
+
+
{{localize feature.name}}
+ {{#if feature.img}}{{/if}} +
+
{{{localize (tertiary feature.description feature.system.description)}}}
+
+ {{/each}} +
\ No newline at end of file diff --git a/templates/ui/tooltip/weapon.hbs b/templates/ui/tooltip/weapon.hbs index c2972700..963b0714 100644 --- a/templates/ui/tooltip/weapon.hbs +++ b/templates/ui/tooltip/weapon.hbs @@ -1,5 +1,56 @@ -
-
{{name}}
- -
{{{system.description}}}
+
+

{{item.name}}

+ +
{{{item.system.description}}}
+ +
+
+ +
{{#if item.system.secondaryWeapon}}{{localize "DAGGERHEART.ITEMS.Weapon.secondaryWeapon"}}{{else}}{{localize "DAGGERHEART.ITEMS.Weapon.primaryWeapon"}}{{/if}}
+
+
+ + {{#with (lookup config.GENERAL.burden item.system.burden) as | burden |}} +
{{localize burden.label}}
+ {{/with}} +
+ {{#if item.system.attack.roll.trait}} +
+ + {{#with (lookup config.ACTOR.abilities item.system.attack.roll.trait) as | trait |}} +
{{localize trait.label}}
+ {{/with}} +
+ {{/if}} +
+ + {{#with (lookup config.GENERAL.range item.system.attack.range) as | range |}} +
{{localize range.label}}
+ {{/with}} +
+
+ +
{{{damageFormula item.system.attack item.parent}}}
+
+
+ +
{{{damageSymbols item.system.attack.damage.parts}}}
+
+
+ + {{#if (gt item.system.weaponFeatures.length 0)}}

{{localize "DAGGERHEART.GENERAL.features"}}

{{/if}} +
+ {{#each item.system.weaponFeatures}} + {{#with (lookup ../config.ITEM.weaponFeatures this.value) as | feature | }} +
+
+
{{localize feature.label}}
+
+
{{{localize feature.description}}}
+
+ {{/with}} + {{/each}} +
+ + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.customActions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
\ No newline at end of file From dee398347fd392cfd418295ecd3cbe10f5cbb81d Mon Sep 17 00:00:00 2001 From: Murilo Brito <91566541+moliloo@users.noreply.github.com> Date: Sat, 12 Jul 2025 09:44:14 -0300 Subject: [PATCH 17/58] fix style problems in bottom sheets and enhance damage and action dialogs (#325) --- lang/en.json | 4 ++ .../dialogs/costSelectionDialog.mjs | 2 +- module/applications/dialogs/damageDialog.mjs | 13 +++++- .../dialogs/damageSelectionDialog.mjs | 2 +- module/applications/sheets/items/feature.mjs | 9 +++- module/documents/item.mjs | 8 +++- styles/less/dialog/actions/action-list.less | 19 +++++++++ .../less/dialog/damage-selection/sheet.less | 20 +++++++++ .../less/dialog/dice-roll/roll-selection.less | 10 ----- styles/less/dialog/index.less | 4 ++ styles/less/global/dialog.less | 16 +++++++ styles/less/global/elements.less | 9 ++-- styles/less/global/sheet.less | 6 ++- .../adversary-settings/experiences.less | 1 + .../adversary-settings/features.less | 1 + .../environment-settings/adversaries.less | 1 + .../environment-settings/features.less | 1 + styles/less/utils/colors.less | 2 + templates/actionTypes/actionType.hbs | 15 ++++--- templates/dialogs/actionSelect.hbs | 14 +++---- .../dialogs/dice-roll/damageSelection.hbs | 42 +++++-------------- 21 files changed, 129 insertions(+), 70 deletions(-) create mode 100644 styles/less/dialog/actions/action-list.less create mode 100644 styles/less/dialog/damage-selection/sheet.less diff --git a/lang/en.json b/lang/en.json index f58cba35..e14a3bc3 100755 --- a/lang/en.json +++ b/lang/en.json @@ -677,6 +677,10 @@ "name": "Dice Set" } }, + "SelectAction": { + "selectType": "Select Action Type", + "selectAction": "Select Action" + }, "Traits": { "agility": { "name": "Agility", diff --git a/module/applications/dialogs/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs index 026aac46..abb79e6a 100644 --- a/module/applications/dialogs/costSelectionDialog.mjs +++ b/module/applications/dialogs/costSelectionDialog.mjs @@ -11,7 +11,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 442a1491..4030d7a7 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -11,11 +11,14 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application static DEFAULT_OPTIONS = { tag: 'form', id: 'roll-selection', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' }, + window: { + icon: 'fa-solid fa-dice' + }, actions: { submitRoll: this.submitRoll }, @@ -34,9 +37,15 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application } }; + get title() { + return game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); + } + async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.title = this.config.title; + context.title = this.config.title + ? this.config.title + : game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); return context; diff --git a/module/applications/dialogs/damageSelectionDialog.mjs b/module/applications/dialogs/damageSelectionDialog.mjs index 5248e81d..547ba87c 100644 --- a/module/applications/dialogs/damageSelectionDialog.mjs +++ b/module/applications/dialogs/damageSelectionDialog.mjs @@ -23,7 +23,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'damage-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], position: { width: 400, height: 'auto' diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index a54c3bcb..3d13d7de 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -61,12 +61,17 @@ export default class FeatureSheet extends DHBaseItemSheet { static async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } + { + types: CONFIG.DH.ACTIONS.actionTypes, + itemName: game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType') + } ), - title = 'Select Action Type'; + title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectType'); + console.log(this.document); return foundry.applications.api.DialogV2.prompt({ window: { title }, + classes: ['daggerheart', 'dh-style'], content, ok: { label: title, diff --git a/module/documents/item.mjs b/module/documents/item.mjs index db34fa49..6c3732db 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -80,12 +80,16 @@ export default class DHItem extends foundry.documents.Item { async selectActionDialog(prevEvent) { const content = await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/dialogs/actionSelect.hbs', - { actions: this.system.actionsList } + { + actions: this.system.actionsList, + itemName: this.name + } ), - title = 'Select Action'; + title = game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectAction'); return foundry.applications.api.DialogV2.prompt({ window: { title }, + classes: ['daggerheart', 'dh-style'], content, ok: { label: title, diff --git a/styles/less/dialog/actions/action-list.less b/styles/less/dialog/actions/action-list.less new file mode 100644 index 00000000..800f7d8e --- /dev/null +++ b/styles/less/dialog/actions/action-list.less @@ -0,0 +1,19 @@ +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style { + .actions-list { + display: flex; + flex-direction: column; + gap: 10px; + + .action-item { + display: flex; + align-items: center; + gap: 5px; + + .label { + font-family: @font-body; + } + } + } +} diff --git a/styles/less/dialog/damage-selection/sheet.less b/styles/less/dialog/damage-selection/sheet.less new file mode 100644 index 00000000..43e4f4d2 --- /dev/null +++ b/styles/less/dialog/damage-selection/sheet.less @@ -0,0 +1,20 @@ +@import '../../utils/colors.less'; + +.daggerheart.dialog.dh-style.views.damage-selection { + .damage-section-container { + display: flex; + flex-direction: column; + gap: 12px; + + input[type='text'], + input[type='number'] { + color: light-dark(@dark, @beige); + outline: 2px solid transparent; + transition: all 0.3s ease; + + &:hover { + outline: 2px solid light-dark(@dark, @beige); + } + } + } +} diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index b2f05dc2..575b7ce9 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -114,15 +114,5 @@ } } } - - .formula-label { - font-family: @font-body; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 17px; - - color: light-dark(@dark, @beige); - } } } diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index 40280270..545ce2e1 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -4,6 +4,10 @@ @import './level-up/summary-container.less'; @import './level-up/tiers-container.less'; +@import './actions/action-list.less'; + +@import './damage-selection/sheet.less'; + @import './downtime/downtime-container.less'; @import './beastform/beastform-container.less'; diff --git a/styles/less/global/dialog.less b/styles/less/global/dialog.less index 3856facb..11a4eee9 100644 --- a/styles/less/global/dialog.less +++ b/styles/less/global/dialog.less @@ -1,5 +1,6 @@ @import '../utils/colors.less'; @import '../utils/fonts.less'; +@import '../utils/mixin.less'; .appTheme({ &.dialog { @@ -40,4 +41,19 @@ } } } + + .submit-btn { + width: 100%; + height: 38px; + } + + .formula-label { + font-family: @font-body; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 17px; + + color: light-dark(@dark, @beige); + } } diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 7466ae8b..84c90336 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -35,15 +35,16 @@ } } - input[type='checkbox'] { + input[type='checkbox'], + input[type='radio'] { &:checked::after { - color: light-dark(@dark, @golden); + color: light-dark(@dark-40, @golden); } &:checked::before { - color: light-dark(transparent, @dark-blue); + color: light-dark(@dark-40, @golden-40); } &::before { - color: light-dark(@dark, @beige); + color: light-dark(@dark-40, @golden-40); } } diff --git a/styles/less/global/sheet.less b/styles/less/global/sheet.less index 1e44d7a0..1a00239a 100755 --- a/styles/less/global/sheet.less +++ b/styles/less/global/sheet.less @@ -4,8 +4,8 @@ // Theme handling .appTheme({ - background: @semi-transparent-dark-blue; - backdrop-filter: blur(9px); + background: @dark-blue-60; + backdrop-filter: blur(10px); }, { background: url('../assets/parchments/dh-parchment-light.png') no-repeat center; }); @@ -44,6 +44,8 @@ top: -36px; min-height: -webkit-fill-available; transition: opacity 0.3s ease; + padding-bottom: 20px; + margin-bottom: -36px; .tab { padding: 0 10px; diff --git a/styles/less/sheets-settings/adversary-settings/experiences.less b/styles/less/sheets-settings/adversary-settings/experiences.less index 89a7c2d9..05595ed4 100644 --- a/styles/less/sheets-settings/adversary-settings/experiences.less +++ b/styles/less/sheets-settings/adversary-settings/experiences.less @@ -5,6 +5,7 @@ .tab.experiences { .add-experience-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/adversary-settings/features.less b/styles/less/sheets-settings/adversary-settings/features.less index 5798bfa9..037a08ea 100644 --- a/styles/less/sheets-settings/adversary-settings/features.less +++ b/styles/less/sheets-settings/adversary-settings/features.less @@ -10,6 +10,7 @@ .add-feature-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/environment-settings/adversaries.less b/styles/less/sheets-settings/environment-settings/adversaries.less index ba8cc8e4..8dc12c87 100644 --- a/styles/less/sheets-settings/environment-settings/adversaries.less +++ b/styles/less/sheets-settings/environment-settings/adversaries.less @@ -10,6 +10,7 @@ .add-action-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/sheets-settings/environment-settings/features.less b/styles/less/sheets-settings/environment-settings/features.less index e4bb039f..f2a9583a 100644 --- a/styles/less/sheets-settings/environment-settings/features.less +++ b/styles/less/sheets-settings/environment-settings/features.less @@ -10,6 +10,7 @@ .add-feature-btn { width: 100%; + height: 38px; margin-bottom: 12px; } diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less index 3e72b743..622480a7 100755 --- a/styles/less/utils/colors.less +++ b/styles/less/utils/colors.less @@ -25,10 +25,12 @@ @dark-blue-10: #18162e10; @dark-blue-40: #18162e40; @dark-blue-50: #18162e50; +@dark-blue-60: #18162e60; @semi-transparent-dark-blue: rgba(24, 22, 46, 0.33); @dark: #222; @dark-15: #22222215; +@dark-40: #22222240; @deep-black: #0e0d15; diff --git a/templates/actionTypes/actionType.hbs b/templates/actionTypes/actionType.hbs index fdffaabe..1cd912e9 100644 --- a/templates/actionTypes/actionType.hbs +++ b/templates/actionTypes/actionType.hbs @@ -1,13 +1,12 @@
-
    +
    +

    {{itemName}}

    +
    +
      {{#each types}} -
    • - +
    • + + {{localize name}}
    • {{/each}}
    diff --git a/templates/dialogs/actionSelect.hbs b/templates/dialogs/actionSelect.hbs index 2ea76cae..200ef29c 100644 --- a/templates/dialogs/actionSelect.hbs +++ b/templates/dialogs/actionSelect.hbs @@ -1,12 +1,12 @@ -
      +
      +

      {{itemName}}

      +
      +
        {{#each actions}} -
      • - +
      • + + {{ name }}
      • {{/each}}
      diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index 988b852e..0286990e 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -1,33 +1,13 @@ -
      +
      +
      +

      {{title}}

      +
      + Formula: {{@root.formula}}
      - -
      - {{!-- --}} -
      {{@root.formula}}
      -
      -
      - -
      +
      - {{!-- {{#each bonusDamage as |damage index|}} -
      - -
      - - - {{#if (and damage.initiallySelected damage.hopeIncrease)}} - - -
      - -
      {{damage.hopeUses}}
      - -
      - {{/if}} -
      -
      - {{/each}} --}} -
      - -
      -
      \ No newline at end of file + + \ No newline at end of file From 3f4c8849740fce0208b05dc8414cc438f997770e Mon Sep 17 00:00:00 2001 From: Murilo Brito <91566541+moliloo@users.noreply.github.com> Date: Sat, 12 Jul 2025 14:14:44 -0300 Subject: [PATCH 18/58] fix firefox problems (#329) --- styles/less/sheets/actors/adversary/sheet.less | 1 + styles/less/sheets/actors/adversary/sidebar.less | 3 ++- styles/less/sheets/actors/character/sheet.less | 1 + styles/less/sheets/actors/character/sidebar.less | 3 ++- styles/less/sheets/actors/companion/header.less | 6 +++++- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/styles/less/sheets/actors/adversary/sheet.less b/styles/less/sheets/actors/adversary/sheet.less index af7918c6..286351c9 100644 --- a/styles/less/sheets/actors/adversary/sheet.less +++ b/styles/less/sheets/actors/adversary/sheet.less @@ -9,6 +9,7 @@ gap: 15px 0; height: 100%; width: 100%; + padding-bottom: 0; .adversary-sidebar-sheet { grid-row: 1 / span 2; diff --git a/styles/less/sheets/actors/adversary/sidebar.less b/styles/less/sheets/actors/adversary/sidebar.less index e50ba0c9..c1bd1856 100644 --- a/styles/less/sheets/actors/adversary/sidebar.less +++ b/styles/less/sheets/actors/adversary/sidebar.less @@ -110,10 +110,11 @@ justify-content: space-evenly; .status-bar { + display: flex; + justify-content: center; position: relative; width: 100px; height: 40px; - justify-items: center; .status-label { position: relative; diff --git a/styles/less/sheets/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less index f2c9bb1a..8afd7404 100644 --- a/styles/less/sheets/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -9,6 +9,7 @@ gap: 15px 0; height: 100%; width: 100%; + padding-bottom: 0; overflow: auto; .character-sidebar-sheet { diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index d6ceab46..f46a9628 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -70,10 +70,11 @@ justify-content: space-evenly; .status-bar { + display: flex; + justify-content: center; position: relative; width: 100px; height: 40px; - justify-items: center; .status-label { position: relative; diff --git a/styles/less/sheets/actors/companion/header.less b/styles/less/sheets/actors/companion/header.less index fac32ea5..832a6050 100644 --- a/styles/less/sheets/actors/companion/header.less +++ b/styles/less/sheets/actors/companion/header.less @@ -45,7 +45,9 @@ justify-content: center; .status-number { - justify-items: center; + display: flex; + flex-direction: column; + align-items: center; .status-value { position: relative; @@ -85,6 +87,8 @@ } .status-bar { + display: flex; + justify-content: center; position: relative; width: 100px; height: 40px; From 812a5e8dd7f646698ac8dbb1881c8bf5851a798d Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Sat, 12 Jul 2025 20:13:09 +0200 Subject: [PATCH 19/58] Feature/167 damage types and resistances (#330) * Add Resistances * Relocate Damage Reduction * Damage Types * dmg type fallback * Actor getRollData * Remove comments --- lang/en.json | 5 ++ .../dialogs/damageReductionDialog.mjs | 2 +- .../sheets-configs/action-config.mjs | 6 +-- module/applications/ui/chatLog.mjs | 2 +- module/config/generalConfig.mjs | 4 +- module/config/itemConfig.mjs | 2 +- module/data/action/actionDice.mjs | 27 +++++----- module/data/action/baseAction.mjs | 11 +--- module/data/action/damageAction.mjs | 8 ++- module/data/actor/adversary.mjs | 9 +++- module/data/actor/base.mjs | 20 +++++-- module/data/actor/character.mjs | 5 +- module/data/actor/companion.mjs | 2 + module/data/actor/environment.mjs | 5 +- module/data/item/weapon.mjs | 1 + module/dice/damageRoll.mjs | 4 ++ module/dice/dhRoll.mjs | 2 +- module/documents/actor.mjs | 54 ++++++++++++------- module/helpers/utils.mjs | 27 +++------- styles/less/global/elements.less | 34 ++++++++++++ templates/actionTypes/damage.hbs | 2 +- templates/sheets/actors/adversary/sidebar.hbs | 8 +-- .../sheets/global/partials/inventory-item.hbs | 18 ++++--- templates/sheets/items/weapon/header.hbs | 6 ++- 24 files changed, 167 insertions(+), 97 deletions(-) diff --git a/lang/en.json b/lang/en.json index e14a3bc3..2e938914 100755 --- a/lang/en.json +++ b/lang/en.json @@ -987,6 +987,11 @@ "minor": "Minor", "none": "None" }, + "DamageResistance": { + "none": "None", + "resistance": "Resistance", + "immunity": "Immunity" + }, "DamageThresholds": { "title": "Damage Thresholds", "minor": "Minor", diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 0612089d..0a0ebce1 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -11,7 +11,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.actor = actor; this.damage = damage; - const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType]; + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); const maxArmorMarks = canApplyArmor ? Math.min( actor.system.armorScore - actor.system.armor.system.marks.value, diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index 0beb8d79..8823fa07 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -56,10 +56,6 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { id: 'effect', template: 'systems/daggerheart/templates/sheets-settings/action-settings/effect.hbs' } - /* form: { - id: 'action', - template: 'systems/daggerheart/templates/config/action.hbs' - } */ }; static TABS = { @@ -161,7 +157,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { container = foundry.utils.getProperty(this.action.parent, this.action.systemPath); let newActions; if (Array.isArray(container)) { - newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); // Find better way + newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data); } else newActions = data; diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 71532733..e8f699e4 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -215,7 +215,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); - target.actor.takeDamage(damage, message.system.roll.type); + target.actor.takeDamage(damage, message.system.damage.damageType); } }; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 282a8c9c..94efec1b 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -59,13 +59,13 @@ export const damageTypes = { id: 'physical', label: 'DAGGERHEART.CONFIG.DamageType.physical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.physical.abbreviation', - icon: ['fa-hand-fist'] + icon: 'fa-hand-fist' }, magical: { id: 'magical', label: 'DAGGERHEART.CONFIG.DamageType.magical.name', abbreviation: 'DAGGERHEART.CONFIG.DamageType.magical.abbreviation', - icon: ['fa-wand-sparkles'] + icon: 'fa-wand-sparkles' } }; diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index cdc8a235..ed77310c 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -395,7 +395,7 @@ export const armorFeatures = { img: 'icons/magic/defensive/barrier-shield-dome-pink.webp', changes: [ { - key: 'system.bonuses.damageReduction.magical', + key: 'system.resistance.magical.reduction', mode: 2, value: '@system.armorScore' } diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index 8b5bbe40..5cc2d10a 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -76,11 +76,7 @@ export class DHActionDiceData extends foundry.abstract.DataModel { }; } - getFormula(actor) { - /* const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total; - return this.custom.enabled - ? this.custom.formula - : `${multiplier ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`; */ + getFormula() { const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : `@${this.multiplier}`, bonus = this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''; return this.custom.enabled ? this.custom.formula : `${multiplier ?? 1}${this.dice}${bonus}`; @@ -93,7 +89,6 @@ export class DHDamageField extends fields.SchemaField { parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)), includeBase: new fields.BooleanField({ initial: false }) }; - // if (hasBase) damageFields.includeBase = new fields.BooleanField({ initial: true }); super(damageFields, options, context); } } @@ -102,15 +97,19 @@ export class DHDamageData extends foundry.abstract.DataModel { /** @override */ static defineSchema() { return { - // ...super.defineSchema(), base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }), - type: new fields.StringField({ - choices: CONFIG.DH.GENERAL.damageTypes, - initial: 'physical', - label: 'Type', - nullable: false, - required: true - }), + type: new fields.SetField( + new fields.StringField({ + choices: CONFIG.DH.GENERAL.damageTypes, + initial: 'physical', + nullable: false, + required: true + }), + { + label: 'Type', + initial: 'physical', + } + ), resultBased: new fields.BooleanField({ initial: false, label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index e2eafbf2..8fb15f50 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -179,16 +179,9 @@ export default class DHBaseAction extends foundry.abstract.DataModel { getRollData(data = {}) { const actorData = this.actor.getRollData(false); - // Remove when included directly in Actor getRollData - actorData.prof = actorData.proficiency?.total ?? 1; - actorData.cast = actorData.spellcast?.total ?? 1; + // Add Roll results to RollDatas actorData.result = data.roll?.total ?? 1; - /* actorData.scale = data.costs?.length - ? data.costs.reduce((a, c) => { - a[c.type] = c.value; - return a; - }, {}) - : 1; */ + actorData.scale = data.costs?.length // Right now only return the first scalable cost. ? (data.costs.find(c => c.scalable)?.total ?? 1) : 1; diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index 2dd88af4..3e840e60 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -10,7 +10,10 @@ export default class DHDamageAction extends DHBaseAction { } async rollDamage(event, data) { - let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '); + let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '), + damageTypes = [...new Set(this.damage.parts.reduce((a,c) => a.concat([...c.type]), []))]; + + damageTypes = !damageTypes.length ? ['physical'] : damageTypes; if (!formula || formula == '') return; let roll = { formula: formula, total: formula }, @@ -25,6 +28,7 @@ export default class DHDamageAction extends DHBaseAction { hasSave: this.hasSave, isCritical: data.system?.roll?.isCritical ?? false, source: data.system?.source, + damageTypes, event }; if (this.hasSave) config.onSave = this.save.damageMod; @@ -32,7 +36,7 @@ export default class DHDamageAction extends DHBaseAction { config.source.message = data._id; config.directDamage = false; } - + roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); } } diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 9bb5d5f8..cf3669a1 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -5,6 +5,7 @@ import BaseDataActor from './base.mjs'; const resourceField = () => new foundry.data.fields.SchemaField({ value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), + bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }), max: new foundry.data.fields.NumberField({ initial: 0, integer: true }) }); @@ -22,6 +23,7 @@ export default class DhpAdversary extends BaseDataActor { static defineSchema() { const fields = foundry.data.fields; return { + ...super.defineSchema(), tier: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.tiers, @@ -32,7 +34,6 @@ export default class DhpAdversary extends BaseDataActor { choices: CONFIG.DH.ACTOR.adversaryTypes, initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id }), - description: new fields.StringField(), motivesAndTactics: new fields.StringField(), notes: new fields.HTMLField(), difficulty: new fields.NumberField({ required: true, initial: 1, integer: true }), @@ -63,6 +64,7 @@ export default class DhpAdversary extends BaseDataActor { damage: { parts: [ { + type: ['physical'], value: { multiplier: 'flat' } @@ -93,4 +95,9 @@ export default class DhpAdversary extends BaseDataActor { get features() { return this.parent.items.filter(x => x.type === 'feature'); } + + prepareDerivedData() { + this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus; + this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus; + } } diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index 1b90968d..d7c7213e 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -1,5 +1,12 @@ import DHBaseActorSettings from "../../applications/sheets/api/actor-setting.mjs"; +const resistanceField = () => + new foundry.data.fields.SchemaField({ + resistance: new foundry.data.fields.BooleanField({ initial: false }), + immunity: new foundry.data.fields.BooleanField({ initial: false }), + reduction: new foundry.data.fields.NumberField({ integer: true, initial: 0 }) + }); + /** * Describes metadata about the actor data model type * @typedef {Object} ActorDataModelMetadata @@ -16,6 +23,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { type: 'base', isNPC: true, settingSheet: null, + hasResistances: true }; } @@ -27,10 +35,16 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { /** @inheritDoc */ static defineSchema() { const fields = foundry.data.fields; + const schema = {}; - return { - description: new fields.HTMLField({ required: true, nullable: true }) - }; + if(this.metadata.isNPC) + schema.description = new fields.HTMLField({ required: true, nullable: true }); + if(this.metadata.hasResistances) + schema.resistance = new fields.SchemaField({ + physical: resistanceField(), + magical: resistanceField() + }) + return schema; } /** diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 93926d9a..d26e368a 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -36,6 +36,7 @@ export default class DhCharacter extends BaseDataActor { const fields = foundry.data.fields; return { + ...super.defineSchema(), resources: new fields.SchemaField({ hitPoints: new fields.SchemaField({ value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), @@ -100,10 +101,6 @@ export default class DhCharacter extends BaseDataActor { levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ armorScore: new fields.NumberField({ integer: true, initial: 0 }), - damageReduction: new fields.SchemaField({ - physical: new fields.NumberField({ integer: true, initial: 0 }), - magical: new fields.NumberField({ integer: true, initial: 0 }) - }), damageThresholds: new fields.SchemaField({ severe: new fields.NumberField({ integer: true, initial: 0 }), major: new fields.NumberField({ integer: true, initial: 0 }) diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 88b149e3..b1c41ea3 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -20,6 +20,7 @@ export default class DhCompanion extends BaseDataActor { const fields = foundry.data.fields; return { + ...super.defineSchema(), partner: new ForeignDocumentUUIDField({ type: 'Actor' }), resources: new fields.SchemaField({ stress: new fields.SchemaField({ @@ -66,6 +67,7 @@ export default class DhCompanion extends BaseDataActor { damage: { parts: [ { + type: ['physical'], value: { dice: 'd6', multiplier: 'prof' diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs index 76990e88..2db1f039 100644 --- a/module/data/actor/environment.mjs +++ b/module/data/actor/environment.mjs @@ -9,20 +9,21 @@ export default class DhEnvironment extends BaseDataActor { return foundry.utils.mergeObject(super.metadata, { label: 'TYPES.Actor.environment', type: 'environment', - settingSheet: DHEnvironmentSettings + settingSheet: DHEnvironmentSettings, + hasResistances: false }); } static defineSchema() { const fields = foundry.data.fields; return { + ...super.defineSchema(), tier: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.tiers, initial: CONFIG.DH.GENERAL.tiers.tier1.id }), type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }), - description: new fields.StringField(), impulses: new fields.StringField(), difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }), potentialAdversaries: new fields.TypedObjectField( diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 80c8271d..8f580b6d 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -56,6 +56,7 @@ export default class DHWeapon extends BaseDataItem { damage: { parts: [ { + type: ['physical'], value: { multiplier: 'prof', dice: 'd8' diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index d9c4a61e..2182d3d0 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -14,6 +14,10 @@ export default class DamageRoll extends DHRoll { super.postEvaluate(roll, config); config.roll.type = config.type; config.roll.modifierTotal = this.calculateTotalModifiers(roll); + } + + static async buildPost(roll, config, message) { + await super.buildPost(roll, config, message); if (config.source?.message) { const chatMessage = ui.chat.collection.get(config.source.message); chatMessage.update({ 'system.damage': config }); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 46e7374e..87c9401e 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -56,8 +56,8 @@ export default class DHRoll extends Roll { // Create Chat Message if (config.source?.message) { + if(game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); } else { - const messageData = {}; config.message = await this.toMessage(roll, config); } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index aba0e0fa..0bd45690 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -370,7 +370,10 @@ export default class DhpActor extends Actor { } getRollData() { - return this.system; + const rollData = super.getRollData(); + rollData.prof = this.system.proficiency?.total ?? 1; + rollData.cast = this.system.spellcast?.total ?? 1; + return rollData; } formatRollModifier(roll) { @@ -462,7 +465,7 @@ export default class DhpActor extends Actor { const canUseArmor = this.system.armor && this.system.armor.system.marks.value < this.system.armorScore && - this.system.armorApplicableDamageTypes[type]; + type.every(t => this.system.armorApplicableDamageTypes[t] === true); const canUseStress = Object.keys(this.system.rules.damageReduction.stressDamageReduction).reduce((acc, x) => { const rule = this.system.rules.damageReduction.stressDamageReduction[x]; if (damageKeyToNumber(x) <= hpDamage) return acc || (rule.enabled && availableStress >= rule.cost); @@ -480,11 +483,9 @@ export default class DhpActor extends Actor { return; } - const flatReduction = this.system.bonuses.damageReduction[type]; - const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); - const hpDamage = this.convertDamageToThreshold(damage); + type = !Array.isArray(type) ? [type] : type; - if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null; + const hpDamage = this.calculateDamage(baseDamage, type); if (!hpDamage) return; @@ -511,6 +512,35 @@ export default class DhpActor extends Actor { if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null; } + calculateDamage(baseDamage, type) { + if (Hooks.call(`${CONFIG.DH.id}.preCalculateDamage`, this, baseDamage, type) === false) return null; + + /* if(this.system.resistance[type]?.immunity) return 0; + if(this.system.resistance[type]?.resistance) baseDamage = Math.ceil(baseDamage / 2); */ + if(this.canResist(type, 'immunity')) return 0; + if(this.canResist(type, 'resistance')) baseDamage = Math.ceil(baseDamage / 2); + + // const flatReduction = this.system.resistance[type].reduction; + const flatReduction = this.getDamageTypeReduction(type); + const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); + const hpDamage = this.convertDamageToThreshold(damage); + + if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, baseDamage, type) === false) return null; + + return hpDamage; + } + + canResist(type, resistance) { + if(!type) return 0; + return type.every(t => this.system.resistance[t]?.[resistance] === true); + } + + getDamageTypeReduction(type) { + if(!type) return 0; + const reduction = Object.entries(this.system.resistance).reduce((a, [index, value]) => type.includes(index) ? Math.min(value.reduction, a) : a, Infinity); + return reduction === Infinity ? 0 : reduction; + } + async takeHealing(resources) { resources.forEach(r => (r.value *= -1)); await this.modifyResource(resources); @@ -553,18 +583,6 @@ export default class DhpActor extends Actor { u.resources, u.target.uuid ); - /* if (game.user.isGM) { - await u.target.update(u.resources); - } else { - await game.socket.emit(`system.${CONFIG.DH.id}`, { - action: socketEvent.GMUpdate, - data: { - action: GMUpdateEvent.UpdateDocument, - uuid: u.target.uuid, - update: u.resources - } - }); - } */ } }); } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 8156736d..40a71ac7 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -236,16 +236,7 @@ Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false }; export const getDamageKey = damage => { - switch (damage) { - case 3: - return 'severe'; - case 2: - return 'major'; - case 1: - return 'minor'; - case 0: - return 'none'; - } + return ['none', 'minor', 'major', 'severe'][damage]; }; export const getDamageLabel = damage => { @@ -253,16 +244,12 @@ export const getDamageLabel = damage => { }; export const damageKeyToNumber = key => { - switch (key) { - case 'severe': - return 3; - case 'major': - return 2; - case 'minor': - return 1; - case 'none': - return 0; - } + return { + 'none': 0, + 'minor': 1, + 'major': 2, + 'severe': 3 + }[key]; }; export default function constructHTMLButton({ diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 84c90336..ab519a1c 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -104,6 +104,40 @@ } } + multi-select { + position: relative; + height: 34px; + .tags { + justify-content: flex-start; + margin: 5px; + height: inherit; + .tag { + box-shadow: 0 0 0 1.1em #E5E5E5 inset; + vertical-align: top; + box-sizing: border-box; + max-width: 100%; + padding: 0.3em 0 0.3em 0.5em; + color: black; + border-radius: 3px; + white-space: nowrap; + transition: .13s ease-out; + height: 22px; + font-size: .9rem; + gap: 0.5em; + z-index: 1; + .remove { + font-size: 10px; + margin-inline: auto 4.6666666667px; + } + } + } + select { + position: absolute; + height: inherit; + outline: initial; + } + } + p { margin: 0; } diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 59519e6d..cbd1f503 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -46,7 +46,7 @@ {{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
{{/if}} - {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} + {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} {{#unless dmg.base}}
{{/unless}} diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index b26c1b81..ad23ab25 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -10,12 +10,12 @@

/

-

{{source.system.resources.hitPoints.max}}

+

{{source.system.resources.hitPoints.maxTotal}}

HP

@@ -26,12 +26,12 @@

/

-

{{source.system.resources.stress.max}}

+

{{source.system.resources.stress.maxTotal}}

Stress

diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index eae3dd5f..117783a5 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -6,7 +6,7 @@ {{else}}
{{item.name}}
{{/if}} - {{#if (eq type 'weapon')}} + {{#if (eq type 'weapon')}}
{{#if isSidebar}}
@@ -16,11 +16,11 @@ - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} {{!-- ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' item.system.attack.damage.parts.0.type '.abbreviation')}}) --}} - {{#with (lookup @root.config.GENERAL.damageTypes item.system.attack.damage.parts.0.type)}} - {{#each icon}} - - {{/each}} - {{/with}} + {{#each item.system.attack.damage.parts.0.type as | type | }} + {{#with (lookup @root.config.GENERAL.damageTypes type)}} + + {{/with}} + {{/each}}
{{else}} @@ -32,7 +32,11 @@
{{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' item.system.attack.damage.parts.0.type '.abbreviation')}}) + ( + {{#each item.system.attack.damage.parts.0.type}} + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} + {{/each}} + )
{{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} diff --git a/templates/sheets/items/weapon/header.hbs b/templates/sheets/items/weapon/header.hbs index 74613699..ee0198ba 100644 --- a/templates/sheets/items/weapon/header.hbs +++ b/templates/sheets/items/weapon/header.hbs @@ -15,7 +15,11 @@ {{localize (concat 'DAGGERHEART.CONFIG.Range.' source.system.attack.range '.name')}} - {{source.system.attack.damage.parts.0.value.dice}}{{#if source.system.attack.damage.parts.0.value.bonus}} + {{source.system.attack.damage.parts.0.value.bonus}}{{/if}} - ({{localize (concat 'DAGGERHEART.CONFIG.DamageType.' source.system.attack.damage.parts.0.type '.abbreviation')}}) + ( + {{#each source.system.attack.damage.parts.0.type}} + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} + {{/each}} + ) - {{localize (concat 'DAGGERHEART.CONFIG.Burden.' source.system.burden)}} From 687500f191557f0112fdbd1348c46c1e8552ae13 Mon Sep 17 00:00:00 2001 From: Psitacus <59754077+Psitacus@users.noreply.github.com> Date: Sat, 12 Jul 2025 19:07:22 -0600 Subject: [PATCH 20/58] Iss4 - create a way to attach attach items to armor and weapons (#310) * add basic drag drop window * add better field * make effects copy onto actor on attachment * make items from inventory draggable * working drop from inventory * remove duplication issue * add attachment only flag and logic * add weapons to attachables * remove debug logs * try to make it drier * remove unecessary try catch * remove extra configs * remove superfluous comments * remove spurious defenses * make drier * remove unecessary code * deduplicate and simplify * its a desert * standardize to be more similar to class item code * fix bug of duplicate effects being created * fix localization string * fix bug of item equiping and un equiping * remove this since were not going to be using attachmentonly * update attachment tab with comments * remove attachment only logic in favor of just transfer * change flags * change armor and weapon to be attachableItem * change armor and weapon to be attachableItem * change weapon to use mixin * add mixin to armor * move everything to mixin sheet * refactor code for review comments * cleanup and somehow git is ignoring some changes * see if this picks up the changes now * Import/Export updates --------- Co-authored-by: psitacus Co-authored-by: WBHarry --- lang/en.json | 8 +- .../applications/sheets/actors/character.mjs | 22 ++- module/applications/sheets/api/_modules.mjs | 1 + .../sheets/api/item-attachment-sheet.mjs | 90 +++++++++++ module/applications/sheets/items/armor.mjs | 7 +- module/applications/sheets/items/weapon.mjs | 8 +- module/config/flagsConfig.mjs | 2 + module/data/item/_module.mjs | 3 + module/data/item/armor.mjs | 5 +- module/data/item/attachableItem.mjs | 152 ++++++++++++++++++ module/data/item/weapon.mjs | 6 +- module/documents/activeEffect.mjs | 30 +++- styles/less/global/index.less | 1 + styles/less/global/tab-attachments.less | 7 + templates/sheets/activeEffect/details.hbs | 2 +- .../sheets/global/partials/inventory-item.hbs | 2 +- .../sheets/global/tabs/tab-attachments.hbs | 29 ++++ templates/sheets/items/weapon/attachments.hbs | 0 18 files changed, 357 insertions(+), 18 deletions(-) create mode 100644 module/applications/sheets/api/item-attachment-sheet.mjs create mode 100644 module/data/item/attachableItem.mjs create mode 100644 styles/less/global/tab-attachments.less create mode 100644 templates/sheets/global/tabs/tab-attachments.hbs create mode 100644 templates/sheets/items/weapon/attachments.hbs diff --git a/lang/en.json b/lang/en.json index 2e938914..5497d5e6 100755 --- a/lang/en.json +++ b/lang/en.json @@ -389,6 +389,7 @@ "default": "Default Ownership" } }, + "CONFIG": { "ActionType": { "passive": "Passive", @@ -958,6 +959,10 @@ "stress": { "name": "Stress" } + }, + "Attachments": { + "attachHint": "Drop items here to attach them", + "transferHint": "If checked, this effect will be applied to any actor that owns this Effect's parent Item. The effect is always applied if this Item is attached to another one." } }, "GENERAL": { @@ -1093,7 +1098,8 @@ "optional": "Optional", "recovery": "Recovery", "setup": "Setup", - "equipment": "Equipment" + "equipment": "Equipment", + "attachments": "Attachments" }, "Tiers": { "singular": "Tier", diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index ae7ffbf9..5f0199f3 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -30,7 +30,12 @@ export default class CharacterSheet extends DHBaseActorSheet { window: { resizable: true }, - dragDrop: [], + dragDrop: [ + { + dragSelector: '[data-item-id][draggable="true"]', + dropSelector: null + } + ], contextMenus: [ { handler: CharacterSheet._getContextMenuOptions, @@ -665,11 +670,24 @@ export default class CharacterSheet extends DHBaseActorSheet { } } - async _onDragStart(_, event) { + async _onDragStart(event) { + const item = this.getItem(event); + + const dragData = { + type: item.documentName, + uuid: item.uuid + }; + + event.dataTransfer.setData('text/plain', JSON.stringify(dragData)); + super._onDragStart(event); } async _onDrop(event) { + // Prevent event bubbling to avoid duplicate handling + event.preventDefault(); + event.stopPropagation(); + super._onDrop(event); this._onDropItem(event, TextEditor.getDragEventData(event)); } diff --git a/module/applications/sheets/api/_modules.mjs b/module/applications/sheets/api/_modules.mjs index cb7eee62..e6caece1 100644 --- a/module/applications/sheets/api/_modules.mjs +++ b/module/applications/sheets/api/_modules.mjs @@ -1,5 +1,6 @@ export { default as DHApplicationMixin } from './application-mixin.mjs'; export { default as DHBaseItemSheet } from './base-item.mjs'; export { default as DHHeritageSheet } from './heritage-sheet.mjs'; +export { default as DHItemAttachmentSheet } from './item-attachment-sheet.mjs'; export { default as DHBaseActorSheet } from './base-actor.mjs'; export { default as DHBaseActorSettings } from './actor-setting.mjs'; diff --git a/module/applications/sheets/api/item-attachment-sheet.mjs b/module/applications/sheets/api/item-attachment-sheet.mjs new file mode 100644 index 00000000..e89c7cba --- /dev/null +++ b/module/applications/sheets/api/item-attachment-sheet.mjs @@ -0,0 +1,90 @@ + +export default function ItemAttachmentSheet(Base) { + return class extends Base { + static DEFAULT_OPTIONS = { + ...super.DEFAULT_OPTIONS, + dragDrop: [ + ...(super.DEFAULT_OPTIONS.dragDrop || []), + { dragSelector: null, dropSelector: '.attachments-section' } + ], + actions: { + ...super.DEFAULT_OPTIONS.actions, + removeAttachment: this.#removeAttachment + } + }; + + static PARTS = { + ...super.PARTS, + attachments: { + template: 'systems/daggerheart/templates/sheets/global/tabs/tab-attachments.hbs', + scrollable: ['.attachments'] + } + }; + + static TABS = { + ...super.TABS, + primary: { + ...super.TABS?.primary, + tabs: [ + ...(super.TABS?.primary?.tabs || []), + { id: 'attachments' } + ], + initial: super.TABS?.primary?.initial || 'description', + labelPrefix: super.TABS?.primary?.labelPrefix || 'DAGGERHEART.GENERAL.Tabs' + } + }; + + async _preparePartContext(partId, context) { + await super._preparePartContext(partId, context); + + if (partId === 'attachments') { + context.attachedItems = await prepareAttachmentContext(this.document); + } + + return context; + } + + async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + + const attachmentsSection = event.target.closest('.attachments-section'); + if (!attachmentsSection) return super._onDrop(event); + + event.preventDefault(); + event.stopPropagation(); + + const item = await Item.implementation.fromDropData(data); + if (!item) return; + + // Call the data model's public method + await this.document.system.addAttachment(item); + } + + + static async #removeAttachment(event, target) { + // Call the data model's public method + await this.document.system.removeAttachment(target.dataset.uuid); +} + + async _preparePartContext(partId, context) { + await super._preparePartContext(partId, context); + + if (partId === 'attachments') { + // Keep this simple UI preparation in the mixin + const attachedUUIDs = this.document.system.attached; + context.attachedItems = await Promise.all( + attachedUUIDs.map(async uuid => { + const item = await fromUuid(uuid); + return { + uuid: uuid, + name: item?.name || 'Unknown Item', + img: item?.img || 'icons/svg/item-bag.svg' + }; + }) + ); + } + + return context; + } + }; +} \ No newline at end of file diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 21fbfea8..a6413cf0 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -1,10 +1,10 @@ import DHBaseItemSheet from '../api/base-item.mjs'; +import ItemAttachmentSheet from '../api/item-attachment-sheet.mjs'; -export default class ArmorSheet extends DHBaseItemSheet { +export default class ArmorSheet extends ItemAttachmentSheet(DHBaseItemSheet) { /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['armor'], - dragDrop: [{ dragSelector: null, dropSelector: null }], tagifyConfigs: [ { selector: '.features-input', @@ -26,7 +26,8 @@ export default class ArmorSheet extends DHBaseItemSheet { settings: { template: 'systems/daggerheart/templates/sheets/items/armor/settings.hbs', scrollable: ['.settings'] - } + }, + ...super.PARTS, }; /**@inheritdoc */ diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index 77396998..e89c3dce 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -1,6 +1,7 @@ import DHBaseItemSheet from '../api/base-item.mjs'; +import ItemAttachmentSheet from '../api/item-attachment-sheet.mjs'; -export default class WeaponSheet extends DHBaseItemSheet { +export default class WeaponSheet extends ItemAttachmentSheet(DHBaseItemSheet) { /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['weapon'], @@ -25,12 +26,13 @@ export default class WeaponSheet extends DHBaseItemSheet { settings: { template: 'systems/daggerheart/templates/sheets/items/weapon/settings.hbs', scrollable: ['.settings'] - } + }, + ...super.PARTS, }; /**@inheritdoc */ async _preparePartContext(partId, context) { - super._preparePartContext(partId, context); + await super._preparePartContext(partId, context); switch (partId) { case 'settings': context.features = this.document.system.weaponFeatures.map(x => x.value); diff --git a/module/config/flagsConfig.mjs b/module/config/flagsConfig.mjs index 252863f1..0c112231 100644 --- a/module/config/flagsConfig.mjs +++ b/module/config/flagsConfig.mjs @@ -7,3 +7,5 @@ export const encounterCountdown = { simple: 'countdown-encounter-simple', position: 'countdown-encounter-position' }; + +export const itemAttachmentSource = 'attachmentSource'; \ No newline at end of file diff --git a/module/data/item/_module.mjs b/module/data/item/_module.mjs index a29d1595..bed18eb5 100644 --- a/module/data/item/_module.mjs +++ b/module/data/item/_module.mjs @@ -1,5 +1,6 @@ import DHAncestry from './ancestry.mjs'; import DHArmor from './armor.mjs'; +import DHAttachableItem from './attachableItem.mjs'; import DHClass from './class.mjs'; import DHCommunity from './community.mjs'; import DHConsumable from './consumable.mjs'; @@ -13,6 +14,7 @@ import DHBeastform from './beastform.mjs'; export { DHAncestry, DHArmor, + DHAttachableItem, DHClass, DHCommunity, DHConsumable, @@ -27,6 +29,7 @@ export { export const config = { ancestry: DHAncestry, armor: DHArmor, + attachableItem: DHAttachableItem, class: DHClass, community: DHCommunity, consumable: DHConsumable, diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index bf2bf73e..7a8b06c0 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -1,8 +1,9 @@ -import BaseDataItem from './base.mjs'; +import AttachableItem from './attachableItem.mjs'; import ActionField from '../fields/actionField.mjs'; import { armorFeatures } from '../../config/itemConfig.mjs'; +import { actionsTypes } from '../action/_module.mjs'; -export default class DHArmor extends BaseDataItem { +export default class DHArmor extends AttachableItem { /** @inheritDoc */ static get metadata() { return foundry.utils.mergeObject(super.metadata, { diff --git a/module/data/item/attachableItem.mjs b/module/data/item/attachableItem.mjs new file mode 100644 index 00000000..2b0608eb --- /dev/null +++ b/module/data/item/attachableItem.mjs @@ -0,0 +1,152 @@ +import BaseDataItem from './base.mjs'; + +export default class AttachableItem extends BaseDataItem { + static defineSchema() { + const fields = foundry.data.fields; + return { + ...super.defineSchema(), + attached: new fields.ArrayField(new fields.DocumentUUIDField({ type: "Item", nullable: true })) + }; + } + + async _preUpdate(changes, options, user) { + const allowed = await super._preUpdate(changes, options, user); + if (allowed === false) return false; + + // Handle equipped status changes for attachment effects + if (changes.system?.equipped !== undefined && changes.system.equipped !== this.equipped) { + await this.#handleAttachmentEffectsOnEquipChange(changes.system.equipped); + } + } + + async #handleAttachmentEffectsOnEquipChange(newEquippedStatus) { + const actor = this.parent.parent?.type === 'character' ? this.parent.parent : this.parent.parent?.parent; + const parentType = this.parent.type; + + if (!actor || !this.attached?.length) { + return; + } + + if (newEquippedStatus) { + // Item is being equipped - add attachment effects + for (const attachedUuid of this.attached) { + const attachedItem = await fromUuid(attachedUuid); + if (attachedItem && attachedItem.effects.size > 0) { + await this.#copyAttachmentEffectsToActor({ + attachedItem, + attachedUuid, + parentType + }); + } + } + } else { + // Item is being unequipped - remove attachment effects + await this.#removeAllAttachmentEffects(parentType); + } + } + + async #copyAttachmentEffectsToActor({ attachedItem, attachedUuid, parentType }) { + const actor = this.parent.parent; + if (!actor || !attachedItem.effects.size > 0 || !this.equipped) { + return []; + } + + const effectsToCreate = []; + for (const effect of attachedItem.effects) { + const effectData = effect.toObject(); + effectData.origin = `${this.parent.uuid}:${attachedUuid}`; + + const attachmentSource = { + itemUuid: attachedUuid, + originalEffectId: effect.id + }; + attachmentSource[`${parentType}Uuid`] = this.parent.uuid; + + effectData.flags = { + ...effectData.flags, + [CONFIG.DH.id]: { + ...effectData.flags?.[CONFIG.DH.id], + [CONFIG.DH.FLAGS.itemAttachmentSource]: attachmentSource + } + }; + effectsToCreate.push(effectData); + } + + if (effectsToCreate.length > 0) { + return await actor.createEmbeddedDocuments('ActiveEffect', effectsToCreate); + } + + return []; + } + + async #removeAllAttachmentEffects(parentType) { + const actor = this.parent.parent; + if (!actor) return; + + const parentUuidProperty = `${parentType}Uuid`; + const effectsToRemove = actor.effects.filter(effect => { + const attachmentSource = effect.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.itemAttachmentSource); + return attachmentSource && attachmentSource[parentUuidProperty] === this.parent.uuid; + }); + + if (effectsToRemove.length > 0) { + await actor.deleteEmbeddedDocuments('ActiveEffect', effectsToRemove.map(e => e.id)); + } + } + + /** + * Public method for adding an attachment + */ + async addAttachment(droppedItem) { + const newUUID = droppedItem.uuid; + + if (this.attached.includes(newUUID)) { + ui.notifications.warn(`${droppedItem.name} is already attached to this ${this.parent.type}.`); + return; + } + + const updatedAttached = [...this.attached, newUUID]; + await this.parent.update({ + 'system.attached': updatedAttached + }); + + // Copy effects if equipped + if (this.equipped && droppedItem.effects.size > 0) { + await this.#copyAttachmentEffectsToActor({ + attachedItem: droppedItem, + attachedUuid: newUUID, + parentType: this.parent.type + }); + } + } + + /** + * Public method for removing an attachment + */ + async removeAttachment(attachedUuid) { + await this.parent.update({ + 'system.attached': this.attached.filter(uuid => uuid !== attachedUuid) + }); + + // Remove effects + await this.#removeAttachmentEffects(attachedUuid); + } + + async #removeAttachmentEffects(attachedUuid) { + const actor = this.parent.parent; + if (!actor) return; + + const parentType = this.parent.type; + const parentUuidProperty = `${parentType}Uuid`; + const effectsToRemove = actor.effects.filter(effect => { + const attachmentSource = effect.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.itemAttachmentSource); + return attachmentSource && + attachmentSource[parentUuidProperty] === this.parent.uuid && + attachmentSource.itemUuid === attachedUuid; + }); + + if (effectsToRemove.length > 0) { + await actor.deleteEmbeddedDocuments('ActiveEffect', effectsToRemove.map(e => e.id)); + } + } +} \ No newline at end of file diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 8f580b6d..82b4ba80 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -1,8 +1,8 @@ -import BaseDataItem from './base.mjs'; +import AttachableItem from './attachableItem.mjs'; import { actionsTypes } from '../action/_module.mjs'; import ActionField from '../fields/actionField.mjs'; -export default class DHWeapon extends BaseDataItem { +export default class DHWeapon extends AttachableItem { /** @inheritDoc */ static get metadata() { return foundry.utils.mergeObject(super.metadata, { @@ -37,7 +37,7 @@ export default class DHWeapon extends BaseDataItem { actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) ), - attack: new ActionField({ + attack: new ActionField({ initial: { name: 'Attack', img: 'icons/skills/melee/blood-slash-foam-red.webp', diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 1abc2d17..03ac73bc 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -1,16 +1,42 @@ export default class DhActiveEffect extends ActiveEffect { get isSuppressed() { - if (['weapon', 'armor'].includes(this.parent.type)) { + // If this is a copied effect from an attachment, never suppress it + // (These effects have attachmentSource metadata) + if (this.flags?.daggerheart?.attachmentSource) { + return false; + } + + // Then apply the standard suppression rules + if (['weapon', 'armor'].includes(this.parent?.type)) { return !this.parent.system.equipped; } - if (this.parent.type === 'domainCard') { + if (this.parent?.type === 'domainCard') { return this.parent.system.inVault; } return super.isSuppressed; } + /** + * Check if the parent item is currently attached to another item + * @returns {boolean} + */ + get isAttached() { + if (!this.parent || !this.parent.parent) return false; + + // Check if this item's UUID is in any actor's armor or weapon attachment lists + const actor = this.parent.parent; + if (!actor || !actor.items) return false; + + return actor.items.some(item => { + return (item.type === 'armor' || item.type === 'weapon') && + item.system?.attached && + Array.isArray(item.system.attached) && + item.system.attached.includes(this.parent.uuid); + }); + } + async _preCreate(data, options, user) { const update = {}; if (!data.img) { diff --git a/styles/less/global/index.less b/styles/less/global/index.less index 0559c7ff..932e48ab 100644 --- a/styles/less/global/index.less +++ b/styles/less/global/index.less @@ -12,3 +12,4 @@ @import './inventory-fieldset-items.less'; @import './prose-mirror.less'; @import './filter-menu.less'; +@import './tab-attachments.less'; diff --git a/styles/less/global/tab-attachments.less b/styles/less/global/tab-attachments.less new file mode 100644 index 00000000..c283269e --- /dev/null +++ b/styles/less/global/tab-attachments.less @@ -0,0 +1,7 @@ +.daggerheart.dh-style { + .tab.attachments { + .attached-items { + width: 100%; + } + } +} \ No newline at end of file diff --git a/templates/sheets/activeEffect/details.hbs b/templates/sheets/activeEffect/details.hbs index 8ff72b98..8a862c53 100644 --- a/templates/sheets/activeEffect/details.hbs +++ b/templates/sheets/activeEffect/details.hbs @@ -7,7 +7,7 @@ {{formGroup fields.origin value=source.origin rootId=rootId disabled=true}} {{/if}} {{#if isItemEffect}} - {{formGroup fields.transfer value=source.transfer rootId=rootId label=legacyTransfer.label hint=legacyTransfer.hint}} + {{formGroup fields.transfer value=source.transfer rootId=rootId label=legacyTransfer.label hint=(localize "DAGGERHEART.EFFECTS.Attachments.transferHint")}} {{/if}} {{formGroup fields.statuses value=source.statuses options=statuses rootId=rootId classes="statuses"}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index 117783a5..21b7de61 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -1,4 +1,4 @@ -
  • +
  • {{#if isCompanion}} diff --git a/templates/sheets/global/tabs/tab-attachments.hbs b/templates/sheets/global/tabs/tab-attachments.hbs new file mode 100644 index 00000000..f7f8b716 --- /dev/null +++ b/templates/sheets/global/tabs/tab-attachments.hbs @@ -0,0 +1,29 @@ +
    +
    + {{localize tabs.attachments.label}} + + {{#if attachedItems}} +
    + {{#each attachedItems as |item|}} +
    + {{item.name}} +
    +
    {{item.name}}
    +
    +
    + +
    +
    + {{/each}} +
    + {{/if}} + +
    + {{localize "DAGGERHEART.EFFECTS.Attachments.attachHint"}} +
    +
    +
    diff --git a/templates/sheets/items/weapon/attachments.hbs b/templates/sheets/items/weapon/attachments.hbs new file mode 100644 index 00000000..e69de29b From 0fd62c610d8a79827e90b698143373ff04ac315b Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Sun, 13 Jul 2025 18:39:23 +0200 Subject: [PATCH 21/58] actors datas max/total rework (#332) * actors datas max/total rework * Removed unused translation --------- Co-authored-by: WBHarry --- lang/en.json | 2 +- .../dialogs/damageReductionDialog.mjs | 4 +- .../applications/levelup/characterLevelup.mjs | 20 ++-- .../applications/levelup/companionLevelup.mjs | 8 +- module/applications/levelup/levelup.mjs | 20 ++-- .../applications/sheets/actors/adversary.mjs | 2 +- .../applications/sheets/actors/character.mjs | 2 +- .../applications/sheets/actors/companion.mjs | 2 +- module/config/itemConfig.mjs | 52 +++++------ module/data/action/baseAction.mjs | 10 +- module/data/actor/adversary.mjs | 11 +-- module/data/actor/character.mjs | 75 +++++---------- module/data/actor/companion.mjs | 34 ++----- module/data/item/subclass.mjs | 6 +- module/dice/d20Roll.mjs | 2 +- module/dice/dualityRoll.mjs | 2 +- module/documents/actor.mjs | 93 +------------------ module/helpers/handlebarsHelper.mjs | 2 +- templates/dialogs/damageReduction.hbs | 2 +- .../adversary-settings/experiences.hbs | 2 +- .../companion-settings/details.hbs | 2 +- templates/sheets/actors/adversary/sidebar.hbs | 12 +-- templates/sheets/actors/character/header.hbs | 8 +- templates/sheets/actors/character/sidebar.hbs | 14 +-- templates/sheets/actors/companion/header.hbs | 6 +- .../sheets/actors/companion/tempMain.hbs | 44 --------- templates/ui/tooltip/adversary.hbs | 2 +- 27 files changed, 133 insertions(+), 306 deletions(-) delete mode 100644 templates/sheets/actors/companion/tempMain.hbs diff --git a/lang/en.json b/lang/en.json index 5497d5e6..bb67b6c2 100755 --- a/lang/en.json +++ b/lang/en.json @@ -389,7 +389,7 @@ "default": "Default Ownership" } }, - + "CONFIG": { "ActionType": { "passive": "Passive", diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 0a0ebce1..984106d7 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -110,7 +110,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap ? { value: this.actor.system.resources.stress.value + selectedStressMarks.length + stressReductionStress, - maxTotal: this.actor.system.resources.stress.maxTotal + max: this.actor.system.resources.stress.max } : null; @@ -197,7 +197,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap : 0; const currentStress = this.actor.system.resources.stress.value + selectedStressMarks.length + stressReductionStress; - if (currentStress + stressReduction.cost > this.actor.system.resources.stress.maxTotal) { + if (currentStress + stressReduction.cost > this.actor.system.resources.stress.max) { ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.notEnoughStress')); return; } diff --git a/module/applications/levelup/characterLevelup.mjs b/module/applications/levelup/characterLevelup.mjs index 6dc6f4c3..d6bbe2db 100644 --- a/module/applications/levelup/characterLevelup.mjs +++ b/module/applications/levelup/characterLevelup.mjs @@ -223,8 +223,8 @@ export default class DhCharacterLevelUp extends LevelUpBase { context.achievements = { proficiency: { - old: this.actor.system.proficiency.total, - new: this.actor.system.proficiency.total + achivementProficiency, + old: this.actor.system.proficiency, + new: this.actor.system.proficiency + achivementProficiency, shown: achivementProficiency > 0 }, damageThresholds: { @@ -332,16 +332,16 @@ export default class DhCharacterLevelUp extends LevelUpBase { new: context.achievements.proficiency.new + (advancement.proficiency ?? 0) }, hitPoints: { - old: this.actor.system.resources.hitPoints.maxTotal, - new: this.actor.system.resources.hitPoints.maxTotal + (advancement.hitPoint ?? 0) + old: this.actor.system.resources.hitPoints.max, + new: this.actor.system.resources.hitPoints.max + (advancement.hitPoint ?? 0) }, stress: { - old: this.actor.system.resources.stress.maxTotal, - new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0) + old: this.actor.system.resources.stress.max, + new: this.actor.system.resources.stress.max + (advancement.stress ?? 0) }, evasion: { - old: this.actor.system.evasion.total, - new: this.actor.system.evasion.total + (advancement.evasion ?? 0) + old: this.actor.system.evasion, + new: this.actor.system.evasion + (advancement.evasion ?? 0) } }, traits: Object.keys(this.actor.system.traits).reduce((acc, traitKey) => { @@ -349,8 +349,8 @@ export default class DhCharacterLevelUp extends LevelUpBase { if (!acc) acc = {}; acc[traitKey] = { label: game.i18n.localize(abilities[traitKey].label), - old: this.actor.system.traits[traitKey].total, - new: this.actor.system.traits[traitKey].total + advancement.trait[traitKey] + old: this.actor.system.traits[traitKey].max, + new: this.actor.system.traits[traitKey].max + advancement.trait[traitKey] }; } return acc; diff --git a/module/applications/levelup/companionLevelup.mjs b/module/applications/levelup/companionLevelup.mjs index de411572..2fcc42a0 100644 --- a/module/applications/levelup/companionLevelup.mjs +++ b/module/applications/levelup/companionLevelup.mjs @@ -122,12 +122,12 @@ export default class DhCompanionLevelUp extends BaseLevelUp { context.advancements = { statistics: { stress: { - old: this.actor.system.resources.stress.maxTotal, - new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0) + old: this.actor.system.resources.stress.max, + new: this.actor.system.resources.stress.max + (advancement.stress ?? 0) }, evasion: { - old: this.actor.system.evasion.total, - new: this.actor.system.evasion.total + (advancement.evasion ?? 0) + old: this.actor.system.evasion, + new: this.actor.system.evasion + (advancement.evasion ?? 0) } }, experiences: diff --git a/module/applications/levelup/levelup.mjs b/module/applications/levelup/levelup.mjs index 93910fe7..141a0a06 100644 --- a/module/applications/levelup/levelup.mjs +++ b/module/applications/levelup/levelup.mjs @@ -157,8 +157,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) context.achievements = { proficiency: { - old: this.actor.system.proficiency.total, - new: this.actor.system.proficiency.total + achivementProficiency, + old: this.actor.system.proficiency, + new: this.actor.system.proficiency + achivementProficiency, shown: achivementProficiency > 0 }, damageThresholds: { @@ -265,16 +265,16 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) new: context.achievements.proficiency.new + (advancement.proficiency ?? 0) }, hitPoints: { - old: this.actor.system.resources.hitPoints.maxTotal, - new: this.actor.system.resources.hitPoints.maxTotal + (advancement.hitPoint ?? 0) + old: this.actor.system.resources.hitPoints.max, + new: this.actor.system.resources.hitPoints.max + (advancement.hitPoint ?? 0) }, stress: { - old: this.actor.system.resources.stress.maxTotal, - new: this.actor.system.resources.stress.maxTotal + (advancement.stress ?? 0) + old: this.actor.system.resources.stress.max, + new: this.actor.system.resources.stress.max + (advancement.stress ?? 0) }, evasion: { - old: this.actor.system.evasion.total, - new: this.actor.system.evasion.total + (advancement.evasion ?? 0) + old: this.actor.system.evasion, + new: this.actor.system.evasion + (advancement.evasion ?? 0) } }, traits: Object.keys(this.actor.system.traits).reduce((acc, traitKey) => { @@ -282,8 +282,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) if (!acc) acc = {}; acc[traitKey] = { label: game.i18n.localize(abilities[traitKey].label), - old: this.actor.system.traits[traitKey].total, - new: this.actor.system.traits[traitKey].total + advancement.trait[traitKey] + old: this.actor.system.traits[traitKey].value, + new: this.actor.system.traits[traitKey].value + advancement.trait[traitKey] }; } return acc; diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 0b01ebee..af89abe6 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -93,7 +93,7 @@ export default class AdversarySheet extends DHBaseActorSheet { const cls = getDocumentClass('ChatMessage'); const systemData = { name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'), - description: `${experience.name} ${experience.total.signedString()}` + description: `${experience.name} ${experience.value.signedString()}` }; const msg = new cls({ type: 'abilityUse', diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 5f0199f3..8a18dd22 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -650,7 +650,7 @@ export default class CharacterSheet extends DHBaseActorSheet { const cls = getDocumentClass('ChatMessage'); const systemData = { name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'), - description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}` + description: `${experience.name} ${experience.value.signedString()}` }; const msg = new cls({ type: 'abilityUse', diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs index 042a4bfa..a1d00d96 100644 --- a/module/applications/sheets/actors/companion.mjs +++ b/module/applications/sheets/actors/companion.mjs @@ -59,7 +59,7 @@ export default class DhCompanionSheet extends DHBaseActorSheet { const cls = getDocumentClass('ChatMessage'); const systemData = { name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'), - description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}` + description: `${experience.name} ${experience.value.signedString()}` }; const msg = new cls({ type: 'abilityUse', diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index ed77310c..1d6b96b8 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -41,37 +41,37 @@ export const armorFeatures = { img: 'icons/magic/control/buff-flight-wings-red.webp', changes: [ { - key: 'system.traits.agility.bonus', + key: 'system.traits.agility.value', mode: 2, value: '-1' }, { - key: 'system.traits.strength.bonus', + key: 'system.traits.strength.value', mode: 2, value: '-1' }, { - key: 'system.traits.finesse.bonus', + key: 'system.traits.finesse.value', mode: 2, value: '-1' }, { - key: 'system.traits.instinct.bonus', + key: 'system.traits.instinct.value', mode: 2, value: '-1' }, { - key: 'system.traits.presence.bonus', + key: 'system.traits.presence.value', mode: 2, value: '-1' }, { - key: 'system.traits.knowledge.bonus', + key: 'system.traits.knowledge.value', mode: 2, value: '-1' }, { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' } @@ -89,7 +89,7 @@ export const armorFeatures = { img: 'icons/magic/movement/abstract-ribbons-red-orange.webp', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '1' } @@ -125,7 +125,7 @@ export const armorFeatures = { img: 'icons/magic/control/control-influence-crown-gold.webp', changes: [ { - key: 'system.traits.presence.bonus', + key: 'system.traits.presence.value', mode: 2, value: '1' } @@ -143,7 +143,7 @@ export const armorFeatures = { img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' } @@ -372,12 +372,12 @@ export const armorFeatures = { img: 'icons/commodities/metal/ingot-stamped-steel.webp', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-2' }, { - key: 'system.traits.agility.bonus', + key: 'system.traits.agility.value', mode: 2, value: '-1' } @@ -413,7 +413,7 @@ export const weaponFeatures = { { changes: [ { - key: 'system.bonuses.armorScore', + key: 'system.armorScore', mode: 2, value: 'ITEM.@system.tier + 1' } @@ -422,7 +422,7 @@ export const weaponFeatures = { { changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' } @@ -474,7 +474,7 @@ export const weaponFeatures = { { changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' } @@ -529,7 +529,7 @@ export const weaponFeatures = { img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp', changes: [ { - key: 'system.proficiency.bonus', + key: 'system.proficiency', mode: 2, value: '1' } @@ -569,7 +569,7 @@ export const weaponFeatures = { img: 'icons/commodities/metal/mail-plate-steel.webp', changes: [ { - key: 'system.traits.finesse.bonus', + key: 'system.traits.finesse.value', mode: 2, value: '-1' } @@ -615,7 +615,7 @@ export const weaponFeatures = { img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '@system.armorScore' } @@ -645,7 +645,7 @@ export const weaponFeatures = { img: 'icons/skills/melee/strike-flail-spiked-pink.webp', changes: [ { - key: 'system.traits.agility.bonus', + key: 'system.traits.agility.value', mode: 2, value: '-1' } @@ -683,7 +683,7 @@ export const weaponFeatures = { img: 'icons/skills/melee/sword-shield-stylized-white.webp', changes: [ { - key: 'system.bonuses.armorScore', + key: 'system.armorScore', mode: 2, value: '1' }, @@ -777,7 +777,7 @@ export const weaponFeatures = { img: 'icons/commodities/currency/coins-crown-stack-gold.webp', changes: [ { - key: 'system.proficiency.bonus', + key: 'system.proficiency', mode: 2, value: '1' } @@ -819,7 +819,7 @@ export const weaponFeatures = { img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' } @@ -941,7 +941,7 @@ export const weaponFeatures = { img: '', changes: [ { - key: 'system.evasion.bonus', + key: 'system.evasion', mode: 2, value: '-1' }, @@ -1031,7 +1031,7 @@ export const weaponFeatures = { img: 'icons/magic/control/hypnosis-mesmerism-eye.webp', changes: [ { - key: 'system.traits.presence.bonus', + key: 'system.traits.presence.value', mode: 2, value: '2' } @@ -1088,7 +1088,7 @@ export const weaponFeatures = { img: 'icons/skills/melee/shield-block-gray-orange.webp', changes: [ { - key: 'system.bonuses.armorScore', + key: 'system.armorScore', mode: 2, value: '1' } @@ -1218,7 +1218,7 @@ export const weaponFeatures = { { key: 'system.bonuses.damage.primaryWeapon.bonus', mode: 2, - value: '@system.traits.agility.total' + value: '@system.traits.agility.value' } ] } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 8fb15f50..ae70bf21 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -331,7 +331,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { .filter(c => c.enabled !== false) .map(c => { const resource = this.actor.system.resources[c.type]; - return { type: c.type, value: (c.total ?? c.value) * (resource.hasOwnProperty('maxTotal') ? 1 : -1) }; + return { type: c.type, value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1) }; }); await this.actor.modifyResource(resources); @@ -384,12 +384,12 @@ export default class DHBaseAction extends foundry.abstract.DataModel { return false; } - /* maxTotal is a sign that the resource is inverted, IE it counts upwards instead of down */ + /* isReversed is a sign that the resource is inverted, IE it counts upwards instead of down */ const resources = this.actor.system.resources; return realCosts.reduce( (a, c) => - a && resources[c.type].hasOwnProperty('maxTotal') - ? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].maxTotal + a && resources[c.type].isReversed + ? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].max : resources[c.type]?.value >= (c.total ?? c.value), true ); @@ -432,7 +432,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { name: actor.actor.name, img: actor.actor.img, difficulty: actor.actor.system.difficulty, - evasion: actor.actor.system.evasion?.total + evasion: actor.actor.system.evasion }; } /* TARGET */ diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index cf3669a1..78e08323 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -5,8 +5,8 @@ import BaseDataActor from './base.mjs'; const resourceField = () => new foundry.data.fields.SchemaField({ value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), - bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }), - max: new foundry.data.fields.NumberField({ initial: 0, integer: true }) + max: new foundry.data.fields.NumberField({ initial: 0, integer: true }), + isReversed: new foundry.data.fields.BooleanField({ initial: true }) }); export default class DhpAdversary extends BaseDataActor { @@ -76,7 +76,7 @@ export default class DhpAdversary extends BaseDataActor { experiences: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField(), - total: new fields.NumberField({ required: true, integer: true, initial: 1 }) + value: new fields.NumberField({ required: true, integer: true, initial: 1 }) }) ), bonuses: new fields.SchemaField({ @@ -95,9 +95,4 @@ export default class DhpAdversary extends BaseDataActor { get features() { return this.parent.items.filter(x => x.type === 'feature'); } - - prepareDerivedData() { - this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus; - this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus; - } } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index d26e368a..d8fc2b5c 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -5,16 +5,15 @@ import BaseDataActor from './base.mjs'; const attributeField = () => new foundry.data.fields.SchemaField({ - value: new foundry.data.fields.NumberField({ initial: null, integer: true }), - bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }), + value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), tierMarked: new foundry.data.fields.BooleanField({ initial: false }) }); -const resourceField = max => +const resourceField = (max, reverse = false) => new foundry.data.fields.SchemaField({ value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), - bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }), - max: new foundry.data.fields.NumberField({ initial: max, integer: true }) + max: new foundry.data.fields.NumberField({ initial: max, integer: true }), + isReversed: new foundry.data.fields.BooleanField({ initial: reverse }) }); const stressDamageReductionRule = () => @@ -38,11 +37,8 @@ export default class DhCharacter extends BaseDataActor { return { ...super.defineSchema(), resources: new fields.SchemaField({ - hitPoints: new fields.SchemaField({ - value: new foundry.data.fields.NumberField({ initial: 0, integer: true }), - bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }) - }), - stress: resourceField(6), + hitPoints: resourceField(0, true), + stress: resourceField(6, true), hope: resourceField(6), tokens: new fields.ObjectField(), dice: new fields.ObjectField() @@ -55,18 +51,17 @@ export default class DhCharacter extends BaseDataActor { presence: attributeField(), knowledge: attributeField() }), - proficiency: new fields.SchemaField({ - value: new fields.NumberField({ initial: 1, integer: true }), - bonus: new fields.NumberField({ initial: 0, integer: true }) - }), - evasion: new fields.SchemaField({ - bonus: new fields.NumberField({ initial: 0, integer: true }) + proficiency: new fields.NumberField({ initial: 1, integer: true }), + evasion: new fields.NumberField({ initial: 0, integer: true }), + armorScore: new fields.NumberField({ integer: true, initial: 0 }), + damageThresholds: new fields.SchemaField({ + severe: new fields.NumberField({ integer: true, initial: 0 }), + major: new fields.NumberField({ integer: true, initial: 0 }) }), experiences: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField(), - value: new fields.NumberField({ integer: true, initial: 0 }), - bonus: new fields.NumberField({ integer: true, initial: 0 }) + value: new fields.NumberField({ integer: true, initial: 0 }) }) ), gold: new fields.SchemaField({ @@ -100,11 +95,6 @@ export default class DhCharacter extends BaseDataActor { }), levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ - armorScore: new fields.NumberField({ integer: true, initial: 0 }), - damageThresholds: new fields.SchemaField({ - severe: new fields.NumberField({ integer: true, initial: 0 }), - major: new fields.NumberField({ integer: true, initial: 0 }) - }), roll: new fields.SchemaField({ attack: new fields.NumberField({ integer: true, initial: 0 }), primaryWeapon: new fields.SchemaField({ @@ -303,7 +293,7 @@ export default class DhCharacter extends BaseDataActor { get deathMoveViable() { return ( - this.resources.hitPoints.maxTotal > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.maxTotal + this.resources.hitPoints.max > 0 && this.resources.hitPoints.value >= this.resources.hitPoints.max ); } @@ -347,32 +337,32 @@ export default class DhCharacter extends BaseDataActor { for (let levelKey in this.levelData.levelups) { const level = this.levelData.levelups[levelKey]; - this.proficiency.bonus += level.achievements.proficiency; + this.proficiency += level.achievements.proficiency; for (let selection of level.selections) { switch (selection.type) { case 'trait': selection.data.forEach(data => { - this.traits[data].bonus += 1; + this.traits[data].value += 1; this.traits[data].tierMarked = selection.tier === currentTier; }); break; case 'hitPoint': - this.resources.hitPoints.bonus += selection.value; + this.resources.hitPoints.max += selection.value; break; case 'stress': - this.resources.stress.bonus += selection.value; + this.resources.stress.max += selection.value; break; case 'evasion': - this.evasion.bonus += selection.value; + this.evasion += selection.value; break; case 'proficiency': - this.proficiency.bonus = selection.value; + this.proficiency = selection.value; break; case 'experience': Object.keys(this.experiences).forEach(key => { const experience = this.experiences[key]; - experience.bonus += selection.value; + experience.value += selection.value; }); break; } @@ -380,7 +370,7 @@ export default class DhCharacter extends BaseDataActor { } const armor = this.armor; - this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; // Bonuses to armorScore won't have been applied yet. Need to solve in documentPreparation somehow + this.armorScore = armor ? armor.system.baseScore : 0; this.damageThresholds = { major: armor ? armor.system.baseThresholds.major + this.levelData.level.current @@ -389,29 +379,12 @@ export default class DhCharacter extends BaseDataActor { ? armor.system.baseThresholds.severe + this.levelData.level.current : this.levelData.level.current * 2 }; + this.resources.hope.max -= Object.keys(this.scars).length; + this.resources.hitPoints.max = this.class.value?.system?.hitPoints ?? 0; } prepareDerivedData() { - this.resources.hope.max -= Object.keys(this.scars).length; this.resources.hope.value = Math.min(this.resources.hope.value, this.resources.hope.max); - - for (var traitKey in this.traits) { - var trait = this.traits[traitKey]; - trait.total = (trait.value ?? 0) + trait.bonus; - } - - for (var experienceKey in this.experiences) { - var experience = this.experiences[experienceKey]; - experience.total = experience.value + experience.bonus; - } - - this.rules.damageReduction.maxArmorMarked.total = - this.rules.damageReduction.maxArmorMarked.value + this.rules.damageReduction.maxArmorMarked.bonus; - - this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + this.resources.hitPoints.bonus; - this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus; - this.evasion.total = (this.class?.evasion ?? 0) + this.evasion.bonus; - this.proficiency.total = this.proficiency.value + this.proficiency.bonus; } getRollData() { diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index b1c41ea3..ea417bd8 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -25,20 +25,16 @@ export default class DhCompanion extends BaseDataActor { resources: new fields.SchemaField({ stress: new fields.SchemaField({ value: new fields.NumberField({ initial: 0, integer: true }), - bonus: new fields.NumberField({ initial: 0, integer: true }), - max: new fields.NumberField({ initial: 3, integer: true }) + max: new fields.NumberField({ initial: 3, integer: true }), + isReversed: new foundry.data.fields.BooleanField({ initial: true }) }), hope: new fields.NumberField({ initial: 0, integer: true }) }), - evasion: new fields.SchemaField({ - value: new fields.NumberField({ required: true, min: 1, initial: 10, integer: true }), - bonus: new fields.NumberField({ initial: 0, integer: true }) - }), + evasion: new fields.NumberField({ required: true, min: 1, initial: 10, integer: true }), experiences: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField({}), - value: new fields.NumberField({ integer: true, initial: 0 }), - bonus: new fields.NumberField({ integer: true, initial: 0 }) + value: new fields.NumberField({ integer: true, initial: 0 }) }), { initial: { @@ -84,19 +80,17 @@ export default class DhCompanion extends BaseDataActor { get traits() { return { - instinct: { total: this.attack.roll.bonus } + instinct: { value: this.attack.roll.bonus } }; } get proficiency() { - return { - total: this.partner?.system?.proficiency?.total ?? 1 - }; + return this.partner?.system?.proficiency ?? 1; } prepareBaseData() { const partnerSpellcastingModifier = this.partner?.system?.spellcastingModifiers?.main; - const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.total; + const spellcastingModifier = this.partner?.system?.traits?.[partnerSpellcastingModifier]?.value; this.attack.roll.bonus = spellcastingModifier ?? 0; // Needs to expand on which modifier it is that should be used because of multiclassing; for (let levelKey in this.levelData.levelups) { @@ -114,15 +108,15 @@ export default class DhCompanion extends BaseDataActor { } break; case 'stress': - this.resources.stress.bonus += selection.value; + this.resources.stress.max += selection.value; break; case 'evasion': - this.evasion.bonus += selection.value; + this.evasion += selection.value; break; case 'experience': Object.keys(this.experiences).forEach(key => { const experience = this.experiences[key]; - experience.bonus += selection.value; + experience.value += selection.value; }); break; } @@ -131,17 +125,9 @@ export default class DhCompanion extends BaseDataActor { } prepareDerivedData() { - for (var experienceKey in this.experiences) { - var experience = this.experiences[experienceKey]; - experience.total = experience.value + experience.bonus; - } - if (this.partner) { this.partner.system.resources.hope.max += this.resources.hope; } - - this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus; - this.evasion.total = this.evasion.value + this.evasion.bonus; } async _preDelete() { diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 3c47841d..265c2566 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -32,9 +32,9 @@ export default class DHSubclass extends BaseDataItem { get features() { return [ - { ...this.foundationFeature.toObject(), identifier: 'foundationFeature' }, - { ...this.specializationFeature.toObject(), identifier: 'specializationFeature' }, - { ...this.masteryFeature.toObject(), identifier: 'masteryFeature' } + { ...this.foundationFeature?.toObject(), identifier: 'foundationFeature' }, + { ...this.specializationFeature?.toObject(), identifier: 'specializationFeature' }, + { ...this.masteryFeature?.toObject(), identifier: 'masteryFeature' } ]; } diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 9c784084..c9e9d428 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -97,7 +97,7 @@ export default class D20Roll extends DHRoll { if (this.options.data.experiences?.[m]) this.options.roll.modifiers.push({ label: this.options.data.experiences[m].name, - value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value + value: this.options.data.experiences[m].value }); }); diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 6c1d0fe4..1044b93a 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -123,7 +123,7 @@ export default class DualityRoll extends D20Roll { if (!this.options.roll.trait) return; this.options.roll.modifiers.push({ label: `DAGGERHEART.CONFIG.Traits.${this.options.roll.trait}.name`, - value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data) + value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.value`, this.data) }); } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 0bd45690..d8d75461 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -371,96 +371,13 @@ export default class DhpActor extends Actor { getRollData() { const rollData = super.getRollData(); - rollData.prof = this.system.proficiency?.total ?? 1; - rollData.cast = this.system.spellcast?.total ?? 1; + rollData.prof = this.system.proficiency ?? 1; + rollData.cast = this.system.spellcast ?? 1; return rollData; } - formatRollModifier(roll) { - const modifier = roll.modifier !== null ? Number.parseInt(roll.modifier) : null; - return modifier !== null - ? [ - { - value: modifier, - label: roll.label - ? modifier >= 0 - ? `${roll.label} +${modifier}` - : `${roll.label} ${modifier}` - : null, - title: roll.label - } - ] - : []; - } - - async damageRoll(title, damage, targets, shiftKey) { - let rollString = damage.value; - let bonusDamage = damage.bonusDamage?.filter(x => x.initiallySelected) ?? []; - if (!shiftKey) { - const dialogClosed = new Promise((resolve, _) => { - new DamageSelectionDialog(rollString, bonusDamage, resolve).render(true); - }); - const result = await dialogClosed; - bonusDamage = result.bonusDamage; - rollString = result.rollString; - - const automateHope = await game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation.Hope); - if (automateHope && result.hopeUsed) { - await this.update({ - 'system.resources.hope.value': this.system.resources.hope.value - result.hopeUsed - }); - } - } - - const roll = new Roll(rollString); - let rollResult = await roll.evaluate(); - - const dice = []; - const modifiers = []; - for (var i = 0; i < rollResult.terms.length; i++) { - const term = rollResult.terms[i]; - if (term.faces) { - dice.push({ - type: `d${term.faces}`, - rolls: term.results.map(x => x.result), - total: term.results.reduce((acc, x) => acc + x.result, 0) - }); - } else if (term.operator) { - } else if (term.number) { - const operator = i === 0 ? '' : rollResult.terms[i - 1].operator; - modifiers.push({ value: term.number, operator: operator }); - } - } - - const cls = getDocumentClass('ChatMessage'); - const systemData = { - title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: title }), - roll: rollString, - damage: { - total: rollResult.total, - type: damage.type - }, - dice: dice, - modifiers: modifiers, - targets: targets - }; - const msg = new cls({ - type: 'damageRoll', - user: game.user.id, - sound: CONFIG.sounds.dice, - system: systemData, - content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/ui/chat/damage-roll.hbs', - systemData - ), - rolls: [roll] - }); - - cls.create(msg.toObject()); - } - #canReduceDamage(hpDamage, type) { - const availableStress = this.system.resources.stress.maxTotal - this.system.resources.stress.value; + const availableStress = this.system.resources.stress.max - this.system.resources.stress.value; const canUseArmor = this.system.armor && @@ -568,7 +485,7 @@ export default class DhpActor extends Actor { updates.actor.resources[`system.resources.${r.type}.value`] = Math.max( Math.min( this.system.resources[r.type].value + r.value, - this.system.resources[r.type].maxTotal ?? this.system.resources[r.type].max + this.system.resources[r.type].max ), 0 ); @@ -600,7 +517,7 @@ export default class DhpActor extends Actor { convertStressDamageToHP(resources) { const stressDamage = resources.find(r => r.type === 'stress'), newValue = this.system.resources.stress.value + stressDamage.value; - if (newValue <= this.system.resources.stress.maxTotal) return; + if (newValue <= this.system.resources.stress.max) return; const hpDamage = resources.find(r => r.type === 'hitPoints'); if (hpDamage) hpDamage.value++; else diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index feeebbd2..b3b46dcb 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -28,7 +28,7 @@ export default class RegisterHandlebarsHelpers { } static damageFormula(attack, actor) { - const traitTotal = actor.system.traits?.[attack.roll.trait]?.total; + const traitTotal = actor.system.traits?.[attack.roll.trait]?.value; const instances = [ attack.damage.parts.map(x => Roll.replaceFormulaData(x.value.getFormula(), actor)).join(' + '), traitTotal diff --git a/templates/dialogs/damageReduction.hbs b/templates/dialogs/damageReduction.hbs index 4c30bbfc..43f55e86 100644 --- a/templates/dialogs/damageReduction.hbs +++ b/templates/dialogs/damageReduction.hbs @@ -8,7 +8,7 @@ {{#if this.stress}}

    {{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stress"}}

    -
    {{this.stress.value}}/{{this.stress.maxTotal}}
    +
    {{this.stress.value}}/{{this.stress.max}}
    {{/if}}
    diff --git a/templates/sheets-settings/adversary-settings/experiences.hbs b/templates/sheets-settings/adversary-settings/experiences.hbs index c15bf6b9..5fe2ab36 100644 --- a/templates/sheets-settings/adversary-settings/experiences.hbs +++ b/templates/sheets-settings/adversary-settings/experiences.hbs @@ -13,7 +13,7 @@ {{#each document.system.experiences as |experience key|}}
  • - +
  • {{/each}} diff --git a/templates/sheets-settings/companion-settings/details.hbs b/templates/sheets-settings/companion-settings/details.hbs index 2811377d..97b04b24 100644 --- a/templates/sheets-settings/companion-settings/details.hbs +++ b/templates/sheets-settings/companion-settings/details.hbs @@ -6,7 +6,7 @@
    {{localize 'DAGGERHEART.GENERAL.basics'}}
    - {{formGroup systemFields.evasion.fields.value value=document.system.evasion.value localize=true}} + {{formGroup systemFields.evasion value=document.system.evasion localize=true}} {{formGroup systemFields.resources.fields.stress.fields.value value=document.system.resources.stress.value label='Current Stress'}} {{formGroup systemFields.resources.fields.stress.fields.max value=document.system.resources.stress.max label='Max Stress'}}
    diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index ad23ab25..4ba2360b 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -1,5 +1,5 @@
    \ No newline at end of file diff --git a/templates/sheets/activeEffect/changes.hbs b/templates/sheets/activeEffect/changes.hbs index c1047206..9cf137f0 100644 --- a/templates/sheets/activeEffect/changes.hbs +++ b/templates/sheets/activeEffect/changes.hbs @@ -11,12 +11,7 @@ {{#with ../fields.changes.element.fields as |changeFields|}}
  • - - - {{#each @root.fieldPaths}} - - {{/each}} - +
    {{formInput changeFields.mode name=(concat "changes." i ".mode") value=change.mode choices=@root.modes}} diff --git a/templates/sheets/actors/companion/details.hbs b/templates/sheets/actors/companion/details.hbs index eb3665a3..0f5587f3 100644 --- a/templates/sheets/actors/companion/details.hbs +++ b/templates/sheets/actors/companion/details.hbs @@ -6,7 +6,7 @@
    -

    Partner

    +

    {{localize "DAGGERHEART.GENERAL.partner"}}

    {{#if document.system.partner}} @@ -20,7 +20,7 @@
    -

    Attack

    +

    {{localize "DAGGERHEART.GENERAL.attack"}}

      @@ -28,6 +28,11 @@
    +
    + +

    {{localize "DAGGERHEART.GENERAL.experience.plural"}}

    + +
    {{#each source.system.experiences as |experience id|}}
    From aa2714e02136a29d1a79d7b1fbfc1df73a58d2f9 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 15 Jul 2025 15:59:01 +0200 Subject: [PATCH 30/58] [Fix] Automation Fixes (#342) * Initial * Split HopeFear automation by GM and Players * Fixed ActionToken automation --- daggerheart.mjs | 3 +- lang/en.json | 7 ++- module/applications/hud/tokenHUD.mjs | 2 +- .../applications/sheets/actors/character.mjs | 5 +- module/applications/ui/combatTracker.mjs | 17 +++++- module/applications/ui/countdowns.mjs | 59 +++++++------------ module/config/_module.mjs | 1 - module/config/generalConfig.mjs | 6 +- module/config/hooksConfig.mjs | 4 -- module/config/system.mjs | 2 - module/data/action/attackAction.mjs | 9 +++ module/data/countdowns.mjs | 10 +++- module/data/settings/Automation.mjs | 22 +++---- module/dice/dhRoll.mjs | 9 +-- templates/settings/automation-settings.hbs | 7 ++- 15 files changed, 87 insertions(+), 76 deletions(-) delete mode 100644 module/config/hooksConfig.mjs diff --git a/daggerheart.mjs b/daggerheart.mjs index a1742641..aeae0dc6 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -5,7 +5,7 @@ import * as documents from './module/documents/_module.mjs'; import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs'; import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs'; import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs'; -import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/ui/countdowns.mjs'; +import { NarrativeCountdowns } from './module/applications/ui/countdowns.mjs'; import { DualityRollColor } from './module/data/settings/Appearance.mjs'; import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/dice/_module.mjs'; import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs'; @@ -168,7 +168,6 @@ Hooks.on('ready', () => { registerCountdownHooks(); socketRegistration.registerSocketHooks(); - registerCountdownApplicationHooks(); registerRollDiceHooks(); registerDHActorHooks(); }); diff --git a/lang/en.json b/lang/en.json index 1adf4bc6..3bf99e3a 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1337,9 +1337,10 @@ "hint": "Automatically increase the GM's fear pool on a fear duality roll result." }, "FIELDS": { - "hope": { - "label": "Hope", - "hint": "Automatically increase a character's hope on a hope duality roll result." + "hopeFear": { + "label": "Hope & Fear", + "gm": { "label": "GM" }, + "players": { "label": "Players" } }, "actionPoints": { "label": "Action Points", diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs index 9a58bab2..572b03f9 100644 --- a/module/applications/hud/tokenHUD.mjs +++ b/module/applications/hud/tokenHUD.mjs @@ -1,4 +1,4 @@ -export default class DHTokenHUD extends TokenHUD { +export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { static DEFAULT_OPTIONS = { classes: ['daggerheart'] }; diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index fcd92842..139a1369 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -669,10 +669,7 @@ export default class CharacterSheet extends DHBaseActorSheet { } else if (item instanceof ActiveEffect) { item.toChat(this); } else { - const wasUsed = await item.use(event); - if (wasUsed && item.type === 'weapon') { - Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {}); - } + item.use(event); } } diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index f9f49ad1..b3348fe2 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -66,6 +66,11 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C } async setCombatantSpotlight(combatantId) { + const update = { + system: { + 'spotlight.requesting': false + } + }; const combatant = this.viewed.combatants.get(combatantId); const toggleTurn = this.viewed.combatants.contents @@ -73,10 +78,18 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C .map(x => x.id) .indexOf(combatantId); - if (this.viewed.turn !== toggleTurn) Hooks.callAll(CONFIG.DH.HOOKS.spotlight, {}); + if (this.viewed.turn !== toggleTurn) { + const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; + await updateCountdowns(CONFIG.DH.GENERAL.countdownTypes.spotlight.id); + + const autoPoints = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).actionPoints; + if (autoPoints) { + update.system.actionTokens = Math.max(combatant.system.actionTokens - 1, 0); + } + } await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn }); - await combatant.update({ 'system.spotlight.requesting': false }); + await combatant.update(update); } static async requestSpotlight(_, target) { diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index c229cda1..5e3ad1ab 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -1,4 +1,3 @@ -import { countdownTypes } from '../../config/generalConfig.mjs'; import { GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import constructHTMLButton from '../../helpers/utils.mjs'; import OwnershipSelection from '../dialogs/ownershipSelection.mjs'; @@ -328,43 +327,29 @@ export class EncounterCountdowns extends Countdowns { }; } -export const registerCountdownApplicationHooks = () => { - const updateCountdowns = async shouldProgress => { - if (game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).countdowns) { - const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); - for (let countdownCategoryKey in countdownSetting) { - const countdownCategory = countdownSetting[countdownCategoryKey]; - for (let countdownKey in countdownCategory.countdowns) { - const countdown = countdownCategory.countdowns[countdownKey]; - - if (shouldProgress(countdown)) { - await countdownSetting.updateSource({ - [`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]: - countdown.progress.current - 1 - }); - await game.settings.set( - CONFIG.DH.id, - CONFIG.DH.SETTINGS.gameSettings.Countdowns, - countdownSetting - ); - foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render(); - } +export async function updateCountdowns(progressType) { + const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); + const update = Object.keys(countdownSetting).reduce((update, typeKey) => { + return foundry.utils.mergeObject( + update, + Object.keys(countdownSetting[typeKey].countdowns).reduce((acc, countdownKey) => { + const countdown = countdownSetting[typeKey].countdowns[countdownKey]; + if (countdown.progress.current > 0 && countdown.progress.type.value === progressType) { + acc[`${typeKey}.countdowns.${countdownKey}.progress.current`] = countdown.progress.current - 1; } - } - } - }; - Hooks.on(CONFIG.DH.HOOKS.characterAttack, async () => { - updateCountdowns(countdown => { - return ( - countdown.progress.type.value === countdownTypes.characterAttack.id && countdown.progress.current > 0 - ); - }); - }); + return acc; + }, {}) + ); + }, {}); - Hooks.on(CONFIG.DH.HOOKS.spotlight, async () => { - updateCountdowns(countdown => { - return countdown.progress.type.value === countdownTypes.spotlight.id && countdown.progress.current > 0; - }); + await countdownSetting.updateSource(update); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, countdownSetting); + + const data = { refreshType: RefreshType.Countdown }; + await game.socket.emit(`system.${CONFIG.DH.id}`, { + action: socketEvent.Refresh, + data }); -}; + Hooks.callAll(socketEvent.Refresh, data); +} diff --git a/module/config/_module.mjs b/module/config/_module.mjs index 88003595..99069dda 100644 --- a/module/config/_module.mjs +++ b/module/config/_module.mjs @@ -4,7 +4,6 @@ export * as domainConfig from './domainConfig.mjs'; export * as effectConfig from './effectConfig.mjs'; export * as flagsConfig from './flagsConfig.mjs'; export * as generalConfig from './generalConfig.mjs'; -export * as hooksConfig from './hooksConfig.mjs'; export * as itemConfig from './itemConfig.mjs'; export * as settingsConfig from './settingsConfig.mjs'; export * as systemConfig from './system.mjs'; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 3522b41a..54430860 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -376,15 +376,15 @@ export const abilityCosts = { export const countdownTypes = { spotlight: { id: 'spotlight', - label: 'DAGGERHEART.CONFIG.CountdownTypes.Spotlight' + label: 'DAGGERHEART.CONFIG.CountdownType.spotlight' }, characterAttack: { id: 'characterAttack', - label: 'DAGGERHEART.CONFIG.CountdownTypes.CharacterAttack' + label: 'DAGGERHEART.CONFIG.CountdownType.characterAttack' }, custom: { id: 'custom', - label: 'DAGGERHEART.CONFIG.CountdownTypes.Custom' + label: 'DAGGERHEART.CONFIG.CountdownType.custom' } }; export const rollTypes = { diff --git a/module/config/hooksConfig.mjs b/module/config/hooksConfig.mjs deleted file mode 100644 index 8410c0de..00000000 --- a/module/config/hooksConfig.mjs +++ /dev/null @@ -1,4 +0,0 @@ -export const hooks = { - characterAttack: 'characterAttackHook', - spotlight: 'spotlightHook' -}; diff --git a/module/config/system.mjs b/module/config/system.mjs index 6ad0e689..e72667b1 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -3,7 +3,6 @@ import * as DOMAIN from './domainConfig.mjs'; import * as ACTOR from './actorConfig.mjs'; import * as ITEM from './itemConfig.mjs'; import * as SETTINGS from './settingsConfig.mjs'; -import { hooks as HOOKS } from './hooksConfig.mjs'; import * as EFFECTS from './effectConfig.mjs'; import * as ACTIONS from './actionConfig.mjs'; import * as FLAGS from './flagsConfig.mjs'; @@ -17,7 +16,6 @@ export const SYSTEM = { ACTOR, ITEM, SETTINGS, - HOOKS, EFFECTS, ACTIONS, FLAGS diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index 137879b8..e17c0e9d 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -38,6 +38,15 @@ export default class DHAttackAction extends DHDamageAction { }; } + async use(event, ...args) { + const result = await super.use(event, args); + + const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; + await updateCountdowns(CONFIG.DH.GENERAL.countdownTypes.characterAttack.id); + + return result; + } + // get modifiers() { // return []; // } diff --git a/module/data/countdowns.mjs b/module/data/countdowns.mjs index e9649f6e..881ecf20 100644 --- a/module/data/countdowns.mjs +++ b/module/data/countdowns.mjs @@ -102,7 +102,7 @@ class DhCountdown extends foundry.abstract.DataModel { value: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.countdownTypes, - initial: CONFIG.DH.GENERAL.countdownTypes.spotlight.id, + initial: CONFIG.DH.GENERAL.countdownTypes.custom.id, label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.type.value.label' }), label: new fields.StringField({ @@ -132,7 +132,13 @@ class DhCountdown extends foundry.abstract.DataModel { export const registerCountdownHooks = () => { Hooks.on(socketEvent.Refresh, ({ refreshType, application }) => { if (refreshType === RefreshType.Countdown) { - foundry.applications.instances.get(application)?.render(); + if (application) { + foundry.applications.instances.get(application)?.render(); + } else { + foundry.applications.instances.get('narrative-countdowns').render(); + foundry.applications.instances.get('encounter-countdowns').render(); + } + return false; } }); diff --git a/module/data/settings/Automation.mjs b/module/data/settings/Automation.mjs index 4e375919..4291423b 100644 --- a/module/data/settings/Automation.mjs +++ b/module/data/settings/Automation.mjs @@ -4,20 +4,22 @@ export default class DhAutomation extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { - hope: new fields.BooleanField({ - required: true, - initial: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hope.label' - }), // Label need to be updated into something like "Duality Roll Auto Gain" + a hint + hopeFear: new fields.SchemaField({ + gm: new fields.BooleanField({ + required: true, + initial: false, + label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.gm.label' + }), + players: new fields.BooleanField({ + required: true, + initial: false, + label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.hopeFear.players.label' + }) + }), actionPoints: new fields.BooleanField({ required: true, initial: false, label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.actionPoints.label' - }), - countdowns: new fields.BooleanField({ - requireD: true, - initial: false, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.countdowns.label' }) }; } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 1bd9a6e5..22f5bb28 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -175,9 +175,10 @@ export default class DHRoll extends Roll { export const registerRollDiceHooks = () => { Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => { + const hopeFearAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hopeFear; if ( !config.source?.actor || - !game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope || + (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) || config.roll.type === 'reaction' ) return; @@ -185,9 +186,9 @@ export const registerRollDiceHooks = () => { const actor = await fromUuid(config.source.actor), updates = []; if (!actor) return; - if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ type: 'hope', value: 1 }); - if (config.roll.isCritical) updates.push({ type: 'stress', value: -1 }); - if (config.roll.result.duality === -1) updates.push({ type: 'fear', value: 1 }); + if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ key: 'hope', value: 1 }); + if (config.roll.isCritical) updates.push({ key: 'stress', value: -1 }); + if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1 }); if (updates.length) actor.modifyResource(updates); diff --git a/templates/settings/automation-settings.hbs b/templates/settings/automation-settings.hbs index 7a637d08..87a48c06 100644 --- a/templates/settings/automation-settings.hbs +++ b/templates/settings/automation-settings.hbs @@ -1,5 +1,10 @@
    - {{formGroup settingFields.schema.fields.hope value=settingFields._source.hope localize=true}} +
    + + {{formGroup settingFields.schema.fields.hopeFear.fields.gm value=settingFields._source.hopeFear.gm localize=true}} + {{formGroup settingFields.schema.fields.hopeFear.fields.players value=settingFields._source.hopeFear.players localize=true}} + +
    {{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}} {{formGroup settingFields.schema.fields.countdowns value=settingFields._source.countdowns localize=true}} From da6d9418b70448e3bd0c954dcff727bde3ea40ae Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 15 Jul 2025 16:15:58 +0200 Subject: [PATCH 31/58] Fixes tokenHUD import path (#348) --- module/applications/hud/_module.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/applications/hud/_module.mjs b/module/applications/hud/_module.mjs index 70edaf8f..92abe4e8 100644 --- a/module/applications/hud/_module.mjs +++ b/module/applications/hud/_module.mjs @@ -1 +1 @@ -export { default as DHTokenHUD } from './tokenHud.mjs'; +export { default as DHTokenHUD } from './tokenHUD.mjs'; From 045754d107295eccf4580b66be03651f36e58f53 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 15 Jul 2025 17:01:17 +0200 Subject: [PATCH 32/58] [Feature] 340-341 RollMode & ChatSpeaker (#347) * Added RollMode to standalone DamageDialog and to RollDialog. ChatMessage now add ChatSpeaker * Just a little fix for Damage Action --------- Co-authored-by: Dapoolp --- lang/en.json | 1 + module/applications/dialogs/d20RollDialog.mjs | 14 +++-- module/applications/dialogs/damageDialog.mjs | 12 ++++- module/applications/ui/chatLog.mjs | 2 +- module/data/action/baseAction.mjs | 3 +- module/data/action/damageAction.mjs | 13 +++-- module/dice/dhRoll.mjs | 2 +- module/documents/chatMessage.mjs | 11 ++++ .../less/dialog/damage-selection/sheet.less | 54 ++++++++++++------- .../less/dialog/dice-roll/roll-selection.less | 14 +++++ .../dialogs/dice-roll/damageSelection.hbs | 15 ++++-- templates/dialogs/dice-roll/rollSelection.hbs | 13 +++-- 12 files changed, 112 insertions(+), 42 deletions(-) diff --git a/lang/en.json b/lang/en.json index 3bf99e3a..b9e0fefa 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1231,6 +1231,7 @@ "quantity": "Quantity", "range": "Range", "recovery": "Recovery", + "roll": "Roll", "scalable": "Scalable", "stress": "Stress", "take": "Take", diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 6cb0761c..7987dd6b 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -64,6 +64,13 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio context.rollConfig = this.config; context.hasRoll = !!this.config.roll; context.canRoll = true; + context.selectedRollMode = this.config.selectedRollMode; + context.rollModes = Object.entries(CONFIG.Dice.rollModes).map(([action, { label, icon }]) => ({ + action, + label, + icon + })); + if (this.config.costs?.length) { const updatedCosts = this.action.calcCosts(this.config.costs); context.costs = updatedCosts.map(x => ({ @@ -99,6 +106,8 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio static updateRollConfiguration(event, _, formData) { const { ...rest } = foundry.utils.expandObject(formData.object); + this.config.selectedRollMode = rest.selectedRollMode; + if (this.config.costs) { this.config.costs = foundry.utils.mergeObject(this.config.costs, rest.costs); } @@ -122,11 +131,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } static selectExperience(_, button) { - /* if (this.config.experiences.find(x => x === button.dataset.key)) { - this.config.experiences = this.config.experiences.filter(x => x !== button.dataset.key); - } else { - this.config.experiences = [...this.config.experiences, button.dataset.key]; - } */ this.config.experiences = this.config.experiences.indexOf(button.dataset.key) > -1 ? this.config.experiences.filter(x => x !== button.dataset.key) diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 4030d7a7..70dcace8 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -48,12 +48,22 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application : game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); + context.directDamage = this.config.directDamage; + context.selectedRollMode = this.config.selectedRollMode; + context.rollModes = Object.entries(CONFIG.Dice.rollModes).map(([action, { label, icon }]) => ({ + action, + label, + icon + })); + return context; } - static updateRollConfiguration(event, _, formData) { + static updateRollConfiguration(_event, _, formData) { const { ...rest } = foundry.utils.expandObject(formData.object); this.config.extraFormula = rest.extraFormula; + this.config.selectedRollMode = rest.selectedRollMode; + this.render(); } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index aa604dda..4570b076 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -88,7 +88,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo onRollDamage = async (event, message) => { event.stopPropagation(); const actor = await this.getActor(message.system.source.actor); - if (!actor || !game.user.isGM) return true; + if (game.user.character?.id !== actor.id && !game.user.isGM) return true; if (message.system.source.item && message.system.source.action) { const action = this.getAction(actor, message.system.source.item, message.system.source.action); if (!action || !action?.rollDamage) return; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 39051434..a46b0a85 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -268,7 +268,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { hasDamage: !!this.damage?.parts?.length, hasHealing: !!this.healing, hasEffect: !!this.effects?.length, - hasSave: this.hasSave + hasSave: this.hasSave, + selectedRollMode: game.settings.get('core', 'rollMode') }; } diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index 492c4184..388c5eb8 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -10,6 +10,7 @@ export default class DHDamageAction extends DHBaseAction { } async rollDamage(event, data) { + const systemData = data.system ?? data; let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '), damageTypes = [...new Set(this.damage.parts.reduce((a, c) => a.concat([...c.type]), []))]; @@ -19,15 +20,15 @@ export default class DHDamageAction extends DHBaseAction { let roll = { formula: formula, total: formula }, bonusDamage = []; - if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data)); - + if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData)); + const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }), roll: { formula }, - targets: data.system?.targets.filter(t => t.hit) ?? data.targets, + targets: systemData.targets.filter(t => t.hit) ?? data.targets, hasSave: this.hasSave, - isCritical: data.system?.roll?.isCritical ?? false, - source: data.system?.source, + isCritical: systemData.roll?.isCritical ?? false, + source: systemData.source, data: this.getRollData(), damageTypes, event @@ -36,6 +37,8 @@ export default class DHDamageAction extends DHBaseAction { if (data.system) { config.source.message = data._id; config.directDamage = false; + } else { + config.directDamage = true; } roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 22f5bb28..27288f15 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -87,7 +87,7 @@ export default class DHRoll extends Roll { system: config, rolls: [roll] }; - return await cls.create(msg); + return await cls.create(msg, { rollMode: config.selectedRollMode }); } static applyKeybindings(config) { diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index ef76d18f..409b4dd0 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -37,4 +37,15 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { e.setAttribute('data-use-perm', document.testUserPermission(game.user, 'OWNER')); }); } + + async _preCreate(data, options, user) { + options.speaker = ChatMessage.getSpeaker(); + const rollActorOwner = data.rolls?.[0]?.data?.parent?.owner; + if (rollActorOwner) { + data.author = rollActorOwner ? rollActorOwner.id : data.author; + await this.updateSource({ author: rollActorOwner ?? user }); + } + + return super._preCreate(data, options, rollActorOwner ?? user); + } } diff --git a/styles/less/dialog/damage-selection/sheet.less b/styles/less/dialog/damage-selection/sheet.less index 43e4f4d2..461fb0b5 100644 --- a/styles/less/dialog/damage-selection/sheet.less +++ b/styles/less/dialog/damage-selection/sheet.less @@ -1,20 +1,34 @@ -@import '../../utils/colors.less'; - -.daggerheart.dialog.dh-style.views.damage-selection { - .damage-section-container { - display: flex; - flex-direction: column; - gap: 12px; - - input[type='text'], - input[type='number'] { - color: light-dark(@dark, @beige); - outline: 2px solid transparent; - transition: all 0.3s ease; - - &:hover { - outline: 2px solid light-dark(@dark, @beige); - } - } - } -} +@import '../../utils/colors.less'; + +.daggerheart.dialog.dh-style.views.damage-selection { + .damage-section-container { + display: flex; + flex-direction: column; + gap: 12px; + + input[type='text'], + input[type='number'] { + color: light-dark(@dark, @beige); + outline: 2px solid transparent; + transition: all 0.3s ease; + + &:hover { + outline: 2px solid light-dark(@dark, @beige); + } + } + + .damage-section-controls { + display: flex; + align-items: center; + gap: 16px; + + .roll-mode-select { + width: min-content; + } + + button { + flex: 1; + } + } + } +} diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index 575b7ce9..14bccf3d 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -114,5 +114,19 @@ } } } + + .roll-dialog-controls { + display: flex; + align-items: center; + gap: 16px; + + .roll-mode-select { + width: min-content; + } + + button { + flex: 1; + } + } } } diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index 0286990e..bd97cfdf 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -6,8 +6,15 @@
    - +
    + {{#if directDamage}} + + {{/if}} + +
    \ No newline at end of file diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index 5c0ba41d..11fce27a 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -117,10 +117,15 @@ {{/unless}} Formula: {{@root.formula}} - +
    + + +
    {{else}}
    {{/if}} {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} + {{#if ../horde}} +
    + {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} +
    + {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." index ".valueAlt.flatMultiplier") label="Multiplier" classes="inline-child" }} + {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." index ".valueAlt.dice") classes="inline-child"}} + {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." index ".valueAlt.bonus") localize=true classes="inline-child"}} +
    +
    + {{/if}} {{else}} {{#with (@root.getRealIndex index) as | realIndex |}}
    @@ -33,11 +43,11 @@ {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base) dmg.resultBased)}}
    - With Hope + {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} {{> formula fields=../../fields.value.fields type=../../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
    - With Fear + {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} {{> formula fields=../../fields.valueAlt.fields type=../../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" realIndex=realIndex}}
    diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index 11fce27a..0d2f3f48 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -5,7 +5,7 @@
    {{#if (eq @root.rollType 'D20Roll')}}
    - +
    +
    + {{#unless (eq @root.rollType 'D20Roll')}} +
    + + - {{/unless}} -
    - +
    + {{/unless}} + {{#if @root.rallyDie.length}} + {{localize "DAGGERHEART.CLASS.Feature.rallyDice"}} + + {{/if}} + {{#if (eq @root.rollType 'DualityRoll')}}Situational Bonus{{/if}} + {{/unless}} Formula: {{@root.formula}} diff --git a/templates/ui/chat/duality-roll.hbs b/templates/ui/chat/duality-roll.hbs index 66d32e95..8b44039b 100644 --- a/templates/ui/chat/duality-roll.hbs +++ b/templates/ui/chat/duality-roll.hbs @@ -16,6 +16,11 @@ {{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}
    {{/if}} + {{#if roll.rally.dice}} +
    + {{localize "DAGGERHEART.CLASS.Feature.rallyDice"}} {{roll.rally.dice}} +
    + {{/if}}
    {{roll.formula}}
    @@ -38,7 +43,7 @@
    {{localize "DAGGERHEART.GENERAL.hope"}}
    - +
    {{roll.hope.value}}
    @@ -49,7 +54,7 @@
    {{localize "DAGGERHEART.GENERAL.fear"}}
    - +
    {{roll.fear.value}}
    @@ -72,7 +77,7 @@
    - +
    {{roll.advantage.value}}
    @@ -82,6 +87,30 @@
    {{/if}} + {{#if roll.rally.dice}} +
    +
    + + 1{{roll.rally.dice}} + + {{roll.rally.value}} +
    +
    +
      +
    1. +
      +
      +
      + +
      +
      {{roll.rally.value}}
      +
      +
      +
    2. +
    +
    +
    + {{/if}} {{#each roll.extra as | extra | }}
    From d7e024be02b3b938c0dc898ed0fa8eeb2fea8954 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:01:15 +0200 Subject: [PATCH 41/58] [Feature] Advantage/Disadvantage Tooltips (#362) * Added advantage/disadvantageSource to Character model. It's shown from a tooltip icon on rolls * Added support for beastform advantageOn --- module/data/actor/character.mjs | 2 ++ module/data/item/beastform.mjs | 1 + module/documents/tooltipManager.mjs | 18 ++++++++++++++++++ .../less/dialog/dice-roll/roll-selection.less | 4 ++++ templates/dialogs/dice-roll/rollSelection.hbs | 6 ++++++ templates/ui/tooltip/advantage.hbs | 5 +++++ 6 files changed, 36 insertions(+) create mode 100644 templates/ui/tooltip/advantage.hbs diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 20bada01..6fe66a53 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -87,6 +87,8 @@ export default class DhCharacter extends BaseDataActor { value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }), subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }) }), + advantageSources: new fields.ArrayField(new fields.StringField()), + disadvantageSources: new fields.ArrayField(new fields.StringField()), levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ roll: new fields.SchemaField({ diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index b7ea5cb9..d19521d0 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -69,6 +69,7 @@ export default class DHBeastform extends BaseDataItem { const beastformEffect = this.parent.effects.find(x => x.type === 'beastform'); await beastformEffect.updateSource({ + changes: [...beastformEffect.changes, { key: 'system.advantageSources', mode: 2, value: this.advantageOn }], system: { characterTokenData: { tokenImg: this.parent.parent.prototypeToken.texture.src, diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index d9444207..f24823f4 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -21,6 +21,24 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti this.tooltip.innerHTML = html; options.direction = this._determineItemTooltipDirection(element); } + } else { + const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#'); + const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#'); + if (isAdvantage || isDisadvantage) { + const actorUuid = element.dataset.tooltip.slice(isAdvantage ? 11 : 14); + const actor = await foundry.utils.fromUuid(actorUuid); + + if (actor) { + html = await foundry.applications.handlebars.renderTemplate( + `systems/daggerheart/templates/ui/tooltip/advantage.hbs`, + { + sources: isAdvantage ? actor.system.advantageSources : actor.system.disadvantageSources + } + ); + + this.tooltip.innerHTML = html; + } + } } super.activate(element, { ...options, html: html }); diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index 55db8bb7..af6c3c20 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -100,6 +100,10 @@ font-size: 14px; line-height: 17px; } + + .advantage-chip-tooltip { + pointer-events: all; + } } .advantage-chip { diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index b4c7ccac..7c894fd8 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -98,6 +98,9 @@ {{/if}} {{localize "DAGGERHEART.GENERAL.Advantage.full"}} + {{#if @root.rollConfig.data.advantageSources.length}} + + {{/if}}
    {{#unless (eq @root.rollType 'D20Roll')}} diff --git a/templates/ui/tooltip/advantage.hbs b/templates/ui/tooltip/advantage.hbs new file mode 100644 index 00000000..886f336d --- /dev/null +++ b/templates/ui/tooltip/advantage.hbs @@ -0,0 +1,5 @@ +
    + {{#each sources as | source |}} +
    {{{source}}}
    + {{/each}} +
    \ No newline at end of file From f15483c7229a782c6b3b8f9be1d2d0f79673e105 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:03:54 +0200 Subject: [PATCH 42/58] Feature/349 items actions macro use (#356) * Added itemUse macro on drag to hotbar * Fixed item.type logic * Added support for actionMacro drag from items * Added MacroDrag for Attacks * Fixed so UseItem macros get the img set --- daggerheart.mjs | 1 + lang/en.json | 6 +- module/applications/sheets/api/base-actor.mjs | 25 +++- module/applications/sheets/api/base-item.mjs | 20 ++- module/applications/ui/_module.mjs | 1 + module/applications/ui/hotbar.mjs | 129 ++++++++++++++++++ module/data/countdowns.mjs | 4 +- 7 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 module/applications/ui/hotbar.mjs diff --git a/daggerheart.mjs b/daggerheart.mjs index 0d78e8fe..22586e90 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -140,6 +140,7 @@ Hooks.once('init', () => { CONFIG.Combat.documentClass = documents.DhpCombat; CONFIG.ui.combat = applications.ui.DhCombatTracker; CONFIG.ui.chat = applications.ui.DhChatLog; + CONFIG.ui.hotbar = applications.ui.DhHotbar; CONFIG.Token.rulerClass = placeables.DhTokenRuler; CONFIG.ui.resources = applications.ui.DhFearTracker; diff --git a/lang/en.json b/lang/en.json index 75f2b886..3456b6b5 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1537,7 +1537,11 @@ "noAvailableArmorMarks": "You have no more available armor marks", "notEnoughStress": "You don't have enough stress", "damageIgnore": "{character} did not take damage", - "featureIsMissing": "Feature is missing" + "featureIsMissing": "Feature is missing", + "actionIsMissing": "Action is missing", + "attackIsMissing": "Attack is missing", + "unownedActionMacro": "Cannot make a Use macro for an Action not on your character", + "unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters" }, "Tooltip": { "openItemWorld": "Open Item World", diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 7102fa1c..78df0aac 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -23,7 +23,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { actions: { openSettings: DHBaseActorSheet.#openSettings }, - dragDrop: [] + dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }] }; /**@type {typeof DHBaseActorSettings}*/ @@ -49,4 +49,27 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { static async #openSettings() { await this.settingSheet.render({ force: true }); } + + /* -------------------------------------------- */ + /* Application Drag/Drop */ + /* -------------------------------------------- */ + + /** + * On dragStart on the item. + * @param {DragEvent} event - The drag event + */ + async _onDragStart(event) { + const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]'); + + if (attackItem) { + const attackData = { + type: 'Attack', + actorUuid: this.document.uuid, + img: this.document.system.attack.img, + fromInternal: true + }; + event.dataTransfer.setData('text/plain', JSON.stringify(attackData)); + event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0); + } + } } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 0c25a44d..723b4802 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -30,7 +30,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { }, dragDrop: [ { dragSelector: null, dropSelector: '.tab.features .drop-section' }, - { dragSelector: '.feature-item', dropSelector: null } + { dragSelector: '.feature-item', dropSelector: null }, + { dragSelector: '.action-item', dropSelector: null } ] }; @@ -258,6 +259,23 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true }; event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0); + } else { + const actionItem = event.currentTarget.closest('.action-item'); + if (actionItem) { + const action = this.document.system.actions[actionItem.dataset.index]; + if (!action) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.actionIsMissing')); + return; + } + + const actionData = { + type: 'Action', + data: { ...action.toObject(), id: action.id, itemUuid: this.document.uuid }, + fromInternal: true + }; + event.dataTransfer.setData('text/plain', JSON.stringify(actionData)); + event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0); + } } } diff --git a/module/applications/ui/_module.mjs b/module/applications/ui/_module.mjs index f1c32840..6a17a61e 100644 --- a/module/applications/ui/_module.mjs +++ b/module/applications/ui/_module.mjs @@ -2,3 +2,4 @@ export { default as DhChatLog } from './chatLog.mjs'; export { default as DhCombatTracker } from './combatTracker.mjs'; export * as DhCountdowns from './countdowns.mjs'; export { default as DhFearTracker } from './fearTracker.mjs'; +export { default as DhHotbar } from './hotbar.mjs'; diff --git a/module/applications/ui/hotbar.mjs b/module/applications/ui/hotbar.mjs new file mode 100644 index 00000000..b4ebc05c --- /dev/null +++ b/module/applications/ui/hotbar.mjs @@ -0,0 +1,129 @@ +export default class DhHotbar extends foundry.applications.ui.Hotbar { + constructor(options) { + super(options); + + this.setupHooks(); + } + + static async useItem(uuid) { + const item = await fromUuid(uuid); + if (!item) { + return ui.notifications.warn('WARNING.ObjectDoesNotExist', { + format: { + name: game.i18n.localize('Document'), + identifier: uuid + } + }); + } + + await item.use({}); + } + + static async useAction(itemUuid, actionId) { + const item = await foundry.utils.fromUuid(itemUuid); + if (!item) { + return ui.notifications.warn('WARNING.ObjectDoesNotExist', { + format: { + name: game.i18n.localize('Document'), + identifier: itemUuid + } + }); + } + + const action = item.system.actions.find(x => x.id === actionId); + if (!action) { + return ui.notifications.warn('DAGGERHEART.UI.Notifications.actionIsMissing'); + } + + await action.use({}); + } + + static async useAttack(actorUuid) { + const actor = await foundry.utils.fromUuid(actorUuid); + if (!actor) { + return ui.notifications.warn('WARNING.ObjectDoesNotExist', { + format: { + name: game.i18n.localize('Document'), + identifier: actorUuid + } + }); + } + + const attack = actor.system.attack; + if (!attack) { + return ui.notifications.warn('DAGGERHEART.UI.Notifications.attackIsMissing'); + } + + await attack.use({}); + } + + setupHooks() { + Hooks.on('hotbarDrop', (bar, data, slot) => { + if (data.type === 'Item') { + const item = foundry.utils.fromUuidSync(data.uuid); + if (item.uuid.startsWith('Compendium') || !item.isOwned || !item.isOwner) return true; + + switch (item.type) { + case 'ancestry': + case 'community': + case 'class': + case 'subclass': + return true; + default: + this.createItemMacro(item, slot); + return false; + } + } else if (data.type === 'Action') { + const item = foundry.utils.fromUuidSync(data.data.itemUuid); + if (item.uuid.startsWith('Compendium')) return true; + if (!item.isOwned || !item.isOwner) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedActionMacro')); + return false; + } + + this.createActionMacro(data, slot); + return false; + } else if (data.type === 'Attack') { + const actor = foundry.utils.fromUuidSync(data.actorUuid); + if (actor.uuid.startsWith('Compendium')) return true; + if (!actor.isOwner) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedAttackMacro')); + return false; + } + + this.createAttackMacro(data, slot); + return false; + } + }); + } + + async createItemMacro(data, slot) { + const macro = await Macro.implementation.create({ + name: `${game.i18n.localize('Display')} ${name}`, + type: CONST.MACRO_TYPES.SCRIPT, + img: data.img, + command: `await game.system.api.applications.ui.DhHotbar.useItem("${data.uuid}");` + }); + await game.user.assignHotbarMacro(macro, slot); + } + + async createActionMacro(data, slot) { + const macro = await Macro.implementation.create({ + name: `${game.i18n.localize('Display')} ${name}`, + type: CONST.MACRO_TYPES.SCRIPT, + img: data.data.img, + command: `await game.system.api.applications.ui.DhHotbar.useAction("${data.data.itemUuid}", "${data.data.id}");` + }); + await game.user.assignHotbarMacro(macro, slot); + } + + async createAttackMacro(data, slot) { + const macro = await Macro.implementation.create({ + name: `${game.i18n.localize('Display')} ${name}`, + type: CONST.MACRO_TYPES.SCRIPT, + img: data.img, + command: `await game.system.api.applications.ui.DhHotbar.useAttack("${data.actorUuid}");` + }); + await game.user.assignHotbarMacro(macro, slot); + } +} diff --git a/module/data/countdowns.mjs b/module/data/countdowns.mjs index 881ecf20..34e8b790 100644 --- a/module/data/countdowns.mjs +++ b/module/data/countdowns.mjs @@ -135,8 +135,8 @@ export const registerCountdownHooks = () => { if (application) { foundry.applications.instances.get(application)?.render(); } else { - foundry.applications.instances.get('narrative-countdowns').render(); - foundry.applications.instances.get('encounter-countdowns').render(); + foundry.applications.instances.get('narrative-countdowns')?.render(); + foundry.applications.instances.get('encounter-countdowns')?.render(); } return false; From 1d5e26728540b065034a4e9551dad65b28adef91 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:07:11 +0200 Subject: [PATCH 43/58] Improved the datastructure some to avoid errors and simplify useage (#361) --- module/applications/dialogs/resourceDiceDialog.mjs | 2 +- module/data/actor/character.mjs | 10 +++++----- module/data/item/base.mjs | 7 +++++-- templates/dialogs/dice-roll/resourceDice.hbs | 8 ++++---- templates/sheets/global/partials/item-resource.hbs | 2 +- templates/sheets/global/partials/resource-section.hbs | 2 +- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/module/applications/dialogs/resourceDiceDialog.mjs b/module/applications/dialogs/resourceDiceDialog.mjs index b79ff895..8205dee5 100644 --- a/module/applications/dialogs/resourceDiceDialog.mjs +++ b/module/applications/dialogs/resourceDiceDialog.mjs @@ -67,7 +67,7 @@ export default class ResourceDiceDialog extends HandlebarsApplicationMixin(Appli static async rerollDice() { const max = itemAbleRollParse(this.item.system.resource.max, this.actor, this.item); - const diceFormula = `${max}d${this.item.system.resource.dieFaces}`; + const diceFormula = `${max}${this.item.system.resource.dieFaces}`; const roll = await new Roll(diceFormula).evaluate(); if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); this.rollValues = roll.terms[0].results.map(x => ({ value: x.result, used: false })); diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 6fe66a53..6b0a2fd7 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -252,13 +252,13 @@ export default class DhCharacter extends BaseDataActor { features = []; for (let item of this.parent.items) { - if (item.system.type === CONFIG.DH.ITEM.featureTypes.ancestry.id) { + if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.ancestry.id) { ancestryFeatures.push(item); - } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.community.id) { + } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) { communityFeatures.push(item); - } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.class.id) { + } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) { classFeatures.push(item); - } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.subclass.id) { + } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) { const subclassState = this.class.subclass.system.featureState; const identifier = item.system.identifier; if ( @@ -268,7 +268,7 @@ export default class DhCharacter extends BaseDataActor { ) { subclassFeatures.push(item); } - } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.companion.id) { + } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) { companionFeatures.push(item); } else if (item.type === 'feature' && !item.system.type) { features.push(item); diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index e99c85c3..24e5e0cc 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -53,11 +53,14 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { }), diceStates: new fields.TypedObjectField( new fields.SchemaField({ - value: new fields.NumberField({ integer: true, nullable: true, initial: null }), + value: new fields.NumberField({ integer: true, initial: 1, min: 1 }), used: new fields.BooleanField({ initial: false }) }) ), - dieFaces: new fields.StringField({ initial: '4' }) + dieFaces: new fields.StringField({ + choices: CONFIG.DH.GENERAL.diceTypes, + initial: CONFIG.DH.GENERAL.diceTypes.d4 + }) }, { nullable: true, initial: null } ); diff --git a/templates/dialogs/dice-roll/resourceDice.hbs b/templates/dialogs/dice-roll/resourceDice.hbs index 33c93386..bebe8f4e 100644 --- a/templates/dialogs/dice-roll/resourceDice.hbs +++ b/templates/dialogs/dice-roll/resourceDice.hbs @@ -3,14 +3,14 @@ {{#times (rollParsed item.system.resource.max actor item numerical=true)}} {{#with (ifThen (lookup ../diceStates this) (lookup ../diceStates this) this) as | state |}}
    - - + +
    {{/with}} {{/times}}
    - - + +
    \ No newline at end of file diff --git a/templates/sheets/global/partials/item-resource.hbs b/templates/sheets/global/partials/item-resource.hbs index 9b92dea0..d90f0b3f 100644 --- a/templates/sheets/global/partials/item-resource.hbs +++ b/templates/sheets/global/partials/item-resource.hbs @@ -10,7 +10,7 @@
    - + {{#if state.used}}{{/if}}
    diff --git a/templates/sheets/global/partials/resource-section.hbs b/templates/sheets/global/partials/resource-section.hbs index f0d322d3..ab329efc 100644 --- a/templates/sheets/global/partials/resource-section.hbs +++ b/templates/sheets/global/partials/resource-section.hbs @@ -19,7 +19,7 @@ {{formGroup systemFields.resource.fields.value value=source.system.resource.value localize=true}} {{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}} {{else}} - {{formGroup systemFields.resource.fields.dieFaces value=source.system.resource.dieFaces localize=true}} + {{formGroup systemFields.resource.fields.dieFaces value=source.system.resource.dieFaces localize=true blank=false}} {{formGroup systemFields.resource.fields.max value=source.system.resource.max label="DAGGERHEART.ITEMS.FIELDS.resource.amount.label" localize=true}} {{/if}}
    From 0cc1597dfe1a37566180dca810f892c28556610e Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:43:35 +0200 Subject: [PATCH 44/58] [Fix] Class Feature Change (#364) * Changed to just use a features field * Subclass now uses a simple Features field --- lang/en.json | 11 ++- .../characterCreation/characterCreation.mjs | 4 +- module/applications/sheets/items/ancestry.mjs | 25 ++----- module/applications/sheets/items/class.mjs | 48 ++++++++----- module/applications/sheets/items/subclass.mjs | 69 +++++++++++++++---- module/config/actorConfig.mjs | 2 +- module/config/itemConfig.mjs | 7 +- module/data/actor/character.mjs | 17 ++--- module/data/item/class.mjs | 17 +++-- module/data/item/domainCard.mjs | 1 - module/data/item/subclass.mjs | 22 +++--- .../sheets/items/domainCard/settings.hbs | 2 - templates/sheets/items/subclass/features.hbs | 30 ++++---- 13 files changed, 158 insertions(+), 97 deletions(-) diff --git a/lang/en.json b/lang/en.json index 3456b6b5..80cc67f7 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1325,8 +1325,8 @@ }, "DomainCard": { "type": "Type", - "foundation": "Foundation", "recallCost": "Recall Cost", + "foundationTitle": "Foundation", "specializationTitle": "Specialization", "masteryTitle": "Mastery" }, @@ -1541,7 +1541,14 @@ "actionIsMissing": "Action is missing", "attackIsMissing": "Attack is missing", "unownedActionMacro": "Cannot make a Use macro for an Action not on your character", - "unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters" + "unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters", + "featureNotHope": "This feature is used as something else than a Hope feature and cannot be used here.", + "featureNotClass": "This feature is used as something else than a Class feature and cannot be used here.", + "featureNotPrimary": "This feature is used as something else than a Primary feature and cannot be used here.", + "featureNotSecondary": "This feature is used as something else than a Secondary feature and cannot be used here.", + "featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.", + "featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.", + "featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here." }, "Tooltip": { "openItemWorld": "Open Item World", diff --git a/module/applications/characterCreation/characterCreation.mjs b/module/applications/characterCreation/characterCreation.mjs index ed0ee5a7..b8759cc5 100644 --- a/module/applications/characterCreation/characterCreation.mjs +++ b/module/applications/characterCreation/characterCreation.mjs @@ -506,9 +506,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl name: this.setup.ancestryName ?? this.setup.primaryAncestry.name, system: { ...this.setup.primaryAncestry.system, - features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid], - primaryFeature: primaryAncestryFeature.uuid, - secondaryFeature: secondaryAncestryFeature.uuid + features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid] } }; diff --git a/module/applications/sheets/items/ancestry.mjs b/module/applications/sheets/items/ancestry.mjs index bd9e3792..de55301d 100644 --- a/module/applications/sheets/items/ancestry.mjs +++ b/module/applications/sheets/items/ancestry.mjs @@ -63,22 +63,8 @@ export default class AncestrySheet extends DHHeritageSheet { event.stopPropagation(); const target = button.closest('.feature-item'); const feature = this.document.system[`${target.dataset.type}Feature`]; - const featureExists = feature && Object.keys(feature).length > 0; - if (featureExists) { - const confirmed = await foundry.applications.api.DialogV2.confirm({ - window: { - title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { - type: game.i18n.localize(`TYPES.Item.feature`), - name: feature.name - }) - }, - content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: feature.name }) - }); - if (!confirmed) return; - } - - if (featureExists && target.dataset.type === 'primary') await feature.update({ 'system.primary': null }); + if (feature) await feature.update({ 'system.subType': null }); await this.document.update({ 'system.features': this.document.system.features.filter(x => x && x.uuid !== feature.uuid).map(x => x.uuid) }); @@ -94,15 +80,18 @@ export default class AncestrySheet extends DHHeritageSheet { */ async _onDrop(event) { event.stopPropagation(); - event.preventDefault(); - const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await fromUuid(data.uuid); if (item?.type === 'feature') { const subType = event.target.closest('.primary-feature') ? 'primary' : 'secondary'; - await item.update({ 'system.subType': subType }); + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes[subType]) { + const error = subType === 'primary' ? 'featureNotPrimary' : 'featureNotSecondary'; + ui.notifications.warn(game.i18n.localize(`DAGGERHEART.UI.Notifications.${error}`)); + return; + } + await item.update({ 'system.subType': subType }); await this.document.update({ 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] }); diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index b49105be..3a34bcec 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -78,6 +78,7 @@ export default class ClassSheet extends DHBaseItemSheet { /* -------------------------------------------- */ async _onDrop(event) { + event.stopPropagation(); const data = TextEditor.getDragEventData(event); const item = await fromUuid(data.uuid); const target = event.target.closest('fieldset.drop-section'); @@ -87,12 +88,24 @@ export default class ClassSheet extends DHBaseItemSheet { }); } else if (item.type === 'feature') { if (target.classList.contains('hope-feature')) { + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.hope) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotHope')); + return; + } + + await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.hope }); await this.document.update({ - 'system.hopeFeatures': [...this.document.system.hopeFeatures.map(x => x.uuid), item.uuid] + 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] }); } else if (target.classList.contains('class-feature')) { + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.class) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotClass')); + return; + } + + await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.class }); await this.document.update({ - 'system.classFeatures': [...this.document.system.classFeatures.map(x => x.uuid), item.uuid] + 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] }); } } else if (item.type === 'weapon') { @@ -177,28 +190,25 @@ export default class ClassSheet extends DHBaseItemSheet { doc.sheet.render({ force: true }); } - getActionPath(type) { - return type === 'hope' ? 'hopeFeatures' : 'classFeatures'; - } - static async addFeature(_, target) { - const actionPath = this.getActionPath(target.dataset.type); const feature = await game.items.documentClass.create({ type: 'feature', - name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }), + system: { + subType: + target.dataset.type === 'hope' + ? CONFIG.DH.ITEM.featureSubTypes.hope + : CONFIG.DH.ITEM.featureSubTypes.class + } }); await this.document.update({ - [`system.${actionPath}`]: [ - ...this.document.system[actionPath].filter(x => x).map(x => x.uuid), - feature.uuid - ] + [`system.features`]: [...this.document.system.features.filter(x => x).map(x => x.uuid), feature.uuid] }); } static async editFeature(_, button) { const target = button.closest('.feature-item'); - const actionPath = this.getActionPath(button.dataset.type); - const feature = this.document.system[actionPath].find(x => x?.id === target.dataset.featureId); + const feature = this.document.system.features.find(x => x?.id === target.dataset.featureId); if (!feature) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing')); return; @@ -210,10 +220,16 @@ export default class ClassSheet extends DHBaseItemSheet { static async deleteFeature(event, button) { event.stopPropagation(); const target = button.closest('.feature-item'); - const actionPath = this.getActionPath(button.dataset.type); + + const feature = this.document.system.features.find( + feature => feature && feature.id === target.dataset.featureId + ); + if (feature) { + await feature.update({ 'system.subType': null }); + } await this.document.update({ - [`system.${actionPath}`]: this.document.system[actionPath] + [`system.features`]: this.document.system.features .filter(feature => feature && feature.id !== target.dataset.featureId) .map(x => x.uuid) }); diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs index 31eca43a..fcf62f69 100644 --- a/module/applications/sheets/items/subclass.mjs +++ b/module/applications/sheets/items/subclass.mjs @@ -40,28 +40,46 @@ export default class SubclassSheet extends DHBaseItemSheet { static async addFeature(_, target) { const feature = await game.items.documentClass.create({ type: 'feature', - name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }), + system: { + subType: + target.dataset.type === 'foundation' + ? CONFIG.DH.ITEM.featureSubTypes.foundation + : target.dataset.type === 'specialization' + ? CONFIG.DH.ITEM.featureSubTypes.specialization + : CONFIG.DH.ITEM.featureSubTypes.mastery + } }); await this.document.update({ - [`system.${target.dataset.type}`]: feature.uuid + [`system.features`]: [...this.document.system.features.map(x => x.uuid), feature.uuid] }); } static async editFeature(_, button) { - const feature = this.document.system[button.dataset.type]; + const feature = this.document.system.features.find(x => x.id === button.dataset.feature); if (!feature) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing')); return; } + if (feature) { + await feature.update({ 'system.subType': null }); + } + feature.sheet.render(true); } - static async deleteFeature(event, button) { + static async deleteFeature(event, target) { event.stopPropagation(); + const feature = this.document.system.features.find(feature => feature.id === target.dataset.feature); + if (feature) { + await feature.update({ 'system.subType': null }); + } await this.document.update({ - [`system.${button.dataset.type}`]: null + [`system.features`]: this.document.system.features + .filter(feature => feature && feature.id !== target.dataset.feature) + .map(x => x.uuid) }); } @@ -82,18 +100,45 @@ export default class SubclassSheet extends DHBaseItemSheet { } async _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); if (data.fromInternal) return; const item = await fromUuid(data.uuid); - if (item?.type === 'feature') { - const dropSection = event.target.closest('.drop-section'); - if (this.document.system[dropSection.dataset.type]) { - ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsFull')); - return; - } + const target = event.target.closest('fieldset.drop-section'); + if (item.type === 'feature') { + if (target.dataset.type === 'foundation') { + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.foundation) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotFoundation')); + return; + } - await this.document.update({ [`system.${dropSection.dataset.type}`]: item.uuid }); + await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.foundation }); + await this.document.update({ + 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] + }); + } else if (target.dataset.type === 'specialization') { + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.specialization) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotSpecialization')); + return; + } + + await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.specialization }); + await this.document.update({ + 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] + }); + } else if (target.dataset.type === 'mastery') { + if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.mastery) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotMastery')); + return; + } + + await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.mastery }); + await this.document.update({ + 'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid] + }); + } } } } diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 02cfd4a9..d05dc81c 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -411,7 +411,7 @@ export const levelupData = { }; export const subclassFeatureLabels = { - 1: 'DAGGERHEART.ITEMS.DomainCard.foundation', + 1: 'DAGGERHEART.ITEMS.DomainCard.foundationTitle', 2: 'DAGGERHEART.ITEMS.DomainCard.specializationTitle', 3: 'DAGGERHEART.ITEMS.DomainCard.masteryTitle' }; diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index ede5ef08..b26a26ca 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -1322,7 +1322,12 @@ export const featureTypes = { export const featureSubTypes = { primary: 'primary', - secondary: 'secondary' + secondary: 'secondary', + hope: 'hope', + class: 'class', + foundation: 'foundation', + specialization: 'specialization', + mastery: 'mastery' }; export const actionTypes = { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 6b0a2fd7..1c15d036 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -124,12 +124,9 @@ export default class DhCharacter extends BaseDataActor { label: 'DAGGERHEART.GENERAL.Range.other' }) }), - rally: new fields.ArrayField( - new fields.StringField(), - { - label: 'DAGGERHEART.CLASS.Feature.rallyDice' - } - ) + rally: new fields.ArrayField(new fields.StringField(), { + label: 'DAGGERHEART.CLASS.Feature.rallyDice' + }) }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), rules: new fields.SchemaField({ @@ -260,11 +257,11 @@ export default class DhCharacter extends BaseDataActor { classFeatures.push(item); } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) { const subclassState = this.class.subclass.system.featureState; - const identifier = item.system.identifier; + const subType = item.system.subType; if ( - identifier === 'foundationFeature' || - (identifier === 'specializationFeature' && subclassState >= 2) || - (identifier === 'masterFeature' && subclassState >= 3) + subType === CONFIG.DH.ITEM.featureSubTypes.foundation || + (subType === CONFIG.DH.ITEM.featureSubTypes.specialization && subclassState >= 2) || + (subType === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3) ) { subclassFeatures.push(item); } diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index 281b0a48..b8a9ab81 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -27,8 +27,7 @@ export default class DHClass extends BaseDataItem { label: 'DAGGERHEART.GENERAL.hitPoints.plural' }), evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }), - hopeFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }), - classFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }), + features: new ForeignDocumentUUIDArrayField({ type: 'Item' }), subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }), inventory: new fields.SchemaField({ take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }), @@ -52,12 +51,18 @@ export default class DHClass extends BaseDataItem { }; } - get hopeFeature() { - return this.hopeFeatures.length > 0 ? this.hopeFeatures[0] : null; + get hopeFeatures() { + return ( + this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.hope) ?? + (this.features.filter(x => !x).length > 0 ? {} : null) + ); } - get features() { - return [...this.hopeFeatures.filter(x => x), ...this.classFeatures.filter(x => x)]; + get classFeatures() { + return ( + this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.class) ?? + (this.features.filter(x => !x).length > 0 ? {} : null) + ); } async _preCreate(data, options, user) { diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index 89bbfb40..df60b9d1 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -29,7 +29,6 @@ export default class DHDomainCard extends BaseDataItem { required: true, initial: CONFIG.DH.DOMAIN.cardTypes.ability.id }), - foundation: new fields.BooleanField({ initial: false }), inVault: new fields.BooleanField({ initial: false }), actions: new fields.ArrayField(new ActionField()) }; diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 265c2566..e0a76092 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -1,4 +1,4 @@ -import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; +import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import BaseDataItem from './base.mjs'; export default class DHSubclass extends BaseDataItem { @@ -22,20 +22,22 @@ export default class DHSubclass extends BaseDataItem { nullable: true, initial: null }), - foundationFeature: new ForeignDocumentUUIDField({ type: 'Item' }), - specializationFeature: new ForeignDocumentUUIDField({ type: 'Item' }), - masteryFeature: new ForeignDocumentUUIDField({ type: 'Item' }), + features: new ForeignDocumentUUIDArrayField({ type: 'Item' }), featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }), isMulticlass: new fields.BooleanField({ initial: false }) }; } - get features() { - return [ - { ...this.foundationFeature?.toObject(), identifier: 'foundationFeature' }, - { ...this.specializationFeature?.toObject(), identifier: 'specializationFeature' }, - { ...this.masteryFeature?.toObject(), identifier: 'masteryFeature' } - ]; + get foundationFeatures() { + return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.foundation); + } + + get specializationFeatures() { + return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.specialization); + } + + get masteryFeatures() { + return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.mastery); } async _preCreate(data, options, user) { diff --git a/templates/sheets/items/domainCard/settings.hbs b/templates/sheets/items/domainCard/settings.hbs index 2faa6934..5518b4c3 100644 --- a/templates/sheets/items/domainCard/settings.hbs +++ b/templates/sheets/items/domainCard/settings.hbs @@ -8,8 +8,6 @@ {{localize "DAGGERHEART.GENERAL.type"}} {{formField systemFields.type value=source.system.type localize=true}} - {{localize "DAGGERHEART.ITEMS.DomainCard.foundation"}} - {{formField systemFields.foundation value=source.system.foundation }} {{localize "DAGGERHEART.GENERAL.Domain.single"}} {{formField systemFields.domain value=source.system.domain localize=true}} {{localize "DAGGERHEART.GENERAL.level"}} diff --git a/templates/sheets/items/subclass/features.hbs b/templates/sheets/items/subclass/features.hbs index d2424d01..1a75974e 100644 --- a/templates/sheets/items/subclass/features.hbs +++ b/templates/sheets/items/subclass/features.hbs @@ -3,42 +3,42 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > -
    +
    {{localize "DAGGERHEART.GENERAL.Tabs.foundation"}} - +
    - {{#if source.system.foundationFeature}} - {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundationFeature' feature=source.system.foundationFeature}} - {{/if}} + {{#each source.system.foundationFeatures as | feature | }} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundation' feature=feature}} + {{/each}}
    -
    +
    {{localize "DAGGERHEART.GENERAL.Tabs.specialization"}} - +
    - {{#if source.system.specializationFeature}} - {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specializationFeature' feature=source.system.specializationFeature}} - {{/if}} + {{#each source.system.specializationFeatures as | feature |}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specialization' feature=feature}} + {{/each}}
    -
    +
    {{localize "DAGGERHEART.GENERAL.Tabs.mastery"}} - +
    - {{#if source.system.masteryFeature}} - {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='masteryFeature' feature=source.system.masteryFeature}} - {{/if}} + {{#each source.system.masteryFeatures as | feature |}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='mastery' feature=feature}} + {{/each}}
    \ No newline at end of file From 6e87e4dad066173cd4cd47fbb135881725f82330 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 18 Jul 2025 00:48:59 +0200 Subject: [PATCH 45/58] [Fix] Downtime Rework (#367) * Fixed so that the dropdown for activeEffectAutocomplete never ends up behind dialog * Downtime can now display both ShortRest and LongRest options depending on character rules * Initial downtime layout rework * Fixed styling for downtime tooltip * Added icon to homebrew menu for DowntimeActions * Fixed columns if both types of moves are not available * Changed the lightmode to darkmode * Added downtime buttons * . * Moved extra rest options from rules to bonuses * Improved dialog width --- lang/en.json | 32 +++++- module/applications/dialogs/downtime.mjs | 87 +++++++++++---- .../components/settingsActionsView.mjs | 10 +- .../settings/homebrewSettings.mjs | 2 + .../sheets-configs/activeEffectConfig.mjs | 3 + .../applications/sheets/actors/character.mjs | 9 +- module/config/generalConfig.mjs | 19 ++-- module/data/actor/character.mjs | 38 +++++++ module/data/settings/Homebrew.mjs | 2 + module/documents/token.mjs | 20 ++-- module/documents/tooltipManager.mjs | 51 ++++++++- module/systemRegistration/handlebars.mjs | 3 +- .../dialog/downtime/downtime-container.less | 102 +++++++++--------- styles/less/global/tab-navigation.less | 20 +++- .../less/sheets/actors/character/header.less | 9 ++ styles/less/ux/autocomplete/autocomplete.less | 1 - styles/less/ux/tooltip/tooltip.less | 14 +++ templates/dialogs/downtime.hbs | 24 ----- templates/dialogs/downtime/activities.hbs | 18 ++++ templates/dialogs/downtime/downtime.hbs | 14 +++ templates/settings/automation-settings.hbs | 2 +- templates/settings/components/action-view.hbs | 19 ++-- templates/sheets/actors/character/header.hbs | 11 +- .../sheets/global/tabs/tab-navigation.hbs | 25 +++-- templates/ui/tooltip/downtime.hbs | 7 ++ 25 files changed, 390 insertions(+), 152 deletions(-) delete mode 100644 templates/dialogs/downtime.hbs create mode 100644 templates/dialogs/downtime/activities.hbs create mode 100644 templates/dialogs/downtime/downtime.hbs create mode 100644 templates/ui/tooltip/downtime.hbs diff --git a/lang/en.json b/lang/en.json index 80cc67f7..39e49b67 100755 --- a/lang/en.json +++ b/lang/en.json @@ -249,8 +249,9 @@ "title": "{actor} - Death Move" }, "Downtime": { - "downtimeHeader": "Downtime Moves ({current}/{max})", "longRest": { + "title": "Long Rest", + "moves": "Long Rest Moves ({current}/{max})", "clearStress": { "description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.", "name": "Clear Stress" @@ -267,7 +268,6 @@ "description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.", "name": "Tend to Wounds" }, - "title": "Long Rest", "workOnAProject": { "description": "Establish or continue work on a project.", "name": "Work on a Project" @@ -275,6 +275,7 @@ }, "shortRest": { "title": "Short Rest", + "moves": "Short Rest Moves ({current}/{max})", "tendToWounds": { "name": "Tend to Wounds", "description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead." @@ -291,7 +292,8 @@ "name": "Prepare", "description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope." } - } + }, + "takeDowntime": "Take Downtime" }, "HUD": { "tokenHUD": { @@ -1012,6 +1014,30 @@ "singular": "Adversary", "plural": "Adversaries" }, + "Bonuses": { + "rest": { + "shortRest": { + "shortRestMoves": { + "label": "Short Rest: Bonus Short Rest Moves", + "hint": "The number of extra Short Rest Moves the character can take during a Short Rest." + }, + "longRestMoves": { + "label": "Short Rest: Bonus Long Rest Moves", + "hint": "The number of extra Long Rest Moves the character can take during a Short Rest." + } + }, + "longRest": { + "shortRestMoves": { + "label": "Long Rest: Bonus Short Rest Moves", + "hint": "The number of extra Short Rest Moves the character can take during a Long Rest." + }, + "longRestMoves": { + "label": "Long Rest: Bonus Long Rest Moves", + "hint": "The number of extra Long Rest Moves the character can take during a Long Rest." + } + } + } + }, "Character": { "singular": "Character", "plural": "Characters" diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 3966f7e4..15add3ad 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -7,8 +7,22 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV this.actor = actor; this.shortrest = shortrest; - const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves; - this.moveData = shortrest ? options.shortRest : options.longRest; + this.moveData = foundry.utils.deepClone( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves + ); + this.nrChoices = { + shortRest: { + max: + (shortrest ? this.moveData.shortRest.nrChoices : 0) + + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].shortMoves + }, + longRest: { + max: + (!shortrest ? this.moveData.longRest.nrChoices : 0) + + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].longMoves + } + }; + this.nrChoices.total = { max: this.nrChoices.shortRest.max + this.nrChoices.longRest.max }; } get title() { @@ -17,8 +31,8 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'downtime'], - position: { width: 680, height: 'auto' }, + classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'downtime'], + position: { width: 'auto', height: 'auto' }, actions: { selectMove: this.selectMove, takeDowntime: this.takeDowntime @@ -29,7 +43,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static PARTS = { application: { id: 'downtime', - template: 'systems/daggerheart/templates/dialogs/downtime.hbs' + template: 'systems/daggerheart/templates/dialogs/downtime/downtime.hbs' } }; @@ -37,46 +51,83 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV super._attachPartListeners(partId, htmlElement, options); htmlElement - .querySelectorAll('.activity-image') + .querySelectorAll('.activity-container') .forEach(element => element.addEventListener('contextmenu', this.deselectMove.bind(this))); } async _prepareContext(_options) { const context = await super._prepareContext(_options); + context.title = game.i18n.localize( + `DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title` + ); context.selectedActivity = this.selectedActivity; context.moveData = this.moveData; - context.nrCurrentChoices = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); - context.disabledDowntime = context.nrCurrentChoices < context.moveData.nrChoices; + context.nrCurrentChoices = Object.values(this.moveData).reduce((acc, category) => { + acc += Object.values(category.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); + return acc; + }, 0); + + context.nrChoices = { + ...this.nrChoices, + shortRest: { + ...this.nrChoices.shortRest, + current: Object.values(this.moveData.shortRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + }, + longRest: { + ...this.nrChoices.longRest, + current: Object.values(this.moveData.longRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + } + }; + context.nrChoices.total = { + ...this.nrChoices.total, + current: context.nrChoices.shortRest.current + context.nrChoices.longRest.current + }; + + context.shortRestMoves = this.nrChoices.shortRest.max > 0 ? this.moveData.shortRest : null; + context.longRestMoves = this.nrChoices.longRest.max > 0 ? this.moveData.longRest : null; + + context.disabledDowntime = context.nrChoices.total.current < context.nrChoices.total.max; return context; } - static selectMove(_, button) { - const nrSelected = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); - if (nrSelected === this.moveData.nrChoices) { + static selectMove(_, target) { + const nrSelected = Object.values(this.moveData[target.dataset.category].moves).reduce( + (acc, x) => acc + (x.selected ?? 0), + 0 + ); + + if (nrSelected === this.nrChoices[target.dataset.category].max) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves')); return; } - const move = button.dataset.move; - this.moveData.moves[move].selected = this.moveData.moves[move].selected - ? this.moveData.moves[move].selected + 1 + const move = target.dataset.move; + this.moveData[target.dataset.category].moves[move].selected = this.moveData[target.dataset.category].moves[move] + .selected + ? this.moveData[target.dataset.category].moves[move].selected + 1 : 1; this.render(); } deselectMove(event) { - const move = event.currentTarget.dataset.move; - this.moveData.moves[move].selected = this.moveData.moves[move].selected - ? this.moveData.moves[move].selected - 1 + const button = event.target.closest('.activity-container'); + const move = button.dataset.move; + this.moveData[button.dataset.category].moves[move].selected = this.moveData[button.dataset.category].moves[move] + .selected + ? this.moveData[button.dataset.category].moves[move].selected - 1 : 0; this.render(); } static async takeDowntime() { - const moves = Object.values(this.moveData.moves).filter(x => x.selected); + const moves = Object.values(this.moveData).flatMap(category => { + return Object.values(category.moves) + .filter(x => x.selected) + .flatMap(move => [...Array(move.selected).keys()].map(_ => move)); + }); const cls = getDocumentClass('ChatMessage'); const msg = new cls({ diff --git a/module/applications/settings/components/settingsActionsView.mjs b/module/applications/settings/components/settingsActionsView.mjs index a905e824..f77c5fce 100644 --- a/module/applications/settings/components/settingsActionsView.mjs +++ b/module/applications/settings/components/settingsActionsView.mjs @@ -4,13 +4,14 @@ import DHActionConfig from '../../sheets-configs/action-config.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DhSettingsActionView extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(resolve, reject, title, name, img, description, actions) { + constructor(resolve, reject, title, name, icon, img, description, actions) { super({}); this.resolve = resolve; this.reject = reject; this.viewTitle = title; this.name = name; + this.icon = icon; this.img = img; this.description = description; this.actions = actions; @@ -23,7 +24,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App static DEFAULT_OPTIONS = { tag: 'form', classes: ['daggerheart', 'setting', 'dh-style'], - position: { width: '400', height: 'auto' }, + position: { width: 440, height: 'auto' }, actions: { editImage: this.onEditImage, addItem: this.addItem, @@ -46,6 +47,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App async _prepareContext(_options) { const context = await super._prepareContext(_options); context.name = this.name; + context.icon = this.icon; context.img = this.img; context.description = this.description; context.enrichedDescription = await foundry.applications.ux.TextEditor.enrichHTML(context.description); @@ -55,8 +57,9 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App } static async updateData(event, element, formData) { - const { name, img, description } = foundry.utils.expandObject(formData.object); + const { name, icon, description } = foundry.utils.expandObject(formData.object); this.name = name; + this.icon = icon; this.description = description; this.render(); @@ -65,6 +68,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App static async saveForm(event) { this.resolve({ name: this.name, + icon: this.icon, img: this.img, description: this.description, actions: this.actions diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 08b4cf4e..e516be03 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -76,6 +76,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli reject, game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.downtimeMoves'), move.name, + move.icon, move.img, move.description, move.actions @@ -87,6 +88,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli await this.settings.updateSource({ [`restMoves.${type}.moves.${id}`]: { name: data.name, + icon: data.icon, img: data.img, description: data.description } diff --git a/module/applications/sheets-configs/activeEffectConfig.mjs b/module/applications/sheets-configs/activeEffectConfig.mjs index 8574a5db..087b5b08 100644 --- a/module/applications/sheets-configs/activeEffectConfig.mjs +++ b/module/applications/sheets-configs/activeEffectConfig.mjs @@ -88,6 +88,9 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac element.value = `system.${item.value}`; }, click: e => e.fetch(), + customize: function (_input, _inputRect, container) { + container.style.zIndex = foundry.applications.api.ApplicationV2._maxZ; + }, minLength: 0 }); }); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 139a1369..0f6f8284 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -28,7 +28,8 @@ export default class CharacterSheet extends DHBaseActorSheet { useAction: this.useAction, toggleResourceDice: this.toggleResourceDice, handleResourceDice: this.handleResourceDice, - toChat: this.toChat + toChat: this.toChat, + useDowntime: this.useDowntime }, window: { resizable: true @@ -752,6 +753,12 @@ export default class CharacterSheet extends DHBaseActorSheet { } } + static useDowntime(_, button) { + new game.system.api.applications.dialogs.Downtime(this.document, button.dataset.type === 'shortRest').render( + true + ); + } + async _onDragStart(event) { const item = this.getItem(event); diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 704a5401..632e5448 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -130,6 +130,7 @@ export const defaultRestOptions = { tendToWounds: { id: 'tendToWounds', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'), + icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.description'), actions: [ @@ -153,6 +154,7 @@ export const defaultRestOptions = { clearStress: { id: 'clearStress', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'), + icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.description'), actions: [ @@ -176,6 +178,7 @@ export const defaultRestOptions = { repairArmor: { id: 'repairArmor', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'), + icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'), actions: [] @@ -183,6 +186,7 @@ export const defaultRestOptions = { prepare: { id: 'prepare', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.name'), + icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'), actions: [] @@ -192,6 +196,7 @@ export const defaultRestOptions = { tendToWounds: { id: 'tendToWounds', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'), + icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.description'), actions: [] @@ -199,6 +204,7 @@ export const defaultRestOptions = { clearStress: { id: 'clearStress', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'), + icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.description'), actions: [] @@ -206,6 +212,7 @@ export const defaultRestOptions = { repairArmor: { id: 'repairArmor', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'), + icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.description'), actions: [] @@ -213,6 +220,7 @@ export const defaultRestOptions = { prepare: { id: 'prepare', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.name'), + icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'), actions: [] @@ -220,19 +228,12 @@ export const defaultRestOptions = { workOnAProject: { id: 'workOnAProject', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.name'), + icon: 'fa-solid fa-diagram-project', img: 'icons/skills/social/thumbsup-approval-like.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'), actions: [] } - }), - custom: { - id: 'customActivity', - name: '', - img: 'icons/skills/trades/academics-investigation-puzzles.webp', - description: '', - namePlaceholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.namePlaceholder', - placeholder: 'DAGGERHEART.APPLICATIONS.Downtime.custom.placeholder' - } + }) }; export const deathMoves = { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 1c15d036..c15d2221 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -126,6 +126,44 @@ export default class DhCharacter extends BaseDataActor { }), rally: new fields.ArrayField(new fields.StringField(), { label: 'DAGGERHEART.CLASS.Feature.rallyDice' + }), + rest: new fields.SchemaField({ + shortRest: new fields.SchemaField({ + shortMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.shortRestMoves.hint' + }), + longMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.shortRest.longRestMoves.hint' + }) + }), + longRest: new fields.SchemaField({ + shortMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.shortRestMoves.hint' + }), + longMoves: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0, + label: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.label', + hint: 'DAGGERHEART.GENERAL.Bonuses.rest.longRest.longRestMoves.hint' + }) + }) }) }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index ead5a09f..008cd73c 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -54,6 +54,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { moves: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField({ required: true }), + icon: new fields.StringField({ required: true }), img: new fields.FilePathField({ initial: 'icons/magic/life/cross-worn-green.webp', categories: ['IMAGE'], @@ -70,6 +71,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { moves: new fields.TypedObjectField( new fields.SchemaField({ name: new fields.StringField({ required: true }), + icon: new fields.StringField({ required: true }), img: new fields.FilePathField({ initial: 'icons/magic/life/cross-worn-green.webp', categories: ['IMAGE'], diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 3e7b49ea..89305128 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -16,7 +16,7 @@ export default class DHToken extends TokenDocument { }); bars.sort((a, b) => a.label.compare(b.label)); - const invalidAttributes = ['gold', 'levelData', 'rules.damageReduction.maxArmorMarked.value']; + const invalidAttributes = ['gold', 'levelData', 'actions', 'rules.damageReduction.maxArmorMarked.value']; const values = attributes.value.reduce((acc, v) => { const a = v.join('.'); if (invalidAttributes.some(x => a.startsWith(x))) return acc; @@ -32,19 +32,19 @@ export default class DHToken extends TokenDocument { return bars.concat(values); } - - static _getTrackedAttributesFromSchema(schema, _path=[]) { - const attributes = {bar: [], value: []}; - for ( const [name, field] of Object.entries(schema.fields) ) { + + static _getTrackedAttributesFromSchema(schema, _path = []) { + const attributes = { bar: [], value: [] }; + for (const [name, field] of Object.entries(schema.fields)) { const p = _path.concat([name]); - if ( field instanceof foundry.data.fields.NumberField ) attributes.value.push(p); - if ( field instanceof foundry.data.fields.ArrayField ) attributes.value.push(p); + if (field instanceof foundry.data.fields.NumberField) attributes.value.push(p); + if (field instanceof foundry.data.fields.ArrayField) attributes.value.push(p); const isSchema = field instanceof foundry.data.fields.SchemaField; const isModel = field instanceof foundry.data.fields.EmbeddedDataField; - if ( isSchema || isModel ) { + if (isSchema || isModel) { const schema = isModel ? field.model.schema : field; - const isBar = schema.has && schema.has("value") && schema.has("max"); - if ( isBar ) attributes.bar.push(p); + const isBar = schema.has && schema.has('value') && schema.has('max'); + if (isBar) attributes.bar.push(p); else { const inner = this.getTrackedAttributes(schema, p); attributes.bar.push(...inner.bar); diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index f24823f4..e622059d 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -22,6 +22,28 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti options.direction = this._determineItemTooltipDirection(element); } } else { + const shortRest = element.dataset.tooltip?.startsWith('#shortRest#'); + const longRest = element.dataset.tooltip?.startsWith('#longRest#'); + if (shortRest || longRest) { + const key = element.dataset.tooltip.slice(shortRest ? 11 : 10); + const downtimeOptions = shortRest + ? CONFIG.DH.GENERAL.defaultRestOptions.shortRest() + : CONFIG.DH.GENERAL.defaultRestOptions.longRest(); + const move = downtimeOptions[key]; + html = await foundry.applications.handlebars.renderTemplate( + `systems/daggerheart/templates/ui/tooltip/downtime.hbs`, + { + move: move + } + ); + + this.tooltip.innerHTML = html; + options.direction = this._determineItemTooltipDirection( + element, + this.constructor.TOOLTIP_DIRECTIONS.UP + ); + } + const isAdvantage = element.dataset.tooltip?.startsWith('#advantage#'); const isDisadvantage = element.dataset.tooltip?.startsWith('#disadvantage#'); if (isAdvantage || isDisadvantage) { @@ -44,9 +66,34 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti super.activate(element, { ...options, html: html }); } - _determineItemTooltipDirection(element) { + _determineItemTooltipDirection(element, prefered = this.constructor.TOOLTIP_DIRECTIONS.LEFT) { const pos = element.getBoundingClientRect(); const dirs = this.constructor.TOOLTIP_DIRECTIONS; - return dirs[pos.x - this.tooltip.offsetWidth < 0 ? 'DOWN' : 'LEFT']; + switch (prefered) { + case this.constructor.TOOLTIP_DIRECTIONS.LEFT: + return dirs[ + pos.x - this.tooltip.offsetWidth < 0 + ? this.constructor.TOOLTIP_DIRECTIONS.DOWN + : this.constructor.TOOLTIP_DIRECTIONS.LEFT + ]; + case this.constructor.TOOLTIP_DIRECTIONS.UP: + return dirs[ + pos.y - this.tooltip.offsetHeight < 0 + ? this.constructor.TOOLTIP_DIRECTIONS.RIGHT + : this.constructor.TOOLTIP_DIRECTIONS.UP + ]; + case this.constructor.TOOLTIP_DIRECTIONS.RIGHT: + return dirs[ + pos.x + this.tooltip.offsetWidth > document.body.clientWidth + ? this.constructor.TOOLTIP_DIRECTIONS.DOWN + : this.constructor.TOOLTIP_DIRECTIONS.RIGHT + ]; + case this.constructor.TOOLTIP_DIRECTIONS.DOWN: + return dirs[ + pos.y + this.tooltip.offsetHeight > document.body.clientHeight + ? this.constructor.TOOLTIP_DIRECTIONS.LEFT + : this.constructor.TOOLTIP_DIRECTIONS.DOWN + ]; + } } } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 8456094c..0c455750 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -25,6 +25,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', 'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs', 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs', - 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs' + 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', + 'systems/daggerheart/templates/dialogs/downtime/activities.hbs' ]); }; diff --git a/styles/less/dialog/downtime/downtime-container.less b/styles/less/dialog/downtime/downtime-container.less index 4e785e7b..0f803d9b 100644 --- a/styles/less/dialog/downtime/downtime-container.less +++ b/styles/less/dialog/downtime/downtime-container.less @@ -1,81 +1,75 @@ @import '../../utils/spacing.less'; @import '../../utils/colors.less'; -.daggerheart.views { +.theme-light .daggerheart.dh-style.views.downtime { + .downtime-container .activity-container .activity-selected-marker { + background-image: url(../assets/parchments/dh-parchment-light.png); + } +} + +.daggerheart.dh-style.views.downtime { + font-family: @font-body; + .downtime-container { - .downtime-header { - margin: 0; - color: light-dark(@dark-blue, @golden); - text-align: center; + .activities-grouping { + width: 280px; } - .activity-container { - display: flex; - align-items: center; - padding: 8px; + .activities-container { + width: 100%; - .activity-title { - flex: 1; + .activity-container { display: flex; align-items: center; + justify-content: space-between; + padding: 8px; - .activity-title-text { - font-size: 24px; - font-weight: bold; - } - - .activity-image { - width: 80px; - position: relative; + .activity-inner-container { display: flex; - justify-content: center; - margin-right: 8px; - border: 2px solid black; - border-radius: 50%; - cursor: pointer; + align-items: center; + gap: 4px; - .activity-select-label { - position: absolute; - top: -9px; - font-size: 14px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url(../assets/parchments/dh-parchment-light.png); - padding: 0 8px; - line-height: 1; - font-weight: bold; + .activity-marker { + font-size: 8px; + flex: none; + color: light-dark(#18162e, #f3c267); + margin-right: 4px; } - img { - border-radius: 50%; - } + .activity-select-section { + display: flex; + align-items: center; + gap: 4px; - &:hover, - &.selected { - filter: drop-shadow(0 0 6px gold); + .activity-icon { + min-width: 24px; + text-align: center; + } } } - .custom-name-input { - font-size: 24px; + .activity-selected-marker { + font-size: 14px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url(../assets/parchments/dh-parchment-dark.png); + padding: 0 8px; + line-height: 1; font-weight: bold; - padding: 0; - background: transparent; - color: rgb(239, 230, 216); } } - - .activity-body { - flex: 1; - font-style: italic; - } } } - &.downtime { - .activity-text-area { - resize: none; + footer { + margin-top: 8px; + display: flex; + gap: 8px; + + button { + flex: 1; + font-family: 'Montserrat', sans-serif; } } } diff --git a/styles/less/global/tab-navigation.less b/styles/less/global/tab-navigation.less index 2880711d..014da89f 100755 --- a/styles/less/global/tab-navigation.less +++ b/styles/less/global/tab-navigation.less @@ -7,12 +7,22 @@ height: 40px; width: 100%; - .feature-tab { - border: none; + .navigation-container { + display: flex; + align-items: center; + gap: 8px; - a { - color: light-dark(@dark-blue, @golden); - font-family: @font-body; + .navigation-inner-container { + flex: 1; + + .feature-tab { + border: none; + + a { + color: light-dark(@dark-blue, @golden); + font-family: @font-body; + } + } } } } diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 6110fcc6..b80da83d 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -193,5 +193,14 @@ } } } + + .character-downtime-container { + display: flex; + gap: 2px; + + button { + flex: 1; + } + } } } diff --git a/styles/less/ux/autocomplete/autocomplete.less b/styles/less/ux/autocomplete/autocomplete.less index 06cabf5a..868b4f43 100644 --- a/styles/less/ux/autocomplete/autocomplete.less +++ b/styles/less/ux/autocomplete/autocomplete.less @@ -10,7 +10,6 @@ border-color: light-dark(@dark, @beige); border-radius: 6px; background-image: url('../assets/parchments/dh-parchment-dark.png'); - z-index: 200; max-height: 400px !important; width: fit-content !important; overflow-y: auto; diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less index 38502d09..0060f74b 100644 --- a/styles/less/ux/tooltip/tooltip.less +++ b/styles/less/ux/tooltip/tooltip.less @@ -4,6 +4,20 @@ align-items: center; gap: 4px; + .tooltip-title-container { + width: 100%; + display: flex; + align-items: center; + gap: 16px; + + .tooltip-image { + height: 40px; + width: 40px; + border-radius: 6px; + border: 1px solid @golden; + } + } + .tooltip-title { margin: 0; text-align: center; diff --git a/templates/dialogs/downtime.hbs b/templates/dialogs/downtime.hbs deleted file mode 100644 index fd5fa405..00000000 --- a/templates/dialogs/downtime.hbs +++ /dev/null @@ -1,24 +0,0 @@ -
    -
    -

    {{localize "DAGGERHEART.APPLICATIONS.Downtime.downtimeHeader" current=nrCurrentChoices max=moveData.nrChoices}}

    - {{#each moveData.moves as |move key|}} -
    -
    -
    - {{#if this.selected}}
    {{move.selected}}
    {{/if}} - -
    - - {{localize this.name}} -
    -
    - {{localize this.description}} -
    -
    - {{/each}} -
    -
    - - -
    -
    \ No newline at end of file diff --git a/templates/dialogs/downtime/activities.hbs b/templates/dialogs/downtime/activities.hbs new file mode 100644 index 00000000..f67e8a10 --- /dev/null +++ b/templates/dialogs/downtime/activities.hbs @@ -0,0 +1,18 @@ +
    + {{localize (concat "DAGGERHEART.APPLICATIONS.Downtime." category ".moves") max=nrChoices.max current=nrChoices.current}} + + +
    \ No newline at end of file diff --git a/templates/dialogs/downtime/downtime.hbs b/templates/dialogs/downtime/downtime.hbs new file mode 100644 index 00000000..c8e44e5d --- /dev/null +++ b/templates/dialogs/downtime/downtime.hbs @@ -0,0 +1,14 @@ +
    +
    +

    {{title}}

    +
    + +
    + {{#if shortRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=shortRestMoves.moves category='shortRest' nrChoices=nrChoices.shortRest}}{{/if}} + {{#if longRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=longRestMoves.moves category='longRest' nrChoices=nrChoices.longRest}}{{/if}} +
    +
    + + +
    +
    \ No newline at end of file diff --git a/templates/settings/automation-settings.hbs b/templates/settings/automation-settings.hbs index 0e158ab6..910ace56 100644 --- a/templates/settings/automation-settings.hbs +++ b/templates/settings/automation-settings.hbs @@ -6,7 +6,7 @@
    {{formGroup settingFields.schema.fields.actionPoints value=settingFields._source.actionPoints localize=true}} -s {{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}} + {{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
    - {{> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}} + {{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}} +
    + + +
    + {{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}} \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-navigation.hbs b/templates/sheets/global/tabs/tab-navigation.hbs index 976aac89..10d76619 100755 --- a/templates/sheets/global/tabs/tab-navigation.hbs +++ b/templates/sheets/global/tabs/tab-navigation.hbs @@ -1,11 +1,18 @@
    - - - +
    \ No newline at end of file diff --git a/templates/ui/tooltip/downtime.hbs b/templates/ui/tooltip/downtime.hbs new file mode 100644 index 00000000..7b7f5c16 --- /dev/null +++ b/templates/ui/tooltip/downtime.hbs @@ -0,0 +1,7 @@ +
    +
    + +

    {{move.name}}

    +
    +
    {{{move.description}}}
    +
    \ No newline at end of file From 1d75b080875586e26cb7ba5cadceeaaba51bbd68 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 18 Jul 2025 00:49:44 +0200 Subject: [PATCH 46/58] Fixed so active effects can handle expressions again (#368) --- lang/en.json | 10 +++------- module/config/itemConfig.mjs | 11 +---------- module/documents/activeEffect.mjs | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lang/en.json b/lang/en.json index 39e49b67..4e9a9b11 100755 --- a/lang/en.json +++ b/lang/en.json @@ -777,7 +777,7 @@ "WeaponFeature": { "barrier": { "name": "Barrier", - "description": "+{armorScore} to Armor Score; -1 to Evasion" + "description": "Gain your character's Tier + 1 to Armor Score; -1 to Evasion" }, "bonded": { "name": "Bonded", @@ -893,7 +893,7 @@ }, "paired": { "name": "Paired", - "description": "+{bonusDamage} to primary weapon damage to targets within Melee range" + "description": "Add your character's Tier + 1 to primary weapon damage against targets within Melee range" }, "parry": { "name": "Parry", @@ -913,7 +913,7 @@ }, "protective": { "name": "Protective", - "description": "+{tier} to Armor Score" + "description": "Add your character's Tier to your Armor Score" }, "quick": { "name": "Quick", @@ -962,10 +962,6 @@ "timebending": { "name": "Timebending", "description": "You can choose the target of your attack after making your attack roll." - }, - "versatile": { - "name": "Versatile", - "description": "This weapon can also be used with these statistics—{characterTrait}, {range}, {damage}." } } }, diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index b26a26ca..6b28a1ae 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -439,7 +439,7 @@ export const weaponFeatures = { { key: 'system.bonuses.damage.primaryWeapon.bonus', mode: 2, - value: '@system.levelData.levels.current' + value: '@system.levelData.level.current' } ] } @@ -1261,15 +1261,6 @@ export const weaponFeatures = { timebending: { label: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.description' - }, - versatile: { - label: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.description' - // versatile: { - // characterTrait: '', - // range: '', - // damage: '' - // } } }; diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index aa1a5b0d..6c4545b1 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -55,10 +55,24 @@ export default class DhActiveEffect extends ActiveEffect { } static applyField(model, change, field) { - change.value = itemAbleRollParse(change.value, model, change.effect.parent); + change.value = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent)); super.applyField(model, change, field); } + /* Altered Foundry safeEval to allow non-numeric returns */ + static effectSafeEval(expression) { + let result; + try { + // eslint-disable-next-line no-new-func + const evl = new Function('sandbox', `with (sandbox) { return ${expression}}`); + result = evl(Roll.MATH_PROXY); + } catch (err) { + return expression; + } + + return result; + } + async toChat(origin) { const cls = getDocumentClass('ChatMessage'); const systemData = { From 26376b49db75fe5af416b84951f4be21435ff462 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sat, 19 Jul 2025 12:45:51 +0100 Subject: [PATCH 47/58] Fix link to Developer Setup section in README (#375) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 760194f4..a5c7fe48 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ - [Overview](#overview) - [User Install Guide](#user-install) -- [Developer Setup](#developer-setup) +- [Developer Setup](#development-setup) - [Contribution Info](#contributing) ## Overview From 7cbbb3168e7cb7a48a63855423570e7fbeafda5f Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Sat, 19 Jul 2025 15:48:50 +0200 Subject: [PATCH 48/58] Feature/336 damage targeted resources (#376) * Unify healing & damage * create DHResourceData * Damages parts roll * h * ChatMessage & takeDamage updates * Adapt healing * No, there was not a console.log ! --- lang/en.json | 8 ++ module/applications/dialogs/damageDialog.mjs | 6 +- .../dialogs/damageReductionDialog.mjs | 6 +- module/applications/ui/chatLog.mjs | 30 ++++-- module/config/generalConfig.mjs | 5 + module/data/action/actionDice.mjs | 37 +++++-- module/data/action/baseAction.mjs | 24 ++--- module/data/action/damageAction.mjs | 39 ++++--- module/data/action/healingAction.mjs | 22 ++-- module/data/actor/character.mjs | 5 +- module/dice/d20Roll.mjs | 19 ++-- module/dice/damageRoll.mjs | 101 +++++++++++++++--- module/dice/dhRoll.mjs | 28 ++--- module/dice/dualityRoll.mjs | 14 +-- module/documents/actor.mjs | 78 ++++++++------ module/documents/token.mjs | 2 +- module/helpers/utils.mjs | 12 +++ styles/less/global/dialog.less | 11 ++ styles/less/global/elements.less | 2 +- styles/less/ui/chat/chat.less | 5 + templates/actionTypes/damage.hbs | 14 ++- templates/actionTypes/healing.hbs | 64 ++++++----- .../dialogs/dice-roll/damageSelection.hbs | 24 ++++- templates/ui/chat/healing-roll.hbs | 42 ++++---- templates/ui/chat/parts/damage-chat.hbs | 49 +++++---- 25 files changed, 415 insertions(+), 232 deletions(-) diff --git a/lang/en.json b/lang/en.json index 4e9a9b11..9f929c77 100755 --- a/lang/en.json +++ b/lang/en.json @@ -35,6 +35,9 @@ "Settings": { "resultBased": { "label": "Formula based on Hope/Fear result." + }, + "applyTo": { + "label": "Targeted Resource" } }, "TYPES": { @@ -662,6 +665,10 @@ "armorStack": { "name": "Armor Stack", "abbreviation": "AS" + }, + "fear": { + "name": "Fear", + "abbreviation": "FR" } }, "ItemResourceType": { @@ -1252,6 +1259,7 @@ }, "fear": "Fear", "features": "Features", + "healing": "Healing", "hitPoints": { "single": "Hit Point", "plural": "Hit Points", diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 70dcace8..1b61b96d 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -43,10 +43,11 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application async _prepareContext(_options) { const context = await super._prepareContext(_options); + context.config = CONFIG.DH; context.title = this.config.title ? this.config.title : game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); - context.extraFormula = this.config.extraFormula; + // context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); context.directDamage = this.config.directDamage; context.selectedRollMode = this.config.selectedRollMode; @@ -55,13 +56,12 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application label, icon })); - return context; } static updateRollConfiguration(_event, _, formData) { const { ...rest } = foundry.utils.expandObject(formData.object); - this.config.extraFormula = rest.extraFormula; + foundry.utils.mergeObject(this.config.roll, rest.roll) this.config.selectedRollMode = rest.selectedRollMode; this.render(); diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 984106d7..658cef96 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -10,12 +10,12 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.reject = reject; this.actor = actor; this.damage = damage; - + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); const maxArmorMarks = canApplyArmor ? Math.min( actor.system.armorScore - actor.system.armor.system.marks.value, - actor.system.rules.damageReduction.maxArmorMarked.total + actor.system.rules.damageReduction.maxArmorMarked.value ) : 0; @@ -100,7 +100,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap context.armorScore = this.actor.system.armorScore; context.armorMarks = currentMarks; context.basicMarksUsed = - selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total; + selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.value; const stressReductionStress = this.availableStressReductions ? stressReductions.reduce((acc, red) => acc + red.cost, 0) diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 4570b076..29a0f46e 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -187,7 +187,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.attackTargetDoesNotExist')); return; } - game.canvas.pan(token); }; @@ -207,15 +206,24 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (!confirm) return; } } - + if (targets.length === 0) - ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - for (let target of targets) { - let damage = message.system.roll.total; - if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) - damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); + return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - target.actor.takeDamage(damage, message.system.damage.damageType); + for (let target of targets) { + let damages = message.system.damage; + if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) { + const mod = CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1; + Object.entries(damages).forEach((k,v) => { + let newTotal = 0; + v.forEach(part => { + v.total = Math.ceil(v.total * mod); + newTotal += v.total; + }) + }) + } + + target.actor.takeDamage(damages.roll); } }; @@ -224,10 +232,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo const targets = Array.from(game.user.targets); if (targets.length === 0) - ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - + return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); + for (var target of targets) { - target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]); + target.actor.takeHealing(message.system.roll); } }; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 632e5448..efe8a016 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -89,6 +89,11 @@ export const healingTypes = { id: 'armorStack', label: 'DAGGERHEART.CONFIG.HealingType.armorStack.name', abbreviation: 'DAGGERHEART.CONFIG.HealingType.armorStack.abbreviation' + }, + fear: { + id: 'fear', + label: 'DAGGERHEART.CONFIG.HealingType.fear.name', + abbreviation: 'DAGGERHEART.CONFIG.HealingType.fear.abbreviation' } }; diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index d71b390a..c3c28247 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -93,10 +93,32 @@ export class DHDamageField extends fields.SchemaField { } } -export class DHDamageData extends foundry.abstract.DataModel { +export class DHResourceData extends foundry.abstract.DataModel { /** @override */ static defineSchema() { return { + applyTo: new fields.StringField({ + choices: CONFIG.DH.GENERAL.healingTypes, + required: true, + blank: false, + initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, + label: 'DAGGERHEART.ACTIONS.Settings.applyTo.label' + }), + resultBased: new fields.BooleanField({ + initial: false, + label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' + }), + value: new fields.EmbeddedDataField(DHActionDiceData), + valueAlt: new fields.EmbeddedDataField(DHActionDiceData) + } + } +} + +export class DHDamageData extends DHResourceData { + /** @override */ + static defineSchema() { + return { + ...super.defineSchema(), base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }), type: new fields.SetField( new fields.StringField({ @@ -106,16 +128,9 @@ export class DHDamageData extends foundry.abstract.DataModel { required: true }), { - label: 'Type', - initial: 'physical' + label: 'Type' } - ), - resultBased: new fields.BooleanField({ - initial: false, - label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' - }), - value: new fields.EmbeddedDataField(DHActionDiceData), - valueAlt: new fields.EmbeddedDataField(DHActionDiceData) - }; + ) + } } } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index a46b0a85..f0176d78 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -1,4 +1,4 @@ -import { DHActionDiceData, DHActionRollData, DHDamageField } from './actionDice.mjs'; +import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField, DHResourceData } from './actionDice.mjs'; import DhpActor from '../../documents/actor.mjs'; import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs'; @@ -96,21 +96,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { onSave: new fields.BooleanField({ initial: false }) }) ), - healing: new fields.SchemaField({ - type: new fields.StringField({ - choices: CONFIG.DH.GENERAL.healingTypes, - required: true, - blank: false, - initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, - label: 'Healing' - }), - resultBased: new fields.BooleanField({ - initial: false, - label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' - }), - value: new fields.EmbeddedDataField(DHActionDiceData), - valueAlt: new fields.EmbeddedDataField(DHActionDiceData) - }), + healing: new fields.EmbeddedDataField(DHResourceData), beastform: new fields.SchemaField({ tierAccess: new fields.SchemaField({ exact: new fields.NumberField({ integer: true, nullable: true, initial: null }) @@ -156,7 +142,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { static getSourceConfig(parent) { const updateSource = {}; updateSource.img ??= parent?.img ?? parent?.system?.img; - if (parent?.type === 'weapon') { + if (parent?.type === 'weapon' && this === game.system.api.models.actions.actionsTypes.attack) { updateSource['damage'] = { includeBase: true }; updateSource['range'] = parent?.system?.attack?.range; updateSource['roll'] = { @@ -177,6 +163,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } getRollData(data = {}) { + if(!this.actor) return null; const actorData = this.actor.getRollData(false); // Add Roll results to RollDatas @@ -191,6 +178,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } async use(event, ...args) { + if(!this.actor) throw new Error("An Action can't be used outside of an Actor context."); + const isFastForward = event.shiftKey || (!this.hasRoll && !this.hasSave); // Prepare base Config const initConfig = this.initActionConfig(event); @@ -227,7 +216,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel { if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; // Display configuration window if necessary - // if (config.dialog?.configure && this.requireConfigurationDialog(config)) { if (this.requireConfigurationDialog(config)) { config = await D20RollDialog.configure(null, config); if (!config) return; diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index ccd996f7..13461d30 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -1,3 +1,4 @@ +import { setsEqual } from '../../helpers/utils.mjs'; import DHBaseAction from './baseAction.mjs'; export default class DHDamageAction extends DHBaseAction { @@ -18,28 +19,40 @@ export default class DHDamageAction extends DHBaseAction { return formulaValue; } + formatFormulas(formulas, systemData) { + const formattedFormulas = []; + formulas.forEach(formula => { + if (isNaN(formula.formula)) formula.formula = Roll.replaceFormulaData(formula.formula, this.getRollData(systemData)); + const same = formattedFormulas.find(f => setsEqual(f.damageTypes, formula.damageTypes) && f.applyTo === formula.applyTo); + if(same) + same.formula += ` + ${formula.formula}`; + else + formattedFormulas.push(formula); + }) + return formattedFormulas; + } + async rollDamage(event, data) { const systemData = data.system ?? data; - let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '), - damageTypes = [...new Set(this.damage.parts.reduce((a, c) => a.concat([...c.type]), []))]; + + let formulas = this.damage.parts.map(p => ({ + formula: this.getFormulaValue(p, data).getFormula(this.actor), + damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type, + applyTo: p.applyTo + })); - damageTypes = !damageTypes.length ? ['physical'] : damageTypes; + if(!formulas.length) return; - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - - if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData)); + formulas = this.formatFormulas(formulas, systemData); const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }), - roll: { formula }, + roll: formulas, targets: systemData.targets.filter(t => t.hit) ?? data.targets, hasSave: this.hasSave, isCritical: systemData.roll?.isCritical ?? false, source: systemData.source, data: this.getRollData(), - damageTypes, event }; if (this.hasSave) config.onSave = this.save.damageMod; @@ -50,10 +63,6 @@ export default class DHDamageAction extends DHBaseAction { config.directDamage = true; } - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + return CONFIG.Dice.daggerheart.DamageRoll.build(config); } - - // get modifiers() { - // return []; - // } } diff --git a/module/data/action/healingAction.mjs b/module/data/action/healingAction.mjs index 4c1366a1..e0a74f27 100644 --- a/module/data/action/healingAction.mjs +++ b/module/data/action/healingAction.mjs @@ -15,25 +15,25 @@ export default class DHHealingAction extends DHBaseAction { } async rollHealing(event, data) { - let formulaValue = this.getFormulaValue(data), - formula = formulaValue.getFormula(this.actor); - - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - + const systemData = data.system ?? data; + let formulas = [{ + formula: this.getFormulaValue(data).getFormula(this.actor), + applyTo: this.healing.applyTo + }]; + const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.healingRoll.title', { - healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.type].label) + healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.applyTo].label) }), - roll: { formula }, + roll: formulas, targets: (data.system?.targets ?? data.targets).filter(t => t.hit), messageType: 'healing', - type: this.healing.type, + source: systemData.source, + data: this.getRollData(), event }; - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + return CONFIG.Dice.daggerheart.DamageRoll.build(config); } get chatTemplate() { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index c15d2221..292eedb7 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -170,11 +170,10 @@ export default class DhCharacter extends BaseDataActor { rules: new fields.SchemaField({ damageReduction: new fields.SchemaField({ maxArmorMarked: new fields.SchemaField({ - value: new fields.NumberField({ required: true, integer: true, initial: 1 }), - bonus: new fields.NumberField({ + value: new fields.NumberField({ required: true, integer: true, - initial: 0, + initial: 1, label: 'DAGGERHEART.GENERAL.Rules.damageReduction.maxArmorMarkedBonus' }), stressExtra: new fields.NumberField({ diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 58d45f95..09dd716e 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -140,28 +140,22 @@ export default class D20Roll extends DHRoll { return modifiers; } - static async buildEvaluate(roll, config = {}, message = {}) { - if (config.evaluate !== false) await roll.evaluate(); - - this.postEvaluate(roll, config); - } - static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); + const data = super.postEvaluate(roll, config); if (config.targets?.length) { config.targets.forEach(target => { const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; target.hit = this.isCritical || roll.total >= difficulty; }); } else if (config.roll.difficulty) - config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty; - config.roll.advantage = { + data.success = roll.isCritical || roll.total >= config.roll.difficulty; + data.advantage = { type: config.roll.advantage, dice: roll.dAdvantage?.denomination, value: roll.dAdvantage?.total }; - config.roll.isCritical = roll.isCritical; - config.roll.extra = roll.dice + data.isCritical = roll.isCritical; + data.extra = roll.dice .filter(d => !roll.baseTerms.includes(d)) .map(d => { return { @@ -169,7 +163,8 @@ export default class D20Roll extends DHRoll { value: d.total }; }); - config.roll.modifierTotal = this.calculateTotalModifiers(roll); + data.modifierTotal = this.calculateTotalModifiers(roll); + return data; } resetFormula() { diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index bfbfc7d5..aa1c4c86 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -10,10 +10,24 @@ export default class DamageRoll extends DHRoll { static DefaultDialog = DamageDialog; - static async postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); - config.roll.type = config.type; - config.roll.modifierTotal = this.calculateTotalModifiers(roll); + static async buildEvaluate(roll, config = {}, message = {}) { + if ( config.evaluate !== false ) { + for ( const roll of config.roll ) await roll.roll.evaluate(); + } + roll._evaluated = true; + const parts = config.roll.map(r => this.postEvaluate(r)); + config.roll = this.unifyDamageRoll(parts); + } + + static postEvaluate(roll, config = {}) { + return { + ...roll, + ...super.postEvaluate(roll.roll, config), + damageTypes: [...(roll.damageTypes ?? [])], + roll: roll.roll, + type: config.type, + modifierTotal: this.calculateTotalModifiers(roll.roll) + } } static async buildPost(roll, config, message) { @@ -24,12 +38,50 @@ export default class DamageRoll extends DHRoll { } } - applyBaseBonus() { + static unifyDamageRoll(rolls) { + const unified = {}; + rolls.forEach(r => { + const resource = unified[r.applyTo] ?? { formula: '', total: 0, parts: [] }; + resource.formula += `${resource.formula !== '' ? ' + ' : ''}${r.formula}`; + resource.total += r.total; + resource.parts.push(r); + unified[r.applyTo] = resource; + }) + return unified; + } + + static formatGlobal(rolls) { + let formula, total; + const applyTo = new Set(rolls.flatMap(r => r.applyTo)); + if(applyTo.size > 1) { + const data = {}; + rolls.forEach(r => { + if(data[r.applyTo]) { + data[r.applyTo].formula += ` + ${r.formula}` ; + data[r.applyTo].total += r.total ; + } else { + data[r.applyTo] = { + formula: r.formula, + total: r.total + } + } + }); + formula = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.formula}`, ''); + total = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.total}`, ''); + } else { + formula = rolls.map(r => r.formula).join(' + '); + total = rolls.reduce((a,c) => a + c.total, 0) + } + return {formula, total} + } + + applyBaseBonus(part) { const modifiers = [], - type = this.options.messageType ?? 'damage'; + type = this.options.messageType ?? 'damage', + options = part ?? this.options; modifiers.push(...this.getBonus(`${type}`, `${type.capitalize()} Bonus`)); - this.options.damageTypes?.forEach(t => { + options.damageTypes?.forEach(t => { modifiers.push(...this.getBonus(`${type}.${t}`, `${t.capitalize()} ${type.capitalize()} Bonus`)); }); const weapons = ['primaryWeapon', 'secondaryWeapon']; @@ -42,13 +94,36 @@ export default class DamageRoll extends DHRoll { } constructFormula(config) { - super.constructFormula(config); + this.options.roll.forEach( part => { + part.roll = new Roll(part.formula); + this.constructFormulaPart(config, part) + }) + return this.options.roll; + } - if (config.isCritical) { - const tmpRoll = new Roll(this._formula)._evaluateSync({ maximize: true }), - criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); - this.terms.push(...this.formatModifier(criticalBonus)); + constructFormulaPart(config, part) { + part.roll.terms = Roll.parse(part.roll.formula, config.data); + + if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { + part.modifiers = this.applyBaseBonus(part); + this.addModifiers(part); + part.modifiers?.forEach(m => { + part.roll.terms.push(...this.formatModifier(m.value)); + }); } - return (this._formula = this.constructor.getFormula(this.terms)); + + if (part.extraFormula) { + part.roll.terms.push( + new foundry.dice.terms.OperatorTerm({ operator: '+' }), + ...this.constructor.parse(part.extraFormula, this.options.data) + ); + } + + if (config.isCritical && part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { + const tmpRoll = Roll.fromTerms(part.roll.terms)._evaluateSync({ maximize: true }), + criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); + part.roll.terms.push(...this.formatModifier(criticalBonus)); + } + return (part.roll._formula = this.constructor.getFormula(part.roll.terms)); } } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 33de251b..cb1007e3 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -47,7 +47,7 @@ export default class DHRoll extends Roll { static async buildEvaluate(roll, config = {}, message = {}) { if (config.evaluate !== false) await roll.evaluate(); - this.postEvaluate(roll, config); + config.roll = this.postEvaluate(roll, config); } static async buildPost(roll, config, message) { @@ -57,25 +57,26 @@ export default class DHRoll extends Roll { // Create Chat Message if (config.source?.message) { + if(Object.values(config.roll)?.length) { + const pool = foundry.dice.terms.PoolTerm.fromRolls(Object.values(config.roll).flatMap(r => r.parts.map(p => p.roll))); + roll = Roll.fromTerms([pool]); + } if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); - } else { + } else config.message = await this.toMessage(roll, config); - } } static postEvaluate(roll, config = {}) { - if (!config.roll) config.roll = {}; - config.roll.total = roll.total; - config.roll.formula = roll.formula; - config.roll.dice = []; - roll.dice.forEach(d => { - config.roll.dice.push({ + return { + total: roll.total, + formula: roll.formula, + dice: roll.dice.map(d => ({ dice: d.denomination, total: d.total, formula: d.formula, results: d.results - }); - }); + })) + } } static async toMessage(roll, config) { @@ -118,8 +119,9 @@ export default class DHRoll extends Roll { return []; } - addModifiers() { - this.options.roll.modifiers?.forEach(m => { + addModifiers(roll) { + roll = roll ?? this.options.roll; + roll.modifiers?.forEach(m => { this.terms.push(...this.formatModifier(m.value)); }); } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 5fd71e6c..e36d2427 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -161,21 +161,21 @@ export default class DualityRoll extends D20Roll { } static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); + const data = super.postEvaluate(roll, config); - config.roll.hope = { + data.hope = { dice: roll.dHope.denomination, value: roll.dHope.total }; - config.roll.fear = { + data.fear = { dice: roll.dFear.denomination, value: roll.dFear.total }; - config.roll.rally = { + data.rally = { dice: roll.dRally?.denomination, value: roll.dRally?.total }; - config.roll.result = { + data.result = { duality: roll.withHope ? 1 : roll.withFear ? -1 : 0, total: roll.dHope.total + roll.dFear.total, label: roll.totalLabel @@ -184,6 +184,8 @@ export default class DualityRoll extends D20Roll { if(roll._rallyIndex && roll.data?.parent) roll.data.parent.deleteEmbeddedDocuments('ActiveEffect', [roll._rallyIndex]); - setDiceSoNiceForDualityRoll(roll, config.roll.advantage.type); + setDiceSoNiceForDualityRoll(roll, data.advantage.type); + + return data; } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 73a8a3db..e6ae781a 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -391,59 +391,70 @@ export default class DhpActor extends Actor { return canUseArmor || canUseStress; } - async takeDamage(baseDamage, type) { - if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, baseDamage, type) === false) return null; + async takeDamage(damages) { + if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damages) === false) return null; if (this.type === 'companion') { await this.modifyResource([{ value: 1, key: 'stress' }]); return; } - type = !Array.isArray(type) ? [type] : type; + const updates = []; - const hpDamage = this.calculateDamage(baseDamage, type); + Object.entries(damages).forEach(([key, damage]) => { + damage.parts.forEach(part => { + if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) + part.total = this.calculateDamage(part.total, part.damageTypes); + const update = updates.find(u => u.key === key); + if(update) { + update.value += part.total; + update.damageTypes.add(...new Set(part.damageTypes)); + } else updates.push({ value: part.total, key, damageTypes: new Set(part.damageTypes) }) + }) + }); - if (!hpDamage) return; + if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, damages) === false) return null; - const updates = [{ value: hpDamage, type: 'hitPoints' }]; + if(!updates.length) return; - if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage, type)) { - const armorStackResult = await this.owner.query('armorStack', { - actorId: this.uuid, - damage: hpDamage, - type: type - }); - if (armorStackResult) { - const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; - updates.find(u => u.type === 'hitPoints').value = modifiedDamage; - updates.push( - ...(armorSpent ? [{ value: armorSpent, key: 'armorStack' }] : []), - ...(stressSpent ? [{ value: stressSpent, key: 'stress' }] : []) - ); + const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); + if(hpDamage) { + hpDamage.value = this.convertDamageToThreshold(hpDamage.value); + if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { + const armorStackResult = await this.owner.query('armorStack', { + actorId: this.uuid, + damage: hpDamage.value, + type: [...hpDamage.damageTypes] + }); + if (armorStackResult) { + const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; + updates.find(u => u.key === 'hitPoints').value = modifiedDamage; + updates.push( + ...(armorSpent ? [{ value: armorSpent, key: 'armorStack' }] : []), + ...(stressSpent ? [{ value: stressSpent, key: 'stress' }] : []) + ); + } } } - + + updates.forEach( u => + u.value = u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value + ); + await this.modifyResource(updates); - if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null; + if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damages) === false) return null; } calculateDamage(baseDamage, type) { - if (Hooks.call(`${CONFIG.DH.id}.preCalculateDamage`, this, baseDamage, type) === false) return null; - /* if(this.system.resistance[type]?.immunity) return 0; - if(this.system.resistance[type]?.resistance) baseDamage = Math.ceil(baseDamage / 2); */ if (this.canResist(type, 'immunity')) return 0; if (this.canResist(type, 'resistance')) baseDamage = Math.ceil(baseDamage / 2); - // const flatReduction = this.system.resistance[type].reduction; const flatReduction = this.getDamageTypeReduction(type); const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); - const hpDamage = this.convertDamageToThreshold(damage); - if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, baseDamage, type) === false) return null; - - return hpDamage; + return damage; } canResist(type, resistance) { @@ -461,8 +472,13 @@ export default class DhpActor extends Actor { } async takeHealing(resources) { - resources.forEach(r => (r.value *= -1)); - await this.modifyResource(resources); + const updates = Object.entries(resources).map(([key, value]) => ( + { + key: key, + value: !(key === 'fear' || this.system?.resources?.[key]?.isReversed === false) ? value.total * -1 : value.total + } + )) + await this.modifyResource(updates); } async modifyResource(resources) { diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 89305128..f48af563 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -16,7 +16,7 @@ export default class DHToken extends TokenDocument { }); bars.sort((a, b) => a.label.compare(b.label)); - const invalidAttributes = ['gold', 'levelData', 'actions', 'rules.damageReduction.maxArmorMarked.value']; + const invalidAttributes = ['gold', 'levelData', 'actions']; const values = attributes.value.reduce((acc, v) => { const a = v.join('.'); if (invalidAttributes.some(x => a.startsWith(x))) return acc; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 336ecf5b..91671e36 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -311,3 +311,15 @@ export const itemAbleRollParse = (value, actor, item) => { return ''; } }; + +export const arraysEqual = (a, b) => + a.length === b.length && + [...new Set([...a, ...b])].every( + v => a.filter(e => e === v).length === b.filter(e => e === v).length + ); + +export const setsEqual = (a, b) => + a.size === b.size && + [...a].every( + value => b.has(value) + ); \ No newline at end of file diff --git a/styles/less/global/dialog.less b/styles/less/global/dialog.less index 11a4eee9..8c86e825 100644 --- a/styles/less/global/dialog.less +++ b/styles/less/global/dialog.less @@ -56,4 +56,15 @@ color: light-dark(@dark, @beige); } + + .damage-formula { + display: flex; + justify-content: space-between; + .damage-details { + font-style: italic; + display: flex; + align-items: center; + gap: 5px; + } + } } diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 9d38e386..b9509b38 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -109,7 +109,7 @@ height: 34px; .tags { justify-content: flex-start; - margin: 5px; + margin: 4px; height: inherit; .tag { padding: 0.3rem 0.5rem; diff --git a/styles/less/ui/chat/chat.less b/styles/less/ui/chat/chat.less index 12e8ba0c..6b5db1b9 100644 --- a/styles/less/ui/chat/chat.less +++ b/styles/less/ui/chat/chat.less @@ -164,6 +164,11 @@ } } } + + .damage-resource { + font-weight: 600; + margin-top: 5px; + } } .dice-total { diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 3c125bd7..bfbbc592 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -22,7 +22,12 @@ {{formField ../fields.value.fields.bonus value=dmg.value.bonus name=(concat ../path "damage.parts." index ".value.bonus") localize=true classes="inline-child"}}
    {{/if}} - {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} +
    + {{formField ../fields.applyTo value=dmg.applyTo name=(concat ../path "damage.parts." realIndex ".applyTo") localize=true}} + {{#if (eq dmg.applyTo 'hitPoints')}} + {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} + {{/if}} +
    {{#if ../horde}}
    {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} @@ -56,7 +61,12 @@ {{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
    {{/if}} - {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} +
    + {{formField ../../fields.applyTo value=dmg.applyTo name=(concat "damage.parts." realIndex ".applyTo") localize=true}} + {{#if (eq dmg.applyTo 'hitPoints')}} + {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} + {{/if}} +
    {{#unless dmg.base}}
    {{/unless}} diff --git a/templates/actionTypes/healing.hbs b/templates/actionTypes/healing.hbs index 5bf46f7a..4b095174 100644 --- a/templates/actionTypes/healing.hbs +++ b/templates/actionTypes/healing.hbs @@ -1,43 +1,41 @@ -
    - -
    Healing
    +
    + + {{localize "DAGGERHEART.GENERAL.healing"}} -
    -
    - {{formField fields.type value=source.type name="healing.type" localize=true}} - {{#if (and (not @root.isNPC) @root.hasRoll)}} - {{formField fields.resultBased value=source.resultBased name="healing.resultBased" localize=true}} - {{/if}} - {{#if (and (not @root.isNPC) @root.hasRoll source.resultBased)}} -
    - -
    With Hope
    -
    - {{> formula fields=fields.value.fields source=source.value target="value"}} -
    -
    - -
    With Fear
    -
    - {{> formula fields=fields.valueAlt.fields source=source.valueAlt target="valueAlt"}} -
    - {{else}} + {{#if (and (not @root.isNPC) @root.hasRoll)}} + {{formField fields.resultBased value=source.resultBased name="healing.resultBased" localize=true classes="checkbox"}} + {{/if}} + {{#if (and (not @root.isNPC) @root.hasRoll source.resultBased)}} +
    +
    + +
    With Hope
    +
    {{> formula fields=fields.value.fields source=source.value target="value"}} - {{/if}} -
    -
    +
    +
    + +
    With Fear
    +
    + {{> formula fields=fields.valueAlt.fields source=source.valueAlt target="valueAlt"}} +
    +
    + {{else}} + {{> formula fields=fields.value.fields source=source.value target="value"}} + {{/if}} + {{formField fields.applyTo value=source.type name="healing.applyTo" localize=true}}
    {{#*inline "formula"}} -
    - {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat "healing." target ".custom.enabled")}} - {{#if source.custom.enabled}} - {{formField fields.custom.fields.formula value=source.custom.formula name=(concat "healing." target ".custom.formula") localize=true}} - {{else}} + {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat "healing." target ".custom.enabled") classes="checkbox"}} + {{#if source.custom.enabled}} + {{formField fields.custom.fields.formula value=source.custom.formula name=(concat "healing." target ".custom.formula") localize=true}} + {{else}} +
    {{formField fields.multiplier value=source.multiplier name=(concat "healing." target ".multiplier") localize=true}} {{formField fields.dice value=source.dice name=(concat "healing." target ".dice")}} {{formField fields.bonus value=source.bonus name=(concat "healing." target ".bonus") localize=true}} - {{/if}} -
    +
    + {{/if}} {{/inline}} \ No newline at end of file diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index bd97cfdf..3e47cf68 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -2,10 +2,26 @@

    {{title}}

    - Formula: {{@root.formula}} -
    - -
    + {{#each @root.formula}} +
    + Formula: {{roll.formula}} + + {{#with (lookup @root.config.GENERAL.healingTypes applyTo)}} + {{localize label}} + {{/with}} + {{#if damageTypes}} + {{#each damageTypes as | type | }} + {{#with (lookup @root.config.GENERAL.damageTypes type)}} + + {{/with}} + {{/each}} + {{/if}} + +
    +
    + +
    + {{/each}}
    {{#if directDamage}} - - - + {{#each document.system.potentialAdversaries as |category categoryId|}} +
    + {{category.label}} +
    + + + + +
    +
    + {{#each category.adversaries as |adversary|}} +
    + {{> 'daggerheart.inventory-item' + item=adversary + type='adversary' + isActor=true + categoryAdversary=categoryId + }}
    -
    - {{#each category.adversaries as |adversary|}} -
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=adversary type='adversary' isActor=true categoryAdversary=@../key}} -
    - {{/each}} -
    -
    - Drop Actors here -
    -
    + {{/each}} +
    +
    + Drop Actors here +
    +
    {{/each}} \ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/features.hbs b/templates/sheets-settings/environment-settings/features.hbs index f232dae9..aab68309 100644 --- a/templates/sheets-settings/environment-settings/features.hbs +++ b/templates/sheets-settings/environment-settings/features.hbs @@ -16,8 +16,8 @@ {{feature.name}}
  • - - + +
    {{/each}} diff --git a/templates/sheets/actors/adversary/effects.hbs b/templates/sheets/actors/adversary/effects.hbs index 3d378802..325610e6 100644 --- a/templates/sheets/actors/adversary/effects.hbs +++ b/templates/sheets/actors/adversary/effects.hbs @@ -1,8 +1,20 @@ -
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
    + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/adversary/features.hbs b/templates/sheets/actors/adversary/features.hbs index 1a8d918e..e5a304ef 100644 --- a/templates/sheets/actors/adversary/features.hbs +++ b/templates/sheets/actors/adversary/features.hbs @@ -1,9 +1,13 @@ -
    +
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true}} + {{> 'daggerheart.inventory-items' + title=tabs.features.label + type='feature' + collection=document.system.features + hideControls=true + canCreate=true + showActions=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs index 28c0d002..fd6389aa 100644 --- a/templates/sheets/actors/adversary/header.hbs +++ b/templates/sheets/actors/adversary/header.hbs @@ -27,7 +27,7 @@
    - {{{source.system.description}}} + {{{description}}}
    {{localize 'DAGGERHEART.ACTORS.Adversary.FIELDS.motivesAndTactics.label'}}: {{{source.system.motivesAndTactics}}} diff --git a/templates/sheets/actors/adversary/notes.hbs b/templates/sheets/actors/adversary/notes.hbs index effa7240..a2378516 100644 --- a/templates/sheets/actors/adversary/notes.hbs +++ b/templates/sheets/actors/adversary/notes.hbs @@ -5,6 +5,6 @@ >
    {{localize tabs.notes.label}} - {{formInput systemFields.notes value=document.system.notes enriched=document.system.notes localize=true toggled=true}} + {{formInput notes.field value=notes.value enriched=notes.enriched toggled=true}}
    \ No newline at end of file diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index 5384504e..8eb4dcb0 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -1,111 +1,118 @@
    - -

    Attack

    + +

    {{localize "DAGGERHEART.GENERAL.attack"}}

      - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=source.system.attack type=source.system.attack.systemPath isSidebar=true}} + {{> 'daggerheart.inventory-item' + item=document.system.attack + type='action' + hideTags=true + hideDescription=true + hideTooltip=true + hideResources=true + noExtensible=true + }}
    - -

    Experience

    + +

    {{localize DAGGERHEART.GENERAL.experience.plural}}

    {{#each source.system.experiences as |experience id|}} -
    -
    - +{{experience.value}} -
    - {{experience.name}} -
    - -
    +
    +
    + +{{experience.value}}
    + {{experience.name}} +
    + + + +
    +
    {{/each}}
    - +
    \ No newline at end of file diff --git a/templates/sheets/actors/character/biography.hbs b/templates/sheets/actors/character/biography.hbs index 34313def..6913f279 100644 --- a/templates/sheets/actors/character/biography.hbs +++ b/templates/sheets/actors/character/biography.hbs @@ -26,11 +26,11 @@
    {{localize 'DAGGERHEART.ACTORS.Character.story.backgroundTitle'}} - {{formInput systemFields.biography.fields.background value=source.system.biography.background enriched=source.system.biography.background localize=true toggled=true}} + {{formInput background.field value=background.value enriched=background.enriched toggled=true}}
    {{localize 'DAGGERHEART.ACTORS.Character.story.connectionsTitle'}} - {{formInput systemFields.biography.fields.connections value=source.system.biography.connections enriched=source.system.biography.connections localize=true toggled=true}} + {{formInput connections.field value=connections.value enriched=connections.enriched toggled=true}}
    \ No newline at end of file diff --git a/templates/sheets/actors/character/effects.hbs b/templates/sheets/actors/character/effects.hbs index 3d378802..4c4fca27 100644 --- a/templates/sheets/actors/character/effects.hbs +++ b/templates/sheets/actors/character/effects.hbs @@ -1,8 +1,21 @@ -
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
    + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/character/features.hbs b/templates/sheets/actors/character/features.hbs index 7fab5263..acabd37e 100644 --- a/templates/sheets/actors/character/features.hbs +++ b/templates/sheets/actors/character/features.hbs @@ -1,13 +1,25 @@ -
    +
    - {{#each document.system.sheetLists}} - {{#if this.values}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=this.title values=this.values}} - {{/if}} + {{#each document.system.sheetLists as |category|}} + {{#if (eq category.type 'feature' )}} + {{> 'daggerheart.inventory-items' + title=category.title + type='feature' + collection=category.values + canCreate=true + showActions=true + }} + {{else if category.values}} + {{> 'daggerheart.inventory-items' + title=category.title + type='feature' + collection=category.values + canCreate=false + showActions=true + }} + + {{/if}} {{/each}}
    \ No newline at end of file diff --git a/templates/sheets/actors/character/header.hbs b/templates/sheets/actors/character/header.hbs index 18e791d1..9e930fd6 100644 --- a/templates/sheets/actors/character/header.hbs +++ b/templates/sheets/actors/character/header.hbs @@ -29,25 +29,25 @@
    {{#if document.system.class.value}} - {{document.system.class.value.name}} + {{document.system.class.value.name}} {{else}} {{localize 'TYPES.Item.class'}} {{/if}} {{#if document.system.class.subclass}} - {{document.system.class.subclass.name}} + {{document.system.class.subclass.name}} {{else}} {{localize 'TYPES.Item.subclass'}} {{/if}} {{#if document.system.community}} - {{document.system.community.name}} + {{document.system.community.name}} {{else}} {{localize 'TYPES.Item.community'}} {{/if}} {{#if document.system.ancestry}} - {{document.system.ancestry.name}} + {{document.system.ancestry.name}} {{else}} {{localize 'TYPES.Item.ancestry'}} {{/if}} @@ -56,13 +56,13 @@ {{#if document.system.multiclass.value}}
    {{#if document.system.multiclass.value}} - {{document.system.multiclass.value.name}} + {{document.system.multiclass.value.name}} {{else}} {{localize 'DAGGERHEART.GENERAL.multiclass'}} {{/if}} {{#if document.system.multiclass.subclass}} - {{document.system.multiclass.subclass.name}} + {{document.system.multiclass.subclass.name}} {{else}} {{localize 'TYPES.Item.subclass'}} {{/if}} diff --git a/templates/sheets/actors/character/inventory.hbs b/templates/sheets/actors/character/inventory.hbs index be8bb251..9610d8e2 100644 --- a/templates/sheets/actors/character/inventory.hbs +++ b/templates/sheets/actors/character/inventory.hbs @@ -1,8 +1,5 @@ -
    +
    \ No newline at end of file diff --git a/templates/sheets/actors/character/loadout.hbs b/templates/sheets/actors/character/loadout.hbs index 5a1d675e..0319d56f 100644 --- a/templates/sheets/actors/character/loadout.hbs +++ b/templates/sheets/actors/character/loadout.hbs @@ -10,28 +10,33 @@ -
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' - title=(localize 'DAGGERHEART.GENERAL.Tabs.loadout') + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Tabs.loadout' type='domainCard' isGlassy=true - cardView=(ifThen listView "list" "card")}} - - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' - title=(localize 'DAGGERHEART.GENERAL.Tabs.vault') + cardView=cardView + collection=document.system.domainCards.loadout + canCreate=true + }} + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Tabs.vault' type='domainCard' - isVault=true isGlassy=true - cardView=(ifThen listView "list" "card")}} + cardView=cardView + collection=document.system.domainCards.vault + canCreate=true + inVault=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index 51816443..553ba246 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -1,14 +1,16 @@
    \ No newline at end of file diff --git a/templates/sheets/actors/companion/effects.hbs b/templates/sheets/actors/companion/effects.hbs index 3d378802..325610e6 100644 --- a/templates/sheets/actors/companion/effects.hbs +++ b/templates/sheets/actors/companion/effects.hbs @@ -1,8 +1,20 @@ -
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
    + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/environment/features.hbs b/templates/sheets/actors/environment/features.hbs index 6697e42c..d7f10d56 100644 --- a/templates/sheets/actors/environment/features.hbs +++ b/templates/sheets/actors/environment/features.hbs @@ -4,6 +4,13 @@ data-group='{{tabs.features.group}}' >
    - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true }} + {{> 'daggerheart.inventory-items' + title=tabs.features.label + type='feature' + collection=document.system.features + hideControls=true + canCreate=true + showActions=true + }}
    \ No newline at end of file diff --git a/templates/sheets/actors/environment/header.hbs b/templates/sheets/actors/environment/header.hbs index e9921bae..fff55144 100644 --- a/templates/sheets/actors/environment/header.hbs +++ b/templates/sheets/actors/environment/header.hbs @@ -34,7 +34,7 @@
    - {{{source.system.description}}} + {{{description}}}
    {{localize 'DAGGERHEART.ACTORS.Environment.FIELDS.impulses.label'}}: {{{source.system.impulses}}} diff --git a/templates/sheets/actors/environment/notes.hbs b/templates/sheets/actors/environment/notes.hbs index effa7240..663a484a 100644 --- a/templates/sheets/actors/environment/notes.hbs +++ b/templates/sheets/actors/environment/notes.hbs @@ -5,6 +5,6 @@ >
    {{localize tabs.notes.label}} - {{formInput systemFields.notes value=document.system.notes enriched=document.system.notes localize=true toggled=true}} + {{formInput notes.field value=notes.value enriched=notes.value toggled=true}}
    \ No newline at end of file diff --git a/templates/sheets/actors/environment/potentialAdversaries.hbs b/templates/sheets/actors/environment/potentialAdversaries.hbs index f39a1adf..cc246312 100644 --- a/templates/sheets/actors/environment/potentialAdversaries.hbs +++ b/templates/sheets/actors/environment/potentialAdversaries.hbs @@ -4,8 +4,17 @@ data-group='{{tabs.potentialAdversaries.group}}' >
    - {{#each document.system.potentialAdversaries}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=this.label type='adversary' isGlassy=true adversaries=this.adversaries}} + {{#each document.system.potentialAdversaries as |category categoryId|}} + {{> 'daggerheart.inventory-items' + title=category.label + type='adversary' + isGlassy=true + isActor=true + categoryAdversary=categoryId + hideControls=true + collection=category.adversaries + hideResources=true + }} {{/each}}
    \ No newline at end of file diff --git a/templates/sheets/global/partials/domain-card-item.hbs b/templates/sheets/global/partials/domain-card-item.hbs index 0ff7e8f5..37d6a0e2 100644 --- a/templates/sheets/global/partials/domain-card-item.hbs +++ b/templates/sheets/global/partials/domain-card-item.hbs @@ -1,34 +1,22 @@ -
  • +
  • -
  • +
  • {{feature.name}}

    {{#unless hideContrals}} - + {{/unless}}
  • \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs new file mode 100644 index 00000000..aa58aad8 --- /dev/null +++ b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs @@ -0,0 +1,70 @@ +{{!-- +Inventory/Domain Card Section + +{{> 'daggerheart.inventory-items' }} + +Parameters: +- title {string} : Localization key used for the legend. +- collection {array} : Array of items to render. +- type {string} : The type of items in the list: +- isGlassy {boolean} : If true, applies the 'glassy' class to the fieldset. +- cardView {boolean} : If true and type is 'domainCard', renders using domain card layout. +- isActor {boolean} : Passed through to inventory-item partials. +- canCreate {boolean} : If true, show createDoc anchor on legend +- inVault {boolean} : If true, the domainCard is created with inVault=true +- disabled {boolean}: If true, the ActiveEffect is created with disabled=true; +- categoryAdversary {string} : Category adversary id. +- showLabels {boolean} : If true, show label-tags else show simple tags. +- hideTooltip {boolean} : If true, disables the tooltip on the item image. +- hideControls {boolean} : If true, hides the controls inside inventory-item partials. +- hideDescription {boolean} : If true, hides the item's description. +- hideResources {boolean} : If true, hides the item's resources. +- showActions {boolean} : If true show feature's actions. +--}} + +
    + + {{localize title}} + {{#if canCreate}} + + + + {{/if }} + + {{#if (and cardView (eq type 'domainCard'))}} +
      + {{#each collection as |item|}} + + {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' + item=item + type='domainCard' + }} + + {{/each}} +
    + {{else}} +
      + {{#each collection as |item|}} + + {{> 'daggerheart.inventory-item' + item=item + type=../type + hideControls=../hideControls + isActor=../isActor + categoryAdversary=../categoryAdversary + hideTooltip=../hideTooltip + showLabels=../showLabels + isAction=../isAction + hideResources=../hideResources + showActions=../showActions + }} + + {{/each}} +
    + {{/if}} +
    \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-fieldset-items.hbs b/templates/sheets/global/partials/inventory-fieldset-items.hbs deleted file mode 100644 index 65c52736..00000000 --- a/templates/sheets/global/partials/inventory-fieldset-items.hbs +++ /dev/null @@ -1,44 +0,0 @@ -
    - {{title}} -
      - {{#unless (eq cardView 'card') }} - {{#if (or (eq type 'domainCard') (eq type 'armor') (eq type 'consumable') (eq type 'miscellaneous') (eq type 'weapon'))}} - {{#each document.items as |item|}} - {{#if (eq item.type ../type)}} - {{#unless (and (eq ../type 'domainCard') (or (and item.system.inVault (not ../isVault)) (and (not item.system.inVault) ../isVault)))}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=item type=../type}} - {{/unless}} - {{/if}} - {{/each}} - {{else}} - {{#if (eq type 'effect')}} - {{#each document.effects as |effect|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=effect type=../type}} - {{/each}} - {{else}} - {{#each values}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls featureType=true }} - {{/each}} - - {{#each adversaries as |adversary|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=adversary type='adversary' hideControls=true isActor=true categoryAdversary=@../key}} - {{/each}} - {{/if}} - {{/if}} - {{/unless}} - -
    - {{#if (and (eq cardView 'card') (eq type 'domainCard'))}} -
      - {{#if isVault}} - {{#each document.system.domainCards.vault as |card|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' item=card type=../type}} - {{/each}} - {{else}} - {{#each document.system.domainCards.loadout as |card|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' item=card type=../type}} - {{/each}} - {{/if}} -
    - {{/if}} -
    \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs new file mode 100644 index 00000000..5329e7b5 --- /dev/null +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -0,0 +1,239 @@ +{{!-- +{{> 'daggerheart.inventory-item' }} + +Parameters: +- type {string} : The type of items in the list +- isActor {boolean} : Passed through to inventory-item partials. +- categoryAdversary {string} : Category adversary id. +- noExtensible {boolean} : If true, the inventory-item-content would be collapsable/extendible else it always be showed +- hideLabels {boolean} : If true, hide label-tags else show label-tags. +- hideTags {boolean} : If true, hide simple-tags else show simple-tags. +- hideTooltip {boolean} : If true, disables the tooltip on the item image. +- hideControls {boolean} : If true, hides the controls inside inventory-item partials. +- hideDescription {boolean} : If true, hides the item's description. +- hideResources {boolean} : If true, hides the item's resources. +- showActions {boolean} : If true show feature's actions. +--}} + +
  • +
    + {{!-- Image --}} +
    + + d20 +
    + + {{!-- Name & Tags --}} +
    + + {{!-- Item Name --}} +
    {{item.name}}
    + + {{!-- Weapon Block Start --}} + {{#if (eq type 'weapon')}} + {{#if (not hideTags)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}} +
    +
    + {{item.system.attack.damage.parts.0.value.dice}} + {{#if item.system.attack.damage.parts.0.value.bonus}} + + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} + ( + {{#each item.system.attack.damage.parts.0.type as |type|}} + + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' type '.abbreviation')}} + {{#unless @last}}|{{/unless}} + {{/each}} + ) + +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}} + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}} + - + {{item.system.attack.damage.parts.0.value.dice}} + {{#if item.system.attack.damage.parts.0.value.bonus}} + + {{item.system.attack.damage.parts.0.value.bonus}} + {{/if}} + {{#with (lookup @root.config.GENERAL.damageTypes item.system.attack.damage.parts.0.type)}} + {{#each icon}}{{/each}} + {{/with}} +
    +
    + {{/if}} + {{/if}} + {{!-- Weapon Block End --}} + + {{!-- Armor Block Start --}} + {{#if (eq type 'armor')}} + {{#if (not hideTags)}} +
    +
    {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}}
    +
    + {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: + {{item.system.baseThresholds.major}} / {{item.system.baseThresholds.severe}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}} +
    +
    + {{/if}} + {{/if}} + {{!-- Armor Block End --}} + + {{!-- Domain Card Block Start --}} + {{#if (eq type 'domainCard')}} + {{#if (not hideTags)}} +
    +
    {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}}
    +
    {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}}
    +
    + {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: + {{item.system.recallCost}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} - + {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} - + {{item.system.recallCost}} + +
    +
    + {{/if}} + {{/if}} + {{!-- Domain Card Block End --}} + + {{!-- Effect Block Start --}} + {{#if (eq type 'effect')}} + {{#if (not hideTags)}} +
    +
    + {{localize item.parent.system.metadata.label}}: {{item.parent.name}} +
    +
    + {{#if item.duration.duration}} + {{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}} + {{else}} + {{localize 'DAGGERHEART.EFFECTS.Duration.passive'}} + {{/if}} +
    + {{#each item.statuses as |status|}} +
    {{localize (concat 'DAGGERHEART.CONFIG.Condition.' status '.name')}}
    + {{/each}} +
    + {{else if (not hideLabels)}} + {{!-- Empty --}} + {{/if}} + {{/if}} + {{!-- Effect Block End --}} + + {{!-- Action Block Start --}} + {{#if (eq type 'action')}} + {{#if (not hideTags)}} +
    +
    {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}}
    +
    {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}}
    +
    + {{else if (not hideLabels)}} + {{!-- Empty --}} + {{/if}} + {{/if}} + {{!-- Action Block End --}} +
    + + {{!-- Simple Resource --}} + {{#if (and (not hideResources) (eq item.system.resource.type 'simple'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{#if (and (not hideResources) item.system.quantity)}} +
    + +
    + {{/if}} + + {{!-- Controls --}} + {{#unless hideControls}} +
    + {{#if isActor}} + + + + {{#if (eq type 'adversary')}} + + + + {{/if}} + {{else}} + {{#if (eq type 'weapon')}} + + + + {{else if (eq type 'armor')}} + + + + {{else if (eq type 'domainCard')}} + + + + {{else if (eq type 'effect')}} + + + + {{/if}} + {{#if (hasProperty item "toChat")}} + + + + {{/if}} + + + + {{/if}} +
    + {{/unless}} +
    +
    + {{!-- Description --}} + {{#unless hideDescription}} +
    + {{/unless}} + {{!-- Dice Resource --}} + {{#if (and (not hideResources) (eq item.system.resource.type 'diceValue'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{!-- Actions Buttons --}} + {{#if (and showActions (eq item.type 'feature'))}} +
    + {{#each item.system.actions as | action |}} + + {{/each}} +
    + {{/if}} +
    +
  • \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs deleted file mode 100644 index a6373c08..00000000 --- a/templates/sheets/global/partials/inventory-item.hbs +++ /dev/null @@ -1,197 +0,0 @@ -
  • - -
    -
    - {{#if isCompanion}} - {{item.name}} - {{else}} -
    {{item.name}}
    - {{/if}} - {{#if (eq type 'weapon')}} -
    - {{#if isSidebar}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}} - {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}} - - - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - {{#each item.system.attack.damage.parts.0.type as | type | }} - {{#with (lookup @root.config.GENERAL.damageTypes type)}} - - {{/with}} - {{/each}} -
    -
    - {{else}} -
    - {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}} -
    -
    - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - ( - {{#each item.system.attack.damage.parts.0.type}} - {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} - {{/each}} - ) -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} -
    - {{/if}} -
    - {{/if}} - {{#if (eq type 'armor')}} - {{#if isSidebar}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: - {{item.system.baseScore}} -
    -
    - {{else}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: - {{item.system.baseScore}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: - {{item.system.baseThresholds.major}} - / - {{item.system.baseThresholds.severe}} -
    -
    - {{/if}} - {{/if}} - {{#if (eq type 'domainCard')}} - {{#if isSidebar}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} - - - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} - - - {{item.system.recallCost}} - -
    -
    - {{else}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} -
    -
    - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} -
    -
    - {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: - {{item.system.recallCost}} -
    -
    - {{/if}} - {{/if}} - {{#if (eq type 'effect')}} -
    -
    - {{localize (concat 'TYPES.Item.' item.parent.type)}} - : - {{item.parent.name}} -
    -
    - {{#if item.duration.duration}} - {{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}} - {{else}} - {{localize 'DAGGERHEART.EFFECTS.Duration.passive'}} - {{/if}} -
    - {{#each item.statuses as |status|}} -
    - {{localize (concat 'DAGGERHEART.CONFIG.Condition.' status '.name')}} -
    - {{/each}} -
    - {{/if}} - {{#if (eq type 'action')}} -
    -
    - {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}} -
    -
    - {{/if}} -
    - {{#if (and (not isSidebar) (eq item.system.resource.type 'simple'))}} - {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} - {{/if}} - {{#if (and (not isSidebar) item.system.quantity)}} -
    - -
    - {{/if}} -
    - {{#unless hideControls}} - {{#if isActor}} -
    - {{#if (eq type 'actor')}} - - - - {{/if}} - {{#if (eq type 'adversary')}} - - - - - - - {{/if}} -
    - {{else}} -
    - {{#if (eq type 'weapon')}} - - - - {{/if}} - {{#if (eq type 'armor')}} - - - - {{/if}} - {{#if (eq type 'domainCard')}} - {{#unless item.system.inVault}} - - - - {{else}} - - - - {{/unless}} - - {{/if}} - - -
    - {{/if}} - {{else}} - - {{/unless}} -
    {{#unless isSidebar}}{{{item.system.description}}}{{/unless}}
    - {{#if (and (not isSidebar) (eq item.system.resource.type 'diceValue'))}} - {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} - {{/if}} - {{#if featureType}} -
    - {{#each item.system.actions as | action |}} - - {{/each}} -
    - {{/if}} -
  • \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-actions.hbs b/templates/sheets/global/tabs/tab-actions.hbs index ed71c45f..584cf782 100644 --- a/templates/sheets/global/tabs/tab-actions.hbs +++ b/templates/sheets/global/tabs/tab-actions.hbs @@ -3,22 +3,11 @@ data-tab='{{tabs.actions.id}}' data-group='{{tabs.actions.group}}' > -
    - {{localize "DAGGERHEART.GENERAL.Action.plural"}} -
    - {{#each document.system.actions as |action index|}} -
    - - {{action.name}} -
    - -
    -
    - {{/each}} -
    -
    + +{{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Action.plural' + collection=document.system.actions + type='action' + canCreate=true +}} \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-effects.hbs b/templates/sheets/global/tabs/tab-effects.hbs index a75f1b0b..c89c6ff4 100644 --- a/templates/sheets/global/tabs/tab-effects.hbs +++ b/templates/sheets/global/tabs/tab-effects.hbs @@ -1,26 +1,21 @@ -
    -
    - - {{localize "DAGGERHEART.GENERAL.Effect.plural"}} - - - - -
    - {{#each document.effects as |effect|}} -
    - - {{effect.name}} -
    - - -
    -
    - {{/each}} -
    -
    +
    + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
    \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-feature-section.hbs b/templates/sheets/global/tabs/tab-feature-section.hbs deleted file mode 100644 index ca6af184..00000000 --- a/templates/sheets/global/tabs/tab-feature-section.hbs +++ /dev/null @@ -1,14 +0,0 @@ -
    -
    - {{localize "DAGGERHEART.GENERAL.Tabs.features"}} -
    - {{#each source.system.abilities as |feature key|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} - {{/each}} -
    -
    -
    \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-features.hbs b/templates/sheets/global/tabs/tab-features.hbs index eced83d7..b70b33d3 100644 --- a/templates/sheets/global/tabs/tab-features.hbs +++ b/templates/sheets/global/tabs/tab-features.hbs @@ -1,23 +1,11 @@ -
    -
    - {{localize "DAGGERHEART.GENERAL.features"}} -
    - {{#each document.system.features as |feature|}} -
    - - {{feature.name}} -
    - -
    -
    - {{/each}} -
    -
    +
    + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.features' + type='feature' + isGlassy=true + collection=document.system.features + canCreate=(or document.parent isGM) + showActions=false + }}
    \ No newline at end of file diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs index b110bf4c..756687b4 100644 --- a/templates/sheets/items/class/settings.hbs +++ b/templates/sheets/items/class/settings.hbs @@ -38,7 +38,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedPrimaryWeaponTitle"}}
    {{#if document.system.characterGuide.suggestedPrimaryWeapon}} -
    +
    {{document.system.characterGuide.suggestedPrimaryWeapon.name}}
    @@ -53,7 +53,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}
    {{#if document.system.characterGuide.suggestedSecondaryWeapon}} -
    +
    {{document.system.characterGuide.suggestedSecondaryWeapon.name}}
    @@ -68,7 +68,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedArmorTitle"}}
    {{#if document.system.characterGuide.suggestedArmor}} -
    +
    {{document.system.characterGuide.suggestedArmor.name}}
    @@ -86,7 +86,7 @@ {{localize "DAGGERHEART.GENERAL.take"}}
    {{#each source.system.inventory.take}} -
    +
    {{this.name}}
    @@ -101,7 +101,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}
    {{#each source.system.inventory.choiceA}} -
    +
    {{this.name}}
    @@ -116,7 +116,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}
    {{#each source.system.inventory.choiceB}} -
    +
    {{this.name}}
    From 50ba7408b93ecf2ec76662f43a06def800c9ac9a Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Sun, 20 Jul 2025 03:58:31 +0200 Subject: [PATCH 52/58] Fix item desc animation (#382) --- styles/less/global/inventory-item.less | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/styles/less/global/inventory-item.less b/styles/less/global/inventory-item.less index d758085b..077ae165 100644 --- a/styles/less/global/inventory-item.less +++ b/styles/less/global/inventory-item.less @@ -113,12 +113,14 @@ margin-bottom: 5px; } &.extensible { - max-height: 0; - overflow: hidden; - transition: max-height 0.5s ease-in-out; + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows 0.3s ease-in-out; &.extended { - max-height: 500px; - overflow: auto; + grid-template-rows: 1fr; + } + .invetory-description { + overflow: hidden; } } .item-resources { From 3dd2378ffb01102ef6468f4721e1fc28648b621f Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sun, 20 Jul 2025 04:15:26 +0200 Subject: [PATCH 53/58] [Fix] Localization Misses (#381) * Initial localization adds * Added remaining missing translation use --- lang/en.json | 39 +++++++++++++++++-- module/data/action/actionDice.mjs | 5 ++- templates/actionTypes/damage.hbs | 6 +-- templates/actionTypes/effect.hbs | 4 +- templates/actionTypes/healing.hbs | 4 +- templates/actionTypes/part/damage-part.hbs | 0 templates/actionTypes/range-target.hbs | 2 +- templates/actionTypes/resource.hbs | 2 +- templates/actionTypes/save.hbs | 2 +- templates/actionTypes/uses.hbs | 2 +- templates/actionTypes/uuid.hbs | 2 +- templates/characterCreation/tabs/story.hbs | 2 +- templates/dialogs/dice-roll/costSelection.hbs | 3 -- .../dialogs/dice-roll/damageSelection.hbs | 2 +- templates/dialogs/dice-roll/rollSelection.hbs | 22 +++++------ templates/settings/homebrew-settings.hbs | 2 +- .../sheets-settings/action-settings/base.hbs | 4 +- .../adversary-settings/attack.hbs | 12 +++--- .../adversary-settings/experiences.hbs | 2 +- .../companion-settings/attack.hbs | 10 ++--- .../companion-settings/details.hbs | 6 +-- .../environment-settings/adversaries.hbs | 4 +- templates/sheets/actors/adversary/header.hbs | 2 +- templates/sheets/actors/character/sidebar.hbs | 14 +++---- templates/sheets/actors/companion/header.hbs | 6 +-- .../sheets/global/partials/action-item.hbs | 6 --- .../global/partials/resource-section.hbs | 2 +- templates/sheets/items/weapon/attachments.hbs | 0 templates/sheets/pseudo-documents/header.hbs | 3 -- templates/ui/chat/adversary-attack-roll.hbs | 2 +- templates/ui/chat/adversary-roll.hbs | 2 +- templates/ui/chat/duality-roll.hbs | 14 ++++++- templates/ui/chat/parts/damage-chat.hbs | 2 +- templates/ui/chat/parts/target-chat.hbs | 5 +-- templates/ui/tooltip/action.hbs | 2 +- 35 files changed, 114 insertions(+), 83 deletions(-) delete mode 100644 templates/actionTypes/part/damage-part.hbs delete mode 100644 templates/sheets/items/weapon/attachments.hbs delete mode 100644 templates/sheets/pseudo-documents/header.hbs diff --git a/lang/en.json b/lang/en.json index 7e25f0d2..4d3927bc 100755 --- a/lang/en.json +++ b/lang/en.json @@ -33,6 +33,10 @@ } }, "Settings": { + "attackBonus": "Attack Bonus", + "attackName": "Attack Name", + "includeBase": { "label": "Include Item Damage" }, + "multiplier": "Multiplier", "resultBased": { "label": "Formula based on Hope/Fear result." }, @@ -128,7 +132,9 @@ "partner": { "label": "Partner" }, "resources": { "stress": { - "value": { "label": "Stress" } + "value": { "label": "Stress" }, + "currentStress": { "label": "Current Stress" }, + "maxStress": { "label": "Max Stress" } } } }, @@ -183,6 +189,7 @@ "selectSecondaryWeapon": "Select Secondary Weapon", "selectSubclass": "Select Subclass", "startingItems": "Starting Items", + "story": "Story", "suggestedArmor": "Suggested Armor", "suggestedPrimaryWeapon": "Suggested Primary Weapon", "suggestedSecondaryWeapon": "Suggested Secondary Weapon", @@ -1139,6 +1146,10 @@ "Healing": { "healingAmount": "Healing Amount" }, + "Modifier": { + "single": "Modifier", + "plural": "Modifiers" + }, "Neutral": { "full": "None", "short": "no" @@ -1237,6 +1248,8 @@ "single": "Trait", "plural": "Traits" }, + "actorName": "Actor Name", + "amount": "Amount", "armorScore": "Armor Score", "activeEffects": "Active Effects", "armorSlots": "Armor Slots", @@ -1245,21 +1258,25 @@ "bonus": "Bonus", "burden": "Burden", "check": "{check} Check", + "continue": "Continue", "criticalSuccess": "Critical Success", "damage": "Damage", "damageType": "Damage Type", "description": "Description", "difficulty": "Difficulty", + "dropActorsHere": "Drop Actors here", "duality": "Duality", "dualityRoll": "Duality Roll", "enabled": "Enabled", "evasion": "Evasion", + "equipment": "Equipment", "experience": { "single": "Experience", "plural": "Experiences" }, "fear": "Fear", "features": "Features", + "formula": "Formula", "healing": "Healing", "hitPoints": { "single": "Hit Point", @@ -1268,24 +1285,37 @@ }, "hope": "Hope", "hordeHp": "Horde HP", + "identify": "Identity", + "imagePath": "Image Path", "inactiveEffects": "Inactive Effects", "inventory": "Inventory", "level": "Level", + "levelUp": "Level Up", + "loadout": "Loadout", "max": "Max", - "modifier": "Modifier", "multiclass": "Multiclass", + "newCategory": "New Category", "none": "None", "partner": "Partner", "proficiency": "Proficiency", "quantity": "Quantity", "range": "Range", "recovery": "Recovery", + "resource": "Resource", "roll": "Roll", + "rollAll": "Roll All", + "rollDamage": "Roll Damage", + "save": "Save", "scalable": "Scalable", + "situationalBonus": "Situational Bonus", "stress": "Stress", "take": "Take", - "target": "Target", + "Target": { + "single": "Target", + "plural": "Targets" + }, "title": "Title", + "total": "Total", "true": "True", "type": "Type", "unarmored": "Unarmored", @@ -1593,7 +1623,8 @@ "sendToVault": "Send to Vault", "sendToLoadout": "Send to Loadout", "makeDeathMove": "Make a Death Move", - "rangeAndTarget": "Range & Target" + "rangeAndTarget": "Range & Target", + "appliedEvenIfSuccessful": "Applied even if save succeeded" } } } diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index c3c28247..e72dc54a 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -87,7 +87,10 @@ export class DHDamageField extends fields.SchemaField { constructor(options, context = {}) { const damageFields = { parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)), - includeBase: new fields.BooleanField({ initial: false }) + includeBase: new fields.BooleanField({ + initial: false, + label: 'DAGGERHEART.ACTIONS.Settings.includeBase.label' + }) }; super(damageFields, options, context); } diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index bfbbc592..ad45fc33 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -6,7 +6,7 @@ {{#unless (or @root.isNPC path)}} {{#if @root.hasBaseDamage}} - {{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase label="Include Item Damage" name="damage.includeBase" classes="checkbox" }} + {{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase name="damage.includeBase" classes="checkbox" localize=true }} {{/if}} {{/unless}} {{#each source.parts as |dmg index|}} @@ -17,7 +17,7 @@ {{formField ../fields.value.fields.custom.fields.formula value=dmg.value.custom.formula name=(concat ../path "damage.parts." index ".value.custom.formula") localize=true}} {{else}}
    - {{#if @root.isNPC}}{{formField ../fields.value.fields.flatMultiplier value=dmg.value.flatMultiplier name=(concat ../path "damage.parts." index ".value.flatMultiplier") label="Multiplier" classes="inline-child" }}{{/if}} + {{#if @root.isNPC}}{{formField ../fields.value.fields.flatMultiplier value=dmg.value.flatMultiplier name=(concat ../path "damage.parts." index ".value.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }}{{/if}} {{formField ../fields.value.fields.dice value=dmg.value.dice name=(concat ../path "damage.parts." index ".value.dice") classes="inline-child"}} {{formField ../fields.value.fields.bonus value=dmg.value.bonus name=(concat ../path "damage.parts." index ".value.bonus") localize=true classes="inline-child"}}
    @@ -32,7 +32,7 @@
    {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}}
    - {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." index ".valueAlt.flatMultiplier") label="Multiplier" classes="inline-child" }} + {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." index ".valueAlt.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }} {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." index ".valueAlt.dice") classes="inline-child"}} {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." index ".valueAlt.bonus") localize=true classes="inline-child"}}
    diff --git a/templates/actionTypes/effect.hbs b/templates/actionTypes/effect.hbs index d144f2fc..0d89399c 100644 --- a/templates/actionTypes/effect.hbs +++ b/templates/actionTypes/effect.hbs @@ -1,6 +1,6 @@
    - Effects + {{localize "DAGGERHEART.GENERAL.Effect.plural"}}
      @@ -13,7 +13,7 @@
    {{/with}} - {{#if @root.source.save.trait}}{{formInput ../fields.onSave value=effect.onSave name=(concat "effects." index ".onSave") dataset=(object tooltip="Applied even if save succeeded" tooltipDirection="UP")}}{{/if}} + {{#if @root.source.save.trait}}{{formInput ../fields.onSave value=effect.onSave name=(concat "effects." index ".onSave") dataset=(object tooltip=(localize "DAGGERHEART.UI.Tooltip.appliedEvenIfSuccessful") tooltipDirection="UP")}}{{/if}}
    diff --git a/templates/actionTypes/healing.hbs b/templates/actionTypes/healing.hbs index 4b095174..9091469e 100644 --- a/templates/actionTypes/healing.hbs +++ b/templates/actionTypes/healing.hbs @@ -10,13 +10,13 @@
    -
    With Hope
    +
    {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}}
    {{> formula fields=fields.value.fields source=source.value target="value"}}
    -
    With Fear
    +
    {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}}
    {{> formula fields=fields.valueAlt.fields source=source.valueAlt target="valueAlt"}}
    diff --git a/templates/actionTypes/part/damage-part.hbs b/templates/actionTypes/part/damage-part.hbs deleted file mode 100644 index e69de29b..00000000 diff --git a/templates/actionTypes/range-target.hbs b/templates/actionTypes/range-target.hbs index 22da2f86..3776f0c1 100644 --- a/templates/actionTypes/range-target.hbs +++ b/templates/actionTypes/range-target.hbs @@ -1,5 +1,5 @@
    - Range{{#if fields.target}} & Target{{/if}} + {{localize "DAGGERHEART.GENERAL.range"}}{{#if fields.target}} & {{localize "DAGGERHEART.GENERAL.Target.single"}}{{/if}} {{formField fields.range value=source.range label="Range" name=(concat path "range") localize=true}} {{#if fields.target}}
    diff --git a/templates/actionTypes/resource.hbs b/templates/actionTypes/resource.hbs index 4b1daa1e..9c8fc965 100644 --- a/templates/actionTypes/resource.hbs +++ b/templates/actionTypes/resource.hbs @@ -1,7 +1,7 @@
    -
    Resource
    +
    {{localize "DAGGERHEART.GENERAL.resource"}}
    diff --git a/templates/actionTypes/save.hbs b/templates/actionTypes/save.hbs index 4f2809ee..ff5be220 100644 --- a/templates/actionTypes/save.hbs +++ b/templates/actionTypes/save.hbs @@ -1,5 +1,5 @@
    - Save + {{localize "DAGGERHEART.GENERAL.save"}} {{formField fields.trait label="Trait" name="save.trait" value=source.trait localize=true}} {{formField fields.difficulty label="Difficulty" name="save.difficulty" value=source.difficulty disabled=(not source.trait)}} {{formField fields.damageMod label="Damage on Save" name="save.damageMod" value=source.damageMod localize=true disabled=(not source.trait)}} diff --git a/templates/actionTypes/uses.hbs b/templates/actionTypes/uses.hbs index 820d67ab..174b1904 100644 --- a/templates/actionTypes/uses.hbs +++ b/templates/actionTypes/uses.hbs @@ -1,5 +1,5 @@
    - Uses + {{localize "DAGGERHEART.GENERAL.uses"}}
    {{formField fields.value label="Spent" value=source.value name="uses.value" rootId=partId}} {{formField fields.max label="Max" value=source.max name="uses.max" rootId=partId}} diff --git a/templates/actionTypes/uuid.hbs b/templates/actionTypes/uuid.hbs index b7ccd578..140cad78 100644 --- a/templates/actionTypes/uuid.hbs +++ b/templates/actionTypes/uuid.hbs @@ -1,7 +1,7 @@
    -
    Macro
    +
    {{localize "DOCUMENT.Macro"}}
    {{formInput fields value=source name="documentUUID" placeholder=fields.options.placeholder}} diff --git a/templates/characterCreation/tabs/story.hbs b/templates/characterCreation/tabs/story.hbs index c2fb7400..6aa08334 100644 --- a/templates/characterCreation/tabs/story.hbs +++ b/templates/characterCreation/tabs/story.hbs @@ -4,6 +4,6 @@ data-group='{{tabs.story.group}}' >
    - Story + {{localize "DAGGERHEART.APPLICATIONS.CharacterCreation.story"}}
    \ No newline at end of file diff --git a/templates/dialogs/dice-roll/costSelection.hbs b/templates/dialogs/dice-roll/costSelection.hbs index 48ff90a0..91d0229f 100644 --- a/templates/dialogs/dice-roll/costSelection.hbs +++ b/templates/dialogs/dice-roll/costSelection.hbs @@ -18,7 +18,4 @@
    {{/each}} - {{!--
    - -
    --}}
    \ No newline at end of file diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index 3e47cf68..6eb2efff 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -4,7 +4,7 @@ {{#each @root.formula}}
    - Formula: {{roll.formula}} + {{localize "DAGGERHEART.GENERAL.formula"}}: {{roll.formula}} {{#with (lookup @root.config.GENERAL.healingTypes applyTo)}} {{localize label}} diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index 7c894fd8..ca918145 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -17,14 +17,14 @@
    - Advantage + {{localize "DAGGERHEART.GENERAL.Advantage.full"}}
    {{else if (eq @root.advantage -1)}}
    - Disdvantage + {{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}
    {{/if}} @@ -34,7 +34,7 @@
    - Hope + {{localize "DAGGERHEART.GENERAL.hope"}} @@ -54,14 +54,14 @@
    - Advantage + {{localize "DAGGERHEART.GENERAL.Advantage.full"}}
    {{else if (eq @root.advantage -1)}}
    - Disdvantage + {{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}
    {{/if}} @@ -70,7 +70,7 @@
    - Experiences + {{localize "DAGGERHEART.GENERAL.experience.plural"}} {{#each experiences}} {{#if name}}
    @@ -89,7 +89,7 @@ {{/each}}
    - Modifiers + {{localize "DAGGERHEART.GENERAL.Modifier.plural"}}
    {{/unless}} - Formula: {{@root.formula}} + {{localize "DAGGERHEART.GENERAL.formula"}}: {{@root.formula}}
    {{else}} {{/if}}
    diff --git a/templates/settings/homebrew-settings.hbs b/templates/settings/homebrew-settings.hbs index 4d0e1f29..07ae0c1f 100644 --- a/templates/settings/homebrew-settings.hbs +++ b/templates/settings/homebrew-settings.hbs @@ -5,7 +5,7 @@
    {{#each settingFields._source.traitArray as |trait index|}}
    - +
    {{/each}} diff --git a/templates/sheets-settings/action-settings/base.hbs b/templates/sheets-settings/action-settings/base.hbs index eab56de7..25db8359 100644 --- a/templates/sheets-settings/action-settings/base.hbs +++ b/templates/sheets-settings/action-settings/base.hbs @@ -4,14 +4,14 @@ data-tab="base" >
    - Identity + {{localize "DAGGERHEART.GENERAL.identify"}} {{formField fields.name value=source.name label="Name" name="name"}} {{formField fields.img value=source.img label="Icon" name="img"}} {{formField fields.actionType value=source.actionType label="Type" name="actionType" localize=true}} {{formField fields.chatDisplay value=source.chatDisplay name="chatDisplay" classes="checkbox"}}
    - Description + {{localize "DAGGERHEART.GENERAL.description"}} {{formInput fields.description value=source.description name="description" }}
    \ No newline at end of file diff --git a/templates/sheets-settings/adversary-settings/attack.hbs b/templates/sheets-settings/adversary-settings/attack.hbs index 8b1e564c..bdb6da5b 100644 --- a/templates/sheets-settings/adversary-settings/attack.hbs +++ b/templates/sheets-settings/adversary-settings/attack.hbs @@ -5,17 +5,17 @@ >
    {{localize "DAGGERHEART.GENERAL.basics"}} - {{formGroup systemFields.attack.fields.img value=document.system.attack.img label="Image Path" name="system.attack.img"}} - {{formGroup systemFields.attack.fields.name value=document.system.attack.name label="Attack Name" name="system.attack.name"}} + {{formGroup systemFields.attack.fields.img value=document.system.attack.img label="DAGGERHEART.GENERAL.imagePath" name="system.attack.img" localize=true}} + {{formGroup systemFields.attack.fields.name value=document.system.attack.name label="DAGGERHEART.ACTIONS.Settings.attackName" name="system.attack.name" localize=true}}
    {{localize "DAGGERHEART.GENERAL.attack"}} - {{formField systemFields.attack.fields.roll.fields.bonus value=document.system.attack.roll.bonus label="Attack Bonus" name="system.attack.roll.bonus"}} - {{formField systemFields.attack.fields.range value=document.system.attack.range label="Range" name="system.attack.range" localize=true}} + {{formField systemFields.attack.fields.roll.fields.bonus value=document.system.attack.roll.bonus label="DAGGERHEART.ACTIONS.Settings.attackBonus" name="system.attack.roll.bonus" localize=true}} + {{formField systemFields.attack.fields.range value=document.system.attack.range label="DAGGERHEART.GENERAL.range" name="system.attack.range" localize=true}} {{#if systemFields.attack.fields.target.fields}} - {{ formField systemFields.attack.fields.target.fields.type value=document.system.attack.target.type label="Target" name="system.attack.target.type" localize=true }} + {{ formField systemFields.attack.fields.target.fields.type value=document.system.attack.target.type label="DAGGERHEART.GENERAL.Target.single" name="system.attack.target.type" localize=true }} {{#if (and document.system.attack.target.type (not (eq document.system.attack.target.type 'self')))}} - {{ formField systemFields.attack.fields.target.fields.amount value=document.system.attack.target.amount label="Amount" name="system.attack.target.amount" }} + {{ formField systemFields.attack.fields.target.fields.amount value=document.system.attack.target.amount label="DAGGERHEART.GENERAL.amount" name="system.attack.target.amount" localize=true}} {{/if}} {{/if}}
    diff --git a/templates/sheets-settings/adversary-settings/experiences.hbs b/templates/sheets-settings/adversary-settings/experiences.hbs index 5fe2ab36..72d2a3c4 100644 --- a/templates/sheets-settings/adversary-settings/experiences.hbs +++ b/templates/sheets-settings/adversary-settings/experiences.hbs @@ -4,7 +4,7 @@ data-group='{{tabs.experiences.group}}' >
    diff --git a/templates/sheets-settings/companion-settings/attack.hbs b/templates/sheets-settings/companion-settings/attack.hbs index 0c874ac1..359536b6 100644 --- a/templates/sheets-settings/companion-settings/attack.hbs +++ b/templates/sheets-settings/companion-settings/attack.hbs @@ -5,16 +5,16 @@ >
    {{localize "DAGGERHEART.GENERAL.basics"}} - {{formGroup systemFields.attack.fields.img value=document.system.attack.img label="Image Path" name="system.attack.img"}} - {{formGroup systemFields.attack.fields.name value=document.system.attack.name label="Attack Name" name="system.attack.name"}} + {{formGroup systemFields.attack.fields.img value=document.system.attack.img label="DAGGERHEART.GENERAL.imagePath" name="system.attack.img" localize=true}} + {{formGroup systemFields.attack.fields.name value=document.system.attack.name label="DAGGERHEART.ACTIONS.Settings.attackName" name="system.attack.name" localize=true}}
    {{localize "DAGGERHEART.GENERAL.attack"}} - {{formField systemFields.attack.fields.range value=document.system.attack.range label="Range" name="system.attack.range" localize=true}} + {{formField systemFields.attack.fields.range value=document.system.attack.range label="DAGGERHEART.GENERAL.range" name="system.attack.range" localize=true}} {{#if systemFields.attack.fields.target.fields}} - {{ formField systemFields.attack.fields.target.fields.type value=document.system.attack.target.type label="Target" name="system.attack.target.type" localize=true }} + {{ formField systemFields.attack.fields.target.fields.type value=document.system.attack.target.type label="DAGGERHEART.GENERAL.Target.single" name="system.attack.target.type" localize=true}} {{#if (and document.system.attack.target.type (not (eq document.system.attack.target.type 'self')))}} - {{ formField systemFields.attack.fields.target.fields.amount value=document.system.attack.target.amount label="Amount" name="system.attack.target.amount" }} + {{ formField systemFields.attack.fields.target.fields.amount value=document.system.attack.target.amount label="DAGGERHEART.GENERAL.amount" name="system.attack.target.amount" localize=true}} {{/if}} {{/if}}
    diff --git a/templates/sheets-settings/companion-settings/details.hbs b/templates/sheets-settings/companion-settings/details.hbs index 31be666c..4f1825d8 100644 --- a/templates/sheets-settings/companion-settings/details.hbs +++ b/templates/sheets-settings/companion-settings/details.hbs @@ -7,8 +7,8 @@ {{localize 'DAGGERHEART.GENERAL.basics'}}
    {{formGroup systemFields.evasion value=document.system.evasion localize=true}} - {{formGroup systemFields.resources.fields.stress.fields.value value=document.system.resources.stress.value label='Current Stress'}} - {{formGroup systemFields.resources.fields.stress.fields.max value=document.system.resources.stress.max label='Max Stress'}} + {{formGroup systemFields.resources.fields.stress.fields.value value=document.system.resources.stress.value label='DAGGERHEART.ACTORS.Companion.FIELDS.resources.stress.currentStress.label' localize=true}} + {{formGroup systemFields.resources.fields.stress.fields.max value=document.system.resources.stress.max label='DAGGERHEART.ACTORS.Companion.FIELDS.resources.stress.maxStress.label' localize=true}}
    @@ -19,5 +19,5 @@
    - + \ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/adversaries.hbs b/templates/sheets-settings/environment-settings/adversaries.hbs index 4a9ef08d..3464a745 100644 --- a/templates/sheets-settings/environment-settings/adversaries.hbs +++ b/templates/sheets-settings/environment-settings/adversaries.hbs @@ -1,7 +1,7 @@
    {{#each document.system.potentialAdversaries as |category categoryId|}}
    @@ -26,7 +26,7 @@ {{/each}}
    - Drop Actors here + {{localize "DAGGERHEART.GENERAL.dropActorsHere"}}
    {{/each}} diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs index fd6389aa..e7625f16 100644 --- a/templates/sheets/actors/adversary/header.hbs +++ b/templates/sheets/actors/adversary/header.hbs @@ -2,7 +2,7 @@

    -

    diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index 553ba246..05280127 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -20,7 +20,7 @@ max='{{document.system.resources.hitPoints.max}}' >
    -

    HP

    +

    {{localize "DAGGERHEART.GENERAL.HitPoints.short"}}

    @@ -37,7 +37,7 @@ max='{{document.system.resources.stress.max}}' >
    -

    Stress

    +

    {{localize "DAGGERHEART.GENERAL.stress"}}

    @@ -47,7 +47,7 @@

    {{document.system.proficiency}}

    -

    Proficiency

    +

    {{localize "DAGGERHEART.GENERAL.proficienc"}}

    @@ -83,7 +83,7 @@

    {{document.system.evasion}}

    -

    Evasion

    +

    {{localize "DAGGERHEART.GENERAL.evasion"}}

    @@ -91,7 +91,7 @@
    -

    Equipment

    +

    {{localize "DAGGERHEART.GENERAL.equipment"}}

      @@ -112,7 +112,7 @@
      -

      Loadout

      +

      {{localize "DAGGERHEART.GENERAL.loadout"}}

        @@ -132,7 +132,7 @@
        -

        Experience

        +

        {{localize "DAGGERHEART.GENERAL.experience.Single"}}

        diff --git a/templates/sheets/actors/companion/header.hbs b/templates/sheets/actors/companion/header.hbs index 27bcec5e..0704536c 100644 --- a/templates/sheets/actors/companion/header.hbs +++ b/templates/sheets/actors/companion/header.hbs @@ -5,7 +5,7 @@ type='text' name='name' value='{{document.name}}' - placeholder='Actor Name' + placeholder='{{localize "DAGGERHEART.GENERAL.actorName"}}' />
        @@ -14,7 +14,7 @@

        {{document.system.evasion}}

        -

        Evasion

        +

        {{localize "DAGGERHEART.GENERAL.evasion"}}

        @@ -29,7 +29,7 @@ max='{{document.system.resources.stress.max}}' >
        -

        Stress

        +

        {{localize "DAGGERHEART.GENERAL.stress"}}

        diff --git a/templates/sheets/global/partials/action-item.hbs b/templates/sheets/global/partials/action-item.hbs index c9c859a5..6b125e8a 100644 --- a/templates/sheets/global/partials/action-item.hbs +++ b/templates/sheets/global/partials/action-item.hbs @@ -2,12 +2,6 @@
        {{item.name}}
        - {{!--
        -
        -
        -
        -
        -
        --}}
        diff --git a/templates/sheets/global/partials/resource-section.hbs b/templates/sheets/global/partials/resource-section.hbs index ab329efc..7c52298d 100644 --- a/templates/sheets/global/partials/resource-section.hbs +++ b/templates/sheets/global/partials/resource-section.hbs @@ -20,7 +20,7 @@ {{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}} {{else}} {{formGroup systemFields.resource.fields.dieFaces value=source.system.resource.dieFaces localize=true blank=false}} - {{formGroup systemFields.resource.fields.max value=source.system.resource.max label="DAGGERHEART.ITEMS.FIELDS.resource.amount.label" localize=true}} + {{formGroup systemFields.resource.fields.max value=source.system.resource.max label="DAGGERHEART.GENERAL.amount" localize=true}} {{/if}}
        diff --git a/templates/sheets/items/weapon/attachments.hbs b/templates/sheets/items/weapon/attachments.hbs deleted file mode 100644 index e69de29b..00000000 diff --git a/templates/sheets/pseudo-documents/header.hbs b/templates/sheets/pseudo-documents/header.hbs deleted file mode 100644 index 4e240356..00000000 --- a/templates/sheets/pseudo-documents/header.hbs +++ /dev/null @@ -1,3 +0,0 @@ -
        - -
        \ No newline at end of file diff --git a/templates/ui/chat/adversary-attack-roll.hbs b/templates/ui/chat/adversary-attack-roll.hbs index 74e0d7ca..b948bd3d 100644 --- a/templates/ui/chat/adversary-attack-roll.hbs +++ b/templates/ui/chat/adversary-attack-roll.hbs @@ -41,7 +41,7 @@

        {{/if}}
        - +
    \ No newline at end of file diff --git a/templates/ui/chat/adversary-roll.hbs b/templates/ui/chat/adversary-roll.hbs index a8918062..a37f93e3 100644 --- a/templates/ui/chat/adversary-roll.hbs +++ b/templates/ui/chat/adversary-roll.hbs @@ -34,7 +34,7 @@
    - Damage + {{localize "DAGGEHEART.GENERAL.damage"}}
    diff --git a/templates/ui/chat/duality-roll.hbs b/templates/ui/chat/duality-roll.hbs index 8b44039b..5e67d3a3 100644 --- a/templates/ui/chat/duality-roll.hbs +++ b/templates/ui/chat/duality-roll.hbs @@ -148,7 +148,7 @@
    - Damage + {{localize "DAGGERHEART.GENERAL.damage"}}
    @@ -176,7 +176,17 @@ {{/if}}
    -
    {{roll.total}} {{#if (eq roll.result.duality 1)}}With Hope{{else}}{{#if (eq roll.result.duality -1)}}With Fear{{else}}Critical Success{{/if}}{{/if}}
    +
    {{roll.total}} + {{#if (eq roll.result.duality 1)}} + {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} + {{else}} + {{#if (eq roll.result.duality -1)}} + {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} + {{else}} + {{localize "DAGGERHEART.GENERAL.criticalSuccess"}} + {{/if}} + {{/if}} +
    diff --git a/templates/ui/chat/parts/damage-chat.hbs b/templates/ui/chat/parts/damage-chat.hbs index 522cdc54..91bee4e7 100644 --- a/templates/ui/chat/parts/damage-chat.hbs +++ b/templates/ui/chat/parts/damage-chat.hbs @@ -22,7 +22,7 @@
    {{#if modifierTotal}}
    {{#if (gt modifierTotal 0)}}+{{/if}}{{modifierTotal}}
    {{/if}} -
    Total: {{total}}
    +
    {{localize "DAGGERHEART.GENERAL.total"}}: {{total}}
    {{/each}}
    diff --git a/templates/ui/chat/parts/target-chat.hbs b/templates/ui/chat/parts/target-chat.hbs index b3785652..1da6cec0 100644 --- a/templates/ui/chat/parts/target-chat.hbs +++ b/templates/ui/chat/parts/target-chat.hbs @@ -1,6 +1,6 @@ {{#if (gt currentTargets.length 0)}}
    - Targets + {{localize "DAGGERHEART.GENERAL.Target.plural"}}
    @@ -9,7 +9,7 @@
    {{#if (and hasSave @root.targetSelection @root.hasHitTarget)}} - + {{/if}}
    {{#each currentTargets as |target|}} @@ -24,7 +24,6 @@
    {{#if (and ../hasSave target.hit @root.targetSelection)}} diff --git a/templates/ui/tooltip/action.hbs b/templates/ui/tooltip/action.hbs index c101ee68..21b8e4d6 100644 --- a/templates/ui/tooltip/action.hbs +++ b/templates/ui/tooltip/action.hbs @@ -67,7 +67,7 @@
    - +
    {{#if item.target.type}} {{#with (lookup @root.config.ACTIONS.targetTypes item.target.type) as | target |}} From 1e828547bbeee4532c0bda9ba17e44706629c51c Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sun, 20 Jul 2025 11:40:11 +0100 Subject: [PATCH 54/58] Apply the first downtime move before picking the second one (#383) * Downtime: allow moves to be taken individually. Fixes https://github.com/Foundryborne/daggerheart/issues/374 Some downtime moves require a roll to see how successful they are. In these cases, the player might want to see how their first move works out before they select their next one. This commit updates the downtime dialog to allow for this behaviour: - The "Take Downtime" button is enabled whenever any moves are selected. - Clicking the button only closes the dialog when all moves have been made. To keep track of this, the `nrChoices` object has been expanded to include a `taken` counter, which is increased whenever a move is taken. After making one move the selection is reset, but the number of moves displayed in the dialog header and the number of permitted selections both take the number of taken moves into account. * Fix heading in short rest chat message. Prior to this commit the heading for a short rest chat message was "long rest". * Remove unused template context. * Extract method for repeated calculation. In the downtime dialog, we need to calculate the number of selected moves in several places. This commit extracts a method to handle that, which reduces repetition and hopefully makes the code more readable. --- module/applications/dialogs/downtime.mjs | 60 +++++++++++++++--------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 4922b4ed..163af03e 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -12,17 +12,18 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV ); this.nrChoices = { shortRest: { + taken: 0, max: (shortrest ? this.moveData.shortRest.nrChoices : 0) + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].shortMoves }, longRest: { + taken: 0, max: (!shortrest ? this.moveData.longRest.nrChoices : 0) + actor.system.bonuses.rest[`${shortrest ? 'short' : 'long'}Rest`].longMoves } }; - this.nrChoices.total = { max: this.nrChoices.shortRest.max + this.nrChoices.longRest.max }; } get title() { @@ -62,50 +63,41 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV ); context.selectedActivity = this.selectedActivity; context.moveData = this.moveData; - context.nrCurrentChoices = Object.values(this.moveData).reduce((acc, category) => { - acc += Object.values(category.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); - return acc; - }, 0); + const shortRestMovesSelected = this.#nrSelectedMoves('shortRest'); + const longRestMovesSelected = this.#nrSelectedMoves('longRest'); context.nrChoices = { ...this.nrChoices, shortRest: { ...this.nrChoices.shortRest, - current: Object.values(this.moveData.shortRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + current: this.nrChoices.shortRest.taken + shortRestMovesSelected }, longRest: { ...this.nrChoices.longRest, - current: Object.values(this.moveData.longRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0) + current: this.nrChoices.longRest.taken + longRestMovesSelected } }; - context.nrChoices.total = { - ...this.nrChoices.total, - current: context.nrChoices.shortRest.current + context.nrChoices.longRest.current - }; context.shortRestMoves = this.nrChoices.shortRest.max > 0 ? this.moveData.shortRest : null; context.longRestMoves = this.nrChoices.longRest.max > 0 ? this.moveData.longRest : null; - context.disabledDowntime = context.nrChoices.total.current < context.nrChoices.total.max; + context.disabledDowntime = shortRestMovesSelected === 0 && longRestMovesSelected === 0; return context; } static selectMove(_, target) { - const nrSelected = Object.values(this.moveData[target.dataset.category].moves).reduce( - (acc, x) => acc + (x.selected ?? 0), - 0 - ); + const { category, move } = target.dataset; - if (nrSelected === this.nrChoices[target.dataset.category].max) { + const nrSelected = this.#nrSelectedMoves(category); + + if (nrSelected + this.nrChoices[category].taken >= this.nrChoices[category].max) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves')); return; } - const move = target.dataset.move; - this.moveData[target.dataset.category].moves[move].selected = this.moveData[target.dataset.category].moves[move] - .selected - ? this.moveData[target.dataset.category].moves[move].selected + 1 + this.moveData[category].moves[move].selected = this.moveData[category].moves[move].selected + ? this.moveData[category].moves[move].selected + 1 : 1; this.render(); @@ -150,7 +142,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV content: await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/ui/chat/downtime.hbs', { - title: `${this.actor.name} - ${game.i18n.localize(`DAGGERHEART.APPLICATIONS.Downtime.${this.shortRest ? 'shortRest' : 'longRest'}.title`)}`, + title: `${this.actor.name} - ${game.i18n.localize(`DAGGERHEART.APPLICATIONS.Downtime.${this.shortrest ? 'shortRest' : 'longRest'}.title`)}`, moves: moves } ) @@ -158,11 +150,33 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV cls.create(msg.toObject()); - this.close(); + // Reset selection and update number of taken moves + for (const [catName, category] of Object.entries(this.moveData)) { + for (const move of Object.values(category.moves)) { + if (move.selected > 0) { + this.nrChoices[catName].taken += move.selected; + move.selected = 0; + } + } + } + + // We can close the window when all moves are taken + if ( + this.nrChoices.shortRest.taken >= this.nrChoices.shortRest.max && + this.nrChoices.longRest.taken >= this.nrChoices.longRest.max + ) { + this.close(); + } else { + this.render(); + } } static async updateData(event, element, formData) { this.customActivity = foundry.utils.mergeObject(this.customActivity, formData.object); this.render(); } + + #nrSelectedMoves(category) { + return Object.values(this.moveData[category].moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); + } } From 867947c2c502c62757f4160d516bcb6ab9723991 Mon Sep 17 00:00:00 2001 From: George Brocklehurst Date: Sun, 20 Jul 2025 11:40:33 +0100 Subject: [PATCH 55/58] Move downtime move tooltip. (#385) This commit moves the downtown dialog's move tooltip to the right of the move. Previously it was above the move, which would obscure other items in the list and the number of already selected moves in the header. --- module/documents/tooltipManager.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index e622059d..005f77bd 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -40,7 +40,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti this.tooltip.innerHTML = html; options.direction = this._determineItemTooltipDirection( element, - this.constructor.TOOLTIP_DIRECTIONS.UP + this.constructor.TOOLTIP_DIRECTIONS.RIGHT ); } From 42a705a870d16c2515eb51c128b200717e28e73e Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:56:22 +0200 Subject: [PATCH 56/58] [Feature] Beastform Types (#372) * Temp * Finished Evolved * Fixed hybrid * Changed generalConfig.tiers to be number based * Weaponhandling while in beastform * Added unarmed strike in sidebar * Added DamageEnricher * Added effect enricher * Corrected downtime buttons and actions * Added BeastformTooltip * Split the BeastformDialog into parts with tabs * Added temp beastform features * rollData change * Improvement * character.getRollData cleanup --- daggerheart.mjs | 40 +-- lang/en.json | 77 ++++- .../applications/dialogs/beastformDialog.mjs | 262 +++++++++++++++++- module/applications/dialogs/damageDialog.mjs | 2 +- .../dialogs/damageReductionDialog.mjs | 2 +- .../sheets-configs/action-config.mjs | 2 +- .../sheets-configs/environment-settings.mjs | 4 +- .../applications/sheets/actors/adversary.mjs | 2 +- .../applications/sheets/actors/character.mjs | 6 + .../sheets/api/application-mixin.mjs | 189 +++++++------ module/applications/sheets/api/base-actor.mjs | 6 +- module/applications/sheets/api/base-item.mjs | 67 +++-- module/applications/sheets/items/armor.mjs | 2 +- .../applications/sheets/items/beastform.mjs | 72 ++++- module/applications/sheets/items/class.mjs | 2 +- module/applications/sheets/items/weapon.mjs | 2 +- module/applications/ui/chatLog.mjs | 26 +- module/applications/ui/hotbar.mjs | 6 +- module/config/actorConfig.mjs | 6 + module/config/generalConfig.mjs | 54 ++-- module/config/itemConfig.mjs | 15 + module/data/action/actionDice.mjs | 4 +- module/data/action/baseAction.mjs | 6 +- module/data/action/beastformAction.mjs | 57 +++- module/data/action/damageAction.mjs | 21 +- module/data/action/healingAction.mjs | 12 +- module/data/activeEffect/beastformEffect.mjs | 7 + module/data/actor/adversary.mjs | 7 +- module/data/actor/character.mjs | 74 ++++- module/data/actor/environment.mjs | 5 +- module/data/item/beastform.mjs | 56 +++- module/data/item/class.mjs | 2 +- module/dice/d20Roll.mjs | 5 +- module/dice/damageRoll.mjs | 38 +-- module/dice/dhRoll.mjs | 11 +- module/dice/dualityRoll.mjs | 28 +- module/documents/actor.mjs | 42 +-- module/documents/token.mjs | 18 +- module/documents/tooltipManager.mjs | 33 ++- module/enrichers/DamageEnricher.mjs | 80 ++++++ module/enrichers/DualityRollEnricher.mjs | 2 +- module/enrichers/EffectEnricher.mjs | 19 ++ module/enrichers/_module.mjs | 45 ++- module/helpers/handlebarsHelper.mjs | 2 +- module/helpers/utils.mjs | 83 +----- module/systemRegistration/handlebars.mjs | 8 +- ...eastform_Agile_Scout_6tr99y6wHaJJYy3J.json | 160 +++++++++++ ...orm_Household_Friend_uxBugKULjn7O1KQc.json | 166 +++++++++++ ...form_Legendary_Beast_mERwC7aMDoIKfZTf.json | 154 ++++++++++ ...tform_Mighty_Strider_LF68kGAcOTZQ81GB.json | 166 +++++++++++ ...stform_Mythic_Hybrid_VI1DyowECDCDdsC1.json | 148 ++++++++++ .../feature_Agile_sef9mwD2eRLZ64oV.json | 34 +++ .../feature_Carrier_YSolAjtv6Sfnai98.json | 34 +++ .../feature_Companion_0tlnxIxlIw2hl1UE.json | 34 +++ .../feature_Evolved_MG21w4u5wXSGZ5WB.json | 34 +++ .../feature_Fragile_9ryNrYWjNtOT6DXN.json | 34 +++ .../feature_Trample_P6tWFIZzXWyekw6r.json | 34 +++ ...s_Beastform_Features_uU8bIoZvXge0rLaU.json | 23 ++ .../dialog/beastform/beastform-container.less | 46 --- styles/less/dialog/beastform/sheet.less | 203 +++++++++++++- styles/less/dialog/index.less | 1 - styles/less/sheets/index.less | 1 + styles/less/sheets/items/beastform.less | 9 + styles/less/ui/chat/chat.less | 8 +- styles/less/ui/chat/sheet.less | 21 ++ styles/less/ux/tooltip/tooltip.less | 16 ++ system.json | 11 +- templates/dialogs/beastform/advanced.hbs | 73 +++++ templates/dialogs/beastform/beastformTier.hbs | 8 + templates/dialogs/beastform/footer.hbs | 3 + templates/dialogs/beastform/tabs.hbs | 11 + templates/dialogs/beastformDialog.hbs | 18 -- .../adversary-settings/details.hbs | 2 +- templates/sheets/actors/adversary/header.hbs | 2 +- templates/sheets/actors/adversary/sidebar.hbs | 6 +- templates/sheets/actors/character/sidebar.hbs | 7 +- .../global/partials/inventory-item-V2.hbs | 28 +- .../sheets/global/partials/inventory-item.hbs | 207 ++++++++++++++ templates/sheets/items/beastform/advanced.hbs | 29 ++ templates/sheets/items/beastform/settings.hbs | 18 +- templates/ui/chat/downtime.hbs | 12 +- templates/ui/tooltip/action.hbs | 2 +- templates/ui/tooltip/adversary.hbs | 4 +- templates/ui/tooltip/armor.hbs | 2 +- templates/ui/tooltip/attack.hbs | 29 ++ templates/ui/tooltip/beastform.hbs | 8 + templates/ui/tooltip/consumable.hbs | 2 +- templates/ui/tooltip/domainCard.hbs | 2 +- templates/ui/tooltip/feature.hbs | 2 +- templates/ui/tooltip/miscellaneous.hbs | 2 +- templates/ui/tooltip/parts/tooltipChips.hbs | 6 + templates/ui/tooltip/parts/tooltipTags.hbs | 2 +- templates/ui/tooltip/weapon.hbs | 2 +- 93 files changed, 2795 insertions(+), 538 deletions(-) create mode 100644 module/enrichers/DamageEnricher.mjs create mode 100644 module/enrichers/EffectEnricher.mjs create mode 100644 src/packs/beastforms/beastform_Agile_Scout_6tr99y6wHaJJYy3J.json create mode 100644 src/packs/beastforms/beastform_Household_Friend_uxBugKULjn7O1KQc.json create mode 100644 src/packs/beastforms/beastform_Legendary_Beast_mERwC7aMDoIKfZTf.json create mode 100644 src/packs/beastforms/beastform_Mighty_Strider_LF68kGAcOTZQ81GB.json create mode 100644 src/packs/beastforms/beastform_Mythic_Hybrid_VI1DyowECDCDdsC1.json create mode 100644 src/packs/beastforms/feature_Agile_sef9mwD2eRLZ64oV.json create mode 100644 src/packs/beastforms/feature_Carrier_YSolAjtv6Sfnai98.json create mode 100644 src/packs/beastforms/feature_Companion_0tlnxIxlIw2hl1UE.json create mode 100644 src/packs/beastforms/feature_Evolved_MG21w4u5wXSGZ5WB.json create mode 100644 src/packs/beastforms/feature_Fragile_9ryNrYWjNtOT6DXN.json create mode 100644 src/packs/beastforms/feature_Trample_P6tWFIZzXWyekw6r.json create mode 100644 src/packs/beastforms/folders_Beastform_Features_uU8bIoZvXge0rLaU.json delete mode 100644 styles/less/dialog/beastform/beastform-container.less create mode 100644 styles/less/sheets/items/beastform.less create mode 100644 templates/dialogs/beastform/advanced.hbs create mode 100644 templates/dialogs/beastform/beastformTier.hbs create mode 100644 templates/dialogs/beastform/footer.hbs create mode 100644 templates/dialogs/beastform/tabs.hbs delete mode 100644 templates/dialogs/beastformDialog.hbs create mode 100644 templates/sheets/global/partials/inventory-item.hbs create mode 100644 templates/sheets/items/beastform/advanced.hbs create mode 100644 templates/ui/tooltip/attack.hbs create mode 100644 templates/ui/tooltip/beastform.hbs create mode 100644 templates/ui/tooltip/parts/tooltipChips.hbs diff --git a/daggerheart.mjs b/daggerheart.mjs index 9239d338..872da5f3 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -3,7 +3,7 @@ import * as applications from './module/applications/_module.mjs'; import * as models from './module/data/_module.mjs'; import * as documents from './module/documents/_module.mjs'; import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs'; -import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs'; +import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.mjs'; import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs'; import { NarrativeCountdowns } from './module/applications/ui/countdowns.mjs'; import { DualityRollColor } from './module/data/settings/Appearance.mjs'; @@ -20,6 +20,7 @@ import { placeables } from './module/canvas/_module.mjs'; import { registerRollDiceHooks } from './module/dice/dhRoll.mjs'; import { registerDHActorHooks } from './module/documents/actor.mjs'; import './node_modules/@yaireo/tagify/dist/tagify.css'; +import { renderDamageButton } from './module/enrichers/DamageEnricher.mjs'; Hooks.once('init', () => { CONFIG.DH = SYSTEM; @@ -29,18 +30,7 @@ Hooks.once('init', () => { documents }; - CONFIG.TextEditor.enrichers.push( - ...[ - { - pattern: /\[\[\/dr\s?(.*?)\]\]/g, - enricher: DhDualityRollEnricher - }, - { - pattern: /^@Template\[(.*)\]$/g, - enricher: DhTemplateEnricher - } - ] - ); + CONFIG.TextEditor.enrichers.push(...enricherConfig); CONFIG.statusEffects = [ ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), @@ -178,33 +168,15 @@ Hooks.on('ready', () => { Hooks.once('dicesoniceready', () => {}); Hooks.on('renderChatMessageHTML', (_, element) => { - element - .querySelectorAll('.duality-roll-button') - .forEach(element => element.addEventListener('click', renderDualityButton)); - - element - .querySelectorAll('.measured-template-button') - .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); + enricherRenderSetup(element); }); Hooks.on('renderJournalEntryPageProseMirrorSheet', (_, element) => { - element - .querySelectorAll('.duality-roll-button') - .forEach(element => element.addEventListener('click', renderDualityButton)); - - element - .querySelectorAll('.measured-template-button') - .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); + enricherRenderSetup(element); }); Hooks.on('renderHandlebarsApplication', (_, element) => { - element - .querySelectorAll('.duality-roll-button') - .forEach(element => element.addEventListener('click', renderDualityButton)); - - element - .querySelectorAll('.measured-template-button') - .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); + enricherRenderSetup(element); }); Hooks.on('chatMessage', (_, message) => { diff --git a/lang/en.json b/lang/en.json index 4d3927bc..ae6ccdf4 100755 --- a/lang/en.json +++ b/lang/en.json @@ -13,6 +13,9 @@ "armor": "Armor", "beastform": "Beastform" }, + "ActiveEffect": { + "beastform": "Beastform" + }, "Actor": { "character": "Character", "companion": "Companion", @@ -110,8 +113,25 @@ "horderHp": "Horde/HP" }, "Character": { + "advantageSources": { + "label": "Advantage Sources", + "hint": "Add single words or short text as reminders and hints of what a character has advantage on." + }, "age": "Age", "companionFeatures": "Companion Features", + "contextMenu": { + "consume": "Consume Item", + "equip": "Equip", + "sendToChat": "Send To Chat", + "toLoadout": "Send to Loadout", + "toVault": "Send to Vault", + "unequip": "Unequip", + "useItem": "Use Item" + }, + "disadvantageSources": { + "label": "Disadvantage Sources", + "hint": "Add single words or short text as reminders and hints of what a character has disadvantage on." + }, "faith": "Faith", "levelUp": "You can level up", "pronouns": "Pronouns", @@ -572,6 +592,11 @@ "description": "You reduce incoming magic damage by your Armor Score before applying it to your damage thresholds." } }, + "BeastformType": { + "normal": "Normal", + "evolved": "Evolved", + "hybrid": "Hybrid" + }, "Burden": { "oneHanded": "One-Handed", "twoHanded": "Two-Handed" @@ -1019,6 +1044,7 @@ }, "Advantage": { "full": "Advantage", + "plural": "Advantages", "short": "Adv" }, "Adversary": { @@ -1202,6 +1228,11 @@ "hint": "The cost in stress you can pay to reduce minor damage to none." } } + }, + "attack": { + "damage": { + "value": { "label": "Base Attack: Damage" } + } } }, "Tabs": { @@ -1235,14 +1266,19 @@ "recovery": "Recovery", "setup": "Setup", "equipment": "Equipment", - "attachments": "Attachments" - }, - "Tiers": { - "singular": "Tier", + "attachments": "Attachments", + "advanced": "Advanced", "tier1": "Tier 1", "tier2": "Tier 2", "tier3": "Tier 3", - "tier4": "Tier 4" + "tier4": "tier 4" + }, + "Tiers": { + "singular": "Tier", + "1": "Tier 1", + "2": "Tier 2", + "3": "Tier 3", + "4": "Tier 4" }, "Trait": { "single": "Trait", @@ -1278,7 +1314,7 @@ "features": "Features", "formula": "Formula", "healing": "Healing", - "hitPoints": { + "HitPoints": { "single": "Hit Point", "plural": "Hit Points", "short": "HP" @@ -1318,6 +1354,8 @@ "total": "Total", "true": "True", "type": "Type", + "unarmed": "Unarmed", + "unarmedStrike": "Unarmed Strike", "unarmored": "Unarmored", "use": "Use", "used": "Used", @@ -1351,7 +1389,9 @@ }, "Beastform": { "FIELDS": { + "beastformType": { "label": "Beastform Type" }, "tier": { "label": "Tier" }, + "mainTrait": { "label": "Main Trait" }, "examples": { "label": "Examples" }, "advantageOn": { "label": "Gain Advantage On" }, "tokenImg": { "label": "Token Image" }, @@ -1360,12 +1400,28 @@ "placeholder": "Using character dimensions", "height": { "label": "Height" }, "width": { "label": "Width" } + }, + "evolved": { + "maximumTier": { "label": "Maximum Tier" }, + "mainTraitBonus": { "label": "Main Trait Bonus" } + }, + "hybrid": { + "beastformOptions": { "label": "Nr Beastforms" }, + "advantages": { "label": "Nr Advantages" }, + "features": { "label": "Nr Features" } } }, + "attackName": "Beast Attack", + "beastformEffect": "Beastform Transformation", "dialogTitle": "Beastform Selection", "tokenTitle": "Beastform Token", "transform": "Transform", - "beastformEffect": "Beastform Transformation" + "evolve": "Evolve", + "evolvedFeatureTitle": "Evolved", + "evolvedDrag": "Drag a form here to evolve it.", + "hybridize": "Hybridize", + "hybridizeFeatureTitle": "Hybrid Features", + "hybridizeDrag": "Drag a form here to hybridize it." }, "Class": { "hopeFeatures": "Hope Features", @@ -1609,7 +1665,11 @@ "featureNotSecondary": "This feature is used as something else than a Secondary feature and cannot be used here.", "featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.", "featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.", - "featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here." + "featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here.", + "beastformMissingEffect": "The Beastform is missing a Beastform Effect. Cannot be used.", + "beastformToManyAdvantages": "You cannot select any more advantages.", + "beastformToManyFeatures": "You cannot select any more features.", + "beastformEquipWeapon": "You cannot use weapons while in a Beastform." }, "Tooltip": { "disableEffect": "Disable Effect", @@ -1624,6 +1684,7 @@ "sendToLoadout": "Send to Loadout", "makeDeathMove": "Make a Death Move", "rangeAndTarget": "Range & Target", + "dragApplyEffect": "Drag effect to apply it to an actor", "appliedEvenIfSuccessful": "Applied even if save succeeded" } } diff --git a/module/applications/dialogs/beastformDialog.mjs b/module/applications/dialogs/beastformDialog.mjs index 367311b0..1d6725ad 100644 --- a/module/applications/dialogs/beastformDialog.mjs +++ b/module/applications/dialogs/beastformDialog.mjs @@ -6,6 +6,10 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat this.configData = configData; this.selected = null; + this.evolved = { form: null }; + this.hybrid = { forms: {}, advantages: {}, features: {} }; + + this._dragDrop = this._createDragDropHandlers(); } static DEFAULT_OPTIONS = { @@ -17,13 +21,16 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat }, actions: { selectBeastform: this.selectBeastform, + toggleHybridFeature: this.toggleHybridFeature, + toggleHybridAdvantage: this.toggleHybridAdvantage, submitBeastform: this.submitBeastform }, form: { handler: this.updateBeastform, submitOnChange: true, submitOnClose: false - } + }, + dragDrop: [{ dragSelector: '.beastform-container', dropSelector: '.advanced-form-container' }] }; get title() { @@ -32,36 +39,217 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat /** @override */ static PARTS = { - beastform: { - template: 'systems/daggerheart/templates/dialogs/beastformDialog.hbs' + tabs: { template: 'systems/daggerheart/templates/dialogs/beastform/tabs.hbs' }, + beastformTier: { template: 'systems/daggerheart/templates/dialogs/beastform/beastformTier.hbs' }, + advanced: { template: 'systems/daggerheart/templates/dialogs/beastform/advanced.hbs' }, + footer: { template: 'systems/daggerheart/templates/dialogs/beastform/footer.hbs' } + }; + + /** @inheritdoc */ + static TABS = { + primary: { + tabs: [{ id: '1' }, { id: '2' }, { id: '3' }, { id: '4' }], + initial: '1', + labelPrefix: 'DAGGERHEART.GENERAL.Tiers' } }; + changeTab(tab, group, options) { + super.changeTab(tab, group, options); + + this.render(); + } + + _createDragDropHandlers() { + return this.options.dragDrop.map(d => { + d.callbacks = { + dragstart: this._onDragStart.bind(this), + drop: this._onDrop.bind(this) + }; + return new foundry.applications.ux.DragDrop.implementation(d); + }); + } + + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + this._dragDrop.forEach(d => d.bind(htmlElement)); + } + async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.beastformTiers = game.items.reduce((acc, x) => { - const tier = CONFIG.DH.GENERAL.tiers[x.system.tier]; - if (x.type !== 'beastform' || tier.value > this.configData.tierLimit) return acc; + context.selected = this.selected; + context.selectedBeastformEffect = this.selected?.effects?.find?.(x => x.type === 'beastform'); - if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} }; - acc[tier.value].values[x.uuid] = { selected: this.selected == x.uuid, value: x }; + context.evolved = this.evolved; + context.hybridForms = Object.keys(this.hybrid.forms).reduce((acc, formKey) => { + if (!this.hybrid.forms[formKey]) { + acc[formKey] = null; + } else { + const data = this.hybrid.forms[formKey].toObject(); + acc[formKey] = { + ...data, + system: { + ...data.system, + features: this.hybrid.forms[formKey].system.features.map(feature => ({ + ...feature.toObject(), + uuid: feature.uuid, + selected: Boolean(this.hybrid.features?.[formKey]?.[feature.uuid]) + })), + advantageOn: Object.keys(data.system.advantageOn).reduce((acc, key) => { + acc[key] = { + ...data.system.advantageOn[key], + selected: Boolean(this.hybrid.advantages?.[formKey]?.[key]) + }; + return acc; + }, {}) + } + }; + } return acc; - }, {}); // Also get from compendium when added - context.canSubmit = this.selected; + }, {}); + + const maximumDragTier = Math.max( + this.selected?.system?.evolved?.maximumTier ?? 0, + this.selected?.system?.hybrid?.maximumTier ?? 0 + ); + + const compendiumBeastforms = await game.packs.get(`daggerheart.beastforms`)?.getDocuments(); + const beastformTiers = [...(compendiumBeastforms ? compendiumBeastforms : []), ...game.items].reduce( + (acc, x) => { + const tier = CONFIG.DH.GENERAL.tiers[x.system.tier]; + if (x.type !== 'beastform' || tier.id > this.configData.tierLimit) return acc; + + if (!acc[tier.id]) acc[tier.id] = { label: game.i18n.localize(tier.label), values: {} }; + + acc[tier.id].values[x.uuid] = { + selected: this.selected?.uuid == x.uuid, + value: x, + draggable: + !['evolved', 'hybrid'].includes(x.system.beastformType) && maximumDragTier + ? x.system.tier <= maximumDragTier + : false + }; + + return acc; + }, + {} + ); + + context.tier = beastformTiers[this.tabGroups.primary]; + context.tierKey = this.tabGroups.primary; + + context.canSubmit = this.canSubmit(); return context; } + canSubmit() { + if (this.selected) { + switch (this.selected.system.beastformType) { + case 'normal': + return true; + case 'evolved': + return this.evolved.form; + case 'hybrid': + const selectedAdvantages = Object.values(this.hybrid.advantages).reduce( + (acc, form) => acc + Object.values(form).length, + 0 + ); + const selectedFeatures = Object.values(this.hybrid.features).reduce( + (acc, form) => acc + Object.values(form).length, + 0 + ); + + const advantagesSelected = selectedAdvantages === this.selected.system.hybrid.advantages; + const featuresSelected = selectedFeatures === this.selected.system.hybrid.features; + return advantagesSelected && featuresSelected; + } + } + + return false; + } + static updateBeastform(event, _, formData) { this.selected = foundry.utils.mergeObject(this.selected, formData.object); this.render(); } - static selectBeastform(_, target) { - this.selected = this.selected === target.dataset.uuid ? null : target.dataset.uuid; + static async selectBeastform(_, target) { + this.element.querySelectorAll('.beastform-container ').forEach(element => { + if (element.dataset.uuid === target.dataset.uuid && this.selected?.uuid !== target.dataset.uuid) { + element.classList.remove('inactive'); + } else { + element.classList.add('inactive'); + } + }); + + const uuid = this.selected?.uuid === target.dataset.uuid ? null : target.dataset.uuid; + this.selected = uuid ? await foundry.utils.fromUuid(uuid) : null; + + if (this.selected) { + if (this.selected.system.beastformType !== 'evolved') this.evolved.form = null; + if (this.selected.system.beastformType !== 'hybrid') { + this.hybrid.forms = {}; + this.hybrid.advantages = {}; + this.hybrid.features = {}; + } else { + this.hybrid.forms = [...Array(this.selected.system.hybrid.beastformOptions).keys()].reduce((acc, _) => { + acc[foundry.utils.randomID()] = null; + return acc; + }, {}); + } + } + + this.render(); + } + + static toggleHybridFeature(_, button) { + const current = this.hybrid.features[button.dataset.form]; + if (!current) this.hybrid.features[button.dataset.form] = {}; + + if (this.hybrid.features[button.dataset.form][button.id]) + delete this.hybrid.features[button.dataset.form][button.id]; + else { + const currentFeatures = Object.values(this.hybrid.features).reduce( + (acc, form) => acc + Object.values(form).length, + 0 + ); + if (currentFeatures === this.selected.system.hybrid.features) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.beastformToManyFeatures')); + return; + } + + const feature = this.hybrid.forms[button.dataset.form].system.features.find(x => x.uuid === button.id); + this.hybrid.features[button.dataset.form][button.id] = feature; + } + + this.render(); + } + + static toggleHybridAdvantage(_, button) { + const current = this.hybrid.advantages[button.dataset.form]; + if (!current) this.hybrid.advantages[button.dataset.form] = {}; + + if (this.hybrid.advantages[button.dataset.form][button.id]) + delete this.hybrid.advantages[button.dataset.form][button.id]; + else { + const currentAdvantages = Object.values(this.hybrid.advantages).reduce( + (acc, form) => acc + Object.values(form).length, + 0 + ); + if (currentAdvantages === this.selected.system.hybrid.advantages) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.beastformToManyAdvantages')); + return; + } + + const advantage = this.hybrid.forms[button.dataset.form].system.advantageOn[button.id]; + this.hybrid.advantages[button.dataset.form][button.id] = advantage; + } + this.render(); } @@ -71,14 +259,60 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat /** @override */ _onClose(options = {}) { - if (!options.submitted) this.config = false; + if (!options.submitted) this.selected = null; } static async configure(configData) { return new Promise(resolve => { const app = new this(configData); - app.addEventListener('close', () => resolve(app.selected), { once: true }); + app.addEventListener( + 'close', + () => resolve({ selected: app.selected, evolved: app.evolved, hybrid: app.hybrid }), + { once: true } + ); app.render({ force: true }); }); } + + async _onDragStart(event) { + const target = event.currentTarget; + const abort = () => event.preventDefault(); + if (!this.selected) abort(); + + const draggedForm = await foundry.utils.fromUuid(target.dataset.uuid); + if (['evolved', 'hybrid'].includes(draggedForm.system.beastformType)) abort(); + + if (this.selected.system.beastformType === 'evolved') { + if (draggedForm.system.tier > this.selected.system.evolved.maximumTier) abort(); + } + if (this.selected.system.beastformType === 'hybrid') { + if (draggedForm.system.tier > this.selected.system.hybrid.maximumTier) abort(); + } + + event.dataTransfer.setData('text/plain', JSON.stringify(target.dataset)); + event.dataTransfer.setDragImage(target, 60, 0); + } + + async _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.getDragEventData(event); + const item = await fromUuid(data.uuid); + if (!item) return; + + if (event.target.closest('.advanced-form-container.evolved')) { + this.evolved.form = item; + } else { + const hybridContainer = event.target.closest('.advanced-form-container.hybridized'); + if (hybridContainer) { + const existingId = Object.keys(this.hybrid.forms).find( + key => this.hybrid.forms[key]?.uuid === item.uuid + ); + if (existingId) this.hybrid.forms[existingId] = null; + + this.hybrid.forms[hybridContainer.id] = item; + } + } + + this.render(); + } } diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 1b61b96d..78452054 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -61,7 +61,7 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application static updateRollConfiguration(_event, _, formData) { const { ...rest } = foundry.utils.expandObject(formData.object); - foundry.utils.mergeObject(this.config.roll, rest.roll) + foundry.utils.mergeObject(this.config.roll, rest.roll); this.config.selectedRollMode = rest.selectedRollMode; this.render(); diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 658cef96..3e3bde44 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -10,7 +10,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.reject = reject; this.actor = actor; this.damage = damage; - + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); const maxArmorMarks = canApplyArmor ? Math.min( diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index db3c4d27..3f915e41 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -114,7 +114,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers; context.tierOptions = [ - { key: 1, label: game.i18n.localize('DAGGERHEART.GENERAL.Tiers.tier1') }, + { key: 1, label: game.i18n.localize('DAGGERHEART.GENERAL.Tiers.1') }, ...Object.values(settingsTiers).map(x => ({ key: x.tier, label: x.name })) ]; diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index c249d6d5..7a91b272 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -70,9 +70,9 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { } /** - * + * * @type {ApplicationClickAction} - * @returns + * @returns */ static async #deleteAdversary(_event, target) { const doc = getDocFromElement(target); diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index e6508695..f6324881 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -8,7 +8,7 @@ export default class AdversarySheet extends DHBaseActorSheet { position: { width: 660, height: 766 }, window: { resizable: true }, actions: { - reactionRoll: AdversarySheet.#reactionRoll, + reactionRoll: AdversarySheet.#reactionRoll }, window: { resizable: true diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 8f157c96..4fe4b5e3 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -619,6 +619,12 @@ export default class CharacterSheet extends DHBaseActorSheet { await item.update({ 'system.equipped': true }); break; case 'weapon': + if (this.document.effects.find(x => x.type === 'beastform')) { + return ui.notifications.warn( + game.i18n.localize('DAGGERHEART.UI.Notifications.beastformEquipWeapon') + ); + } + await this.document.system.constructor.unequipBeforeEquip.bind(this.document.system)(item); await item.update({ 'system.equipped': true }); diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index b343eb62..65a43123 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -84,24 +84,26 @@ export default function DHApplicationMixin(Base) { useItem: DHSheetV2.#useItem, useAction: DHSheetV2.#useAction, toggleEffect: DHSheetV2.#toggleEffect, - toggleExtended: DHSheetV2.#toggleExtended, + toggleExtended: DHSheetV2.#toggleExtended }, - contextMenus: [{ - handler: DHSheetV2.#getEffectContextOptions, - selector: '[data-item-uuid][data-type="effect"]', - options: { - parentClassHooks: false, - fixed: true + contextMenus: [ + { + handler: DHSheetV2.#getEffectContextOptions, + selector: '[data-item-uuid][data-type="effect"]', + options: { + parentClassHooks: false, + fixed: true + } }, - }, - { - handler: DHSheetV2.#getActionContextOptions, - selector: '[data-item-uuid][data-type="action"]', - options: { - parentClassHooks: false, - fixed: true + { + handler: DHSheetV2.#getActionContextOptions, + selector: '[data-item-uuid][data-type="action"]', + options: { + parentClassHooks: false, + fixed: true + } } - }], + ], dragDrop: [], tagifyConfigs: [] }; @@ -132,13 +134,13 @@ export default function DHApplicationMixin(Base) { /**@inheritdoc */ _syncPartState(partId, newElement, priorElement, state) { super._syncPartState(partId, newElement, priorElement, state); - for (const el of priorElement.querySelectorAll(".extensible.extended")) { + for (const el of priorElement.querySelectorAll('.extensible.extended')) { const { actionId, itemUuid } = el.parentElement.dataset; const selector = `${actionId ? `[data-action-id="${actionId}"]` : `[data-item-uuid="${itemUuid}"]`} .extensible`; const newExtensible = newElement.querySelector(selector); if (!newExtensible) continue; - newExtensible.classList.add("extended"); + newExtensible.classList.add('extended'); const descriptionElement = newExtensible.querySelector('.invetory-description'); if (descriptionElement) { this.#prepareInventoryDescription(newExtensible, descriptionElement); @@ -209,14 +211,14 @@ export default function DHApplicationMixin(Base) { * @param {DragEvent} event * @protected */ - _onDragStart(event) { } + _onDragStart(event) {} /** * Handle drop event. * @param {DragEvent} event * @protected */ - _onDrop(event) { } + _onDrop(event) {} /* -------------------------------------------- */ /* Context Menu */ @@ -251,7 +253,7 @@ export default function DHApplicationMixin(Base) { icon: 'fa-regular fa-lightbulb', condition: target => getDocFromElement(target).disabled, callback: target => getDocFromElement(target).update({ disabled: false }) - }, + } ].map(option => ({ ...option, name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, @@ -269,7 +271,7 @@ export default function DHApplicationMixin(Base) { */ static #getActionContextOptions() { /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ - const getAction = (target) => { + const getAction = target => { const { actionId } = target.closest('[data-action-id]').dataset; const { actions, attack } = this.document.system; return attack?.id === actionId ? attack : actions?.find(a => a.id === actionId); @@ -279,30 +281,31 @@ export default function DHApplicationMixin(Base) { { name: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', icon: 'fa-solid fa-burst', - condition: this.document instanceof foundry.documents.Actor || + condition: + this.document instanceof foundry.documents.Actor || (this.document instanceof foundry.documents.Item && this.document.parent), - callback: (target, event) => getAction(target).use(event), + callback: (target, event) => getAction(target).use(event) }, { name: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', icon: 'fa-solid fa-message', - callback: (target) => getAction(target).toChat(this.document.id), + callback: target => getAction(target).toChat(this.document.id) }, { name: 'CONTROLS.CommonEdit', icon: 'fa-solid fa-pen-to-square', - callback: (target) => new DHActionConfig(getAction(target)).render({ force: true }) + callback: target => new DHActionConfig(getAction(target)).render({ force: true }) }, { name: 'CONTROLS.CommonDelete', icon: 'fa-solid fa-trash', - condition: (target) => { + condition: target => { const { actionId } = target.closest('[data-action-id]').dataset; const { attack } = this.document.system; - return attack?.id !== actionId + return attack?.id !== actionId; }, - callback: async (target) => { - const action = getAction(target) + callback: async target => { + const action = getAction(target); const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { @@ -310,12 +313,14 @@ export default function DHApplicationMixin(Base) { name: action.name }) }, - content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: action.name }) + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { + name: action.name + }) }); if (!confirmed) return; return this.document.update({ - 'system.actions': this.document.system.actions.filter((a) => a.id !== action.id) + 'system.actions': this.document.system.actions.filter(a => a.id !== action.id) }); } } @@ -337,35 +342,38 @@ export default function DHApplicationMixin(Base) { name: 'CONTROLS.CommonEdit', icon: 'fa-solid fa-pen-to-square', callback: target => getDocFromElement(target).sheet.render({ force: true }) - }, + } ]; - if (usable) options.unshift({ - name: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', - icon: 'fa-solid fa-burst', - callback: (target, event) => getDocFromElement(target).use(event), - }); + if (usable) + options.unshift({ + name: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', + icon: 'fa-solid fa-burst', + callback: (target, event) => getDocFromElement(target).use(event) + }); - if (toChat) options.unshift({ - name: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', - icon: 'fa-solid fa-message', - callback: (target) => getDocFromElement(target).toChat(this.document.id), - }); + if (toChat) + options.unshift({ + name: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', + icon: 'fa-solid fa-message', + callback: target => getDocFromElement(target).toChat(this.document.id) + }); - if (deletable) options.push({ - name: 'CONTROLS.CommonDelete', - icon: 'fa-solid fa-trash', - callback: (target, event) => { - const doc = getDocFromElement(target); - if (event.shiftKey) return doc.delete(); - else return doc.deleteDialog(); - } - }) + if (deletable) + options.push({ + name: 'CONTROLS.CommonDelete', + icon: 'fa-solid fa-trash', + callback: (target, event) => { + const doc = getDocFromElement(target); + if (event.shiftKey) return doc.delete(); + else return doc.deleteDialog(); + } + }); return options.map(option => ({ ...option, icon: `` - })) + })); } /* -------------------------------------------- */ @@ -400,17 +408,20 @@ export default function DHApplicationMixin(Base) { const doc = itemUuid ? getDocFromElement(extensibleElement) : this.document.system.attack?.id === actionId - ? this.document.system.attack - : this.document.system.actions?.find(a => a.id === actionId); + ? this.document.system.attack + : this.document.system.actions?.find(a => a.id === actionId); if (!doc) return; const description = doc.system?.description ?? doc.description; const isAction = !!actionId; - descriptionElement.innerHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(description, { - relativeTo: isAction ? doc.parent : doc, - rollData: doc.getRollData?.(), - secrets: isAction ? doc.parent.isOwner : doc.isOwner - }); + descriptionElement.innerHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML( + description, + { + relativeTo: isAction ? doc.parent : doc, + rollData: doc.getRollData?.(), + secrets: isAction ? doc.parent.isOwner : doc.isOwner + } + ); } /* -------------------------------------------- */ @@ -427,26 +438,28 @@ export default function DHApplicationMixin(Base) { const parent = parentIsItem && documentClass === 'Item' ? null : this.document; if (type === 'action') { - const { type: actionType } = await foundry.applications.api.DialogV2.input({ - window: { title: 'Select Action Type' }, - content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } - ), - ok: { - label: game.i18n.format('DOCUMENT.Create', { - type: game.i18n.localize('DAGGERHEART.GENERAL.Action.single') - }), - } - }) ?? {}; + const { type: actionType } = + (await foundry.applications.api.DialogV2.input({ + window: { title: 'Select Action Type' }, + content: await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } + ), + ok: { + label: game.i18n.format('DOCUMENT.Create', { + type: game.i18n.localize('DAGGERHEART.GENERAL.Action.single') + }) + } + })) ?? {}; if (!actionType) return; - const cls = game.system.api.models.actions.actionsTypes[actionType] - const action = new cls({ - _id: foundry.utils.randomID(), - type: actionType, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), - ...cls.getSourceConfig(this.document) - }, + const cls = game.system.api.models.actions.actionsTypes[actionType]; + const action = new cls( + { + _id: foundry.utils.randomID(), + type: actionType, + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), + ...cls.getSourceConfig(this.document) + }, { parent: this.document } @@ -456,14 +469,13 @@ export default function DHApplicationMixin(Base) { force: true }); return action; - } else { const cls = getDocumentClass(documentClass); const data = { name: cls.defaultName({ type, parent }), - type, - } - if (inVault) data["system.inVault"] = true; + type + }; + if (inVault) data['system.inVault'] = true; if (disabled) data.disabled = true; const doc = await cls.create(data, { parent, renderSheet: !event.shiftKey }); @@ -474,7 +486,6 @@ export default function DHApplicationMixin(Base) { } return doc; } - } /** @@ -489,7 +500,7 @@ export default function DHApplicationMixin(Base) { const { actionId } = target.closest('[data-action-id]').dataset; const { actions, attack } = this.document.system; const action = attack?.id === actionId ? attack : actions?.find(a => a.id === actionId); - new DHActionConfig(action).render({ force: true }) + new DHActionConfig(action).render({ force: true }); } /** @@ -500,8 +511,8 @@ export default function DHApplicationMixin(Base) { const doc = getDocFromElement(target); if (doc) { - if (event.shiftKey) return doc.delete() - else return await doc.deleteDialog() + if (event.shiftKey) return doc.delete(); + else return await doc.deleteDialog(); } // TODO: REDO this @@ -524,7 +535,7 @@ export default function DHApplicationMixin(Base) { } return await this.document.update({ - 'system.actions': actions.filter((a) => a.id !== action.id) + 'system.actions': actions.filter(a => a.id !== action.id) }); } @@ -555,7 +566,7 @@ export default function DHApplicationMixin(Base) { const { actionId } = target.closest('[data-action-id]').dataset; const { actions, attack } = this.document.system; doc = attack?.id === actionId ? attack : actions?.find(a => a.id === actionId); - if(this.document instanceof foundry.documents.Item && !this.document.parent) return; + if (this.document instanceof foundry.documents.Item && !this.document.parent) return; } await doc.use(event); @@ -573,7 +584,6 @@ export default function DHApplicationMixin(Base) { await action.use(event); } - /** * Toggle a ActiveEffect * @type {ApplicationClickAction} @@ -604,7 +614,6 @@ export default function DHApplicationMixin(Base) { const descriptionElement = extensible?.querySelector('.invetory-description'); if (t && !!descriptionElement) this.#prepareInventoryDescription(extensible, descriptionElement); } - } return DHSheetV2; diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 56f00e9b..346a0ab6 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -22,7 +22,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { }, actions: { openSettings: DHBaseActorSheet.#openSettings, - sendExpToChat: DHBaseActorSheet.#sendExpToChat, + sendExpToChat: DHBaseActorSheet.#sendExpToChat }, contextMenus: [ { @@ -59,7 +59,6 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { return context; } - /**@inheritdoc */ async _preparePartContext(partId, context, options) { context = await super._preparePartContext(partId, context, options); @@ -81,7 +80,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { async _prepareEffectsContext(context, _options) { context.effects = { actives: [], - inactives: [], + inactives: [] }; for (const effect of this.actor.allApplicableEffects()) { @@ -104,7 +103,6 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { return this._getContextMenuCommonOptions.call(this, { usable: true, toChat: true }); } - /* -------------------------------------------- */ /* Application Clicks Actions */ /* -------------------------------------------- */ diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 766b443c..1888be9e 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -72,10 +72,10 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { secrets: this.item.isOwner }); break; - case "effects": - await this._prepareEffectsContext(context, options) + case 'effects': + await this._prepareEffectsContext(context, options); break; - case "features": + case 'features': context.isGM = game.user.isGM; break; } @@ -93,7 +93,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { async _prepareEffectsContext(context, _options) { context.effects = { actives: [], - inactives: [], + inactives: [] }; for (const effect of this.item.effects) { @@ -113,30 +113,30 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { * @protected */ static #getFeatureContextOptions() { - const options = this._getContextMenuCommonOptions({ usable: true, toChat: true, deletable: false }) - options.push( - { - name: 'CONTROLS.CommonDelete', - icon: '', - callback: async (target) => { - const feature = getDocFromElement(target); - if (!feature) return; - const confirmed = await foundry.applications.api.DialogV2.confirm({ - window: { - title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { - type: game.i18n.localize(`TYPES.Item.feature`), - name: feature.name - }) - }, - content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: feature.name }) - }); - if (!confirmed) return; - await this.document.update({ - 'system.features': this.document.system.toObject().features.filter(uuid => uuid !== feature.uuid) - }); - }, + const options = this._getContextMenuCommonOptions({ usable: true, toChat: true, deletable: false }); + options.push({ + name: 'CONTROLS.CommonDelete', + icon: '', + callback: async target => { + const feature = getDocFromElement(target); + if (!feature) return; + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize(`TYPES.Item.feature`), + name: feature.name + }) + }, + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { + name: feature.name + }) + }); + if (!confirmed) return; + await this.document.update({ + 'system.features': this.document.system.toObject().features.filter(uuid => uuid !== feature.uuid) + }); } - ) + }); return options; } @@ -153,7 +153,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { const actionIndex = button.closest('[data-index]').dataset.index; const action = this.document.system.actions[actionIndex]; - if(!event.shiftKey) { + if (!event.shiftKey) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { @@ -166,7 +166,6 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { if (!confirmed) return; } - await this.document.update({ 'system.actions': this.document.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) }); @@ -180,9 +179,9 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { const { type } = target.dataset; const cls = foundry.documents.Item.implementation; const feature = await cls.create({ - type: 'feature', - name: cls.defaultName({ type: 'feature' }), - "system.subType": CONFIG.DH.ITEM.featureSubTypes[type] + 'type': 'feature', + 'name': cls.defaultName({ type: 'feature' }), + 'system.subType': CONFIG.DH.ITEM.featureSubTypes[type] }); await this.document.update({ 'system.features': [...this.document.system.features, feature].map(f => f.uuid) @@ -198,9 +197,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing')); await feature.update({ 'system.subType': null }); await this.document.update({ - 'system.features': this.document.system.features - .map(x => x.uuid) - .filter(uuid => uuid !== feature.uuid) + 'system.features': this.document.system.features.map(x => x.uuid).filter(uuid => uuid !== feature.uuid) }); } diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 80bbe139..bdc482c3 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -31,7 +31,7 @@ export default class ArmorSheet extends ItemAttachmentSheet(DHBaseItemSheet) { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-effects.hbs', scrollable: ['.effects'] }, - ...super.PARTS, + ...super.PARTS }; /**@inheritdoc */ diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index db769e94..8894b694 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -1,4 +1,5 @@ import DHBaseItemSheet from '../api/base-item.mjs'; +import Tagify from '@yaireo/tagify'; export default class BeastformSheet extends DHBaseItemSheet { /**@inheritdoc */ @@ -15,6 +16,7 @@ export default class BeastformSheet extends DHBaseItemSheet { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-features.hbs', scrollable: ['.features'] }, + advanced: { template: 'systems/daggerheart/templates/sheets/items/beastform/advanced.hbs' }, effects: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-effects.hbs', scrollable: ['.effects'] @@ -23,9 +25,77 @@ export default class BeastformSheet extends DHBaseItemSheet { static TABS = { primary: { - tabs: [{ id: 'settings' }, { id: 'features' }, { id: 'effects' }], + tabs: [{ id: 'settings' }, { id: 'features' }, { id: 'advanced' }, { id: 'effects' }], initial: 'settings', labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } }; + + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + const advantageOnInput = htmlElement.querySelector('.advantageon-input'); + if (advantageOnInput) { + const tagifyElement = new Tagify(advantageOnInput, { + tagTextProp: 'name', + templates: { + tag(tagData) { + return ` + +
    + ${tagData[this.settings.tagTextProp] || tagData.value} + ${tagData.src ? `` : ''} +
    +
    `; + } + } + }); + tagifyElement.on('add', this.advantageOnAdd.bind(this)); + tagifyElement.on('remove', this.advantageOnRemove.bind(this)); + } + } + + /**@inheritdoc */ + async _preparePartContext(partId, context, options) { + await super._preparePartContext(partId, context, options); + + switch (partId) { + case 'settings': + context.advantageOn = JSON.stringify( + Object.keys(context.document.system.advantageOn).map(key => ({ + value: key, + name: context.document.system.advantageOn[key].value + })) + ); + break; + case 'effects': + context.effects.actives = context.effects.actives.map(effect => { + const data = effect.toObject(); + data.id = effect.id; + if (effect.type === 'beastform') data.mandatory = true; + + return data; + }); + break; + } + + return context; + } + + async advantageOnAdd(event) { + await this.document.update({ + [`system.advantageOn.${foundry.utils.randomID()}`]: { value: event.detail.data.value } + }); + } + + async advantageOnRemove(event) { + await this.document.update({ + [`system.advantageOn.-=${event.detail.data.value}`]: null + }); + } } diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index 11feb1b2..1520844b 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -9,7 +9,7 @@ export default class ClassSheet extends DHBaseItemSheet { position: { width: 700 }, actions: { removeItemFromCollection: ClassSheet.#removeItemFromCollection, - removeSuggestedItem: ClassSheet.#removeSuggestedItem, + removeSuggestedItem: ClassSheet.#removeSuggestedItem }, tagifyConfigs: [ { diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index 3fb725d7..2533287b 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -31,7 +31,7 @@ export default class WeaponSheet extends ItemAttachmentSheet(DHBaseItemSheet) { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-effects.hbs', scrollable: ['.effects'] }, - ...super.PARTS, + ...super.PARTS }; /**@inheritdoc */ diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 13bfb5f9..41f9ef20 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -206,21 +206,24 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (!confirm) return; } } - + if (targets.length === 0) return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); for (let target of targets) { let damages = foundry.utils.deepClone(message.system.damage?.roll ?? message.system.roll); - if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) { + if ( + message.system.onSave && + message.system.targets.find(t => t.id === target.id)?.saved?.success === true + ) { const mod = CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1; - Object.entries(damages).forEach(([k,v]) => { + Object.entries(damages).forEach(([k, v]) => { v.total = 0; v.parts.forEach(part => { part.total = Math.ceil(part.total * mod); v.total += part.total; - }) - }) + }); + }); } target.actor.takeDamage(damages); @@ -233,7 +236,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (targets.length === 0) return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - + for (var target of targets) { target.actor.takeHealing(message.system.roll); } @@ -294,15 +297,16 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo await actor.useAction(action); }; - actionUseButton = async (_, message) => { + actionUseButton = async (event, message) => { + const { moveIndex, actionIndex } = event.currentTarget.dataset; const parent = await foundry.utils.fromUuid(message.system.actor); - const actionType = Object.values(message.system.moves)[0].actions[0]; - const cls = CONFIG.DH.ACTIONS.actionTypes[actionType.type]; + const actionType = message.system.moves[moveIndex].actions[actionIndex]; + const cls = game.system.api.models.actions.actionsTypes[actionType.type]; const action = new cls( { ...actionType, _id: foundry.utils.randomID(), name: game.i18n.localize(actionType.name) }, - { parent: parent } + { parent: parent.system } ); - action.use(); + action.use(event); }; } diff --git a/module/applications/ui/hotbar.mjs b/module/applications/ui/hotbar.mjs index b4ebc05c..9d102c6c 100644 --- a/module/applications/ui/hotbar.mjs +++ b/module/applications/ui/hotbar.mjs @@ -99,7 +99,7 @@ export default class DhHotbar extends foundry.applications.ui.Hotbar { async createItemMacro(data, slot) { const macro = await Macro.implementation.create({ - name: `${game.i18n.localize('Display')} ${name}`, + name: data.name, type: CONST.MACRO_TYPES.SCRIPT, img: data.img, command: `await game.system.api.applications.ui.DhHotbar.useItem("${data.uuid}");` @@ -109,7 +109,7 @@ export default class DhHotbar extends foundry.applications.ui.Hotbar { async createActionMacro(data, slot) { const macro = await Macro.implementation.create({ - name: `${game.i18n.localize('Display')} ${name}`, + name: data.data.name, type: CONST.MACRO_TYPES.SCRIPT, img: data.data.img, command: `await game.system.api.applications.ui.DhHotbar.useAction("${data.data.itemUuid}", "${data.data.id}");` @@ -119,7 +119,7 @@ export default class DhHotbar extends foundry.applications.ui.Hotbar { async createAttackMacro(data, slot) { const macro = await Macro.implementation.create({ - name: `${game.i18n.localize('Display')} ${name}`, + name: data.name, type: CONST.MACRO_TYPES.SCRIPT, img: data.img, command: `await game.system.api.applications.ui.DhHotbar.useAttack("${data.actorUuid}");` diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index d05dc81c..edf3a9f3 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -1,5 +1,6 @@ export const abilities = { agility: { + id: 'agility', label: 'DAGGERHEART.CONFIG.Traits.agility.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.agility.verb.sprint', @@ -8,6 +9,7 @@ export const abilities = { ] }, strength: { + id: 'strength', label: 'DAGGERHEART.CONFIG.Traits.strength.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.strength.verb.lift', @@ -16,6 +18,7 @@ export const abilities = { ] }, finesse: { + id: 'finesse', label: 'DAGGERHEART.CONFIG.Traits.finesse.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.finesse.verb.control', @@ -24,6 +27,7 @@ export const abilities = { ] }, instinct: { + id: 'instinct', label: 'DAGGERHEART.CONFIG.Traits.instinct.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.instinct.verb.perceive', @@ -32,6 +36,7 @@ export const abilities = { ] }, presence: { + id: 'presence', label: 'DAGGERHEART.CONFIG.Traits.presence.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.presence.verb.charm', @@ -40,6 +45,7 @@ export const abilities = { ] }, knowledge: { + id: 'knowledge', label: 'DAGGERHEART.CONFIG.Traits.knowledge.name', verbs: [ 'DAGGERHEART.CONFIG.Traits.knowledge.verb.recall', diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index efe8a016..390435b4 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -145,11 +145,11 @@ export const defaultRestOptions = { img: 'icons/magic/life/cross-worn-green.webp', actionType: 'action', healing: { - type: 'health', + applyTo: healingTypes.hitPoints.id, value: { custom: { enabled: true, - formula: '1d4 + 1' // should be 1d4 + {tier}. How to use the roll param? + formula: '1d4 + @tier' } } } @@ -169,11 +169,11 @@ export const defaultRestOptions = { img: 'icons/magic/perception/eye-ringed-green.webp', actionType: 'action', healing: { - type: 'stress', + applyTo: healingTypes.stress.id, value: { custom: { enabled: true, - formula: '1d4 + 1' // should be 1d4 + {tier}. How to use the roll param? + formula: '1d4 + @tier' } } } @@ -186,7 +186,23 @@ export const defaultRestOptions = { icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'), - actions: [] + actions: [ + { + type: 'healing', + name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'), + img: 'icons/skills/trades/smithing-anvil-silver-red.webp', + actionType: 'action', + healing: { + applyTo: healingTypes.armorStack.id, + value: { + custom: { + enabled: true, + formula: '1d4 + @tier' + } + } + } + } + ] }, prepare: { id: 'prepare', @@ -263,25 +279,21 @@ export const deathMoves = { }; export const tiers = { - tier1: { - id: 'tier1', - label: 'DAGGERHEART.GENERAL.Tiers.tier1', - value: 1 + 1: { + id: 1, + label: 'DAGGERHEART.GENERAL.Tiers.1' }, - tier2: { - id: 'tier2', - label: 'DAGGERHEART.GENERAL.Tiers.tier2', - value: 2 + 2: { + id: 2, + label: 'DAGGERHEART.GENERAL.Tiers.2' }, - tier3: { - id: 'tier3', - label: 'DAGGERHEART.GENERAL.Tiers.tier3', - value: 3 + 3: { + id: 3, + label: 'DAGGERHEART.GENERAL.Tiers.3' }, - tier4: { - id: 'tier4', - label: 'DAGGERHEART.GENERAL.Tiers.tier4', - value: 4 + 4: { + id: 4, + label: 'DAGGERHEART.GENERAL.Tiers.4' } }; diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index 6b28a1ae..9deed7f1 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -1346,3 +1346,18 @@ export const itemResourceTypes = { label: 'DAGGERHEART.CONFIG.ItemResourceType.diceValue' } }; + +export const beastformTypes = { + normal: { + id: 'normal', + label: 'DAGGERHEART.CONFIG.BeastformType.normal' + }, + evolved: { + id: 'evolved', + label: 'DAGGERHEART.CONFIG.BeastformType.evolved' + }, + hybrid: { + id: 'hybrid', + label: 'DAGGERHEART.CONFIG.BeastformType.hybrid' + } +}; diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index e72dc54a..1d2b204b 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -113,7 +113,7 @@ export class DHResourceData extends foundry.abstract.DataModel { }), value: new fields.EmbeddedDataField(DHActionDiceData), valueAlt: new fields.EmbeddedDataField(DHActionDiceData) - } + }; } } @@ -134,6 +134,6 @@ export class DHDamageData extends DHResourceData { label: 'Type' } ) - } + }; } } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index f0176d78..ad442951 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -163,7 +163,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } getRollData(data = {}) { - if(!this.actor) return null; + if (!this.actor) return null; const actorData = this.actor.getRollData(false); // Add Roll results to RollDatas @@ -178,8 +178,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } async use(event, ...args) { - if(!this.actor) throw new Error("An Action can't be used outside of an Actor context."); - + if (!this.actor) throw new Error("An Action can't be used outside of an Actor context."); + const isFastForward = event.shiftKey || (!this.hasRoll && !this.hasSave); // Prepare base Config const initConfig = this.initActionConfig(event); diff --git a/module/data/action/beastformAction.mjs b/module/data/action/beastformAction.mjs index 98d8053f..2116662c 100644 --- a/module/data/action/beastformAction.mjs +++ b/module/data/action/beastformAction.mjs @@ -10,10 +10,10 @@ export default class DhBeastformAction extends DHBaseAction { const abort = await this.handleActiveTransformations(); if (abort) return; - const beastformUuid = await BeastformDialog.configure(beastformConfig); - if (!beastformUuid) return; + const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig); + if (!selected) return; - await this.transform(beastformUuid); + await this.transform(selected, evolved, hybrid); } prepareBeastformConfig(config) { @@ -29,21 +29,48 @@ export default class DhBeastformAction extends DHBaseAction { }; } - async transform(beastformUuid) { - const beastform = await foundry.utils.fromUuid(beastformUuid); - this.actor.createEmbeddedDocuments('Item', [beastform.toObject()]); + async transform(selectedForm, evolvedData, hybridData) { + const formData = evolvedData?.form ? evolvedData.form.toObject() : selectedForm.toObject(); + const beastformEffect = formData.effects.find(x => x.type === 'beastform'); + if (!beastformEffect) { + ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect'); + return; + } + + if (evolvedData?.form) { + const evolvedForm = selectedForm.effects.find(x => x.type === 'beastform'); + if (!evolvedForm) { + ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect'); + return; + } + + beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes]; + formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)]; + } + + if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) { + formData.system.advantageOn = Object.values(hybridData.advantages).reduce((advantages, formCategory) => { + Object.keys(formCategory).forEach(advantageKey => { + advantages[advantageKey] = formCategory[advantageKey]; + }); + return advantages; + }, {}); + formData.system.features = [ + ...formData.system.features, + ...Object.values(hybridData.features).flatMap(x => Object.keys(x)) + ]; + } + + this.actor.createEmbeddedDocuments('Item', [formData]); } async handleActiveTransformations() { const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform'); - if (beastformEffects.length > 0) { - for (let effect of beastformEffects) { - await effect.delete(); - } - - return true; - } - - return false; + const existingEffects = beastformEffects.length > 0; + await this.actor.deleteEmbeddedDocuments( + 'ActiveEffect', + beastformEffects.map(x => x.id) + ); + return existingEffects; } } diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index 13461d30..988e1844 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -22,31 +22,32 @@ export default class DHDamageAction extends DHBaseAction { formatFormulas(formulas, systemData) { const formattedFormulas = []; formulas.forEach(formula => { - if (isNaN(formula.formula)) formula.formula = Roll.replaceFormulaData(formula.formula, this.getRollData(systemData)); - const same = formattedFormulas.find(f => setsEqual(f.damageTypes, formula.damageTypes) && f.applyTo === formula.applyTo); - if(same) - same.formula += ` + ${formula.formula}`; - else - formattedFormulas.push(formula); - }) + if (isNaN(formula.formula)) + formula.formula = Roll.replaceFormulaData(formula.formula, this.getRollData(systemData)); + const same = formattedFormulas.find( + f => setsEqual(f.damageTypes, formula.damageTypes) && f.applyTo === formula.applyTo + ); + if (same) same.formula += ` + ${formula.formula}`; + else formattedFormulas.push(formula); + }); return formattedFormulas; } async rollDamage(event, data) { const systemData = data.system ?? data; - + let formulas = this.damage.parts.map(p => ({ formula: this.getFormulaValue(p, data).getFormula(this.actor), damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type, applyTo: p.applyTo })); - if(!formulas.length) return; + if (!formulas.length) return; formulas = this.formatFormulas(formulas, systemData); const config = { - title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }), + title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: game.i18n.localize(this.name) }), roll: formulas, targets: systemData.targets.filter(t => t.hit) ?? data.targets, hasSave: this.hasSave, diff --git a/module/data/action/healingAction.mjs b/module/data/action/healingAction.mjs index e0a74f27..b7cc4a75 100644 --- a/module/data/action/healingAction.mjs +++ b/module/data/action/healingAction.mjs @@ -16,11 +16,13 @@ export default class DHHealingAction extends DHBaseAction { async rollHealing(event, data) { const systemData = data.system ?? data; - let formulas = [{ - formula: this.getFormulaValue(data).getFormula(this.actor), - applyTo: this.healing.applyTo - }]; - + let formulas = [ + { + formula: this.getFormulaValue(data).getFormula(this.actor), + applyTo: this.healing.applyTo + } + ]; + const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.healingRoll.title', { healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.applyTo].label) diff --git a/module/data/activeEffect/beastformEffect.mjs b/module/data/activeEffect/beastformEffect.mjs index 6445f65d..4e6fa104 100644 --- a/module/data/activeEffect/beastformEffect.mjs +++ b/module/data/activeEffect/beastformEffect.mjs @@ -26,6 +26,13 @@ export default class BeastformEffect extends foundry.abstract.TypeDataModel { }; } + async _onCreate() { + if (this.parent.parent?.type === 'character') { + this.parent.parent.system.primaryWeapon?.update?.({ 'system.equipped': false }); + this.parent.parent.system.secondayWeapon?.update?.({ 'system.equipped': false }); + } + } + async _preDelete() { if (this.parent.parent.type === 'character') { const update = { diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 00a19d05..7360e42f 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -18,10 +18,11 @@ export default class DhpAdversary extends BaseDataActor { const fields = foundry.data.fields; return { ...super.defineSchema(), - tier: new fields.StringField({ + tier: new fields.NumberField({ required: true, + integer: true, choices: CONFIG.DH.GENERAL.tiers, - initial: CONFIG.DH.GENERAL.tiers.tier1.id + initial: CONFIG.DH.GENERAL.tiers[1].id }), type: new fields.StringField({ required: true, @@ -52,7 +53,7 @@ export default class DhpAdversary extends BaseDataActor { }) }), resources: new fields.SchemaField({ - hitPoints: resourceField(0, 'DAGGERHEART.GENERAL.hitPoints.plural', true), + hitPoints: resourceField(0, 'DAGGERHEART.GENERAL.HitPoints.plural', true), stress: resourceField(0, 'DAGGERHEART.GENERAL.stress', true) }), attack: new ActionField({ diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index c484465a..34a1f525 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -3,6 +3,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import DhLevelData from '../levelData.mjs'; import BaseDataActor from './base.mjs'; import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs'; +import ActionField from '../fields/actionField.mjs'; export default class DhCharacter extends BaseDataActor { static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character']; @@ -21,7 +22,7 @@ export default class DhCharacter extends BaseDataActor { return { ...super.defineSchema(), resources: new fields.SchemaField({ - hitPoints: resourceField(0, 'DAGGERHEART.GENERAL.hitPoints.plural', true), + hitPoints: resourceField(0, 'DAGGERHEART.GENERAL.HitPoints.plural', true), stress: resourceField(6, 'DAGGERHEART.GENERAL.stress', true), hope: resourceField(6, 'DAGGERHEART.GENERAL.hope') }), @@ -87,8 +88,45 @@ export default class DhCharacter extends BaseDataActor { value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }), subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }) }), - advantageSources: new fields.ArrayField(new fields.StringField()), - disadvantageSources: new fields.ArrayField(new fields.StringField()), + attack: new ActionField({ + initial: { + name: 'Attack', + img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp', + _id: foundry.utils.randomID(), + systemPath: 'attack', + type: 'attack', + range: 'melee', + target: { + type: 'any', + amount: 1 + }, + roll: { + type: 'attack', + trait: 'strength' + }, + damage: { + parts: [ + { + type: ['physical'], + value: { + custom: { + enabled: true, + formula: '@system.rules.attack.damage.value' + } + } + } + ] + } + } + }), + advantageSources: new fields.ArrayField(new fields.StringField(), { + label: 'DAGGERHEART.ACTORS.Character.advantageSources.label', + hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint' + }), + disadvantageSources: new fields.ArrayField(new fields.StringField(), { + label: 'DAGGERHEART.ACTORS.Character.disadvantageSources.label', + hint: 'DAGGERHEART.ACTORS.Character.disadvantageSources.hint' + }), levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ roll: new fields.SchemaField({ @@ -198,6 +236,15 @@ export default class DhCharacter extends BaseDataActor { magical: new fields.BooleanField({ initial: false }), physical: new fields.BooleanField({ initial: false }) }), + attack: new fields.SchemaField({ + damage: new fields.SchemaField({ + value: new fields.StringField({ + required: true, + initial: '@profd4', + label: 'DAGGERHEART.GENERAL.Rules.attack.damage.value.label' + }) + }) + }), weapon: new fields.SchemaField({ /* Unimplemented -> Should remove the lowest damage dice from weapon damage @@ -277,6 +324,24 @@ export default class DhCharacter extends BaseDataActor { return this.parent.items.find(x => x.type === 'armor' && x.system.equipped); } + get activeBeastform() { + return this.parent.effects.find(x => x.type === 'beastform'); + } + + get usedUnarmed() { + const primaryWeaponEquipped = this.primaryWeapon?.system?.equipped; + const secondaryWeaponEquipped = this.secondaryWeapon?.system?.equipped; + return !primaryWeaponEquipped && !secondaryWeaponEquipped + ? { + ...this.attack, + id: this.attack.id, + name: this.activeBeastform ? 'DAGGERHEART.ITEMS.Beastform.attackName' : this.attack.name, + img: this.activeBeastform ? 'icons/creatures/claws/claw-straight-brown.webp' : this.attack.img, + actor: this.parent + } + : null; + } + get sheetLists() { const ancestryFeatures = [], communityFeatures = [], @@ -457,9 +522,6 @@ export default class DhCharacter extends BaseDataActor { const data = super.getRollData(); return { ...data, - ...this.resources.tokens, - ...this.resources.dice, - ...this.bonuses, tier: this.tier, level: this.levelData.level.current }; diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs index 2db1f039..e9a484b3 100644 --- a/module/data/actor/environment.mjs +++ b/module/data/actor/environment.mjs @@ -18,10 +18,11 @@ export default class DhEnvironment extends BaseDataActor { const fields = foundry.data.fields; return { ...super.defineSchema(), - tier: new fields.StringField({ + tier: new fields.NumberField({ required: true, + integer: true, choices: CONFIG.DH.GENERAL.tiers, - initial: CONFIG.DH.GENERAL.tiers.tier1.id + initial: CONFIG.DH.GENERAL.tiers[1].id }), type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }), impulses: new fields.StringField(), diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index d19521d0..226504df 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -19,10 +19,16 @@ export default class DHBeastform extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - tier: new fields.StringField({ + beastformType: new fields.StringField({ required: true, + choices: CONFIG.DH.ITEM.beastformTypes, + initial: CONFIG.DH.ITEM.beastformTypes.normal.id + }), + tier: new fields.NumberField({ + required: true, + integer: true, choices: CONFIG.DH.GENERAL.tiers, - initial: CONFIG.DH.GENERAL.tiers.tier1.id + initial: CONFIG.DH.GENERAL.tiers[1].id }), tokenImg: new fields.FilePathField({ initial: 'icons/svg/mystery-man.svg', @@ -38,9 +44,40 @@ export default class DHBeastform extends BaseDataItem { height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }), width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }) }), + mainTrait: new fields.StringField({ + required: true, + choices: CONFIG.DH.ACTOR.abilities, + initial: CONFIG.DH.ACTOR.abilities.agility.id + }), examples: new fields.StringField(), - advantageOn: new fields.StringField(), - features: new ForeignDocumentUUIDArrayField({ type: 'Item' }) + advantageOn: new fields.TypedObjectField( + new fields.SchemaField({ + value: new fields.StringField() + }) + ), + features: new ForeignDocumentUUIDArrayField({ type: 'Item' }), + evolved: new fields.SchemaField({ + maximumTier: new fields.NumberField({ + integer: true, + choices: CONFIG.DH.GENERAL.tiers + }), + mainTraitBonus: new fields.NumberField({ + required: true, + integer: true, + min: 0, + initial: 0 + }) + }), + hybrid: new fields.SchemaField({ + maximumTier: new fields.NumberField({ + integer: true, + choices: CONFIG.DH.GENERAL.tiers, + label: 'DAGGERHEART.ITEMS.Beastform.FIELDS.evolved.maximumTier.label' + }), + beastformOptions: new fields.NumberField({ required: true, integer: true, initial: 2, min: 2 }), + advantages: new fields.NumberField({ required: true, integer: true, initial: 2, min: 2 }), + features: new fields.NumberField({ required: true, integer: true, initial: 2, min: 2 }) + }) }; } @@ -69,7 +106,16 @@ export default class DHBeastform extends BaseDataItem { const beastformEffect = this.parent.effects.find(x => x.type === 'beastform'); await beastformEffect.updateSource({ - changes: [...beastformEffect.changes, { key: 'system.advantageSources', mode: 2, value: this.advantageOn }], + changes: [ + ...beastformEffect.changes, + { + key: 'system.advantageSources', + mode: 2, + value: Object.values(this.advantageOn) + .map(x => x.value) + .join(', ') + } + ], system: { characterTokenData: { tokenImg: this.parent.parent.prototypeToken.texture.src, diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index b8a9ab81..4016a4c7 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -24,7 +24,7 @@ export default class DHClass extends BaseDataItem { integer: true, min: 1, initial: 5, - label: 'DAGGERHEART.GENERAL.hitPoints.plural' + label: 'DAGGERHEART.GENERAL.HitPoints.plural' }), evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }), features: new ForeignDocumentUUIDArrayField({ type: 'Item' }), diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 09dd716e..95cba5ca 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -92,7 +92,7 @@ export default class D20Roll extends DHRoll { configureModifiers() { this.applyAdvantage(); - + this.baseTerms = foundry.utils.deepClone(this.dice); this.options.roll.modifiers = this.applyBaseBonus(); @@ -147,8 +147,7 @@ export default class D20Roll extends DHRoll { const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; target.hit = this.isCritical || roll.total >= difficulty; }); - } else if (config.roll.difficulty) - data.success = roll.isCritical || roll.total >= config.roll.difficulty; + } else if (config.roll.difficulty) data.success = roll.isCritical || roll.total >= config.roll.difficulty; data.advantage = { type: config.roll.advantage, dice: roll.dAdvantage?.denomination, diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index aa1c4c86..34fe77d7 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -11,8 +11,8 @@ export default class DamageRoll extends DHRoll { static DefaultDialog = DamageDialog; static async buildEvaluate(roll, config = {}, message = {}) { - if ( config.evaluate !== false ) { - for ( const roll of config.roll ) await roll.roll.evaluate(); + if (config.evaluate !== false) { + for (const roll of config.roll) await roll.roll.evaluate(); } roll._evaluated = true; const parts = config.roll.map(r => this.postEvaluate(r)); @@ -27,7 +27,7 @@ export default class DamageRoll extends DHRoll { roll: roll.roll, type: config.type, modifierTotal: this.calculateTotalModifiers(roll.roll) - } + }; } static async buildPost(roll, config, message) { @@ -46,33 +46,33 @@ export default class DamageRoll extends DHRoll { resource.total += r.total; resource.parts.push(r); unified[r.applyTo] = resource; - }) + }); return unified; } static formatGlobal(rolls) { let formula, total; const applyTo = new Set(rolls.flatMap(r => r.applyTo)); - if(applyTo.size > 1) { + if (applyTo.size > 1) { const data = {}; rolls.forEach(r => { - if(data[r.applyTo]) { - data[r.applyTo].formula += ` + ${r.formula}` ; - data[r.applyTo].total += r.total ; + if (data[r.applyTo]) { + data[r.applyTo].formula += ` + ${r.formula}`; + data[r.applyTo].total += r.total; } else { data[r.applyTo] = { formula: r.formula, total: r.total - } + }; } }); - formula = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.formula}`, ''); - total = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.total}`, ''); + formula = Object.entries(data).reduce((a, [k, v]) => a + ` ${k}: ${v.formula}`, ''); + total = Object.entries(data).reduce((a, [k, v]) => a + ` ${k}: ${v.total}`, ''); } else { formula = rolls.map(r => r.formula).join(' + '); - total = rolls.reduce((a,c) => a + c.total, 0) + total = rolls.reduce((a, c) => a + c.total, 0); } - return {formula, total} + return { formula, total }; } applyBaseBonus(part) { @@ -94,17 +94,17 @@ export default class DamageRoll extends DHRoll { } constructFormula(config) { - this.options.roll.forEach( part => { - part.roll = new Roll(part.formula); - this.constructFormulaPart(config, part) - }) + this.options.roll.forEach(part => { + part.roll = new Roll(Roll.replaceFormulaData(part.formula, config.data)); + this.constructFormulaPart(config, part); + }); return this.options.roll; } constructFormulaPart(config, part) { part.roll.terms = Roll.parse(part.roll.formula, config.data); - if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { + if (part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { part.modifiers = this.applyBaseBonus(part); this.addModifiers(part); part.modifiers?.forEach(m => { @@ -118,7 +118,7 @@ export default class DamageRoll extends DHRoll { ...this.constructor.parse(part.extraFormula, this.options.data) ); } - + if (config.isCritical && part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { const tmpRoll = Roll.fromTerms(part.roll.terms)._evaluateSync({ maximize: true }), criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index cb1007e3..c50c126a 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -57,13 +57,14 @@ export default class DHRoll extends Roll { // Create Chat Message if (config.source?.message) { - if(Object.values(config.roll)?.length) { - const pool = foundry.dice.terms.PoolTerm.fromRolls(Object.values(config.roll).flatMap(r => r.parts.map(p => p.roll))); + if (Object.values(config.roll)?.length) { + const pool = foundry.dice.terms.PoolTerm.fromRolls( + Object.values(config.roll).flatMap(r => r.parts.map(p => p.roll)) + ); roll = Roll.fromTerms([pool]); } if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); - } else - config.message = await this.toMessage(roll, config); + } else config.message = await this.toMessage(roll, config); } static postEvaluate(roll, config = {}) { @@ -76,7 +77,7 @@ export default class DHRoll extends Roll { formula: d.formula, results: d.results })) - } + }; } static async toMessage(roll, config) { diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index e36d2427..142f21e8 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -63,24 +63,22 @@ export default class DualityRoll extends D20Roll { } setRallyChoices() { - return this.data?.parent?.effects.reduce((a,c) => { - const change = c.changes.find(ch => ch.key === 'system.bonuses.rally'); - if(change) a.push({ value: c.id, label: change.value }); - return a; - }, []); + return this.data?.parent?.effects.reduce((a, c) => { + const change = c.changes.find(ch => ch.key === 'system.bonuses.rally'); + if (change) a.push({ value: c.id, label: change.value }); + return a; + }, []); } get dRally() { - if(!this.rallyFaces) return null; - if(this.hasDisadvantage || this.hasAdvantage) - return this.dice[3]; - else - return this.dice[2]; + if (!this.rallyFaces) return null; + if (this.hasDisadvantage || this.hasAdvantage) return this.dice[3]; + else return this.dice[2]; } get rallyFaces() { const rallyChoice = this.rallyChoices?.find(r => r.value === this._rallyIndex)?.label; - return rallyChoice ? this.getFaces(rallyChoice) : null; + return rallyChoice ? this.getFaces(rallyChoice) : null; } get isCritical() { @@ -129,13 +127,13 @@ export default class DualityRoll extends D20Roll { if (this.hasAdvantage || this.hasDisadvantage) { const dieFaces = this.advantageFaces, advDie = new foundry.dice.terms.Die({ faces: dieFaces, number: this.advantageNumber }); - if(this.advantageNumber > 1) advDie.modifiers = ['kh']; + if (this.advantageNumber > 1) advDie.modifiers = ['kh']; this.terms.push( new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }), advDie ); } - if(this.rallyFaces) + if (this.rallyFaces) this.terms.push( new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }), new foundry.dice.terms.Die({ faces: this.rallyFaces }) @@ -162,7 +160,7 @@ export default class DualityRoll extends D20Roll { static postEvaluate(roll, config = {}) { const data = super.postEvaluate(roll, config); - + data.hope = { dice: roll.dHope.denomination, value: roll.dHope.total @@ -181,7 +179,7 @@ export default class DualityRoll extends D20Roll { label: roll.totalLabel }; - if(roll._rallyIndex && roll.data?.parent) + if (roll._rallyIndex && roll.data?.parent) roll.data.parent.deleteEmbeddedDocuments('ActiveEffect', [roll._rallyIndex]); setDiceSoNiceForDualityRoll(roll, data.advantage.type); diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index e6ae781a..490f53eb 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -370,6 +370,7 @@ export default class DhpActor extends Actor { getRollData() { const rollData = super.getRollData(); + rollData.system = this.system.getRollData(); rollData.prof = this.system.proficiency ?? 1; rollData.cast = this.system.spellcastModifier ?? 1; return rollData; @@ -403,24 +404,28 @@ export default class DhpActor extends Actor { Object.entries(damages).forEach(([key, damage]) => { damage.parts.forEach(part => { - if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) + if (part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) part.total = this.calculateDamage(part.total, part.damageTypes); const update = updates.find(u => u.key === key); - if(update) { + if (update) { update.value += part.total; update.damageTypes.add(...new Set(part.damageTypes)); - } else updates.push({ value: part.total, key, damageTypes: new Set(part.damageTypes) }) - }) + } else updates.push({ value: part.total, key, damageTypes: new Set(part.damageTypes) }); + }); }); if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, damages) === false) return null; - if(!updates.length) return; + if (!updates.length) return; const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); - if(hpDamage) { + if (hpDamage) { hpDamage.value = this.convertDamageToThreshold(hpDamage.value); - if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { + if ( + this.type === 'character' && + this.system.armor && + this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes) + ) { const armorStackResult = await this.owner.query('armorStack', { actorId: this.uuid, damage: hpDamage.value, @@ -436,18 +441,19 @@ export default class DhpActor extends Actor { } } } - - updates.forEach( u => - u.value = u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value + + updates.forEach( + u => + (u.value = + u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value) ); - + await this.modifyResource(updates); if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damages) === false) return null; } calculateDamage(baseDamage, type) { - if (this.canResist(type, 'immunity')) return 0; if (this.canResist(type, 'resistance')) baseDamage = Math.ceil(baseDamage / 2); @@ -472,12 +478,12 @@ export default class DhpActor extends Actor { } async takeHealing(resources) { - const updates = Object.entries(resources).map(([key, value]) => ( - { - key: key, - value: !(key === 'fear' || this.system?.resources?.[key]?.isReversed === false) ? value.total * -1 : value.total - } - )) + const updates = Object.entries(resources).map(([key, value]) => ({ + key: key, + value: !(key === 'fear' || this.system?.resources?.[key]?.isReversed === false) + ? value.total * -1 + : value.total + })); await this.modifyResource(updates); } diff --git a/module/documents/token.mjs b/module/documents/token.mjs index f48af563..a8105eb2 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -16,7 +16,21 @@ export default class DHToken extends TokenDocument { }); bars.sort((a, b) => a.label.compare(b.label)); - const invalidAttributes = ['gold', 'levelData', 'actions']; + const invalidAttributes = [ + 'gold', + 'levelData', + 'actions', + 'biography', + 'class', + 'multiclass', + 'companion', + 'notes', + 'partner', + 'description', + 'impulses', + 'tier', + 'type' + ]; const values = attributes.value.reduce((acc, v) => { const a = v.join('.'); if (invalidAttributes.some(x => a.startsWith(x))) return acc; @@ -38,9 +52,11 @@ export default class DHToken extends TokenDocument { for (const [name, field] of Object.entries(schema.fields)) { const p = _path.concat([name]); if (field instanceof foundry.data.fields.NumberField) attributes.value.push(p); + if (field instanceof foundry.data.fields.StringField) attributes.value.push(p); if (field instanceof foundry.data.fields.ArrayField) attributes.value.push(p); const isSchema = field instanceof foundry.data.fields.SchemaField; const isModel = field instanceof foundry.data.fields.EmbeddedDataField; + if (isSchema || isModel) { const schema = isModel ? field.model.schema : field; const isBar = schema.has && schema.has('value') && schema.has('max'); diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index 005f77bd..8e1c729e 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -1,5 +1,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager { async activate(element, options = {}) { + const { TextEditor } = foundry.applications.ux; + let html = options.html; if (element.dataset.tooltip?.startsWith('#item#')) { const splitValues = element.dataset.tooltip.slice(6).split('#action#'); @@ -10,10 +12,16 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti const item = actionId ? baseItem.system.actions.find(x => x.id === actionId) : baseItem; if (item) { const type = actionId ? 'action' : item.type; + const description = await TextEditor.enrichHTML(item.system.description); + for (let feature of item.system.features) { + feature.system.enrichedDescription = await TextEditor.enrichHTML(feature.system.description); + } + html = await foundry.applications.handlebars.renderTemplate( `systems/daggerheart/templates/ui/tooltip/${type}.hbs`, { item: item, + description: description, config: CONFIG.DH } ); @@ -22,6 +30,26 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti options.direction = this._determineItemTooltipDirection(element); } } else { + const attack = element.dataset.tooltip?.startsWith('#attack#'); + if (attack) { + const actorUuid = element.dataset.tooltip.slice(8); + const actor = await foundry.utils.fromUuid(actorUuid); + const attack = actor.system.attack; + + const description = await TextEditor.enrichHTML(attack.description); + html = await foundry.applications.handlebars.renderTemplate( + `systems/daggerheart/templates/ui/tooltip/attack.hbs`, + { + attack: attack, + description: description, + parent: actor, + config: CONFIG.DH + } + ); + + this.tooltip.innerHTML = html; + } + const shortRest = element.dataset.tooltip?.startsWith('#shortRest#'); const longRest = element.dataset.tooltip?.startsWith('#longRest#'); if (shortRest || longRest) { @@ -29,11 +57,14 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti const downtimeOptions = shortRest ? CONFIG.DH.GENERAL.defaultRestOptions.shortRest() : CONFIG.DH.GENERAL.defaultRestOptions.longRest(); + const move = downtimeOptions[key]; + const description = await TextEditor.enrichHTML(move.description); html = await foundry.applications.handlebars.renderTemplate( `systems/daggerheart/templates/ui/tooltip/downtime.hbs`, { - move: move + move: move, + description: description } ); diff --git a/module/enrichers/DamageEnricher.mjs b/module/enrichers/DamageEnricher.mjs new file mode 100644 index 00000000..918edc39 --- /dev/null +++ b/module/enrichers/DamageEnricher.mjs @@ -0,0 +1,80 @@ +export default function DhDamageEnricher(match, _options) { + const parts = match[1].split('|').map(x => x.trim()); + + let value = null, + type = null; + + parts.forEach(part => { + const split = part.split(':').map(x => x.toLowerCase().trim()); + if (split.length === 2) { + switch (split[0]) { + case 'value': + value = split[1]; + break; + case 'type': + type = split[1]; + break; + } + } + }); + + if (!value || !value) return match[0]; + + return getDamageMessage(value, type, match[0]); +} + +function getDamageMessage(damage, type, defaultElement) { + const typeIcons = type + .replace('[', '') + .replace(']', '') + .split(',') + .map(x => x.trim()) + .map(x => { + return CONFIG.DH.GENERAL.damageTypes[x]?.icon ?? null; + }) + .filter(x => x); + + if (!typeIcons.length) return defaultElement; + + const iconNodes = typeIcons.map(x => ``).join(''); + + const dualityElement = document.createElement('span'); + dualityElement.innerHTML = ` + + `; + + return dualityElement; +} + +export const renderDamageButton = async event => { + const button = event.currentTarget, + value = button.dataset.value, + type = button.dataset.type + .replace('[', '') + .replace(']', '') + .split(',') + .map(x => x.trim()); + + const config = { + event: event, + title: game.i18n.localize('Damage Roll'), + data: { bonuses: [] }, + source: {}, + roll: [ + { + formula: value, + applyTo: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, + type: type + } + ] + }; + + CONFIG.Dice.daggerheart.DamageRoll.build(config); +}; diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 094a6948..a2da2805 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -8,7 +8,7 @@ export default function DhDualityRollEnricher(match, _options) { return getDualityMessage(roll); } -export function getDualityMessage(roll) { +function getDualityMessage(roll) { const traitLabel = roll.trait && abilities[roll.trait] ? game.i18n.format('DAGGERHEART.GENERAL.check', { diff --git a/module/enrichers/EffectEnricher.mjs b/module/enrichers/EffectEnricher.mjs new file mode 100644 index 00000000..69b89ef2 --- /dev/null +++ b/module/enrichers/EffectEnricher.mjs @@ -0,0 +1,19 @@ +export default async function DhEffectEnricher(match, _options) { + const effect = await foundry.utils.fromUuid(match[1]); + if (!effect) return match[0]; + + const dualityElement = document.createElement('span'); + dualityElement.innerHTML = ` + + + ${effect.name} + + `; + + return dualityElement; +} diff --git a/module/enrichers/_module.mjs b/module/enrichers/_module.mjs index 1907f117..abfd8158 100644 --- a/module/enrichers/_module.mjs +++ b/module/enrichers/_module.mjs @@ -1,2 +1,43 @@ -export { default as DhDualityRollEnricher } from './DualityRollEnricher.mjs'; -export { default as DhTemplateEnricher } from './TemplateEnricher.mjs'; +import { default as DhDamageEnricher, renderDamageButton } from './DamageEnricher.mjs'; +import { default as DhDualityRollEnricher, renderDualityButton } from './DualityRollEnricher.mjs'; +import { default as DhEffectEnricher } from './EffectEnricher.mjs'; +import { default as DhTemplateEnricher, renderMeasuredTemplate } from './TemplateEnricher.mjs'; + +export { DhDamageEnricher, DhDualityRollEnricher, DhEffectEnricher, DhTemplateEnricher }; + +export const enricherConfig = [ + { + pattern: /^@Damage\[(.*)\]$/g, + enricher: DhDamageEnricher + }, + { + pattern: /\[\[\/dr\s?(.*?)\]\]/g, + enricher: DhDualityRollEnricher + }, + { + pattern: /^@Effect\[(.*)\]$/g, + enricher: DhEffectEnricher + }, + { + pattern: /^@Template\[(.*)\]$/g, + enricher: DhTemplateEnricher + } +]; + +export const enricherRenderSetup = element => { + element + .querySelectorAll('.enriched-damage-button') + .forEach(element => element.addEventListener('click', renderDamageButton)); + + element + .querySelectorAll('.duality-roll-button') + .forEach(element => element.addEventListener('click', renderDualityButton)); + + element + .querySelectorAll('.measured-template-button') + .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); + + // element + // .querySelectorAll('.enriched-effect') + // .forEach(element => element.addEventListener('dragstart', dragEnrichedEffect)); +}; diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 0a57a6a6..0c919191 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -9,7 +9,7 @@ export default class RegisterHandlebarsHelpers { damageFormula: this.damageFormula, damageSymbols: this.damageSymbols, rollParsed: this.rollParsed, - hasProperty: foundry.utils.hasProperty, + hasProperty: foundry.utils.hasProperty }); } static add(a, b) { diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 2aacd5c7..7e73695e 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -1,80 +1,10 @@ import { diceTypes, getDiceSoNicePresets, range } from '../config/generalConfig.mjs'; import Tagify from '@yaireo/tagify'; -export const loadCompendiumOptions = async compendiums => { - const compendiumValues = []; - - for (var compendium of compendiums) { - const values = await getCompendiumOptions(compendium); - compendiumValues.push(values); - } - - return compendiumValues; -}; - -const getCompendiumOptions = async compendium => { - const compendiumPack = await game.packs.get(compendium); - - const values = []; - for (var value of compendiumPack.index) { - const document = await compendiumPack.getDocument(value._id); - values.push(document); - } - - return values; -}; - -export const getWidthOfText = (txt, fontsize, allCaps, bold) => { - const text = allCaps ? txt.toUpperCase() : txt; - if (getWidthOfText.c === undefined) { - getWidthOfText.c = document.createElement('canvas'); - getWidthOfText.ctx = getWidthOfText.c.getContext('2d'); - } - var fontspec = `${bold ? 'bold' : ''} ${fontsize}px` + ' ' + 'Signika, sans-serif'; - if (getWidthOfText.ctx.font !== fontspec) getWidthOfText.ctx.font = fontspec; - - return getWidthOfText.ctx.measureText(text).width; -}; - -export const padArray = (arr, len, fill) => { - return arr.concat(Array(len).fill(fill)).slice(0, len); -}; - -export const getTier = (level, asNr) => { - switch (Math.floor((level + 1) / 3)) { - case 1: - return asNr ? 1 : 'tier1'; - case 2: - return asNr ? 2 : 'tier2'; - case 3: - return asNr ? 3 : 'tier3'; - default: - return asNr ? 0 : 'tier0'; - } -}; - export const capitalize = string => { return string.charAt(0).toUpperCase() + string.slice(1); }; -export const getPathValue = (path, entity, numeric) => { - const pathValue = foundry.utils.getProperty(entity, path); - if (pathValue) return numeric ? Number.parseInt(pathValue) : pathValue; - - return numeric ? Number.parseInt(path) : path; -}; - -export const generateId = (title, length) => { - const id = title - .split(' ') - .map((w, i) => { - const p = w.slugify({ replacement: '', strict: true }); - return i ? p.titleCase() : p; - }) - .join(''); - return Number.isNumeric(length) ? id.slice(0, length).padEnd(length, '0') : id; -}; - export function rollCommandToJSON(text) { if (!text) return {}; @@ -311,7 +241,6 @@ export function getDocFromElement(element) { return foundry.utils.fromUuidSync(target.dataset.itemUuid) ?? null; } - export const itemAbleRollParse = (value, actor, item) => { if (!value) return value; @@ -325,13 +254,7 @@ export const itemAbleRollParse = (value, actor, item) => { }; export const arraysEqual = (a, b) => - a.length === b.length && - [...new Set([...a, ...b])].every( - v => a.filter(e => e === v).length === b.filter(e => e === v).length - ); + a.length === b.length && + [...new Set([...a, ...b])].every(v => a.filter(e => e === v).length === b.filter(e => e === v).length); -export const setsEqual = (a, b) => - a.size === b.size && - [...a].every( - value => b.has(value) - ); \ No newline at end of file +export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value)); diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index ec5f2df1..b15bf820 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -1,8 +1,9 @@ export const preloadHandlebarsTemplates = async function () { foundry.applications.handlebars.loadTemplates({ - 'daggerheart.inventory-items': 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs', - 'daggerheart.inventory-item': 'systems/daggerheart/templates/sheets/global/partials/inventory-item-V2.hbs', - }) + 'daggerheart.inventory-items': + 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs', + 'daggerheart.inventory-item': 'systems/daggerheart/templates/sheets/global/partials/inventory-item-V2.hbs' + }); return foundry.applications.handlebars.loadTemplates([ 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs', 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs', @@ -27,6 +28,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', 'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs', 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs', + 'systems/daggerheart/templates/ui/tooltip/parts/tooltipChips.hbs', 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', 'systems/daggerheart/templates/dialogs/downtime/activities.hbs' ]); diff --git a/src/packs/beastforms/beastform_Agile_Scout_6tr99y6wHaJJYy3J.json b/src/packs/beastforms/beastform_Agile_Scout_6tr99y6wHaJJYy3J.json new file mode 100644 index 00000000..0885d9f3 --- /dev/null +++ b/src/packs/beastforms/beastform_Agile_Scout_6tr99y6wHaJJYy3J.json @@ -0,0 +1,160 @@ +{ + "name": "Agile Scout", + "type": "beastform", + "img": "icons/creatures/mammals/goat-horned-blue.webp", + "system": { + "beastformType": "normal", + "tier": 1, + "tokenImg": "icons/creatures/mammals/goat-horned-blue.webp", + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": { + "height": null, + "width": null + }, + "mainTrait": "agility", + "advantageOn": { + "tXlf8FvWrgGqfaJu": { + "value": "deceit" + }, + "lp1gv9iNUCpC2Fli": { + "value": "locate" + }, + "GxDMKUpOeDHzyhAT": { + "value": "sneak" + } + }, + "features": [ + "Compendium.daggerheart.beastforms.Item.sef9mwD2eRLZ64oV", + "Compendium.daggerheart.beastforms.Item.9ryNrYWjNtOT6DXN" + ], + "evolved": { + "mainTraitBonus": 0 + }, + "hybrid": { + "beastformOptions": 2, + "advantages": 2, + "features": 2 + }, + "examples": "Fox, Mouse, Weasel, etc." + }, + "effects": [ + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "m098fyKkAjTFZ6UJ", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [ + { + "key": "system.traits.agility.value", + "mode": 2, + "value": "1", + "priority": null + }, + { + "key": "system.evasion", + "mode": 2, + "value": "2", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "lastModifiedBy": null + }, + "_key": "!items.effects!6tr99y6wHaJJYy3J.m098fyKkAjTFZ6UJ" + }, + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "5mi9ku2R4paP579i", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [], + "disabled": false, + "duration": { + "startTime": null, + "combat": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976985351, + "modifiedTime": 1752976985351, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!items.effects!6tr99y6wHaJJYy3J.5mi9ku2R4paP579i" + } + ], + "folder": null, + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976985346, + "modifiedTime": 1752976987362, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "6tr99y6wHaJJYy3J", + "sort": 100000, + "_key": "!items!6tr99y6wHaJJYy3J" +} diff --git a/src/packs/beastforms/beastform_Household_Friend_uxBugKULjn7O1KQc.json b/src/packs/beastforms/beastform_Household_Friend_uxBugKULjn7O1KQc.json new file mode 100644 index 00000000..288afead --- /dev/null +++ b/src/packs/beastforms/beastform_Household_Friend_uxBugKULjn7O1KQc.json @@ -0,0 +1,166 @@ +{ + "name": "Household Friend", + "type": "beastform", + "img": "icons/creatures/mammals/cat-hunched-glowing-red.webp", + "system": { + "beastformType": "normal", + "tier": 1, + "tokenImg": "icons/creatures/mammals/cat-hunched-glowing-red.webp", + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": { + "height": null, + "width": null + }, + "mainTrait": "instinct", + "advantageOn": { + "u0mzlWihDHITgh1x": { + "value": "climb" + }, + "m53oFXA2SA5jAjWc": { + "value": "locate" + }, + "XLPn5Egg9mIuLyVP": { + "value": "protect" + } + }, + "features": [ + "Compendium.daggerheart.beastforms.Item.0tlnxIxlIw2hl1UE", + "Compendium.daggerheart.beastforms.Item.9ryNrYWjNtOT6DXN" + ], + "evolved": { + "mainTraitBonus": 0 + }, + "hybrid": { + "beastformOptions": 2, + "advantages": 2, + "features": 2 + }, + "examples": "Cat, Dog, Rabbit, etc." + }, + "effects": [ + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "d25tcdgssnDvekKR", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [ + { + "key": "system.rules.attack.trait", + "mode": 5, + "value": "instinct", + "priority": null + }, + { + "key": "system.rules.attack.range", + "mode": 5, + "value": "melee", + "priority": null + }, + { + "key": "system.rules.attack.damage.value", + "mode": 5, + "value": "1d8", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "lastModifiedBy": null + }, + "_key": "!items.effects!uxBugKULjn7O1KQc.d25tcdgssnDvekKR" + }, + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "idqGh9sm1zBLME1O", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [], + "disabled": false, + "duration": { + "startTime": null, + "combat": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976986453, + "modifiedTime": 1752976986453, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!items.effects!uxBugKULjn7O1KQc.idqGh9sm1zBLME1O" + } + ], + "folder": null, + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976986449, + "modifiedTime": 1752976987362, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "uxBugKULjn7O1KQc", + "sort": 300000, + "_key": "!items!uxBugKULjn7O1KQc" +} diff --git a/src/packs/beastforms/beastform_Legendary_Beast_mERwC7aMDoIKfZTf.json b/src/packs/beastforms/beastform_Legendary_Beast_mERwC7aMDoIKfZTf.json new file mode 100644 index 00000000..4588bc0a --- /dev/null +++ b/src/packs/beastforms/beastform_Legendary_Beast_mERwC7aMDoIKfZTf.json @@ -0,0 +1,154 @@ +{ + "name": "Legendary Beast", + "type": "beastform", + "img": "icons/creatures/magical/spirit-undead-horned-blue.webp", + "system": { + "beastformType": "evolved", + "tier": 3, + "tokenImg": "icons/creatures/magical/spirit-undead-horned-blue.webp", + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": { + "height": null, + "width": null + }, + "mainTrait": "agility", + "advantageOn": {}, + "features": [], + "evolved": { + "mainTraitBonus": 1, + "maximumTier": 1 + }, + "hybrid": { + "beastformOptions": 2, + "advantages": 2, + "features": 2 + }, + "examples": "" + }, + "effects": [ + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "cKAoI5JqYOtGBscd", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [ + { + "key": "system.bonuses.damage.physical.bonus", + "mode": 2, + "value": "6", + "priority": null + }, + { + "key": "system.bonuses.damage.magical.bonus", + "mode": 2, + "value": "6", + "priority": null + }, + { + "key": "system.evasion", + "mode": 2, + "value": "2", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "

    Pick a Tier 1 Beastform option and become a larger, more powerful version of that creature. While you’re in this form, you retain all traits and features from the original form and gain the following bonuses:

    • - A +6 bonus to damage rolls

    • - A +1 bonus to the trait used by this form

    • - A +2 bonus to evasion

    ", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "lastModifiedBy": null + }, + "_key": "!items.effects!mERwC7aMDoIKfZTf.cKAoI5JqYOtGBscd" + }, + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "LltLvTqjhk9RseV8", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [], + "disabled": false, + "duration": { + "startTime": null, + "combat": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976989252, + "modifiedTime": 1752976989252, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!items.effects!mERwC7aMDoIKfZTf.LltLvTqjhk9RseV8" + } + ], + "folder": null, + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976989245, + "modifiedTime": 1752976989245, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "mERwC7aMDoIKfZTf", + "sort": 0, + "_key": "!items!mERwC7aMDoIKfZTf" +} diff --git a/src/packs/beastforms/beastform_Mighty_Strider_LF68kGAcOTZQ81GB.json b/src/packs/beastforms/beastform_Mighty_Strider_LF68kGAcOTZQ81GB.json new file mode 100644 index 00000000..04049a81 --- /dev/null +++ b/src/packs/beastforms/beastform_Mighty_Strider_LF68kGAcOTZQ81GB.json @@ -0,0 +1,166 @@ +{ + "name": "Mighty Strider", + "type": "beastform", + "img": "icons/creatures/mammals/bull-horned-blue.webp", + "system": { + "beastformType": "normal", + "tier": 2, + "tokenImg": "icons/creatures/mammals/bull-horned-blue.webp", + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": { + "height": null, + "width": null + }, + "mainTrait": "agility", + "advantageOn": { + "Xxr01TwSerOS8qsd": { + "value": "leap" + }, + "cASut9AUij2Uf4zm": { + "value": "navigate" + }, + "XJie4FhCSwUCg9uN": { + "value": "sprint" + } + }, + "features": [ + "Compendium.daggerheart.beastforms.Item.YSolAjtv6Sfnai98", + "Compendium.daggerheart.beastforms.Item.P6tWFIZzXWyekw6r" + ], + "evolved": { + "mainTraitBonus": 0 + }, + "hybrid": { + "beastformOptions": 2, + "advantages": 2, + "features": 2 + }, + "examples": "Camel, Horse, Zebra, etc." + }, + "effects": [ + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "1KdhXARm6rg2fg22", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [ + { + "key": "system.rules.attack.damage.value", + "mode": 5, + "value": "d8 + 1", + "priority": null + }, + { + "key": "system.rules.attack.trait", + "mode": 5, + "value": "agility", + "priority": null + }, + { + "key": "system.rules.attack.range", + "mode": 5, + "value": "melee", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "lastModifiedBy": null + }, + "_key": "!items.effects!LF68kGAcOTZQ81GB.1KdhXARm6rg2fg22" + }, + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "ngEREmS8hzNyshak", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [], + "disabled": false, + "duration": { + "startTime": null, + "combat": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976987358, + "modifiedTime": 1752976987358, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!items.effects!LF68kGAcOTZQ81GB.ngEREmS8hzNyshak" + } + ], + "folder": null, + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976987354, + "modifiedTime": 1752976987362, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "LF68kGAcOTZQ81GB", + "sort": 200000, + "_key": "!items!LF68kGAcOTZQ81GB" +} diff --git a/src/packs/beastforms/beastform_Mythic_Hybrid_VI1DyowECDCDdsC1.json b/src/packs/beastforms/beastform_Mythic_Hybrid_VI1DyowECDCDdsC1.json new file mode 100644 index 00000000..0117a189 --- /dev/null +++ b/src/packs/beastforms/beastform_Mythic_Hybrid_VI1DyowECDCDdsC1.json @@ -0,0 +1,148 @@ +{ + "name": "Mythic Hybrid", + "type": "beastform", + "img": "icons/creatures/magical/humanoid-silhouette-glowing-pink.webp", + "system": { + "beastformType": "hybrid", + "tier": 4, + "tokenImg": "icons/creatures/magical/humanoid-silhouette-glowing-pink.webp", + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": { + "height": null, + "width": null + }, + "mainTrait": "strength", + "advantageOn": {}, + "features": [], + "evolved": { + "mainTraitBonus": 0 + }, + "hybrid": { + "beastformOptions": 3, + "advantages": 5, + "features": 3, + "maximumTier": 3 + }, + "examples": "" + }, + "effects": [ + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "dvqS0a0ur8xM2swY", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [ + { + "key": "system.traits.strength.value", + "mode": 2, + "value": "3", + "priority": null + }, + { + "key": "system.evasion", + "mode": 2, + "value": "2", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "

    To transform into this creature, mark 2 additional Stress. Choose any three Beastform options from Tiers 1–3. Choose a total of five advantages and three features from those options.

    ", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "lastModifiedBy": null + }, + "_key": "!items.effects!VI1DyowECDCDdsC1.dvqS0a0ur8xM2swY" + }, + { + "type": "beastform", + "name": "Beastform Transformation", + "img": "icons/creatures/abilities/paw-print-pair-purple.webp", + "_id": "xSMy4BO5PuqASEKW", + "system": { + "characterTokenData": { + "tokenImg": null, + "tokenRingImg": "icons/svg/mystery-man.svg", + "tokenSize": {} + }, + "advantageOn": [], + "featureIds": [], + "effectIds": [] + }, + "changes": [], + "disabled": false, + "duration": { + "startTime": null, + "combat": null + }, + "description": "", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976990470, + "modifiedTime": 1752976990470, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!items.effects!VI1DyowECDCDdsC1.xSMy4BO5PuqASEKW" + } + ], + "folder": null, + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976990466, + "modifiedTime": 1752976990466, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "VI1DyowECDCDdsC1", + "sort": 0, + "_key": "!items!VI1DyowECDCDdsC1" +} diff --git a/src/packs/beastforms/feature_Agile_sef9mwD2eRLZ64oV.json b/src/packs/beastforms/feature_Agile_sef9mwD2eRLZ64oV.json new file mode 100644 index 00000000..70fd6e11 --- /dev/null +++ b/src/packs/beastforms/feature_Agile_sef9mwD2eRLZ64oV.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Agile", + "img": "icons/skills/movement/arrow-upward-blue.webp", + "system": { + "description": "

    Your movement is silent, and you can spend a Hope to move up to Far range without rolling.

    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976877948, + "modifiedTime": 1752976906072, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "sef9mwD2eRLZ64oV", + "sort": 100000, + "_key": "!items!sef9mwD2eRLZ64oV" +} diff --git a/src/packs/beastforms/feature_Carrier_YSolAjtv6Sfnai98.json b/src/packs/beastforms/feature_Carrier_YSolAjtv6Sfnai98.json new file mode 100644 index 00000000..0ecd47f5 --- /dev/null +++ b/src/packs/beastforms/feature_Carrier_YSolAjtv6Sfnai98.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Carrier", + "img": "icons/creatures/abilities/bull-head-horns-glowing.webp", + "system": { + "description": "

    You can carry up to two willing allies with you when you move.

    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976866309, + "modifiedTime": 1752976907469, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "YSolAjtv6Sfnai98", + "sort": 200000, + "_key": "!items!YSolAjtv6Sfnai98" +} diff --git a/src/packs/beastforms/feature_Companion_0tlnxIxlIw2hl1UE.json b/src/packs/beastforms/feature_Companion_0tlnxIxlIw2hl1UE.json new file mode 100644 index 00000000..d7f35b73 --- /dev/null +++ b/src/packs/beastforms/feature_Companion_0tlnxIxlIw2hl1UE.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Companion", + "img": "icons/magic/life/heart-hand-gold-green-light.webp", + "system": { + "description": "

    When you Help an Ally, you can roll a d8 as your advantage die.

    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976848672, + "modifiedTime": 1752976908157, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "0tlnxIxlIw2hl1UE", + "sort": 0, + "_key": "!items!0tlnxIxlIw2hl1UE" +} diff --git a/src/packs/beastforms/feature_Evolved_MG21w4u5wXSGZ5WB.json b/src/packs/beastforms/feature_Evolved_MG21w4u5wXSGZ5WB.json new file mode 100644 index 00000000..520283bb --- /dev/null +++ b/src/packs/beastforms/feature_Evolved_MG21w4u5wXSGZ5WB.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Evolved", + "img": "icons/creatures/abilities/dragon-breath-purple.webp", + "system": { + "description": "

    Pick a Tier 1 Beastform option and become a larger, more powerful version of that creature. While you’re in this form, you retain all traits and features from the original form and gain the following bonuses:

    • A +6 bonus to damage rolls
    • A +1 bonus to the trait used by this form
    • A +2 bonus to Evasion
    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976852417, + "modifiedTime": 1752976908700, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "MG21w4u5wXSGZ5WB", + "sort": 50000, + "_key": "!items!MG21w4u5wXSGZ5WB" +} diff --git a/src/packs/beastforms/feature_Fragile_9ryNrYWjNtOT6DXN.json b/src/packs/beastforms/feature_Fragile_9ryNrYWjNtOT6DXN.json new file mode 100644 index 00000000..beae6eb2 --- /dev/null +++ b/src/packs/beastforms/feature_Fragile_9ryNrYWjNtOT6DXN.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Fragile", + "img": "icons/magic/life/heart-broken-red.webp", + "system": { + "description": "

    When you take Major or greater damage, you drop out of Beastform.

    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976855944, + "modifiedTime": 1752976909267, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "9ryNrYWjNtOT6DXN", + "sort": 150000, + "_key": "!items!9ryNrYWjNtOT6DXN" +} diff --git a/src/packs/beastforms/feature_Trample_P6tWFIZzXWyekw6r.json b/src/packs/beastforms/feature_Trample_P6tWFIZzXWyekw6r.json new file mode 100644 index 00000000..9e1ca0c5 --- /dev/null +++ b/src/packs/beastforms/feature_Trample_P6tWFIZzXWyekw6r.json @@ -0,0 +1,34 @@ +{ + "type": "feature", + "name": "Trample", + "img": "icons/creatures/mammals/ox-bull-horned-glowing-orange.webp", + "system": { + "description": "

    Mark a Stress to move up to Close range in a straight line and make an attack against all targets within Melee range of the line. Targets you succeed against take [[/r d8+1]] physical damage using your Proficiency and are temporarily Vulnerable.

    ", + "resource": null, + "originItemType": null, + "subType": null, + "originId": null, + "actions": [] + }, + "effects": [], + "folder": "uU8bIoZvXge0rLaU", + "ownership": { + "default": 0, + "k0gmQFlvrPvlTtbh": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976867812, + "modifiedTime": 1752976976609, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_id": "P6tWFIZzXWyekw6r", + "sort": -100000, + "_key": "!items!P6tWFIZzXWyekw6r" +} diff --git a/src/packs/beastforms/folders_Beastform_Features_uU8bIoZvXge0rLaU.json b/src/packs/beastforms/folders_Beastform_Features_uU8bIoZvXge0rLaU.json new file mode 100644 index 00000000..74cd56a6 --- /dev/null +++ b/src/packs/beastforms/folders_Beastform_Features_uU8bIoZvXge0rLaU.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Beastform Features", + "color": null, + "sorting": "a", + "_id": "uU8bIoZvXge0rLaU", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.346", + "systemId": "daggerheart", + "systemVersion": "0.0.1", + "createdTime": 1752976835537, + "modifiedTime": 1752976835537, + "lastModifiedBy": "k0gmQFlvrPvlTtbh" + }, + "_key": "!folders!uU8bIoZvXge0rLaU" +} diff --git a/styles/less/dialog/beastform/beastform-container.less b/styles/less/dialog/beastform/beastform-container.less deleted file mode 100644 index bf0d0cae..00000000 --- a/styles/less/dialog/beastform/beastform-container.less +++ /dev/null @@ -1,46 +0,0 @@ -@import '../../utils/colors.less'; - -.application.daggerheart.dh-style.views.beastform-selection { - .beastforms-container { - display: flex; - flex-direction: column; - gap: 4px; - - .beastforms-tier { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - gap: 4px; - - .beastform-container { - position: relative; - display: flex; - justify-content: center; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - cursor: pointer; - - &.inactive { - opacity: 0.4; - } - - img { - width: 100%; - border-radius: 6px; - } - - .beastform-title { - position: absolute; - top: 4px; - display: flex; - flex-wrap: wrap; - font-size: 16px; - margin: 0 4px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - color: light-dark(@beige, @dark); - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } - } - } -} diff --git a/styles/less/dialog/beastform/sheet.less b/styles/less/dialog/beastform/sheet.less index bd757b87..ce2e990d 100644 --- a/styles/less/dialog/beastform/sheet.less +++ b/styles/less/dialog/beastform/sheet.less @@ -1,15 +1,208 @@ @import '../../utils/colors.less'; @import '../../utils/mixin.less'; -.appTheme({ - &.beastform-selection { - .beastforms-container .beastforms-tier .beastform-container .beastform-title { - background-image: url('../assets/parchments/dh-parchment-dark.png'); +.theme-light .application.daggerheart.dh-style.views.beastform-selection .beastforms-outer-container { + .beastform-title { + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + + .advanced-container { + .advanced-forms-container { + .advanced-form-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + + .hybrid-data-wrapper .hybrid-data-container .hybrid-data-inner-container .hybrid-data { + background-image: url('../assets/parchments/dh-parchment-light.png'); + } + } + .form-features .form-feature { + background-image: url('../assets/parchments/dh-parchment-light.png'); } } -}, {}); +} .application.daggerheart.dh-style.views.beastform-selection { + .beastform-nav { + nav { + flex: 1; + + a { + white-space: nowrap; + } + } + } + + .beastform-title { + position: absolute; + top: 4px; + padding: 0 2px; + display: flex; + flex-wrap: wrap; + text-align: center; + font-size: 16px; + margin: 0 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url('../assets/parchments/dh-parchment-dark.png'); + } + + .beastforms-tier { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + gap: 4px; + + .beastform-container { + position: relative; + display: flex; + justify-content: center; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + cursor: pointer; + width: 120px; + height: 120px; + + &.inactive { + opacity: 0.4; + cursor: default; + } + + &.draggable { + cursor: pointer; + filter: drop-shadow(0 0 15px light-dark(@dark-blue, @golden)); + } + + img { + width: 100%; + border-radius: 6px; + } + } + } + + .advanced-container { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 12px; + transition: width 0.3s ease; + + h2 { + margin: 0; + } + + .advanced-forms-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 16px; + } + + .advanced-form-container { + position: relative; + display: flex; + justify-content: center; + border: 1px solid light-dark(#18162e, #f3c267); + border-radius: 6px; + cursor: pointer; + width: 120px; + height: 120px; + align-items: center; + text-align: center; + color: light-dark(@dark, @beige); + background-image: url('../assets/parchments/dh-parchment-dark.png'); + + &.hybridized { + flex-direction: column; + justify-content: start; + padding-top: 4px; + height: 200px; + width: 100%; + overflow: hidden; + + &.empty { + justify-content: center; + } + + .beastform-title { + position: initial; + } + } + + .empty-form { + display: flex; + flex-direction: column; + align-items: center; + + i { + font-size: 24px; + } + } + + .beastform-title-wrapper { + height: 44px; + } + + .hybrid-data-wrapper { + overflow: auto; + + .hybrid-data-container { + display: flex; + flex-direction: column; + gap: 2px; + padding: 0 4px; + + label { + font-weight: bold; + } + + .hybrid-data-inner-container { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 4px; + + .hybrid-data { + padding: 0 2px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url('../assets/parchments/dh-parchment-dark.png'); + opacity: 0.4; + + &.active { + opacity: 1; + } + } + } + } + } + } + + .form-features { + display: flex; + flex-direction: column; + gap: 8px; + padding: 0 16px; + margin: 8px 0; + + .form-feature { + display: flex; + flex-direction: column; + gap: 4px; + padding: 0 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url('../assets/parchments/dh-parchment-dark.png'); + + h4 { + text-align: center; + margin: 0; + } + } + } + } + footer { margin-top: 8px; display: flex; diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index f3e86518..66fd981d 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -12,7 +12,6 @@ @import './downtime/downtime-container.less'; -@import './beastform/beastform-container.less'; @import './beastform/sheet.less'; @import './character-creation/creation-action-footer.less'; diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 89370ec6..3470de37 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -18,6 +18,7 @@ @import './actors/environment/header.less'; @import './actors/environment/sheet.less'; +@import './items/beastform.less'; @import './items/class.less'; @import './items/domain-card.less'; @import './items/feature.less'; diff --git a/styles/less/sheets/items/beastform.less b/styles/less/sheets/items/beastform.less new file mode 100644 index 00000000..162c4925 --- /dev/null +++ b/styles/less/sheets/items/beastform.less @@ -0,0 +1,9 @@ +.application.sheet.daggerheart.dh-style.beastform { + .settings.tab { + .advantage-on-section { + display: flex; + flex-direction: column; + margin-top: 10px; + } + } +} diff --git a/styles/less/ui/chat/chat.less b/styles/less/ui/chat/chat.less index 6b5db1b9..c2c72d48 100644 --- a/styles/less/ui/chat/chat.less +++ b/styles/less/ui/chat/chat.less @@ -21,13 +21,8 @@ width: 80px; } - .downtime-refresh-container { - margin-top: @fullMargin; + .action-use-button { width: 100%; - - .refresh-title { - font-weight: bold; - } } } @@ -365,6 +360,7 @@ width: 80px; } } + button { &.inner-button { --button-size: 1.25rem; diff --git a/styles/less/ui/chat/sheet.less b/styles/less/ui/chat/sheet.less index 58281690..1c41f97e 100644 --- a/styles/less/ui/chat/sheet.less +++ b/styles/less/ui/chat/sheet.less @@ -4,6 +4,27 @@ .dice-title { display: none; } + + .message-content { + .enriched-effect { + display: flex; + align-items: center; + border: 1px solid black; + width: fit-content; + padding: 0 2px 0 0; + border-radius: 6px; + color: @dark; + background-image: url(../assets/parchments/dh-parchment-light.png); + + &:hover { + text-shadow: none; + } + + span { + white-space: nowrap; + } + } + } } fieldset.daggerheart.chat { diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less index 0060f74b..e6b660a5 100644 --- a/styles/less/ux/tooltip/tooltip.less +++ b/styles/less/ux/tooltip/tooltip.less @@ -74,6 +74,22 @@ } } + .tooltip-chips { + display: flex; + justify-content: space-around; + flex-wrap: wrap; + gap: 8px; + + .tooltip-chip { + font-size: 18px; + padding: 2px 4px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + color: light-dark(@dark, @beige); + background-image: url(../assets/parchments/dh-parchment-dark.png); + } + } + .tooltip-tags { width: 100%; display: flex; diff --git a/system.json b/system.json index bfa25df3..eaef71c1 100644 --- a/system.json +++ b/system.json @@ -144,6 +144,15 @@ "type": "Item", "private": false, "flags": {} + }, + { + "name": "beastforms", + "label": "Beastforms", + "system": "daggerheart", + "path": "packs/beastforms.db", + "type": "Item", + "private": false, + "flags": {} } ], "packFolders": [ @@ -157,7 +166,7 @@ "name": "Character Options", "sorting": "m", "color": "#000000", - "packs": ["ancestries", "communities", "classes", "subclasses", "domains"] + "packs": ["ancestries", "communities", "classes", "subclasses", "domains", "beastforms"] }, { "name": "Items", diff --git a/templates/dialogs/beastform/advanced.hbs b/templates/dialogs/beastform/advanced.hbs new file mode 100644 index 00000000..78a690da --- /dev/null +++ b/templates/dialogs/beastform/advanced.hbs @@ -0,0 +1,73 @@ +
    + {{#if (eq selected.system.beastformType 'evolved')}} +

    {{localize "DAGGERHEART.ITEMS.Beastform.evolve"}}

    + +
    + {{#if selectedBeastformEffect}} +
    +

    {{localize "DAGGERHEART.ITEMS.Beastform.evolvedFeatureTitle"}}

    +
    {{{selectedBeastformEffect.description}}}
    +
    + {{/if}} +
    + +
    + {{#if evolved.form}} +
    {{concat (localize "DAGGERHEART.CONFIG.BeastformType.evolved") " " evolved.form.name}}
    + + {{else}} +
    + + +
    + {{/if}} +
    + {{/if}} + {{#if (eq selected.system.beastformType 'hybrid')}} +

    {{localize "DAGGERHEART.ITEMS.Beastform.hybridize"}}

    + +
    + {{#if selectedBeastformEffect}} +
    +

    {{localize "DAGGERHEART.ITEMS.Beastform.hybridizeFeatureTitle"}}

    +
    {{{selectedBeastformEffect.description}}}
    +
    + {{/if}} +
    + +
    + {{#each hybridForms as | form key |}} +
    + {{#if form}} +
    +
    {{form.name}}
    +
    +
    +
    + +
    + {{#each form.system.features as | feature |}} +
    {{feature.name}}
    + {{/each}} +
    +
    +
    + +
    + {{#each form.system.advantageOn as | advantage id |}} +
    {{advantage.value}}
    + {{/each}} +
    +
    +
    + {{else}} +
    + + +
    + {{/if}} +
    + {{/each}} +
    + {{/if}} +
    \ No newline at end of file diff --git a/templates/dialogs/beastform/beastformTier.hbs b/templates/dialogs/beastform/beastformTier.hbs new file mode 100644 index 00000000..db307158 --- /dev/null +++ b/templates/dialogs/beastform/beastformTier.hbs @@ -0,0 +1,8 @@ +
    + {{#each tier.values as |form uuid|}} +
    + +
    {{form.value.name}}
    +
    + {{/each}} +
    \ No newline at end of file diff --git a/templates/dialogs/beastform/footer.hbs b/templates/dialogs/beastform/footer.hbs new file mode 100644 index 00000000..8ad53964 --- /dev/null +++ b/templates/dialogs/beastform/footer.hbs @@ -0,0 +1,3 @@ +
    + +
    \ No newline at end of file diff --git a/templates/dialogs/beastform/tabs.hbs b/templates/dialogs/beastform/tabs.hbs new file mode 100644 index 00000000..25bb2180 --- /dev/null +++ b/templates/dialogs/beastform/tabs.hbs @@ -0,0 +1,11 @@ +
    + +
    \ No newline at end of file diff --git a/templates/dialogs/beastformDialog.hbs b/templates/dialogs/beastformDialog.hbs deleted file mode 100644 index 05f87b89..00000000 --- a/templates/dialogs/beastformDialog.hbs +++ /dev/null @@ -1,18 +0,0 @@ -
    -
    - {{#each beastformTiers as |tier tierKey|}} -
    - {{tier.label}} - {{#each tier.values as |form uuid|}} -
    - -
    {{form.value.name}}
    -
    - {{/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 2fc61e2c..e3ecf859 100644 --- a/templates/sheets-settings/adversary-settings/details.hbs +++ b/templates/sheets-settings/adversary-settings/details.hbs @@ -19,7 +19,7 @@
    - {{localize "DAGGERHEART.GENERAL.hitPoints.plural"}} + {{localize "DAGGERHEART.GENERAL.HitPoints.plural"}} {{formGroup systemFields.resources.fields.hitPoints.fields.value value=document.system.resources.hitPoints.value label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.resources.hitPoints.value.label")}} {{formGroup systemFields.resources.fields.hitPoints.fields.max value=document.system.resources.hitPoints.max}}
    diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs index e7625f16..a7cfa3a6 100644 --- a/templates/sheets/actors/adversary/header.hbs +++ b/templates/sheets/actors/adversary/header.hbs @@ -20,7 +20,7 @@ {{#if (eq source.system.type 'horde')}}
    {{source.system.hordeHp}} - /{{localize "DAGGERHEART.GENERAL.hitPoints.short"}} + /{{localize "DAGGERHEART.GENERAL.HitPoints.short"}}
    {{/if}}
    diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index 8eb4dcb0..131fb33b 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -17,7 +17,7 @@
    -

    {{localize 'DAGGERHEART.GENERAL.attack.hitPoints.short'}}

    +

    {{localize 'DAGGERHEART.GENERAL.HitPoints.short'}}

    @@ -92,7 +92,7 @@
    -

    {{localize DAGGERHEART.GENERAL.experience.plural}}

    +

    {{localize "DAGGERHEART.GENERAL.experience.plural"}}

    @@ -113,6 +113,6 @@
    - +
    \ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index 05280127..b9ac28a6 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -47,7 +47,7 @@

    {{document.system.proficiency}}

    -

    {{localize "DAGGERHEART.GENERAL.proficienc"}}

    +

    {{localize "DAGGERHEART.GENERAL.proficiency"}}

    @@ -95,6 +95,9 @@
      + {{#if document.system.usedUnarmed}} + {{> 'daggerheart.inventory-item' item=document.system.usedUnarmed type='attack' isSidebar=true}} + {{/if}} {{#each document.items as |item|}} {{#if item.system.equipped}} {{> 'daggerheart.inventory-item' @@ -132,7 +135,7 @@
      -

      {{localize "DAGGERHEART.GENERAL.experience.Single"}}

      +

      {{localize "DAGGERHEART.GENERAL.experience.single"}}

      diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs index 5329e7b5..b58f6f44 100644 --- a/templates/sheets/global/partials/inventory-item-V2.hbs +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -15,13 +15,20 @@ Parameters: - showActions {boolean} : If true show feature's actions. --}} -
    • {{!-- Image --}}
      + data-action='{{ifThen (or (hasProperty item "use") (eq type 'attack')) "useItem" (ifThen (hasProperty item "toChat") "toChat" "editDoc") }}' + {{#unless hideTooltip}} + {{#if (eq type 'attack')}} + data-tooltip="#attack#{{item.actor.uuid}}" + {{else}} + data-tooltip="#item#{{item.uuid}}" + {{/if}} + {{/unless}} + > d20
      @@ -30,7 +37,20 @@ Parameters:
      {{!-- Item Name --}} -
      {{item.name}}
      +
      {{localize item.name}}
      + + {{!-- Attack Block Start --}} + {{#if (eq type 'attack')}} +
      +
      + {{localize 'DAGGERHEART.GENERAL.unarmed'}} +
      +
      + {{localize 'DAGGERHEART.CONFIG.ActionType.action'}} +
      +
      + {{/if}} + {{!-- Attack Block End --}} {{!-- Weapon Block Start --}} {{#if (eq type 'weapon')}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs new file mode 100644 index 00000000..b239e226 --- /dev/null +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -0,0 +1,207 @@ +
    • + +
      +
      + {{#if isCompanion}} + {{item.name}} + {{else}} +
      {{localize item.name}}
      + {{/if}} + {{#if (eq type 'weapon')}} +
      + {{#if isSidebar}} +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}} + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}} + - + {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} + {{#each item.system.attack.damage.parts.0.type as | type | }} + {{#with (lookup @root.config.GENERAL.damageTypes type)}} + + {{/with}} + {{/each}} +
      +
      + {{else}} +
      + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}} +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}} +
      +
      + {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} + ( + {{#each item.system.attack.damage.parts.0.type}} + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} + {{/each}} + ) +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} +
      + {{/if}} +
      + {{/if}} + {{#if (eq type 'armor')}} + {{#if isSidebar}} +
      +
      + {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: + {{item.system.baseScore}} +
      +
      + {{else}} +
      +
      + {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: + {{item.system.baseScore}} +
      +
      + {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: + {{item.system.baseThresholds.major}} + / + {{item.system.baseThresholds.severe}} +
      +
      + {{/if}} + {{/if}} + {{#if (eq type 'domainCard')}} + {{#if isSidebar}} +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} + - + {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} + - + {{item.system.recallCost}} + +
      +
      + {{else}} +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} +
      +
      + {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} +
      +
      + {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: + {{item.system.recallCost}} +
      +
      + {{/if}} + {{/if}} + {{#if (eq type 'effect')}} +
      +
      + {{localize (concat 'TYPES.Item.' item.parent.type)}} + : + {{item.parent.name}} +
      +
      + {{#if item.duration.duration}} + {{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}} + {{else}} + {{localize 'DAGGERHEART.EFFECTS.Duration.passive'}} + {{/if}} +
      + {{#each item.statuses as |status|}} +
      + {{localize (concat 'DAGGERHEART.CONFIG.Condition.' status '.name')}} +
      + {{/each}} +
      + {{/if}} + {{#if (eq type 'action')}} +
      +
      + {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}} +
      +
      + {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}} +
      +
      + {{/if}} + {{#if (eq type 'attack')}} +
      +
      + {{localize 'DAGGERHEART.GENERAL.unarmed'}} +
      +
      + {{localize 'DAGGERHEART.CONFIG.ActionType.action'}} +
      +
      + {{/if}} +
      + {{#if (and (not isSidebar) (eq item.system.resource.type 'simple'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{#if (and (not isSidebar) item.system.quantity)}} +
      + +
      + {{/if}} +
      + {{#unless hideControls}} + {{#if isActor}} +
      + {{#if (eq type 'actor')}} + + + + {{/if}} + {{#if (eq type 'adversary')}} + + + + + + + {{/if}} +
      + {{else}} +
      + {{#if (eq type 'weapon')}} + + + + {{/if}} + {{#if (eq type 'armor')}} + + + + {{/if}} + {{#if (eq type 'domainCard')}} + {{#unless item.system.inVault}} + + + + {{else}} + + + + {{/unless}} + + {{/if}} + + +
      + {{/if}} + {{else}} + + {{/unless}} +
      {{#unless isSidebar}}{{{item.system.description}}}{{/unless}}
      + {{#if (and (not isSidebar) (eq item.system.resource.type 'diceValue'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{#if featureType}} +
      + {{#each item.system.actions as | action |}} + + {{/each}} +
      + {{/if}} +
    • \ No newline at end of file diff --git a/templates/sheets/items/beastform/advanced.hbs b/templates/sheets/items/beastform/advanced.hbs new file mode 100644 index 00000000..aefec003 --- /dev/null +++ b/templates/sheets/items/beastform/advanced.hbs @@ -0,0 +1,29 @@ +
      + {{formGroup systemFields.beastformType value=source.system.beastformType localize=true blank=false}} + + {{#if (eq source.system.beastformType 'evolved')}} +
      + {{localize "DAGGERHEART.CONFIG.BeastformType.evolved"}} + + {{formGroup systemFields.evolved.fields.maximumTier value=source.system.evolved.maximumTier localize=true blank=false}} + {{formGroup systemFields.evolved.fields.mainTraitBonus value=source.system.evolved.mainTraitBonus localize=true}} +
      + {{/if}} + + {{#if (eq source.system.beastformType 'hybrid')}} +
      + {{localize "DAGGERHEART.CONFIG.BeastformType.hybrid"}} + + {{formGroup systemFields.hybrid.fields.maximumTier value=source.system.hybrid.maximumTier localize=true blank=false}} +
      + {{formGroup systemFields.hybrid.fields.beastformOptions value=source.system.hybrid.beastformOptions localize=true}} + {{formGroup systemFields.hybrid.fields.advantages value=source.system.hybrid.advantages localize=true}} + {{formGroup systemFields.hybrid.fields.features value=source.system.hybrid.features localize=true}} +
      +
      + {{/if}} +
      \ No newline at end of file diff --git a/templates/sheets/items/beastform/settings.hbs b/templates/sheets/items/beastform/settings.hbs index dec7d134..c0ea3965 100644 --- a/templates/sheets/items/beastform/settings.hbs +++ b/templates/sheets/items/beastform/settings.hbs @@ -3,12 +3,22 @@ data-tab='{{tabs.settings.id}}' data-group='{{tabs.settings.group}}' > -
      + {{#if (eq source.system.beastformType 'evolved')}} {{formGroup systemFields.tier value=source.system.tier localize=true}} - {{formGroup systemFields.examples value=source.system.examples localize=true}} -
      + {{else}} +
      + {{formGroup systemFields.tier value=source.system.tier localize=true}} + {{formGroup systemFields.mainTrait value=source.system.mainTrait blank=false localize=true}} +
      - {{formGroup systemFields.advantageOn value=source.system.advantageOn localize=true}} + {{#unless (eq source.system.beastformType 'hybrid')}} + {{formGroup systemFields.examples value=source.system.examples localize=true}} +
      + + +
      + {{/unless}} + {{/if}}
      {{localize "DAGGERHEART.ITEMS.Beastform.tokenTitle"}} diff --git a/templates/ui/chat/downtime.hbs b/templates/ui/chat/downtime.hbs index 98a7a227..cd50b3c6 100644 --- a/templates/ui/chat/downtime.hbs +++ b/templates/ui/chat/downtime.hbs @@ -2,10 +2,12 @@

      {{title}}

      - {{#each moves}} - {{this.name}} - -
      {{{this.description}}}
      - {{#if (gt this.actions.length 0)}}{{/if}} + {{#each moves as | move index |}} + {{move.name}} + +
      {{{move.description}}}
      + {{#each move.actions as | action index |}} + + {{/each}} {{/each}}
      \ No newline at end of file diff --git a/templates/ui/tooltip/action.hbs b/templates/ui/tooltip/action.hbs index 21b8e4d6..59e0be70 100644 --- a/templates/ui/tooltip/action.hbs +++ b/templates/ui/tooltip/action.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.description}}}
      +
      {{{description}}}
      {{#if item.uses.max}}

      {{localize "DAGGERHEART.GENERAL.uses"}}

      diff --git a/templates/ui/tooltip/adversary.hbs b/templates/ui/tooltip/adversary.hbs index 0a95c1ac..cb8a9bc0 100644 --- a/templates/ui/tooltip/adversary.hbs +++ b/templates/ui/tooltip/adversary.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      @@ -23,7 +23,7 @@
      - +
      {{item.system.resources.hitPoints.max}}
      diff --git a/templates/ui/tooltip/armor.hbs b/templates/ui/tooltip/armor.hbs index 456fb226..6bdf9ce3 100644 --- a/templates/ui/tooltip/armor.hbs +++ b/templates/ui/tooltip/armor.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      diff --git a/templates/ui/tooltip/attack.hbs b/templates/ui/tooltip/attack.hbs new file mode 100644 index 00000000..e07e1d55 --- /dev/null +++ b/templates/ui/tooltip/attack.hbs @@ -0,0 +1,29 @@ +
      +

      {{attack.name}}

      + +
      {{{description}}}
      + +
      +
      + + {{#with (lookup config.ACTOR.abilities attack.roll.trait) as | trait |}} +
      {{localize trait.label}}
      + {{/with}} +
      +
      + + {{#with (lookup config.GENERAL.range attack.range) as | range |}} +
      {{localize range.label}}
      + {{/with}} +
      + +
      + +
      {{{damageFormula attack parent}}}
      +
      +
      + +
      {{{damageSymbols attack.damage.parts}}}
      +
      +
      +
      \ No newline at end of file diff --git a/templates/ui/tooltip/beastform.hbs b/templates/ui/tooltip/beastform.hbs new file mode 100644 index 00000000..3afc0c84 --- /dev/null +++ b/templates/ui/tooltip/beastform.hbs @@ -0,0 +1,8 @@ +
      +

      {{item.name}}

      + +
      {{{description}}}
      + + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipChips.hbs" chips=item.system.advantageOn label=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.advantageOn.label")}} + {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.features label=(localize "DAGGERHEART.GENERAL.features")}} +
      \ No newline at end of file diff --git a/templates/ui/tooltip/consumable.hbs b/templates/ui/tooltip/consumable.hbs index 2c998b1d..f4c4c700 100644 --- a/templates/ui/tooltip/consumable.hbs +++ b/templates/ui/tooltip/consumable.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      diff --git a/templates/ui/tooltip/domainCard.hbs b/templates/ui/tooltip/domainCard.hbs index dad00b1b..ae2fe349 100644 --- a/templates/ui/tooltip/domainCard.hbs +++ b/templates/ui/tooltip/domainCard.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      diff --git a/templates/ui/tooltip/feature.hbs b/templates/ui/tooltip/feature.hbs index 17ff2db6..ce475664 100644 --- a/templates/ui/tooltip/feature.hbs +++ b/templates/ui/tooltip/feature.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }} {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.effects label=(localize "DAGGERHEART.GENERAL.Effect.plural") }} diff --git a/templates/ui/tooltip/miscellaneous.hbs b/templates/ui/tooltip/miscellaneous.hbs index 83014a88..b4912b4d 100644 --- a/templates/ui/tooltip/miscellaneous.hbs +++ b/templates/ui/tooltip/miscellaneous.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      {{> "systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs" features=item.system.actions label=(localize "DAGGERHEART.GENERAL.Action.plural") }}
      \ No newline at end of file diff --git a/templates/ui/tooltip/parts/tooltipChips.hbs b/templates/ui/tooltip/parts/tooltipChips.hbs new file mode 100644 index 00000000..a8d9ec44 --- /dev/null +++ b/templates/ui/tooltip/parts/tooltipChips.hbs @@ -0,0 +1,6 @@ +

      {{localize label}}

      +
      + {{#each chips as | chip |}} +
      {{ifThen chip.value chip.value chip}}
      + {{/each}} +
      \ No newline at end of file diff --git a/templates/ui/tooltip/parts/tooltipTags.hbs b/templates/ui/tooltip/parts/tooltipTags.hbs index ba4e875f..711945a0 100644 --- a/templates/ui/tooltip/parts/tooltipTags.hbs +++ b/templates/ui/tooltip/parts/tooltipTags.hbs @@ -6,7 +6,7 @@
      {{localize feature.name}}
      {{#if feature.img}}{{/if}}
      -
      {{{localize (ifThen feature.description feature.description feature.system.description)}}}
      +
      {{{localize (ifThen feature.description feature.description (ifThen feature.system.enrichedDescription feature.system.enrichedDescription feature.system.description))}}}
      {{/each}}
      \ No newline at end of file diff --git a/templates/ui/tooltip/weapon.hbs b/templates/ui/tooltip/weapon.hbs index 963b0714..8b152f22 100644 --- a/templates/ui/tooltip/weapon.hbs +++ b/templates/ui/tooltip/weapon.hbs @@ -1,7 +1,7 @@

      {{item.name}}

      -
      {{{item.system.description}}}
      +
      {{{description}}}
      From 3d723e7d8cc7e89b0b1eb49b192194705662776a Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 22 Jul 2025 01:51:49 +0200 Subject: [PATCH 57/58] [Feature] Roll Difficulty Support (#393) * Added difficulty support in rollDialog/rollMessage and [[/dr]] * Fixed /dr chat command --- daggerheart.mjs | 56 +++++-------------- lang/en.json | 3 + module/documents/chatMessage.mjs | 8 +-- module/enrichers/DualityRollEnricher.mjs | 50 +++++++++++++++-- .../less/dialog/dice-roll/roll-selection.less | 4 ++ templates/dialogs/dice-roll/rollSelection.hbs | 10 +++- templates/ui/chat/duality-roll.hbs | 12 +++- 7 files changed, 89 insertions(+), 54 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 872da5f3..da04334c 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -8,7 +8,7 @@ import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs' import { NarrativeCountdowns } from './module/applications/ui/countdowns.mjs'; import { DualityRollColor } from './module/data/settings/Appearance.mjs'; import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/dice/_module.mjs'; -import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs'; +import { enrichedDualityRoll, renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs'; import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs'; import { registerCountdownHooks } from './module/data/countdowns.mjs'; import { @@ -188,49 +188,21 @@ Hooks.on('chatMessage', (_, message) => { } const traitValue = rollCommand.trait?.toLowerCase(); - const advantageState = rollCommand.advantage ? true : rollCommand.disadvantage ? false : null; + const advantage = rollCommand.advantage + ? CONFIG.DH.ACTIONS.advandtageState.advantage.value + : rollCommand.disadvantage + ? CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + : undefined; + const difficulty = rollCommand.difficulty; - // Target not required if an attribute is not used. - const target = traitValue ? getCommandTarget() : undefined; - if (target || !traitValue) { - new Promise(async (resolve, reject) => { - const trait = target ? target.system.traits[traitValue] : undefined; - if (traitValue && !trait) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.attributeFaulty')); - reject(); - return; - } - - const title = traitValue - ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { - ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) - }) - : game.i18n.localize('DAGGERHEART.GENERAL.duality'); - - const config = { - title: title, - roll: { - trait: traitValue - }, - data: { - traits: { - [traitValue]: trait - } - }, - source: target, - hasSave: false, - dialog: { configure: false }, - evaluate: true, - advantage: rollCommand.advantage == true, - disadvantage: rollCommand.disadvantage == true - }; - - await CONFIG.Dice.daggerheart['DualityRoll'].build(config); - - resolve(); - }); - } + const target = getCommandTarget(); + const title = traitValue + ? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { + ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) + }) + : game.i18n.localize('DAGGERHEART.GENERAL.duality'); + enrichedDualityRoll({ traitValue, target, difficulty, title, label: 'test', actionType: null, advantage }); return false; } }); diff --git a/lang/en.json b/lang/en.json index ae6ccdf4..017d542d 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1196,6 +1196,7 @@ }, "Roll": { "attack": "Attack Roll", + "difficulty": "Roll (Difficulty {difficulty})", "primaryWeaponAttack": "Primary Weapon Attack Roll", "secondaryWeaponAttack": "Secondary Weapon Attack Roll", "spellcast": "Spellcast Roll", @@ -1310,6 +1311,7 @@ "single": "Experience", "plural": "Experiences" }, + "failure": "Failure", "fear": "Fear", "features": "Features", "formula": "Formula", @@ -1345,6 +1347,7 @@ "scalable": "Scalable", "situationalBonus": "Situational Bonus", "stress": "Stress", + "success": "Success", "take": "Take", "Target": { "single": "Target", diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 409b4dd0..46f95633 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -1,10 +1,10 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { async renderHTML() { if (this.system.messageTemplate) - this.content = await foundry.applications.handlebars.renderTemplate( - this.system.messageTemplate, - this.system - ); + this.content = await foundry.applications.handlebars.renderTemplate(this.system.messageTemplate, { + ...this.system, + _source: this.system._source + }); /* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */ const html = await super.renderHTML(); diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index a2da2805..dde82a48 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -21,19 +21,34 @@ function getDualityMessage(roll) { ? game.i18n.localize(abilities[roll.trait].label) : game.i18n.localize('DAGGERHEART.GENERAL.duality'); + const advantage = roll.advantage + ? CONFIG.DH.ACTIONS.advandtageState.advantage.value + : roll.disadvantage + ? CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + : undefined; + const advantageLabel = + advantage === CONFIG.DH.ACTIONS.advandtageState.advantage.value + ? 'Advantage' + : advantage === CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + ? 'Disadvantage' + : undefined; + const dualityElement = document.createElement('span'); dualityElement.innerHTML = ` `; @@ -43,16 +58,39 @@ function getDualityMessage(roll) { export const renderDualityButton = async event => { const button = event.currentTarget, traitValue = button.dataset.trait?.toLowerCase(), - target = getCommandTarget(); + target = getCommandTarget(), + difficulty = button.dataset.difficulty, + advantage = button.dataset.advantage ? Number(button.dataset.advantage) : undefined; + + await enrichedDualityRoll( + { + traitValue, + target, + difficulty, + title: button.dataset.title, + label: button.dataset.label, + actionType: button.dataset.actionType, + advantage + }, + event + ); +}; + +export const enrichedDualityRoll = async ( + { traitValue, target, difficulty, title, label, actionType, advantage }, + event +) => { if (!target) return; const config = { - event: event, - title: button.dataset.title, + event: event ?? {}, + title: title, roll: { modifier: traitValue ? target.system.traits[traitValue].value : null, - label: button.dataset.label, - type: button.dataset.actionType ?? null // Need check + label: label, + difficulty: difficulty, + advantage, + type: actionType ?? null // Need check, }, chatMessage: { template: 'systems/daggerheart/templates/ui/chat/duality-roll.hbs' diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index af6c3c20..5e36990e 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -131,13 +131,17 @@ display: flex; align-items: center; gap: 16px; + height: 32px; .roll-mode-select { width: min-content; + height: 100%; } button { flex: 1; + height: 100%; + font-family: @font-body; } } } diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index ca918145..e3129e30 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -136,14 +136,22 @@
    {{/unless}} + {{localize "DAGGERHEART.GENERAL.formula"}}: {{@root.formula}} +
    {{else}} diff --git a/templates/ui/chat/duality-roll.hbs b/templates/ui/chat/duality-roll.hbs index 5e67d3a3..8076e093 100644 --- a/templates/ui/chat/duality-roll.hbs +++ b/templates/ui/chat/duality-roll.hbs @@ -140,7 +140,17 @@
    -
    {{roll.result.label}}
    +
    + {{#unless (eq _source.roll.success undefined)}} + {{#if _source.roll.success}} + {{localize "DAGGERHEART.GENERAL.success"}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.result.label}} + {{else}} + {{localize "DAGGERHEART.GENERAL.failure"}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.result.label}} + {{/if}} + {{else}} + {{roll.result.label}} + {{/unless}} +
    {{roll.total}}
    From 2721dfe417ccc55696e18370434bf3c958e1b6b7 Mon Sep 17 00:00:00 2001 From: Murilo Brito <91566541+moliloo@users.noreply.github.com> Date: Mon, 21 Jul 2025 22:04:17 -0300 Subject: [PATCH 58/58] Feature/enhance style applications (#390) * enhance settings style applications * enhance beastform application and fix action selection style * Start-aligned downtime move fieldsets * requested changes * fixing continue button style * fixing double scroll bars in char sheet * set currency above item list * fix experience not appearing in sidebar --------- Co-authored-by: WBHarry --- lang/en.json | 3 +- module/applications/dialogs/_module.mjs | 1 - .../applications/dialogs/beastformDialog.mjs | 19 +- .../dialogs/costSelectionDialog.mjs | 66 -- module/applications/dialogs/d20RollDialog.mjs | 6 +- .../settings/appearanceSettings.mjs | 7 +- .../settings/automationSettings.mjs | 7 +- .../settings/homebrewSettings.mjs | 7 +- .../settings/rangeMeasurementSettings.mjs | 7 +- .../settings/variantRuleSettings.mjs | 7 +- .../sheets/api/application-mixin.mjs | 8 +- module/data/action/beastformAction.mjs | 4 +- module/systemRegistration/handlebars.mjs | 3 +- styles/less/dialog/beastform/sheet.less | 4 + .../less/dialog/dice-roll/roll-selection.less | 2 + styles/less/global/elements.css | 607 ++++++++++++++++++ styles/less/global/elements.less | 48 ++ .../sheets/actors/character/features.less | 2 +- .../sheets/actors/character/inventory.less | 7 +- .../less/sheets/actors/character/loadout.less | 2 +- .../less/sheets/actors/character/sheet.less | 2 +- styles/less/ui/settings/settings.less | 4 + templates/dialogs/beastform/header.hbs | 3 + templates/dialogs/beastform/tabs.hbs | 18 +- templates/dialogs/dice-roll/costSelection.hbs | 49 +- templates/dialogs/dice-roll/rollSelection.hbs | 14 +- templates/settings/appearance-settings.hbs | 3 + templates/settings/automation-settings.hbs | 3 + templates/settings/homebrew-settings.hbs | 7 +- .../settings/range-measurement-settings.hbs | 3 + templates/settings/variant-rules.hbs | 4 + .../sheets/actors/character/inventory.hbs | 48 +- templates/sheets/actors/character/sidebar.hbs | 2 +- 33 files changed, 823 insertions(+), 154 deletions(-) delete mode 100644 module/applications/dialogs/costSelectionDialog.mjs create mode 100644 styles/less/global/elements.css create mode 100644 templates/dialogs/beastform/header.hbs diff --git a/lang/en.json b/lang/en.json index 017d542d..fc51a610 100755 --- a/lang/en.json +++ b/lang/en.json @@ -756,7 +756,7 @@ }, "SelectAction": { "selectType": "Select Action Type", - "selectAction": "Select Action" + "selectAction": "Action Selection" }, "Traits": { "agility": { @@ -1519,6 +1519,7 @@ } }, "Menu": { + "title": "Daggerheart Game Settings", "automation": { "name": "Automation Settings", "label": "Configure Automation", diff --git a/module/applications/dialogs/_module.mjs b/module/applications/dialogs/_module.mjs index 0722c747..bbffb791 100644 --- a/module/applications/dialogs/_module.mjs +++ b/module/applications/dialogs/_module.mjs @@ -1,5 +1,4 @@ export { default as BeastformDialog } from './beastformDialog.mjs'; -export { default as costSelectionDialog } from './costSelectionDialog.mjs'; export { default as d20RollDialog } from './d20RollDialog.mjs'; export { default as DamageDialog } from './damageDialog.mjs'; export { default as DamageReductionDialog } from './damageReductionDialog.mjs'; diff --git a/module/applications/dialogs/beastformDialog.mjs b/module/applications/dialogs/beastformDialog.mjs index 1d6725ad..3c35b542 100644 --- a/module/applications/dialogs/beastformDialog.mjs +++ b/module/applications/dialogs/beastformDialog.mjs @@ -1,9 +1,11 @@ const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; export default class BeastformDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(configData) { + constructor(configData, item) { super(); + this.item = item; + this.configData = configData; this.selected = null; this.evolved = { form: null }; @@ -14,11 +16,14 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'views', 'dh-style', 'beastform-selection'], + classes: ['daggerheart', 'views', 'dialog', 'dh-style', 'beastform-selection'], position: { width: 600, height: 'auto' }, + window: { + icon: 'fa-solid fa-paw' + }, actions: { selectBeastform: this.selectBeastform, toggleHybridFeature: this.toggleHybridFeature, @@ -34,11 +39,12 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat }; get title() { - return game.i18n.localize('DAGGERHEART.ITEMS.Beastform.dialogTitle'); + return this.item.name; } /** @override */ static PARTS = { + header: { template: 'systems/daggerheart/templates/dialogs/beastform/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/dialogs/beastform/tabs.hbs' }, beastformTier: { template: 'systems/daggerheart/templates/dialogs/beastform/beastformTier.hbs' }, advanced: { template: 'systems/daggerheart/templates/dialogs/beastform/advanced.hbs' }, @@ -262,12 +268,13 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat if (!options.submitted) this.selected = null; } - static async configure(configData) { + static async configure(configData, item) { return new Promise(resolve => { - const app = new this(configData); + const app = new this(configData, item); + const featureItem = item; app.addEventListener( 'close', - () => resolve({ selected: app.selected, evolved: app.evolved, hybrid: app.hybrid }), + () => resolve({ selected: app.selected, evolved: app.evolved, hybrid: app.hybrid, item: featureItem }), { once: true } ); app.render({ force: true }); diff --git a/module/applications/dialogs/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs deleted file mode 100644 index abb79e6a..00000000 --- a/module/applications/dialogs/costSelectionDialog.mjs +++ /dev/null @@ -1,66 +0,0 @@ -const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; - -export default class CostSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(costs, uses, action, resolve) { - super({}); - this.costs = costs; - this.uses = uses; - this.action = action; - this.resolve = resolve; - } - - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'damage-selection'], - position: { - width: 400, - height: 'auto' - }, - actions: { - sendCost: this.sendCost - }, - form: { - handler: this.updateForm, - submitOnChange: true, - closeOnSubmit: false - } - }; - - /** @override */ - static PARTS = { - costSelection: { - id: 'costSelection', - template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs' - } - }; - - /* -------------------------------------------- */ - - /** @inheritDoc */ - get title() { - return `Cost Options`; - } - - async _prepareContext(_options) { - const updatedCosts = this.action.calcCosts(this.costs), - updatedUses = this.action.calcUses(this.uses); - return { - costs: updatedCosts, - uses: updatedUses, - canUse: this.action.hasCost(updatedCosts) && this.action.hasUses(updatedUses) - }; - } - - static async updateForm(event, _, formData) { - const data = foundry.utils.expandObject(formData.object); - this.costs = foundry.utils.mergeObject(this.costs, data.costs); - this.uses = foundry.utils.mergeObject(this.uses, data.uses); - this.render(true); - } - - static sendCost(event) { - event.preventDefault(); - this.resolve({ costs: this.action.getRealCosts(this.costs), uses: this.uses }); - this.close(); - } -} diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 67ca77e6..53fc9d69 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -22,7 +22,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio id: 'roll-selection', classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'roll-selection'], position: { - width: 550 + width: 'auto' }, window: { icon: 'fa-solid fa-dice' @@ -52,10 +52,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio rollSelection: { id: 'rollSelection', template: 'systems/daggerheart/templates/dialogs/dice-roll/rollSelection.hbs' - }, - costSelection: { - id: 'costSelection', - template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs' } }; diff --git a/module/applications/settings/appearanceSettings.mjs b/module/applications/settings/appearanceSettings.mjs index 006bab78..78f067c7 100644 --- a/module/applications/settings/appearanceSettings.mjs +++ b/module/applications/settings/appearanceSettings.mjs @@ -12,14 +12,17 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App } get title() { - return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.appearance.name'); + return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title'); } static DEFAULT_OPTIONS = { tag: 'form', id: 'daggerheart-appearance-settings', - classes: ['daggerheart', 'setting', 'dh-style'], + classes: ['daggerheart', 'dialog', 'dh-style', 'setting'], position: { width: '600', height: 'auto' }, + window: { + icon: 'fa-solid fa-gears' + }, actions: { reset: this.reset, save: this.save diff --git a/module/applications/settings/automationSettings.mjs b/module/applications/settings/automationSettings.mjs index 75105b16..489bae02 100644 --- a/module/applications/settings/automationSettings.mjs +++ b/module/applications/settings/automationSettings.mjs @@ -12,14 +12,17 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App } get title() { - return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.automation.name'); + return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title'); } static DEFAULT_OPTIONS = { tag: 'form', id: 'daggerheart-automation-settings', - classes: ['daggerheart', 'setting', 'dh-style'], + classes: ['daggerheart', 'dh-style', 'dialog', 'setting'], position: { width: '600', height: 'auto' }, + window: { + icon: 'fa-solid fa-gears' + }, actions: { reset: this.reset, save: this.save diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index e516be03..d2861595 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -13,14 +13,17 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli } get title() { - return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.homebrew.name'); + return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title'); } static DEFAULT_OPTIONS = { tag: 'form', id: 'daggerheart-homebrew-settings', - classes: ['daggerheart', 'setting', 'dh-style'], + classes: ['daggerheart', 'dh-style', 'dialog', 'setting'], position: { width: '600', height: 'auto' }, + window: { + icon: 'fa-solid fa-gears' + }, actions: { addItem: this.addItem, editItem: this.editItem, diff --git a/module/applications/settings/rangeMeasurementSettings.mjs b/module/applications/settings/rangeMeasurementSettings.mjs index e9fd332e..410b2cbe 100644 --- a/module/applications/settings/rangeMeasurementSettings.mjs +++ b/module/applications/settings/rangeMeasurementSettings.mjs @@ -12,14 +12,17 @@ export default class DhRangeMeasurementSettings extends HandlebarsApplicationMix } get title() { - return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.automation.name'); + return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title'); } static DEFAULT_OPTIONS = { tag: 'form', id: 'daggerheart-automation-settings', - classes: ['daggerheart', 'setting', 'dh-style'], + classes: ['daggerheart', 'dialog', 'dh-style', 'setting'], position: { width: '600', height: 'auto' }, + window: { + icon: 'fa-solid fa-gears' + }, actions: { reset: this.reset, save: this.save diff --git a/module/applications/settings/variantRuleSettings.mjs b/module/applications/settings/variantRuleSettings.mjs index 059e1726..3bc11a68 100644 --- a/module/applications/settings/variantRuleSettings.mjs +++ b/module/applications/settings/variantRuleSettings.mjs @@ -12,14 +12,17 @@ export default class DHVariantRuleSettings extends HandlebarsApplicationMixin(Ap } get title() { - return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.variantRules.name'); + return game.i18n.localize('DAGGERHEART.SETTINGS.Menu.title'); } static DEFAULT_OPTIONS = { tag: 'form', id: 'daggerheart-appearance-settings', - classes: ['daggerheart', 'setting', 'dh-style'], + classes: ['daggerheart', 'dialog', 'dh-style', 'setting'], position: { width: '600', height: 'auto' }, + window: { + icon: 'fa-solid fa-gears' + }, actions: { reset: this.reset, save: this.save diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 65a43123..6597f130 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -441,9 +441,13 @@ export default function DHApplicationMixin(Base) { const { type: actionType } = (await foundry.applications.api.DialogV2.input({ window: { title: 'Select Action Type' }, + classes: ['daggerheart', 'dh-style'], content: await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } + { + types: CONFIG.DH.ACTIONS.actionTypes, + itemName: game.i18n.localize('DAGGERHEART.CONFIG.SelectAction.selectAction') + } ), ok: { label: game.i18n.format('DOCUMENT.Create', { @@ -581,7 +585,7 @@ export default function DHApplicationMixin(Base) { const { actionId } = target.closest('[data-action-id]').dataset; const { actions, attack } = doc.system; const action = attack?.id === actionId ? attack : actions?.find(a => a.id === actionId); - await action.use(event); + await action.use(event, doc); } /** diff --git a/module/data/action/beastformAction.mjs b/module/data/action/beastformAction.mjs index 2116662c..bb926dac 100644 --- a/module/data/action/beastformAction.mjs +++ b/module/data/action/beastformAction.mjs @@ -10,7 +10,9 @@ export default class DhBeastformAction extends DHBaseAction { const abort = await this.handleActiveTransformations(); if (abort) return; - const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig); + const item = args[0]; + + const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig, item); if (!selected) return; await this.transform(selected, evolved, hybrid); diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index b15bf820..fc6decd3 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -30,6 +30,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs', 'systems/daggerheart/templates/ui/tooltip/parts/tooltipChips.hbs', 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', - 'systems/daggerheart/templates/dialogs/downtime/activities.hbs' + 'systems/daggerheart/templates/dialogs/downtime/activities.hbs', + 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs' ]); }; diff --git a/styles/less/dialog/beastform/sheet.less b/styles/less/dialog/beastform/sheet.less index ce2e990d..26b6072a 100644 --- a/styles/less/dialog/beastform/sheet.less +++ b/styles/less/dialog/beastform/sheet.less @@ -1,5 +1,6 @@ @import '../../utils/colors.less'; @import '../../utils/mixin.less'; +@import '../../utils/fonts.less'; .theme-light .application.daggerheart.dh-style.views.beastform-selection .beastforms-outer-container { .beastform-title { @@ -209,6 +210,9 @@ button { flex: 1; + font-family: @font-body; + font-weight: bold; + height: 40px; } } } diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index 5e36990e..4ee2ee1f 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -13,6 +13,7 @@ display: flex; flex-direction: column; gap: 12px; + max-width: 550px; .dices-section { display: flex; @@ -141,6 +142,7 @@ button { flex: 1; height: 100%; + font-weight: bold; font-family: @font-body; } } diff --git a/styles/less/global/elements.css b/styles/less/global/elements.css new file mode 100644 index 00000000..2644d93f --- /dev/null +++ b/styles/less/global/elements.css @@ -0,0 +1,607 @@ +@keyframes glow { + 0% { + box-shadow: 0 0 1px 1px #f3c267; + } + 100% { + box-shadow: 0 0 2px 2px #f3c267; + } +} +@keyframes glow-dark { + 0% { + box-shadow: 0 0 1px 1px #18162e; + } + 100% { + box-shadow: 0 0 2px 2px #18162e; + } +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v25/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v25/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel Decorative'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzeldecorative/v18/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); +} +.application.sheet.daggerheart.dh-style h1 { + font-family: 'Cinzel Decorative', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h2, +.application.sheet.daggerheart.dh-style h3 { + font-family: 'Cinzel', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h4 { + font-family: 'Montserrat', sans-serif; + font-size: 14px; + border: none; + font-weight: 700; + margin: 0; + text-shadow: none; + color: #f3c267; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h5 { + font-size: 14px; + color: #f3c267; + margin: 0; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style p, +.application.sheet.daggerheart.dh-style span { + font-family: 'Montserrat', sans-serif; +} +.application.sheet.daggerheart.dh-style small { + font-family: 'Montserrat', sans-serif; + opacity: 0.8; +} +.application.dh-style { + border: 1px solid light-dark(#18162e, #f3c267); +} +.application.dh-style input[type='text'], +.application.dh-style input[type='number'] { + background: light-dark(transparent, transparent); + border-radius: 6px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.05); + backdrop-filter: blur(9.5px); + -webkit-backdrop-filter: blur(9.5px); + outline: none; + color: light-dark(#18162e, #f3c267); + border: 1px solid light-dark(#222, #efe6d8); +} +.application.dh-style input[type='text']:hover[type='text'], +.application.dh-style input[type='number']:hover[type='text'], +.application.dh-style input[type='text']:hover[type='number'], +.application.dh-style input[type='number']:hover[type='number'], +.application.dh-style input[type='text']:focus[type='text'], +.application.dh-style input[type='number']:focus[type='text'], +.application.dh-style input[type='text']:focus[type='number'], +.application.dh-style input[type='number']:focus[type='number'] { + background: light-dark(rgba(0, 0, 0, 0.05), rgba(24, 22, 46, 0.33)); + box-shadow: none; + outline: 2px solid light-dark(#222, #efe6d8); +} +.application.dh-style input[type='text']:disabled[type='text'], +.application.dh-style input[type='number']:disabled[type='text'], +.application.dh-style input[type='text']:disabled[type='number'], +.application.dh-style input[type='number']:disabled[type='number'] { + outline: 2px solid transparent; + cursor: not-allowed; +} +.application.dh-style input[type='text']:disabled[type='text']:hover, +.application.dh-style input[type='number']:disabled[type='text']:hover, +.application.dh-style input[type='text']:disabled[type='number']:hover, +.application.dh-style input[type='number']:disabled[type='number']:hover { + background: transparent; +} +.application.dh-style input[type='checkbox']:checked::after, +.application.dh-style input[type='radio']:checked::after { + color: light-dark(#222, #f3c267); +} +.application.dh-style input[type='checkbox']:checked::before, +.application.dh-style input[type='radio']:checked::before { + color: light-dark(#22222240, #f3c26740); +} +.application.dh-style input[type='checkbox']::before, +.application.dh-style input[type='radio']::before { + color: light-dark(#22222240, #f3c26740); +} +.application.dh-style button { + background: light-dark(transparent, #f3c267); + border: 1px solid light-dark(#18162e, #18162e); + color: light-dark(#18162e, #18162e); + outline: none; + box-shadow: none; +} +.application.dh-style button:hover { + background: light-dark(rgba(0, 0, 0, 0.3), #18162e); + color: light-dark(#18162e, #f3c267); +} +.application.dh-style button.glow { + animation: glow 0.75s infinite alternate; +} +.application.dh-style button:disabled { + background: light-dark(transparent, #f3c267); + color: light-dark(#18162e, #18162e); + opacity: 0.6; + cursor: not-allowed; +} +.application.dh-style button:disabled:hover { + background: light-dark(transparent, #f3c267); + color: light-dark(#18162e, #18162e); +} +.application.dh-style select { + background: light-dark(transparent, transparent); + color: light-dark(#222, #efe6d8); + font-family: 'Montserrat', sans-serif; + outline: 2px solid transparent; + border: 1px solid light-dark(#222, #efe6d8); +} +.application.dh-style select:focus, +.application.dh-style select:hover { + outline: 2px solid light-dark(#222, #efe6d8); + box-shadow: none; +} +.application.dh-style select option, +.application.dh-style select optgroup { + color: #efe6d8; + background-color: #18162e; + border-radius: 6px; +} +.application.dh-style select:disabled { + opacity: 0.6; + outline: 2px solid transparent; + cursor: not-allowed; +} +.application.dh-style multi-select { + position: relative; + height: 34px; +} +.application.dh-style multi-select .tags { + justify-content: flex-start; + margin: 4px; + height: inherit; +} +.application.dh-style multi-select .tags .tag { + padding: 0.3rem 0.5rem; + color: light-dark(#18162e, #f3c267); + background-color: light-dark(#18162e10, #f3c26740); + font-family: 'Montserrat', sans-serif; + border-radius: 3px; + transition: 0.13s ease-out; + gap: 0.5rem; + z-index: 1; +} +.application.dh-style multi-select .tags .tag .remove { + font-size: 10px; +} +.application.dh-style multi-select select { + position: absolute; + height: inherit; + outline: initial; +} +.application.dh-style p { + margin: 0; +} +.application.dh-style ul { + margin: 0; + padding: 0; + list-style: none; +} +.application.dh-style li { + margin: 0; +} +.application.dh-style a:hover, +.application.dh-style a.active { + font-weight: bold; + text-shadow: 0 0 8px light-dark(#18162e, #f3c267); +} +.application.dh-style fieldset { + align-items: center; + margin-top: 5px; + border-radius: 6px; + border-color: light-dark(#18162e, #f3c267); +} +.application.dh-style fieldset.glassy { + background-color: light-dark(#18162e10, #f3c26710); + border-color: transparent; +} +.application.dh-style fieldset.glassy legend { + padding: 2px 12px; + border-radius: 3px; + background-color: light-dark(#18162e, #f3c267); + color: light-dark(#efe6d8, #18162e); +} +.application.dh-style fieldset.fit-height { + height: 95%; +} +.application.dh-style fieldset.flex { + display: flex; + gap: 20px; +} +.application.dh-style fieldset.flex.wrap { + flex-wrap: wrap; + gap: 10px 20px; +} +.application.dh-style fieldset.flex .inline-child { + flex: 1; +} +.application.dh-style fieldset .list-w-img { + padding: 5px; +} +.application.dh-style fieldset .list-w-img label { + flex: 1; +} +.application.dh-style fieldset .list-w-img img { + width: 2rem; + height: 2rem; +} +.application.dh-style fieldset.one-column { + display: flex; + flex-direction: column; + align-items: start; + gap: 10px; + min-height: 64px; + flex: 1; +} +.application.dh-style fieldset.one-column > .one-column { + width: 100%; +} +.application.dh-style fieldset.two-columns { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 10px; +} +.application.dh-style fieldset.two-columns.even { + grid-template-columns: 1fr 1fr; +} +.application.dh-style fieldset.two-columns .full-width { + grid-column: span 2; +} +.application.dh-style fieldset legend { + font-family: 'Montserrat', sans-serif; + font-weight: bold; + color: light-dark(#18162e, #f3c267); +} +.application.dh-style fieldset input[type='text'], +.application.dh-style fieldset input[type='number'] { + color: light-dark(#222, #efe6d8); + font-family: 'Montserrat', sans-serif; + transition: all 0.3s ease; + outline: 2px solid transparent; +} +.application.dh-style fieldset input[type='text']:focus, +.application.dh-style fieldset input[type='number']:focus, +.application.dh-style fieldset input[type='text']:hover, +.application.dh-style fieldset input[type='number']:hover { + outline: 2px solid light-dark(#222, #efe6d8); +} +.application.dh-style fieldset[disabled], +.application.dh-style fieldset.child-disabled .form-group, +.application.dh-style fieldset select[disabled], +.application.dh-style fieldset input[disabled] { + opacity: 0.5; +} +.application.dh-style fieldset.child-disabled .form-group { + pointer-events: none; +} +.application.dh-style fieldset .nest-inputs { + display: flex; + align-items: center; + width: 100%; + gap: 5px; +} +.application.dh-style fieldset .nest-inputs .btn { + padding-top: 15px; +} +.application.dh-style fieldset .nest-inputs .image { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 6px; + border: none; +} +.application.dh-style fieldset .nest-inputs > .checkbox { + align-self: end; +} +.application.dh-style fieldset .form-group { + width: 100%; +} +.application.dh-style fieldset .form-group label { + font-family: 'Montserrat', sans-serif; + font-weight: bold; + font-size: smaller; +} +.application.dh-style fieldset .form-group.checkbox { + width: fit-content; + display: flex; + align-items: center; +} +.application.dh-style fieldset .form-group.checkbox .form-fields { + height: 32px; + align-content: center; +} +.application.dh-style fieldset:has(.list-w-img) { + gap: 0; +} +.application.dh-style .two-columns { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 10px; +} +.application.dh-style .two-columns.even { + grid-template-columns: 1fr 1fr; +} +.application.dh-style line-div { + display: block; + height: 1px; + width: 100%; + border-bottom: 1px solid light-dark(#18162e, #f3c267); + mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%); +} +.application.dh-style side-line-div { + display: block; + height: 1px; + width: 100%; + border-bottom: 1px solid light-dark(#18162e, #f3c267); + mask-image: linear-gradient(270deg, transparent 0%, black 100%); +} +.application.dh-style side-line-div.invert { + mask-image: linear-gradient(270deg, black 0%, transparent 100%); +} +.application.dh-style .item-description { + opacity: 1; + transform: translateY(0); + grid-column: 1/-1; + transition: opacity 0.3s ease-out, transform 0.3s ease-out; +} +.application.dh-style .item-description.invisible { + height: 0; + opacity: 0; + overflow: hidden; + transform: translateY(-20px); + transform-origin: top; +} +.application.dh-style .item-buttons { + grid-column: span 3; + display: flex; + gap: 8px; + flex-wrap: wrap; +} +.application.dh-style .item-buttons button { + white-space: nowrap; +} +.application.setting.dh-style fieldset h2, +.application.setting.dh-style fieldset h3, +.application.setting.dh-style fieldset h4 { + margin: 8px 0 4px; + text-align: center; +} +.application.setting.dh-style fieldset .title-hint { + font-size: 12px; + font-variant: small-caps; + text-align: center; +} +.application.setting.dh-style fieldset .field-section .split-section { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} +.application.setting.dh-style fieldset .label-container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} +.application.setting.dh-style fieldset .label-container label { + align-self: center; + text-align: center; +} +.application.setting.dh-style footer { + margin-top: 8px; + display: flex; + gap: 8px; +} +.application.setting.dh-style footer button { + flex: 1; +} +.application.setting.dh-style .form-group { + display: flex; + justify-content: space-between; + align-items: center; +} +.application.setting.dh-style .form-group label { + font-size: 16px; + font-family: 'Montserrat', sans-serif; +} +.application.setting.dh-style .form-group .form-fields { + display: flex; + gap: 4px; + align-items: center; +} +.system-daggerheart .tagify { + background: light-dark(transparent, transparent); + border: 1px solid light-dark(#222, #efe6d8); + height: 34px; + --tags-disabled-bg: none; + --tags-border-color: none; + --tags-hover-border-color: none; + --tags-focus-border-color: none; + --tag-border-radius: 3px; + --tag-bg: light-dark(#18162e, #f3c267); + --tag-remove-btn-color: light-dark(#18162e, #f3c267); + --tag-hover: light-dark(#18162e, #f3c267); + --tag-text-color: light-dark(#efe6d8, #222); + --tag-text-color--edit: light-dark(#efe6d8, #222); + --tag-pad: 0.3em 0.5em; + --tag-inset-shadow-size: 1.2em; + --tag-invalid-color: #d39494; + --tag-invalid-bg: rgba(211, 148, 148, 0.5); + --tag--min-width: 1ch; + --tag--max-width: 100%; + --tag-hide-transition: 0.3s; + --tag-remove-bg: light-dark(#18162e40, #f3c26740); + --tag-remove-btn-color: light-dark(#efe6d8, #222); + --tag-remove-btn-bg: none; + --tag-remove-btn-bg--hover: light-dark(#efe6d8, #222); + --input-color: inherit; + --placeholder-color: light-dark(#efe6d815, #22222215); + --placeholder-color-focus: light-dark(#efe6d815, #22222215); + --loader-size: 0.8em; + --readonly-striped: 1; + border-radius: 3px; + margin-right: 1px; +} +.system-daggerheart .tagify tag div { + display: flex; + justify-content: space-between; + align-items: center; + height: 22px; +} +.system-daggerheart .tagify tag div span { + font-weight: 400; +} +.system-daggerheart .tagify tag div img { + margin-left: 8px; + height: 20px; + width: 20px; +} +.system-daggerheart .tagify__dropdown { + border: 1px solid light-dark(#222, #efe6d8) !important; + font-family: 'Montserrat', sans-serif; + color: light-dark(#222, #efe6d8); +} +.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper { + background-image: url(../assets/parchments/dh-parchment-dark.png); + background-color: transparent; + border: 0; + color: light-dark(#222, #efe6d8); +} +.system-daggerheart .tagify__dropdown .tagify__dropdown__wrapper .tagify__dropdown__item--active { + background-color: light-dark(#222, #efe6d8); + color: light-dark(#efe6d8, #222); +} +.system-daggerheart.theme-light .tagify__dropdown .tagify__dropdown__wrapper { + background-image: url(../assets/parchments/dh-parchment-light.png); +} +.theme-light .application.sheet.dh-style button.glow { + animation: glow-dark 0.75s infinite alternate; +} +.theme-light .application .component.dh-style.card-preview-container { + background-image: url('../assets/parchments/dh-parchment-light.png'); +} +.theme-light .application .component.dh-style.card-preview-container .preview-text-container { + background-image: url(../assets/parchments/dh-parchment-dark.png); +} +.theme-light .application .component.dh-style.card-preview-container .preview-selected-icon-container { + background-image: url(../assets/parchments/dh-parchment-dark.png); + color: var(--color-light-5); +} +.application .component.dh-style.card-preview-container { + position: relative; + border-radius: 6px; + border: 2px solid var(--color-tabs-border); + display: flex; + flex-direction: column; + aspect-ratio: 0.75; + background-image: url('../assets/parchments/dh-parchment-dark.png'); +} +.application .component.dh-style.card-preview-container.selectable { + cursor: pointer; +} +.application .component.dh-style.card-preview-container.disabled { + pointer-events: none; + opacity: 0.4; +} +.application .component.dh-style.card-preview-container .preview-image-outer-container { + position: relative; + display: flex; + align-items: center; + justify-content: center; +} +.application .component.dh-style.card-preview-container .preview-image-container { + flex: 1; + border-radius: 4px 4px 0 0; +} +.application .component.dh-style.card-preview-container .preview-text-container { + flex: 1; + border-radius: 0 0 4px 4px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: 18px; + text-align: center; + color: var(--color-text-selection-bg); + background-image: url(../assets/parchments/dh-parchment-light.png); +} +.application .component.dh-style.card-preview-container .preview-empty-container { + pointer-events: none; + position: relative; + display: flex; + align-items: center; + justify-content: center; + flex: 1; +} +.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container { + width: 100%; + display: flex; + justify-content: center; +} +.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-add-icon { + font-size: 48px; +} +.application .component.dh-style.card-preview-container .preview-empty-container .preview-empty-inner-container .preview-empty-subtext { + position: absolute; + top: 10%; + font-size: 18px; + font-variant: small-caps; + text-align: center; +} +.application .component.dh-style.card-preview-container .preview-selected-icon-container { + position: absolute; + height: 54px; + width: 54px; + border-radius: 50%; + border: 2px solid; + font-size: 48px; + display: flex; + align-items: center; + justify-content: center; + background-image: url(../assets/parchments/dh-parchment-light.png); + color: var(--color-dark-5); +} +.application .component.dh-style.card-preview-container .preview-selected-icon-container i { + position: relative; + right: 2px; +} diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index b9509b38..29a2c1dd 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -15,6 +15,10 @@ color: light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark, @beige); + &::placeholder { + color: light-dark(@dark-40, @beige-50); + } + &:hover[type='text'], &:hover[type='number'], &:focus[type='text'], @@ -48,6 +52,24 @@ } } + input[type='range'] { + &::-webkit-slider-runnable-track { + background: light-dark(@dark-blue-40, @golden-40); + } + &::-moz-range-track { + background: light-dark(@dark-blue-40, @golden-40); + } + &::-webkit-slider-thumb { + background: light-dark(@dark-blue, @golden); + border: none; + border-radius: 50%; + + &:hover { + box-shadow: 0 0 8px light-dark(@dark-blue, @golden); + } + } + } + button { background: light-dark(transparent, @golden); border: 1px solid light-dark(@dark-blue, @dark-blue); @@ -296,6 +318,31 @@ } } + .scalable-input { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + + .form-group { + width: fit-content; + .nest-inputs { + width: fit-content; + } + } + + label { + font-family: @font-body; + font-size: 14px; + font-weight: 400; + + &.modifier-label { + width: 6ch; + text-align: end; + } + } + } + &:has(.list-w-img) { gap: 0; } @@ -413,6 +460,7 @@ label { font-size: 16px; + font-family: @font-body; } .form-fields { diff --git a/styles/less/sheets/actors/character/features.less b/styles/less/sheets/actors/character/features.less index 767544c1..c2feb6b1 100644 --- a/styles/less/sheets/actors/character/features.less +++ b/styles/less/sheets/actors/character/features.less @@ -11,7 +11,7 @@ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); padding: 20px 0; padding-top: 10px; - height: 95%; + height: 84%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; diff --git a/styles/less/sheets/actors/character/inventory.less b/styles/less/sheets/actors/character/inventory.less index 43669d7f..eac1065d 100644 --- a/styles/less/sheets/actors/character/inventory.less +++ b/styles/less/sheets/actors/character/inventory.less @@ -56,7 +56,7 @@ overflow-y: auto; mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); padding: 20px 0; - height: 80%; + height: 73%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; @@ -65,6 +65,11 @@ .currency-section { display: flex; gap: 10px; + padding: 10px 10px 0; + + input { + color: light-dark(@dark, @beige); + } } } } diff --git a/styles/less/sheets/actors/character/loadout.less b/styles/less/sheets/actors/character/loadout.less index cdf0e2e4..b7863e77 100644 --- a/styles/less/sheets/actors/character/loadout.less +++ b/styles/less/sheets/actors/character/loadout.less @@ -97,7 +97,7 @@ overflow-y: auto; mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%); padding: 20px 0; - height: 90%; + height: 84%; scrollbar-width: thin; scrollbar-color: light-dark(@dark-blue, @golden) transparent; diff --git a/styles/less/sheets/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less index 8afd7404..3d19a3b2 100644 --- a/styles/less/sheets/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -10,7 +10,7 @@ height: 100%; width: 100%; padding-bottom: 0; - overflow: auto; + overflow-x: auto; .character-sidebar-sheet { grid-row: 1 / span 2; diff --git a/styles/less/ui/settings/settings.less b/styles/less/ui/settings/settings.less index 3bd200a2..580c79ca 100644 --- a/styles/less/ui/settings/settings.less +++ b/styles/less/ui/settings/settings.less @@ -15,6 +15,10 @@ grid-template-columns: 1fr 1fr; } } + + &.start-align { + align-self: flex-start; + } } .setting-group-field { diff --git a/templates/dialogs/beastform/header.hbs b/templates/dialogs/beastform/header.hbs new file mode 100644 index 00000000..ac92d14c --- /dev/null +++ b/templates/dialogs/beastform/header.hbs @@ -0,0 +1,3 @@ +
    +

    {{localize 'DAGGERHEART.ITEMS.Beastform.dialogTitle'}}

    +
    \ No newline at end of file diff --git a/templates/dialogs/beastform/tabs.hbs b/templates/dialogs/beastform/tabs.hbs index 25bb2180..0a252dd6 100644 --- a/templates/dialogs/beastform/tabs.hbs +++ b/templates/dialogs/beastform/tabs.hbs @@ -1,11 +1,15 @@
    \ No newline at end of file diff --git a/templates/dialogs/dice-roll/costSelection.hbs b/templates/dialogs/dice-roll/costSelection.hbs index 91d0229f..d376c749 100644 --- a/templates/dialogs/dice-roll/costSelection.hbs +++ b/templates/dialogs/dice-roll/costSelection.hbs @@ -1,21 +1,30 @@ -
    - {{#if uses}} -
    -
    - - +
    + {{localize 'DAGGERHEART.GENERAL.Cost.single'}} +
      + {{#if uses}} +
    • +
      +
      + + +
      +
      + +
    • + {{/if}} + {{#each costs as | cost index |}} +
    • +
      +
      + + +
      -
    - {{/if}} - {{#each costs as | cost index |}} -
    -
    - - - {{#if scalable}} - - {{/if}} -
    -
    - {{/each}} -
    \ No newline at end of file + {{#if scalable}} + + {{/if}} + + + {{/each}} + +
    \ No newline at end of file diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index e3129e30..995be022 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -135,6 +135,9 @@ {{#if (eq @root.rollType 'DualityRoll')}}{{localize "DAGGERHEART.GENERAL.situationalBonus"}}{{/if}} + {{#if (or costs uses)}} + {{> 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs'}} + {{/if}} {{/unless}} {{localize "DAGGERHEART.GENERAL.formula"}}: {{@root.formula}} @@ -155,9 +158,14 @@ {{else}} - + {{#if (or costs uses)}} + {{> 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs'}} + {{/if}} +
    + +
    {{/if}} \ No newline at end of file diff --git a/templates/settings/appearance-settings.hbs b/templates/settings/appearance-settings.hbs index da435c75..f297a28f 100644 --- a/templates/settings/appearance-settings.hbs +++ b/templates/settings/appearance-settings.hbs @@ -1,4 +1,7 @@
    +
    +

    {{localize 'DAGGERHEART.SETTINGS.Menu.appearance.name'}}

    +
    {{formGroup settingFields.schema.fields.displayFear value=settingFields._source.displayFear localize=true}} {{formGroup settingFields.schema.fields.showGenericStatusEffects value=settingFields._source.showGenericStatusEffects localize=true}} diff --git a/templates/settings/automation-settings.hbs b/templates/settings/automation-settings.hbs index 910ace56..9ffe5049 100644 --- a/templates/settings/automation-settings.hbs +++ b/templates/settings/automation-settings.hbs @@ -1,4 +1,7 @@
    +
    +

    {{localize 'DAGGERHEART.SETTINGS.Menu.automation.name'}}

    +
    {{formGroup settingFields.schema.fields.hopeFear.fields.gm value=settingFields._source.hopeFear.gm localize=true}} diff --git a/templates/settings/homebrew-settings.hbs b/templates/settings/homebrew-settings.hbs index 07ae0c1f..ada2c7a9 100644 --- a/templates/settings/homebrew-settings.hbs +++ b/templates/settings/homebrew-settings.hbs @@ -1,4 +1,7 @@
    +
    +

    {{localize 'DAGGERHEART.SETTINGS.Menu.homebrew.name'}}

    +
    {{formGroup settingFields.schema.fields.maxFear value=settingFields._source.maxFear localize=true}}

    {{localize "DAGGERHEART.SETTINGS.Homebrew.FIELDS.traitArray.label"}}

    @@ -27,7 +30,7 @@
    {{localize "DAGGERHEART.SETTINGS.Homebrew.downtimeMoves"}} -
    +
    {{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}} @@ -48,7 +51,7 @@
    -
    +
    {{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}} diff --git a/templates/settings/range-measurement-settings.hbs b/templates/settings/range-measurement-settings.hbs index 36357d57..617d1899 100644 --- a/templates/settings/range-measurement-settings.hbs +++ b/templates/settings/range-measurement-settings.hbs @@ -1,4 +1,7 @@
    +
    +

    {{localize 'DAGGERHEART.SETTINGS.Menu.range.name'}}

    +
    {{formGroup settingFields.schema.fields.enabled value=settingFields._source.enabled localize=true}} {{formGroup settingFields.schema.fields.melee value=settingFields._source.melee localize=true}} diff --git a/templates/settings/variant-rules.hbs b/templates/settings/variant-rules.hbs index 1ee18b99..75a5534b 100644 --- a/templates/settings/variant-rules.hbs +++ b/templates/settings/variant-rules.hbs @@ -1,4 +1,8 @@
    +
    +

    {{localize 'DAGGERHEART.SETTINGS.Menu.variantRules.name'}}

    +
    +
    diff --git a/templates/sheets/actors/character/inventory.hbs b/templates/sheets/actors/character/inventory.hbs index 9610d8e2..24f7836f 100644 --- a/templates/sheets/actors/character/inventory.hbs +++ b/templates/sheets/actors/character/inventory.hbs @@ -12,6 +12,30 @@
    +
    +
    + {{localize this.inventory.currency.coins}} + {{formInput systemFields.gold.fields.coins value=source.system.gold.coins enriched=source.system.gold.coins + localize=true toggled=true}} +
    +
    + {{localize this.inventory.currency.handfulls}} + {{formInput systemFields.gold.fields.handfulls value=source.system.gold.handfulls + enriched=source.system.gold.handfulls localize=true toggled=true}} +
    +
    + {{localize this.inventory.currency.bags}} + {{formInput systemFields.gold.fields.bags value=source.system.gold.bags enriched=source.system.gold.bags + localize=true toggled=true}} +
    +
    + {{localize this.inventory.currency.chests}} + {{formInput systemFields.gold.fields.chests value=source.system.gold.chests + enriched=source.system.gold.chests localize=true toggled=true}} +
    + +
    +
    {{> 'daggerheart.inventory-items' title='TYPES.Item.weapon' @@ -44,28 +68,4 @@ canCreate=true }}
    - -
    -
    - {{localize this.inventory.currency.coins}} - {{formInput systemFields.gold.fields.coins value=source.system.gold.coins enriched=source.system.gold.coins - localize=true toggled=true}} -
    -
    - {{localize this.inventory.currency.handfulls}} - {{formInput systemFields.gold.fields.handfulls value=source.system.gold.handfulls - enriched=source.system.gold.handfulls localize=true toggled=true}} -
    -
    - {{localize this.inventory.currency.bags}} - {{formInput systemFields.gold.fields.bags value=source.system.gold.bags enriched=source.system.gold.bags - localize=true toggled=true}} -
    -
    - {{localize this.inventory.currency.chests}} - {{formInput systemFields.gold.fields.chests value=source.system.gold.chests - enriched=source.system.gold.chests localize=true toggled=true}} -
    - -
    \ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index b9ac28a6..6ed47fc7 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -142,7 +142,7 @@ {{#each document.system.experiences as |experience id|}}
    - +{{experience.total}} + +{{experience.value}}