mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-21 23:13:39 +02:00
Compare commits
8 commits
d32f1fe9db
...
dddc8413cb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dddc8413cb | ||
|
|
7e54ed1218 | ||
|
|
4fedb42d44 | ||
|
|
94f9a7a0d2 | ||
|
|
154c1c939b | ||
|
|
303f2fdae7 | ||
|
|
9bea8d6a97 | ||
|
|
7ca420ae0e |
20 changed files with 769 additions and 584 deletions
31
lang/en.json
31
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}",
|
||||
|
|
|
|||
|
|
@ -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', '<div class="team-container"></div>');
|
||||
initializationPart.insertAdjacentHTML(
|
||||
'afterend',
|
||||
`<div class="section-title">${game.i18n.localize('Aiding Characters')}</div>`
|
||||
);
|
||||
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', '<div class="team-container"></div>');
|
||||
initializationPart.insertAdjacentHTML(
|
||||
'afterend',
|
||||
`<div class="section-title">${game.i18n.localize('Aiding Characters')}</div>`
|
||||
);
|
||||
|
||||
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 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
<section class="tab {{#if tabs.groupRoll.active}} active{{/if}}" data-group="{{tabs.groupRoll.group}}" data-tab="{{tabs.groupRoll.id}}">
|
||||
<fieldset>
|
||||
<legend>{{localize "Result"}}</legend>
|
||||
<legend>{{localize "DAGGERHEART.GENERAL.result.single"}}</legend>
|
||||
|
||||
<div class="group-roll-results">
|
||||
<span class="roll-title">{{groupRoll.total}} {{groupRoll.totalLabel}}</span>
|
||||
{{#if hasRolled}}<span class="roll-title {{groupRoll.totalDualityClass}}">{{groupRoll.total}} {{groupRoll.totalLabel}}</span>{{/if}}
|
||||
<div class="group-roll-container">
|
||||
<span>{{#if groupRoll.mainCharacterTotal includeZero=true}}{{groupRoll.mainCharacterTotal}}{{else}}{{localize "<Main Character Roll>"}}{{/if}}</span>
|
||||
<span>{{#if groupRoll.leaderTotal includeZero=true}}{{groupRoll.leaderTotal}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leaderRoll"}}{{/if}}</span>
|
||||
{{#each groupRoll.modifiers as |modifier|}}
|
||||
<span>{{#if (gte modifier 0)}}+{{else}}-{{/if}}</span>
|
||||
<span>{{positive modifier}}</span>
|
||||
{{/each}}
|
||||
{{#unless groupRoll.modifiers.length}}
|
||||
<span>+</span>
|
||||
<span>{{localize "DAGGERHEART.GENERAL.Modifier.plural"}}</span>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
{{#with mainCharacter}}
|
||||
<div class="main-character-outer-container">
|
||||
<div class="section-title">{{localize "Main Character"}}</div>
|
||||
<fieldset>
|
||||
<div class="main-character-container">
|
||||
<div class="character-info">
|
||||
<img src="{{img}}" />
|
||||
<div class="character-data">
|
||||
<span>{{name}}</span>
|
||||
<div class="roll-setup">
|
||||
<div class="form-group">
|
||||
<div class="form-fields">
|
||||
<select name="system.groupRoll.mainCharacter.rollChoice" {{#if hasRolled}}disabled{{/if}}>
|
||||
{{selectOptions ../traitOptions selected=rollChoice localize=true}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if readyToRoll}}
|
||||
<div class="roll-container">
|
||||
<span class="roll-title">
|
||||
{{localize "DAGGERHEART.GENERAL.roll"}}
|
||||
<div class="roll-tools">
|
||||
<a class="roll-button" data-action="makeMainCharacterRoll">
|
||||
<img src="systems/daggerheart/assets/icons/dice/hope/d12.svg" />
|
||||
</a>
|
||||
|
||||
{{#if hasRolled}}
|
||||
<a class="delete-button" data-action="removeMainCharacterRoll">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</span>
|
||||
|
||||
{{#if roll}}
|
||||
<div class="roll-data {{#if roll.withHope}}hope{{else if roll.withFear}}fear{{else}}critical{{/if}}">
|
||||
<div class="duality-label">{{roll.total}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</div>
|
||||
<div class="roll-dice-container">
|
||||
<a class="roll-dice" data-action="rerollMainCharacterDice" data-dice-type="hope">
|
||||
<span class="dice-label">{{roll.dHope.total}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" roll.dHope.denomination ".svg"}}" />
|
||||
</a>
|
||||
<span class="roll-operator">+</span>
|
||||
<a class="roll-dice" data-action="rerollMainCharacterDice" data-dice-type="fear">
|
||||
<span class="dice-label">{{roll.dFear.total}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/fear/" roll.dFear.denomination ".svg"}}" />
|
||||
</a>
|
||||
{{#if roll.advantage.type}}
|
||||
<span class="roll-operator">{{#if (eq roll.advantage.type 1)}}+{{else}}-{{/if}}</span>
|
||||
<span class="roll-dice">
|
||||
<span class="dice-label">{{roll.advantage.value}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/" (ifThen (eq roll.advantage.type 1) "adv/" "disadv/") roll.advantage.dice ".svg"}}" />
|
||||
</span>
|
||||
{{/if}}
|
||||
<span class="roll-operator">{{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}}</span>
|
||||
<span class="roll-value">{{positive roll.modifierTotal}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<span class="hint">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.makeYourRoll"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</fieldset>
|
||||
</div>
|
||||
{{/with}}
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
<div class="roll-success-modifier {{#if successfull}}success{{else if (not (isNullish successfull))}}failure{{/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}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="main-roll {{#if selectedMainCharacterDisabled}}inactive{{/if}}">
|
||||
<div class="main-roll {{#if selectedLeaderDisabled}}inactive{{/if}}">
|
||||
<div class="form-group">
|
||||
<label>{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.mainCharacter"}}</label>
|
||||
<label>{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}</label>
|
||||
<div class="form-fields">
|
||||
<select class="main-character-field" {{#if selectedMainCharacterDisabled}}disabled{{/if}}>
|
||||
{{selectOptions selectedMainCharacterOptions selected=selectedMainCharacter.memberId blank="" }}
|
||||
<select class="main-character-field" {{#if selectedLeaderDisabled}}disabled{{/if}}>
|
||||
{{selectOptions selectedLeaderOptions selected=selectedLeader.memberId blank="" }}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
73
templates/dialogs/groupRollDialog/leader.hbs
Normal file
73
templates/dialogs/groupRollDialog/leader.hbs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<section class="tab {{#if tabs.groupRoll.active}} active{{/if}}" data-group="{{tabs.groupRoll.group}}" data-tab="{{tabs.groupRoll.id}}">
|
||||
{{#with leader}}
|
||||
<div class="main-character-outer-container">
|
||||
<div class="section-title">{{localize "DAGGERHEART.APPLICATIONS.GroupRollSelect.leader"}}</div>
|
||||
<fieldset>
|
||||
<div class="main-character-container">
|
||||
<div class="character-info">
|
||||
<img src="{{img}}" />
|
||||
<div class="character-data">
|
||||
<span>{{name}}</span>
|
||||
<div class="roll-setup">
|
||||
<div class="form-group">
|
||||
<div class="form-fields">
|
||||
<select name="system.groupRoll.leader.rollChoice" {{#if hasRolled}}disabled{{/if}}>
|
||||
{{selectOptions ../traitOptions selected=rollChoice localize=true}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if readyToRoll}}
|
||||
<div class="roll-container">
|
||||
<span class="roll-title">
|
||||
{{localize "DAGGERHEART.GENERAL.roll"}}
|
||||
<div class="roll-tools">
|
||||
<a class="roll-button" data-action="makeLeaderRoll">
|
||||
<img src="systems/daggerheart/assets/icons/dice/hope/d12.svg" />
|
||||
</a>
|
||||
|
||||
{{#if hasRolled}}
|
||||
<a class="delete-button" data-action="removeLeaderRoll">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</span>
|
||||
|
||||
{{#if roll}}
|
||||
<div class="roll-data {{#if roll.withHope}}hope{{else if roll.withFear}}fear{{else}}critical{{/if}}">
|
||||
<div class="duality-label">{{roll.total}} {{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</div>
|
||||
<div class="roll-dice-container">
|
||||
<a class="roll-dice" data-action="rerollLeaderDice" data-dice-type="hope">
|
||||
<span class="dice-label">{{roll.dHope.total}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" roll.dHope.denomination ".svg"}}" />
|
||||
</a>
|
||||
<span class="roll-operator">+</span>
|
||||
<a class="roll-dice" data-action="rerollLeaderDice" data-dice-type="fear">
|
||||
<span class="dice-label">{{roll.dFear.total}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/fear/" roll.dFear.denomination ".svg"}}" />
|
||||
</a>
|
||||
{{#if roll.advantage.type}}
|
||||
<span class="roll-operator">{{#if (eq roll.advantage.type 1)}}+{{else}}-{{/if}}</span>
|
||||
<span class="roll-dice">
|
||||
<span class="dice-label">{{roll.advantage.value}}</span>
|
||||
<img src="{{concat "systems/daggerheart/assets/icons/dice/" (ifThen (eq roll.advantage.type 1) "adv/" "disadv/") roll.advantage.dice ".svg"}}" />
|
||||
</span>
|
||||
{{/if}}
|
||||
<span class="roll-operator">{{#if (gte roll.modifierTotal 0)}}+{{else}}-{{/if}}</span>
|
||||
<span class="roll-value">{{positive roll.modifierTotal}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<span class="hint">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.makeYourRoll"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</fieldset>
|
||||
</div>
|
||||
{{/with}}
|
||||
</section>
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
<div class='item-container'>
|
||||
<div class="item-info">
|
||||
<h1 class='item-name'><input type='text' name='name' value='{{source.name}}' /></h1>
|
||||
<h2 class="label">Party</h2>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -9,33 +9,160 @@
|
|||
<i class="fa-solid fa-user-group"></i>
|
||||
<span>Tag Team Roll</span>
|
||||
</button>
|
||||
<button data-action="groupRoll">
|
||||
<button data-action="groupRoll" class="{{#if groupRollActive}}active-action{{/if}}">
|
||||
<i class="fa-solid fa-users"></i>
|
||||
<span>Group Roll</span>
|
||||
</button>
|
||||
{{!-- NOT YET IMPLEMENTED --}}
|
||||
{{!-- <button>
|
||||
<i class="fa-solid fa-handshake-angle"></i>
|
||||
<span>Help Action</span>
|
||||
</button> --}}
|
||||
<button data-action="triggerRest" data-action="triggerRest" data-type="shortRest">
|
||||
<i class="fa-solid fa-utensils"></i>
|
||||
<span>{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}</span>
|
||||
</button>
|
||||
<button data-action="triggerRest" data-type="longRest">
|
||||
<i class="fa-solid fa-bed"></i>
|
||||
<span>{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<fieldset class="actors-section glassy">
|
||||
<legend>{{localize tabs.partyMembers.label}}</legend>
|
||||
<ul class="actors-list">
|
||||
{{#each document.system.partyMembers as |actor id|}}
|
||||
{{> 'daggerheart.inventory-item'
|
||||
item=actor
|
||||
type='character'
|
||||
isActor=true
|
||||
hideContextMenu=true
|
||||
}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#unless document.system.partyMembers.length}}
|
||||
<div class="actors-dragger">
|
||||
<span>{{localize "DAGGERHEART.GENERAL.dropActorsHere"}}</span>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</fieldset>
|
||||
</section>
|
||||
<ul class="actors-list">
|
||||
{{#each partyMembers as |member id|}}
|
||||
<li class="actor-resources">
|
||||
<div class="actor-img-frame">
|
||||
<img class="actor-img" src="{{member.img}}">
|
||||
{{#if member.weapons}}
|
||||
<div class="equipped-weapons">
|
||||
{{#each member.weapons as |weapon|}}
|
||||
<img src="{{weapon.img}}" data-tooltip="{{weapon.name}}"/>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if member.evasion includeZero=true}}
|
||||
<div class="evasion" data-tooltip="DAGGERHEART.GENERAL.evasion">{{member.evasion}}</div>
|
||||
{{/if}}
|
||||
{{#if member.difficulty includeZero=true}}
|
||||
<div class="evasion" data-tooltip="DAGGERHEART.GENERAL.difficulty">{{member.difficulty}}</div>
|
||||
{{/if}}
|
||||
{{#unless (eq member.type 'companion')}}
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{member.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{member.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.ACTORS.Party.Thresholds.severe"}}</h4>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
<header>
|
||||
<h2 class="actor-name">
|
||||
<a data-action="openDocument" data-uuid="{{member.uuid}}">{{member.name}}</a>
|
||||
<a class="delete-icon" data-action="deletePartyMember" data-uuid="{{member.uuid}}"><i class="fa-regular fa-times" inert></i></a>
|
||||
</h2>
|
||||
<div>
|
||||
{{#unless (or (eq member.type 'companion') (eq member.type 'adversary')) }}
|
||||
<div class="hope-section">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
|
||||
{{#times member.resources.hope.max}}
|
||||
<span class='hope-value' data-action='toggleHope' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
|
||||
{{#if (gte member.resources.hope.value (add this 1))}}
|
||||
<i class='fa-solid fa-diamond'></i>
|
||||
{{else}}
|
||||
<i class='fa-regular fa-circle'></i>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
{{#if member.subtitle}}
|
||||
<span class="subtitle">{{member.subtitle}}</span>
|
||||
{{/if}}
|
||||
</header>
|
||||
<section class="body">
|
||||
<section class="resources">
|
||||
{{#unless (eq member.type 'companion') }}
|
||||
<div class="slot-section">
|
||||
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.HitPoints.plural">
|
||||
<span class="label">
|
||||
<i class="fa-solid fa-heart" inert></i>
|
||||
</span>
|
||||
<span class="value">
|
||||
<span class="current">{{member.resources.hitPoints.value}}</span>
|
||||
/
|
||||
<span class="max">{{member.resources.hitPoints.max}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="slot-bar">
|
||||
{{#times member.resources.hitPoints.max}}
|
||||
<span class='slot {{#if (gte member.resources.hitPoints.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleHitPoints' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="slot-section">
|
||||
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.stress">
|
||||
<span class="label">
|
||||
<i class="fa-solid fa-bolt" inert></i>
|
||||
</span>
|
||||
<span class="value">
|
||||
<span class="current">{{member.resources.stress.value}}</span>
|
||||
/
|
||||
<span class="max">{{member.resources.stress.max}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="slot-bar">
|
||||
{{#times member.resources.stress.max}}
|
||||
<span class='slot {{#if (gte member.resources.stress.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleStress' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if member.armorScore.max}}
|
||||
<div class="slot-section">
|
||||
<div class="slot-label" data-tooltip="DAGGERHEART.GENERAL.armorSlots">
|
||||
<span class="label">
|
||||
<i class="fa-solid fa-shield" inert></i>
|
||||
</span>
|
||||
<span class="value">
|
||||
<span class="current">{{member.armorScore.value}}</span>
|
||||
/
|
||||
<span class="max">{{member.armorScore.max}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="slot-bar">
|
||||
{{#times member.armorScore.max}}
|
||||
<a class='armor-slot' data-action='toggleArmorSlot' data-actor-id="{{member.uuid}}" data-value="{{add this 1}}">
|
||||
{{#if (gte member.armorScore.value (add this 1))}}
|
||||
<i class="fa-solid fa-shield"></i>
|
||||
{{else}}
|
||||
<i class="fa-solid fa-shield-halved"></i>
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/times}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
{{#if member.traits}}
|
||||
<div class="traits">
|
||||
{{#each member.traits as |trait|}}
|
||||
<span class="trait">
|
||||
<span class="label">{{trait.label}}</span>
|
||||
<span class="value">{{trait.value}}</span>
|
||||
</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#unless document.system.partyMembers.length}}
|
||||
<div class="actors-dragger">
|
||||
<span>{{localize "DAGGERHEART.GENERAL.dropActorsHere"}}</span>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
<section
|
||||
class='tab {{tabs.resources.cssClass}} {{tabs.resources.id}}'
|
||||
data-tab='{{tabs.resources.id}}'
|
||||
data-group='{{tabs.resources.group}}'
|
||||
>
|
||||
<div data-action="triggerRest" data-type="longRest" class="actions-section">
|
||||
<button data-type="longRest">
|
||||
<i class="fa-solid fa-bed"></i>
|
||||
<span>{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}</span>
|
||||
</button>
|
||||
<button data-action="triggerRest" data-type="shortRest">
|
||||
<i class="fa-solid fa-utensils"></i>
|
||||
<span>{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<fieldset class="resource-section glassy">
|
||||
<legend>{{localize tabs.resources.label}}</legend>
|
||||
<ul class="actors-list">
|
||||
{{#each document.system.partyMembers as |actor id|}}
|
||||
<li class="actor-resources">
|
||||
<h2 class="actor-name">{{actor.name}}</h2>
|
||||
<img class="actor-img" src="{{actor.img}}">
|
||||
<div class="resources">
|
||||
{{#unless (eq actor.type 'companion') }}
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
{{#times actor.system.resources.hitPoints.max}}
|
||||
<span class='slot {{#if (gte actor.system.resources.hitPoints.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleHitPoints' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.HitPoints.short"}}</span>
|
||||
<span class="value">{{actor.system.resources.hitPoints.value}} / {{actor.system.resources.hitPoints.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
{{#times actor.system.resources.stress.max}}
|
||||
<span class='slot {{#if (gte actor.system.resources.stress.value (add this 1))}}filled{{/if}}'
|
||||
data-action='toggleStress' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.stress"}}</span>
|
||||
<span class="value">{{actor.system.resources.stress.value}} / {{actor.system.resources.stress.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if actor.system.armorScore.max}}
|
||||
<div class="slot-section">
|
||||
<div class="slot-bar">
|
||||
{{#times actor.system.armorScore.max}}
|
||||
<a class='armor-slot' data-action='toggleArmorSlot' data-actor-id="{{actor.id}}" data-value="{{add this 1}}">
|
||||
{{#if (gte actor.system.armorScore.value (add this 1))}}
|
||||
<i class="fa-solid fa-shield"></i>
|
||||
{{else}}
|
||||
<i class="fa-solid fa-shield-halved"></i>
|
||||
{{/if}}
|
||||
</a>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.armorSlots"}}</span>
|
||||
<span class="value">{{actor.system.armorScore.value}} / {{actor.system.armorScore.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless (or (eq actor.type 'companion') (eq actor.type 'adversary')) }}
|
||||
<div class="hope-section">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.hope"}}</h4>
|
||||
{{#times actor.system.resources.hope.max}}
|
||||
<span class='hope-value' data-action='toggleHope' data-actor-id="{{actor.uuid}}" data-value="{{add this 1}}">
|
||||
{{#if (gte actor.system.resources.hope.value (add this 1))}}
|
||||
<i class='fa-solid fa-diamond'></i>
|
||||
{{else}}
|
||||
<i class='fa-regular fa-circle'></i>
|
||||
{{/if}}
|
||||
</span>
|
||||
{{/times}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
{{#if (eq actor.type 'character')}}
|
||||
<div class="stat-section">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.evasion"}}: {{actor.system.evasion}}</h4>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless (eq actor.type 'companion')}}
|
||||
<div class="threshold-section">
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.minor"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.major}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.major"}}</h4>
|
||||
<h4 class="threshold-value">{{actor.system.damageThresholds.severe}}</h4>
|
||||
<h4 class="threshold-label">{{localize "DAGGERHEART.GENERAL.DamageThresholds.severe"}}</h4>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</fieldset>
|
||||
</section>
|
||||
Loading…
Add table
Add a link
Reference in a new issue