Feature/chat message styles (#514)

* style items and action chat messages

* enhance death move chat message and fix border bottom from title actions

* fix padding bottom

* Added basic chat-message.hbs

* .

* style remaing chat messages

* style action messages

* remove console log

* add colapsable descriptions in chat messages

* inital style for message rolls

* fix deal damage button style

* add new partchments

* Roll Chat message new design template

* j

* l

* p

* y

* fix _getTags type error and add a alias label for non base messages

* Fix damage & healing roll

* Fix conflict

* Deleting old templates

* Good for now

* fix labels in duality rolls messages and style experience and effects messages

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>
Co-authored-by: Dapoolp <elcatnet@gmail.com>
This commit is contained in:
Murilo Brito 2025-08-02 04:24:51 -03:00 committed by GitHub
parent a4b1130142
commit 74df2c4e87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 1661 additions and 996 deletions

View file

@ -8,10 +8,6 @@ export default class DHAttackAction extends DHDamageAction {
return parent.parent.type === 'weapon' ? 'attack' : 'spellcast';
}
get chatTemplate() {
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
}
prepareData() {
super.prepareData();
if (!!this.item?.system?.attack) {

View file

@ -1,6 +1,7 @@
import DhpActor from '../../documents/actor.mjs';
import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs';
import { ActionMixin } from '../fields/actionField.mjs';
import { abilities } from '../../config/actorConfig.mjs';
const fields = foundry.data.fields;
@ -69,10 +70,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
: this.item?.actor;
}
get chatTemplate() {
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
}
static getRollType(parent) {
return 'trait';
}
@ -161,21 +158,26 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
prepareConfig(event) {
return {
event,
title: this.item.name,
title: `${this.item.name}: ${this.name}`,
source: {
item: this.item._id,
action: this._id,
actor: this.actor.uuid
},
dialog: {},
dialog: {
configure: this.hasRoll
},
type: this.type,
hasRoll: this.hasRoll,
hasDamage: this.damage?.parts?.length && this.type !== 'healing',
hasHealing: this.damage?.parts?.length && this.type === 'healing',
hasEffect: !!this.effects?.length,
hasSave: this.hasSave,
hasTarget: true,
selectedRollMode: game.settings.get('core', 'rollMode'),
isFastForward: event.shiftKey,
data: this.getRollData()
data: this.getRollData(),
evaluate: this.hasRoll
};
}
@ -192,7 +194,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
formula: this.roll.getFormula(),
advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value
};
if (this.roll?.type === 'diceSet') roll.lite = true;
if (this.roll?.type === 'diceSet'
|| !this.hasRoll
) roll.lite = true;
return roll;
}
@ -296,19 +300,27 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
/* SAVE */
async rollSave(actor, event, message) {
if (!actor) return;
const title = actor.isNPC
? game.i18n.localize('DAGGERHEART.GENERAL.reactionRoll')
: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
ability: game.i18n.localize(abilities[this.save.trait]?.label)
});
return actor.diceRoll({
event,
title: 'Roll Save',
title,
roll: {
trait: this.save.trait,
difficulty: this.save.difficulty ?? this.actor?.baseSaveDifficulty,
type: 'reaction'
},
type: 'trait',
hasRoll: true,
data: actor.getRollData()
});
}
updateSaveMessage(result, message, targetId) {
if(!result) return;
const updateMsg = this.updateChatMessage.bind(this, message, targetId, {
result: result.roll.total,
success: result.roll.success

View file

@ -44,19 +44,14 @@ export default class DHDamageAction extends DHBaseAction {
formulas = this.formatFormulas(formulas, systemData);
delete systemData.evaluate;
systemData.targets.forEach(t => t.hit = true);
const config = {
title: game.i18n.format(`DAGGERHEART.UI.Chat.${this.type === 'healing' ? 'healing' : 'damage'}Roll.title`, {
damage: game.i18n.localize(this.name)
}),
...systemData,
roll: formulas,
targets: systemData.targets?.filter(t => t.hit) ?? data.targets,
hasSave: this.hasSave,
isCritical: systemData.roll?.isCritical ?? false,
isHealing: this.type === 'healing',
source: systemData.source,
data: this.getRollData(),
event
};
dialog: {},
data: this.getRollData()
}
if (this.hasSave) config.onSave = this.save.damageMod;
if (data.system) {
config.source.message = data._id;

View file

@ -1,4 +1,3 @@
import DHBaseAction from './baseAction.mjs';
import DHDamageAction from './damageAction.mjs';
export default class DHHealingAction extends DHDamageAction {
@ -7,49 +6,4 @@ export default class DHHealingAction extends DHDamageAction {
static getRollType(parent) {
return 'spellcast';
}
/* static extraSchemas = [...super.extraSchemas, 'target', 'effects', 'healing', 'roll'];
static getRollType(parent) {
return 'spellcast';
}
getFormulaValue(data) {
let formulaValue = this.healing.value;
if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1)
return this.healing.valueAlt;
return formulaValue;
}
async rollHealing(event, data) {
const systemData = data.system ?? data;
let formulas = [
{
formula: this.getFormulaValue(data).getFormula(this.actor),
applyTo: this.healing.applyTo
}
];
const config = {
title: game.i18n.format('DAGGERHEART.UI.Chat.healingRoll.title', {
healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.applyTo].label)
}),
roll: formulas,
targets: systemData.targets?.filter(t => t.hit),
messageType: 'healing',
source: systemData.source,
data: this.getRollData(),
event
};
return CONFIG.Dice.daggerheart.DamageRoll.build(config);
}
get chatTemplate() {
return 'systems/daggerheart/templates/ui/chat/healing-roll.hbs';
}
get modifiers() {
return [];
} */
}

View file

@ -1,21 +1,11 @@
import DHAbilityUse from "./abilityUse.mjs";
import DHAdversaryRoll from "./adversaryRoll.mjs";
import DHDamageRoll from "./damageRoll.mjs";
import DHDualityRoll from "./dualityRoll.mjs";
import DHActorRoll from "./adversaryRoll.mjs";
import DHApplyEffect from './applyEffects.mjs'
export {
DHAbilityUse,
DHAdversaryRoll,
DHDamageRoll,
DHDualityRoll,
DHApplyEffect
}
export const config = {
abilityUse: DHAbilityUse,
adversaryRoll: DHAdversaryRoll,
damageRoll: DHDamageRoll,
dualityRoll: DHDualityRoll,
adversaryRoll: DHActorRoll,
damageRoll: DHActorRoll,
dualityRoll: DHActorRoll,
applyEffect: DHApplyEffect
};

View file

@ -1,6 +1,6 @@
const fields = foundry.data.fields;
export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
export default class DHActorRoll extends foundry.abstract.TypeDataModel {
static defineSchema() {
return {
title: new fields.StringField(),
@ -20,22 +20,29 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
})
})
),
targetSelection: new fields.BooleanField({ initial: true }),
targetSelection: new fields.BooleanField({ initial: false }),
hasRoll: new fields.BooleanField({ initial: false }),
hasDamage: new fields.BooleanField({ initial: false }),
hasHealing: new fields.BooleanField({ initial: false }),
hasEffect: new fields.BooleanField({ initial: false }),
hasSave: new fields.BooleanField({ initial: false }),
hasTarget: new fields.BooleanField({ initial: false }),
isCritical: new fields.BooleanField({ initial: false }),
onSave: new fields.StringField(),
source: new fields.SchemaField({
actor: new fields.StringField(),
item: new fields.StringField(),
action: new fields.StringField()
}),
damage: new fields.ObjectField()
damage: new fields.ObjectField(),
costs: new fields.ArrayField(
new fields.ObjectField()
)
};
}
get messageTemplate() {
return 'systems/daggerheart/templates/ui/chat/adversary-roll.hbs';
return 'systems/daggerheart/templates/ui/chat/roll.hbs';
}
prepareDerivedData() {
@ -46,5 +53,15 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
game.system.api.fields.ActionFields.TargetField.formatTarget(t)
)
: this.targets;
if(this.targetSelection === true) {
this.targetShort = this.targets.reduce((a,c) => {
if(c.hit) a.hit += 1;
else c.miss += 1;
return a;
}, {hit: 0, miss: 0})
}
this.pendingSaves = this.targets.filter(
target => target.hit && target.saved.success === null
).length > 0;
}
}

