[Feature] 340-341 RollMode & ChatSpeaker (#347)

* Added RollMode to standalone DamageDialog and to RollDialog. ChatMessage now add ChatSpeaker

* Just a little fix for Damage Action

---------

Co-authored-by: Dapoolp <elcatnet@gmail.com>
This commit is contained in:
WBHarry 2025-07-15 17:01:17 +02:00 committed by GitHub
parent da6d9418b7
commit 045754d107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 112 additions and 42 deletions

View file

@ -64,6 +64,13 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
context.rollConfig = this.config;
context.hasRoll = !!this.config.roll;
context.canRoll = true;
context.selectedRollMode = this.config.selectedRollMode;
context.rollModes = Object.entries(CONFIG.Dice.rollModes).map(([action, { label, icon }]) => ({
action,
label,
icon
}));
if (this.config.costs?.length) {
const updatedCosts = this.action.calcCosts(this.config.costs);
context.costs = updatedCosts.map(x => ({
@ -99,6 +106,8 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
static updateRollConfiguration(event, _, formData) {
const { ...rest } = foundry.utils.expandObject(formData.object);
this.config.selectedRollMode = rest.selectedRollMode;
if (this.config.costs) {
this.config.costs = foundry.utils.mergeObject(this.config.costs, rest.costs);
}
@ -122,11 +131,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}
static selectExperience(_, button) {
/* if (this.config.experiences.find(x => x === button.dataset.key)) {
this.config.experiences = this.config.experiences.filter(x => x !== button.dataset.key);
} else {
this.config.experiences = [...this.config.experiences, button.dataset.key];
} */
this.config.experiences =
this.config.experiences.indexOf(button.dataset.key) > -1
? this.config.experiences.filter(x => x !== button.dataset.key)

View file

@ -48,12 +48,22 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
: game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name');
context.extraFormula = this.config.extraFormula;
context.formula = this.roll.constructFormula(this.config);
context.directDamage = this.config.directDamage;
context.selectedRollMode = this.config.selectedRollMode;
context.rollModes = Object.entries(CONFIG.Dice.rollModes).map(([action, { label, icon }]) => ({
action,
label,
icon
}));
return context;
}
static updateRollConfiguration(event, _, formData) {
static updateRollConfiguration(_event, _, formData) {
const { ...rest } = foundry.utils.expandObject(formData.object);
this.config.extraFormula = rest.extraFormula;
this.config.selectedRollMode = rest.selectedRollMode;
this.render();
}

View file

@ -88,7 +88,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
onRollDamage = async (event, message) => {
event.stopPropagation();
const actor = await this.getActor(message.system.source.actor);
if (!actor || !game.user.isGM) return true;
if (game.user.character?.id !== actor.id && !game.user.isGM) return true;
if (message.system.source.item && message.system.source.action) {
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
if (!action || !action?.rollDamage) return;

View file

@ -268,7 +268,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
hasDamage: !!this.damage?.parts?.length,
hasHealing: !!this.healing,
hasEffect: !!this.effects?.length,
hasSave: this.hasSave
hasSave: this.hasSave,
selectedRollMode: game.settings.get('core', 'rollMode')
};
}

View file

@ -10,6 +10,7 @@ export default class DHDamageAction extends DHBaseAction {
}
async rollDamage(event, data) {
const systemData = data.system ?? data;
let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '),
damageTypes = [...new Set(this.damage.parts.reduce((a, c) => a.concat([...c.type]), []))];
@ -19,15 +20,15 @@ export default class DHDamageAction extends DHBaseAction {
let roll = { formula: formula, total: formula },
bonusDamage = [];
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data));
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData));
const config = {
title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }),
roll: { formula },
targets: data.system?.targets.filter(t => t.hit) ?? data.targets,
targets: systemData.targets.filter(t => t.hit) ?? data.targets,
hasSave: this.hasSave,
isCritical: data.system?.roll?.isCritical ?? false,
source: data.system?.source,
isCritical: systemData.roll?.isCritical ?? false,
source: systemData.source,
data: this.getRollData(),
damageTypes,
event
@ -36,6 +37,8 @@ export default class DHDamageAction extends DHBaseAction {
if (data.system) {
config.source.message = data._id;
config.directDamage = false;
} else {
config.directDamage = true;
}
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);

View file

@ -87,7 +87,7 @@ export default class DHRoll extends Roll {
system: config,
rolls: [roll]
};
return await cls.create(msg);
return await cls.create(msg, { rollMode: config.selectedRollMode });
}
static applyKeybindings(config) {

View file

@ -37,4 +37,15 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
e.setAttribute('data-use-perm', document.testUserPermission(game.user, 'OWNER'));
});
}
async _preCreate(data, options, user) {
options.speaker = ChatMessage.getSpeaker();
const rollActorOwner = data.rolls?.[0]?.data?.parent?.owner;
if (rollActorOwner) {
data.author = rollActorOwner ? rollActorOwner.id : data.author;
await this.updateSource({ author: rollActorOwner ?? user });
}
return super._preCreate(data, options, rollActorOwner ?? user);
}
}