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 1/6] 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 2/6] 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 3/6] 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 4/6] 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 isGM}}
+
+ {{/if}}
+
+
+
+ {{#each systemStatusEffects as |status|}}
+

+ {{/each}}
+ {{#if genericStatusEffects}}
+
+ {{#each genericStatusEffects as |status|}}
+

+ {{/each}}
+ {{/if}}
+
+
+
+
+
+
+
+ {{#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}}