FEAT: add _gettags and _getLabels to armor, domainCard, weapons and ActiveEffect

This commit is contained in:
Joaquin Pereyra 2025-07-29 22:30:49 -03:00
parent faa412bfc1
commit e5c617d62e
6 changed files with 140 additions and 133 deletions

View file

@ -115,4 +115,26 @@ export default class DHArmor extends AttachableItem {
} }
} }
} }
/**
* Generates a list of localized tags based on this item's type-specific properties.
* @returns {string[]} An array of localized tag strings.
*/
_getTags() {
const tags = [
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`,
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseThresholds.base')}: ${this.baseThresholds.major} / ${this.baseThresholds.severe}`
];
return tags;
}
/**
* Generate a localized label array for this item subtype.
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
*/
_getLabels() {
const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`];
return labels;
}
} }

View file

@ -1,5 +1,4 @@
import BaseDataItem from './base.mjs'; import BaseDataItem from './base.mjs';
import { ActionField } from '../fields/actionField.mjs';
export default class DHDomainCard extends BaseDataItem { export default class DHDomainCard extends BaseDataItem {
/** @inheritDoc */ /** @inheritDoc */
@ -34,6 +33,7 @@ export default class DHDomainCard extends BaseDataItem {
}; };
} }
/**@inheritdoc */
async _preCreate(data, options, user) { async _preCreate(data, options, user) {
const allowed = await super._preCreate(data, options, user); const allowed = await super._preCreate(data, options, user);
if (allowed === false) return; if (allowed === false) return;
@ -55,4 +55,35 @@ export default class DHDomainCard extends BaseDataItem {
} }
} }
} }
/**
* Generates a list of localized tags based on this item's type-specific properties.
* @returns {string[]} An array of localized tag strings.
*/
_getTags() {
const tags = [
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
game.i18n.localize(`DAGGERHEART.GENERAL.Domain.${this.domain}.label`),
`${game.i18n.localize('DAGGERHEART.ITEMS.DomainCard.recallCost')}: ${this.recallCost}`
];
return tags;
}
/**
* Generate a localized label array for this item subtype.
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
*/
_getLabels() {
const labels = [
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
game.i18n.localize(`DAGGERHEART.GENERAL.Domain.${this.domain}.label`),
{
value: `${this.recallCost}`, //converts the number to a string
icons: ['fa-bolt']
}
];
return labels;
}
} }

View file

@ -167,15 +167,13 @@ export default class DHWeapon extends AttachableItem {
* Generates a list of localized tags based on this item's type-specific properties. * Generates a list of localized tags based on this item's type-specific properties.
* @returns {string[]} An array of localized tag strings. * @returns {string[]} An array of localized tag strings.
*/ */
getTags() { _getTags() {
const { attack, burden } = this; const { attack, burden } = this;
const tags = []; const tags = [
game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${attack.roll.trait}.name`),
const traitTag = game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${attack.roll.trait}.name`); game.i18n.localize(`DAGGERHEART.CONFIG.Range.${attack.range}.name`),
const rangeTag = game.i18n.localize(`DAGGERHEART.CONFIG.Range.${attack.range}.name`); game.i18n.localize(`DAGGERHEART.CONFIG.Burden.${burden}`)
const burdenTag = game.i18n.localize(`DAGGERHEART.CONFIG.Burden.${burden}`); ];
tags.push(traitTag, rangeTag, burdenTag);
for (const { value, type } of attack.damage.parts) { for (const { value, type } of attack.damage.parts) {
const parts = [value.dice]; const parts = [value.dice];
@ -184,14 +182,13 @@ export default class DHWeapon extends AttachableItem {
if (type.size > 0) { if (type.size > 0) {
const typeTags = Array.from(type) const typeTags = Array.from(type)
.map(t => game.i18n.localize(`DAGGERHEART.CONFIG.DamageType.${t}.abbreviation`)) .map(t => game.i18n.localize(`DAGGERHEART.CONFIG.DamageType.${t}.abbreviation`))
.join(" | "); .join(' | ');
parts.push(` (${typeTags})`); // Add a space in front and put it inside a (). parts.push(` (${typeTags})`); // Add a space in front and put it inside a ().
} }
tags.push(parts.join("")); tags.push(parts.join(''));
} }
return tags; return tags;
} }
@ -199,12 +196,13 @@ export default class DHWeapon extends AttachableItem {
* Generate a localized label array for this item subtype. * Generate a localized label array for this item subtype.
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects. * @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
*/ */
getLabels() { _getLabels() {
const labels = [];
const { roll, range, damage } = this.attack; const { roll, range, damage } = this.attack;
labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`));
labels.push(game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`)); const labels = [
game.i18n.localize(`DAGGERHEART.CONFIG.Traits.${roll.trait}.short`),
game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.short`)
];
for (const { value, type } of damage.parts) { for (const { value, type } of damage.parts) {
const str = [value.dice]; const str = [value.dice];
@ -214,7 +212,7 @@ export default class DHWeapon extends AttachableItem {
.map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon) .map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon)
.filter(Boolean); .filter(Boolean);
const labelValue = str.join(""); const labelValue = str.join('');
if (icons.length === 0) { if (icons.length === 0) {
labels.push(labelValue); labels.push(labelValue);
} else { } else {
@ -224,7 +222,4 @@ export default class DHWeapon extends AttachableItem {
return labels; return labels;
} }
} }

