diff --git a/lang/en.json b/lang/en.json index 65323790..e31a1d1b 100755 --- a/lang/en.json +++ b/lang/en.json @@ -319,21 +319,6 @@ } }, "newAdversary": "New Adversary" - }, - "Party": { - "Subtitle": { - "character": "{community} {ancestry} | {subclass} {class}", - "companion": "Companion of {partner}" - }, - "RemoveConfirmation": { - "title": "Remove member {name}", - "text": "Are you sure you want to remove {name} from the party?" - }, - "Thresholds": { - "minor": "MIN", - "major": "MAJ", - "severe": "SEV" - } } }, "APPLICATIONS": { @@ -550,6 +535,18 @@ }, "takeDowntime": "Take Downtime" }, + "GroupRoll": { + "title": "Group Roll", + "leader": "Leader", + "partyTeam": "Party Team", + "team": "Team", + "selectLeader": "Select a Leader", + "selectMember": "Select a Member", + "rerollTitle": "Reroll Group Roll", + "rerollContent": "Are you sure you want to reroll your {trait} roll?", + "rerollTooltip": "Reroll", + "wholePartySelected": "The whole party is selected" + }, "HUD": { "tokenHUD": { "genericEffects": "Foundry Effects", @@ -735,8 +732,7 @@ }, "GroupRollSelect": { "title": "Group Roll", - "leader": "Leader", - "leaderRoll": "Leader Roll", + "mainCharacter": "Main Character", "openDialogForAll": "Open Dialog For All", "startGroupRoll": "Start Group Roll", "cancelGroupRoll": "Cancel", @@ -2401,6 +2397,7 @@ }, "maxWithThing": "Max {thing}", "missingDragDropThing": "Drop {thing} here", + "modifier": "Modifier", "multiclass": "Multiclass", "newCategory": "New Category", "newThing": "New {thing}", diff --git a/module/applications/dialogs/groupRollDialog.mjs b/module/applications/dialogs/groupRollDialog.mjs index a488f315..b5169443 100644 --- a/module/applications/dialogs/groupRollDialog.mjs +++ b/module/applications/dialogs/groupRollDialog.mjs @@ -1,4 +1,3 @@ -import { ResourceUpdateMap } from '../../data/action/baseAction.mjs'; import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import Party from '../sheets/actors/party.mjs'; @@ -19,7 +18,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat owned: member.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) })); - this.leader = null; + this.mainCharacter = null; this.openForAllPlayers = true; this.tabGroups.application = Object.keys(party.system.groupRoll.participants).length @@ -30,7 +29,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat } get title() { - return game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRollSelect.title'); + return game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRoll.title'); } static DEFAULT_OPTIONS = { @@ -44,9 +43,9 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat makeRoll: this.#makeRoll, removeRoll: this.#removeRoll, rerollDice: this.#rerollDice, - makeLeaderRoll: this.#makeLeaderRoll, - removeLeaderRoll: this.#removeLeaderRoll, - rerollLeaderDice: this.#rerollLeaderDice, + makeMainCharacterRoll: this.#makeMainCharacterRoll, + removeMainCharacterRoll: this.#removeMainCharacterRoll, + rerollMainCharacterDice: this.#rerollMainCharacterDice, markSuccessfull: this.#markSuccessfull, cancelRoll: this.#onCancelRoll, finishRoll: this.#finishRoll @@ -59,9 +58,9 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat id: 'initialization', template: 'systems/daggerheart/templates/dialogs/groupRollDialog/initialization.hbs' }, - leader: { - id: 'leader', - template: 'systems/daggerheart/templates/dialogs/groupRollDialog/leader.hbs' + mainCharacter: { + id: 'mainCharacter', + template: 'systems/daggerheart/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs' }, groupRoll: { id: 'groupRoll', @@ -85,11 +84,11 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat htmlElement .querySelector('.main-character-field') - ?.addEventListener('input', this.updateLeaderField.bind(this)); + ?.addEventListener('input', this.updateMainCharacterField.bind(this)); } _configureRenderParts(options) { - const { initialization, leader, groupRoll, footer } = super._configureRenderParts(options); + const { initialization, mainCharacter, groupRoll, footer } = super._configureRenderParts(options); const augmentedParts = { initialization }; for (const memberKey of Object.keys(this.party.system.groupRoll.aidingCharacters)) { augmentedParts[memberKey] = { @@ -98,7 +97,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat }; } - augmentedParts.leader = leader; + augmentedParts.mainCharacter = mainCharacter; augmentedParts.groupRoll = groupRoll; augmentedParts.footer = footer; @@ -110,19 +109,15 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat await super._onRender(context, options); if (this.element.querySelector('.team-container')) return; - - if (this.tabGroups.application !== this.constructor.PARTS.initialization.id) { - const initializationPart = this.element.querySelector('.initialization-container'); - initializationPart.insertAdjacentHTML('afterend', '
'); - initializationPart.insertAdjacentHTML( - 'afterend', - `
${game.i18n.localize('Aiding Characters')}
` - ); - - const teamContainer = this.element.querySelector('.team-container'); - for (const memberContainer of this.element.querySelectorAll('.team-member-container')) - teamContainer.appendChild(memberContainer); - } + const initializationPart = this.element.querySelector('.initialization-container'); + initializationPart.insertAdjacentHTML('afterend', '
'); + initializationPart.insertAdjacentHTML( + 'afterend', + `
${game.i18n.localize('Aiding Characters')}
` + ); + const teamContainer = this.element.querySelector('.team-container'); + for (const memberContainer of this.element.querySelectorAll('.team-member-container')) + teamContainer.appendChild(memberContainer); } async _prepareContext(_options) { @@ -153,25 +148,19 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat const selectedMembers = partContext.memberSelection.filter(x => x.selected); - partContext.selectedLeader = this.leader; - partContext.selectedLeaderOptions = selectedMembers + partContext.selectedMainCharacter = this.mainCharacter; + partContext.selectedMainCharacterOptions = selectedMembers .filter(actor => actor.owned) .map(x => ({ value: x.id, label: x.name })); - partContext.selectedLeaderDisabled = !selectedMembers.length; + partContext.selectedMainCharacterDisabled = !selectedMembers.length; - partContext.canStartGroupRoll = selectedMembers.length > 1 && this.leader?.memberId; + partContext.canStartGroupRoll = selectedMembers.length > 1; partContext.openForAllPlayers = this.openForAllPlayers; break; - case 'leader': - partContext.leader = this.getRollCharacterData(this.party.system.groupRoll.leader); + case 'mainCharacter': + partContext.mainCharacter = this.getRollCharacterData(this.party.system.groupRoll.mainCharacter); break; case 'groupRoll': - const leader = this.party.system.groupRoll.leader; - partContext.hasRolled = - leader?.rollData || - Object.values(this.party.system.groupRoll?.aidingCharacters ?? {}).some( - x => x.successfull !== null - ); const { modifierTotal, modifiers } = Object.values(this.party.system.groupRoll.aidingCharacters).reduce( (acc, curr) => { const modifier = curr.successfull === true ? 1 : curr.successfull === false ? -1 : null; @@ -184,22 +173,23 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat }, { modifierTotal: 0, modifiers: [] } ); - const leaderTotal = leader?.rollData ? leader.roll.total : null; + const mainCharacterTotal = this.party.system.groupRoll.mainCharacter?.rollData + ? this.party.system.groupRoll.mainCharacter.roll.total + : null; partContext.groupRoll = { - totalLabel: leader?.rollData + totalLabel: this.party.system.groupRoll.mainCharacter?.rollData ? game.i18n.format('DAGGERHEART.GENERAL.withThing', { - thing: leader.roll.totalLabel + thing: this.party.system.groupRoll.mainCharacter.roll.totalLabel }) : null, - totalDualityClass: leader?.roll?.isCritical ? 'critical' : leader?.roll?.withHope ? 'hope' : 'fear', - total: leaderTotal + modifierTotal, - leaderTotal: leaderTotal, + total: mainCharacterTotal + modifierTotal, + mainCharacterTotal, modifiers }; break; case 'footer': partContext.canFinishRoll = - Boolean(this.party.system.groupRoll.leader?.rollData) && + Boolean(this.party.system.groupRoll.mainCharacter?.rollData) && Object.values(this.party.system.groupRoll.aidingCharacters).every(x => x.successfull !== null); break; } @@ -256,15 +246,15 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat } getUpdatingParts(target) { - const { initialization, leader, groupRoll, footer } = this.constructor.PARTS; + const { initialization, mainCharacter, groupRoll, footer } = this.constructor.PARTS; const isInitialization = this.tabGroups.application === initialization.id; const updatingMember = target.closest('.team-member-container')?.dataset?.memberKey; - const updatingLeader = target.closest('.main-character-outer-container'); + const updatingMainCharacter = target.closest('.main-character-outer-container'); return [ ...(isInitialization ? [initialization.id] : []), ...(updatingMember ? [updatingMember] : []), - ...(updatingLeader ? [leader.id] : []), + ...(updatingMainCharacter ? [mainCharacter.id] : []), ...(!isInitialization ? [groupRoll.id, footer.id] : []) ]; } @@ -307,16 +297,16 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat this.render(); } - updateLeaderField(event) { - if (!this.leader) this.leader = {}; - this.leader.memberId = event.target.value; + updateMainCharacterField(event) { + if (!this.mainCharacter) this.mainCharacter = {}; + this.mainCharacter.memberId = event.target.value; this.render(); } static async #startGroupRoll() { - const leader = this.partyMembers.find(x => x.id === this.leader.memberId); + const mainCharacter = this.partyMembers.find(x => x.id === this.mainCharacter.memberId); const aidingCharacters = this.partyMembers.reduce((acc, curr) => { - if (curr.selected && curr.id !== this.leader.memberId) + if (curr.selected && curr.id !== this.mainCharacter.memberId) acc[curr.id] = { id: curr.id, name: curr.name, img: curr.img }; return acc; @@ -326,7 +316,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat 'system.groupRoll': _replace( new game.system.api.data.GroupRollData({ ...this.party.system.groupRoll.toObject(), - leader: { id: leader.id, name: leader.name, img: leader.img }, + mainCharacter: { id: mainCharacter.id, name: mainCharacter.name, img: mainCharacter.img }, aidingCharacters }) ) @@ -343,10 +333,13 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat } //#endregion - async makeRoll(button, characterData, path) { - const actor = game.actors.find(x => x.id === characterData.id); + static async #makeRoll(_event, button) { + const { member } = button.dataset; + + const actor = game.actors.find(x => x.id === member); if (!actor) return; + const characterData = this.party.system.groupRoll.aidingCharacters[member]; const result = await actor.rollTrait(characterData.rollChoice, { skips: { createMessage: true, @@ -361,43 +354,36 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat delete rollData.options.messageRoll; this.updatePartyData( { - [path]: rollData + [`system.groupRoll.aidingCharacters.${member}.rollData`]: rollData }, this.getUpdatingParts(button) ); } - static async #makeRoll(_event, button) { - const { member } = button.dataset; - const character = this.party.system.groupRoll.aidingCharacters[member]; - this.makeRoll(button, character, `system.groupRoll.aidingCharacters.${member}.rollData`); - } - - static async #makeLeaderRoll(_event, button) { - const character = this.party.system.groupRoll.leader; - this.makeRoll(button, character, 'system.groupRoll.leader.rollData'); - } - - async removeRoll(button, path) { + static async #removeRoll(_, button) { this.updatePartyData( { - [path]: { + [`system.groupRoll.aidingCharacters.${button.dataset.member}`]: { rollData: null, rollChoice: null, - selected: false, - successfull: null + selected: false } }, this.getUpdatingParts(button) ); } - static async #removeRoll(_event, button) { - this.removeRoll(button, `system.groupRoll.aidingCharacters.${button.dataset.member}`); + static async #rerollDice(_, button) { + const { member } = button.dataset; + this.rerollDice( + button, + this.party.system.groupRoll.aidingCharacters[member], + `system.groupRoll.aidingCharacters.${member}.rollData` + ); } - static async #removeLeaderRoll(_event, button) { - this.removeRoll(button, 'system.groupRoll.leader'); + static async #rerollMainCharacterDice(_, button) { + this.rerollDice(button, this.party.system.groupRoll.mainCharacter, `system.groupRoll.mainCharacter.rollData`); } async rerollDice(button, data, path) { @@ -421,17 +407,42 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat ); } - static async #rerollDice(_, button) { - const { member } = button.dataset; - this.rerollDice( - button, - this.party.system.groupRoll.aidingCharacters[member], - `system.groupRoll.aidingCharacters.${member}.rollData` + static async #makeMainCharacterRoll(_event, button) { + const actor = game.actors.find(x => x.id === this.party.system.groupRoll.mainCharacter.id); + if (!actor) return; + + const characterData = this.party.system.groupRoll.mainCharacter; + const result = await actor.rollTrait(characterData.rollChoice, { + skips: { + createMessage: true, + resources: true, + triggers: true + } + }); + + if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice }); + + const rollData = result.messageRoll.toJSON(); + delete rollData.options.messageRoll; + this.updatePartyData( + { + [`system.groupRoll.mainCharacter.rollData`]: rollData + }, + this.getUpdatingParts(button) ); } - static async #rerollLeaderDice(_, button) { - this.rerollDice(button, this.party.system.groupRoll.leader, `system.groupRoll.leader.rollData`); + static async #removeMainCharacterRoll(_event, button) { + this.updatePartyData( + { + [`system.groupRoll.mainCharacter`]: { + rollData: null, + rollChoice: null, + selected: false + } + }, + this.getUpdatingParts(button) + ); } static #markSuccessfull(_event, button) { @@ -465,7 +476,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat await this.updatePartyData( { 'system.groupRoll': { - leader: null, + mainCharacter: null, aidingCharacters: _replace({}) } }, @@ -481,7 +492,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat } static async #finishRoll() { - const totalRoll = this.party.system.groupRoll.leader.roll; + const totalRoll = this.party.system.groupRoll.mainCharacter.roll; for (const character of Object.values(this.party.system.groupRoll.aidingCharacters)) { totalRoll.terms.push(new foundry.dice.terms.OperatorTerm({ operator: character.successfull ? '+' : '-' })); totalRoll.terms.push(new foundry.dice.terms.NumericTerm({ number: 1 })); @@ -490,13 +501,13 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat await totalRoll._evaluate(); const systemData = totalRoll.options; - const actor = game.actors.get(this.party.system.groupRoll.leader.id); + const actor = game.actors.get(this.party.system.groupRoll.mainCharacter.id); const cls = getDocumentClass('ChatMessage'), msgData = { type: 'dualityRoll', user: game.user.id, - title: game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRollSelect.title'), + title: game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title'), speaker: cls.getSpeaker({ actor }), system: systemData, rolls: [JSON.stringify(totalRoll)], @@ -506,20 +517,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat await cls.create(msgData); - const resourceMap = new ResourceUpdateMap(actor); - if (totalRoll.isCritical) { - resourceMap.addResources([ - { key: 'stress', value: -1, total: 1 }, - { key: 'hope', value: 1, total: 1 } - ]); - } else if (totalRoll.withHope) { - resourceMap.addResources([{ key: 'hope', value: 1, total: 1 }]); - } else { - resourceMap.addResources([{ key: 'fear', value: 1, total: 1 }]); - } - - resourceMap.updateResources(); - /* Fin */ this.cancelRoll({ confirm: false }); } diff --git a/module/applications/sheets/actors/party.mjs b/module/applications/sheets/actors/party.mjs index d4545f63..cd747474 100644 --- a/module/applications/sheets/actors/party.mjs +++ b/module/applications/sheets/actors/party.mjs @@ -1,5 +1,5 @@ import DHBaseActorSheet from '../api/base-actor.mjs'; -import { getDocFromElement, sortBy } from '../../../helpers/utils.mjs'; +import { getDocFromElement } from '../../../helpers/utils.mjs'; import { ItemBrowser } from '../../ui/itemBrowser.mjs'; import FilterMenu from '../../ux/filter-menu.mjs'; import DaggerheartMenu from '../../sidebar/tabs/daggerheartMenu.mjs'; @@ -17,14 +17,13 @@ export default class Party extends DHBaseActorSheet { static DEFAULT_OPTIONS = { classes: ['party'], position: { - width: 600, + width: 550, height: 900 }, window: { resizable: true }, actions: { - openDocument: Party.#openDocument, deletePartyMember: Party.#deletePartyMember, deleteItem: Party.#deleteItem, toggleHope: Party.#toggleHope, @@ -45,6 +44,10 @@ export default class Party extends DHBaseActorSheet { header: { template: 'systems/daggerheart/templates/sheets/actors/party/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, partyMembers: { template: 'systems/daggerheart/templates/sheets/actors/party/party-members.hbs' }, + resources: { + template: 'systems/daggerheart/templates/sheets/actors/party/resources.hbs', + scrollable: [''] + }, /* NOT YET IMPLEMENTED */ // projects: { // template: 'systems/daggerheart/templates/sheets/actors/party/projects.hbs', @@ -62,6 +65,7 @@ export default class Party extends DHBaseActorSheet { primary: { tabs: [ { id: 'partyMembers' }, + { id: 'resources' }, /* NOT YET IMPLEMENTED */ // { id: 'projects' }, { id: 'inventory' }, @@ -91,8 +95,6 @@ export default class Party extends DHBaseActorSheet { case 'header': await this._prepareHeaderContext(context, options); break; - case 'partyMembers': - await this._prepareMembersContext(context, options); case 'notes': await this._prepareNotesContext(context, options); break; @@ -116,60 +118,6 @@ export default class Party extends DHBaseActorSheet { relativeTo: this.document }); context.tagTeamActive = Boolean(this.document.system.tagTeam.initiator); - context.groupRollActive = Boolean(this.document.system.groupRoll.leader); - } - - async _prepareMembersContext(context, _options) { - context.partyMembers = []; - const traits = ['agility', 'strength', 'finesse', 'instinct', 'presence', 'knowledge']; - for (const actor of this.document.system.partyMembers) { - const weapons = []; - if (actor.type === 'character') { - if (actor.system.usedUnarmed) { - weapons.push(actor.system.usedUnarmed); - } - const equipped = actor.items.filter(i => i.system.equipped && i.type === 'weapon'); - weapons.push(...sortBy(equipped, i => (i.system.secondary ? 1 : 0))); - } - - context.partyMembers.push({ - uuid: actor.uuid, - img: actor.img, - name: actor.name, - subtitle: (() => { - if (!['character', 'companion'].includes(actor.type)) { - return game.i18n.format(`TYPES.Actor.${actor.type}`); - } - - const { value: classItem, subclass } = actor.system.class ?? {}; - const partner = actor.system.partner; - const ancestry = actor.system.ancestry; - const community = actor.system.community; - if (partner || (classItem && subclass && ancestry && community)) { - return game.i18n.format(`DAGGERHEART.ACTORS.Party.Subtitle.${actor.type}`, { - class: classItem?.name, - subclass: subclass?.name, - partner: partner?.name, - ancestry: ancestry?.name, - community: community?.name - }); - } - })(), - type: actor.type, - resources: actor.system.resources, - armorScore: actor.system.armorScore, - damageThresholds: actor.system.damageThresholds, - evasion: actor.system.evasion, - difficulty: actor.system.difficulty, - traits: actor.system.traits - ? traits.map(t => ({ - label: game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${t}.short`), - value: actor.system.traits[t].value - })) - : null, - weapons - }); - } } /** @@ -200,12 +148,6 @@ export default class Party extends DHBaseActorSheet { } } - static async #openDocument(_, target) { - const uuid = target.dataset.uuid; - const document = await foundry.utils.fromUuid(uuid); - document?.sheet?.render(true); - } - /** * Toggles a hope resource value. * @type {ApplicationClickAction} @@ -247,7 +189,7 @@ export default class Party extends DHBaseActorSheet { * @type {ApplicationClickAction} */ static async #toggleArmorSlot(_, target) { - const actor = await foundry.utils.fromUuid(target.dataset.actorId); + const actor = game.actors.get(target.dataset.actorId); const { value, max } = actor.system.armorScore; const inputValue = Number.parseInt(target.dataset.value); const newValue = value >= inputValue ? inputValue - 1 : inputValue; @@ -480,23 +422,25 @@ export default class Party extends DHBaseActorSheet { } static async #deletePartyMember(event, target) { - const doc = await foundry.utils.fromUuid(target.closest('[data-uuid]')?.dataset.uuid); + const doc = await getDocFromElement(target.closest('.inventory-item')); + if (!event.shiftKey) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { - title: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.title', { + title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', { + type: game.i18n.localize('TYPES.Actor.adversary'), name: doc.name }) }, - content: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.text', { name: doc.name }) + content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: doc.name }) }); if (!confirmed) return; } const currentMembers = this.document.system.partyMembers.map(x => x.uuid); - const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid); - await this.document.update({ 'system.partyMembers': newMembersList }); + const newMemberdList = currentMembers.filter(uuid => uuid !== doc.uuid); + await this.document.update({ 'system.partyMembers': newMemberdList }); } static async #deleteItem(event, target) { diff --git a/module/data/groupRollData.mjs b/module/data/groupRollData.mjs index 78a06b13..5047c4e2 100644 --- a/module/data/groupRollData.mjs +++ b/module/data/groupRollData.mjs @@ -3,14 +3,14 @@ export default class GroupRollData extends foundry.abstract.DataModel { const fields = foundry.data.fields; return { - leader: new fields.EmbeddedDataField(CharacterData, { nullable: true, initial: null }), + mainCharacter: new fields.EmbeddedDataField(CharacterData, { nullable: true, initial: null }), aidingCharacters: new fields.TypedObjectField(new fields.EmbeddedDataField(CharacterData)) }; } get participants() { return { - ...(this.leader ? { [this.leader.id]: this.leader } : {}), + ...(this.mainCharacter ? { [this.mainCharacter.id]: this.mainCharacter } : {}), ...this.aidingCharacters }; } diff --git a/styles/less/dialog/group-roll-dialog/initialization.less b/styles/less/dialog/group-roll-dialog/initialization.less index 96990339..211495ee 100644 --- a/styles/less/dialog/group-roll-dialog/initialization.less +++ b/styles/less/dialog/group-roll-dialog/initialization.less @@ -1,11 +1,3 @@ -.theme-light .daggerheart.dialog.dh-style.views.group-roll-dialog { - .initialization-container .members-container .member-container { - .member-name { - background-image: url('../assets/parchments/dh-parchment-light.png'); - } - } -} - .daggerheart.dialog.dh-style.views.group-roll-dialog { .initialization-container { h2 { @@ -28,17 +20,6 @@ .member-name { position: absolute; - padding: 0 2px; - border: 1px solid; - border-radius: 6px; - margin-top: 4px; - color: light-dark(@dark, @beige); - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - - img { - border-radius: 6px; - border: 1px solid light-dark(@dark-blue, @golden); } } } diff --git a/styles/less/dialog/group-roll-dialog/leader.less b/styles/less/dialog/group-roll-dialog/mainCharacter.less similarity index 100% rename from styles/less/dialog/group-roll-dialog/leader.less rename to styles/less/dialog/group-roll-dialog/mainCharacter.less diff --git a/styles/less/dialog/group-roll-dialog/sheet.less b/styles/less/dialog/group-roll-dialog/sheet.less index 823f6cbf..571d0d38 100644 --- a/styles/less/dialog/group-roll-dialog/sheet.less +++ b/styles/less/dialog/group-roll-dialog/sheet.less @@ -12,11 +12,6 @@ gap: 8px; flex: 1; - &.inactive { - opacity: 0.3; - pointer-events: none; - } - .data-container { display: flex; flex-direction: column; @@ -64,27 +59,9 @@ align-items: center; gap: 8px; - &.hope, - &.fear, - &.critical { - color: var(--text-color); - } - - &.hope { - --text-color: @golden; - } - - &.fear { - --text-color: @chat-blue; - } - - &.critical { - --text-color: @chat-purple; - } - &::before, &::after { - color: var(--text-color); + color: light-dark(@dark-blue, @golden); content: ''; flex: 1; height: 2px; diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less index 947142ff..fa59d0f5 100644 --- a/styles/less/dialog/index.less +++ b/styles/less/dialog/index.less @@ -37,7 +37,7 @@ @import './tag-team-dialog/sheet.less'; @import './group-roll-dialog/initialization.less'; -@import './group-roll-dialog/leader.less'; +@import './group-roll-dialog/mainCharacter.less'; @import './group-roll-dialog/sheet.less'; @import './image-select/sheet.less'; diff --git a/styles/less/dialog/tag-team-dialog/initialization.less b/styles/less/dialog/tag-team-dialog/initialization.less index 0d16aa3b..30676f82 100644 --- a/styles/less/dialog/tag-team-dialog/initialization.less +++ b/styles/less/dialog/tag-team-dialog/initialization.less @@ -20,17 +20,6 @@ .member-name { position: absolute; - padding: 0 2px; - border: 1px solid; - border-radius: 6px; - margin-top: 4px; - color: light-dark(@dark, @beige); - background-image: url('../assets/parchments/dh-parchment-dark.png'); - } - - img { - border-radius: 6px; - border: 1px solid light-dark(@dark-blue, @golden); } } } diff --git a/styles/less/sheets/actors/party/party-members.less b/styles/less/sheets/actors/party/party-members.less index 155fcc36..a433ae34 100644 --- a/styles/less/sheets/actors/party/party-members.less +++ b/styles/less/sheets/actors/party/party-members.less @@ -1,293 +1,28 @@ @import '../../../utils/colors.less'; @import '../../../utils/fonts.less'; -@import '../../../utils/mixin.less'; -body.game:is(.performance-low, .noblur) { - .application.sheet.daggerheart.actor.dh-style.party .tab.resources .actors-list .actor-resources { - background: light-dark(@dark-blue, @dark-golden); +.application.sheet.daggerheart.actor.dh-style.party { + .tab.partyMembers { + max-height: 400px; + overflow: auto; - .actor-name { - background: light-dark(@dark-blue, @dark-golden); + .actors-list { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + width: 100%; + } + .actors-dragger { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + border: 1px dashed light-dark(@dark-blue-50, @beige-50); + border-radius: 3px; + color: light-dark(@dark-blue-50, @beige-50); } } } - -.application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers { - overflow: auto; - - .actors-list { - display: flex; - flex-direction: column; - gap: 8px; - align-items: stretch; - width: 100%; - - .actor-resources { - display: grid; - grid-template: - "img header" min-content - "img body" 1fr - / 7.5rem 1fr; - gap: 6px; - column-gap: 12px; - padding: 6px; - background-color: light-dark(@dark-blue-10, @golden-10); - - .actor-img-frame { - grid-area: img; - width: 7.5rem; - height: 7.5rem; - position: relative; - - .actor-img { - object-fit: cover; - object-position: top center; - border-radius: 6px; - width: 100%; - height: 100%; - } - - .equipped-weapons { - position: absolute; - top: -2px; - left: -3px; - display: flex; - flex-direction: column; - gap: 1px; - img { - border-radius: 50%; - width: 24px; - height: 24px; - border: 1px solid light-dark(@dark-blue, @golden); - object-fit: cover; - } - } - - .evasion { - position: absolute; - top: 1px; - right: 1px; - width: 1.75rem; - height: 1.75rem; - background: url('../assets/svg/trait-shield.svg') no-repeat; - background-size: 100%; - font-size: var(--font-size-14); - font-weight: 700; - display: flex; - align-items: center; - justify-content: center; - } - - .threshold-section { - position: absolute; - left: 0; - right: 0; - bottom: -2px; - margin: auto; - - display: flex; - gap: 4px; - background-color: light-dark(transparent, @dark-blue); - color: light-dark(@dark-blue, @golden); - padding: 4px 6px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 3px; - align-items: baseline; - width: fit-content; - - h4 { - font-weight: bold; - text-transform: uppercase; - white-space: nowrap; - - &.threshold-label { - font-size: var(--font-size-10); - color: light-dark(@dark-blue, @golden); - } - - &.threshold-value { - font-size: var(--font-size-11); - color: light-dark(@dark, @beige); - } - } - } - } - - header { - grid-area: header; - display: grid; - grid-template: - "name hope" min-content - "subtitle subtitle" min-content - / 1fr min-content; - - .actor-name { - width: 100%; - z-index: 1; - font-size: var(--font-size-20); - color: light-dark(@beige, @golden); - font-weight: bold; - } - - .delete-icon { - font-size: 0.75em; - } - - .subtitle { - grid-area: subtitle; - font-size: var(--font-size-14); - } - - .hope-section { - display: flex; - background-color: light-dark(transparent, @dark-blue); - color: light-dark(@dark-blue, @golden); - padding: 3px 6px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 3px; - align-items: center; - width: fit-content; - margin-left: auto; - - h4 { - font-size: var(--font-size-12); - font-weight: bold; - text-transform: uppercase; - color: light-dark(@dark-blue, @golden); - margin-right: 3px; - } - - .hope-value { - display: flex; - cursor: pointer; - font-size: var(--font-size-12); - margin-left: 1px; - } - } - } - - .body { - grid-area: body; - display: flex; - align-items: start; - justify-content: space-between; - } - - .resources { - display: flex; - flex-direction: column; - gap: 4px; - - .slot-section { - display: flex; - flex-direction: row; - align-items: stretch; - - .slot-label { - display: flex; - align-items: center; - color: light-dark(@beige, @dark-blue); - background: light-dark(@dark-blue, @golden); - padding: 0 4px; - width: fit-content; - font-weight: bold; - border-radius: 6px 0px 0px 6px; - font-size: var(--font-size-12); - white-space: nowrap; - - .label { - padding-right: 2px; - } - - .value { - font-variant-numeric: tabular-nums; - .current { - display: inline-block; - text-align: end; - width: 2ch; - } - .max { - display: inline-block; - text-align: start; - width: 2ch; - } - } - } - - .slot-bar { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 4px; - - background-color: light-dark(@dark-blue-10, @dark-blue); - color: light-dark(@dark-blue, @golden); - padding: 2px 5px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 0 6px 6px 0; - width: fit-content; - min-height: 22px; - - .armor-slot { - cursor: pointer; - transition: all 0.3s ease; - font-size: var(--font-size-12); - - .fa-shield-halved { - color: light-dark(@dark-blue-40, @golden-40); - } - } - - .slot { - width: 16px; - height: 10px; - border: 1px solid light-dark(@dark-blue, @golden); - background: light-dark(@dark-blue-10, @golden-10); - border-radius: 3px; - transition: all 0.3s ease; - cursor: pointer; - - &.filled { - background: light-dark(@dark-blue, @golden); - } - } - } - } - } - - .traits { - background-color: light-dark(@dark-blue-10, @dark-blue); - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - display: grid; - grid-template-columns: 1fr 1fr; - font-size: var(--font-size-12); - padding: 3px 4px; - gap: 3px 7px; - .trait { - display: flex; - justify-content: space-between; - gap: 3px; - .label { - color: light-dark(@dark-blue, @golden); - } - .value { - font-weight: 600; - } - } - } - } - } - - .actors-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 40px; - border: 1px dashed light-dark(@dark-blue-50, @beige-50); - border-radius: 3px; - color: light-dark(@dark-blue-50, @beige-50); - } -} diff --git a/styles/less/sheets/actors/party/resources.less b/styles/less/sheets/actors/party/resources.less new file mode 100644 index 00000000..68628295 --- /dev/null +++ b/styles/less/sheets/actors/party/resources.less @@ -0,0 +1,216 @@ +@import '../../../utils/colors.less'; +@import '../../../utils/fonts.less'; +@import '../../../utils/mixin.less'; + +body.game:is(.performance-low, .noblur) { + .application.sheet.daggerheart.actor.dh-style.party .tab.resources .actors-list .actor-resources { + background: light-dark(@dark-blue, @dark-golden); + + .actor-name { + background: light-dark(@dark-blue, @dark-golden); + } + } +} + +.application.sheet.daggerheart.actor.dh-style.party { + .tab.resources { + overflow: auto; + + .actors-list { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 10px; + align-items: center; + width: 100%; + justify-content: center; + + .actor-resources { + display: flex; + flex-direction: column; + position: relative; + background: light-dark(@dark-blue-40, @dark-golden-40); + border-radius: 6px; + border: 1px solid light-dark(@dark-blue, @golden); + width: 230px; + height: -webkit-fill-available; + + .actor-name { + position: absolute; + top: 0px; + background: light-dark(@dark-blue-90, @dark-golden-80); + backdrop-filter: blur(6.5px); + border-radius: 6px 6px 0px 0px; + text-align: center; + width: 100%; + z-index: 1; + font-size: var(--font-size-20); + color: light-dark(@beige, @golden); + font-weight: bold; + padding: 5px 0; + } + + .actor-img { + height: 150px; + object-fit: cover; + object-position: top center; + border-radius: 6px 6px 0px 0px; + mask-image: linear-gradient(180deg, black 88%, transparent 100%); + } + + .resources { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + margin: 10px; + + .slot-section { + display: flex; + flex-direction: column; + align-items: center; + + .slot-bar { + display: flex; + flex-wrap: wrap; + gap: 5px; + width: 239px; + + background-color: light-dark(@dark-blue-10, @dark-blue); + color: light-dark(@dark-blue, @golden); + padding: 5px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 6px; + width: fit-content; + + .armor-slot { + cursor: pointer; + transition: all 0.3s ease; + font-size: var(--font-size-12); + + .fa-shield-halved { + color: light-dark(@dark-blue-40, @golden-40); + } + } + + .slot { + width: 20px; + height: 10px; + border: 1px solid light-dark(@dark-blue, @golden); + background: light-dark(@dark-blue-10, @golden-10); + border-radius: 3px; + transition: all 0.3s ease; + cursor: pointer; + + &.filled { + background: light-dark(@dark-blue, @golden); + } + } + } + .slot-label { + display: flex; + align-items: center; + color: light-dark(@beige, @dark-blue); + background: light-dark(@dark-blue, @golden); + padding: 0 5px; + width: fit-content; + font-weight: bold; + border-radius: 0px 0px 5px 5px; + font-size: var(--font-size-12); + + .label { + padding-right: 5px; + } + + .value { + padding-left: 6px; + border-left: 1px solid light-dark(@beige, @dark-golden); + } + } + } + + .hope-section { + position: relative; + display: flex; + gap: 10px; + background-color: light-dark(transparent, @dark-blue); + color: light-dark(@dark-blue, @golden); + padding: 5px 10px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 3px; + align-items: center; + width: fit-content; + + h4 { + font-size: var(--font-size-12); + font-weight: bold; + text-transform: uppercase; + color: light-dark(@dark-blue, @golden); + } + + .hope-value { + display: flex; + cursor: pointer; + font-size: var(--font-size-12); + } + } + + .stat-section { + position: relative; + display: flex; + gap: 10px; + background-color: light-dark(transparent, @dark-blue); + color: light-dark(@dark-blue, @golden); + padding: 5px 10px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 3px; + align-items: center; + width: fit-content; + + h4 { + font-size: var(--font-size-12); + font-weight: bold; + text-transform: uppercase; + color: light-dark(@dark-blue, @golden); + } + } + + .threshold-section { + display: flex; + align-self: center; + gap: 10px; + background-color: light-dark(transparent, @dark-blue); + color: light-dark(@dark-blue, @golden); + padding: 5px 10px; + border: 1px solid light-dark(@dark-blue, @golden); + border-radius: 3px; + align-items: center; + width: fit-content; + + h4 { + font-size: var(--font-size-12); + font-weight: bold; + text-transform: uppercase; + color: light-dark(@dark-blue, @golden); + + &.threshold-value { + color: light-dark(@dark, @beige); + } + } + } + } + } + } + .actors-dragger { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + width: 100%; + height: 40px; + border: 1px dashed light-dark(@dark-blue-50, @beige-50); + border-radius: 3px; + color: light-dark(@dark-blue-50, @beige-50); + } + } +} diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 7d595614..e5ffbf3e 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -31,6 +31,7 @@ @import './actors/party/party-members.less'; @import './actors/party/sheet.less'; @import './actors/party/inventory.less'; +@import './actors/party/resources.less'; @import './items/beastform.less'; @import './items/class.less'; diff --git a/templates/dialogs/groupRollDialog/groupRoll.hbs b/templates/dialogs/groupRollDialog/groupRoll.hbs index edf1c980..24f317a2 100644 --- a/templates/dialogs/groupRollDialog/groupRoll.hbs +++ b/templates/dialogs/groupRollDialog/groupRoll.hbs @@ -1,19 +1,15 @@
- {{localize "DAGGERHEART.GENERAL.result.single"}} + {{localize "Result"}}
- {{#if hasRolled}}{{groupRoll.total}} {{groupRoll.totalLabel}}{{/if}} + {{groupRoll.total}} {{groupRoll.totalLabel}}
- {{#if groupRoll.leaderTotal includeZero=true}}{{groupRoll.leaderTotal}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leaderRoll"}}{{/if}} + {{#if groupRoll.mainCharacterTotal includeZero=true}}{{groupRoll.mainCharacterTotal}}{{else}}{{localize "
"}}{{/if}} {{#each groupRoll.modifiers as |modifier|}} {{#if (gte modifier 0)}}+{{else}}-{{/if}} {{positive modifier}} {{/each}} - {{#unless groupRoll.modifiers.length}} - + - {{localize "DAGGERHEART.GENERAL.Modifier.plural"}} - {{/unless}}
diff --git a/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs b/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs new file mode 100644 index 00000000..0a090acf --- /dev/null +++ b/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs @@ -0,0 +1,71 @@ +{{#with mainCharacter}} +
+
{{localize "Main Character"}}
+
+
+
+ +
+ {{name}} +
+
+
+ +
+
+
+
+
+
+ + {{#if readyToRoll}} +
+ + {{localize "DAGGERHEART.GENERAL.roll"}} +
+ + + + + {{#if hasRolled}} + + + + {{/if}} +
+
+ + {{#if roll}} +
+
{{roll.total}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}
+
+ + {{roll.dHope.total}} + + + + + + {{roll.dFear.total}} + + + {{#if roll.advantage.type}} + {{#if (eq roll.advantage.type 1)}}+{{else}}-{{/if}} + + {{roll.advantage.value}} + + + {{/if}} + {{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}} + {{positive roll.modifierTotal}} +
+
+ {{else}} + {{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.makeYourRoll"}} + {{/if}} +
+ {{/if}} +
+
+{{/with}} \ No newline at end of file diff --git a/templates/dialogs/groupRollDialog/groupRollMember.hbs b/templates/dialogs/groupRollDialog/groupRollMember.hbs index acf8e8f1..af1e7909 100644 --- a/templates/dialogs/groupRollDialog/groupRollMember.hbs +++ b/templates/dialogs/groupRollDialog/groupRollMember.hbs @@ -76,7 +76,7 @@ {{/if}}
- {{localize "DAGGERHEART.GENERAL.Modifier.single"}}{{#if successfull}} + 1{{else if (isNullish successfull)}} + ?{{else}} - 1{{/if}} + {{localize "DAGGERHEART.GENERAL.modifier"}}{{#if successfull}} + 1{{else if (isNullish successfull)}} + ?{{else}} - 1{{/if}}
{{/if}} diff --git a/templates/dialogs/groupRollDialog/initialization.hbs b/templates/dialogs/groupRollDialog/initialization.hbs index a520b8bd..06741363 100644 --- a/templates/dialogs/groupRollDialog/initialization.hbs +++ b/templates/dialogs/groupRollDialog/initialization.hbs @@ -11,12 +11,12 @@ {{/each}} -
+
- +
- + {{selectOptions selectedMainCharacterOptions selected=selectedMainCharacter.memberId blank="" }}
diff --git a/templates/dialogs/groupRollDialog/leader.hbs b/templates/dialogs/groupRollDialog/leader.hbs deleted file mode 100644 index 78fbcb42..00000000 --- a/templates/dialogs/groupRollDialog/leader.hbs +++ /dev/null @@ -1,73 +0,0 @@ -
- {{#with leader}} -
-
{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}
-
-
-
- -
- {{name}} -
-
-
- -
-
-
-
-
-
- - {{#if readyToRoll}} -
- - {{localize "DAGGERHEART.GENERAL.roll"}} -
- - - - - {{#if hasRolled}} - - - - {{/if}} -
-
- - {{#if roll}} -
-
{{roll.total}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}
-
- - {{roll.dHope.total}} - - - + - - {{roll.dFear.total}} - - - {{#if roll.advantage.type}} - {{#if (eq roll.advantage.type 1)}}+{{else}}-{{/if}} - - {{roll.advantage.value}} - - - {{/if}} - {{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}} - {{positive roll.modifierTotal}} -
-
- {{else}} - {{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.makeYourRoll"}} - {{/if}} -
- {{/if}} -
-
- {{/with}} -
\ No newline at end of file diff --git a/templates/sheets/actors/party/header.hbs b/templates/sheets/actors/party/header.hbs index 3fdb137d..f39f683f 100644 --- a/templates/sheets/actors/party/header.hbs +++ b/templates/sheets/actors/party/header.hbs @@ -3,6 +3,7 @@

+

Party

\ No newline at end of file diff --git a/templates/sheets/actors/party/party-members.hbs b/templates/sheets/actors/party/party-members.hbs index bc0c6672..b3dd53e6 100644 --- a/templates/sheets/actors/party/party-members.hbs +++ b/templates/sheets/actors/party/party-members.hbs @@ -9,160 +9,33 @@ Tag Team Roll - - - + {{!-- NOT YET IMPLEMENTED --}} + {{!-- --}}
- - {{#unless document.system.partyMembers.length}} -
- {{localize "DAGGERHEART.GENERAL.dropActorsHere"}} -
- {{/unless}} -
+
+ {{localize tabs.partyMembers.label}} + + {{#unless document.system.partyMembers.length}} +
+ {{localize "DAGGERHEART.GENERAL.dropActorsHere"}} +
+ {{/unless}} +
+ \ No newline at end of file diff --git a/templates/sheets/actors/party/resources.hbs b/templates/sheets/actors/party/resources.hbs new file mode 100644 index 00000000..b53282ca --- /dev/null +++ b/templates/sheets/actors/party/resources.hbs @@ -0,0 +1,110 @@ +
+
+ + +
+ +
+ {{localize tabs.resources.label}} + +
+
\ No newline at end of file