diff --git a/daggerheart.mjs b/daggerheart.mjs index 4f7ad0ca..65163a19 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -34,15 +34,6 @@ Hooks.once('init', () => { CONFIG.TextEditor.enrichers.push(...enricherConfig); - CONFIG.statusEffects = [ - ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), - ...Object.values(SYSTEM.GENERAL.conditions).map(x => ({ - ...x, - name: game.i18n.localize(x.name), - systemEffect: true - })) - ]; - CONFIG.Dice.daggerheart = { DHRoll: DHRoll, DualityRoll: DualityRoll, @@ -160,6 +151,17 @@ Hooks.once('init', () => { return handlebarsRegistration(); }); +Hooks.on('setup', () => { + CONFIG.statusEffects = [ + ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), + ...Object.values(SYSTEM.GENERAL.conditions()).map(x => ({ + ...x, + name: game.i18n.localize(x.name), + systemEffect: true + })) + ]; +}); + Hooks.on('ready', async () => { ui.resources = new CONFIG.ui.resources(); if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear !== 'hide') diff --git a/lang/en.json b/lang/en.json index de1c8ade..dfb3d911 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2309,6 +2309,9 @@ "label": "Apply Effects", "hint": "Automatically apply effects. Targets must be selected before the action is made and Reaction Roll Automation must be different than Never. Bypass users permissions." } + }, + "summaryMessages": { + "label": "Summary Messages" } }, "defeated": { @@ -2430,6 +2433,7 @@ "action": { "title": "Action" }, + "appliedTo": "Applied To", "applyEffect": { "title": "Apply Effects - {name}" }, @@ -2439,6 +2443,11 @@ "rollHealing": "Roll Healing", "applyEffect": "Apply Effects" }, + "clearResource": "Clear {quantity} {resource}", + "damageSummary": { + "title": "Damage Applied", + "healingTitle": "Healing Applied" + }, "damageRoll": { "title": "Damage - {damage}", "dealDamageToTargets": "Damage Hit Targets", @@ -2460,12 +2469,16 @@ "dualityRoll": { "abilityCheckTitle": "{ability} Check" }, + "effectSummary": { + "title": "Effects Applied" + }, "featureTitle": "Class Feature", "healingRoll": { "title": "Heal - {damage}", "heal": "Heal", "applyHealing": "Apply Healing" }, + "markResource": "Mark {quantity} {resource}", "refreshMessage": { "title": "Feature Refresh", "header": "Refreshed" diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 900dcfbc..cb12f8f0 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -164,28 +164,31 @@ export const healingTypes = { } }; -export const defeatedConditions = { - defeated: { - id: 'defeated', - name: 'DAGGERHEART.CONFIG.Condition.defeated.name', - img: 'icons/magic/control/fear-fright-mask-orange.webp', - description: 'DAGGERHEART.CONFIG.Condition.defeated.description' - }, - unconscious: { - id: 'unconscious', - name: 'DAGGERHEART.CONFIG.Condition.unconscious.name', - img: 'icons/magic/control/sleep-bubble-purple.webp', - description: 'DAGGERHEART.CONFIG.Condition.unconscious.description' - }, - dead: { - id: 'dead', - name: 'DAGGERHEART.CONFIG.Condition.dead.name', - img: 'icons/magic/death/grave-tombstone-glow-teal.webp', - description: 'DAGGERHEART.CONFIG.Condition.dead.description' - } +export const defeatedConditions = () => { + const defeated = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated; + return { + defeated: { + id: 'defeated', + name: 'DAGGERHEART.CONFIG.Condition.defeated.name', + img: defeated.defeatedIcon, + description: 'DAGGERHEART.CONFIG.Condition.defeated.description' + }, + unconscious: { + id: 'unconscious', + name: 'DAGGERHEART.CONFIG.Condition.unconscious.name', + img: defeated.unconsciousIcon, + description: 'DAGGERHEART.CONFIG.Condition.unconscious.description' + }, + dead: { + id: 'dead', + name: 'DAGGERHEART.CONFIG.Condition.dead.name', + img: defeated.deadIcon, + description: 'DAGGERHEART.CONFIG.Condition.dead.description' + } + }; }; -export const conditions = { +export const conditions = () => ({ vulnerable: { id: 'vulnerable', name: 'DAGGERHEART.CONFIG.Condition.vulnerable.name', @@ -204,8 +207,8 @@ export const conditions = { img: 'icons/magic/control/debuff-chains-shackle-movement-red.webp', description: 'DAGGERHEART.CONFIG.Condition.restrained.description' }, - ...defeatedConditions -}; + ...defeatedConditions() +}); export const defaultRestOptions = { shortRest: () => ({ diff --git a/module/data/chat-message/_modules.mjs b/module/data/chat-message/_modules.mjs index 7e301906..67046248 100644 --- a/module/data/chat-message/_modules.mjs +++ b/module/data/chat-message/_modules.mjs @@ -1,9 +1,11 @@ import DHAbilityUse from './abilityUse.mjs'; import DHActorRoll from './actorRoll.mjs'; +import DHSystemMessage from './systemMessage.mjs'; export const config = { abilityUse: DHAbilityUse, adversaryRoll: DHActorRoll, damageRoll: DHActorRoll, - dualityRoll: DHActorRoll + dualityRoll: DHActorRoll, + systemMessage: DHSystemMessage }; diff --git a/module/data/chat-message/systemMessage.mjs b/module/data/chat-message/systemMessage.mjs new file mode 100644 index 00000000..cd2a06a1 --- /dev/null +++ b/module/data/chat-message/systemMessage.mjs @@ -0,0 +1,9 @@ +export default class DHSystemMessage extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields; + + return { + useTitle: new fields.BooleanField({ initial: true }) + }; + } +} diff --git a/module/data/fields/action/damageField.mjs b/module/data/fields/action/damageField.mjs index 26d720c0..43623c94 100644 --- a/module/data/fields/action/damageField.mjs +++ b/module/data/fields/action/damageField.mjs @@ -81,6 +81,9 @@ export default class DamageField extends fields.SchemaField { static async applyDamage(config, targets = null, force = false) { targets ??= config.targets.filter(target => target.hit); if (!config.damage || !targets?.length || (!DamageField.getApplyAutomation() && !force)) return; + + const targetDamage = []; + const damagePromises = []; for (let target of targets) { const actor = fromUuidSync(target.actorId); if (!actor) continue; @@ -95,9 +98,45 @@ export default class DamageField extends fields.SchemaField { }); } - if (config.hasHealing) actor.takeHealing(config.damage); - else actor.takeDamage(config.damage, config.isDirect); + if (config.hasHealing) + damagePromises.push( + actor + .takeHealing(config.damage) + .then(updates => targetDamage.push({ token: actor.token ?? actor.prototypeToken, updates })) + ); + else + damagePromises.push( + actor + .takeDamage(config.damage, config.isDirect) + .then(updates => targetDamage.push({ token: actor.token ?? actor.prototypeToken, updates })) + ); } + + Promise.all(damagePromises).then(async _ => { + const summaryMessageSettings = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.Automation + ).summaryMessages; + if (!summaryMessageSettings.damage) return; + + const cls = getDocumentClass('ChatMessage'); + const msg = { + type: 'systemMessage', + user: game.user.id, + speaker: cls.getSpeaker(), + title: game.i18n.localize( + `DAGGERHEART.UI.Chat.damageSummary.${config.hasHealing ? 'healingTitle' : 'title'}` + ), + content: await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/ui/chat/damageSummary.hbs', + { + targets: targetDamage + } + ) + }; + + cls.create(msg); + }); } /** diff --git a/module/data/fields/action/effectsField.mjs b/module/data/fields/action/effectsField.mjs index 0f205d72..887607ba 100644 --- a/module/data/fields/action/effectsField.mjs +++ b/module/data/fields/action/effectsField.mjs @@ -46,17 +46,48 @@ export default class EffectsField extends fields.ArrayField { */ static async applyEffects(targets) { if (!this.effects?.length || !targets?.length) return; + let effects = this.effects; - targets.forEach(async token => { + const messageTargets = []; + targets.forEach(async baseToken => { if (this.hasSave && token.saved.success === true) effects = this.effects.filter(e => e.onSave === true); if (!effects.length) return; + + const token = canvas.tokens.get(baseToken.id); + if (!token) return; + messageTargets.push(token.document); + effects.forEach(async e => { - const actor = canvas.tokens.get(token.id)?.actor, - effect = this.item.effects.get(e._id); - if (!actor || !effect) return; - await EffectsField.applyEffect(effect, actor); + const effect = this.item.effects.get(e._id); + if (!token.actor || !effect) return; + await EffectsField.applyEffect(effect, token.actor); }); }); + + if (messageTargets.length === 0) return; + + const summaryMessageSettings = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.Automation + ).summaryMessages; + if (!summaryMessageSettings.effects) return; + + const cls = getDocumentClass('ChatMessage'); + const msg = { + type: 'systemMessage', + user: game.user.id, + speaker: cls.getSpeaker(), + title: game.i18n.localize('DAGGERHEART.UI.Chat.effectSummary.title'), + content: await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/ui/chat/effectSummary.hbs', + { + effects: this.effects.map(e => this.item.effects.get(e._id)), + targets: messageTargets + } + ) + }; + + cls.create(msg); } /** diff --git a/module/data/settings/Automation.mjs b/module/data/settings/Automation.mjs index beefac0b..43000277 100644 --- a/module/data/settings/Automation.mjs +++ b/module/data/settings/Automation.mjs @@ -2,6 +2,10 @@ export default class DhAutomation extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; return { + summaryMessages: new fields.SchemaField({ + damage: new fields.BooleanField({ initial: true, label: 'DAGGERHEART.GENERAL.damage' }), + effects: new fields.BooleanField({ initial: true, label: 'DAGGERHEART.GENERAL.Effect.plural' }) + }), hopeFear: new fields.SchemaField({ gm: new fields.BooleanField({ required: true, @@ -64,21 +68,39 @@ export default class DhAutomation extends foundry.abstract.DataModel { }), characterDefault: new fields.StringField({ required: true, - choices: CONFIG.DH.GENERAL.defeatedConditions, - initial: CONFIG.DH.GENERAL.defeatedConditions.unconscious.id, + choices: () => CONFIG.DH.GENERAL.defeatedConditions(), + initial: 'unconscious', label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.characterDefault.label' }), adversaryDefault: new fields.StringField({ required: true, - choices: CONFIG.DH.GENERAL.defeatedConditions, - initial: CONFIG.DH.GENERAL.defeatedConditions.defeated.id, + choices: () => CONFIG.DH.GENERAL.defeatedConditions(), + initial: 'defeated', label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.adversaryDefault.label' }), companionDefault: new fields.StringField({ required: true, - choices: CONFIG.DH.GENERAL.defeatedConditions, - initial: CONFIG.DH.GENERAL.defeatedConditions.defeated.id, + choices: () => CONFIG.DH.GENERAL.defeatedConditions(), + initial: 'defeated', label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.defeated.companionDefault.label' + }), + deadIcon: new fields.FilePathField({ + initial: 'icons/magic/death/grave-tombstone-glow-teal.webp', + categories: ['IMAGE'], + base64: false, + label: 'Dead' + }), + defeatedIcon: new fields.FilePathField({ + initial: 'icons/magic/control/fear-fright-mask-orange.webp', + categories: ['IMAGE'], + base64: false, + label: 'Defeated' + }), + unconsciousIcon: new fields.FilePathField({ + initial: 'icons/magic/control/sleep-bubble-purple.webp', + categories: ['IMAGE'], + base64: false, + label: 'Unconcious' }) }), roll: new fields.SchemaField({ diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 3601e09d..6e286fc8 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -599,6 +599,8 @@ export default class DhpActor extends Actor { await this.modifyResource(updates); if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, updates) === false) return null; + + return updates; } calculateDamage(baseDamage, type) { @@ -647,6 +649,8 @@ export default class DhpActor extends Actor { await this.modifyResource(updates); if (Hooks.call(`${CONFIG.DH.id}.postTakeHealing`, this, updates) === false) return null; + + return updates; } async modifyResource(resources) { @@ -749,7 +753,7 @@ export default class DhpActor extends Actor { async toggleDefeated(defeatedState) { const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).defeated; - const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions; + const { unconscious, defeated, dead } = CONFIG.DH.GENERAL.conditions(); const defeatedConditions = new Set([unconscious.id, defeated.id, dead.id]); if (!defeatedState) { for (let defeatedId of defeatedConditions) { diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index d7476395..bb535c6d 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -143,6 +143,12 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { html.querySelectorAll('.button-target-selection').forEach(element => { element.addEventListener('click', this.onTargetSelection.bind(this)); }); + + html.querySelectorAll('.token-target-container').forEach(element => { + element.addEventListener('pointerover', this.hoverTarget); + element.addEventListener('pointerout', this.unhoverTarget); + element.addEventListener('click', this.clickTarget); + }); } async onRollDamage(event) { diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index e6c1a2f0..847b04ce 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -14,7 +14,8 @@ export default class RegisterHandlebarsHelpers { getProperty: foundry.utils.getProperty, setVar: this.setVar, empty: this.empty, - pluralize: this.pluralize + pluralize: this.pluralize, + positive: this.positive }); } static add(a, b) { @@ -89,4 +90,8 @@ export default class RegisterHandlebarsHelpers { const key = isSingular ? `${baseKey}.single` : `${baseKey}.plural`; return game.i18n.localize(key); } + + static positive(a) { + return Math.abs(Number(a)); + } } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 24047827..7bc9a8ff 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -1,5 +1,6 @@ export const preloadHandlebarsTemplates = async function () { foundry.applications.handlebars.loadTemplates({ + 'daggerheart.inventory-item-compact': 'systems/daggerheart/templates/sheets/global/partials/inventory-item-compact.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' @@ -29,7 +30,6 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', 'systems/daggerheart/templates/dialogs/downtime/activities.hbs', 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs', - 'systems/daggerheart/templates/ui/chat/parts/roll-part.hbs', 'systems/daggerheart/templates/ui/chat/parts/damage-part.hbs', 'systems/daggerheart/templates/ui/chat/parts/target-part.hbs', diff --git a/styles/less/global/inventory-item.less b/styles/less/global/inventory-item.less index 1f5840af..50cdf116 100644 --- a/styles/less/global/inventory-item.less +++ b/styles/less/global/inventory-item.less @@ -14,7 +14,7 @@ } .appTheme({}, { - .inventory-item-header .img-portait .roll-img { + .inventory-item .img-portait .roll-img { filter: invert(1); } }); @@ -25,14 +25,12 @@ list-style-type: none; &:not(.single-img) { - .inventory-item-header:hover { - .img-portait:has(.roll-img) { - .roll-img { - opacity: 1; - } - .item-img { - opacity: 0; - } + .img-portait:has(.roll-img):hover { + .roll-img { + opacity: 1; + } + .item-img { + opacity: 0; } } @@ -68,18 +66,15 @@ } } - .inventory-item-header { - display: flex; - align-items: center; - gap: 10px; - cursor: pointer; - border-radius: 3px; - + .inventory-item-header, + &.inventory-item-compact { .img-portait { flex: 0 0 40px; height: 40px; - cursor: pointer; position: relative; + &:has(.roll-img) { + cursor: pointer; + } .item-img, .roll-img { @@ -102,53 +97,6 @@ } } - .item-label { - flex: 1; - align-self: center; - - .item-name { - font-size: var(--font-size-14); - - .expanded-icon { - display: none; - } - } - - .item-tags, - .item-labels { - display: flex; - gap: 10px; - - .tag, - .label { - display: flex; - flex-direction: row; - align-items: center; - font-size: var(--font-size-12); - flex-wrap: wrap; - justify-content: start; - } - - .tag { - padding: 3px 5px; - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - gap: 4px; - color: light-dark(@dark-80, @beige-80); - } - } - } - - .item-resource { - flex: 0 0 60px; - display: flex; - align-items: center; - gap: 4px; - } .controls { flex: 0 0 auto; display: flex; @@ -167,6 +115,52 @@ } } + .inventory-item-header { + align-items: center; + border-radius: 3px; + cursor: pointer; + display: flex; + gap: 10px; + + .item-label { + flex: 1; + align-self: center; + + .item-name { + font-size: var(--font-size-14); + + .expanded-icon { + display: none; + } + } + + .item-tags { + display: flex; + gap: 10px; + + .tag { + align-items: center; + background: light-dark(@dark-15, @beige-15); + border-radius: 3px; + border: 1px solid light-dark(@dark, @beige); + display: flex; + flex-direction: row; + flex-wrap: wrap; + font-size: var(--font-size-12); + justify-content: start; + padding: 3px 5px; + } + } + } + + .item-resource { + flex: 0 0 60px; + display: flex; + align-items: center; + gap: 4px; + } + } + .inventory-item-content { > *:not(:last-child) { margin-bottom: 5px; @@ -251,6 +245,41 @@ } } } + + &.inventory-item-compact { + display: grid; + grid-template: + "img name controls" auto + "img labels labels" 1fr + / 40px 1fr min-content; + column-gap: 8px; + + > .img-portait { + grid-area: img; + } + > .item-name { + align-self: end; + line-height: 1; + padding-bottom: 1px; + } + > .controls { + grid-area: controls; + align-self: start; + padding-top: 0.3125rem; + gap: 4px; + margin-bottom: -1px; + } + > .item-labels { + align-self: start; + color: light-dark(@dark-80, @beige-80); + display: flex; + flex-direction: row; + flex-wrap: wrap; + font-size: var(--font-size-12); + gap: 4px; + grid-area: labels; + } + } } .card-item { diff --git a/styles/less/ui/chat/damage-summary.less b/styles/less/ui/chat/damage-summary.less new file mode 100644 index 00000000..02fdbadf --- /dev/null +++ b/styles/less/ui/chat/damage-summary.less @@ -0,0 +1,87 @@ +@import '../../utils/colors.less'; + +#interface.theme-light { + .daggerheart.chat.damage-summary .token-target-container { + &:hover { + background: @dark-blue-10; + } + + header { + .actor-name { + color: @dark; + } + + &::after { + background: @dark-blue; + } + } + } +} + +.daggerheart.chat.damage-summary { + display: flex; + flex-direction: column; + gap: 5px; + padding: 0; + + .token-target-container { + display: flex; + flex-direction: column; + gap: 2px; + cursor: pointer; + transition: all 0.3s ease; + border-radius: 6px; + + &:hover { + background: @golden-10; + } + + header { + display: flex; + align-items: center; + gap: 5px; + pointer-events: none; + position: relative; + margin-bottom: 10px; + + img { + width: 40px; + height: 40px; + padding: 0; + border-radius: 50%; + } + + .actor-name { + margin: 0; + color: @beige; + font-size: var(--font-size-20); + padding: 8px; + } + + &::after { + content: ''; + position: absolute; + bottom: -10px; + background: @golden; + mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%); + height: 2px; + width: 100%; + } + } + + .damage-container { + display: flex; + flex-direction: column; + justify-content: center; + gap: 5px; + pointer-events: none; + margin-top: 5px; + list-style: disc; + + .damage-row { + padding: 0 2px; + gap: 4px; + } + } + } +} diff --git a/styles/less/ui/chat/effect-summary.less b/styles/less/ui/chat/effect-summary.less new file mode 100644 index 00000000..9bea1fd9 --- /dev/null +++ b/styles/less/ui/chat/effect-summary.less @@ -0,0 +1,166 @@ +@import '../../utils/colors.less'; + +#interface.theme-light { + .daggerheart.chat.effect-summary { + .effect-header, + .actor-header { + &::before, + &::after { + height: 2px; + background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, @dark-blue 100%); + } + + &::after { + background: linear-gradient(90deg, @dark-blue 0%, rgba(0, 0, 0, 0) 100%); + } + + span { + color: @dark; + } + } + + .token-target-container, + .effect-target-container { + .effect-label .title, + .title { + color: @dark-blue; + } + + .effect-label { + border-color: @dark-blue; + } + + &:hover { + background: @dark-blue-10; + } + } + } +} + +.daggerheart.chat.effect-summary { + display: flex; + flex-direction: column; + + .effect-header, + .actor-header { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 5px; + + &::before, + &::after { + content: ''; + flex: 1; + height: 2px; + background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, @golden 100%); + } + + &::after { + background: linear-gradient(90deg, @golden 0%, rgba(0, 0, 0, 0) 100%); + } + + span { + color: @beige; + padding: 0 10px; + white-space: nowrap; + } + } + + .effects-container { + display: flex; + flex-wrap: wrap; + gap: 5px; + margin-bottom: 8px; + } + + .targets-container { + display: flex; + flex-direction: column; + gap: 5px; + } + + .token-target-container { + display: flex; + align-items: center; + gap: 13px; + border-radius: 6px; + padding: 0 2px; + border-radius: 6px; + background: transparent; + transition: all 0.3s ease; + padding: 5px; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: @golden-10; + } + + img { + width: 40px; + height: 40px; + border-radius: 50%; + pointer-events: none; + } + + .title { + font-size: var(--font-size-20); + color: @golden; + font-weight: 700; + margin: 0; + pointer-events: none; + } + } + + details[open] { + .fa-chevron-down { + transform: rotate(180deg); + transition: all 0.3s ease; + } + } + + .effect-target-container { + width: 100%; + transition: all 0.3s ease; + cursor: pointer; + + &:hover { + background: @golden-10; + } + + .fa-chevron-down { + transition: all 0.3s ease; + margin-left: auto; + } + + .effect-label { + display: flex; + flex-direction: row; + align-items: center; + margin: 8px 8px 0; + padding-bottom: 5px; + width: -webkit-fill-available; + gap: 13px; + border-bottom: 1px solid @golden; + + .effect-img { + width: 40px; + height: 40px; + border-radius: 3px; + object-fit: cover; + } + + .title { + font-size: var(--font-size-20); + color: @golden; + font-weight: 700; + margin: 0; + } + } + + .description { + padding: 8px; + } + } +} diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 0a89afc3..296ef325 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -1,7 +1,9 @@ @import './chat/ability-use.less'; @import './chat/action.less'; @import './chat/chat.less'; +@import './chat/damage-summary.less'; @import './chat/downtime.less'; +@import './chat/effect-summary.less'; @import './chat/refresh-message.less'; @import './chat/sheet.less'; diff --git a/system.json b/system.json index 4eeeff1a..2caeca2b 100644 --- a/system.json +++ b/system.json @@ -266,7 +266,8 @@ "dualityRoll": {}, "adversaryRoll": {}, "damageRoll": {}, - "abilityUse": {} + "abilityUse": {}, + "systemMessage": {} } }, "background": "systems/daggerheart/assets/logos/FoundrybornBackgroundLogo.png", diff --git a/templates/settings/automation-settings/general.hbs b/templates/settings/automation-settings/general.hbs index 211ee68e..8921ab6a 100644 --- a/templates/settings/automation-settings/general.hbs +++ b/templates/settings/automation-settings/general.hbs @@ -7,7 +7,11 @@ {{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}} - + +