View file

@ -1,49 +0,0 @@
export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
messageType: new fields.StringField({ initial: 'damage' }),
title: new fields.StringField(),
roll: new fields.DataField({}),
targets: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({ required: true }),
actorId: new fields.StringField({}),
name: new fields.StringField(),
img: new fields.StringField(),
hit: new fields.BooleanField({ initial: false }),
saved: new fields.SchemaField({
result: new fields.NumberField(),
success: new fields.BooleanField({ nullable: true, initial: null })
})
})
),
targetSelection: new fields.BooleanField({ initial: true }),
hasSave: new fields.BooleanField({ initial: false }),
isHealing: new fields.BooleanField({ initial: false }),
onSave: new fields.StringField(),
source: new fields.SchemaField({
actor: new fields.StringField(),
item: new fields.StringField(),
action: new fields.StringField(),
message: new fields.StringField()
}),
directDamage: new fields.BooleanField({ initial: true })
};
}
get messageTemplate() {
return `systems/daggerheart/templates/ui/chat/${this.messageType}-roll.hbs`;
}
prepareDerivedData() {
this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0;
this.currentTargets =
this.targetSelection !== true
? Array.from(game.user.targets).map(t =>
game.system.api.fields.ActionFields.TargetField.formatTarget(t)
)
: this.targets;
}
}