View file

@ -1,6 +1,12 @@
import { itemAbleRollParse } from '../helpers/utils.mjs'; import { itemAbleRollParse } from '../helpers/utils.mjs';
export default class DhActiveEffect extends ActiveEffect { export default class DhActiveEffect extends foundry.documents.ActiveEffect {
/* -------------------------------------------- */
/* Properties */
/* -------------------------------------------- */
/**@override */
get isSuppressed() { get isSuppressed() {
// If this is a copied effect from an attachment, never suppress it // If this is a copied effect from an attachment, never suppress it
// (These effects have attachmentSource metadata) // (These effects have attachmentSource metadata)
@ -41,14 +47,11 @@ export default class DhActiveEffect extends ActiveEffect {
}); });
} }
get localizedStatuses() { /* -------------------------------------------- */
const statusMap = new Map(foundry.CONFIG.statusEffects.map(status => [status.id, status.name])); /* Event Handlers */
return this.statuses.map(x => ({ /* -------------------------------------------- */
key: x,
name: game.i18n.localize(statusMap.get(x))
}));
}
/**@inheritdoc*/
async _preCreate(data, options, user) { async _preCreate(data, options, user) {
const update = {}; const update = {};
if (!data.img) { if (!data.img) {
@ -62,13 +65,22 @@ export default class DhActiveEffect extends ActiveEffect {
await super._preCreate(data, options, user); await super._preCreate(data, options, user);
} }
/* -------------------------------------------- */
/* Methods */
/* -------------------------------------------- */
/**@inheritdoc*/
static applyField(model, change, field) { static applyField(model, change, field) {
const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent)); const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent));
change.value = evalValue ?? change.value; change.value = evalValue ?? change.value;
super.applyField(model, change, field); super.applyField(model, change, field);
} }
/* Altered Foundry safeEval to allow non-numeric returns */ /**
* Altered Foundry safeEval to allow non-numeric return
* @param {string} expression
* @returns
*/
static effectSafeEval(expression) { static effectSafeEval(expression) {
let result; let result;
try { try {
@ -82,6 +94,24 @@ export default class DhActiveEffect extends ActiveEffect {
return result; return result;
} }
/**
* Generates a list of localized tags based on this item's type-specific properties.
* @returns {string[]} An array of localized tag strings.
*/
_getTags() {
const tags = [
`${game.i18n.localize(this.parent.system.metadata.label)}: ${this.parent.name}`,
game.i18n.localize(this.isTemporary ? 'DAGGERHEART.EFFECTS.Duration.temporary' : 'DAGGERHEART.EFFECTS.Duration.passive')
];
for (const statusId of this.statuses) {
const status = CONFIG.statusEffects.find(s => s.id === statusId);
tags.push(game.i18n.localize(status.name));
}
return tags;
}
async toChat(origin) { async toChat(origin) {
const cls = getDocumentClass('ChatMessage'); const cls = getDocumentClass('ChatMessage');
const systemData = { const systemData = {

View file

@ -237,7 +237,7 @@ export const updateActorTokens = async (actor, update) => {
* Retrieves a Foundry document associated with the nearest ancestor element * Retrieves a Foundry document associated with the nearest ancestor element
* that has a `data-item-uuid` attribute. * that has a `data-item-uuid` attribute.
* @param {HTMLElement} element - The DOM element to start the search from. * @param {HTMLElement} element - The DOM element to start the search from.
* @returns {foundry.abstract.Document|null} The resolved document, or null if not found or invalid. * @returns {Promise<foundry.abstract.Document|null>} The resolved document, or null if not found or invalid.
*/ */
export async function getDocFromElement(element) { export async function getDocFromElement(element) {
const target = element.closest('[data-item-uuid]'); const target = element.closest('[data-item-uuid]');

View file

@ -15,8 +15,8 @@ Parameters:
- showActions {boolean} : If true show feature's actions. - showActions {boolean} : If true show feature's actions.
--}} --}}
<li class="inventory-item" data-item-id="{{item.id}}" {{#if (or (eq type 'action' ) (eq type 'attack'))}} data-action-id="{{item.id}}" {{/if}} <li class="inventory-item" data-item-id="{{item.id}}" {{#if (or (eq type 'action' ) (eq type 'attack' ))}}
data-item-uuid="{{item.uuid}}" data-type="{{type}}" draggable="true"> data-action-id="{{item.id}}" {{/if}} data-item-uuid="{{item.uuid}}" data-type="{{type}}" draggable="true">
<div class="inventory-item-header" {{#unless noExtensible}}data-action="toggleExtended" {{/unless}}> <div class="inventory-item-header" {{#unless noExtensible}}data-action="toggleExtended" {{/unless}}>
{{!-- Image --}} {{!-- Image --}}
<div class="img-portait" data-action='{{ifThen (or (hasProperty item "use") (eq type ' attack')) "useItem" (ifThen <div class="img-portait" data-action='{{ifThen (or (hasProperty item "use") (eq type ' attack')) "useItem" (ifThen
@ -32,7 +32,7 @@ Parameters:
{{!-- Item Name --}} {{!-- Item Name --}}
<div class="item-name">{{localize item.name}}</div> <div class="item-name">{{localize item.name}}</div>
{{!-- Attack Block Start --}} {{!-- Attack Tags Start --}}
{{#if (eq type 'attack')}} {{#if (eq type 'attack')}}
<div class="item-tags"> <div class="item-tags">
<div class="tag"> <div class="tag">
@ -42,106 +42,35 @@ Parameters:
{{localize 'DAGGERHEART.CONFIG.ActionType.action'}} {{localize 'DAGGERHEART.CONFIG.ActionType.action'}}
</div> </div>
</div> </div>
{{/if}} {{!-- Attack Tags End --}}
{{!-- Attack Block End --}} {{else}}
{{#with item}}
{{!-- Weapon Block Start --}} {{#if (not ../hideTags)}}
{{#if (eq type 'weapon')}}
{{#if (not hideTags)}}
<div class="item-tags"> <div class="item-tags">
{{#each item.getTags as |tag|}} {{#each this._getTags as |tag|}}
<div class="tag"> <div class="tag">
{{tag}} {{tag}}
</div> </div>
{{/each}} {{/each}}
</div> </div>
{{else if (not hideLabels)}} {{else if (not ../hideLabels)}}
<div class="item-labels"> <div class="item-lables">
{{#each item.getLabels as |label|}}
<div class="label"> <div class="label">
{{#each this._getLabels as |label|}}
{{ifThen label.value label.value label}} {{ifThen label.value label.value label}}
{{log label.icons}}
{{#each label.icons as |icon|}} {{#each label.icons as |icon|}}
<i class="fa-solid {{icon}}"></i> <i class="fa-solid {{icon}}"></i>
{{/each}} {{/each}}
{{#if (not @last)}} {{#if (not @last)}}
<span>-</span> <span>-</span>
{{/if}} {{/if}}
</div>
{{/each}} {{/each}}
</div> </div>
</div>
{{/if}} {{/if}}
{{/with}}
{{/if}} {{/if}}
{{!-- Weapon Block End --}}
{{!-- Armor Block Start --}}
{{#if (eq type 'armor')}}
{{#if (not hideTags)}}
<div class="item-tags">
<div class="tag">{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}}</div>
<div class="tag">
{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}:
{{item.system.baseThresholds.major}} / {{item.system.baseThresholds.severe}}
</div>
</div>
{{else if (not hideLabels)}}
<div class="item-labels">
<div class="label">
{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}}
</div>
</div>
{{/if}}
{{/if}}
{{!-- Armor Block End --}}
{{!-- Domain Card Block Start --}}
{{#if (eq type 'domainCard')}}
{{#if (not hideTags)}}
<div class="item-tags">
<div class="tag">{{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}}</div>
<div class="tag">{{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}}</div>
<div class="tag">
<span class="recall-label">{{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: </span>
<span class="recall-value">{{item.system.recallCost}}</span>
</div>
</div>
{{else if (not hideLabels)}}
<div class="item-labels">
<div class="label">
{{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} -
{{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} -
<span class="recall-value">{{item.system.recallCost}}</span>
<i class="fa-solid fa-bolt"></i>
</div>
</div>
{{/if}}
{{/if}}
{{!-- Domain Card Block End --}}
{{!-- Effect Block Start --}}
{{#if (eq type 'effect')}}
{{#if (not hideTags)}}
<div class="item-tags">
<div class="tag">
{{localize item.parent.system.metadata.label}}: {{item.parent.name}}
</div>
<div class="tag">
{{#if item.duration.duration}}
{{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}}
{{else}}
{{localize 'DAGGERHEART.EFFECTS.Duration.passive'}}
{{/if}}
</div>
{{#each item.localizedStatuses as |status|}}
<div class="tag">{{status.name}}</div>
{{/each}}
</div>
{{else if (not hideLabels)}}
{{!-- Empty --}}
{{/if}}
{{/if}}
{{!-- Effect Block End --}}
{{!-- Action Block Start --}} {{!-- Action Block Start --}}
{{#if (eq type 'action')}} {{#if (eq type 'action')}}