Skip to content

Commit

Permalink
[foundryvtt#1401] Adjust how available spell level is calculated for …
Browse files Browse the repository at this point in the history
…classes
  • Loading branch information
arbron committed Jan 25, 2023
1 parent 8759b96 commit 5141fc5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
1 change: 1 addition & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"DND5E.AdvancementItemChoiceHint": "Present the player with a choice of items (such as equipment, features, or spells) that they can choose for their character at one or more levels.",
"DND5E.AdvancementItemChoiceChosen": "Chosen: {current} of {max}",
"DND5E.AdvancementItemChoiceLevelsHint": "Specify how many choices are allowed at each level.",
"DND5E.AdvancementItemChoicePreviouslyChosenWarning": "This item has already been chosen at a previous level.",
"DND5E.AdvancementItemChoiceSpellLevelAvailable": "Any Available Level",
"DND5E.AdvancementItemChoiceSpellLevelAvailableWarning": "Only {level} or lower spells can be chosen for this advancement.",
"DND5E.AdvancementItemChoiceSpellLevelSpecificWarning": "Only {level} spells can be chosen for this advancement.",
Expand Down
26 changes: 22 additions & 4 deletions module/applications/advancement/item-choice-flow.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Actor5e from "../../documents/actor/actor.mjs";
import ItemGrantFlow from "./item-grant-flow.mjs";

/**
Expand Down Expand Up @@ -134,9 +135,11 @@ export default class ItemChoiceFlow extends ItemGrantFlow {
if ( this.selected.has(item.uuid) ) return false;

// Check to ensure the dropped item hasn't been selected at a lower level
for ( const [level, data] of Object.entries(this.advancement.value) ) {
for ( const [level, data] of Object.entries(this.advancement.value.added ?? {}) ) {
if ( level >= this.level ) continue;
if ( Object.values(data).includes(item.uuid) ) return;
if ( Object.values(data).includes(item.uuid) ) {
return ui.notifications.error(game.i18n.localize("DND5E.AdvancementItemChoicePreviouslyChosenWarning"));
}
}

// If spell level is restricted to available level, ensure the spell is of the appropriate level
Expand Down Expand Up @@ -167,12 +170,27 @@ export default class ItemChoiceFlow extends ItemGrantFlow {
* @returns {number}
*/
_maxSpellSlotLevel() {
const largestSlot = Object.entries(this.advancement.actor.system.spells).reduce((slot, [key, data]) => {
const spellcasting = this.advancement.item.spellcasting;
let spells;

// For advancements on classes or subclasses, use the largest slot available for that class
if ( spellcasting ) {
const progression = { slot: 0, pact: {} };
const maxSpellLevel = CONFIG.DND5E.SPELL_SLOT_TABLE[CONFIG.DND5E.SPELL_SLOT_TABLE.length - 1].length;
spells = Object.fromEntries(Array.fromRange(maxSpellLevel, 1).map(l => [`spell${l}`, {}]));
Actor5e.computeClassProgression(progression, this.advancement.item, { spellcasting });
Actor5e.prepareSpellcastingSlots(spells, spellcasting.type, progression);
}

// For all other items, use the largest slot possible
else spells = this.advancement.actor.system.spells;

const largestSlot = Object.entries(spells).reduce((slot, [key, data]) => {
if ( data.max === 0 ) return slot;
const level = parseInt(key.replace("spell", ""));
if ( !Number.isNaN(level) && level > slot ) return level;
return slot;
}, -1);
return Math.max(this.advancement.actor.system.spells.pact.level, largestSlot);
return Math.max(spells.pact?.level ?? 0, largestSlot);
}
}

0 comments on commit 5141fc5

Please sign in to comment.