This commit is contained in:
WBHarry 2026-03-08 19:35:27 +01:00
parent c6bf482b07
commit 8b7a455410
11 changed files with 162 additions and 61 deletions

View file

@ -102,7 +102,19 @@ Hooks.once('init', () => {
initial: 0,
max: 4,
reverse: false,
label: 'Corruption'
label: 'Corruption',
images: {
full: {
value: 'icons/magic/fire/barrier-wall-explosion-orange.webp',
isPath: true,
isNotTransparent: true
},
empty: {
value: 'icons/magic/fire/barrier-wall-flame-ring-blue.webp',
isPath: true,
isNotTransparent: true
}
}
};
CONFIG.DH.ACTOR.characterResources.hunger = {
@ -110,7 +122,15 @@ Hooks.once('init', () => {
initial: 0,
max: 6,
reverse: false,
label: 'Hunger'
label: 'Hunger',
images: {
full: {
value: 'fa-solid fa-burger'
},
empty: {
value: 'fa-regular fa-burger'
}
}
};
CONFIG.DH.ACTOR.characterResources.glitched = {
@ -118,7 +138,15 @@ Hooks.once('init', () => {
initial: 0,
max: 6,
reverse: false,
label: 'Glitched'
label: 'Glitched',
images: {
full: {
value: 'fa-solid fa-robot'
},
empty: {
value: 'fa-regular fa-robot'
}
}
};
game.system.registeredTriggers = new game.system.api.data.RegisteredTriggers();

View file

@ -958,7 +958,9 @@ export default class CharacterSheet extends DHBaseActorSheet {
id: resource.id,
label: game.i18n.localize(resource.label),
value: resourceData.value,
max: resourceData.max
max: resourceData.max,
fullIcon: resource.images?.full ?? { value: 'fa-solid fa-circle' },
emptyIcon: resource.images?.empty ?? { value: 'fa-regular fa-circle' }
};
return acc;
@ -999,11 +1001,11 @@ export default class CharacterSheet extends DHBaseActorSheet {
const section = target.closest('.resource-section');
for (const element of section.querySelectorAll('.resource-value')) {
if (Number.parseInt(element.dataset.value) <= value) {
element.querySelector('.fa-diamond').classList.remove('hidden');
element.querySelector('.fa-circle').classList.add('hidden');
element.querySelector('.full').classList.remove('hidden');
element.querySelector('.empty').classList.add('hidden');
} else {
element.querySelector('.fa-diamond').classList.add('hidden');
element.querySelector('.fa-circle').classList.remove('hidden');
element.querySelector('.full').classList.add('hidden');
element.querySelector('.empty').classList.remove('hidden');
}
}
}

View file

@ -55,7 +55,20 @@ export const abilities = {
}
};
const baseResources = {
/**
* Full custom typing:
* id
* initial
* max
* reverse
* label
* images {
* full { value, isPath, isNotTransparent }
* empty { value, isPath isNotTransparent }
* }
*/
export const characterBaseResources = {
hitPoints: {
id: 'hitPoints',
initial: 0,
@ -80,20 +93,63 @@ const baseResources = {
}
};
export const characterBaseResources = {
...baseResources
};
export const characterResources = {
...characterBaseResources
};
export const adversaryBaseResources = {
hitPoints: {
id: 'hitPoints',
initial: 0,
max: 0,
reverse: true,
label: 'DAGGERHEART.GENERAL.HitPoints.plural',
maxLabel: 'DAGGERHEART.ACTORS.Character.maxHPBonus'
},
stress: {
id: 'stress',
initial: 0,
max: 0,
reverse: true,
label: 'DAGGERHEART.GENERAL.stress'
}
};
export const adversaryResources = {
...adversaryBaseResources
};
export const companionBaseResources = {
stress: {
id: 'stress',
initial: 0,
max: 0,
reverse: true,
label: 'DAGGERHEART.GENERAL.stress'
},
hope: {
id: 'hope',
initial: 0,
min: 0,
reverse: false,
label: 'DAGGERHEART.GENERAL.hope'
}
};
export const companionResources = {
...companionBaseResources
};
export const getScrollingTextResources = actorType => ({
armor: {
label: 'DAGGERHEART.GENERAL.armor',
reverse: true
},
...(actorType === 'character' ? characterResources : {})
...(actorType === 'character'
? characterResources
: actorType === 'adversary'
? adversaryResources
: companionResources)
});
export const featureProperties = {

View file

@ -2,7 +2,7 @@ import DHAdversarySettings from '../../applications/sheets-configs/adversary-set
import { ActionField } from '../fields/actionField.mjs';
import { commonActorRules } from './base.mjs';
import DhCreature from './creature.mjs';
import { resourceField, bonusField } from '../fields/actorField.mjs';
import { bonusField } from '../fields/actorField.mjs';
import { calculateExpectedValue, parseTermsFromSimpleFormula } from '../../helpers/utils.mjs';
import { adversaryExpectedDamage, adversaryScalingData } from '../../config/actorConfig.mjs';
@ -65,10 +65,6 @@ export default class DhpAdversary extends DhCreature {
label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold'
})
}),
resources: new fields.SchemaField({
hitPoints: resourceField(0, 0, 'DAGGERHEART.GENERAL.HitPoints.plural', true),
stress: resourceField(0, 0, 'DAGGERHEART.GENERAL.stress', true)
}),
rules: new fields.SchemaField({
...commonActorRules()
}),

View file

@ -3,7 +3,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
import DhLevelData from '../levelData.mjs';
import { commonActorRules } from './base.mjs';
import DhCreature from './creature.mjs';
import { attributeField, resourceField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
import { attributeField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs';
import { ActionField } from '../fields/actionField.mjs';
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
@ -27,34 +27,6 @@ export default class DhCharacter extends DhCreature {
return {
...super.defineSchema(),
resources: new fields.SchemaField({
...Object.values(CONFIG.DH.ACTOR.characterResources).reduce((acc, resource) => {
if (resource.max !== undefined) {
acc[resource.id] = resourceField(
resource.max,
resource.initial,
resource.label,
resource.reverse,
resource.maxLabel
);
} else {
acc[resource.id] = new fields.SchemaField(
{
value: new fields.NumberField({
initial: resource.initial,
min: resource.min,
integer: true,
label: resource.label
}),
isReversed: new fields.BooleanField({ initial: resource.reverse })
},
{ label: resource.label }
);
}
return acc;
}, {})
}),
traits: new fields.SchemaField({
agility: attributeField('DAGGERHEART.CONFIG.Traits.agility.name'),
strength: attributeField('DAGGERHEART.CONFIG.Traits.strength.name'),

View file

@ -4,7 +4,7 @@ import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
import { ActionField } from '../fields/actionField.mjs';
import { adjustDice, adjustRange } from '../../helpers/utils.mjs';
import DHCompanionSettings from '../../applications/sheets-configs/companion-settings.mjs';
import { resourceField, bonusField } from '../fields/actorField.mjs';
import { bonusField } from '../fields/actorField.mjs';
export default class DhCompanion extends DhCreature {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Companion'];
@ -26,10 +26,6 @@ export default class DhCompanion extends DhCreature {
return {
...super.defineSchema(),
partner: new ForeignDocumentUUIDField({ type: 'Actor' }),
resources: new fields.SchemaField({
stress: resourceField(3, 0, 'DAGGERHEART.GENERAL.stress', true),
hope: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.hope' })
}),
evasion: new fields.NumberField({
required: true,
min: 1,

View file

@ -1,3 +1,4 @@
import { resourceField } from '../fields/actorField.mjs';
import BaseDataActor from './base.mjs';
export default class DhCreature extends BaseDataActor {
@ -7,6 +8,34 @@ export default class DhCreature extends BaseDataActor {
return {
...super.defineSchema(),
resources: new fields.SchemaField({
...Object.values(CONFIG.DH.ACTOR[`${this.metadata.type}Resources`]).reduce((acc, resource) => {
if (resource.max !== undefined) {
acc[resource.id] = resourceField(
resource.max,
resource.initial,
resource.label,
resource.reverse,
resource.maxLabel
);
} else {
acc[resource.id] = new fields.SchemaField(
{
value: new fields.NumberField({
initial: resource.initial,
min: resource.min,
integer: true,
label: resource.label
}),
isReversed: new fields.BooleanField({ initial: resource.reverse })
},
{ label: resource.label }
);
}
return acc;
}, {})
}),
advantageSources: new fields.ArrayField(new fields.StringField(), {
label: 'DAGGERHEART.ACTORS.Character.advantageSources.label',
hint: 'DAGGERHEART.ACTORS.Character.advantageSources.hint'

View file

@ -138,10 +138,6 @@
align-items: center;
gap: 4px;
margin-right: 20px;
.resource-manager {
color: light-dark(@dark-blue, @golden);
}
}
.downtime-section {

View file

@ -32,6 +32,24 @@
.hidden {
display: none;
}
img {
width: 18px;
height: 18px;
&.empty {
opacity: 0.4;
}
&.filter {
filter: @golden-filter;
}
&.non-transparent {
border-radius: 50%;
border: 1px solid @golden;
}
}
}
}
}

View file

@ -83,7 +83,7 @@
</span>
{{/times}}
</div>
<a class="resource-manager" data-action="toggleResourceManagement"><i class="fa-solid fa-gear"></i></a>
<button type="button" class="resource-manager" data-action="toggleResourceManagement"><i class="fa-solid fa-bars"></i></button>
</div>
{{#if document.system.class.value}}
<div class="domains-section">

View file

@ -1,11 +1,19 @@
<div class="daggerheart resource-management-container">
{{#each resources as |resource|}}
<div class="resource-section">
<div class="resource-section {{resource.resourceClass}}">
<h4>{{resource.label}}</h4>
{{#times resource.max}}
<span class='resource-value' data-action='toggleResource' data-value="{{add this 1}}" data-resource="{{resource.id}}">
<i class='fa-solid fa-diamond {{#unless (gte ../value (add this 1))}}hidden{{/unless}}'></i>
<i class='fa-regular fa-circle {{#if (gte ../value (add this 1))}}hidden{{/if}}'></i>
{{#unless resource.fullIcon.isPath}}
<i class='{{resource.fullIcon.value}} full {{#unless (gte ../value (add this 1))}}hidden{{/unless}}'></i>
{{else}}
<img src="{{resource.fullIcon.value}}" class="full {{#unless resource.fullIcon.isNotTransparent}}filter{{else}}non-transparent{{/unless}} {{#unless (gte ../value (add this 1))}}hidden{{/unless}}" />
{{/unless}}
{{#unless resource.emptyIcon.isPath}}
<i class='{{resource.emptyIcon.value}} empty {{#if (gte ../value (add this 1))}}hidden{{/if}}'></i>
{{else}}
<img src="{{resource.emptyIcon.value}}" class="empty {{#unless resource.fullIcon.isNotTransparent}}filter{{else}}non-transparent{{/unless}} {{#if (gte ../value (add this 1))}}hidden{{/if}}" />
{{/unless}}
</span>
{{/times}}
</div>