diff --git a/lang/en.json b/lang/en.json
index e31a1d1b..65323790 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -319,6 +319,21 @@
}
},
"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": {
@@ -535,18 +550,6 @@
},
"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",
@@ -732,7 +735,8 @@
},
"GroupRollSelect": {
"title": "Group Roll",
- "mainCharacter": "Main Character",
+ "leader": "Leader",
+ "leaderRoll": "Leader Roll",
"openDialogForAll": "Open Dialog For All",
"startGroupRoll": "Start Group Roll",
"cancelGroupRoll": "Cancel",
@@ -2397,7 +2401,6 @@
},
"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 b5169443..a488f315 100644
--- a/module/applications/dialogs/groupRollDialog.mjs
+++ b/module/applications/dialogs/groupRollDialog.mjs
@@ -1,3 +1,4 @@
+import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
import Party from '../sheets/actors/party.mjs';
@@ -18,7 +19,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
owned: member.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
}));
- this.mainCharacter = null;
+ this.leader = null;
this.openForAllPlayers = true;
this.tabGroups.application = Object.keys(party.system.groupRoll.participants).length
@@ -29,7 +30,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
get title() {
- return game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRoll.title');
+ return game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRollSelect.title');
}
static DEFAULT_OPTIONS = {
@@ -43,9 +44,9 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
makeRoll: this.#makeRoll,
removeRoll: this.#removeRoll,
rerollDice: this.#rerollDice,
- makeMainCharacterRoll: this.#makeMainCharacterRoll,
- removeMainCharacterRoll: this.#removeMainCharacterRoll,
- rerollMainCharacterDice: this.#rerollMainCharacterDice,
+ makeLeaderRoll: this.#makeLeaderRoll,
+ removeLeaderRoll: this.#removeLeaderRoll,
+ rerollLeaderDice: this.#rerollLeaderDice,
markSuccessfull: this.#markSuccessfull,
cancelRoll: this.#onCancelRoll,
finishRoll: this.#finishRoll
@@ -58,9 +59,9 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
id: 'initialization',
template: 'systems/daggerheart/templates/dialogs/groupRollDialog/initialization.hbs'
},
- mainCharacter: {
- id: 'mainCharacter',
- template: 'systems/daggerheart/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs'
+ leader: {
+ id: 'leader',
+ template: 'systems/daggerheart/templates/dialogs/groupRollDialog/leader.hbs'
},
groupRoll: {
id: 'groupRoll',
@@ -84,11 +85,11 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
htmlElement
.querySelector('.main-character-field')
- ?.addEventListener('input', this.updateMainCharacterField.bind(this));
+ ?.addEventListener('input', this.updateLeaderField.bind(this));
}
_configureRenderParts(options) {
- const { initialization, mainCharacter, groupRoll, footer } = 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)) {
augmentedParts[memberKey] = {
@@ -97,7 +98,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
};
}
- augmentedParts.mainCharacter = mainCharacter;
+ augmentedParts.leader = leader;
augmentedParts.groupRoll = groupRoll;
augmentedParts.footer = footer;
@@ -109,15 +110,19 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
await super._onRender(context, options);
if (this.element.querySelector('.team-container')) return;
- 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);
+
+ 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);
+ }
}
async _prepareContext(_options) {
@@ -148,19 +153,25 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
const selectedMembers = partContext.memberSelection.filter(x => x.selected);
- partContext.selectedMainCharacter = this.mainCharacter;
- partContext.selectedMainCharacterOptions = selectedMembers
+ partContext.selectedLeader = this.leader;
+ partContext.selectedLeaderOptions = selectedMembers
.filter(actor => actor.owned)
.map(x => ({ value: x.id, label: x.name }));
- partContext.selectedMainCharacterDisabled = !selectedMembers.length;
+ partContext.selectedLeaderDisabled = !selectedMembers.length;
- partContext.canStartGroupRoll = selectedMembers.length > 1;
+ partContext.canStartGroupRoll = selectedMembers.length > 1 && this.leader?.memberId;
partContext.openForAllPlayers = this.openForAllPlayers;
break;
- case 'mainCharacter':
- partContext.mainCharacter = this.getRollCharacterData(this.party.system.groupRoll.mainCharacter);
+ 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.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;
@@ -173,23 +184,22 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
},
{ modifierTotal: 0, modifiers: [] }
);
- const mainCharacterTotal = this.party.system.groupRoll.mainCharacter?.rollData
- ? this.party.system.groupRoll.mainCharacter.roll.total
- : null;
+ const leaderTotal = leader?.rollData ? leader.roll.total : null;
partContext.groupRoll = {
- totalLabel: this.party.system.groupRoll.mainCharacter?.rollData
+ totalLabel: leader?.rollData
? game.i18n.format('DAGGERHEART.GENERAL.withThing', {
- thing: this.party.system.groupRoll.mainCharacter.roll.totalLabel
+ thing: leader.roll.totalLabel
})
: null,
- total: mainCharacterTotal + modifierTotal,
- mainCharacterTotal,
+ totalDualityClass: leader?.roll?.isCritical ? 'critical' : leader?.roll?.withHope ? 'hope' : 'fear',
+ total: leaderTotal + modifierTotal,
+ leaderTotal: leaderTotal,
modifiers
};
break;
case 'footer':
partContext.canFinishRoll =
- Boolean(this.party.system.groupRoll.mainCharacter?.rollData) &&
+ Boolean(this.party.system.groupRoll.leader?.rollData) &&
Object.values(this.party.system.groupRoll.aidingCharacters).every(x => x.successfull !== null);
break;
}
@@ -246,15 +256,15 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
getUpdatingParts(target) {
- const { initialization, mainCharacter, groupRoll, footer } = this.constructor.PARTS;
+ const { initialization, leader, groupRoll, footer } = this.constructor.PARTS;
const isInitialization = this.tabGroups.application === initialization.id;
const updatingMember = target.closest('.team-member-container')?.dataset?.memberKey;
- const updatingMainCharacter = target.closest('.main-character-outer-container');
+ const updatingLeader = target.closest('.main-character-outer-container');
return [
...(isInitialization ? [initialization.id] : []),
...(updatingMember ? [updatingMember] : []),
- ...(updatingMainCharacter ? [mainCharacter.id] : []),
+ ...(updatingLeader ? [leader.id] : []),
...(!isInitialization ? [groupRoll.id, footer.id] : [])
];
}
@@ -297,16 +307,16 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
this.render();
}
- updateMainCharacterField(event) {
- if (!this.mainCharacter) this.mainCharacter = {};
- this.mainCharacter.memberId = event.target.value;
+ updateLeaderField(event) {
+ if (!this.leader) this.leader = {};
+ this.leader.memberId = event.target.value;
this.render();
}
static async #startGroupRoll() {
- const mainCharacter = this.partyMembers.find(x => x.id === this.mainCharacter.memberId);
+ const leader = this.partyMembers.find(x => x.id === this.leader.memberId);
const aidingCharacters = this.partyMembers.reduce((acc, curr) => {
- if (curr.selected && curr.id !== this.mainCharacter.memberId)
+ if (curr.selected && curr.id !== this.leader.memberId)
acc[curr.id] = { id: curr.id, name: curr.name, img: curr.img };
return acc;
@@ -316,7 +326,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
'system.groupRoll': _replace(
new game.system.api.data.GroupRollData({
...this.party.system.groupRoll.toObject(),
- mainCharacter: { id: mainCharacter.id, name: mainCharacter.name, img: mainCharacter.img },
+ leader: { id: leader.id, name: leader.name, img: leader.img },
aidingCharacters
})
)
@@ -333,13 +343,10 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
//#endregion
- static async #makeRoll(_event, button) {
- const { member } = button.dataset;
-
- const actor = game.actors.find(x => x.id === member);
+ async makeRoll(button, characterData, path) {
+ const actor = game.actors.find(x => x.id === characterData.id);
if (!actor) return;
- const characterData = this.party.system.groupRoll.aidingCharacters[member];
const result = await actor.rollTrait(characterData.rollChoice, {
skips: {
createMessage: true,
@@ -354,36 +361,43 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
delete rollData.options.messageRoll;
this.updatePartyData(
{
- [`system.groupRoll.aidingCharacters.${member}.rollData`]: rollData
+ [path]: rollData
},
this.getUpdatingParts(button)
);
}
- static async #removeRoll(_, 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) {
this.updatePartyData(
{
- [`system.groupRoll.aidingCharacters.${button.dataset.member}`]: {
+ [path]: {
rollData: null,
rollChoice: null,
- selected: false
+ selected: false,
+ successfull: null
}
},
this.getUpdatingParts(button)
);
}
- static async #rerollDice(_, button) {
- const { member } = button.dataset;
- this.rerollDice(
- button,
- this.party.system.groupRoll.aidingCharacters[member],
- `system.groupRoll.aidingCharacters.${member}.rollData`
- );
+ static async #removeRoll(_event, button) {
+ this.removeRoll(button, `system.groupRoll.aidingCharacters.${button.dataset.member}`);
}
- static async #rerollMainCharacterDice(_, button) {
- this.rerollDice(button, this.party.system.groupRoll.mainCharacter, `system.groupRoll.mainCharacter.rollData`);
+ static async #removeLeaderRoll(_event, button) {
+ this.removeRoll(button, 'system.groupRoll.leader');
}
async rerollDice(button, data, path) {
@@ -407,42 +421,17 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
);
}
- 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 #rerollDice(_, button) {
+ const { member } = button.dataset;
+ this.rerollDice(
+ button,
+ this.party.system.groupRoll.aidingCharacters[member],
+ `system.groupRoll.aidingCharacters.${member}.rollData`
);
}
- static async #removeMainCharacterRoll(_event, button) {
- this.updatePartyData(
- {
- [`system.groupRoll.mainCharacter`]: {
- rollData: null,
- rollChoice: null,
- selected: false
- }
- },
- this.getUpdatingParts(button)
- );
+ static async #rerollLeaderDice(_, button) {
+ this.rerollDice(button, this.party.system.groupRoll.leader, `system.groupRoll.leader.rollData`);
}
static #markSuccessfull(_event, button) {
@@ -476,7 +465,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
await this.updatePartyData(
{
'system.groupRoll': {
- mainCharacter: null,
+ leader: null,
aidingCharacters: _replace({})
}
},
@@ -492,7 +481,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
}
static async #finishRoll() {
- const totalRoll = this.party.system.groupRoll.mainCharacter.roll;
+ 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.successfull ? '+' : '-' }));
totalRoll.terms.push(new foundry.dice.terms.NumericTerm({ number: 1 }));
@@ -501,13 +490,13 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
await totalRoll._evaluate();
const systemData = totalRoll.options;
- const actor = game.actors.get(this.party.system.groupRoll.mainCharacter.id);
+ const actor = game.actors.get(this.party.system.groupRoll.leader.id);
const cls = getDocumentClass('ChatMessage'),
msgData = {
type: 'dualityRoll',
user: game.user.id,
- title: game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title'),
+ title: game.i18n.localize('DAGGERHEART.APPLICATIONS.GroupRollSelect.title'),
speaker: cls.getSpeaker({ actor }),
system: systemData,
rolls: [JSON.stringify(totalRoll)],
@@ -517,6 +506,20 @@ 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 cd747474..d4545f63 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 } from '../../../helpers/utils.mjs';
+import { getDocFromElement, sortBy } 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,13 +17,14 @@ export default class Party extends DHBaseActorSheet {
static DEFAULT_OPTIONS = {
classes: ['party'],
position: {
- width: 550,
+ width: 600,
height: 900
},
window: {
resizable: true
},
actions: {
+ openDocument: Party.#openDocument,
deletePartyMember: Party.#deletePartyMember,
deleteItem: Party.#deleteItem,
toggleHope: Party.#toggleHope,
@@ -44,10 +45,6 @@ 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',
@@ -65,7 +62,6 @@ export default class Party extends DHBaseActorSheet {
primary: {
tabs: [
{ id: 'partyMembers' },
- { id: 'resources' },
/* NOT YET IMPLEMENTED */
// { id: 'projects' },
{ id: 'inventory' },
@@ -95,6 +91,8 @@ 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;
@@ -118,6 +116,60 @@ 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
+ });
+ }
}
/**
@@ -148,6 +200,12 @@ 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}
@@ -189,7 +247,7 @@ export default class Party extends DHBaseActorSheet {
* @type {ApplicationClickAction}
*/
static async #toggleArmorSlot(_, target) {
- const actor = game.actors.get(target.dataset.actorId);
+ const actor = await foundry.utils.fromUuid(target.dataset.actorId);
const { value, max } = actor.system.armorScore;
const inputValue = Number.parseInt(target.dataset.value);
const newValue = value >= inputValue ? inputValue - 1 : inputValue;
@@ -422,25 +480,23 @@ export default class Party extends DHBaseActorSheet {
}
static async #deletePartyMember(event, target) {
- const doc = await getDocFromElement(target.closest('.inventory-item'));
-
+ const doc = await foundry.utils.fromUuid(target.closest('[data-uuid]')?.dataset.uuid);
if (!event.shiftKey) {
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: {
- title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
- type: game.i18n.localize('TYPES.Actor.adversary'),
+ title: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.title', {
name: doc.name
})
},
- content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: doc.name })
+ content: game.i18n.format('DAGGERHEART.ACTORS.Party.RemoveConfirmation.text', { name: doc.name })
});
if (!confirmed) return;
}
const currentMembers = this.document.system.partyMembers.map(x => x.uuid);
- const newMemberdList = currentMembers.filter(uuid => uuid !== doc.uuid);
- await this.document.update({ 'system.partyMembers': newMemberdList });
+ const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid);
+ await this.document.update({ 'system.partyMembers': newMembersList });
}
static async #deleteItem(event, target) {
diff --git a/module/data/groupRollData.mjs b/module/data/groupRollData.mjs
index 5047c4e2..78a06b13 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 {
- mainCharacter: new fields.EmbeddedDataField(CharacterData, { nullable: true, initial: null }),
+ leader: new fields.EmbeddedDataField(CharacterData, { nullable: true, initial: null }),
aidingCharacters: new fields.TypedObjectField(new fields.EmbeddedDataField(CharacterData))
};
}
get participants() {
return {
- ...(this.mainCharacter ? { [this.mainCharacter.id]: this.mainCharacter } : {}),
+ ...(this.leader ? { [this.leader.id]: this.leader } : {}),
...this.aidingCharacters
};
}
diff --git a/styles/less/dialog/group-roll-dialog/initialization.less b/styles/less/dialog/group-roll-dialog/initialization.less
index 211495ee..96990339 100644
--- a/styles/less/dialog/group-roll-dialog/initialization.less
+++ b/styles/less/dialog/group-roll-dialog/initialization.less
@@ -1,3 +1,11 @@
+.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 {
@@ -20,6 +28,17 @@
.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/mainCharacter.less b/styles/less/dialog/group-roll-dialog/leader.less
similarity index 100%
rename from styles/less/dialog/group-roll-dialog/mainCharacter.less
rename to styles/less/dialog/group-roll-dialog/leader.less
diff --git a/styles/less/dialog/group-roll-dialog/sheet.less b/styles/less/dialog/group-roll-dialog/sheet.less
index 571d0d38..823f6cbf 100644
--- a/styles/less/dialog/group-roll-dialog/sheet.less
+++ b/styles/less/dialog/group-roll-dialog/sheet.less
@@ -12,6 +12,11 @@
gap: 8px;
flex: 1;
+ &.inactive {
+ opacity: 0.3;
+ pointer-events: none;
+ }
+
.data-container {
display: flex;
flex-direction: column;
@@ -59,9 +64,27 @@
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: light-dark(@dark-blue, @golden);
+ color: var(--text-color);
content: '';
flex: 1;
height: 2px;
diff --git a/styles/less/dialog/index.less b/styles/less/dialog/index.less
index fa59d0f5..947142ff 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/mainCharacter.less';
+@import './group-roll-dialog/leader.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 30676f82..0d16aa3b 100644
--- a/styles/less/dialog/tag-team-dialog/initialization.less
+++ b/styles/less/dialog/tag-team-dialog/initialization.less
@@ -20,6 +20,17 @@
.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 a433ae34..155fcc36 100644
--- a/styles/less/sheets/actors/party/party-members.less
+++ b/styles/less/sheets/actors/party/party-members.less
@@ -1,28 +1,293 @@
@import '../../../utils/colors.less';
@import '../../../utils/fonts.less';
+@import '../../../utils/mixin.less';
-.application.sheet.daggerheart.actor.dh-style.party {
- .tab.partyMembers {
- max-height: 400px;
- overflow: auto;
+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);
- .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);
+ .actor-name {
+ background: light-dark(@dark-blue, @dark-golden);
}
}
}
+
+.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
deleted file mode 100644
index 68628295..00000000
--- a/styles/less/sheets/actors/party/resources.less
+++ /dev/null
@@ -1,216 +0,0 @@
-@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 e5ffbf3e..7d595614 100644
--- a/styles/less/sheets/index.less
+++ b/styles/less/sheets/index.less
@@ -31,7 +31,6 @@
@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 24f317a2..edf1c980 100644
--- a/templates/dialogs/groupRollDialog/groupRoll.hbs
+++ b/templates/dialogs/groupRollDialog/groupRoll.hbs
@@ -1,15 +1,19 @@
- {{localize "Result"}}
+ {{localize "DAGGERHEART.GENERAL.result.single"}}
-
{{groupRoll.total}} {{groupRoll.totalLabel}}
+ {{#if hasRolled}}
{{groupRoll.total}} {{groupRoll.totalLabel}} {{/if}}
- {{#if groupRoll.mainCharacterTotal includeZero=true}}{{groupRoll.mainCharacterTotal}}{{else}}{{localize ""}}{{/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}}
diff --git a/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs b/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs
deleted file mode 100644
index 0a090acf..00000000
--- a/templates/dialogs/groupRollDialog/groupRollMainCharacter.hbs
+++ /dev/null
@@ -1,71 +0,0 @@
-{{#with mainCharacter}}
-
-
{{localize "Main Character"}}
-
-
-
-
-
-
-
-
- {{#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/groupRollMember.hbs b/templates/dialogs/groupRollDialog/groupRollMember.hbs
index af1e7909..acf8e8f1 100644
--- a/templates/dialogs/groupRollDialog/groupRollMember.hbs
+++ b/templates/dialogs/groupRollDialog/groupRollMember.hbs
@@ -76,7 +76,7 @@
{{/if}}
- {{localize "DAGGERHEART.GENERAL.modifier"}}{{#if successfull}} + 1{{else if (isNullish successfull)}} + ?{{else}} - 1{{/if}}
+ {{localize "DAGGERHEART.GENERAL.Modifier.single"}}{{#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 06741363..a520b8bd 100644
--- a/templates/dialogs/groupRollDialog/initialization.hbs
+++ b/templates/dialogs/groupRollDialog/initialization.hbs
@@ -11,12 +11,12 @@
{{/each}}
-
+
diff --git a/templates/dialogs/groupRollDialog/leader.hbs b/templates/dialogs/groupRollDialog/leader.hbs
new file mode 100644
index 00000000..78fbcb42
--- /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/sheets/actors/party/header.hbs b/templates/sheets/actors/party/header.hbs
index f39f683f..3fdb137d 100644
--- a/templates/sheets/actors/party/header.hbs
+++ b/templates/sheets/actors/party/header.hbs
@@ -3,7 +3,6 @@
\ 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 b3dd53e6..bc0c6672 100644
--- a/templates/sheets/actors/party/party-members.hbs
+++ b/templates/sheets/actors/party/party-members.hbs
@@ -9,33 +9,160 @@
Tag Team Roll
-
+
Group Roll
- {{!-- NOT YET IMPLEMENTED --}}
- {{!--
-
- Help Action
- --}}
+
+
+ {{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}
+
+
+
+ {{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}
+
-
- {{localize tabs.partyMembers.label}}
-
- {{#each document.system.partyMembers as |actor id|}}
- {{> 'daggerheart.inventory-item'
- item=actor
- type='character'
- isActor=true
- hideContextMenu=true
- }}
- {{/each}}
-
- {{#unless document.system.partyMembers.length}}
-
- {{localize "DAGGERHEART.GENERAL.dropActorsHere"}}
-
- {{/unless}}
-
-
\ No newline at end of file
+
+ {{#each partyMembers as |member id|}}
+
+
+
+ {{#if member.weapons}}
+
+ {{#each member.weapons as |weapon|}}
+
+ {{/each}}
+
+ {{/if}}
+ {{#if member.evasion includeZero=true}}
+
{{member.evasion}}
+ {{/if}}
+ {{#if member.difficulty includeZero=true}}
+
{{member.difficulty}}
+ {{/if}}
+ {{#unless (eq member.type 'companion')}}
+
+
{{localize "DAGGERHEART.ACTORS.Party.Thresholds.minor"}}
+ {{member.damageThresholds.major}}
+ {{localize "DAGGERHEART.ACTORS.Party.Thresholds.major"}}
+ {{member.damageThresholds.severe}}
+ {{localize "DAGGERHEART.ACTORS.Party.Thresholds.severe"}}
+
+ {{/unless}}
+
+
+
+
+ {{#unless (eq member.type 'companion') }}
+
+
+
+
+
+
+ {{member.resources.hitPoints.value}}
+ /
+ {{member.resources.hitPoints.max}}
+
+
+
+ {{#times member.resources.hitPoints.max}}
+
+
+ {{/times}}
+
+
+ {{/unless}}
+
+
+
+
+
+
+
+ {{member.resources.stress.value}}
+ /
+ {{member.resources.stress.max}}
+
+
+
+ {{#times member.resources.stress.max}}
+
+
+ {{/times}}
+
+
+
+ {{#if member.armorScore.max}}
+
+
+
+
+
+
+ {{member.armorScore.value}}
+ /
+ {{member.armorScore.max}}
+
+
+
+
+ {{/if}}
+
+ {{#if member.traits}}
+
+ {{#each member.traits as |trait|}}
+
+ {{trait.label}}
+ {{trait.value}}
+
+ {{/each}}
+
+ {{/if}}
+
+
+ {{/each}}
+
+ {{#unless document.system.partyMembers.length}}
+
+ {{localize "DAGGERHEART.GENERAL.dropActorsHere"}}
+
+ {{/unless}}
+
diff --git a/templates/sheets/actors/party/resources.hbs b/templates/sheets/actors/party/resources.hbs
deleted file mode 100644
index b53282ca..00000000
--- a/templates/sheets/actors/party/resources.hbs
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
- {{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}
-
-
-
- {{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}
-
-
-
-
- {{localize tabs.resources.label}}
-
- {{#each document.system.partyMembers as |actor id|}}
-
- {{actor.name}}
-
-
- {{#unless (eq actor.type 'companion') }}
-
-
- {{#times actor.system.resources.hitPoints.max}}
-
-
- {{/times}}
-
-
- {{localize "DAGGERHEART.GENERAL.HitPoints.short"}}
- {{actor.system.resources.hitPoints.value}} / {{actor.system.resources.hitPoints.max}}
-
-
- {{/unless}}
-
-
-
- {{#times actor.system.resources.stress.max}}
-
-
- {{/times}}
-
-
- {{localize "DAGGERHEART.GENERAL.stress"}}
- {{actor.system.resources.stress.value}} / {{actor.system.resources.stress.max}}
-
-
-
- {{#if actor.system.armorScore.max}}
-
-
-
- {{localize "DAGGERHEART.GENERAL.armorSlots"}}
- {{actor.system.armorScore.value}} / {{actor.system.armorScore.max}}
-
-
- {{/if}}
-
- {{#unless (or (eq actor.type 'companion') (eq actor.type 'adversary')) }}
-
-
{{localize "DAGGERHEART.GENERAL.hope"}}
- {{#times actor.system.resources.hope.max}}
-
- {{#if (gte actor.system.resources.hope.value (add this 1))}}
-
- {{else}}
-
- {{/if}}
-
- {{/times}}
-
- {{/unless}}
-
- {{#if (eq actor.type 'character')}}
-
-
{{localize "DAGGERHEART.GENERAL.evasion"}}: {{actor.system.evasion}}
-
- {{/if}}
-
- {{#unless (eq actor.type 'companion')}}
-
-
{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}
- {{actor.system.damageThresholds.major}}
- {{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}
- {{actor.system.damageThresholds.severe}}
- {{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}
-
- {{/unless}}
-
-
- {{/each}}
-
-
-
\ No newline at end of file