Compare commits

..

No commits in common. "0128106de63e54ad55e45ecadd78a8dbda8e6715" and "85ca7efc6de317ca52c30fbea50531a8f917f90a" have entirely different histories.

16 changed files with 242 additions and 276 deletions

View file

@ -2822,15 +2822,6 @@
"hideObserverPermissionInChat": { "hideObserverPermissionInChat": {
"label": "Hide Chat Info From Players", "label": "Hide Chat Info From Players",
"hint": "Information such as hit/miss on attack rolls against adversaries will be hidden" "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"
}
} }
} }
}, },

View file

@ -209,9 +209,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => { context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => {
acc[key] = { acc[key] = {
...this.document.system.traits[key], ...this.document.system.traits[key],
label: _loc(CONFIG.DH.ACTOR.abilities[key].label), name: game.i18n.localize(CONFIG.DH.ACTOR.abilities[key].name),
verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)), verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x))
isSpellcasting: this.document.system.spellcastModifierTrait.key === key
}; };
return acc; return acc;
@ -228,7 +227,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0; context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0;
context.equippedItems = sortBy( context.equippedItems = sortBy(
this.document.items.filter(i => i.system.equipped && (i.type === 'weapon' || i.usable)), this.document.items.filter(i => i.system.equipped),
i => (i.type === 'weapon' ? (i.system.secondary ? 1 : 0) : 2) i => (i.type === 'weapon' ? (i.system.secondary ? 1 : 0) : 2)
); );

View file

