diff --git a/module/applications/dialogs/groupRollDialog.mjs b/module/applications/dialogs/groupRollDialog.mjs index 52baf537..dd504b4b 100644 --- a/module/applications/dialogs/groupRollDialog.mjs +++ b/module/applications/dialogs/groupRollDialog.mjs @@ -106,7 +106,12 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat const context = await super._prepareContext(_options); context.isGM = game.user.isGM; - context.isEditable = this.getIsEditable(); + context.isEditable = + game.user.isGM || + this.party.system.partyMembers.some(actor => { + const selected = Boolean(this.party.system.groupRoll.participants[actor.id]); + return selected && actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER); + }); context.fields = this.party.system.schema.fields.groupRoll.fields; context.data = this.party.system.groupRoll; context.traitOptions = CONFIG.DH.ACTOR.abilities; @@ -265,13 +270,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat ]; } - getIsEditable() { - return this.party.system.partyMembers.some(actor => { - const selected = Boolean(this.party.system.groupRoll.participants[actor.id]); - return selected && actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER); - }); - } - groupRollRefresh = ({ refreshType, action, parts }) => { if (refreshType !== RefreshType.GroupRoll) return; diff --git a/module/applications/dialogs/tagTeamDialog.mjs b/module/applications/dialogs/tagTeamDialog.mjs index 4e63d93b..3dc6b0fc 100644 --- a/module/applications/dialogs/tagTeamDialog.mjs +++ b/module/applications/dialogs/tagTeamDialog.mjs @@ -116,7 +116,12 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.isEditable = this.getIsEditable(); + context.isEditable = + game.user.isGM || + this.party.system.partyMembers.some(actor => { + const selected = Boolean(this.party.system.tagTeam.members[actor.id]); + return selected && actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER); + }); context.fields = this.party.system.schema.fields.tagTeam.fields; context.data = this.party.system.tagTeam; context.rollTypes = CONFIG.DH.GENERAL.tagTeamRollTypes; @@ -179,57 +184,56 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio } if (Object.keys(this.party.system.tagTeam.members).includes(partId)) { - const data = this.party.system.tagTeam.members[partId]; - const actor = game.actors.get(partId); - - const rollOptions = []; - const damageRollOptions = []; - for (const item of actor.items) { - if (item.system.metadata.hasActions) { - const actions = [...item.system.actions, ...(item.system.attack ? [item.system.attack] : [])]; - for (const action of actions) { - if (action.hasRoll) { - const actionItem = { - value: action.uuid, - label: action.name, - group: item.name, - baseAction: action.baseAction - }; - - if (action.hasDamage) damageRollOptions.push(actionItem); - else rollOptions.push(actionItem); - } - } - } - } - - 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; - partContext.hasDamage |= Boolean(damage); - const critHitPointsDamage = await this.getCriticalDamage(damage); - - partContext.members[partId] = { - ...data, - roll: data.roll, - isEditable: actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER), - key: partId, - readyToRoll: Boolean(data.rollChoice), - hasRolled: Boolean(data.rollData), - rollOptions, - damageRollOptions, - damage: damage, - critDamage: critHitPointsDamage, - useCritDamage: critSelected || (critSelected === undefined && data.rollData?.options?.roll?.isCritical) - }; + const data = await this.#prepareMemberContext(partId); + partContext.hasDamage |= Boolean(data?.damage); + partContext.members[partId] = data; } return partContext; } + async #prepareMemberContext(partId) { + const data = this.party.system.tagTeam.members[partId] ?? {}; + const actor = game.actors.get(partId); + if (!actor) console.error(`Failed to get actor ${partId}`); + + const rollOptions = []; + const damageRollOptions = []; + for (const item of actor?.items ?? []) { + if (!item.system.metadata.hasActions) continue; + const actions = [...item.system.actions, ...(item.system.attack ? [item.system.attack] : [])]; + for (const action of actions) { + if (action.hasRoll) { + const collection = action.hasDamage ? damageRollOptions : rollOptions; + collection.push({ + value: action.uuid, + label: action.name, + group: item.name, + baseAction: action.baseAction + }); + } + } + } + + 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, + roll: data.roll, + isEditable: actor?.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER), + key: partId, + readyToRoll: Boolean(data.rollChoice), + hasRolled: Boolean(data.rollData), + rollOptions, + damageRollOptions, + damage: damage, + critDamage: await this.getCriticalDamage(damage), + useCritDamage: critSelected || (critSelected === undefined && data.rollData?.options?.roll?.isCritical) + }; + } + getUpdatingParts(target) { const { initialization, rollSelection, result } = this.constructor.PARTS; const isInitialization = this.tabGroups.application === initialization.id; @@ -273,13 +277,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio ); } - getIsEditable() { - return this.party.system.partyMembers.some(actor => { - const selected = Boolean(this.party.system.tagTeam.members[actor.id]); - return selected && actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER); - }); - } - tagTeamRefresh = ({ refreshType, action, parts }) => { if (refreshType !== RefreshType.TagTeamRoll) return; @@ -649,42 +646,50 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio } async getJoinedRoll({ overrideIsCritical, displayVersion } = {}) { - const memberValues = Object.values(this.party.system.tagTeam.members); - const selectedRoll = memberValues.find(x => x.selected); - let baseMainRoll = selectedRoll ?? memberValues[0]; - let baseSecondaryRoll = selectedRoll - ? memberValues.find(x => !x.selected) - : memberValues.length > 1 - ? memberValues[1] - : null; + try { + const memberValues = Object.values(this.party.system.tagTeam.members); + const selectedRoll = memberValues.find(x => x.selected); + const baseMainRoll = selectedRoll ?? memberValues[0]; + const baseSecondaryRoll = selectedRoll + ? memberValues.find(x => !x.selected) + : memberValues.length > 1 + ? memberValues[1] + : null; - if (!baseMainRoll?.rollData || !baseSecondaryRoll) return null; + if (!baseMainRoll?.rollData || !baseSecondaryRoll) return null; - const mainRoll = new MemberData(baseMainRoll.toObject()); - const secondaryRollData = new MemberData(baseSecondaryRoll.toObject()).rollData; - const systemData = mainRoll.rollData.options; - const isCritical = overrideIsCritical ?? systemData.roll.isCritical; - if (isCritical) systemData.damage = await this.getCriticalDamage(systemData.damage); + const mainRoll = new MemberData(baseMainRoll.toObject()); + const secondaryRollData = new MemberData(baseSecondaryRoll.toObject()).rollData; + const systemData = mainRoll.rollData.options; + const isCritical = overrideIsCritical ?? systemData.roll.isCritical; + if (isCritical) systemData.damage = await this.getCriticalDamage(systemData.damage); - if (secondaryRollData?.options.hasDamage) { - const secondaryDamage = (displayVersion ? overrideIsCritical : isCritical) - ? await this.getCriticalDamage(secondaryRollData.options.damage) - : secondaryRollData.options.damage; - if (systemData.damage) { - for (const key in secondaryDamage) { - const damage = secondaryDamage[key]; - 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); + if (secondaryRollData?.options.hasDamage) { + const secondaryDamage = (displayVersion ? overrideIsCritical : isCritical) + ? 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 { + systemData.damage[key] = damage; + } + } + } else { + systemData.damage = secondaryDamage; } - } else { - systemData.damage = secondaryDamage; } - } - return mainRoll; + return mainRoll; + } catch (err) { + console.error(err); + return null; + } } static async #onCancelRoll(_event, _button, options = { confirm: true }) { diff --git a/styles/less/sheets/actors/adversary/actions.less b/styles/less/sheets/actors/adversary/features.less similarity index 100% rename from styles/less/sheets/actors/adversary/actions.less rename to styles/less/sheets/actors/adversary/features.less diff --git a/styles/less/sheets/actors/adversary/index.less b/styles/less/sheets/actors/adversary/index.less new file mode 100644 index 00000000..a1ab41c7 --- /dev/null +++ b/styles/less/sheets/actors/adversary/index.less @@ -0,0 +1,5 @@ +@import './features.less'; +@import './header.less'; +@import './sheet.less'; +@import './sidebar.less'; +@import './effects.less'; diff --git a/styles/less/sheets/actors/character/index.less b/styles/less/sheets/actors/character/index.less new file mode 100644 index 00000000..edefe0a1 --- /dev/null +++ b/styles/less/sheets/actors/character/index.less @@ -0,0 +1,8 @@ +@import './biography.less'; +@import './effects.less'; +@import './features.less'; +@import './header.less'; +@import './inventory.less'; +@import './loadout.less'; +@import './sheet.less'; +@import './sidebar.less'; diff --git a/styles/less/sheets/actors/companion/index.less b/styles/less/sheets/actors/companion/index.less new file mode 100644 index 00000000..c4931814 --- /dev/null +++ b/styles/less/sheets/actors/companion/index.less @@ -0,0 +1,4 @@ +@import './details.less'; +@import './header.less'; +@import './sheet.less'; +@import './effects.less'; diff --git a/styles/less/sheets/actors/environment/actions.less b/styles/less/sheets/actors/environment/features.less similarity index 100% rename from styles/less/sheets/actors/environment/actions.less rename to styles/less/sheets/actors/environment/features.less diff --git a/styles/less/sheets/actors/environment/index.less b/styles/less/sheets/actors/environment/index.less new file mode 100644 index 00000000..211c8e60 --- /dev/null +++ b/styles/less/sheets/actors/environment/index.less @@ -0,0 +1,4 @@ +@import './features.less'; +@import './header.less'; +@import './potentialAdversaries.less'; +@import './sheet.less'; diff --git a/styles/less/sheets/actors/party/index.less b/styles/less/sheets/actors/party/index.less new file mode 100644 index 00000000..56f7a457 --- /dev/null +++ b/styles/less/sheets/actors/party/index.less @@ -0,0 +1,4 @@ +@import './header.less'; +@import './party-members.less'; +@import './sheet.less'; +@import './inventory.less'; diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 7d595614..ca1bc840 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -2,35 +2,11 @@ @import './actors/actor-sheet-shared.less'; -@import './actors/adversary/actions.less'; -@import './actors/adversary/header.less'; -@import './actors/adversary/sheet.less'; -@import './actors/adversary/sidebar.less'; -@import './actors/adversary/effects.less'; - -@import './actors/character/biography.less'; -@import './actors/character/effects.less'; -@import './actors/character/features.less'; -@import './actors/character/header.less'; -@import './actors/character/inventory.less'; -@import './actors/character/loadout.less'; -@import './actors/character/sheet.less'; -@import './actors/character/sidebar.less'; - -@import './actors/companion/details.less'; -@import './actors/companion/header.less'; -@import './actors/companion/sheet.less'; -@import './actors/companion/effects.less'; - -@import './actors/environment/actions.less'; -@import './actors/environment/header.less'; -@import './actors/environment/potentialAdversaries.less'; -@import './actors/environment/sheet.less'; - -@import './actors/party/header.less'; -@import './actors/party/party-members.less'; -@import './actors/party/sheet.less'; -@import './actors/party/inventory.less'; +@import './actors/adversary/index.less'; +@import './actors/character/index.less'; +@import './actors/companion/index.less'; +@import './actors/environment/index.less'; +@import './actors/party/index.less'; @import './items/beastform.less'; @import './items/class.less';