From 00c013cdceb7b1b24b75c9e7ed6a1578b7e720e7 Mon Sep 17 00:00:00 2001 From: Jeff Hitchcock Date: Wed, 15 Jan 2025 14:23:23 -0800 Subject: [PATCH] [#5003] Add ability attack, spell attack, & spell ability labels Adds `attack` to each ability which is the default attack to hit using that ability (e.g. prof + mod). Also adds the spell attack and ability label to actor attributes inside a new `attributes.spells` object. This moves the old `spelldc` and `spellmod` into that object with deprecation warnings. Closes #5003 --- module/config.mjs | 6 ++--- module/data/actor/templates/common.mjs | 1 + module/documents/activity/summon.mjs | 2 +- module/documents/actor/actor.mjs | 28 +++++++++++++++++++--- module/documents/item.mjs | 4 ++-- module/utils.mjs | 2 +- templates/actors/character-sheet.hbs | 2 +- templates/actors/parts/actor-spellbook.hbs | 2 +- 8 files changed, 35 insertions(+), 12 deletions(-) diff --git a/module/config.mjs b/module/config.mjs index d9f2b0621c..30be313f2f 100644 --- a/module/config.mjs +++ b/module/config.mjs @@ -3470,9 +3470,9 @@ preLocalize("cover"); * @deprecated since v10 */ DND5E.trackableAttributes = [ - "attributes.ac.value", "attributes.init.bonus", "attributes.movement", "attributes.senses", "attributes.spelldc", - "attributes.spellLevel", "details.cr", "details.spellLevel", "details.xp.value", "skills.*.passive", - "abilities.*.value" + "attributes.ac.value", "attributes.init.bonus", "attributes.movement", "attributes.senses", + "attributes.spell.attack", "attributes.spell.dc", "attributes.spellLevel", "details.cr", + "details.spellLevel", "details.xp.value", "skills.*.passive", "abilities.*.value" ]; /* -------------------------------------------- */ diff --git a/module/data/actor/templates/common.mjs b/module/data/actor/templates/common.mjs index 7a4a8b3d1b..d6985af273 100644 --- a/module/data/actor/templates/common.mjs +++ b/module/data/actor/templates/common.mjs @@ -149,6 +149,7 @@ export default class CommonTemplate extends ActorDataModel.mixin(CurrencyTemplat abl.save = abl.mod + abl.saveBonus; if ( Number.isNumeric(abl.saveProf.term) ) abl.save += abl.saveProf.flat; + abl.attack = abl.mod + prof; abl.dc = 8 + abl.mod + prof + dcBonus; if ( !Number.isFinite(abl.max) ) abl.max = CONFIG.DND5E.maxAbilityScore; diff --git a/module/documents/activity/summon.mjs b/module/documents/activity/summon.mjs index a894c2f1c5..05e07fb15e 100644 --- a/module/documents/activity/summon.mjs +++ b/module/documents/activity/summon.mjs @@ -500,7 +500,7 @@ export default class SummonActivity extends ActivityMixin(SummonActivityData) { // Match saves if ( this.match.saves && item.hasSave ) { - let dc = rollData.abilities?.[this.ability]?.dc ?? rollData.attributes.spelldc; + let dc = rollData.abilities?.[this.ability]?.dc ?? rollData.attributes.spell.dc; if ( this.item.type === "spell" ) { const ability = this.item.system.availableAbilities?.first(); if ( ability ) dc = rollData.abilities[ability]?.dc ?? dc; diff --git a/module/documents/actor/actor.mjs b/module/documents/actor/actor.mjs index cbfd2ac78e..308f006791 100644 --- a/module/documents/actor/actor.mjs +++ b/module/documents/actor/actor.mjs @@ -617,9 +617,31 @@ export default class Actor5e extends SystemDocumentMixin(Actor) { * Prepare spellcasting DC & modifier. */ _prepareSpellcastingAbility() { - const spellcastingAbility = this.system.abilities[this.system.attributes.spellcasting]; - this.system.attributes.spelldc = spellcastingAbility ? spellcastingAbility.dc : 8 + this.system.attributes.prof; - this.system.attributes.spellmod = spellcastingAbility ? spellcastingAbility.mod : 0; + const ability = this.system.abilities[this.system.attributes.spellcasting]; + this.system.attributes.spell = { + abilityLabel: CONFIG.DND5E.abilities[this.system.attributes.spellcasting]?.label ?? "", + attack: ability ? ability.attack : this.system.attributes.prof, + dc: ability ? ability.dc : 8 + this.system.attributes.prof, + mod: ability ? ability.mod : 0 + }; + Object.defineProperty(this.system.attributes, "spelldc", { + get() { + foundry.utils.logCompatibilityWarning( + "The `attributes.spelldc` property on actors has been moved to `attributes.spell.dc`.", + { since: "DnD5e 4.2", until: "DnD5e 5.0" } + ); + return this.spell.dc; + } + }); + Object.defineProperty(this.system.attributes, "spellmod", { + get() { + foundry.utils.logCompatibilityWarning( + "The `attributes.spellmod` property on actors has been moved to `attributes.spell.mod`.", + { since: "DnD5e 4.2", until: "DnD5e 5.0" } + ); + return this.spell.mod; + } + }); } /* -------------------------------------------- */ diff --git a/module/documents/item.mjs b/module/documents/item.mjs index d1820f3d5b..5706d1863c 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -1549,8 +1549,8 @@ export default class Item5e extends SystemDocumentMixin(Item) { values.bonus = spellcastingClass.spellcasting.attack; values.dc = spellcastingClass.spellcasting.save; } else { - values.bonus = spell.actor.system.attributes?.spellmod; - values.dc = spell.actor.system.attributes?.spelldc; + values.bonus = spell.actor.system.attributes?.spell?.mod; + values.dc = spell.actor.system.attributes?.spell?.dc; } } diff --git a/module/utils.mjs b/module/utils.mjs index 641c48b78b..8a644408a5 100644 --- a/module/utils.mjs +++ b/module/utils.mjs @@ -1067,7 +1067,7 @@ export function getHumanReadableAttributeLabel(attr, { actor }={}) { // Derived fields. if ( attr === "attributes.init.total" ) label = "DND5E.InitiativeBonus"; else if ( (attr === "attributes.ac.value") || (attr === "attributes.ac.flat") ) label = "DND5E.ArmorClass"; - else if ( attr === "attributes.spelldc" ) label = "DND5E.SpellDC"; + else if ( attr === "attributes.spell.dc" ) label = "DND5E.SpellDC"; // Abilities. else if ( attr.startsWith("abilities.") ) { diff --git a/templates/actors/character-sheet.hbs b/templates/actors/character-sheet.hbs index 80a45f3aad..cb8f5493a5 100644 --- a/templates/actors/character-sheet.hbs +++ b/templates/actors/character-sheet.hbs @@ -107,7 +107,7 @@ {{system.attributes.ac.value}} diff --git a/templates/actors/parts/actor-spellbook.hbs b/templates/actors/parts/actor-spellbook.hbs index 5d797538f9..7a5d4f57bc 100644 --- a/templates/actors/parts/actor-spellbook.hbs +++ b/templates/actors/parts/actor-spellbook.hbs @@ -12,7 +12,7 @@ {{ selectOptions config.abilities selected=system.attributes.spellcasting labelAttr="label" blank=(localize "DND5E.None") }} - {{localize "DND5E.AbbreviationDC"}} {{system.attributes.spelldc}} + {{localize "DND5E.AbbreviationDC"}} {{system.attributes.spell.dc}}