mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-06 04:44:16 +02:00
Merged with main
This commit is contained in:
commit
a6e9f2cac2
10 changed files with 120 additions and 73 deletions
|
|
@ -1,5 +1,3 @@
|
||||||
import { slugify } from '../../helpers/utils.mjs';
|
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
export default class CompendiumBrowserSettings extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class CompendiumBrowserSettings extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
@ -55,9 +53,9 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
|
||||||
const { type, label, packageType, packageName: basePackageName, id: baseId } = pack.metadata;
|
const { type, label, packageType, packageName: basePackageName, id: baseId } = pack.metadata;
|
||||||
if (!CompendiumBrowserSettings.#browserPackTypes.includes(type)) return acc;
|
if (!CompendiumBrowserSettings.#browserPackTypes.includes(type)) return acc;
|
||||||
|
|
||||||
const id = slugify(baseId);
|
const id = baseId.slugify();
|
||||||
const isWorldPack = packageType === 'world';
|
const isWorldPack = packageType === 'world';
|
||||||
const packageName = isWorldPack ? 'world' : slugify(basePackageName);
|
const packageName = isWorldPack ? 'world' : basePackageName.slugify();
|
||||||
const sourceChecked =
|
const sourceChecked =
|
||||||
!excludedSourceData[packageName] ||
|
!excludedSourceData[packageName] ||
|
||||||
!excludedSourceData[packageName].excludedDocumentTypes.includes(type);
|
!excludedSourceData[packageName].excludedDocumentTypes.includes(type);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { DhHomebrew } from '../../data/settings/_module.mjs';
|
import { DhHomebrew } from '../../data/settings/_module.mjs';
|
||||||
import { Resource } from '../../data/settings/Homebrew.mjs';
|
import { Resource } from '../../data/settings/Homebrew.mjs';
|
||||||
import { slugify } from '../../helpers/utils.mjs';
|
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -403,12 +402,12 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
const domainName = button.form.elements.domainName.value;
|
const domainName = button.form.elements.domainName.value;
|
||||||
if (!domainName) return;
|
if (!domainName) return;
|
||||||
|
|
||||||
const newSlug = slugify(domainName);
|
const newSlug = domainName.slugify();
|
||||||
const existingDomains = [
|
const existingDomains = [
|
||||||
...Object.values(this.settings.domains),
|
...Object.values(this.settings.domains),
|
||||||
...Object.values(CONFIG.DH.DOMAIN.domains)
|
...Object.values(CONFIG.DH.DOMAIN.domains)
|
||||||
];
|
];
|
||||||
if (existingDomains.find(x => slugify(game.i18n.localize(x.label)) === newSlug)) {
|
if (existingDomains.find(x => x.id === newSlug)) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -529,7 +528,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
const identifier = button.form.elements.identifier.value;
|
const identifier = button.form.elements.identifier.value;
|
||||||
if (!identifier) return;
|
if (!identifier) return;
|
||||||
|
|
||||||
const sluggedIdentifier = slugify(identifier);
|
const sluggedIdentifier = identifier.slugify();
|
||||||
|
|
||||||
await this.settings.updateSource({
|
await this.settings.updateSource({
|
||||||
[`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier)
|
[`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,14 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
contextMenus: [
|
contextMenus: [
|
||||||
|
{
|
||||||
|
handler: CharacterSheet.#getCreationMainContextOptions,
|
||||||
|
selector: '.character-details [data-action="editDoc"]',
|
||||||
|
options: {
|
||||||
|
parentClassHooks: false,
|
||||||
|
fixed: true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
handler: CharacterSheet.#getDomainCardContextOptions,
|
handler: CharacterSheet.#getDomainCardContextOptions,
|
||||||
selector: '[data-item-uuid][data-type="domainCard"]',
|
selector: '[data-item-uuid][data-type="domainCard"]',
|
||||||
|
|
@ -319,6 +327,56 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
/* Context Menu */
|
/* Context Menu */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
static #getCreationMainContextOptions() {
|
||||||
|
/** Returns true if the item is managed by the level up wizard. Such items shouldn't allow things like manual removal */
|
||||||
|
function isItemWizardManaged(item) {
|
||||||
|
const actor = item?.actor;
|
||||||
|
if (!actor) return false;
|
||||||
|
|
||||||
|
// If levelup automation is off in general or for this character, all items are unmanaged
|
||||||
|
// This is disabled until we have proper granted feature removal, for now this feature is to correct errors
|
||||||
|
// const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||||
|
// if (!levelupAuto) return false;
|
||||||
|
|
||||||
|
// Core items aren't part of levelup data. TODO: add some way to flag a specific character as no auto leveling
|
||||||
|
const classPair = actor.system.class;
|
||||||
|
const coreItems = [actor.system.ancestry, actor.system.community, classPair?.value, classPair?.subclass];
|
||||||
|
if (coreItems.includes(item)) return true;
|
||||||
|
|
||||||
|
const levelups = Object.values(actor.system.levelData?.levelups) ?? [];
|
||||||
|
const uuid = item.uuid;
|
||||||
|
const sourceUuid = item._stats.compendiumSource; // on older characters this may be missing
|
||||||
|
return levelups.some(data => {
|
||||||
|
if (item.type === 'subclass') {
|
||||||
|
const selectedSubclasses = data.selections.map(s => s.secondaryData?.subclass).filter(s => !!s);
|
||||||
|
return sourceUuid
|
||||||
|
? selectedSubclasses.includes(sourceUuid)
|
||||||
|
: selectedSubclasses.length && item.system.isMulticlass;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchesCard = data.achievements.domainCards.some(i => i.itemUuid === uuid);
|
||||||
|
const matchesSelection = data.selections.some(s => s.itemUuid === uuid);
|
||||||
|
return matchesCard || matchesSelection;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'CONTROLS.CommonDelete',
|
||||||
|
icon: 'fa-solid fa-trash',
|
||||||
|
visible: target => {
|
||||||
|
const doc = getDocFromElementSync(target);
|
||||||
|
return doc?.isOwner && !isItemWizardManaged(doc);
|
||||||
|
},
|
||||||
|
callback: async (target, event) => {
|
||||||
|
const doc = await getDocFromElement(target);
|
||||||
|
if (event.shiftKey) return doc.delete();
|
||||||
|
else return doc.deleteDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the set of ContextMenu options for DomainCards.
|
* Get the set of ContextMenu options for DomainCards.
|
||||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
||||||
|
|
@ -718,7 +776,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
? {
|
? {
|
||||||
'system.linkedClass.uuid': {
|
'system.linkedClass.uuid': {
|
||||||
key: 'system.linkedClass.uuid',
|
key: 'system.linkedClass.uuid',
|
||||||
value: this.document.system.class.value._stats.compendiumSource
|
value: this.document.system.class.value?._stats.compendiumSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
|
||||||
|
|
@ -443,10 +443,12 @@ export const typeConfig = {
|
||||||
const list = [];
|
const list = [];
|
||||||
for (const item of items.filter(item => item.system.linkedClass)) {
|
for (const item of items.filter(item => item.system.linkedClass)) {
|
||||||
const linkedClass = await foundry.utils.fromUuid(item.system.linkedClass);
|
const linkedClass = await foundry.utils.fromUuid(item.system.linkedClass);
|
||||||
list.push({
|
if (linkedClass) {
|
||||||
value: linkedClass.uuid,
|
list.push({
|
||||||
label: linkedClass.name
|
value: linkedClass.uuid,
|
||||||
});
|
label: linkedClass.name
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.reduce((a, c) => {
|
return list.reduce((a, c) => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { slugify } from '../helpers/utils.mjs';
|
|
||||||
|
|
||||||
export default class CompendiumBrowserSettings extends foundry.abstract.DataModel {
|
export default class CompendiumBrowserSettings extends foundry.abstract.DataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
@ -26,11 +24,11 @@ export default class CompendiumBrowserSettings extends foundry.abstract.DataMode
|
||||||
const pack = game.packs.get(item.pack);
|
const pack = game.packs.get(item.pack);
|
||||||
if (!pack) return false;
|
if (!pack) return false;
|
||||||
|
|
||||||
const packageName = pack.metadata.packageType === 'world' ? 'world' : slugify(pack.metadata.packageName);
|
const packageName = pack.metadata.packageType === 'world' ? 'world' : pack.metadata.packageName.slugify();
|
||||||
const excludedSourceData = this.excludedSources[packageName];
|
const excludedSourceData = this.excludedSources[packageName];
|
||||||
if (excludedSourceData && excludedSourceData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
if (excludedSourceData && excludedSourceData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
||||||
|
|
||||||
const packName = slugify(item.pack);
|
const packName = item.pack.slugify();
|
||||||
const excludedPackData = this.excludedPacks[packName];
|
const excludedPackData = this.excludedPacks[packName];
|
||||||
if (excludedPackData && excludedPackData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
if (excludedPackData && excludedPackData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,38 +56,30 @@ export default class DHSubclass extends BaseDataItem {
|
||||||
if (allowed === false) return;
|
if (allowed === false) return;
|
||||||
|
|
||||||
if (this.actor?.type === 'character') {
|
if (this.actor?.type === 'character') {
|
||||||
const dataUuid = data.uuid ?? data._stats.compendiumSource ?? `Item.${data._id}`;
|
const { value: actorClass, subclass: existingSubclass } = this.actor.system.class;
|
||||||
if (this.actor.system.class.subclass) {
|
const { value: multiclass, subclass: existingMultisubclass } = this.actor.system.multiclass;
|
||||||
if (this.actor.system.multiclass.subclass) {
|
if (!actorClass && !multiclass) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent'));
|
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingClass', { localize: true });
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
const multiclass = this.actor.items.find(x => x.type === 'class' && x.system.isMulticlass);
|
if (existingSubclass && existingMultisubclass) {
|
||||||
if (!multiclass) {
|
ui.notifications.warn('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent', { localize: true });
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingMulticlass'));
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
if (existingSubclass && !multiclass) {
|
||||||
|
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingMulticlass', { localize: true });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (multiclass.system.subclasses.every(x => x.uuid !== dataUuid)) {
|
const match = [multiclass, actorClass].find(
|
||||||
ui.notifications.error(
|
c => c && (c._stats.compendiumSource ?? c.uuid) === this.linkedClass
|
||||||
game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInMulticlass')
|
);
|
||||||
);
|
if (!match) {
|
||||||
return false;
|
const key = multiclass ? 'subclassNotInMulticlass' : 'subclassNotInClass';
|
||||||
}
|
ui.notifications.warn(`DAGGERHEART.UI.Notifications.${key}`, { localize: true });
|
||||||
|
return false;
|
||||||
await this.updateSource({ isMulticlass: true });
|
} else if (match.system.isMulticlass) {
|
||||||
}
|
await this.updateSource({ isMulticlass: true });
|
||||||
} else {
|
|
||||||
const actorClass = this.actor.items.find(x => x.type === 'class' && !x.system.isMulticlass);
|
|
||||||
if (!actorClass) {
|
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClass'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((await actorClass.system.fetchSubclasses()).every(x => x.uuid !== dataUuid)) {
|
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInClass'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,10 +153,13 @@ export default class DhpActor extends Actor {
|
||||||
async updateLevel(newLevel) {
|
async updateLevel(newLevel) {
|
||||||
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
|
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
|
||||||
|
|
||||||
|
const tiers = Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers);
|
||||||
|
const maxLevel = tiers.reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
|
||||||
|
const multiclassMinLevel = Math.min(
|
||||||
|
maxLevel,
|
||||||
|
...tiers.filter(t => t.options.multiclass).map(t => t.levels.start)
|
||||||
|
);
|
||||||
if (newLevel > this.system.levelData.level.current) {
|
if (newLevel > this.system.levelData.level.current) {
|
||||||
const maxLevel = Object.values(
|
|
||||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers
|
|
||||||
).reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
|
|
||||||
if (newLevel > maxLevel) {
|
if (newLevel > maxLevel) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.tooHighLevel'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.tooHighLevel'));
|
||||||
}
|
}
|
||||||
|
|
@ -231,18 +234,19 @@ export default class DhpActor extends Actor {
|
||||||
this.system.multiclass.subclass.update({ 'system.featureState': subclassFeatureState.multiclass });
|
this.system.multiclass.subclass.update({ 'system.featureState': subclassFeatureState.multiclass });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (multiclass) {
|
// Remove multiclass if we're removing a multiclass feature or if we're below the multiclass minimum level
|
||||||
const multiclassItem = this.items.find(x => x.uuid === multiclass.itemUuid);
|
// Multclasses cannot be manually removed on the sheet, so this allows recovering in the case of errors
|
||||||
const multiclassFeatures = this.items.filter(
|
if (multiclass || newLevel < multiclassMinLevel) {
|
||||||
x => x.system.originItemType === 'class' && x.system.multiclassOrigin
|
const multiclassItems = this.items.filter(
|
||||||
);
|
x =>
|
||||||
const subclassFeatures = this.items.filter(
|
x.uuid === multiclass?.itemUuid ||
|
||||||
x => x.system.originItemType === 'subclass' && x.system.multiclassOrigin
|
x.system.isMulticlass ||
|
||||||
|
(['class', 'subclass'].includes(x.system.originItemType) && x.system.multiclassOrigin)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.deleteEmbeddedDocuments(
|
this.deleteEmbeddedDocuments(
|
||||||
'Item',
|
'Item',
|
||||||
[multiclassItem, ...multiclassFeatures, ...subclassFeatures].map(x => x.id)
|
multiclassItems.map(x => x.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.update({
|
this.update({
|
||||||
|
|
@ -281,6 +285,7 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
async levelUp(levelupData) {
|
async levelUp(levelupData) {
|
||||||
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||||
|
const getStatsWithSource = document => ({ ...(document._stats ?? {}), compendiumSource: document.uuid });
|
||||||
|
|
||||||
const levelups = {};
|
const levelups = {};
|
||||||
for (var levelKey of Object.keys(levelupData)) {
|
for (var levelKey of Object.keys(levelupData)) {
|
||||||
|
|
@ -393,8 +398,8 @@ export default class DhpActor extends Actor {
|
||||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||||
{
|
{
|
||||||
...multiclassData,
|
...multiclassData,
|
||||||
uuid: multiclassItem.uuid,
|
uuid: multiclassItem.uuid, // todo: replace with setting an id and using keepId
|
||||||
_stats: multiclassItem._stats,
|
_stats: getStatsWithSource(multiclassItem),
|
||||||
system: {
|
system: {
|
||||||
...multiclassData.system,
|
...multiclassData.system,
|
||||||
features: multiclassData.system.features.filter(x => x.type !== 'hope'),
|
features: multiclassData.system.features.filter(x => x.type !== 'hope'),
|
||||||
|
|
@ -407,8 +412,8 @@ export default class DhpActor extends Actor {
|
||||||
await this.createEmbeddedDocuments('Item', [
|
await this.createEmbeddedDocuments('Item', [
|
||||||
{
|
{
|
||||||
...subclassData,
|
...subclassData,
|
||||||
uuid: subclassItem.uuid,
|
uuid: subclassItem.uuid, // todo: replace with setting an id and using keepId
|
||||||
_stats: subclassItem._stats,
|
_stats: getStatsWithSource(subclassItem),
|
||||||
system: {
|
system: {
|
||||||
...subclassData.system,
|
...subclassData.system,
|
||||||
isMulticlass: true
|
isMulticlass: true
|
||||||
|
|
@ -428,8 +433,8 @@ export default class DhpActor extends Actor {
|
||||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||||
{
|
{
|
||||||
...cardData,
|
...cardData,
|
||||||
uuid: cardItem.uuid,
|
uuid: cardItem.uuid, // todo: replace with setting an id and using keepId
|
||||||
_stats: cardItem._stats,
|
_stats: getStatsWithSource(cardItem),
|
||||||
system: {
|
system: {
|
||||||
...cardData.system,
|
...cardData.system,
|
||||||
inVault: true
|
inVault: true
|
||||||
|
|
@ -450,8 +455,7 @@ export default class DhpActor extends Actor {
|
||||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||||
{
|
{
|
||||||
...cardData,
|
...cardData,
|
||||||
uuid: cardItem.uuid,
|
_stats: getStatsWithSource(cardItem),
|
||||||
_stats: cardItem._stats,
|
|
||||||
system: {
|
system: {
|
||||||
...cardData.system,
|
...cardData.system,
|
||||||
inVault: true
|
inVault: true
|
||||||
|
|
|
||||||
|
|
@ -452,10 +452,6 @@ export async function createEmbeddedItemsWithEffects(actor, baseData) {
|
||||||
await actor.createEmbeddedDocuments('Item', effectData);
|
await actor.createEmbeddedDocuments('Item', effectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const slugify = name => {
|
|
||||||
return name.toLowerCase().replaceAll(' ', '-').replaceAll('.', '_');
|
|
||||||
};
|
|
||||||
|
|
||||||
export function shuffleArray(array) {
|
export function shuffleArray(array) {
|
||||||
let currentIndex = array.length;
|
let currentIndex = array.length;
|
||||||
while (currentIndex != 0) {
|
while (currentIndex != 0) {
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if document.system.multiclass.value}}
|
{{#if (or document.system.multiclass.value document.system.multiclass.subclass)}}
|
||||||
<div class="multiclass">
|
<div class="multiclass">
|
||||||
{{#if document.system.multiclass.value}}
|
{{#if document.system.multiclass.value}}
|
||||||
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>
|
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
{{#if roll.isCritical}}
|
{{#if roll.isCritical}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.criticalShort"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.criticalShort"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if (and roll.dHope (not (eq roll.type "reaction")))}}
|
{{#if (and roll.dHope (not (eq roll.options.roll.type "reaction")))}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue