mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-15 13:11:08 +01:00
Finished GroupRoll
This commit is contained in:
parent
a442cb904b
commit
c49079c57c
15 changed files with 632 additions and 42 deletions
15
lang/en.json
15
lang/en.json
|
|
@ -2488,6 +2488,17 @@
|
||||||
"title": "Effects Applied"
|
"title": "Effects Applied"
|
||||||
},
|
},
|
||||||
"featureTitle": "Class Feature",
|
"featureTitle": "Class Feature",
|
||||||
|
"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} check?",
|
||||||
|
"rerollTooltip": "Reroll"
|
||||||
|
},
|
||||||
"healingRoll": {
|
"healingRoll": {
|
||||||
"title": "Heal - {damage}",
|
"title": "Heal - {damage}",
|
||||||
"heal": "Heal",
|
"heal": "Heal",
|
||||||
|
|
@ -2629,7 +2640,9 @@
|
||||||
"noDiceSystem": "Your selected dice {system} does not have a {faces} dice",
|
"noDiceSystem": "Your selected dice {system} does not have a {faces} dice",
|
||||||
"gmMenuRefresh": "You refreshed all actions and resources {types}",
|
"gmMenuRefresh": "You refreshed all actions and resources {types}",
|
||||||
"subclassAlreadyLinked": "{name} is already a subclass in the class {class}. Remove it from there if you want it to be a subclass to this class.",
|
"subclassAlreadyLinked": "{name} is already a subclass in the class {class}. Remove it from there if you want it to be a subclass to this class.",
|
||||||
"gmRequired": "This action requires an online GM"
|
"gmRequired": "This action requires an online GM",
|
||||||
|
"gmOnly": "This can only be accessed by the GM",
|
||||||
|
"noActorOwnership": "You do not have permissions for this character"
|
||||||
},
|
},
|
||||||
"Sidebar": {
|
"Sidebar": {
|
||||||
"daggerheartMenu": {
|
"daggerheartMenu": {
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
}
|
}
|
||||||
|
|
||||||
const tagTeamSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
const tagTeamSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||||
if (tagTeamSetting.members[this.actor.id]) {
|
if (tagTeamSetting.members[this.actor.id] && !this.config.skips?.createMessage) {
|
||||||
context.activeTagTeamRoll = true;
|
context.activeTagTeamRoll = true;
|
||||||
context.tagTeamSelected = this.config.tagTeamSelected;
|
context.tagTeamSelected = this.config.tagTeamSelected;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll'],
|
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll'],
|
||||||
position: { width: 'auto', height: 'auto' },
|
position: { width: 'auto', height: 'auto' },
|
||||||
|
window: {
|
||||||
|
title: 'DAGGERHEART.UI.Chat.groupRoll.title'
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
roll: GroupRollDialog.#roll,
|
roll: GroupRollDialog.#roll,
|
||||||
removeLeader: GroupRollDialog.#removeLeader,
|
removeLeader: GroupRollDialog.#removeLeader,
|
||||||
|
|
@ -36,17 +39,20 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
|
|
||||||
_attachPartListeners(partId, htmlElement, options) {
|
_attachPartListeners(partId, htmlElement, options) {
|
||||||
super._attachPartListeners(partId, htmlElement, options);
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
const changeChoices = this.actors;
|
const leaderChoices = this.actors.filter(x => this.actorsMembers.every(member => member.actor?.id !== x.id));
|
||||||
|
const memberChoices = this.actors.filter(
|
||||||
|
x => this.actorLeader?.actor?.id !== x.id && this.actorsMembers.every(member => member.actor?.id !== x.id)
|
||||||
|
);
|
||||||
|
|
||||||
htmlElement.querySelectorAll('.leader-change-input').forEach(element => {
|
htmlElement.querySelectorAll('.leader-change-input').forEach(element => {
|
||||||
autocomplete({
|
autocomplete({
|
||||||
input: element,
|
input: element,
|
||||||
fetch: function (text, update) {
|
fetch: function (text, update) {
|
||||||
if (!text) {
|
if (!text) {
|
||||||
update(changeChoices);
|
update(leaderChoices);
|
||||||
} else {
|
} else {
|
||||||
text = text.toLowerCase();
|
text = text.toLowerCase();
|
||||||
var suggestions = changeChoices.filter(n => n.name.toLowerCase().includes(text));
|
var suggestions = leaderChoices.filter(n => n.name.toLowerCase().includes(text));
|
||||||
update(suggestions);
|
update(suggestions);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -76,7 +82,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
},
|
},
|
||||||
onSelect: actor => {
|
onSelect: actor => {
|
||||||
element.value = actor.uuid;
|
element.value = actor.uuid;
|
||||||
this.actorLeader = { actor: actor, trait: '', difficulty: 0 };
|
this.actorLeader = { actor: actor, trait: 'agility', difficulty: 0 };
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
click: e => e.fetch(),
|
click: e => e.fetch(),
|
||||||
|
|
@ -92,10 +98,10 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
input: element,
|
input: element,
|
||||||
fetch: function (text, update) {
|
fetch: function (text, update) {
|
||||||
if (!text) {
|
if (!text) {
|
||||||
update(changeChoices);
|
update(memberChoices);
|
||||||
} else {
|
} else {
|
||||||
text = text.toLowerCase();
|
text = text.toLowerCase();
|
||||||
var suggestions = changeChoices.filter(n => n.name.toLowerCase().includes(text));
|
var suggestions = memberChoices.filter(n => n.name.toLowerCase().includes(text));
|
||||||
update(suggestions);
|
update(suggestions);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -125,7 +131,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
},
|
},
|
||||||
onSelect: actor => {
|
onSelect: actor => {
|
||||||
element.value = actor.uuid;
|
element.value = actor.uuid;
|
||||||
this.actorsMembers.push({ actor: actor, trait: '', difficulty: 0 });
|
this.actorsMembers.push({ actor: actor, trait: 'agility', difficulty: 0 });
|
||||||
this.render({ force: true });
|
this.render({ force: true });
|
||||||
},
|
},
|
||||||
click: e => e.fetch(),
|
click: e => e.fetch(),
|
||||||
|
|
@ -140,14 +146,22 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.leader = this.actorLeader;
|
context.leader = this.actorLeader;
|
||||||
context.members = [...this.actorsMembers];
|
context.members = this.actorsMembers;
|
||||||
context.traitList = Object.values(abilities).map(trait => ({
|
context.traitList = abilities;
|
||||||
label: game.i18n.localize(trait.label),
|
|
||||||
value: trait.id
|
context.allSelected = this.actorsMembers.length + (this.actorLeader?.actor ? 1 : 0) === this.actors.length;
|
||||||
}));
|
context.rollDisabled = context.members.length === 0 || !this.actorLeader?.actor;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static updateData(event, _, formData) {
|
||||||
|
const { actorLeader, actorsMembers } = foundry.utils.expandObject(formData.object);
|
||||||
|
this.actorLeader = foundry.utils.mergeObject(this.actorLeader, actorLeader);
|
||||||
|
this.actorsMembers = foundry.utils.mergeObject(this.actorsMembers, actorsMembers);
|
||||||
|
this.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
static async #removeLeader(_, button) {
|
static async #removeLeader(_, button) {
|
||||||
this.actorLeader = null;
|
this.actorLeader = null;
|
||||||
this.render();
|
this.render();
|
||||||
|
|
@ -158,8 +172,25 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #roll(_, button) {
|
static async #roll() {
|
||||||
console.log(this.leader, this.members);
|
const cls = getDocumentClass('ChatMessage');
|
||||||
console.log(this);
|
const systemData = {
|
||||||
|
leader: this.actorLeader,
|
||||||
|
members: this.actorsMembers
|
||||||
|
};
|
||||||
|
const msg = {
|
||||||
|
type: 'groupRoll',
|
||||||
|
user: game.user.id,
|
||||||
|
speaker: cls.getSpeaker(),
|
||||||
|
title: game.i18n.localize('DAGGERHEART.UI.Chat.groupRoll.title'),
|
||||||
|
system: systemData,
|
||||||
|
content: await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/ui/chat/groupRoll.hbs',
|
||||||
|
{ system: systemData }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
cls.create(msg);
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { abilities } from '../../config/actorConfig.mjs';
|
||||||
|
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
|
@ -67,6 +68,18 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
html.querySelectorAll('.reroll-button').forEach(element =>
|
html.querySelectorAll('.reroll-button').forEach(element =>
|
||||||
element.addEventListener('click', event => this.rerollEvent(event, data.message))
|
element.addEventListener('click', event => this.rerollEvent(event, data.message))
|
||||||
);
|
);
|
||||||
|
html.querySelectorAll('.group-roll-button').forEach(element =>
|
||||||
|
element.addEventListener('click', event => this.groupRollButton(event, data.message))
|
||||||
|
);
|
||||||
|
html.querySelectorAll('.group-roll-reroll').forEach(element =>
|
||||||
|
element.addEventListener('click', event => this.groupRollReroll(event, data.message))
|
||||||
|
);
|
||||||
|
html.querySelectorAll('.group-roll-success').forEach(element =>
|
||||||
|
element.addEventListener('click', event => this.groupRollSuccessEvent(event, data.message))
|
||||||
|
);
|
||||||
|
html.querySelectorAll('.group-roll-header-expand-section').forEach(element =>
|
||||||
|
element.addEventListener('click', this.groupRollExpandSection)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
setupHooks() {
|
setupHooks() {
|
||||||
|
|
@ -176,4 +189,156 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async groupRollButton(event, message) {
|
||||||
|
const path = event.currentTarget.dataset.path;
|
||||||
|
const { actor: actorData, trait } = foundry.utils.getProperty(message.system, path);
|
||||||
|
const actor = game.actors.get(actorData._id);
|
||||||
|
|
||||||
|
if (!actor.testUserPermission(game.user, 'OWNER')) {
|
||||||
|
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noActorOwnership'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const traitLabel = game.i18n.localize(abilities[trait].label);
|
||||||
|
const config = {
|
||||||
|
event: event,
|
||||||
|
title: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${actor.name}`,
|
||||||
|
headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||||
|
ability: traitLabel
|
||||||
|
}),
|
||||||
|
roll: {
|
||||||
|
trait: trait,
|
||||||
|
advantage: 0,
|
||||||
|
modifiers: [{ label: traitLabel, value: actor.system.traits[trait].value }]
|
||||||
|
},
|
||||||
|
hasRoll: true,
|
||||||
|
skips: {
|
||||||
|
createMessage: true,
|
||||||
|
resources: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await actor.diceRoll({
|
||||||
|
...config,
|
||||||
|
headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${actor.name}`,
|
||||||
|
title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||||
|
ability: traitLabel
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderData = { system: foundry.utils.deepClone(message.system) };
|
||||||
|
foundry.utils.setProperty(renderData.system, `${path}.result`, result.roll);
|
||||||
|
|
||||||
|
const updatedContent = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/ui/chat/groupRoll.hbs',
|
||||||
|
{ ...renderData, user: game.user }
|
||||||
|
);
|
||||||
|
const mess = game.messages.get(message._id);
|
||||||
|
|
||||||
|
await emitAsGM(
|
||||||
|
GMUpdateEvent.UpdateDocument,
|
||||||
|
mess.update.bind(mess),
|
||||||
|
{
|
||||||
|
...renderData,
|
||||||
|
content: updatedContent
|
||||||
|
},
|
||||||
|
mess.uuid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async groupRollReroll(event, message) {
|
||||||
|
const path = event.currentTarget.dataset.path;
|
||||||
|
const { actor: actorData, trait } = foundry.utils.getProperty(message.system, path);
|
||||||
|
const actor = game.actors.get(actorData._id);
|
||||||
|
|
||||||
|
if (!actor.testUserPermission(game.user, 'OWNER')) {
|
||||||
|
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noActorOwnership'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const traitLabel = game.i18n.localize(abilities[trait].label);
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
event: event,
|
||||||
|
title: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${actor.name}`,
|
||||||
|
headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||||
|
ability: traitLabel
|
||||||
|
}),
|
||||||
|
roll: {
|
||||||
|
trait: trait,
|
||||||
|
advantage: 0,
|
||||||
|
modifiers: [{ label: traitLabel, value: actor.system.traits[trait].value }]
|
||||||
|
},
|
||||||
|
hasRoll: true,
|
||||||
|
skips: {
|
||||||
|
createMessage: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await actor.diceRoll({
|
||||||
|
...config,
|
||||||
|
headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${actor.name}`,
|
||||||
|
title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||||
|
ability: traitLabel
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderData = { system: foundry.utils.deepClone(message.system) };
|
||||||
|
foundry.utils.setProperty(renderData.system, `${path}.result`, { ...result.roll, rerolled: true });
|
||||||
|
|
||||||
|
const updatedContent = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/ui/chat/groupRoll.hbs',
|
||||||
|
{ ...renderData, user: game.user }
|
||||||
|
);
|
||||||
|
const mess = game.messages.get(message._id);
|
||||||
|
await emitAsGM(
|
||||||
|
GMUpdateEvent.UpdateDocument,
|
||||||
|
mess.update.bind(mess),
|
||||||
|
{
|
||||||
|
...renderData,
|
||||||
|
content: updatedContent
|
||||||
|
},
|
||||||
|
mess.uuid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async groupRollSuccessEvent(event, message) {
|
||||||
|
if (!game.user.isGM) {
|
||||||
|
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.gmOnly'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { path, success } = event.currentTarget.dataset;
|
||||||
|
const { actor: actorData } = foundry.utils.getProperty(message.system, path);
|
||||||
|
const actor = game.actors.get(actorData._id);
|
||||||
|
|
||||||
|
if (!actor.testUserPermission(game.user, 'OWNER')) {
|
||||||
|
return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noActorOwnership'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderData = { system: foundry.utils.deepClone(message.system) };
|
||||||
|
foundry.utils.setProperty(renderData.system, `${path}.manualSuccess`, Boolean(success));
|
||||||
|
|
||||||
|
const updatedContent = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
'systems/daggerheart/templates/ui/chat/groupRoll.hbs',
|
||||||
|
{ ...renderData, user: game.user }
|
||||||
|
);
|
||||||
|
const mess = game.messages.get(message._id);
|
||||||
|
await emitAsGM(
|
||||||
|
GMUpdateEvent.UpdateDocument,
|
||||||
|
mess.update.bind(mess),
|
||||||
|
{
|
||||||
|
...renderData,
|
||||||
|
content: updatedContent
|
||||||
|
},
|
||||||
|
mess.uuid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async groupRollExpandSection(event) {
|
||||||
|
event.target
|
||||||
|
.closest('.group-roll-header-expand-section')
|
||||||
|
.querySelectorAll('i')
|
||||||
|
.forEach(element => {
|
||||||
|
element.classList.toggle('fa-angle-up');
|
||||||
|
element.classList.toggle('fa-angle-down');
|
||||||
|
});
|
||||||
|
event.target.closest('.group-roll-section').querySelector('.group-roll-content').classList.toggle('closed');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { emitAsGM, GMUpdateEvent, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import DHAbilityUse from './abilityUse.mjs';
|
import DHAbilityUse from './abilityUse.mjs';
|
||||||
import DHActorRoll from './actorRoll.mjs';
|
import DHActorRoll from './actorRoll.mjs';
|
||||||
|
import DHGroupRoll from './groupRoll.mjs';
|
||||||
import DHSystemMessage from './systemMessage.mjs';
|
import DHSystemMessage from './systemMessage.mjs';
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
|
@ -7,5 +8,6 @@ export const config = {
|
||||||
adversaryRoll: DHActorRoll,
|
adversaryRoll: DHActorRoll,
|
||||||
damageRoll: DHActorRoll,
|
damageRoll: DHActorRoll,
|
||||||
dualityRoll: DHActorRoll,
|
dualityRoll: DHActorRoll,
|
||||||
|
groupRoll: DHGroupRoll,
|
||||||
systemMessage: DHSystemMessage
|
systemMessage: DHSystemMessage
|
||||||
};
|
};
|
||||||
|
|
|
||||||
31
module/data/chat-message/groupRoll.mjs
Normal file
31
module/data/chat-message/groupRoll.mjs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { abilities } from '../../config/actorConfig.mjs';
|
||||||
|
|
||||||
|
export default class DHGroupRoll extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
return {
|
||||||
|
leader: new fields.EmbeddedDataField(GroupRollMemberField),
|
||||||
|
members: new fields.ArrayField(new fields.EmbeddedDataField(GroupRollMemberField))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupRollMemberField extends foundry.abstract.DataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
return {
|
||||||
|
actor: new fields.ObjectField(),
|
||||||
|
trait: new fields.StringField({ choices: abilities }),
|
||||||
|
difficulty: new fields.StringField(),
|
||||||
|
result: new fields.ObjectField({ nullable: true, initial: null }),
|
||||||
|
manualSuccess: new fields.BooleanField({ nullable: true, initial: null })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can be expanded if we handle automation of success/failure */
|
||||||
|
get success() {
|
||||||
|
return manualSuccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -70,8 +70,11 @@ export default class DHRoll extends Roll {
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postRoll${hook.capitalize()}`, config, message) === false) return null;
|
if (Hooks.call(`${CONFIG.DH.id}.postRoll${hook.capitalize()}`, config, message) === false) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Chat Message
|
if (config.skips?.createMessage && game.modules.get('dice-so-nice')?.active) {
|
||||||
if (!config.source?.message) config.message = await this.toMessage(roll, config);
|
await game.dice3d.showForRoll(roll, game.user, true);
|
||||||
|
} else if (!config.source?.message) {
|
||||||
|
config.message = await this.toMessage(roll, config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static postEvaluate(roll, config = {}) {
|
static postEvaluate(roll, config = {}) {
|
||||||
|
|
@ -237,7 +240,8 @@ export const registerRollDiceHooks = () => {
|
||||||
!config.source?.actor ||
|
!config.source?.actor ||
|
||||||
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
||||||
config.actionType === 'reaction' ||
|
config.actionType === 'reaction' ||
|
||||||
config.tagTeamSelected
|
config.tagTeamSelected ||
|
||||||
|
config.skips?.resources
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
const actor = await fromUuid(config.source.actor);
|
const actor = await fromUuid(config.source.actor);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ export default class RegisterHandlebarsHelpers {
|
||||||
setVar: this.setVar,
|
setVar: this.setVar,
|
||||||
empty: this.empty,
|
empty: this.empty,
|
||||||
pluralize: this.pluralize,
|
pluralize: this.pluralize,
|
||||||
positive: this.positive
|
positive: this.positive,
|
||||||
|
isNullish: this.isNullish
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static add(a, b) {
|
static add(a, b) {
|
||||||
|
|
@ -94,4 +95,8 @@ export default class RegisterHandlebarsHelpers {
|
||||||
static positive(a) {
|
static positive(a) {
|
||||||
return Math.abs(Number(a));
|
return Math.abs(Number(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isNullish(a) {
|
||||||
|
return a === null || a === undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,4 +44,7 @@
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tooltip-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
210
styles/less/ui/chat/group-roll.less
Normal file
210
styles/less/ui/chat/group-roll.less
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
.daggerheart .chat-message .message-content .group-roll {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
|
||||||
|
.group-roll-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
.group-roll-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
&.first {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-header-expand-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: light-dark(@dark-blue, @golden);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
height: auto;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.closed {
|
||||||
|
height: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.finished {
|
||||||
|
background: light-dark(@dark-blue-10, @golden-10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-main-roll {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-roll-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
color: light-dark(@dark-blue, @golden);
|
||||||
|
|
||||||
|
.main-value {
|
||||||
|
font-size: var(--font-size-24);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-text {
|
||||||
|
font-size: var(--font-size-16);
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-member {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.group-roll-data {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-label-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.group-roll-label-inner-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-modifier {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border: 1px solid light-dark(@green, @green);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: light-dark(@green, @green);
|
||||||
|
background: light-dark(@green-40, @green-40);
|
||||||
|
|
||||||
|
&.failure {
|
||||||
|
border-color: light-dark(@red, @red);
|
||||||
|
color: light-dark(@red, @red);
|
||||||
|
background: light-dark(@red-40, @red-40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-trait {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border: 1px solid light-dark(white, white);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: light-dark(white, white);
|
||||||
|
background: light-dark(@beige-80, @beige-80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-rolling {
|
||||||
|
img {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: drop-shadow(0 0 8px light-dark(@dark-blue, @golden));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.roll-results {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: fit-content;
|
||||||
|
gap: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
background: light-dark(@dark-blue-10, @golden-10);
|
||||||
|
color: light-dark(@dark-blue, @golden);
|
||||||
|
|
||||||
|
&.finished {
|
||||||
|
background-color: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reroll-result-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: var(--font-size-18);
|
||||||
|
line-height: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success,
|
||||||
|
.success i {
|
||||||
|
color: @green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.failure,
|
||||||
|
.failure i {
|
||||||
|
color: @red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-roll-reroll {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.dice-icon {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reroll-icon {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 14px;
|
||||||
|
color: black;
|
||||||
|
filter: drop-shadow(0 0 3px black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
@import './chat/damage-summary.less';
|
@import './chat/damage-summary.less';
|
||||||
@import './chat/downtime.less';
|
@import './chat/downtime.less';
|
||||||
@import './chat/effect-summary.less';
|
@import './chat/effect-summary.less';
|
||||||
|
@import './chat/group-roll.less';
|
||||||
@import './chat/refresh-message.less';
|
@import './chat/refresh-message.less';
|
||||||
@import './chat/sheet.less';
|
@import './chat/sheet.less';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@
|
||||||
"damageRoll": {},
|
"damageRoll": {},
|
||||||
"abilityUse": {},
|
"abilityUse": {},
|
||||||
"tagTeam": {},
|
"tagTeam": {},
|
||||||
|
"groupRoll": {},
|
||||||
"systemMessage": {}
|
"systemMessage": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<div class="group-roll">
|
<div class="group-roll">
|
||||||
<header class="dialog-header">
|
<header class="dialog-header">
|
||||||
<h1>Group Roll</h1>
|
<h1>{{localize "DAGGERHEART.UI.Chat.groupRoll.title"}}</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<fieldset class="one-column">
|
<fieldset class="one-column">
|
||||||
<legend>Leader</legend>
|
<legend>{{localize "DAGGERHEART.UI.Chat.groupRoll.leader"}}</legend>
|
||||||
{{#unless leader.actor}}
|
{{#unless leader.actor}}
|
||||||
<input type="text" class="leader-change-input" name="leader"/>
|
<input type="text" class="leader-change-input" />
|
||||||
<div class="drag-area">
|
<div class="drag-area">
|
||||||
<span>Select a Leader</span>
|
<span>{{localize "DAGGERHEART.UI.Chat.groupRoll.selectLeader"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="actor-item">
|
<div class="actor-item">
|
||||||
|
|
@ -18,13 +18,13 @@
|
||||||
<div class="actor-check-info">
|
<div class="actor-check-info">
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.Trait.single"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.Trait.single"}}</label>
|
||||||
<select name="leader.trait" data-dtype="Number">
|
<select name="actorLeader.trait">
|
||||||
{{selectOptions traitList selected=leader.trait labelAttr="label" valueAttr="value" }}
|
{{selectOptions traitList selected=leader.trait labelAttr="label" valueAttr="id" localize=true }}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.difficulty"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.difficulty"}}</label>
|
||||||
<input type="number" name="leader.difficulty" value="{{leader.difficulty}}">
|
<input type="number" name="actorLeader.difficulty" value="{{leader.difficulty}}" data-dtype="Number">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -38,10 +38,12 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class="one-column">
|
<fieldset class="one-column">
|
||||||
<legend>Party Team</legend>
|
<legend>{{localize "DAGGERHEART.UI.Chat.groupRoll.partyTeam"}}</legend>
|
||||||
<input type="text" class="team-push-input" name="member"/>
|
<span class="tooltip-container" {{#if allSelected}}data-tooltip="{{localize "The whole party is selected"}}"{{/if}}>
|
||||||
|
<input type="text" class="team-push-input" {{disabled @root.allSelected}}/>
|
||||||
|
</span>
|
||||||
{{#if (gt this.members.length 0)}}
|
{{#if (gt this.members.length 0)}}
|
||||||
{{#each members as |member|}}
|
{{#each members as |member index|}}
|
||||||
<div class="actor-item">
|
<div class="actor-item">
|
||||||
<img src="{{member.actor.img}}" alt="{{member.actor.name}}">
|
<img src="{{member.actor.img}}" alt="{{member.actor.name}}">
|
||||||
<div class="actor-info">
|
<div class="actor-info">
|
||||||
|
|
@ -49,30 +51,32 @@
|
||||||
<div class="actor-check-info">
|
<div class="actor-check-info">
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.Trait.single"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.Trait.single"}}</label>
|
||||||
<select name="member.trait" data-dtype="Number">
|
<select name="{{concat "actorsMembers." index ".trait"}}">
|
||||||
{{selectOptions traitList selected=member.trait labelAttr="label" valueAttr="value" }}
|
{{selectOptions @root.traitList selected=member.trait labelAttr="label" valueAttr="id" localize=true }}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.difficulty"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.difficulty"}}</label>
|
||||||
<input type="number" name="member.difficulty" value="{{member.difficulty}}">
|
<input type="number" name="{{concat "actorsMembers." index ".difficulty"}}" value="{{member.difficulty}}" data-dtype="Number">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a data-action="removemember" data-member-uuid="{{member.actor.uuid}}">
|
<a data-action="removeMember" data-member-uuid="{{member.actor.uuid}}">
|
||||||
<i class="fa-solid fa-trash"></i>
|
<i class="fa-solid fa-trash"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="drag-area">
|
{{#unless allSelected}}
|
||||||
<span>Select a Member</span>
|
<div class="drag-area">
|
||||||
</div>
|
<span>{{localize "DAGGERHEART.UI.Chat.groupRoll.selectMember"}}</span>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<button class="submit-btn" data-action="roll">
|
<button class="submit-btn" data-action="roll" {{disabled @root.rollDisabled}}>
|
||||||
<i class="fa-solid fa-dice"></i>
|
<i class="fa-solid fa-dice"></i>
|
||||||
<span>Roll</span>
|
<span>{{localize "DAGGERHEART.General.roll"}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
120
templates/ui/chat/groupRoll.hbs
Normal file
120
templates/ui/chat/groupRoll.hbs
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
<div class="group-roll">
|
||||||
|
<div class="group-roll-section">
|
||||||
|
<h4 class="divider group-roll-header first">
|
||||||
|
<label>{{localize "DAGGERHEART.UI.Chat.groupRoll.leader"}}</label>
|
||||||
|
</h4>
|
||||||
|
<div class="group-roll-content {{#unless (isNullish system.leader.manualSuccess)}}finished{{/unless}}">
|
||||||
|
<div class="group-roll-member">
|
||||||
|
<div class="group-roll-data">
|
||||||
|
<img src="{{system.leader.actor.img}}" />
|
||||||
|
<div class="group-roll-label-container">
|
||||||
|
<div>{{system.leader.actor.name}}</div>
|
||||||
|
<div class="group-roll-label-inner-container">
|
||||||
|
{{#unless (isNullish system.leader.manualSuccess)}}
|
||||||
|
<label class="group-roll-modifier {{#unless system.leader.manualSuccess}}failure{{/unless}}">{{#if system.leader.manualSuccess}}{{localize "DAGGERHEART.GENERAL.hit.single"}}{{else}}{{localize "DAGGERHEART.GENERAL.miss.single"}}{{/if}}</label>
|
||||||
|
{{/unless}}
|
||||||
|
<div class="group-roll-trait">{{localize (concat "DAGGERHEART.CONFIG.Traits." system.leader.trait ".name")}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#unless system.leader.result}}
|
||||||
|
<div class="group-roll-rolling">
|
||||||
|
<a class="group-roll-button" data-path="leader"><img class="dice-icon normal" src="{{concat 'systems/daggerheart/assets/icons/dice/default/d20.svg'}}" alt=""></a>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="roll-results {{#unless (isNullish system.leader.manualSuccess)}}finished{{/unless}}">
|
||||||
|
{{#if (isNullish system.leader.manualSuccess)}}
|
||||||
|
<div class="reroll-result-container">
|
||||||
|
<span class="label">{{system.leader.result.total}}</span>
|
||||||
|
|
||||||
|
<a class="group-roll-success success" data-success="true" data-path="leader"><i class="fa-solid fa-check"></i></a>
|
||||||
|
<a class="group-roll-success failure" data-path="leader"><i class="fa-solid fa-xmark"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="group-roll-reroll" data-path="leader" data-tooltip="{{localize "DAGGERHEART.UI.Chat.groupRoll.rerollTooltip"}}">
|
||||||
|
<img class="dice-icon normal" src="{{concat 'systems/daggerheart/assets/icons/dice/default/d20.svg'}}" alt=""></img>
|
||||||
|
<i class="fa-solid fa-arrow-rotate-left reroll-icon"></i>
|
||||||
|
</a>
|
||||||
|
{{else}}
|
||||||
|
<div class="reroll-result-container">
|
||||||
|
{{#if system.leader.manualSuccess}}
|
||||||
|
<i class="fa-solid fa-check success"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-solid fa-xmark failure"></i>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
{{#unless (isNullish system.leader.manualSuccess)}}
|
||||||
|
<div class="group-roll-main-roll">
|
||||||
|
<h4 class="divider">
|
||||||
|
{{localize "DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle" ability=(localize (concat "DAGGERHEART.CONFIG.Traits." system.leader.trait ".name"))}}
|
||||||
|
</h4>
|
||||||
|
<span class="main-roll-content">
|
||||||
|
<span class="main-value">{{system.leader.result.total}}</span>
|
||||||
|
<span class="main-text">{{localize "DAGGERHEART.GENERAL.withThing" thing=system.leader.result.result.label}}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="group-roll-section">
|
||||||
|
<h4 class="divider group-roll-header">
|
||||||
|
<a class="group-roll-header-expand-section">
|
||||||
|
<i class="fa-solid fa-angle-down"></i>
|
||||||
|
<label>{{localize "DAGGERHEART.UI.Chat.groupRoll.team"}}</label>
|
||||||
|
<i class="fa-solid fa-angle-down"></i>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
<div class="group-roll-content">
|
||||||
|
{{#each system.members as |member index|}}
|
||||||
|
<div class="group-roll-member">
|
||||||
|
<div class="group-roll-data">
|
||||||
|
<img src="{{member.actor.img}}" />
|
||||||
|
<div class="group-roll-label-container">
|
||||||
|
<div>{{member.actor.name}}</div>
|
||||||
|
<div class="group-roll-label-inner-container">
|
||||||
|
{{#unless (isNullish member.manualSuccess)}}
|
||||||
|
<label class="group-roll-modifier {{#unless member.manualSuccess}}failure{{/unless}}">{{#if member.manualSuccess}}+1{{else}}-1{{/if}}</label>
|
||||||
|
{{/unless}}
|
||||||
|
<div class="group-roll-trait">{{localize (concat "DAGGERHEART.CONFIG.Traits." member.trait ".name")}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#unless member.result}}
|
||||||
|
<div class="group-roll-rolling">
|
||||||
|
<a class="group-roll-button" data-path="{{concat "members." index}}"><img class="dice-icon normal" src="{{concat 'systems/daggerheart/assets/icons/dice/default/d20.svg'}}" alt=""></a>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="roll-results">
|
||||||
|
{{#if (isNullish member.manualSuccess)}}
|
||||||
|
<div class="reroll-result-container">
|
||||||
|
<span class="label">{{member.result.total}}</span>
|
||||||
|
|
||||||
|
<a class="group-roll-success success" data-success="true" data-path="{{concat "members." index}}"><i class="fa-solid fa-check"></i></a>
|
||||||
|
<a class="group-roll-success failure" data-path="{{concat "members." index}}"><i class="fa-solid fa-xmark"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="group-roll-reroll" data-path="{{concat "members." index}}" data-tooltip="{{localize "DAGGERHEART.UI.Chat.groupRoll.rerollTooltip"}}">
|
||||||
|
<img class="dice-icon normal" src="{{concat 'systems/daggerheart/assets/icons/dice/default/d20.svg'}}" alt=""></img>
|
||||||
|
<i class="fa-solid fa-arrow-rotate-left reroll-icon"></i>
|
||||||
|
</a>
|
||||||
|
{{else}}
|
||||||
|
<div class="reroll-result-container">
|
||||||
|
<span class="label">{{member.result.total}}</span>
|
||||||
|
{{#if member.manualSuccess}}
|
||||||
|
<i class="fa-solid fa-check success"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-solid fa-xmark failure"></i>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue