Compare commits

...

2 commits

Author SHA1 Message Date
WBHarry
c68b3045f2 TagTeamDialog fixes to accomodate new flat damage.types structure 2026-07-17 15:48:41 +02:00
WBHarry
fbcb9e4572 Moved DamageTypes to roll.options 2026-07-17 14:10:06 +02:00
7 changed files with 81 additions and 86 deletions

View file

@ -612,14 +612,13 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
async getCriticalDamage(origDamage) { async getCriticalDamage(origDamage) {
const newDamage = origDamage ? ChatDamageData.fromJSON(JSON.stringify(origDamage)) : null; const newDamage = origDamage ? ChatDamageData.fromJSON(JSON.stringify(origDamage)) : null;
for (let key in newDamage?.types ?? {}) { for (let key in newDamage?.types ?? {}) {
const damage = newDamage.types[key]; const criticalDamage = await getCritDamageBonus(newDamage.types[key].formula);
const criticalDamage = await getCritDamageBonus(damage.roll.formula);
if (!criticalDamage) continue; if (!criticalDamage) continue;
const criticalTerm = new foundry.dice.terms.NumericTerm({ number: criticalDamage, evaluated: true }); const criticalTerm = new foundry.dice.terms.NumericTerm({ number: criticalDamage, evaluated: true });
criticalTerm.evaluate(); criticalTerm.evaluate();
damage.roll = await Roll.fromTerms([ newDamage.types[key] = await Roll.fromTerms([
...origDamage.types[key].roll.terms, ...origDamage.types[key].terms,
new foundry.dice.terms.OperatorTerm({ operator: '+' }), new foundry.dice.terms.OperatorTerm({ operator: '+' }),
criticalTerm criticalTerm
]); ]);
@ -675,10 +674,10 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
if (mainRoll.damageRollData) { if (mainRoll.damageRollData) {
for (const [key, damage] of Object.entries(secondaryDamage.types ?? {})) { for (const [key, damage] of Object.entries(secondaryDamage.types ?? {})) {
if (key in mainRoll.damageRollData.types) { if (key in mainRoll.damageRollData.types) {
mainRoll.damageRollData.types[key].roll = Roll.fromTerms([ mainRoll.damageRollData.types[key] = Roll.fromTerms([
...baseMainRoll.damageRollData.types[key].roll.terms, ...baseMainRoll.damageRollData.types[key].terms,
new foundry.dice.terms.OperatorTerm({ operator: '+' }), new foundry.dice.terms.OperatorTerm({ operator: '+' }),
...baseSecondaryRoll.damageRollData.types[key].roll.terms ...baseSecondaryRoll.damageRollData.types[key].terms
]); ]);
} else { } else {
mainRoll.damageRollData.types[key] = damage; mainRoll.damageRollData.types[key] = damage;
@ -744,10 +743,10 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
/* This could assumably be done better. For some reason rolls don't get correctly done through rollData.toJSON */ /* This could assumably be done better. For some reason rolls don't get correctly done through rollData.toJSON */
const systemData = { const systemData = {
...mainRoll.options, ...mainRoll.options,
damage: joinedRoll.damageRollData.toJSON() damage: joinedRoll.damageRollData?.toJSON()
}; };
for (const type of Object.keys(joinedRoll.damageRollData.types)) { for (const type of Object.keys(joinedRoll.damageRollData?.types ?? {})) {
systemData.damage.types[type].roll = joinedRoll.damageRollData.types[type].roll.toJSON(); systemData.damage.types[type] = joinedRoll.damageRollData.types[type].toJSON();
} }
const cls = getDocumentClass('ChatMessage'), const cls = getDocumentClass('ChatMessage'),

View file

@ -258,9 +258,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
await message.system.damage.rerollDamageDie(damageType, dice, result); await message.system.damage.rerollDamageDie(damageType, dice, result);
await message.update({ await message.update({
'system.damage.types': { 'system.damage.types': {
[damageType]: { [damageType]: message.system.damage.types[damageType].toJSON()
roll: message.system.damage.types[damageType].roll.toJSON()
}
} }
}); });
} else { } else {

View file

@ -140,9 +140,9 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
const update = { system: { damage: { types: {} } } }; const update = { system: { damage: { types: {} } } };
for (const key of Object.keys(this.damage.types)) { for (const key of Object.keys(this.damage.types)) {
const type = this.damage.types[key]; const type = this.damage.types[key];
const reroll = await type.roll.reroll(); const reroll = await type.reroll();
rerolls.push(reroll); rerolls.push(reroll);
update.system.damage.types[key] = { roll: reroll.toJSON() }; update.system.damage.types[key] = reroll.toJSON();
} }
await triggerChatRollFx(rerolls); await triggerChatRollFx(rerolls);
@ -192,10 +192,15 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
source.damage = { source.damage = {
types: Object.keys(source.damage).reduce((acc, key) => { types: Object.keys(source.damage).reduce((acc, key) => {
const damageData = source.damage[key]; const damageData = source.damage[key];
acc[key] = { const oldRoll = damageData.parts[0]?.roll;
roll: damageData.parts[0]?.roll ?? null, acc[key] = oldRoll ? {
damageTypes: damageData.parts[0]?.damageTypes ?? [] ...oldRoll,
}; options: {
...oldRoll.options,
damageTypes: damageData.parts[0].damageTypes ?? []
}
} : null;
return acc; return acc;
}, {}) }, {})
}; };

View file

@ -11,10 +11,7 @@ export class ChatDamageData extends foundry.abstract.DataModel {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
types: new fields.TypedObjectField(new fields.SchemaField({ types: new fields.TypedObjectField(new fields.JSONField({validate: ChatDamageData.#validateRoll}))
roll: new fields.JSONField({validate: ChatDamageData.#validateRoll}),
damageTypes: new fields.ArrayField(new fields.StringField({ choices: CONFIG.DH.GENERAL.damageTypes }))
}))
}; };
} }
@ -31,14 +28,14 @@ export class ChatDamageData extends foundry.abstract.DataModel {
for (const key of Object.keys(this.types)) { for (const key of Object.keys(this.types)) {
const type = this.types[key]; const type = this.types[key];
try { try {
type.roll = Roll.fromData(type.roll); this.types[key] = Roll.fromData(type);
type.roll.modifierTotal = CONFIG.Dice.daggerheart.DHRoll.calculateTotalModifiers(type.roll); this.types[key].options.modifierTotal = CONFIG.Dice.daggerheart.DHRoll.calculateTotalModifiers(type);
} catch {} } catch {}
} }
} }
async rerollDamageDie(damageType, dice, resultIndex) { async rerollDamageDie(damageType, dice, resultIndex) {
const reroll = this.types[damageType].roll; const reroll = this.types[damageType];
const rerollDice = reroll.dice[dice]; const rerollDice = reroll.dice[dice];
await rerollDice.rerollResult(resultIndex); await rerollDice.rerollResult(resultIndex);
await reroll._evaluate(); await reroll._evaluate();

View file

@ -19,12 +19,10 @@ export default class DamageRoll extends DHRoll {
for (const roll of config.roll) { for (const roll of config.roll) {
await roll.roll.evaluate(); await roll.roll.evaluate();
roll.roll.options = { damageTypes: roll.damageTypes ?? [] };
if (!config.damage?.types) config.damage = { types: {} }; if (!config.damage?.types) config.damage = { types: {} };
config.damage.types[roll.applyTo] = { config.damage.types[roll.applyTo] = roll.roll;
roll: roll.roll,
damageTypes: roll.damageTypes ?? []
};
} }
roll._evaluated = true; roll._evaluated = true;

View file

@ -1,25 +1,24 @@
{{#each damage.types as |damage key|}} {{#each damage.types as |roll key|}}
<div class="roll-data {{#if isCritical}}critical{{/if}}"> <div class="roll-data {{#if isCritical}}critical{{/if}}">
<div class="duality-label"> <div class="duality-label">
<span>{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}:</span> <span>{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}:</span>
<span>{{damage.roll.total}}</span> <span>{{damage.roll.total}}</span>
</div> </div>
{{#with damage.roll}}
<div class="roll-dice-container"> <div class="roll-dice-container">
{{#each this.dice as |dice index|}} {{#each roll.dice as |dice index|}}
<a class="roll-dice" data-action="rerollDamageDice" data-member-key="{{../../../key}}" data-damage-key="{{@../../key}}" data-dice="{{index}}"> <a class="roll-dice" data-action="rerollDamageDice" data-member-key="{{../../../key}}" data-damage-key="{{@../../key}}" data-dice="{{index}}">
<span class="dice-label">{{dice.total}}</span> <span class="dice-label">{{dice.total}}</span>
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" dice.denomination ".svg"}}" /> <img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" dice.denomination ".svg"}}" />
</a> </a>
{{#unless @last}} {{#unless @last}}
<span class="roll-operator">+</span> <span class="roll-operator">+</span>
{{/unless}} {{/unless}}
{{/each}} {{/each}}
{{#if this.modifierTotal}} {{#if roll.modifierTotal}}
{{#if this.dice.length}}<span class="roll-operator">{{#if (gte this.modifierTotal 0)}}+{{else}}-{{/if}}</span>{{/if}} {{#if roll.dice.length}}<span class="roll-operator">{{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}}</span>{{/if}}
<span class="roll-value">{{positive this.modifierTotal}}</span> <span class="roll-value">{{positive roll.modifierTotal}}</span>
{{/if}} {{/if}}
</div> </div>
{{/with}}
</div> </div>
{{/each}} {{/each}}

View file

@ -10,57 +10,56 @@
</div> </div>
<div class="roll-part-extra on-reduced"> <div class="roll-part-extra on-reduced">
<div class="wrapper"> <div class="wrapper">
{{#each damage.types as | data index | }} {{#each damage.types as | roll index | }}
<div class="roll-formula">{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.inChatRoll')}}: {{data.roll.total}}</div> <div class="roll-formula">{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.inChatRoll')}}: {{roll.total}}</div>
{{/each}} {{/each}}
</div> </div>
</div> </div>
<div class="roll-part-content dice-result"> <div class="roll-part-content dice-result">
<div class="dice-tooltip"> <div class="dice-tooltip">
<div class="wrapper"> <div class="wrapper">
{{#each damage.types as | data index | }} {{#each damage.types as | roll index | }}
<fieldset> <fieldset>
<legend> <legend>
{{#if ../hasHealing}}{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.name')}}{{else}}{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.inChatRoll')}}{{/if}} <div class="roll-formula">{{localize "DAGGERHEART.GENERAL.total"}}: {{roll.total}}</div>{{#if (and (eq index "hitPoints") ../isDirect)}} <div class="roll-formula">{{localize "DAGGERHEART.CONFIG.DamageType.direct.short"}}</div>{{/if}} {{#if ../hasHealing}}{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.name')}}{{else}}{{localize (concat 'DAGGERHEART.CONFIG.HealingType.' index '.inChatRoll')}}{{/if}} <div class="roll-formula">{{localize "DAGGERHEART.GENERAL.total"}}: {{roll.total}}</div>{{#if (and (eq index "hitPoints") ../isDirect)}} <div class="roll-formula">{{localize "DAGGERHEART.CONFIG.DamageType.direct.short"}}</div>{{/if}}
</legend> </legend>
{{#with data.roll}}
{{#if (and (not @root.hasHealing) damageTypes.length)}} {{#if (and (not @root.hasHealing) roll.options.damageTypes.length)}}
<label class="roll-part-header"><span> <label class="roll-part-header"><span>
{{#each damageTypes}} {{#each roll.options.damageTypes}}
{{localize (concat 'DAGGERHEART.CONFIG.ArmorFeature.' this '.name')}} {{localize (concat 'DAGGERHEART.CONFIG.ArmorFeature.' this '.name')}}
{{#unless @last}}/{{/unless}} {{#unless @last}}/{{/unless}}
{{/each}} {{/each}}
<div class="roll-formula">{{total}}</div></span></label> <div class="roll-formula">{{roll.total}}</div></span></label>
{{/if}} {{/if}}
<div class="roll-dice"> <div class="roll-dice">
{{#if dice.length}} {{#if roll.dice.length}}
{{#each dice}} {{#each roll.dice}}
{{#each results}} {{#each results}}
{{#if active}} {{#if active}}
<div class="roll-die{{#unless @../first}} has-plus{{/unless}}"> <div class="roll-die{{#unless @../first}} has-plus{{/unless}}">
<div <div
class="dice reroll-button {{../dice}}" class="dice reroll-button {{../dice}}"
data-die-index="0" data-type="damage" data-damage-type="{{@../../key}}" data-dice="{{@../key}}" data-result="{{@key}}" data-die-index="0" data-type="damage" data-damage-type="{{@../../key}}" data-dice="{{@../key}}" data-result="{{@key}}"
> >
{{#if hasRerolls}}<i class="fa-solid fa-dice dice-rerolled" data-tooltip="{{localize "DAGGERHEART.GENERAL.rerolled"}}"></i>{{/if}} {{#if hasRerolls}}<i class="fa-solid fa-dice dice-rerolled" data-tooltip="{{localize "DAGGERHEART.GENERAL.rerolled"}}"></i>{{/if}}
{{result}} {{result}}
</div>
</div> </div>
{{/if}} </div>
{{/each}} {{/if}}
{{/each}} {{/each}}
{{#if modifierTotal}} {{/each}}
<div class="roll-die{{#if (gt modifierTotal 0)}} has-plus{{/if}}"> {{#if roll.modifierTotal}}
<div class="font-20">{{modifierTotal}}</div> <div class="roll-die{{#if (gt roll.modifierTotal 0)}} has-plus{{/if}}">
</div> <div class="font-20">{{roll.modifierTotal}}</div>
{{/if}}
{{else}}
<div class="roll-die">
<div class="font-20">{{total}}</div>
</div> </div>
{{/if}} {{/if}}
</div> {{else}}
{{/with}} <div class="roll-die">
<div class="font-20">{{roll.total}}</div>
</div>
{{/if}}
</div>
</fieldset> </fieldset>
{{/each}} {{/each}}
</div> </div>