diff --git a/module/applications/actor/character-sheet.mjs b/module/applications/actor/character-sheet.mjs index 6c6a76da9f..d8498481cc 100644 --- a/module/applications/actor/character-sheet.mjs +++ b/module/applications/actor/character-sheet.mjs @@ -78,10 +78,10 @@ export default class ActorSheet5eCharacter extends ActorSheet5e { ctx.isExpanded = this._expanded.has(item.id); // Item usage - ctx.hasUses = uses && (uses.max > 0); + ctx.hasUses = item.hasLimitedUses; ctx.isOnCooldown = recharge && !!recharge.value && (recharge.charged === false); - ctx.isDepleted = ctx.isOnCooldown && (uses.per && (uses.value > 0)); - ctx.hasTarget = !!target && !(["none", ""].includes(target.type)); + ctx.isDepleted = ctx.isOnCooldown && ctx.hasUses && (uses.value > 0); + ctx.hasTarget = item.hasAreaTarget || item.hasIndividualTarget; // Item toggle state this._prepareItemToggleState(item, ctx); diff --git a/module/data/item/feat.mjs b/module/data/item/feat.mjs index d9bd055835..f405116f67 100644 --- a/module/data/item/feat.mjs +++ b/module/data/item/feat.mjs @@ -89,7 +89,7 @@ export default class FeatData extends SystemDataModel.mixin( /** @inheritdoc */ get hasLimitedUses() { - return !!this.recharge.value || super.hasLimitedUses; + return this.isActive && (!!this.recharge.value || super.hasLimitedUses); } /* -------------------------------------------- */ diff --git a/module/data/item/templates/activated-effect.mjs b/module/data/item/templates/activated-effect.mjs index 1c70ca7549..3ed2b4c85e 100644 --- a/module/data/item/templates/activated-effect.mjs +++ b/module/data/item/templates/activated-effect.mjs @@ -210,12 +210,20 @@ export default class ActivatedEffectTemplate extends SystemDataModel { /* -------------------------------------------- */ + /** + * Is this Item an activatable item? + * @type {boolean} + */ + get isActive() { + return !!this.activation.type; + } + /** * Does the Item have an area of effect target? * @type {boolean} */ get hasAreaTarget() { - return this.target.type in CONFIG.DND5E.areaTargetTypes; + return this.isActive && (this.target.type in CONFIG.DND5E.areaTargetTypes); } /* -------------------------------------------- */ @@ -225,7 +233,7 @@ export default class ActivatedEffectTemplate extends SystemDataModel { * @type {boolean} */ get hasIndividualTarget() { - return this.target.type in CONFIG.DND5E.individualTargetTypes; + return this.isActive && (this.target.type in CONFIG.DND5E.individualTargetTypes); } /* -------------------------------------------- */ @@ -235,7 +243,16 @@ export default class ActivatedEffectTemplate extends SystemDataModel { * @type {boolean} */ get hasLimitedUses() { - return !!this.uses.per && (this.uses.max > 0); + return this.isActive && (this.uses.per in CONFIG.DND5E.limitedUsePeriods) && (this.uses.max > 0); + } + + /** + * Does this Item draw from a resource? + * @type {boolean} + */ + get hasResource() { + const consume = this.consume; + return this.isActive && !!consume.target && !!consume.type && (!this.hasAttack || (consume.type !== "ammo")); } /* -------------------------------------------- */ @@ -275,7 +292,7 @@ export default class ActivatedEffectTemplate extends SystemDataModel { * @type {boolean} */ get hasTarget() { - return !["", null].includes(this.target.type); + return this.isActive && !["", null].includes(this.target.type); } } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index ec64b60d43..6bca1b5be1 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -20,6 +20,14 @@ export default class Item5e extends Item { /* Item Properties */ /* -------------------------------------------- */ + /** + * Is this Item an activatable item? + * @type {boolean} + */ + get isActive() { + return this.system.isActive ?? false; + } + /** * Which ability score modifier is used by this item? * @type {string|null} @@ -117,6 +125,15 @@ export default class Item5e extends Item { return this.system.hasLimitedUses ?? false; } + /** + * Does this Item draw from a resource? + * @type {boolean} + * @see {@link ActivatedEffectTemplate#hasResource} + */ + get hasResource() { + return this.system.hasResource ?? false; + } + /* -------------------------------------------- */ /** @@ -421,15 +438,18 @@ export default class Item5e extends Item { if ( ["none", ""].includes(tgt.type) ) tgt.type = null; // Backwards compatibility if ( [null, "self"].includes(tgt.type) ) tgt.value = tgt.units = null; else if ( tgt.units === "touch" ) tgt.value = null; - this.labels.target = tgt.type - ? [tgt.value, C.distanceUnits[tgt.units], C.targetTypes[tgt.type]].filterJoin(" ") : ""; + + if ( this.hasTarget ) { + this.labels.target = [tgt.value, C.distanceUnits[tgt.units], C.targetTypes[tgt.type]].filterJoin(" "); + } // Range Label let rng = this.system.range ?? {}; if ( ["none", ""].includes(rng.units) ) rng.units = null; // Backwards compatibility if ( [null, "touch", "self"].includes(rng.units) ) rng.value = rng.long = null; - this.labels.range = rng.units - ? [rng.value, rng.long ? `/ ${rng.long}` : null, C.distanceUnits[rng.units]].filterJoin(" ") : ""; + if ( this.isActive && rng.units ) { + this.labels.range = [rng.value, rng.long ? `/ ${rng.long}` : null, C.distanceUnits[rng.units]].filterJoin(" "); + } else this.labels.range = game.i18n.localize("DND5E.None"); // Recharge Label let chg = this.system.recharge ?? {}; diff --git a/templates/actors/parts/actor-spellbook.hbs b/templates/actors/parts/actor-spellbook.hbs index 82d893fe97..4fad3dc1c0 100644 --- a/templates/actors/parts/actor-spellbook.hbs +++ b/templates/actors/parts/actor-spellbook.hbs @@ -73,8 +73,10 @@

{{item.name}}

- {{#if item.system.uses.per }} -
Uses {{item.system.uses.value}} / {{item.system.uses.max}}
+ {{#if item.hasLimitedUses}} +
+ {{localize "DND5E.Uses"}} {{#if item.system.uses.value}}{{item.system.uses.value}}{{else}}0{{/if}} / {{item.system.uses.max}} +
{{/if}}
{{#each item.labels.components.all}}