diff --git a/lang/en.json b/lang/en.json index 817fc355..aff0d60a 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2822,6 +2822,15 @@ "hideObserverPermissionInChat": { "label": "Hide Chat Info From Players", "hint": "Information such as hit/miss on attack rolls against adversaries will be hidden" + }, + "hidePartyStats": { + "label": "Hide Party Stats", + "hint": "Resources and stats in the party sheet's member list will be hidden to the following users, even if the user is part of the same party", + "choices": { + "never": "Never, always show", + "players": "Hide From Players", + "always": "Hide from Everyone" + } } } }, diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 513ad3f3..7adffa1e 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -209,8 +209,9 @@ export default class CharacterSheet extends DHBaseActorSheet { context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => { acc[key] = { ...this.document.system.traits[key], - name: game.i18n.localize(CONFIG.DH.ACTOR.abilities[key].name), - verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)) + label: _loc(CONFIG.DH.ACTOR.abilities[key].label), + verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)), + isSpellcasting: this.document.system.spellcastModifierTrait.key === key }; return acc; @@ -227,7 +228,7 @@ export default class CharacterSheet extends DHBaseActorSheet { context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0; context.equippedItems = sortBy( - this.document.items.filter(i => i.system.equipped), + this.document.items.filter(i => i.system.equipped && (i.type === 'weapon' || i.usable)), i => (i.type === 'weapon' ? (i.system.secondary ? 1 : 0) : 2) ); diff --git a/module/applications/sheets/actors/party.mjs b/module/applications/sheets/actors/party.mjs index a7eeccdf..403960c0 100644 --- a/module/applications/sheets/actors/party.mjs +++ b/module/applications/sheets/actors/party.mjs @@ -85,6 +85,14 @@ export default class Party extends DHBaseActorSheet { /* Prepare Context */ /* -------------------------------------------- */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming); + context.showStats = + settings.hidePartyStats === 'never' || (settings.hidePartyStats === 'players' && game.user.isGM); + return context; + } + async _preparePartContext(partId, context, options) { context = await super._preparePartContext(partId, context, options); switch (partId) { diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index b5e02675..31247458 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -1,4 +1,5 @@ import { defaultRestOptions } from '../../config/generalConfig.mjs'; +import { resetAndRerenderActors } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; const currencyField = (initial, label, icon) => @@ -209,7 +210,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { } this.refreshConfig(); - this.#resetActors(); + resetAndRerenderActors(); } /** Update config values based on homebrew data. Make sure the references don't change */ @@ -230,29 +231,6 @@ export default class DhHomebrew extends foundry.abstract.DataModel { }); } } - - /** - * Triggers a reset and non-forced re-render on all given actors (if given) - * or all world actors and actors in all scenes to show immediate results for a changed setting. - */ - #resetActors() { - const actors = new Set( - [ - game.actors.contents, - game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) - ].flat() - ); - for (const actor of actors) { - for (const app of Object.values(actor.apps)) { - for (const element of app.element?.querySelectorAll('prose-mirror.active')) { - element.open = false; // This triggers a save - } - } - - actor.reset(); - actor.render(); - } - } } export class Resource extends foundry.abstract.DataModel { diff --git a/module/data/settings/Metagaming.mjs b/module/data/settings/Metagaming.mjs index 2bb5afdf..3694e09e 100644 --- a/module/data/settings/Metagaming.mjs +++ b/module/data/settings/Metagaming.mjs @@ -1,3 +1,5 @@ +import { resetAndRerenderActors } from '../../helpers/utils.mjs'; + export default class DhMetagaming extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; @@ -6,7 +8,24 @@ export default class DhMetagaming extends foundry.abstract.DataModel { initial: false, label: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.label', hint: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.hint' + }), + hidePartyStats: new fields.StringField({ + initial: 'never', + label: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hidePartyStats.label', + hint: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hidePartyStats.hint', + required: true, + nullable: false, + choices: { + never: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hidePartyStats.choices.never', + players: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hidePartyStats.choices.players', + always: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hidePartyStats.choices.always' + } }) }; } + + /** Invoked by the setting when data changes */ + handleChange() { + resetAndRerenderActors(); + } } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index faa046ff..cec493b4 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -793,6 +793,26 @@ export function getArmorSources(actor) { }); } +/** + * Triggers a reset and non-forced re-render on all given actors (if given) + * or all world actors and actors in all scenes to show immediate results for a changed setting. + */ +export function resetAndRerenderActors() { + const actors = new Set( + [game.actors.contents, game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? [])].flat() + ); + for (const actor of actors) { + for (const app of Object.values(actor.apps)) { + for (const element of app.element?.querySelectorAll('prose-mirror.active')) { + element.open = false; // This triggers a save + } + } + + actor.reset(); + actor.render(); + } +} + /** * Returns an array sorted by a function that returns a thing to compare, or an array to compare in order * Similar to lodash's sortBy function. diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index 41cab011..a66323c7 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -91,7 +91,10 @@ const registerMenuSettings = () => { game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming, { scope: 'world', config: false, - type: DhMetagaming + type: DhMetagaming, + onChange: value => { + value.handleChange(); + } }); game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, { diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index afd56057..ff668bfd 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -251,8 +251,7 @@ a:hover, a.active { - font-weight: bold; - text-shadow: 0 0 8px light-dark(@dark-blue, @golden); + text-shadow: 0 0 1px currentColor, 0 0 1px currentColor, 0 0 8px light-dark(@dark-blue, @golden); } fieldset { diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 31fd4256..ffd01c83 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -5,20 +5,12 @@ // Theme header backgrounds .appTheme({ .character-header-sheet { - .trait { - background: url(../assets/svg/trait-shield.svg) no-repeat; - } - .character-row .domains-section img { filter: @golden-filter; } } }, { .character-header-sheet { - .trait { - background: url('../assets/svg/trait-shield-light.svg') no-repeat; - } - .character-row .domains-section img { filter: brightness(0) saturate(100%); } @@ -101,7 +93,7 @@ display: flex; justify-content: space-between; padding: 5px 0; - margin-bottom: 10px; + margin-bottom: 8px; font-size: var(--font-size-12); color: light-dark(@dark-blue, @golden); @@ -131,7 +123,7 @@ display: flex; align-items: center; padding: 0; - margin-bottom: 15px; + margin-bottom: 12px; .resource-section { display: flex; @@ -217,37 +209,68 @@ .character-traits { display: flex; - justify-content: space-between; padding: 0; margin-bottom: 15px; + gap: 8px; .trait { - height: 60px; - width: 60px; + height: 3.625rem; cursor: pointer; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + flex: 1; + position: relative; + background-color: light-dark(transparent, @dark-blue); + + display: flex; + justify-content: center; + flex-direction: column; .trait-name { display: flex; align-items: center; padding-top: 5px; color: light-dark(@dark-blue, @golden); - font-size: var(--font-size-14); + font-size: var(--font-size-12); font-weight: 600; align-items: center; justify-content: center; - gap: 3px; - - i { - line-height: 17px; - font-size: var(--font-size-10); - } } .trait-value { font-style: normal; - font-weight: 400; + font-weight: 600; font-size: var(--font-size-20); text-align: center; + margin-bottom: 0.375rem; + } + + .tier-mark, + .spellcasting-mark { + position: absolute; + opacity: 0.9; + color: light-dark(@dark-blue, @golden); + i { + line-height: 17px; + font-size: var(--font-size-11); + } + } + + .tier-mark { + bottom: 1px; + left: 3px; + } + + .spellcasting-mark { + bottom: 1px; + right: 3px; + } + + &:hover { + .trait-name { + color: light-dark(@dark, @beige); + text-shadow: 0 0 8px light-dark(@dark-80, @beige-80); + } } } } diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index b159a8e8..0e6e3d97 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -74,62 +74,6 @@ .death-roll-btn { display: none; } - - .icons-list { - position: absolute; - display: flex; - flex-direction: column; - gap: 5px; - align-items: end; - justify-content: center; - top: 45px; - right: 10px; - - .spellcast-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(@dark-blue-60, @dark-golden-80); - backdrop-filter: blur(8px); - border: 4px double light-dark(@beige, @golden); - color: light-dark(@beige, @golden); - border-radius: 999px; - transition: all 0.3s ease; - - .spellcast-label { - font-size: var(--font-size-14); - opacity: 0; - margin-right: 0.3rem; - transition: all 0.3s ease; - } - - i { - height: 24px; - width: 24px; - align-content: center; - margin-right: 3px; - } - - &:not(.no-label):hover { - max-width: 300px; - padding: 0 10px; - border-radius: 60px; - - .spellcast-label { - opacity: 1; - } - - i { - margin-right: 0px; - } - } - } - } } .info-section { diff --git a/styles/less/sheets/actors/party/party-members.less b/styles/less/sheets/actors/party/party-members.less index 2e2f4cf8..a29f7c88 100644 --- a/styles/less/sheets/actors/party/party-members.less +++ b/styles/less/sheets/actors/party/party-members.less @@ -280,6 +280,17 @@ body.game:is(.performance-low, .noblur) { } } + .actors-list.limited { + .actor-resources { + display: flex; + align-items: center; + } + .actor-img-frame { + width: 3rem; + height: 3rem; + } + } + .actors-dragger { display: flex; align-items: center; diff --git a/styles/less/utils/fonts.less b/styles/less/utils/fonts.less index 5c1e597a..d4902508 100755 --- a/styles/less/utils/fonts.less +++ b/styles/less/utils/fonts.less @@ -5,6 +5,9 @@ --dh-font-title: 'Cinzel Decorative'; --dh-font-subtitle: 'Cinzel'; --dh-font-body: 'Montserrat'; + + /* Include missing font sizes */ + --font-size-22: 1.375rem; } @font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif"; diff --git a/templates/settings/metagaming-settings/general.hbs b/templates/settings/metagaming-settings/general.hbs index 7f36715e..775ff016 100644 --- a/templates/settings/metagaming-settings/general.hbs +++ b/templates/settings/metagaming-settings/general.hbs @@ -1,3 +1,4 @@