[Feature] 946 - Damage/Effect ChatMessages (#1089)

* Initial damage message

* Added hover functionality to adversary damage cards

* Added effect message

* enhance chat messages styles

* .

* Fixed promise lockup

* .

* Fixed token path for message

---------

Co-authored-by: moliloo <dev.murilobrito@gmail.com>
This commit is contained in:
WBHarry 2025-10-29 18:56:37 +01:00 committed by GitHub
parent 906c7ac853
commit ff79dd19bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 450 additions and 12 deletions

View file

@ -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
};

View file

@ -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 })
};
}
}

View file

@ -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);
});
}
/**

View file

@ -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);
}
/**

View file

@ -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,