@ -85,14 +85,6 @@ export default class Party extends DHBaseActorSheet {
/* Prepare Context */ /* 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) { async _preparePartContext(partId, context, options) {
context = await super._preparePartContext(partId, context, options); context = await super._preparePartContext(partId, context, options);
switch (partId) { switch (partId) {

View file

@ -1,5 +1,4 @@
import { defaultRestOptions } from '../../config/generalConfig.mjs'; import { defaultRestOptions } from '../../config/generalConfig.mjs';
import { resetAndRerenderActors } from '../../helpers/utils.mjs';
import { ActionsField } from '../fields/actionField.mjs'; import { ActionsField } from '../fields/actionField.mjs';
const currencyField = (initial, label, icon) => const currencyField = (initial, label, icon) =>
@ -210,7 +209,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
} }
this.refreshConfig(); this.refreshConfig();
resetAndRerenderActors(); this.#resetActors();
} }
/** Update config values based on homebrew data. Make sure the references don't change */ /** Update config values based on homebrew data. Make sure the references don't change */
@ -231,6 +230,29 @@ 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 { export class Resource extends foundry.abstract.DataModel {

View file

@ -1,5 +1,3 @@
import { resetAndRerenderActors } from '../../helpers/utils.mjs';
export default class DhMetagaming extends foundry.abstract.DataModel { export default class DhMetagaming extends foundry.abstract.DataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
@ -8,24 +6,7 @@ export default class DhMetagaming extends foundry.abstract.DataModel {
initial: false, initial: false,
label: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.label', label: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.label',
hint: 'DAGGERHEART.SETTINGS.Metagaming.FIELDS.hideObserverPermissionInChat.hint' 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();
}
} }

View file

@ -793,26 +793,6 @@ 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 * 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. * Similar to lodash's sortBy function.

View file

@ -91,10 +91,7 @@ const registerMenuSettings = () => {
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming, { game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Metagaming, {
scope: 'world', scope: 'world',
config: false, config: false,
type: DhMetagaming, type: DhMetagaming
onChange: value => {
value.handleChange();
}
}); });
game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, { game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, {

View file

@ -251,7 +251,8 @@
a:hover, a:hover,
a.active { a.active {
text-shadow: 0 0 1px currentColor, 0 0 1px currentColor, 0 0 8px light-dark(@dark-blue, @golden); font-weight: bold;
text-shadow: 0 0 8px light-dark(@dark-blue, @golden);
} }
fieldset { fieldset {

View file

@ -5,12 +5,20 @@
// Theme header backgrounds // Theme header backgrounds
.appTheme({ .appTheme({
.character-header-sheet { .character-header-sheet {
.trait {
background: url(../assets/svg/trait-shield.svg) no-repeat;
}
.character-row .domains-section img { .character-row .domains-section img {
filter: @golden-filter; filter: @golden-filter;
} }
} }
}, { }, {
.character-header-sheet { .character-header-sheet {
.trait {
background: url('../assets/svg/trait-shield-light.svg') no-repeat;
}
.character-row .domains-section img { .character-row .domains-section img {
filter: brightness(0) saturate(100%); filter: brightness(0) saturate(100%);
} }
@ -93,7 +101,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 5px 0; padding: 5px 0;
margin-bottom: 8px; margin-bottom: 10px;
font-size: var(--font-size-12); font-size: var(--font-size-12);
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
@ -123,7 +131,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0; padding: 0;
margin-bottom: 12px; margin-bottom: 15px;
.resource-section { .resource-section {
display: flex; display: flex;
@ -209,68 +217,37 @@
.character-traits { .character-traits {
display: flex; display: flex;
justify-content: space-between;
padding: 0; padding: 0;
margin-bottom: 15px; margin-bottom: 15px;
gap: 8px;
.trait { .trait {
height: 3.625rem; height: 60px;
width: 60px;
cursor: pointer; 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 { .trait-name {
display: flex; display: flex;
align-items: center; align-items: center;
padding-top: 5px; padding-top: 5px;
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
font-size: var(--font-size-12); font-size: var(--font-size-14);
font-weight: 600; font-weight: 600;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 3px;
i {
line-height: 17px;
font-size: var(--font-size-10);
}
} }
.trait-value { .trait-value {
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 400;
font-size: var(--font-size-20); font-size: var(--font-size-20);
text-align: center; 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);
}
} }
} }
} }

View file

@ -74,6 +74,62 @@
.death-roll-btn { .death-roll-btn {
display: none; 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 { .info-section {

View file

@ -280,17 +280,6 @@ 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 { .actors-dragger {
display: flex; display: flex;
align-items: center; align-items: center;

View file

@ -5,9 +5,6 @@
--dh-font-title: 'Cinzel Decorative'; --dh-font-title: 'Cinzel Decorative';
--dh-font-subtitle: 'Cinzel'; --dh-font-subtitle: 'Cinzel';
--dh-font-body: 'Montserrat'; --dh-font-body: 'Montserrat';
/* Include missing font sizes */
--font-size-22: 1.375rem;
} }
@font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif"; @font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif";

View file

@ -1,4 +1,3 @@
<div> <div>
{{formGroup settingFields.schema.fields.hideObserverPermissionInChat value=settingFields._source.hideObserverPermissionInChat localize=true}} {{formGroup settingFields.schema.fields.hideObserverPermissionInChat value=settingFields._source.hideObserverPermissionInChat localize=true}}
{{formGroup settingFields.schema.fields.hidePartyStats value=settingFields._source.hidePartyStats localize=true}}
</div> </div>

View file

@ -125,9 +125,14 @@
<div class="character-traits"> <div class="character-traits">
{{#each this.attributes as |attribute key|}} {{#each this.attributes as |attribute key|}}
<div class="trait" data-tooltip="<b>{{attribute.label}}:</b><br>{{#each attribute.verbs}}{{this}}<br>{{/each}}" data-action="rollAttribute" data-attribute="{{key}}" data-value="{{attribute.value}}"> <div class="trait" data-tooltip="<b>{{localize (concat 'DAGGERHEART.CONFIG.Traits.' key '.name') }}:</b><br>{{#each attribute.verbs}}{{this}}<br>{{/each}}" data-action="rollAttribute" data-attribute="{{key}}" data-value="{{attribute.value}}">
<div class="trait-name"> <div class="trait-name">
<span>{{attribute.label}}</span> <span>{{localize (concat 'DAGGERHEART.CONFIG.Traits.' key '.short')}}</span>
{{#if attribute.tierMarked}}
<i class='fa-solid fa-circle'></i>
{{else}}
<i class='fa-regular fa-circle'></i>
{{/if}}
</div> </div>
<div class="trait-value"> <div class="trait-value">
{{#if (gt attribute.value 0)}} {{#if (gt attribute.value 0)}}
@ -136,16 +141,6 @@
<span>{{attribute.value}}</span> <span>{{attribute.value}}</span>
{{/if}} {{/if}}
</div> </div>
{{#if attribute.tierMarked}}
<div class="tier-mark">
<i class='fa-solid fa-circle' inert></i>
</div>
{{/if}}
{{#if isSpellcasting}}
<div class="spellcasting-mark" data-tooltip="DAGGERHEART.ITEMS.Subclass.spellcastingTrait">
<i class="fa-solid fa-wand-magic-sparkles" inert></i>
</div>
{{/if}}
</div> </div>
{{/each}} {{/each}}
</div> </div>

View file

@ -1,6 +1,17 @@
<aside class="character-sidebar-sheet"> <aside class="character-sidebar-sheet">
<div class="portrait {{#if isDeath}}death-roll{{/if}}"> <div class="portrait {{#if isDeath}}death-roll{{/if}}">
<img src="{{document.img}}" alt="{{document.name}}" data-action='editImage' data-edit="img"> <img src="{{document.img}}" alt="{{document.name}}" data-action='editImage' data-edit="img">
{{#if document.system.spellcastModifierTrait.key}}
<div class="icons-list">
<span class="spellcast-icon {{#if isDeath}}no-label{{/if}}">
<span class="spellcast-label">
{{localize "DAGGERHEART.ITEMS.Subclass.spellcastingTrait"}}:
{{localize (concat 'DAGGERHEART.CONFIG.Traits.' document.system.spellcastModifierTrait.key '.short')}}
</span>
<i class="fa-solid fa-wand-sparkles"></i>
</span>
</div>
{{/if}}
<a class="death-roll-btn" data-tooltip="DAGGERHEART.UI.Tooltip.makeDeathMove" {{#if <a class="death-roll-btn" data-tooltip="DAGGERHEART.UI.Tooltip.makeDeathMove" {{#if
isDeath}}data-action="makeDeathMove" {{/if}}><i class="fa-solid fa-skull death-save"></i></a> isDeath}}data-action="makeDeathMove" {{/if}}><i class="fa-solid fa-skull death-save"></i></a>
</div> </div>

View file

@ -23,164 +23,143 @@
</button> </button>
</div> </div>
{{#if @root.showStats}} <ul class="actors-list">
<ul class="actors-list"> {{#each partyMembers as |member id|}}
{{#each partyMembers as |member id|}} <li class="actor-resources">
<li class="actor-resources"> <div class="actor-img-frame">
<div class="actor-img-frame"> <img class="actor-img" src="{{member.img}}">
<img class="actor-img" src="{{member.img}}"> {{#if member.weapons}}
{{#if member.weapons}} <div class="equipped-weapons">
<div class="equipped-weapons"> {{#each member.weapons as |weapon|}}
{{#each member.weapons as |weapon|}} <img src="{{weapon.img}}" data-tooltip="{{weapon.name}}"/>
<img src="{{weapon.img}}" data-tooltip="{{weapon.name}}"/> {{/each}}
{{/each}} </div>
</div> {{/if}}
{{/if}} {{#if member.evasion includeZero=true}}
{{#if member.evasion includeZero=true}} <div class="evasion" data-tooltip="DAGGERHEART.GENERAL.evasion">{{member.evasion}}</div>
<div class="evasion" data-tooltip="DAGGERHEART.GENERAL.evasion">{{member.evasion}}</div> {{/if}}
{{/if}} {{#if member.difficulty includeZero=true}}
{{#if member.difficulty includeZero=true}} <div class="evasion" data-tooltip="DAGGERHEART.GENERAL.difficulty">{{member.difficulty}}</div>
<div class="evasion" data-tooltip="DAGGERHEART.GENERAL.difficulty">{{member.difficulty}}</div> {{/if}}
{{/if}} {{#unless (eq member.type 'companion')}}
{{#unless (eq member.type 'companion')}} <div class="threshold-section">
<div class="threshold-section"> <h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.minor"}}</h4>
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.minor"}}</h4> <h4 class="threshold-value">{{member.damageThresholds.major}}</h4>
<h4 class="threshold-value">{{member.damageThresholds.major}}</h4> <h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.major"}}</h4>
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.major"}}</h4> <h4 class="threshold-value">{{member.damageThresholds.severe}}</h4>
<h4 class="threshold-value">{{member.damageThresholds.severe}}</h4> <h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.severe"}}</h4>
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.severe"}}</h4> </div>
{{/unless}}
</div>
<header>
<h2 class="actor-name">
<a data-action="openDocument" data-uuid="{{member.uuid}}">{{member.name}}</a>
<a class="delete-icon" data-action="deletePartyMember" data-uuid="{{member.uuid}}"><i class="fa-regular fa-times" inert></i></a>
</h2>
<div>
{{#unless (or (eq member.type 'companion') (eq member.type 'adversary')) }}
<div class="hope-section">
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
{{#times member.resources.hope.max}}
<span class='hope-value' data-action='toggleHope' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
{{#if (gte member.resources.hope.value (add this 1))}}
<i class='fa-solid fa-diamond'></i>
{{else}}
<i class='fa-regular fa-circle'></i>
{{/if}}
</span>
{{/times}}
</div> </div>
{{/unless}} {{/unless}}
</div> </div>
<header> {{#if member.subtitle}}
<h2 class="actor-name"> <span class="subtitle">{{member.subtitle}}</span>
<a data-action="openDocument" data-uuid="{{member.uuid}}">{{member.name}}</a> {{/if}}
<a class="delete-icon" data-action="deletePartyMember" data-uuid="{{member.uuid}}"><i class="fa-regular fa-times" inert></i></a> </header>
</h2> <section class="body">
<div> <section class="resources">
{{#unless (or (eq member.type 'companion') (eq member.type 'adversary')) }} {{#unless (eq member.type 'companion') }}
<div class="hope-section">
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
{{#times member.resources.hope.max}}
<span class='hope-value' data-action='toggleHope' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
{{#if (gte member.resources.hope.value (add this 1))}}
<i class='fa-solid fa-diamond'></i>
{{else}}
<i class='fa-regular fa-circle'></i>
{{/if}}
</span>
{{/times}}
</div>
{{/unless}}
</div>
{{#if member.subtitle}}
<span class="subtitle">{{member.subtitle}}</span>
{{/if}}
</header>
<section class="body">
<section class="resources">
{{#unless (eq member.type 'companion') }}
<div class="slot-section">
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.HitPoints.plural">
<span class="label">
<i class="fa-solid fa-heart" inert></i>
</span>
<span class="value">
<span class="current">{{member.resources.hitPoints.value}}</span>
/
<span class="max">{{member.resources.hitPoints.max}}</span>
</span>
</div>
<div class="slot-bar">
{{#times member.resources.hitPoints.max}}
<span class='slot {{#if (gte member.resources.hitPoints.value (add this 1))}}filled{{/if}}'
data-action='toggleHitPoints' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
</span>
{{/times}}
</div>
</div>
{{/unless}}
<div class="slot-section"> <div class="slot-section">
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.stress"> <div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.HitPoints.plural">
<span class="label"> <span class="label">
<i class="fa-solid fa-bolt" inert></i> <i class="fa-solid fa-heart" inert></i>
</span> </span>
<span class="value"> <span class="value">
<span class="current">{{member.resources.stress.value}}</span> <span class="current">{{member.resources.hitPoints.value}}</span>
/ /
<span class="max">{{member.resources.stress.max}}</span> <span class="max">{{member.resources.hitPoints.max}}</span>
</span> </span>
</div> </div>
<div class="slot-bar"> <div class="slot-bar">
{{#times member.resources.stress.max}} {{#times member.resources.hitPoints.max}}
<span class='slot {{#if (gte member.resources.stress.value (add this 1))}}filled{{/if}}' <span class='slot {{#if (gte member.resources.hitPoints.value (add this 1))}}filled{{/if}}'
data-action='toggleStress' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}"> data-action='toggleHitPoints' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
</span> </span>
{{/times}} {{/times}}
</div> </div>
</div> </div>
{{/unless}}
{{#if member.armorScore.max}} <div class="slot-section">
<div class="slot-section"> <div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.stress">
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.armorSlots"> <span class="label">
<span class="label"> <i class="fa-solid fa-bolt" inert></i>
<i class="fa-solid fa-shield" inert></i> </span>
</span> <span class="value">
<span class="value"> <span class="current">{{member.resources.stress.value}}</span>
<span class="current">{{member.armorScore.value}}</span> /
/ <span class="max">{{member.resources.stress.max}}</span>
<span class="max">{{member.armorScore.max}}</span> </span>
</span> </div>
</div> <div class="slot-bar">
<div class="slot-bar"> {{#times member.resources.stress.max}}
{{#times member.armorScore.max}} <span class='slot {{#if (gte member.resources.stress.value (add this 1))}}filled{{/if}}'
<a class='armor-slot' data-action='toggleArmorSlot' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}"> data-action='toggleStress' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
{{#if (gte member.armorScore.value (add this 1))}}
<i class="fa-solid fa-shield"></i>
{{else}}
<i class="fa-solid fa-shield-halved"></i>
{{/if}}
</a>
{{/times}}
</div>
</div>
{{/if}}
</section>
{{#if member.traits}}
<div class="traits">
{{#each member.traits as |trait|}}
<span class="trait">
<span class="label">{{trait.label}}</span>
<span class="value">{{trait.value}}</span>
</span> </span>
{{/each}} {{/times}}
</div>
</div>
{{#if member.armorScore.max}}
<div class="slot-section">
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.armorSlots">
<span class="label">
<i class="fa-solid fa-shield" inert></i>
</span>
<span class="value">
<span class="current">{{member.armorScore.value}}</span>
/
<span class="max">{{member.armorScore.max}}</span>
</span>
</div>
<div class="slot-bar">
{{#times member.armorScore.max}}
<a class='armor-slot' data-action='toggleArmorSlot' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
{{#if (gte member.armorScore.value (add this 1))}}
<i class="fa-solid fa-shield"></i>
{{else}}
<i class="fa-solid fa-shield-halved"></i>
{{/if}}
</a>
{{/times}}
</div>
</div> </div>
{{/if}} {{/if}}
</section> </section>
</li> {{#if member.traits}}
{{/each}} <div class="traits">
</ul> {{#each member.traits as |trait|}}
{{else}} <span class="trait">
<ul class="actors-list limited"> <span class="label">{{trait.label}}</span>
{{#each partyMembers as |member id|}} <span class="value">{{trait.value}}</span>
<li class="actor-resources"> </span>
<div class="actor-img-frame"> {{/each}}
<img class="actor-img" src="{{member.img}}"> </div>
</div> {{/if}}
<header> </section>
<h2 class="actor-name"> </li>
<a data-action="openDocument" data-uuid="{{member.uuid}}">{{member.name}}</a> {{/each}}
<a class="delete-icon" data-action="deletePartyMember" data-uuid="{{member.uuid}}"><i class="fa-regular fa-times" inert></i></a> </ul>
</h2>
{{#if member.subtitle}}
<span class="subtitle">{{member.subtitle}}</span>
{{/if}}
</header>
</li>
{{/each}}
</ul>
{{/if}}
{{#unless document.system.partyMembers.length}} {{#unless document.system.partyMembers.length}}
<div class="actors-dragger"> <div class="actors-dragger">
<span>{{localize "DAGGERHEART.GENERAL.dropActorsHere"}}</span> <span>{{localize "DAGGERHEART.GENERAL.dropActorsHere"}}</span>