diff --git a/gulpfile.js b/gulpfile.js
index 1a81f5ae..45479a5c 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -3,7 +3,7 @@ var gulp = require('gulp');
var less = require('gulp-less');
gulp.task('less', function (cb) {
- gulp.src('styles/daggerheart.less').pipe(less()).on('error', console.error.bind(console)).pipe(gulp.dest('styles'));
+ gulp.src('styles/daggerheart.less').pipe(less()).pipe(gulp.dest('styles'));
cb();
});
diff --git a/lang/en.json b/lang/en.json
index b4b1410e..99a75f83 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -758,20 +758,15 @@
}
},
"GroupRollSelect": {
- "cancelConfirmText": "Are you sure you want to cancel the Group Roll? This will close it for all other players too.",
- "cancelConfirmTitle": "Cancel Group Roll",
- "initializationTitle": "Character Selection",
- "finishGroupRoll": "Finish Group Roll",
+ "title": "Group Roll",
+ "aidingCharacters": "Aiding Characters",
"leader": "Leader",
"leaderRoll": "Leader Roll",
- "members": "Members",
"openDialogForAll": "Open Dialog For All",
- "removeRoll": "Remove Roll",
- "resultsHint": "Results will appear when characters roll",
- "selectLeaderHint": "Select one Character to be the leader",
- "selectParticipantsHint": "Select one Character to be the leader",
"startGroupRoll": "Start Group Roll",
- "title": "Group Roll"
+ "finishGroupRoll": "Finish Group Roll",
+ "cancelConfirmTitle": "Cancel Group Roll",
+ "cancelConfirmText": "Are you sure you want to cancel the Group Roll? This will close it for all other players too."
},
"TokenConfig": {
"actorSizeUsed": "Actor size is set, determining the dimensions"
diff --git a/module/applications/dialogs/groupRollDialog.mjs b/module/applications/dialogs/groupRollDialog.mjs
index df03a061..a47dd0a8 100644
--- a/module/applications/dialogs/groupRollDialog.mjs
+++ b/module/applications/dialogs/groupRollDialog.mjs
@@ -37,17 +37,17 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
tag: 'form',
id: 'GroupRollDialog',
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll-dialog'],
- position: { width: 390, height: 'auto' },
- window: {
- icon: 'fa-solid fa-users'
- },
+ position: { width: 550, height: 'auto' },
actions: {
toggleSelectMember: this.#toggleSelectMember,
startGroupRoll: this.#startGroupRoll,
makeRoll: this.#makeRoll,
removeRoll: this.#removeRoll,
rerollDice: this.#rerollDice,
- markSuccessful: this.#markSuccessful,
+ makeLeaderRoll: this.#makeLeaderRoll,
+ removeLeaderRoll: this.#removeLeaderRoll,
+ rerollLeaderDice: this.#rerollLeaderDice,
+ markSuccessfull: this.#markSuccessfull,
cancelRoll: this.#onCancelRoll,
finishRoll: this.#finishRoll
},
@@ -59,21 +59,17 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
id: 'initialization',
template: 'systems/daggerheart/templates/dialogs/groupRollDialog/initialization.hbs'
},
- main: {
- id: 'main',
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/main.hbs'
- },
leader: {
id: 'leader',
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/parts/member.hbs'
+ template: 'systems/daggerheart/templates/dialogs/groupRollDialog/leader.hbs'
},
- result: {
- id: 'result',
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/parts/result.hbs'
+ groupRoll: {
+ id: 'groupRoll',
+ template: 'systems/daggerheart/templates/dialogs/groupRollDialog/groupRoll.hbs'
},
footer: {
id: 'footer',
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/parts/footer.hbs'
+ template: 'systems/daggerheart/templates/dialogs/groupRollDialog/footer.hbs'
}
};
@@ -93,14 +89,40 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
_configureRenderParts(options) {
- const parts = super._configureRenderParts(options);
+ const { initialization, leader, groupRoll, footer } = super._configureRenderParts(options);
+ const augmentedParts = { initialization };
for (const memberKey of Object.keys(this.party.system.groupRoll.aidingCharacters)) {
- parts[memberKey] = {
+ augmentedParts[memberKey] = {
id: memberKey,
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/parts/member.hbs'
+ template: 'systems/daggerheart/templates/dialogs/groupRollDialog/groupRollMember.hbs'
};
}
- return parts;
+
+ augmentedParts.leader = leader;
+ augmentedParts.groupRoll = groupRoll;
+ augmentedParts.footer = footer;
+
+ return augmentedParts;
+ }
+
+ /**@inheritdoc */
+ async _onRender(context, options) {
+ 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('DAGGERHEART.APPLICATIONS.GroupRollSelect.aidingCharacters')}
`
+ );
+
+ const teamContainer = this.element.querySelector('.team-container');
+ for (const memberContainer of this.element.querySelectorAll('.team-member-container'))
+ teamContainer.appendChild(memberContainer);
+ }
}
async _prepareContext(_options) {
@@ -112,7 +134,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
context.data = this.party.system.groupRoll;
context.traitOptions = CONFIG.DH.ACTOR.abilities;
context.members = {};
- context.aidKeys = Object.keys(this.party.system.groupRoll.aidingCharacters);
context.allHaveRolled = Object.keys(context.data.participants).every(key => {
const data = context.data.participants[key];
return Boolean(data.rollData);
@@ -124,7 +145,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
async _preparePartContext(partId, context, options) {
const partContext = await super._preparePartContext(partId, context, options);
partContext.partId = partId;
- partContext.leader = this.getRollCharacterData(this.party.system.groupRoll.leader);
switch (partId) {
case 'initialization':
@@ -142,14 +162,19 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
partContext.canStartGroupRoll = selectedMembers.length > 1 && this.leader?.memberId;
partContext.openForAllPlayers = this.openForAllPlayers;
break;
- case 'result':
+ case 'leader':
+ partContext.leader = this.getRollCharacterData(this.party.system.groupRoll.leader);
+ break;
+ case 'groupRoll':
const leader = this.party.system.groupRoll.leader;
partContext.hasRolled =
leader?.rollData ||
- Object.values(this.party.system.groupRoll?.aidingCharacters ?? {}).some(x => x.successful !== null);
+ 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.successful === true ? 1 : curr.successful === false ? -1 : null;
+ const modifier = curr.successfull === true ? 1 : curr.successfull === false ? -1 : null;
if (modifier) {
acc.modifierTotal += modifier;
acc.modifiers.push(modifier);
@@ -175,7 +200,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
case 'footer':
partContext.canFinishRoll =
Boolean(this.party.system.groupRoll.leader?.rollData) &&
- Object.values(this.party.system.groupRoll.aidingCharacters).every(x => x.successful !== null);
+ Object.values(this.party.system.groupRoll.aidingCharacters).every(x => x.successfull !== null);
break;
}
@@ -191,42 +216,20 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
if (!data) return {};
const actor = game.actors.get(data.id);
- const isLeader = data === this.party.system.groupRoll.leader;
-
- const roll = data.roll;
- const withTypeSuffix = !roll ? null : roll.isCritical ? 'criticalShort' : roll.withHope ? 'hope' : 'fear';
- const thing = withTypeSuffix ? _loc(`DAGGERHEART.GENERAL.${withTypeSuffix}`) : null;
return {
...data,
- type: isLeader ? 'leader' : 'aid',
- basePath: isLeader ? 'system.groupRoll.leader' : `system.groupRoll.aidingCharacters.${data.id}`,
- rollChoiceLabel: _loc(CONFIG.DH.ACTOR.abilities[data.rollChoice]?.label),
roll: data.roll,
- isEditable: actor?.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER),
+ isEditable: actor.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER),
key: partId,
readyToRoll: Boolean(data.rollChoice),
- hasRolled: Boolean(data.rollData),
- modifier: data.successful ? 1 : data.successful === false ? -1 : 0,
- withLabelShort: thing ? _loc('DAGGERHEART.GENERAL.withThing', { thing }) : null
+ hasRolled: Boolean(data.rollData)
};
}
- #getCharacterDataById(id) {
- if (!id) return null;
-
- const groupRoll = this.party.system.groupRoll;
- if (id === 'leader' || id === groupRoll.leader?.id) {
- return { data: groupRoll.leader, basePath: 'system.groupRoll.leader' };
- } else if (id in groupRoll.aidingCharacters) {
- return { data: groupRoll.aidingCharacters[id], basePath: `system.groupRoll.aidingCharacters.${id}` };
- }
-
- return null;
- }
-
static async updateData(event, _, formData) {
const partyData = foundry.utils.expandObject(formData.object);
+
this.updatePartyData(partyData, this.getUpdatingParts(event.target));
}
@@ -253,16 +256,16 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
getUpdatingParts(target) {
- const { initialization, leader, result, footer } = this.constructor.PARTS;
+ const { initialization, leader, groupRoll, footer } = this.constructor.PARTS;
const isInitialization = this.tabGroups.application === initialization.id;
- const updatingMember = target.closest('.member-roll-container.aid')?.dataset?.memberKey;
- const updatingLeader = target.closest('.member-roll-container.leader');
+ const updatingMember = target.closest('.team-member-container')?.dataset?.memberKey;
+ const updatingLeader = target.closest('.main-character-outer-container');
return [
...(isInitialization ? [initialization.id] : []),
...(updatingMember ? [updatingMember] : []),
...(updatingLeader ? [leader.id] : []),
- ...(!isInitialization ? [result.id, footer.id] : [])
+ ...(!isInitialization ? [groupRoll.id, footer.id] : [])
];
}
@@ -301,9 +304,6 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
static #toggleSelectMember(_, button) {
const member = this.partyMembers.find(x => x.id === button.dataset.id);
member.selected = !member.selected;
- if (this.leader?.memberId === member.id) {
- this.leader = null;
- }
this.render();
}
@@ -343,14 +343,11 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
//#endregion
- /** @this GroupRollDialog */
- static async #makeRoll(_event, button) {
- const member = button.closest('[data-member-key]').dataset.memberKey;
- const { data, basePath } = this.#getCharacterDataById(member);
- const actor = game.actors.find(x => x.id === data.id);
+ async makeRoll(button, characterData, path) {
+ const actor = game.actors.find(x => x.id === characterData.id);
if (!actor) return;
- const result = await actor.rollTrait(data.rollChoice, {
+ const result = await actor.rollTrait(characterData.rollChoice, {
skips: {
createMessage: true,
resources: true,
@@ -359,40 +356,53 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
});
if (!result) return;
- // todo: move logic to actor.rollTrait() or actor.diceRoll()
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(
{
- [basePath]: { rollData, successful: null }
+ [path]: rollData
},
this.getUpdatingParts(button)
);
}
- /** @this GroupRollDialog */
- static async #removeRoll(_event, button) {
- const member = button.closest('[data-member-key]').dataset.memberKey;
- const { basePath } = this.#getCharacterDataById(member);
+ 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) {
this.updatePartyData(
{
- [basePath]: {
+ [path]: {
rollData: null,
rollChoice: null,
selected: false,
- successful: null
+ successfull: null
}
},
this.getUpdatingParts(button)
);
}
- /** @this GroupRollDialog */
- static async #rerollDice(_, button) {
+ static async #removeRoll(_event, button) {
+ this.removeRoll(button, `system.groupRoll.aidingCharacters.${button.dataset.member}`);
+ }
+
+ static async #removeLeaderRoll(_event, button) {
+ this.removeRoll(button, 'system.groupRoll.leader');
+ }
+
+ async rerollDice(button, data, path) {
const { diceType } = button.dataset;
- const { data, basePath } = this.#getCharacterDataById(button.dataset.member);
const dieIndex = diceType === 'hope' ? 0 : diceType === 'fear' ? 1 : 2;
const newRoll = game.system.api.dice.DualityRoll.fromData(data.rollData);
@@ -406,19 +416,31 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
const rollData = newRoll.toJSON();
this.updatePartyData(
{
- [`${basePath}.rollData`]: rollData
+ [path]: rollData
},
this.getUpdatingParts(button)
);
}
- static #markSuccessful(_event, button) {
- const memberKey = button.closest('[data-member-key]').dataset.memberKey;
- const previousValue = this.party.system.groupRoll.aidingCharacters[memberKey].successful;
- const newValue = Boolean(button.dataset.success === 'true');
+ static async #rerollDice(_, button) {
+ const { member } = button.dataset;
+ this.rerollDice(
+ button,
+ this.party.system.groupRoll.aidingCharacters[member],
+ `system.groupRoll.aidingCharacters.${member}.rollData`
+ );
+ }
+
+ static async #rerollLeaderDice(_, button) {
+ this.rerollDice(button, this.party.system.groupRoll.leader, `system.groupRoll.leader.rollData`);
+ }
+
+ static #markSuccessfull(_event, button) {
+ const previousValue = this.party.system.groupRoll.aidingCharacters[button.dataset.member].successfull;
+ const newValue = Boolean(button.dataset.successfull === 'true');
this.updatePartyData(
{
- [`system.groupRoll.aidingCharacters.${memberKey}.successful`]:
+ [`system.groupRoll.aidingCharacters.${button.dataset.member}.successfull`]:
previousValue === newValue ? null : newValue
},
this.getUpdatingParts(button)
@@ -462,7 +484,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
static async #finishRoll() {
const totalRoll = this.party.system.groupRoll.leader.roll;
for (const character of Object.values(this.party.system.groupRoll.aidingCharacters)) {
- totalRoll.terms.push(new foundry.dice.terms.OperatorTerm({ operator: character.successful ? '+' : '-' }));
+ totalRoll.terms.push(new foundry.dice.terms.OperatorTerm({ operator: character.successfull ? '+' : '-' }));
totalRoll.terms.push(new foundry.dice.terms.NumericTerm({ number: 1 }));
}
diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs
index 513ad3f3..c59dd64e 100644
--- a/module/applications/sheets/actors/character.mjs
+++ b/module/applications/sheets/actors/character.mjs
@@ -3,7 +3,7 @@ import DhDeathMove from '../../dialogs/deathMove.mjs';
import { CharacterLevelup, LevelupViewMode } from '../../levelup/_module.mjs';
import DhCharacterCreation from '../../characterCreation/characterCreation.mjs';
import FilterMenu from '../../ux/filter-menu.mjs';
-import { getArmorSources, getDocFromElement, getDocFromElementSync, sortBy } from '../../../helpers/utils.mjs';
+import { getArmorSources, getDocFromElement, getDocFromElementSync } from '../../../helpers/utils.mjs';
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
@@ -226,11 +226,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
context.resources.stress.emptyPips =
context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0;
- context.equippedItems = sortBy(
- this.document.items.filter(i => i.system.equipped),
- i => (i.type === 'weapon' ? (i.system.secondary ? 1 : 0) : 2)
- );
-
context.beastformActive = this.document.effects.find(x => x.type === 'beastform');
return context;
diff --git a/module/config/resourceConfig.mjs b/module/config/resourceConfig.mjs
index d33d7ab3..56ef6cd5 100644
--- a/module/config/resourceConfig.mjs
+++ b/module/config/resourceConfig.mjs
@@ -57,9 +57,15 @@ const companionBaseResources = Object.freeze({
stress: {
id: 'stress',
initial: 0,
- max: 3,
+ max: 0,
reverse: true,
label: 'DAGGERHEART.GENERAL.stress'
+ },
+ hope: {
+ id: 'hope',
+ initial: 0,
+ reverse: false,
+ label: 'DAGGERHEART.GENERAL.hope'
}
});
diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs
index d69e17ad..d30e090a 100644
--- a/module/data/actor/adversary.mjs
+++ b/module/data/actor/adversary.mjs
@@ -189,9 +189,6 @@ export default class DhpAdversary extends DhCreature {
prepareDerivedData() {
super.prepareDerivedData();
this.attack.roll.isStandardAttack = true;
-
- // Clamp resources (must be done last to ensure all updates occur)
- this.resources.clamp();
}
_getTags() {
diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs
index d42f2f64..6f60356e 100644
--- a/module/data/actor/character.mjs
+++ b/module/data/actor/character.mjs
@@ -778,8 +778,6 @@ export default class DhCharacter extends DhCreature {
prepareDerivedData() {
super.prepareDerivedData();
-
- this.resources.hope.max -= this.scars;
if (this.companion) {
for (let levelKey in this.companion.system.levelData.levelups) {
const level = this.companion.system.levelData.levelups[levelKey];
@@ -793,6 +791,7 @@ export default class DhCharacter extends DhCreature {
}
}
+ this.resources.hope.max -= this.scars;
this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait;
this.resources.armor = {
@@ -802,9 +801,6 @@ export default class DhCharacter extends DhCreature {
};
this.attack.damage.parts.hitPoints.value.custom.formula = `@prof${this.basicAttackDamageDice}${this.rules.attack.damage.bonus ? ` + ${this.rules.attack.damage.bonus}` : ''}`;
-
- // Clamp resources (must be done last to ensure all updates occur)
- this.resources.clamp();
}
getRollData() {
diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs
index 300bd698..538031fb 100644
--- a/module/data/actor/companion.mjs
+++ b/module/data/actor/companion.mjs
@@ -144,6 +144,9 @@ export default class DhCompanion extends DhCreature {
const level = this.levelData.levelups[levelKey];
for (let selection of level.selections) {
switch (selection.type) {
+ case 'hope':
+ this.resources.hope += selection.value;
+ break;
case 'vicious':
if (selection.data[0] === 'damage') {
this.attack.damage.parts.hitPoints.value.dice = adjustDice(
@@ -180,9 +183,6 @@ export default class DhCompanion extends DhCreature {
return acc;
}, this.partner.system.companionData.levelupChoices);
}
-
- // Clamp resources (must be done last to ensure all updates occur)
- this.resources.clamp();
}
async _preUpdate(changes, options, userId) {
diff --git a/module/data/actor/creature.mjs b/module/data/actor/creature.mjs
index 601068ad..88646301 100644
--- a/module/data/actor/creature.mjs
+++ b/module/data/actor/creature.mjs
@@ -60,4 +60,14 @@ export default class DhCreature extends BaseDataActor {
}
}
}
+
+ prepareDerivedData() {
+ const minLimitResource = resource => {
+ if (resource) resource.value = Math.min(resource.value, resource.max);
+ };
+
+ minLimitResource(this.resources.stress);
+ minLimitResource(this.resources.hitPoints);
+ minLimitResource(this.resources.hope);
+ }
}
diff --git a/module/data/fields/actorField.mjs b/module/data/fields/actorField.mjs
index a5f6f379..d6b58675 100644
--- a/module/data/fields/actorField.mjs
+++ b/module/data/fields/actorField.mjs
@@ -80,18 +80,6 @@ class ResourcesField extends fields.TypedObjectField {
value.isReversed = resources[key].reverse;
value.max = typeof resource.max === 'number' ? (value.max ?? resource.max) : null;
}
- Object.defineProperty(data, 'clamp', {
- value: function () {
- for (const key of Object.keys(this)) {
- const resource = this[key];
- if (typeof resource?.max === 'number') {
- resource.value = Math.clamp(resource.value, 0, resource.max);
- }
- }
- },
- enumerable: false
- });
-
return data;
}
diff --git a/module/data/groupRollData.mjs b/module/data/groupRollData.mjs
index 10123152..78a06b13 100644
--- a/module/data/groupRollData.mjs
+++ b/module/data/groupRollData.mjs
@@ -30,7 +30,7 @@ export class CharacterData extends foundry.abstract.DataModel {
}),
rollData: new fields.JSONField({ nullable: true, initial: null }),
selected: new fields.BooleanField({ initial: false }),
- successful: new fields.BooleanField({ nullable: true, initial: null })
+ successfull: new fields.BooleanField({ nullable: true, initial: null })
};
}
diff --git a/styles/less/dialog/group-roll-dialog/_common.less b/styles/less/dialog/group-roll-dialog/_common.less
deleted file mode 100644
index 41573718..00000000
--- a/styles/less/dialog/group-roll-dialog/_common.less
+++ /dev/null
@@ -1,46 +0,0 @@
-h1 {
- color: light-dark(@dark-blue, @golden);
- font-family: var(--dh-font-subtitle);
- font-size: var(--font-size-24);
- text-align: center;
- font-weight: 700;
-}
-
-header {
- --bar-color: light-dark(@dark-blue, @golden);
- color: light-dark(@dark, @beige);
- display: flex;
- justify-content: center;
- align-items: center;
-
- &:not(:first-child) {
- margin-top: var(--spacer-8);
- }
-
- span {
- padding: 0 10px;
- }
-
- &:before {
- content: ' ';
- flex: 1;
- height: 1px;
- background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, var(--bar-color) 100%);
- }
-
- &:after {
- content: ' ';
- flex: 1;
- height: 1px;
- background: linear-gradient(90deg, var(--bar-color) 0%, rgba(0, 0, 0, 0) 100%);
- }
-}
-
-img.portrait {
- border-radius: 50%;
- border: none;
- object-fit: cover;
- object-position: center top;
- width: 2.5rem;
- height: 2.5rem;
-}
diff --git a/styles/less/dialog/group-roll-dialog/index.less b/styles/less/dialog/group-roll-dialog/index.less
deleted file mode 100644
index 27925fa2..00000000
--- a/styles/less/dialog/group-roll-dialog/index.less
+++ /dev/null
@@ -1,8 +0,0 @@
-.daggerheart.dialog.dh-style.views.group-roll-dialog {
- .window-content {
- @import "./_common.less";
- }
-}
-
-@import "./initialization.less";
-@import "./main.less";
diff --git a/styles/less/dialog/group-roll-dialog/initialization.less b/styles/less/dialog/group-roll-dialog/initialization.less
index b32f4756..b2e7e021 100644
--- a/styles/less/dialog/group-roll-dialog/initialization.less
+++ b/styles/less/dialog/group-roll-dialog/initialization.less
@@ -1,59 +1,62 @@
+.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.active {
- display: flex;
- flex-direction: column;
- overflow: hidden;
+ .initialization-container {
+ h2 {
+ text-align: center;
+ }
+
+ .members-container {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ gap: 8px;
+
+ .member-container {
+ position: relative;
+ display: flex;
+ justify-content: center;
+
+ &.inactive {
+ opacity: 0.4;
+ }
+
+ .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');
+ text-align: center;
+ }
+
+ img {
+ border-radius: 6px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ }
+ }
+ }
.main-roll {
- display: flex;
- flex-direction: column;
- text-align: center;
- padding-bottom: 4px;
+ margin-top: 8px;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 8px;
&.inactive {
opacity: 0.4;
}
}
- .hint {
- color: var(--color-form-hint);
- line-height: 1;
- padding: var(--spacer-8) 0;
- font-family: var(--dh-font-body);
- font-size: var(--font-size-12);
- font-weight: 300;
- }
-
- .members-container {
- display: flex;
- flex-direction: column;
- gap: 8px;
- overflow-y: auto;
-
- .member-container {
- display: flex;
- position: relative;
- justify-content: center;
- height: unset;
- padding: 4px 8px;
- gap: var(--spacer-8);
- flex: 0 0 auto;
-
- &:not(.inactive) {
- background: @golden-bg;
- }
-
- .name {
- flex: 1;
- color: light-dark(@dark, @beige);
- font-weight: 500;
- text-align: left;
- }
- }
- }
-
footer {
- margin-top: 12px;
+ margin-top: 8px;
display: flex;
gap: 8px;
diff --git a/styles/less/dialog/group-roll-dialog/leader.less b/styles/less/dialog/group-roll-dialog/leader.less
new file mode 100644
index 00000000..b3fa3a3b
--- /dev/null
+++ b/styles/less/dialog/group-roll-dialog/leader.less
@@ -0,0 +1,35 @@
+.daggerheart.dialog.dh-style.views.group-roll-dialog {
+ .main-character-outer-container {
+ &.inactive {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
+ .main-character-container {
+ .character-info {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ height: 64px;
+
+ img {
+ height: 64px;
+ border-radius: 6px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ }
+
+ .character-data {
+ padding-left: 0.75rem;
+ flex: 1;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ text-align: left;
+ font-size: var(--font-size-18);
+ }
+ }
+ }
+ }
+}
diff --git a/styles/less/dialog/group-roll-dialog/main.less b/styles/less/dialog/group-roll-dialog/main.less
deleted file mode 100644
index f266dcc7..00000000
--- a/styles/less/dialog/group-roll-dialog/main.less
+++ /dev/null
@@ -1,273 +0,0 @@
-.daggerheart.dialog.dh-style.views.group-roll-dialog {
- .group-roll.active {
- display: flex;
- flex-direction: column;
- overflow: hidden;
-
- a.roll-button {
- &:hover {
- text-shadow: none;
- filter: drop-shadow(0 0 3px @golden-90);
- }
- }
-
- .aiding-members {
- display: flex;
- flex-direction: column;
- gap: 6px;
- overflow-y: auto;
- }
-
- .item-tags {
- gap: 6px;
- .tag.failure,
- .tag.success {
- font-weight: 600;
- justify-content: center;
- min-width: 3ch;
- }
-
- .tag.success {
- border-color: @green;
- background: @green-10;
- color: @green;
- }
-
- .tag.failure {
- border-color: @red;
- background: @red-10;
- color: @red;
- }
-
- .tag {
- padding-top: 0;
- padding-bottom: 0;
- line-height: 1.1875rem;
- }
- }
-
- .with-result {
- border-radius: 5px;
- background: var(--duality-bg);
- color: var(--color-light-2);
-
- &.hope {
- --duality-text-color: @golden;
- --duality-bg: url(../assets/parchments/dh-parchment-hope.png);
- }
-
- &.fear {
- --duality-text-color: @chat-blue;
- --duality-bg: url(../assets/parchments/dh-parchment-fear.png);
- }
-
- &.critical {
- --duality-text-color: @chat-purple;
- --duality-bg: url(../assets/parchments/dh-parchment-critical.png);
- }
-
- .duality-label {
- font-family: var(--dh-font-subtitle);
- color: var(--duality-text-color);
- font-weight: 700;
- }
- }
-
- .member-roll-container {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 8px;
- min-height: 3.375rem;
-
- &.inactive {
- pointer-events: none;
- }
-
- .name-area {
- display: flex;
- flex-direction: column;
- flex: 1;
- justify-content: center;
- .name {
- font-weight: 500;
- }
- .trait {
- display: flex;
- align-items: center;
- gap: 6px;
- select {
- --input-height: 2em;
- width: auto;
- }
- }
- .item-tags {
- align-items: stretch;
- }
- }
-
- .buttons {
- display: flex;
- flex-direction: row;
- button {
- --button-text-color: var(--color-text-primary);
- --button-size: 1.5em;
- padding: 0 var(--spacer-4);
- img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- }
- }
- }
-
- a.roll-button.initial-roll {
- width: 1.875rem;
- height: 1.875rem;
- margin-right: 2px; /** makes hover look a bit nicer */
- }
-
- .with-result {
- display: flex;
- justify-content: end;
- align-items: center;
- gap: 6px;
-
- .roll-data {
- display: flex;
- flex-direction: column;
- align-items: end;
- justify-content: center;
- padding: 0 4px;
- min-height: 3rem;
-
- .duality-label {
- font-size: var(--font-size-15);
-
- .unused-damage {
- text-decoration: line-through;
- }
-
- .with {
- font-size: var(--font-size-10);
- }
- }
-
- .roll-dice-container {
- display: flex;
- align-items: center;
- justify-content: center;
- flex-wrap: wrap;
- gap: 2px;
-
- .roll-dice {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
-
- .dice-label {
- position: absolute;
- color: white;
- font-size: 1rem;
- paint-order: stroke fill;
- -webkit-text-stroke: 2px black;
- }
-
- img {
- height: 1.3125rem;
- }
- }
-
- .roll-operator {
- font-size: var(--font-size-18);
- padding: 0 1px;
- }
-
- .roll-value {
- font-size: var(--font-size-16);
- padding: 0 1px;
- }
- }
- }
-
- .buttons {
- flex-direction: column;
- button {
- color: var(--medium-red);
- &[data-success=true] {
- color: var(--green);
- }
- &.active {
- text-shadow: 0 0 1px light-dark(@dark-80, @beige-80);
- }
- &.inactive {
- opacity: 0.35;
- }
- }
- }
- }
- }
- }
-
- .group-roll-results {
- display: flex;
- flex-direction: column;
- align-items: stretch;
- gap: 4px;
- font-size: var(--font-size-12);
- padding: 6px 12px;
- margin-top: 8px;
-
- &.empty {
- color: light-dark(@dark-blue-90, @beige-80);
- border-radius: 3px;
- justify-content: center;
- border: 1px dashed light-dark(@dark-blue-90, @beige-80);
- text-align: center;
- height: 3.25rem;
- font-family: @font-body;
- }
-
- .row {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
-
- .divider {
- height: 1px;
- background-image: linear-gradient(90deg, transparent 0%, var(--duality-text-color) 50%, transparent 100%);
- margin-block: var(--spacer-4);
- }
-
- .modifiers .item-tags {
- min-height: calc(2px + 1.1875rem);
- }
-
- .total {
- .label {
- font-size: var(--font-size-14);
- }
- .duality-label {
- display: flex;
- align-items: center;
- gap: var(--spacer-4);
- .value {
- font-size: 20px;
- }
- }
- }
- }
-
- .finish-container {
- margin-top: 16px;
- gap: 16px;
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
-
- .finish-button {
- grid-column: span 2;
- }
- }
-}
diff --git a/styles/less/dialog/group-roll-dialog/sheet.less b/styles/less/dialog/group-roll-dialog/sheet.less
new file mode 100644
index 00000000..70afc1fe
--- /dev/null
+++ b/styles/less/dialog/group-roll-dialog/sheet.less
@@ -0,0 +1,265 @@
+.daggerheart.dialog.dh-style.views.group-roll-dialog {
+ .team-container {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 16px;
+ margin-bottom: 16px;
+
+ .team-member-container {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 8px;
+ flex: 1;
+
+ &.inactive {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
+ .data-container {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ width: 100%;
+ }
+
+ .member-info {
+ display: flex;
+ align-items: start;
+ width: 100%;
+
+ img {
+ height: 64px;
+ border-radius: 6px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ }
+
+ .member-data {
+ padding-left: 0.75rem;
+ flex: 1;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ text-align: left;
+ font-size: var(--font-size-18);
+ }
+ }
+ }
+ }
+
+ .roll-container {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .roll-title {
+ font-size: var(--font-size-20);
+ font-weight: bold;
+ color: light-dark(@dark-blue, @golden);
+ text-align: center;
+ display: flex;
+ 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);
+ content: '';
+ flex: 1;
+ height: 2px;
+ }
+
+ &::before {
+ background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, light-dark(@dark-blue, @golden) 100%);
+ }
+
+ &::after {
+ background: linear-gradient(90deg, light-dark(@dark-blue, @golden) 0%, rgba(0, 0, 0, 0) 100%);
+ }
+ }
+
+ .roll-tools {
+ display: flex;
+ gap: 4px;
+ align-items: center;
+
+ img {
+ height: 16px;
+ }
+
+ a {
+ display: flex;
+ font-size: 16px;
+
+ &:hover {
+ text-shadow: none;
+ filter: drop-shadow(0 0 8px var(--golden));
+ }
+ }
+ }
+
+ .roll-data {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+
+ &.hope {
+ --text-color: @golden;
+ --bg-color: @golden-40;
+ }
+
+ &.fear {
+ --text-color: @chat-blue;
+ --bg-color: @chat-blue-40;
+ }
+
+ &.critical {
+ --text-color: @chat-purple;
+ --bg-color: @chat-purple-40;
+ }
+
+ .duality-label {
+ color: var(--text-color);
+ font-size: var(--font-size-20);
+ font-weight: bold;
+ text-align: center;
+
+ .unused-damage {
+ text-decoration: line-through;
+ }
+ }
+
+ .roll-dice-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+ gap: 8px;
+
+ .roll-dice {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .dice-label {
+ position: absolute;
+ color: white;
+ font-size: 1rem;
+ paint-order: stroke fill;
+ -webkit-text-stroke: 2px black;
+ }
+
+ img {
+ height: 32px;
+ }
+ }
+
+ .roll-operator {
+ font-size: var(--font-size-24);
+ }
+
+ .roll-value {
+ font-size: 18px;
+ }
+ }
+
+ .roll-total {
+ background: var(--bg-color);
+ color: var(--text-color);
+ border-radius: 4px;
+ padding: 3px;
+ }
+ }
+
+ .roll-success-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+
+ .roll-success-tools {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ color: light-dark(@dark-blue, @golden);
+
+ i {
+ font-size: 24px;
+ }
+ }
+
+ .roll-success-modifier {
+ display: flex;
+ align-items: center;
+ justify-content: right;
+ gap: 2px;
+ font-size: var(--font-size-20);
+ padding: 0px 4px;
+
+ &.success {
+ background: @green-10;
+ color: @green;
+ }
+
+ &.failure {
+ background: @red-10;
+ color: @red;
+ }
+ }
+ }
+
+ .section-title {
+ font-size: var(--font-size-18);
+ font-weight: bold;
+ }
+
+ .group-roll-results {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ font-size: var(--font-size-20);
+
+ .group-roll-container {
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ }
+ }
+
+ .finish-container {
+ margin-top: 16px;
+ gap: 16px;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+
+ .finish-button {
+ grid-column: span 2;
+ }
+ }
+
+ .hint {
+ text-align: center;
+ }
+}
diff --git a/styles/less/dialog/group-roll/group-roll.less b/styles/less/dialog/group-roll/group-roll.less
new file mode 100644
index 00000000..f2895d31
--- /dev/null
+++ b/styles/less/dialog/group-roll/group-roll.less
@@ -0,0 +1,50 @@
+@import '../../utils/colors.less';
+
+.application.daggerheart.group-roll {
+ fieldset.one-column {
+ min-width: 500px;
+ margin-bottom: 10px;
+ }
+ .actor-item {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+ width: 100%;
+
+ img {
+ height: 40px;
+ width: 40px;
+ border-radius: 50%;
+ object-fit: cover;
+ }
+
+ .actor-info {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ .actor-check-info {
+ display: flex;
+ gap: 10px;
+
+ .form-fields {
+ display: flex;
+ gap: 5px;
+ align-items: center;
+
+ input {
+ max-width: 40px;
+ text-align: center;
+ }
+ }
+ }
+ }
+
+ .controls {
+ margin-left: auto;
+ }
+ }
+ .tooltip-container {
+ width: 100%;
+ }
+}
diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less
index eb882eeb..947142ff 100644
--- a/styles/less/dialog/index.less
+++ b/styles/less/dialog/index.less
@@ -31,10 +31,14 @@
@import './reroll-dialog/sheet.less';
+@import './group-roll/group-roll.less';
+
@import './tag-team-dialog/initialization.less';
@import './tag-team-dialog/sheet.less';
-@import './group-roll-dialog/index.less';
+@import './group-roll-dialog/initialization.less';
+@import './group-roll-dialog/leader.less';
+@import './group-roll-dialog/sheet.less';
@import './image-select/sheet.less';
diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less
index afd56057..c5bca1da 100755
--- a/styles/less/global/elements.less
+++ b/styles/less/global/elements.less
@@ -100,7 +100,7 @@
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
- button:where(:not(.plain)) {
+ button {
background: light-dark(transparent, @golden);
border: 1px solid light-dark(@dark-blue, @dark-blue);
color: light-dark(@dark-blue, @dark-blue);
diff --git a/templates/dialogs/group-roll/group-roll.hbs b/templates/dialogs/group-roll/group-roll.hbs
new file mode 100644
index 00000000..9b23c0a5
--- /dev/null
+++ b/templates/dialogs/group-roll/group-roll.hbs
@@ -0,0 +1,84 @@
+
+
+
+
+ {{localize "DAGGERHEART.UI.Chat.groupRoll.leader"}}
+ {{#unless leader.actor}}
+
+
+ {{localize "DAGGERHEART.UI.Chat.groupRoll.selectLeader"}}
+
+ {{else}}
+
+
+
+
{{leader.actor.name}}
+
+
+ {{localize "DAGGERHEART.GENERAL.Trait.single"}}
+
+ {{selectOptions traitList selected=leader.trait labelAttr="label" valueAttr="id" localize=true }}
+
+
+ {{!-- Not used yet --}}
+ {{!--
+ {{localize "DAGGERHEART.GENERAL.difficulty"}}
+
+
--}}
+
+
+
+
+ {{/unless}}
+
+
+
+ {{localize "DAGGERHEART.UI.Chat.groupRoll.partyTeam"}}
+
+
+
+ {{#if (gt this.members.length 0)}}
+ {{#each members as |member index|}}
+
+
+
+
{{member.actor.name}}
+
+
+ {{localize "DAGGERHEART.GENERAL.Trait.single"}}
+
+ {{selectOptions @root.traitList selected=member.trait labelAttr="label" valueAttr="id" localize=true }}
+
+
+ {{!-- Not used yet --}}
+ {{!--
+ {{localize "DAGGERHEART.GENERAL.difficulty"}}
+
+
--}}
+
+
+
+
+ {{/each}}
+ {{/if}}
+ {{#unless allSelected}}
+
+ {{localize "DAGGERHEART.UI.Chat.groupRoll.selectMember"}}
+
+ {{/unless}}
+
+
+
+ {{localize "DAGGERHEART.GENERAL.roll"}}
+
+
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/parts/footer.hbs b/templates/dialogs/groupRollDialog/footer.hbs
similarity index 62%
rename from templates/dialogs/groupRollDialog/parts/footer.hbs
rename to templates/dialogs/groupRollDialog/footer.hbs
index 34b4efa1..e401966b 100644
--- a/templates/dialogs/groupRollDialog/parts/footer.hbs
+++ b/templates/dialogs/groupRollDialog/footer.hbs
@@ -1,9 +1,6 @@
{{localize "COMMON.Cancel"}}
-
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.finishGroupRoll"}}
-
+ {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.finishGroupRoll"}}
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/groupRoll.hbs b/templates/dialogs/groupRollDialog/groupRoll.hbs
new file mode 100644
index 00000000..edf1c980
--- /dev/null
+++ b/templates/dialogs/groupRollDialog/groupRoll.hbs
@@ -0,0 +1,20 @@
+
+
+ {{localize "DAGGERHEART.GENERAL.result.single"}}
+
+
+ {{#if hasRolled}}
{{groupRoll.total}} {{groupRoll.totalLabel}} {{/if}}
+
+ {{#if groupRoll.leaderTotal includeZero=true}}{{groupRoll.leaderTotal}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leaderRoll"}}{{/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}}
+
+
+
+
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/groupRollMember.hbs b/templates/dialogs/groupRollDialog/groupRollMember.hbs
new file mode 100644
index 00000000..acf8e8f1
--- /dev/null
+++ b/templates/dialogs/groupRollDialog/groupRollMember.hbs
@@ -0,0 +1,85 @@
+{{#with (lookup members partId)}}
+
+
+
+
+
+
+ {{#if readyToRoll}}
+
+
+ {{localize "DAGGERHEART.GENERAL.roll"}}
+
+
+
+ {{#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}}
+ {{#if hasRolled}}
+
+ {{#if ../isGM}}
+
+ {{/if}}
+
+ {{localize "DAGGERHEART.GENERAL.Modifier.single"}}{{#if successfull}} + 1{{else if (isNullish successfull)}} + ?{{else}} - 1{{/if}}
+
+
+ {{/if}}
+
+
+{{/with}}
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/initialization.hbs b/templates/dialogs/groupRollDialog/initialization.hbs
index a01a00bb..a520b8bd 100644
--- a/templates/dialogs/groupRollDialog/initialization.hbs
+++ b/templates/dialogs/groupRollDialog/initialization.hbs
@@ -1,43 +1,32 @@
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.initializationTitle"}}
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.selectLeaderHint"}}
-
- {{selectOptions selectedLeaderOptions selected=selectedLeader.memberId blank="" }}
-
-
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.members"}}
- {{"DAGGERHEART.APPLICATIONS.GroupRollSelect.selectParticipantsHint"}}
{{#each memberSelection as |member|}}
-
-
-
- {{member.name}}
- {{#if (eq @root.selectedLeader.memberId member.id)}}
-
- {{/if}}
-
-
-
+
{{member.name}}
+
+
{{/each}}
+
+
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/leader.hbs b/templates/dialogs/groupRollDialog/leader.hbs
new file mode 100644
index 00000000..3d5db3f7
--- /dev/null
+++ b/templates/dialogs/groupRollDialog/leader.hbs
@@ -0,0 +1,73 @@
+
+ {{#with leader}}
+
+
{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}
+
+
+
+
+
+
+
+
+ {{#if readyToRoll}}
+
+
+ {{localize "DAGGERHEART.GENERAL.roll"}}
+
+
+
+ {{#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/main.hbs b/templates/dialogs/groupRollDialog/main.hbs
deleted file mode 100644
index 6807a7e4..00000000
--- a/templates/dialogs/groupRollDialog/main.hbs
+++ /dev/null
@@ -1,15 +0,0 @@
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.title"}}
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.members"}}
-
- {{#each aidKeys as |key|}}
-
- {{/each}}
-
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}
-
- {{localize "DAGGERHEART.GENERAL.result.single"}}
-
-
-
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/parts/member.hbs b/templates/dialogs/groupRollDialog/parts/member.hbs
deleted file mode 100644
index ee857794..00000000
--- a/templates/dialogs/groupRollDialog/parts/member.hbs
+++ /dev/null
@@ -1,95 +0,0 @@
-{{#with (ifThen (eq partId "leader") leader (lookup members partId))}}
-
-
-
-
{{name}}
- {{#if hasRolled}}
-
- {{else if readyToRoll}}
-
- {{localize "DAGGERHEART.CONFIG.RollTypes.trait.name" }}
-
- {{selectOptions ../traitOptions selected=rollChoice localize=true}}
-
-
- {{/if}}
-
- {{#if roll}}
-
-
-
- {{roll.total}}
- {{withLabelShort}}
-
-
-
- {{roll.dHope.total}}
-
-
-
- {{roll.dFear.total}}
-
-
- {{#if roll.hasAdvantage}}
-
+
-
- {{roll.dAdvantage.total}}
-
-
- {{/if}}
- {{#if roll.hasDisadvantage}}
-
-
-
- {{roll.dDisadvantage.total}}
-
-
- {{/if}}
-
{{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}}
-
{{positive roll.modifierTotal}}
-
-
- {{#if (and @root.isGM (ne ../partId "leader"))}}
-
-
-
-
- {{/if}}
-
- {{else if (and readyToRoll isEditable)}}
-
-
-
- {{/if}}
-
-{{/with}}
\ No newline at end of file
diff --git a/templates/dialogs/groupRollDialog/parts/result.hbs b/templates/dialogs/groupRollDialog/parts/result.hbs
deleted file mode 100644
index d90dfb5c..00000000
--- a/templates/dialogs/groupRollDialog/parts/result.hbs
+++ /dev/null
@@ -1,30 +0,0 @@
-{{#if (and hasRolled leader.roll)}}
-
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leaderRoll"}}
-
- {{leader.roll.total}}
- {{localize "DAGGERHEART.GENERAL.withThing" thing=leader.roll.totalLabel}}
-
-
-
-
{{localize "DAGGERHEART.GENERAL.Modifier.plural"}}
-
- {{#each groupRoll.modifiers as |modifier|}}
-
- {{numberFormat modifier sign=true}}
-
- {{/each}}
-
-
-
-
- {{localize "DAGGERHEART.GENERAL.total"}}
- {{groupRoll.total}} {{groupRoll.totalLabel}}
-
-
-{{else}}
-
- {{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.resultsHint"}}
-
-{{/if}}
\ No newline at end of file
diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs
index a0f93121..0142ac1d 100644
--- a/templates/sheets/actors/character/sidebar.hbs
+++ b/templates/sheets/actors/character/sidebar.hbs
@@ -108,16 +108,18 @@