View file

@ -1,7 +0,0 @@
import DHAdversaryRoll from './adversaryRoll.mjs';
export default class DHDualityRoll extends DHAdversaryRoll {
get messageTemplate() {
return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs';
}
}

View file

@ -26,7 +26,7 @@ export default class CostField extends fields.ArrayField {
}
static calcCosts(costs) {
console.log(costs, CostField.getResources.call(this, costs));
// console.log(costs, CostField.getResources.call(this, costs));
const resources = CostField.getResources.call(this, costs);
return costs.map(c => {
c.scale = c.scale ?? 1;

View file

@ -54,7 +54,7 @@ export class DHActionRollData extends foundry.abstract.DataModel {
this.diceRolling.multiplier === 'flat'
? this.diceRolling.flatMultiplier
: `@${this.diceRolling.multiplier}`;
if (this.diceRolling.compare && this.diceRolling.threshold) {
if (this.diceRolling.compare && this.diceRolling.treshold) {
formula = `${multiplier}${this.diceRolling.dice}cs${CONFIG.DH.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`;
} else {
formula = `${multiplier}${this.diceRolling.dice}`;

View file

@ -252,19 +252,27 @@ export function ActionMixin(Base) {
const systemData = {
title: game.i18n.localize('DAGGERHEART.CONFIG.ActionType.action'),
origin: origin,
img: this.img,
name: this.name,
description: this.description,
actions: []
action: { name: this.name, img: this.img, tags: this.tags ? this.tags : ['Spell', 'Arcana', 'Lv 10'] },
itemOrigin: this.item,
description: this.description
};
const msg = {
type: 'abilityUse',
user: game.user.id,
actor: { name: this.actor.name, img: this.actor.img },
author: this.author,
speaker: cls.getSpeaker(),
title: game.i18n.localize('DAGGERHEART.UI.Chat.action.title'),
system: systemData,
content: await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
'systems/daggerheart/templates/ui/chat/action.hbs',
systemData
)
),
flags: {
daggerheart: {
cssClass: 'dh-chat-message dh-style'
}
}
};
cls.create(msg);