diff --git a/module/applications/dialogs/tagTeamDialog.mjs b/module/applications/dialogs/tagTeamDialog.mjs index e6492c50..b33541a3 100644 --- a/module/applications/dialogs/tagTeamDialog.mjs +++ b/module/applications/dialogs/tagTeamDialog.mjs @@ -1,5 +1,4 @@ import { ResourceUpdateMap } from '../../data/action/baseAction.mjs'; -import { ChatDamageData } from '../../data/chat-message/chatDamageData.mjs'; import { MemberData } from '../../data/tagTeamData.mjs'; import { getCritDamageBonus, shouldUseHopeFearAutomation } from '../../helpers/utils.mjs'; import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; @@ -237,6 +236,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio const selectedRoll = Object.values(this.party.system.tagTeam.members).find(member => member.selected); const critSelected = !selectedRoll ? undefined : (selectedRoll?.rollData?.options?.roll?.isCritical ?? false); + const damage = data.rollData?.options?.damage; return { ...data, @@ -247,8 +247,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio hasRolled: Boolean(data.rollData), rollOptions, damageRollOptions, - damage: data.damageRollData, - critDamage: await this.getCriticalDamage(data.damageRollData), + damage: damage, + critDamage: await this.getCriticalDamage(damage), useCritDamage: critSelected || (critSelected === undefined && data.rollData?.options?.roll?.isCritical) }; } @@ -609,20 +609,47 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio ); } - async getCriticalDamage(origDamage) { - const newDamage = origDamage ? ChatDamageData.fromJSON(JSON.stringify(origDamage)) : null; - for (let key in newDamage?.types ?? {}) { - const damage = newDamage.types[key]; - const criticalDamage = await getCritDamageBonus(damage.roll.formula); - if (!criticalDamage) continue; - - const criticalTerm = new foundry.dice.terms.NumericTerm({ number: criticalDamage, evaluated: true }); - criticalTerm.evaluate(); - damage.roll = await Roll.fromTerms([ - ...origDamage.types[key].roll.terms, - new foundry.dice.terms.OperatorTerm({ operator: '+' }), - criticalTerm - ]); + async getCriticalDamage(damage) { + const newDamage = foundry.utils.deepClone(damage); + for (let key in newDamage) { + var damage = newDamage[key]; + damage.formula = ''; + damage.total = 0; + + for (let part of damage.parts) { + const criticalDamage = await getCritDamageBonus(part.formula); + if (criticalDamage) { + part.modifierTotal += criticalDamage; + part.total += criticalDamage; + part.formula = `${part.dice.map(x => x.formula).join(' + ')} + ${part.modifierTotal}`; + part.roll = new Roll(part.formula); + } + + damage.formula = [damage.formula, part.formula].filter(x => x).join(' + '); + damage.total += part.total; + } + } + + return newDamage; + } + + async getNonCriticalDamage(config) { + const newDamage = foundry.utils.deepClone(config.damage); + for (let key in newDamage) { + var damage = newDamage[key]; + damage.formula = ''; + damage.total = 0; + + for (let part of damage.parts) { + const critDamageBonus = await getCritDamageBonus(part.formula); + part.modifierTotal -= critDamageBonus; + part.total -= critDamageBonus; + part.formula = `${part.dice.map(x => x.formula).join(' + ')} + ${part.modifierTotal}`; + part.roll = new Roll(part.formula); + + damage.formula = [damage.formula, part.formula].filter(x => x).join(' + '); + damage.total += part.total; + } } return newDamage; @@ -658,34 +685,29 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio if (!baseMainRoll?.rollData || !baseSecondaryRoll) return null; const mainRoll = new MemberData(baseMainRoll.toObject()); - mainRoll.damageRollData = baseMainRoll.damageRollData ? - ChatDamageData.fromJSON(JSON.stringify(baseMainRoll.damageRollData)) : null; - const secondaryRoll = new MemberData(baseSecondaryRoll.toObject()); - secondaryRoll.damageRollData = baseSecondaryRoll.damageRollData ? - ChatDamageData.fromJSON(JSON.stringify(baseSecondaryRoll.damageRollData)) : null; - + const secondaryRollData = new MemberData(baseSecondaryRoll.toObject()).rollData; const systemData = mainRoll.rollData.options; const isCritical = overrideIsCritical ?? systemData.roll.isCritical; - if (isCritical) mainRoll.damageRollData = await this.getCriticalDamage(systemData.damageRollData); + if (isCritical) systemData.damage = await this.getCriticalDamage(systemData.damage); - if (secondaryRoll.damageRollData) { + if (secondaryRollData?.options.hasDamage) { const secondaryDamage = (displayVersion ? overrideIsCritical : isCritical) - ? await this.getCriticalDamage(secondaryRoll.damageRollData) - : secondaryRoll.damageRollData; - if (mainRoll.damageRollData) { - for (const [key, damage] of Object.entries(secondaryDamage.types ?? {})) { - if (key in mainRoll.damageRollData.types) { - mainRoll.damageRollData.types[key].roll = Roll.fromTerms([ - ...baseMainRoll.damageRollData.types[key].roll.terms, - new foundry.dice.terms.OperatorTerm({ operator: '+' }), - ...baseSecondaryRoll.damageRollData.types[key].roll.terms - ]); + ? await this.getCriticalDamage(secondaryRollData.options.damage) + : secondaryRollData.options.damage; + if (systemData.damage) { + for (const [key, damage] of Object.entries(secondaryDamage ?? {})) { + if (key in systemData.damage) { + systemData.damage[key].formula = [systemData.damage[key]?.formula, damage.formula] + .filter(x => x) + .join(' + '); + systemData.damage[key].total += damage.total; + systemData.damage[key].parts.push(...damage.parts); } else { - mainRoll.damageRollData.types[key] = damage; + systemData.damage[key] = damage; } } } else { - mainRoll.damageRollData = secondaryDamage; + systemData.damage = secondaryDamage; } } @@ -740,23 +762,13 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio const mainActor = this.party.system.partyMembers.find(x => x.uuid === mainRoll.options.source.actor); mainRoll.options.title = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.chatMessageRollTitle'); - - /* This could assumably be done better. For some reason rolls don't get correctly done through rollData.toJSON */ - const systemData = { - ...mainRoll.options, - damage: joinedRoll.damageRollData.toJSON() - }; - for (const type of Object.keys(joinedRoll.damageRollData.types)) { - systemData.damage.types[type].roll = joinedRoll.damageRollData.types[type].roll.toJSON(); - } - const cls = getDocumentClass('ChatMessage'), msgData = { type: 'dualityRoll', user: game.user.id, title: game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title'), speaker: cls.getSpeaker({ actor: mainActor }), - system: systemData, + system: mainRoll.options, rolls: [JSON.stringify(joinedRoll.roll)], sound: null, flags: { core: { RollTable: true } } diff --git a/module/data/actor/party.mjs b/module/data/actor/party.mjs index 61062847..5b9cccab 100644 --- a/module/data/actor/party.mjs +++ b/module/data/actor/party.mjs @@ -3,7 +3,6 @@ import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayFie import TagTeamData from '../tagTeamData.mjs'; import GroupRollData from '../groupRollData.mjs'; import { GoldField } from '../fields/actorField.mjs'; -import { ChatDamageData } from '../chat-message/chatDamageData.mjs'; export default class DhParty extends BaseDataActor { /** @inheritdoc */ @@ -49,15 +48,6 @@ export default class DhParty extends BaseDataActor { } } - prepareDerivedData() { - for (const memberKey in this.tagTeam.members) { - const member = this.tagTeam.members[memberKey]; - member.damageRollData = member.rollData?.options.damage ? - ChatDamageData.fromJSON(JSON.stringify(member.rollData.options.damage)) : null; - member.damageRollData?.prepareRolls(); - } - } - _onCreate(data, options, userId) { super._onCreate(data, options, userId); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 13408329..16472fea 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -1,8 +1,7 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; import { triggerChatRollFx } from '../helpers/utils.mjs'; -import BaseRoll from './baseRoll.mjs'; -export default class DHRoll extends BaseRoll { +export default class DHRoll extends Roll { baseTerms = []; constructor(formula, data = {}, options = {}) { super(formula, data, foundry.utils.mergeObject(options, { roll: [] }, { overwrite: false })); diff --git a/module/systemRegistration/migration-handlers/2_6_0.mjs b/module/systemRegistration/migration-handlers/2_6_0.mjs deleted file mode 100644 index 1efd5600..00000000 --- a/module/systemRegistration/migration-handlers/2_6_0.mjs +++ /dev/null @@ -1,20 +0,0 @@ -import { MigrationHandlerBase } from './base.mjs'; - -export class Migration_2_6_0 extends MigrationHandlerBase { - version = '2.6.0'; - - /** @inheritdoc */ - async updateActorSource(actor) { - if (actor.type === 'party') { - return { - _id: actor._id, - system: { - tagTeam: { - initiator: null, - members: _replace({}) - } - } - }; - } - } -} \ No newline at end of file diff --git a/module/systemRegistration/migration-handlers/base.mjs b/module/systemRegistration/migration-handlers/base.mjs index 29c181ce..7426570d 100644 --- a/module/systemRegistration/migration-handlers/base.mjs +++ b/module/systemRegistration/migration-handlers/base.mjs @@ -1,9 +1,8 @@ /** * @import DHItem from "../../documents/item.mjs"; -* @import DhActor from "../../documents/actor.mjs"; */ -/** +/** * The base class of an async migration. * These are generally run between versions for things that require compendiums or must be done in post. * The migrate() functions calls the various updateXSource() functions. @@ -23,16 +22,6 @@ export class MigrationHandlerBase { return null; } - /** - * Update a world actor - * @param {DhActor} actor - * @returns {Promise} - * @protected - */ - async updateActorSource(actor) { - return null; - } - async migrate() { // todo: handle more than just migrating effects. Right now this can only migrate effects // NOTE: the preload is hardcoded, we should not hardcode it @@ -71,39 +60,10 @@ export class MigrationHandlerBase { } }; - const updateActor = async actor => { - const actorUpdate = await this.updateActorSource(actor); - if (actorUpdate) { - batch.push({ - action: 'update', - documentName: 'Actor', - updates: [actorUpdate] - }); - } - - const aeUpdates = []; + for (const actor of game.actors) { for (const item of actor.items) { await updateItem(item); } - - for (const effect of actor.effects) { - const changes = await this.updateActiveEffectSource(effect.toObject(), { parent: actor }); - if (changes) aeUpdates.push(changes); - } - if (aeUpdates.length) { - batch.push({ - action: 'update', - documentName: 'ActiveEffect', - updates: aeUpdates, - parent: actor - }); - } - } - - - for (const actor of game.actors) { - await updateActor(actor); - progress.advance(); } for (const item of game.items) { diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index af11cd2c..fef97b8f 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -1,6 +1,5 @@ import { defaultRestOptions } from '../config/generalConfig.mjs'; import { Migration_2_5_2 } from './migration-handlers/2_5_2.mjs'; -import { Migration_2_6_0 } from './migration-handlers/2_6_0.mjs'; export async function runMigrations() { let lastMigrationVersion = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion); @@ -330,8 +329,7 @@ export async function runMigrations() { /* -------------------------------------------- */ const migrations = [ - new Migration_2_5_2(), - new Migration_2_6_0() + new Migration_2_5_2() ].filter(m => m.version && foundry.utils.isNewerVersion(m.version, lastMigrationVersion)); for (const handler of migrations) { diff --git a/templates/dialogs/tagTeamDialog/parts/tagTeamDamageParts.hbs b/templates/dialogs/tagTeamDialog/parts/tagTeamDamageParts.hbs index 90f720cf..2a366269 100644 --- a/templates/dialogs/tagTeamDialog/parts/tagTeamDamageParts.hbs +++ b/templates/dialogs/tagTeamDialog/parts/tagTeamDamageParts.hbs @@ -1,25 +1,25 @@ -{{#each damage.types as |damage key|}} +{{#each damage as |damage key|}}
{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}: - {{damage.roll.total}} + {{damage.total}}
- {{#with damage.roll}} + {{#each damage.parts as |part|}}
- {{#each this.dice as |dice index|}} - + {{#each part.dice as |dice index|}} + {{dice.total}} - + {{#unless @last}} + {{/unless}} {{/each}} - {{#if this.modifierTotal}} - {{#if this.dice.length}}{{#if (gte this.modifierTotal 0)}}+{{else}}-{{/if}}{{/if}} - {{positive this.modifierTotal}} + {{#if part.modifierTotal}} + {{#if part.dice.length}}{{#if (gte part.modifierTotal 0)}}+{{else}}-{{/if}}{{/if}} + {{positive part.modifierTotal}} {{/if}}
- {{/with}} + {{/each}}
{{/each}} \ No newline at end of file diff --git a/templates/dialogs/tagTeamDialog/result.hbs b/templates/dialogs/tagTeamDialog/result.hbs index ccce9504..151c8c87 100644 --- a/templates/dialogs/tagTeamDialog/result.hbs +++ b/templates/dialogs/tagTeamDialog/result.hbs @@ -6,22 +6,22 @@ {{#if hintText}}
{{localize hintText}}
{{else}} - {{#if joinedRoll.rollData}} + {{#if joinedRoll.roll}}
-
{{joinedRoll.rollData.total}}
+
{{joinedRoll.roll.total}}
{{localize "DAGGERHEART.GENERAL.withThing" thing=joinedRoll.roll.totalLabel}}
{{/if}} - {{#if joinedRoll.damageRollData}} + {{#if joinedRoll.rollData.options.hasDamage}}
- {{#each joinedRoll.damageRollData.types as |damage key|}} + {{#each joinedRoll.rollData.options.damage as |damage key|}}
{{localize (concat "DAGGERHEART.CONFIG.HealingType." key ".name")}}
-
{{damage.roll.total}}
+
{{damage.total}}
{{/each}}