mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 11:41:08 +01:00
.
This commit is contained in:
parent
4954e41b02
commit
aec5c06da7
14 changed files with 156 additions and 46 deletions
|
|
@ -2032,6 +2032,7 @@
|
||||||
"basics": "Basics",
|
"basics": "Basics",
|
||||||
"bonus": "Bonus",
|
"bonus": "Bonus",
|
||||||
"burden": "Burden",
|
"burden": "Burden",
|
||||||
|
"condition": "Condition",
|
||||||
"continue": "Continue",
|
"continue": "Continue",
|
||||||
"criticalSuccess": "Critical Success",
|
"criticalSuccess": "Critical Success",
|
||||||
"criticalShort": "Critical",
|
"criticalShort": "Critical",
|
||||||
|
|
@ -2586,7 +2587,8 @@
|
||||||
"increasingLoop": "Increasing Looping"
|
"increasingLoop": "Increasing Looping"
|
||||||
},
|
},
|
||||||
"EffectsDisplay": {
|
"EffectsDisplay": {
|
||||||
"title": ""
|
"removeThing": "[Right Click] Remove {thing}",
|
||||||
|
"appliedBy": "Applied By: {by}"
|
||||||
},
|
},
|
||||||
"ItemBrowser": {
|
"ItemBrowser": {
|
||||||
"title": "Daggerheart Compendium Browser",
|
"title": "Daggerheart Compendium Browser",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
classes: ['daggerheart'],
|
classes: ['daggerheart'],
|
||||||
actions: {
|
actions: {
|
||||||
|
effect: { handler: DHTokenHUD.#onToggleEffect, buttons: [0, 2] },
|
||||||
combat: DHTokenHUD.#onToggleCombat,
|
combat: DHTokenHUD.#onToggleCombat,
|
||||||
togglePartyTokens: DHTokenHUD.#togglePartyTokens
|
togglePartyTokens: DHTokenHUD.#togglePartyTokens
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +22,6 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||||
|
|
||||||
async _prepareContext(options) {
|
async _prepareContext(options) {
|
||||||
const context = await super._prepareContext(options);
|
const context = await super._prepareContext(options);
|
||||||
|
|
||||||
context.partyOnCanvas =
|
context.partyOnCanvas =
|
||||||
this.actor.type === 'party' &&
|
this.actor.type === 'party' &&
|
||||||
this.actor.system.partyMembers.some(member => member.getActiveTokens().length > 0);
|
this.actor.system.partyMembers.some(member => member.getActiveTokens().length > 0);
|
||||||
|
|
@ -31,6 +31,7 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||||
context.canToggleCombat = DHTokenHUD.#nonCombatTypes.includes(this.actor.type)
|
context.canToggleCombat = DHTokenHUD.#nonCombatTypes.includes(this.actor.type)
|
||||||
? false
|
? false
|
||||||
: context.canToggleCombat;
|
: context.canToggleCombat;
|
||||||
|
|
||||||
context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => {
|
context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => {
|
||||||
const effect = context.statusEffects[key];
|
const effect = context.statusEffects[key];
|
||||||
if (effect.systemEffect) {
|
if (effect.systemEffect) {
|
||||||
|
|
@ -193,16 +194,18 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the status of effects which are active for the token actor
|
// Update the status of effects which are active for the token actor
|
||||||
const activeEffects = this.actor?.effects || [];
|
const activeEffects = this.actor?.getActiveEffects() || [];
|
||||||
for (const effect of activeEffects) {
|
for (const effect of activeEffects) {
|
||||||
for (const statusId of effect.statuses) {
|
for (const statusId of effect.statuses) {
|
||||||
const status = choices[statusId];
|
const status = choices[statusId];
|
||||||
|
status.instances = 1 + (status.instances ?? 0);
|
||||||
|
status.locked = status.locked || effect.condition || status.instances > 1;
|
||||||
if (!status) continue;
|
if (!status) continue;
|
||||||
if (status._id) {
|
if (status._id) {
|
||||||
if (status._id !== effect.id) continue;
|
if (status._id !== effect.id) continue;
|
||||||
}
|
}
|
||||||
status.isActive = true;
|
status.isActive = true;
|
||||||
if (effect.getFlag('core', 'overlay')) status.isOverlay = true;
|
if (effect.getFlag?.('core', 'overlay')) status.isOverlay = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,4 +215,17 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
|
||||||
}
|
}
|
||||||
return choices;
|
return choices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async #onToggleEffect(event, target) {
|
||||||
|
if (!this.actor) {
|
||||||
|
ui.notifications.warn('HUD.WarningEffectNoActor', { localize: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusId = target.dataset.statusId;
|
||||||
|
await this.actor.toggleStatusEffect(statusId, {
|
||||||
|
active: !target.classList.contains('active'),
|
||||||
|
overlay: event.button === 2
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { RefreshType } from '../../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,7 +50,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
|
||||||
super._attachPartListeners(partId, htmlElement, options);
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
|
|
||||||
if (this.element) {
|
if (this.element) {
|
||||||
this.element.querySelectorAll('.effect-container').forEach(element => {
|
this.element.querySelectorAll('.effect-container a').forEach(element => {
|
||||||
element.addEventListener('contextmenu', this.removeEffect.bind(this));
|
element.addEventListener('contextmenu', this.removeEffect.bind(this));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +72,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
|
||||||
? game.user.character
|
? game.user.character
|
||||||
: null
|
: null
|
||||||
: canvas.tokens.controlled[0].actor;
|
: canvas.tokens.controlled[0].actor;
|
||||||
return actor?.effects ? Array.from(actor.effects) : [];
|
return actor?.getActiveEffects() ?? [];
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleHidden(token, focused) {
|
toggleHidden(token, focused) {
|
||||||
|
|
@ -92,6 +94,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
|
||||||
|
|
||||||
setupHooks() {
|
setupHooks() {
|
||||||
Hooks.on('controlToken', this.toggleHidden.bind(this));
|
Hooks.on('controlToken', this.toggleHidden.bind(this));
|
||||||
|
Hooks.on(RefreshType.EffectsDisplay, this.toggleHidden.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(options) {
|
async close(options) {
|
||||||
|
|
@ -99,6 +102,7 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica
|
||||||
if (options.closeKey) return;
|
if (options.closeKey) return;
|
||||||
|
|
||||||
Hooks.off('controlToken', this.toggleHidden);
|
Hooks.off('controlToken', this.toggleHidden);
|
||||||
|
Hooks.off(RefreshType.EffectsDisplay, this.toggleHidden);
|
||||||
return super.close(options);
|
return super.close(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,29 +10,7 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
|
||||||
this.effects.overlay = null;
|
this.effects.overlay = null;
|
||||||
|
|
||||||
// Categorize effects
|
// Categorize effects
|
||||||
const statusMap = new Map(foundry.CONFIG.statusEffects.map(status => [status.id, status]));
|
const activeEffects = this.actor?.getActiveEffects() ?? [];
|
||||||
const activeEffects = (this.actor ? this.actor.effects.filter(x => !x.disabled) : []).reduce((acc, effect) => {
|
|
||||||
acc.push(effect);
|
|
||||||
|
|
||||||
const currentStatusActiveEffects = acc.filter(
|
|
||||||
x => x.statuses.size === 1 && x.name === game.i18n.localize(statusMap.get(x.statuses.first())?.name)
|
|
||||||
);
|
|
||||||
for (var status of effect.statuses) {
|
|
||||||
if (!currentStatusActiveEffects.find(x => x.statuses.has(status))) {
|
|
||||||
const statusData = statusMap.get(status);
|
|
||||||
if (statusData) {
|
|
||||||
acc.push({
|
|
||||||
name: game.i18n.localize(statusData.name),
|
|
||||||
statuses: [status],
|
|
||||||
img: statusData.icon ?? statusData.img,
|
|
||||||
tint: effect.tint
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, []);
|
|
||||||
const overlayEffect = activeEffects.findLast(e => e.img && e.getFlag?.('core', 'overlay'));
|
const overlayEffect = activeEffects.findLast(e => e.img && e.getFlag?.('core', 'overlay'));
|
||||||
|
|
||||||
// Draw effects
|
// Draw effects
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { itemAbleRollParse } from '../helpers/utils.mjs';
|
import { itemAbleRollParse } from '../helpers/utils.mjs';
|
||||||
|
import { RefreshType, socketEvent } from '../systemRegistration/socket.mjs';
|
||||||
|
|
||||||
export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
@ -85,6 +86,20 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
await super._preCreate(data, options, user);
|
await super._preCreate(data, options, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
_onCreate(data, options, userId) {
|
||||||
|
super._onCreate(data, options, userId);
|
||||||
|
|
||||||
|
Hooks.callAll(RefreshType.EffectsDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritdoc */
|
||||||
|
_onDelete(data, options, userId) {
|
||||||
|
super._onDelete(data, options, userId);
|
||||||
|
|
||||||
|
Hooks.callAll(RefreshType.EffectsDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Methods */
|
/* Methods */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -834,4 +834,37 @@ export default class DhpActor extends Actor {
|
||||||
if (this.system._getTags) tags.push(...this.system._getTags());
|
if (this.system._getTags) tags.push(...this.system._getTags());
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get active effects */
|
||||||
|
getActiveEffects() {
|
||||||
|
const statusMap = new Map(foundry.CONFIG.statusEffects.map(status => [status.id, status]));
|
||||||
|
return this.effects
|
||||||
|
.filter(x => !x.disabled)
|
||||||
|
.reduce((acc, effect) => {
|
||||||
|
acc.push(effect);
|
||||||
|
|
||||||
|
const currentStatusActiveEffects = acc.filter(
|
||||||
|
x => x.statuses.size === 1 && x.name === game.i18n.localize(statusMap.get(x.statuses.first()).name)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (var status of effect.statuses) {
|
||||||
|
if (!currentStatusActiveEffects.find(x => x.statuses.has(status))) {
|
||||||
|
const statusData = statusMap.get(status);
|
||||||
|
if (statusData) {
|
||||||
|
acc.push({
|
||||||
|
condition: status,
|
||||||
|
appliedBy: game.i18n.localize(effect.name),
|
||||||
|
name: game.i18n.localize(statusData.name),
|
||||||
|
statuses: new Set([status]),
|
||||||
|
img: statusData.icon ?? statusData.img,
|
||||||
|
description: game.i18n.localize(statusData.description),
|
||||||
|
tint: effect.tint
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,26 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
||||||
let html = options.html;
|
let html = options.html;
|
||||||
if (element.dataset.tooltip === '#effect-display#') {
|
if (element.dataset.tooltip === '#effect-display#') {
|
||||||
this.#bordered = true;
|
this.#bordered = true;
|
||||||
const effect = await foundry.utils.fromUuid(element.dataset.uuid);
|
let effect = {};
|
||||||
|
if (element.dataset.uuid) {
|
||||||
|
const effectData = (await foundry.utils.fromUuid(element.dataset.uuid)).toObject();
|
||||||
|
effect = {
|
||||||
|
...effectData,
|
||||||
|
name: game.i18n.localize(effectData.name),
|
||||||
|
description: game.i18n.localize(effectData.description ?? effectData.parent.system.description)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const conditions = CONFIG.DH.GENERAL.conditions();
|
||||||
|
const condition = conditions[element.dataset.condition];
|
||||||
|
effect = {
|
||||||
|
...condition,
|
||||||
|
name: game.i18n.localize(condition.name),
|
||||||
|
description: game.i18n.localize(condition.description),
|
||||||
|
appliedBy: element.dataset.appliedBy,
|
||||||
|
isLockedCondition: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
html = await foundry.applications.handlebars.renderTemplate(
|
html = await foundry.applications.handlebars.renderTemplate(
|
||||||
`systems/daggerheart/templates/ui/tooltip/effect-display.hbs`,
|
`systems/daggerheart/templates/ui/tooltip/effect-display.hbs`,
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ export const GMUpdateEvent = {
|
||||||
|
|
||||||
export const RefreshType = {
|
export const RefreshType = {
|
||||||
Countdown: 'DhCoundownRefresh',
|
Countdown: 'DhCoundownRefresh',
|
||||||
TagTeamRoll: 'DhTagTeamRollRefresh'
|
TagTeamRoll: 'DhTagTeamRollRefresh',
|
||||||
|
EffectsDisplay: 'DhEffectsDisplayRefresh'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const registerSocketHooks = () => {
|
export const registerSocketHooks = () => {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,15 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.effect-locked {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 2px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: @golden;
|
||||||
|
filter: drop-shadow(0 0 3px black);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 68px;
|
width: 68px;
|
||||||
max-height: 300px;
|
max-height: 600px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
border: 0;
|
||||||
|
|
||||||
.window-content {
|
.window-content {
|
||||||
> div {
|
> div {
|
||||||
|
|
@ -14,13 +15,20 @@
|
||||||
.effects-display-container {
|
.effects-display-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 4px;
|
||||||
|
|
||||||
.effect-container {
|
.effect-container {
|
||||||
cursor: pointer;
|
position: relative;
|
||||||
|
pointer-events: all;
|
||||||
|
border: 2px solid light-dark(@dark-blue, @golden);
|
||||||
|
|
||||||
img {
|
.effect-locked {
|
||||||
pointer-events: all;
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
|
right: 4px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: @golden;
|
||||||
|
filter: drop-shadow(0 0 3px black);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,14 @@
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,18 +46,22 @@
|
||||||
</button>
|
</button>
|
||||||
<div class="palette status-effects" data-palette="effects">
|
<div class="palette status-effects" data-palette="effects">
|
||||||
{{#each systemStatusEffects as |status|}}
|
{{#each systemStatusEffects as |status|}}
|
||||||
<div class="effect-control-container" {{#if status.disabled}}data-tooltip="{{localize "DAGGERHEART.UI.Tooltip.immune"}}"{{/if}}>
|
<div class="effect-control-container" {{#if status.disabled}}data-tooltip="{{localize "DAGGERHEART.UI.Tooltip.immune"}}"{{else if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
||||||
<img class="effect-control {{status.cssClass}} {{#if status.disabled}}disabled{{/if}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
<img class="effect-control {{status.cssClass}} {{#if (or status.disabled status.locked)}}disabled{{/if}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}">
|
||||||
{{#if status.disabled}}
|
{{#if status.disabled}}
|
||||||
<span class="effect-control-disabled-marker">/</span>
|
<span class="effect-control-disabled-marker">/</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if status.locked}}<i class="effect-locked fa-solid fa-lock"></i>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#if genericStatusEffects}}
|
{{#if genericStatusEffects}}
|
||||||
<label class="palette-category-title">{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.genericEffects"}}</label>
|
<div class="effect-control-container">>
|
||||||
{{#each genericStatusEffects as |status|}}
|
<label class="palette-category-title">{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.genericEffects"}}</label>
|
||||||
<img class="effect-control {{status.cssClass}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
{{#each genericStatusEffects as |status|}}
|
||||||
{{/each}}
|
<img class="effect-control {{status.cssClass}}" src="{{status.src}}" data-action="effect" data-status-id="{{status.id}}" {{#if status.title}}data-tooltip-text="{{status.title}}"{{/if}}>
|
||||||
|
{{/each}}
|
||||||
|
{{#if status.locked}}<i class="effect-locked fa-solid fa-lock"></i>{{/if}}
|
||||||
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="effects-display-container">
|
<div class="effects-display-container">
|
||||||
{{#each effects as | effect |}}
|
{{#each effects as | effect |}}
|
||||||
<div class="effect-container" data-tooltip="#effect-display#" data-uuid="{{effect.uuid}}" id="{{effect.id}}">
|
<span class="effect-container {{#if effect.condition}}disabled{{/if}}" data-tooltip="#effect-display#" id="{{effect.id}}"
|
||||||
<img src="{{effect.img}}" />
|
data-applied-by="{{effect.appliedBy}}" {{#if effect.condition}}data-condition="{{effect.condition}}"{{else}}data-uuid="{{effect.uuid}}"{{/if}}
|
||||||
</div>
|
>
|
||||||
|
<a {{#if effect.condition}}disabled{{/if}}>
|
||||||
|
<img src="{{effect.img}}" />
|
||||||
|
</a>
|
||||||
|
{{#if effect.condition}}<i class="effect-locked fa-solid fa-lock"></i>{{/if}}
|
||||||
|
</span>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
<div class="daggerheart dh-style tooltip">
|
<div class="daggerheart dh-style tooltip">
|
||||||
<div class="tooltip-header">
|
<div class="tooltip-header">
|
||||||
<h3>{{effect.name}}</h3>
|
<h3>{{effect.name}}</h3>
|
||||||
<div class="helper">{{localize "[Right Click] Remove Effect"}}</div>
|
<div class="helper">
|
||||||
|
{{#unless effect.isLockedCondition}}
|
||||||
|
{{localize "DAGGERHEART.UI.EffectsDisplay.removeThing" thing=(localize "DAGGERHEART.GENERAL.Effect.single")}}
|
||||||
|
{{/unless}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{#if effect.description}}{{{effect.description}}}{{else}}{{{effect.parent.system.description}}}{{/if}}
|
{{#if effect.description}}{{{effect.description}}}{{else}}{{{effect.parent.system.description}}}{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
{{#if effect.appliedBy}}
|
||||||
|
<footer class="tooltip-footer">{{localize "DAGGERHEART.UI.EffectsDisplay.appliedBy" by=effect.appliedBy}}</footer>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue