Grabbed dndbeyond's source code
``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
This commit is contained in:
@@ -0,0 +1,535 @@
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinition(charClass) {
|
||||
return charClass.definition;
|
||||
}
|
||||
/**
|
||||
* @param charClass
|
||||
*/
|
||||
export function getName(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getId(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionHitDiceType(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.hitDice) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getHitDiceType(charClass) {
|
||||
return getDefinitionHitDiceType(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSpellcastingStatId(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.spellCastingAbilityId) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSpellContainerName(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.spellContainerName) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSpellContainerName(charClass) {
|
||||
return getDefinitionSpellContainerName(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionKnowsAllSpells(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.knowsAllSpells) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
export function getKnowsAllSpells(charClass) {
|
||||
return getDefinitionKnowsAllSpells(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSpellPrepareType(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.spellPrepareType) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
export function getSpellPrepareType(charClass) {
|
||||
return getDefinitionSpellPrepareType(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSpellCastingLearningStyle(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.spellCastingLearningStyle) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
export function getSpellCastingLearningStyle(charClass) {
|
||||
return charClass.spellCastingLearningStyle;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getPortraitUrl(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.portraitAvatarUrl) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getAvatarUrl(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.avatarUrl) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getLargeAvatarUrl(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.largeAvatarUrl) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isKnownSpellcaster(charClass) {
|
||||
const spellRules = getSpellRules(charClass);
|
||||
return spellRules.isKnownSpellcaster;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isPreparedSpellcaster(charClass) {
|
||||
const spellRules = getSpellRules(charClass);
|
||||
return spellRules.isPreparedSpellcaster;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isSpellbookSpellcaster(charClass) {
|
||||
const spellRules = getSpellRules(charClass);
|
||||
return spellRules.isSpellbookSpellcaster;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isRitualSpellCaster(charClass) {
|
||||
const spellRules = getSpellRules(charClass);
|
||||
return spellRules.isRitualSpellCaster;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getCanCastSpells(charClass) {
|
||||
getDefinitionCanCastSpells(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionCanCastSpells(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.canCastSpells) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionDescription(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDescription(charClass) {
|
||||
return getDefinitionDescription(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionEquipmentDescription(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.equipmentDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getEquipmentDescription(charClass) {
|
||||
return getDefinitionEquipmentDescription(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getMoreDetailsUrl(charClass) {
|
||||
return getDefinitionMoreDetailsUrl(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionMoreDetailsUrl(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.moreDetailsUrl) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionParentClassId(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.parentClassId) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getParentClassId(charClass) {
|
||||
return getDefinitionParentClassId(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSubclassDefinition(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.subclassDefinition) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getWealthDice(charClass) {
|
||||
return getDefinitionWealthDice(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionWealthDice(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.wealthDice) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionClassFeatures(charClass) {
|
||||
var _a;
|
||||
return (_a = charClass.classFeatures) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getMappingEntityTypeId(charClass) {
|
||||
return charClass.entityTypeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getHitDiceUsed(charClass) {
|
||||
return charClass.hitDiceUsed;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getMappingId(charClass) {
|
||||
return charClass.id;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isStartingClass(charClass) {
|
||||
return charClass.isStartingClass;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getLevel(charClass) {
|
||||
return charClass.level;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSubclassName(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.subclassDefinition) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSubclass(charClass) {
|
||||
return charClass.subclassDefinition;
|
||||
}
|
||||
/**
|
||||
* this field will always return null until character service updates to populate it
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSubclassDefinitionId(charClass) {
|
||||
return charClass.subclassDefinitionId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isPactMagicActive(charClass) {
|
||||
return charClass.isPactMagicActive;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isSpellcastingActive(charClass) {
|
||||
return charClass.isSpellcastingActive;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSlug(charClass) {
|
||||
return charClass.slug;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSpellRules(charClass) {
|
||||
return charClass.spellRules;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getActions(charClass) {
|
||||
return charClass.actions;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getActiveClassFeatures(charClass) {
|
||||
return charClass.activeClassFeatures;
|
||||
}
|
||||
/**
|
||||
* @deprecated only used for typescript parody because of spells being in two different states within the same location
|
||||
* @param charClass
|
||||
*/
|
||||
export function getBaseClassSpells(charClass) {
|
||||
return charClass.spells;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getClassFeatures(charClass) {
|
||||
var _a;
|
||||
return (_a = charClass.classFeatures) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getEnablesHexWeapon(charClass) {
|
||||
return charClass.enablesHexWeapon;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getEnablesPactWeapon(charClass) {
|
||||
return charClass.enablesPactWeapon;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getEnablesDedicatedWeapon(charClass) {
|
||||
return charClass.enablesDedicatedWeapon;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getFeats(charClass) {
|
||||
return charClass.feats;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getFeatureSpells(charClass) {
|
||||
return charClass.featureSpells;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getModifiers(charClass) {
|
||||
return charClass.modifiers;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getOrderedClassFeatures(charClass) {
|
||||
return charClass.orderedClassFeatures;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSpells(charClass) {
|
||||
return charClass.spells;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getUniqueClassFeatures(charClass) {
|
||||
return charClass.uniqueClassFeatures;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getVisibileClassFeatures(charClass) {
|
||||
return charClass.visibleClassFeatures;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getActiveId(charClass) {
|
||||
return charClass.activeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionPrimaryAbilities(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.primaryAbilities) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getPrimaryAbilities(charClass) {
|
||||
return getDefinitionPrimaryAbilities(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionPrerequisites(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.prerequisites) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getPrerequisites(charClass) {
|
||||
return getDefinitionPrerequisites(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSpellConfiguration(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.spellRules) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSpellConfiguration(charClass) {
|
||||
return getDefinitionSpellConfiguration(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionSources(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.sources) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSources(charClass) {
|
||||
return getDefinitionSources(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getDefinitionIsHomebrew(charClass) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = charClass.definition) === null || _a === void 0 ? void 0 : _a.isHomebrew) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function isHomebrew(charClass) {
|
||||
return getDefinitionIsHomebrew(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getSpellListIds(charClass) {
|
||||
return charClass.spellListIds;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function getOptionalClassFeatures(charClass) {
|
||||
return charClass.optionalClassFeatures;
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
import { orderBy } from 'lodash';
|
||||
import { ChoiceUtils } from '../Choice';
|
||||
import { ClassFeatureAccessors, ClassFeatureUtils, ClassFeatureValidators } from '../ClassFeature';
|
||||
import { DB_STRING_BOOK_OF_ANCIENT_SECRETS, DB_STRING_INFUSE_ITEM, FeatureTypeEnum, } from '../Core';
|
||||
import { DataOriginGenerators } from '../DataOrigin';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { ModifierValidators } from '../Modifier';
|
||||
import { OptionalClassFeatureAccessors } from '../OptionalClassFeature';
|
||||
import { DefaultSpellCastingLearningStyle, SpellDerivers } from '../Spell';
|
||||
import { getActiveId, getDefinitionClassFeatures, getDefinitionSpellcastingStatId, getId, getLevel, getMappingId, getSubclass, getClassFeatures, getDefinitionSpellCastingLearningStyle, } from './accessors';
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param subclassDefinition
|
||||
*/
|
||||
export function deriveSpellcastingStatId(charClass, subclassDefinition) {
|
||||
if (subclassDefinition && subclassDefinition.spellCastingAbilityId !== null) {
|
||||
return subclassDefinition.spellCastingAbilityId;
|
||||
}
|
||||
return getDefinitionSpellcastingStatId(charClass);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param subclassDefinition
|
||||
*/
|
||||
export function deriveSpellCastingLearningStyle(charClass) {
|
||||
var _a;
|
||||
const subclassDefinition = getSubclass(charClass);
|
||||
if (subclassDefinition === null || subclassDefinition === void 0 ? void 0 : subclassDefinition.spellCastingLearningStyle) {
|
||||
return subclassDefinition.spellCastingLearningStyle;
|
||||
}
|
||||
return (_a = getDefinitionSpellCastingLearningStyle(charClass)) !== null && _a !== void 0 ? _a : DefaultSpellCastingLearningStyle;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classFeatures
|
||||
* @param classLevel
|
||||
*/
|
||||
export function deriveIsSpellcastingActive(classFeatures, classLevel) {
|
||||
const spellcastingFeature = classFeatures.find((feature) => ClassFeatureUtils.doesEnableSpellcasting(feature));
|
||||
return !!spellcastingFeature && ClassFeatureAccessors.getRequiredLevel(spellcastingFeature) <= classLevel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classFeatures
|
||||
* @param classLevel
|
||||
*/
|
||||
export function deriveIsPactMagicActive(classFeatures, classLevel) {
|
||||
const pactMagicFeature = classFeatures.find((feature) => ClassFeatureUtils.doesEnablePactMagic(feature));
|
||||
return !!pactMagicFeature && ClassFeatureAccessors.getRequiredLevel(pactMagicFeature) <= classLevel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param allClassSpells
|
||||
* @param allClassAlwaysPreparedSpells
|
||||
* @param allClassAlwaysKnownSpells
|
||||
*/
|
||||
export function deriveSpells(charClass, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells) {
|
||||
const classSpells = allClassSpells.find((classSpell) => classSpell.characterClassId === getMappingId(charClass));
|
||||
const spells = [];
|
||||
if (classSpells === null || classSpells === void 0 ? void 0 : classSpells.spells) {
|
||||
spells.push(...classSpells.spells);
|
||||
}
|
||||
let classSpellMappingLookup = {};
|
||||
const alwaysPreparedSpells = HelperUtils.lookupDataOrFallback(allClassAlwaysPreparedSpells, deriveActiveId(charClass));
|
||||
const alwaysKnownSpells = HelperUtils.lookupDataOrFallback(allClassAlwaysKnownSpells, deriveActiveId(charClass));
|
||||
// If we have any "always" spells, make a lookup of the existing class spell mappings
|
||||
if (alwaysKnownSpells !== null || alwaysPreparedSpells !== null) {
|
||||
if (classSpells === null || classSpells === void 0 ? void 0 : classSpells.spells) {
|
||||
classSpellMappingLookup = classSpells.spells.reduce((acc, spell) => {
|
||||
acc[SpellDerivers.deriveKnownKey(spell)] = true;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
// exclude always prepared spells that we are already sent in the class spell mappings
|
||||
if (alwaysPreparedSpells !== null) {
|
||||
alwaysPreparedSpells.forEach((spell) => {
|
||||
const knownKey = SpellDerivers.deriveKnownKey(spell);
|
||||
if (!HelperUtils.lookupDataOrFallback(classSpellMappingLookup, knownKey, false)) {
|
||||
spells.push(spell);
|
||||
classSpellMappingLookup[knownKey] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
// exclude always known spells that we are already sent in the class spell mappings
|
||||
if (alwaysKnownSpells !== null) {
|
||||
alwaysKnownSpells.forEach((spell) => {
|
||||
if (!HelperUtils.lookupDataOrFallback(classSpellMappingLookup, SpellDerivers.deriveKnownKey(spell), false)) {
|
||||
spells.push(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
return spells;
|
||||
}
|
||||
/**
|
||||
* The classFeatures being passed in here are updated during BaseCharClass generation and cannot be accessed off charClass
|
||||
* fix this to eventually not have class and class features from separate stages
|
||||
*
|
||||
* @param charClass
|
||||
* @param classFeatures
|
||||
* @param choiceLookup
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveSpellRules(charClass, classFeatures, choiceLookup, ruleData) {
|
||||
const abilityId = deriveSpellcastingStatId(charClass, getSubclass(charClass));
|
||||
let enablesRitualCasting = false;
|
||||
classFeatures.forEach((feature) => {
|
||||
const id = ClassFeatureAccessors.getId(feature);
|
||||
const entityTypeId = ClassFeatureAccessors.getEntityTypeId(feature);
|
||||
const choicesFallback = [];
|
||||
const choices = HelperUtils.lookupDataOrFallback(choiceLookup, DataOriginGenerators.generateDataOriginKey(id, entityTypeId), choicesFallback);
|
||||
if (choices.length > 0) {
|
||||
choices.forEach((choice) => {
|
||||
const selectedOption = ChoiceUtils.getSelectedOption(choice);
|
||||
if (!enablesRitualCasting &&
|
||||
selectedOption &&
|
||||
selectedOption.label === DB_STRING_BOOK_OF_ANCIENT_SECRETS) {
|
||||
enablesRitualCasting = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return SpellDerivers.deriveClassSpellRules(charClass, abilityId, ruleData, enablesRitualCasting);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param classFeatures
|
||||
* @param appContext
|
||||
*/
|
||||
export function deriveClassFeatureGroups(charClass, classFeatures, appContext) {
|
||||
const activeFeatures = classFeatures.filter((feature) => ClassFeatureAccessors.getRequiredLevel(feature) <= getLevel(charClass));
|
||||
const visibleFeatures = activeFeatures.filter((feature) => appContext === null || !ClassFeatureUtils.getHideInContext(feature, appContext));
|
||||
const orderedFeatures = deriveOrderedClassFeatures(visibleFeatures);
|
||||
const uniqueFeatures = orderedFeatures.reduce((acc, feature) => {
|
||||
const existingFeatureIdx = acc.findIndex((accFeature) => ClassFeatureAccessors.getName(accFeature) === ClassFeatureAccessors.getName(feature));
|
||||
if (existingFeatureIdx > 0) {
|
||||
acc[existingFeatureIdx] = feature;
|
||||
}
|
||||
else {
|
||||
acc.push(feature);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
return {
|
||||
activeFeatures,
|
||||
visibleFeatures,
|
||||
orderedFeatures,
|
||||
uniqueFeatures,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classFeatures
|
||||
*/
|
||||
export function deriveOrderedClassFeatures(classFeatures) {
|
||||
return orderBy(classFeatures, [
|
||||
(classFeature) => ClassFeatureAccessors.getRequiredLevel(classFeature),
|
||||
(classFeature) => ClassFeatureAccessors.getDisplayOrder(classFeature),
|
||||
(classFeature) => ClassFeatureAccessors.getName(classFeature),
|
||||
]);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classFeatures
|
||||
*/
|
||||
export function deriveDedicatedHexAndPactWeaponEnabled(classFeatures, classModifiers) {
|
||||
let enablesHexWeapon = false;
|
||||
let enablesPactWeapon = false;
|
||||
let enablesDedicatedWeapon = false;
|
||||
classModifiers.forEach((modifier) => {
|
||||
if (!enablesPactWeapon && ModifierValidators.isEnablePactWeaponModifier(modifier)) {
|
||||
enablesPactWeapon = true;
|
||||
return;
|
||||
}
|
||||
if (!enablesHexWeapon && ModifierValidators.isEnableHexWeaponModifier(modifier)) {
|
||||
enablesHexWeapon = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
//TODO remove this once we have dedicated weapon driven by modifiers
|
||||
classFeatures.forEach((feature) => {
|
||||
if (!enablesDedicatedWeapon && ClassFeatureUtils.doesEnableDedicatedWeapon(feature)) {
|
||||
enablesDedicatedWeapon = true;
|
||||
}
|
||||
});
|
||||
return {
|
||||
enablesHexWeapon,
|
||||
enablesPactWeapon,
|
||||
enablesDedicatedWeapon,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function deriveActiveId(charClass) {
|
||||
const subclass = getSubclass(charClass);
|
||||
if (subclass === null) {
|
||||
return getId(charClass);
|
||||
}
|
||||
return subclass.id;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function deriveIsMulticlassCharacter(classes) {
|
||||
return classes.length > 1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function deriveUniqueKey(charClass) {
|
||||
return `class-${getActiveId(charClass)}`;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classFeatures
|
||||
* @param classLevel
|
||||
*/
|
||||
export function deriveSpellListIds(classFeatures, classLevel) {
|
||||
let spellLidsIds = [];
|
||||
classFeatures
|
||||
.filter((classFeature) => ClassFeatureAccessors.getRequiredLevel(classFeature) <= classLevel)
|
||||
.forEach((classFeature) => {
|
||||
spellLidsIds.push(...ClassFeatureAccessors.getSpellListIds(classFeature));
|
||||
});
|
||||
return spellLidsIds;
|
||||
}
|
||||
/**
|
||||
* has mirrored deriver RaceDerivers.deriveConsolidatedRacialTraits
|
||||
* - most likely update together
|
||||
*
|
||||
* @param charClass
|
||||
* @param optionalClassFeatures
|
||||
* @param enableOptionalClassFeatures
|
||||
*/
|
||||
export function deriveConsolidatedClassFeatures(charClass, optionalClassFeatures, enableOptionalClassFeatures) {
|
||||
//filtering because after generating CharClass, this function is used in getUpdateEnableOptionalClassFeaturesSpellListIdsToRemove
|
||||
// to determine updated look of race and we don't store original definition info for classes
|
||||
const originalDefinitionClassFeatures = getDefinitionClassFeatures(charClass).filter((feature) => ClassFeatureAccessors.getFeatureType(feature) === FeatureTypeEnum.GRANTED);
|
||||
if (!enableOptionalClassFeatures) {
|
||||
return originalDefinitionClassFeatures;
|
||||
}
|
||||
const additionalClassFeatures = [];
|
||||
const definitionKeysToRemove = new Set();
|
||||
optionalClassFeatures.forEach((optionalClassFeature) => {
|
||||
const classFeature = OptionalClassFeatureAccessors.getClassFeature(optionalClassFeature);
|
||||
if (classFeature === null) {
|
||||
return;
|
||||
}
|
||||
const featureType = ClassFeatureAccessors.getFeatureType(classFeature);
|
||||
switch (featureType) {
|
||||
case FeatureTypeEnum.REPLACEMENT: {
|
||||
const affectedDefinitionKey = OptionalClassFeatureAccessors.getAffectedClassFeatureDefinitionKey(optionalClassFeature);
|
||||
const affectedFeatureKeys = ClassFeatureAccessors.getAffectedFeatureDefinitionKeys(classFeature);
|
||||
//verify this is a valid replacement
|
||||
if (affectedDefinitionKey &&
|
||||
affectedFeatureKeys.includes(affectedDefinitionKey) &&
|
||||
ClassFeatureValidators.isValidClassClassFeature(charClass, classFeature)) {
|
||||
definitionKeysToRemove.add(affectedDefinitionKey);
|
||||
additionalClassFeatures.push(classFeature);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FeatureTypeEnum.ADDITIONAL:
|
||||
case FeatureTypeEnum.GRANTED:
|
||||
default:
|
||||
if (ClassFeatureValidators.isValidClassClassFeature(charClass, classFeature)) {
|
||||
additionalClassFeatures.push(classFeature);
|
||||
}
|
||||
}
|
||||
});
|
||||
//remove definitionKeysToRemove
|
||||
const filteredDefinitionClassFeatures = originalDefinitionClassFeatures.filter((feature) => !definitionKeysToRemove.has(ClassFeatureAccessors.getDefinitionKey(feature)));
|
||||
return [...filteredDefinitionClassFeatures, ...additionalClassFeatures];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
*/
|
||||
export function deriveMaxInfusions(charClass) {
|
||||
var _a;
|
||||
const features = getClassFeatures(charClass);
|
||||
const infuseFeature = features.find((classFeature) => ClassFeatureAccessors.getName(classFeature) === DB_STRING_INFUSE_ITEM);
|
||||
if (infuseFeature) {
|
||||
const infusionLevelScale = ClassFeatureAccessors.getLevelScale(infuseFeature);
|
||||
return (_a = infusionLevelScale === null || infusionLevelScale === void 0 ? void 0 : infusionLevelScale.fixedValue) !== null && _a !== void 0 ? _a : 0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
import { keyBy, orderBy } from 'lodash';
|
||||
import { AbilityDerivers } from '../Ability';
|
||||
import { CharacterDerivers, } from '../Character';
|
||||
import { ClassFeatureAccessors, ClassFeatureGenerators } from '../ClassFeature';
|
||||
import { DB_STRING_IMPROVED_PACT_WEAPON } from '../Core';
|
||||
import { DataOriginDataInfoKeyEnum, DataOriginTypeEnum } from '../DataOrigin';
|
||||
import { FormatUtils } from '../Format';
|
||||
import { ModifierDerivers, ModifierValidators } from '../Modifier';
|
||||
import { OptionAccessors } from '../Option';
|
||||
import { SpellAccessors, SpellDerivers, SpellGenerators, } from '../Spell';
|
||||
import { getActiveId, getBaseClassSpells, getClassFeatures, getDefinitionClassFeatures, getEnablesDedicatedWeapon, getEnablesHexWeapon, getEnablesPactWeapon, getId, getLevel, getMappingId, getName, getSlug, getSpellPrepareType, getSpellRules, getSpells, getSubclass, isPactMagicActive, isSpellcastingActive, isStartingClass, } from './accessors';
|
||||
import { deriveActiveId, deriveClassFeatureGroups, deriveConsolidatedClassFeatures, deriveDedicatedHexAndPactWeaponEnabled, deriveIsPactMagicActive, deriveIsSpellcastingActive, deriveSpellCastingLearningStyle, deriveSpellListIds, deriveSpellRules, deriveSpells, deriveUniqueKey, } from './derivers';
|
||||
export function generateBaseCharClasses(charClasses, optionalClassFeatures, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells, appContext, ruleData, classesLookupData, definitionPool, characterPreferences, characterId, choiceComponents, baseFeats) {
|
||||
const orderedClasses = orderBy(charClasses, [(charClass) => isStartingClass(charClass), (charClass) => getName(charClass)], ['desc', 'asc']);
|
||||
const hack__baseCharClasses = orderedClasses.map((charClass) => hack__generateHackBaseCharClass(charClass, optionalClassFeatures, ruleData, classesLookupData, characterPreferences.enableOptionalClassFeatures));
|
||||
return hack__baseCharClasses.map((charClass) => generateBaseCharClass(charClass, optionalClassFeatures, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells, appContext, ruleData, classesLookupData, definitionPool, characterId, choiceComponents, baseFeats));
|
||||
}
|
||||
export function hack__generateHackBaseCharClass(charClass, optionalClassFeatures, ruleData, classesLookupData, enableOptionalClassFeatures) {
|
||||
const consolidatedClassFeatureDefinitions = deriveConsolidatedClassFeatures(charClass, optionalClassFeatures, enableOptionalClassFeatures);
|
||||
return Object.assign(Object.assign({}, charClass), { spellRules: deriveSpellRules(charClass, consolidatedClassFeatureDefinitions, classesLookupData.choiceLookup, ruleData), isSpellcastingActive: deriveIsSpellcastingActive(consolidatedClassFeatureDefinitions, getLevel(charClass)), isPactMagicActive: deriveIsPactMagicActive(consolidatedClassFeatureDefinitions, getLevel(charClass)), classFeatures: consolidatedClassFeatureDefinitions });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param classSpells
|
||||
* @param classFeatures
|
||||
*/
|
||||
function updateClassFeatures(charClass, classSpells, classFeatures) {
|
||||
return classFeatures.map((classFeature) => {
|
||||
const spells = SpellGenerators.updateClassFeatureSpells(ClassFeatureAccessors.getSpells(classFeature), classSpells);
|
||||
const options = ClassFeatureAccessors.getOptions(classFeature).map((option) => {
|
||||
const spells = SpellGenerators.updateClassFeatureSpells(OptionAccessors.getSpells(option), classSpells);
|
||||
return Object.assign(Object.assign({}, option), { spells });
|
||||
});
|
||||
return Object.assign(Object.assign({}, classFeature), { spells,
|
||||
options });
|
||||
});
|
||||
}
|
||||
export function generateBaseCharClass(charClass, optionalClassFeatures, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells, appContext, ruleData, classesLookupData, definitionPool, characterId, choiceComponents, baseFeats) {
|
||||
const classModifiers = [];
|
||||
const featureSpells = [];
|
||||
const feats = [];
|
||||
const actions = [];
|
||||
const generatedClassFeatures = getDefinitionClassFeatures(charClass).map((classFeature) => ClassFeatureGenerators.generateClassFeature(charClass, classFeature, ruleData, classesLookupData, definitionPool, characterId, choiceComponents, baseFeats));
|
||||
// update modifiers, feats and actions arrays based on classFeatures
|
||||
generatedClassFeatures.forEach((generatedClassFeature) => {
|
||||
classModifiers.push(...ClassFeatureAccessors.getModifiers(generatedClassFeature));
|
||||
feats.push(...ClassFeatureAccessors.getFeats(generatedClassFeature));
|
||||
actions.push(...ClassFeatureAccessors.getActions(generatedClassFeature));
|
||||
ClassFeatureAccessors.getOptions(generatedClassFeature).forEach((option) => {
|
||||
classModifiers.push(...OptionAccessors.getModifiers(option));
|
||||
feats.push(...OptionAccessors.getFeats(option));
|
||||
actions.push(...OptionAccessors.getActions(option));
|
||||
});
|
||||
});
|
||||
const classSpells = deriveSpells(charClass, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells);
|
||||
const updatedFeatures = updateClassFeatures(charClass, classSpells, generatedClassFeatures);
|
||||
// update spells array base on updated classFeatures
|
||||
updatedFeatures.forEach((classFeature) => {
|
||||
featureSpells.push(...ClassFeatureAccessors.getSpells(classFeature));
|
||||
ClassFeatureAccessors.getOptions(classFeature).forEach((option) => {
|
||||
featureSpells.push(...OptionAccessors.getSpells(option));
|
||||
});
|
||||
});
|
||||
const { activeFeatures, visibleFeatures, orderedFeatures, uniqueFeatures } = deriveClassFeatureGroups(charClass, updatedFeatures, appContext);
|
||||
// do any class features or modifiers enable hex, pact or dedicated weapons
|
||||
//TODO eventually should just be able to use modifiers here and not have to check class feature names
|
||||
const { enablesHexWeapon, enablesPactWeapon, enablesDedicatedWeapon } = deriveDedicatedHexAndPactWeaponEnabled(updatedFeatures, classModifiers);
|
||||
return Object.assign(Object.assign({}, charClass), { activeId: deriveActiveId(charClass), spells: SpellGenerators.updateClassSpells(featureSpells, classSpells), modifiers: classModifiers, featureSpells, classFeatures: updatedFeatures, optionalClassFeatures, activeClassFeatures: activeFeatures, visibleClassFeatures: visibleFeatures, orderedClassFeatures: orderedFeatures, uniqueClassFeatures: uniqueFeatures, feats,
|
||||
actions,
|
||||
enablesDedicatedWeapon,
|
||||
enablesHexWeapon,
|
||||
enablesPactWeapon, slug: FormatUtils.cobaltSlugify(getName(charClass)), spellListIds: deriveSpellListIds(updatedFeatures, getLevel(charClass)), spellCastingLearningStyle: deriveSpellCastingLearningStyle(charClass) });
|
||||
}
|
||||
export function generateClassFeatureLookup(baseCharClasses) {
|
||||
const lookup = {};
|
||||
for (const baseCharClass of baseCharClasses) {
|
||||
for (const classFeature of baseCharClass.classFeatures) {
|
||||
if (classFeature.definition) {
|
||||
lookup[classFeature.definition.id] = classFeature;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateTotalClassLevel(classes) {
|
||||
return classes.reduce((acc, charClass) => (acc += getLevel(charClass)), 0);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
* @param ruleData
|
||||
* @param proficiencyBonus
|
||||
* @param modifiers
|
||||
* @param abilityLookup
|
||||
*/
|
||||
export function generateClassSpellInfoLookup(classes, ruleData, proficiencyBonus, modifiers, abilityLookup) {
|
||||
const lookup = {};
|
||||
classes.forEach((charClass) => {
|
||||
var _a;
|
||||
const classId = getId(charClass);
|
||||
const classSlug = getSlug(charClass);
|
||||
const classLevel = getLevel(charClass);
|
||||
const classSpellRules = getSpellRules(charClass);
|
||||
const spellPrepareType = getSpellPrepareType(charClass);
|
||||
const spellcastingModifier = AbilityDerivers.deriveStatModifier(classSpellRules.spellcastingAbilityStatId, abilityLookup);
|
||||
const knownCantripsMax = classSpellRules.levelCantripsKnownMaxes
|
||||
? classSpellRules.levelCantripsKnownMaxes[classLevel]
|
||||
: null;
|
||||
const preparedSpellsMax = classSpellRules.levelPreparedSpellMaxes
|
||||
? (_a = classSpellRules.levelPreparedSpellMaxes[classLevel]) !== null && _a !== void 0 ? _a : null // coallesce if the array is shorter than the class level, happens for prepared classes not using OSIRIS rules
|
||||
: null;
|
||||
const prepareMax = preparedSpellsMax !== null && preparedSpellsMax !== void 0 ? preparedSpellsMax : SpellDerivers.deriveSpellPrepareMax(spellPrepareType, classLevel, spellcastingModifier);
|
||||
const baseToHitModifier = SpellDerivers.deriveSpellAttackModifier(proficiencyBonus, spellcastingModifier);
|
||||
const bonusSpellSaveDcModifiers = modifiers.filter((modifier) => ModifierValidators.isBonusSpellSaveDc(modifier));
|
||||
const bonusSpellSaveDcModifierTotal = ModifierDerivers.sumModifiers(bonusSpellSaveDcModifiers, abilityLookup);
|
||||
const bonusClassCantripDamageModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusClassCantripDamageModifier(modifier, classSlug));
|
||||
const bonusClassCantripDamageModifierTotal = ModifierDerivers.sumModifiers(bonusClassCantripDamageModifiers, abilityLookup);
|
||||
const classSaveDcModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusClassSpellSaveDcModifier(modifier, classSlug));
|
||||
const classSaveDcModifierTotal = ModifierDerivers.sumModifiers(classSaveDcModifiers, abilityLookup);
|
||||
const bonusSpellAttackModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusSpellAttackModifier(modifier, null));
|
||||
const bonusSpellAttackModifierTotal = ModifierDerivers.sumModifiers(bonusSpellAttackModifiers, abilityLookup);
|
||||
const classSpellAttackModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusClassSpellAttackModifier(modifier, classSlug));
|
||||
const classSpellAttackModifierTotal = ModifierDerivers.sumModifiers(classSpellAttackModifiers, abilityLookup);
|
||||
const classSpellDamageModifiers = modifiers.filter((modifier) => ModifierValidators.isValidDamageClassSpellAttackModifier(modifier, classSlug));
|
||||
const classSpellDamageModifierTotal = ModifierDerivers.sumModifiers(classSpellDamageModifiers, abilityLookup);
|
||||
const spellSaveDc = CharacterDerivers.deriveAttackSaveValue(proficiencyBonus, spellcastingModifier) +
|
||||
bonusSpellSaveDcModifierTotal +
|
||||
classSaveDcModifierTotal;
|
||||
const bonusSpellAttack = bonusSpellAttackModifierTotal + classSpellAttackModifierTotal;
|
||||
const toHit = baseToHitModifier + bonusSpellAttack;
|
||||
lookup[classId] = {
|
||||
spellcastingModifier,
|
||||
baseToHitModifier,
|
||||
bonusSpellAttack,
|
||||
spellDamage: classSpellDamageModifierTotal,
|
||||
bonusCantripDamage: bonusClassCantripDamageModifierTotal,
|
||||
spellSaveDc,
|
||||
toHit,
|
||||
knownCantripsMax,
|
||||
prepareMax,
|
||||
knowsAllSpells: classSpellRules.knowsAllSpells,
|
||||
};
|
||||
});
|
||||
return lookup;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClasses
|
||||
* @param classSpellInfoLookup
|
||||
* @param overallSpellInfo
|
||||
* @param spellListDataOriginLookup
|
||||
* @param valueLookup
|
||||
* @param ruleData
|
||||
* @param modifierData
|
||||
*/
|
||||
export function generateCharClasses(charClasses, classSpellInfoLookup, overallSpellInfo, spellListDataOriginLookup, valueLookup, ruleData, modifierData) {
|
||||
return charClasses.map((charClass) => generateCharClass(charClass, classSpellInfoLookup, overallSpellInfo, spellListDataOriginLookup, valueLookup, ruleData, modifierData));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param classSpellInfoLookup
|
||||
* @param overallSpellInfo
|
||||
* @param spellListDataOriginLookup
|
||||
* @param valueLookup
|
||||
* @param ruleData
|
||||
* @param modifierData
|
||||
*/
|
||||
export function generateCharClass(charClass, classSpellInfoLookup, overallSpellInfo, spellListDataOriginLookup, valueLookup, ruleData, modifierData) {
|
||||
const classSpellInfo = classSpellInfoLookup[getId(charClass)];
|
||||
const generatedSpells = getBaseClassSpells(charClass).map((spell) => {
|
||||
const dataOriginSpell = SpellGenerators.generateDataOriginSpell(spell, DataOriginTypeEnum.CLASS, charClass, null, spellListDataOriginLookup);
|
||||
return SpellGenerators.generateClassSpell(dataOriginSpell, classSpellInfo, overallSpellInfo, valueLookup, ruleData, modifierData);
|
||||
});
|
||||
return Object.assign(Object.assign({}, charClass), { spells: generatedSpells });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateStartingClass(classes) {
|
||||
const startingClass = classes.find((charClass) => isStartingClass(charClass));
|
||||
return startingClass ? startingClass : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateHexWeaponEnabled(classes) {
|
||||
let hexWeaponEnabled = false;
|
||||
classes.forEach((charClass) => {
|
||||
hexWeaponEnabled = getEnablesHexWeapon(charClass) || hexWeaponEnabled;
|
||||
});
|
||||
return hexWeaponEnabled;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generatePactWeaponEnabled(classes) {
|
||||
let pactWeaponEnabled = false;
|
||||
classes.forEach((charClass) => {
|
||||
pactWeaponEnabled = getEnablesPactWeapon(charClass) || pactWeaponEnabled;
|
||||
});
|
||||
return pactWeaponEnabled;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateImprovedPactWeaponEnabled(classes) {
|
||||
let improvedPactWeaponEnabled = false;
|
||||
classes.forEach((charClass) => {
|
||||
if (improvedPactWeaponEnabled) {
|
||||
return;
|
||||
}
|
||||
const features = getClassFeatures(charClass);
|
||||
features.forEach((feature) => {
|
||||
if (improvedPactWeaponEnabled) {
|
||||
return;
|
||||
}
|
||||
const options = ClassFeatureAccessors.getOptions(feature);
|
||||
options.forEach((option) => {
|
||||
improvedPactWeaponEnabled =
|
||||
improvedPactWeaponEnabled || OptionAccessors.getName(option) === DB_STRING_IMPROVED_PACT_WEAPON;
|
||||
});
|
||||
});
|
||||
});
|
||||
return improvedPactWeaponEnabled;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateDedicatedWeaponEnabled(classes) {
|
||||
let dedicatedWeaponEnabled = false;
|
||||
classes.forEach((charClass) => {
|
||||
dedicatedWeaponEnabled = getEnablesDedicatedWeapon(charClass) || dedicatedWeaponEnabled;
|
||||
});
|
||||
return dedicatedWeaponEnabled;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateClassLevelLookup(classes) {
|
||||
return classes.reduce((acc, charClass) => {
|
||||
var _a, _b;
|
||||
acc[getId(charClass)] = getLevel(charClass);
|
||||
// add subclass level - this is used for Druid Circle of the Moon creature rules
|
||||
const subclassId = (_b = (_a = getSubclass(charClass)) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
|
||||
if (subclassId) {
|
||||
acc[subclassId] = getLevel(charClass);
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param modifierLookup
|
||||
* @param spellLookup
|
||||
* @param actionLookup
|
||||
* @param choiceLookup
|
||||
* @param optionLookup
|
||||
* @param valueLookup
|
||||
* @param featLookup
|
||||
* @param infusionChoiceInfusionLookup
|
||||
* @param knownInfusionLookupByChoiceKey
|
||||
* @param spellListDataOriginLookup
|
||||
*/
|
||||
export function generateClassesLookupData(modifierLookup, spellLookup, actionLookup, choiceLookup, optionLookup, valueLookup, featLookup, infusionChoiceInfusionLookup, knownInfusionLookupByChoiceKey, spellListDataOriginLookup) {
|
||||
return {
|
||||
modifierLookup,
|
||||
spellLookup,
|
||||
actionLookup,
|
||||
choiceLookup,
|
||||
optionLookup,
|
||||
valueLookup,
|
||||
featLookup,
|
||||
infusionChoiceInfusionLookup,
|
||||
knownInfusionLookupByChoiceKey,
|
||||
spellListDataOriginLookup,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateSpellcastingClasses(classes) {
|
||||
return classes.filter(isSpellcastingActive);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generatePactMagicClasses(classes) {
|
||||
return classes.filter(isPactMagicActive);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param spellcastingClasses
|
||||
* @param pactMagicClasses
|
||||
*/
|
||||
export function generateAggregatedSpellClasses(spellcastingClasses, pactMagicClasses) {
|
||||
return [...spellcastingClasses, ...pactMagicClasses];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateClassMappingIdLookupByActiveId(classes) {
|
||||
return classes.reduce((acc, charClass) => {
|
||||
acc[getActiveId(charClass)] = getMappingId(charClass);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
* @param isMulticlassCharacter
|
||||
*/
|
||||
export function generateClassesModifiers(classes, isMulticlassCharacter) {
|
||||
const modifiers = [];
|
||||
if (classes.length === 0) {
|
||||
return modifiers;
|
||||
}
|
||||
classes.forEach((charClass) => {
|
||||
getClassFeatures(charClass).forEach((classFeature) => {
|
||||
modifiers.push(...ClassFeatureAccessors.getModifiers(classFeature).filter((modifier) => ModifierValidators.isValidClassModifier(modifier, charClass, isMulticlassCharacter)));
|
||||
ClassFeatureAccessors.getOptions(classFeature).forEach((option) => {
|
||||
modifiers.push(...OptionAccessors.getModifiers(option).filter((modifier) => ModifierValidators.isValidClassModifier(modifier, charClass, isMulticlassCharacter)));
|
||||
});
|
||||
});
|
||||
});
|
||||
return modifiers;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateRefClassData(classes) {
|
||||
let data = {};
|
||||
classes.forEach((charClass) => {
|
||||
data[deriveUniqueKey(charClass)] = {
|
||||
[DataOriginDataInfoKeyEnum.PRIMARY]: charClass,
|
||||
[DataOriginDataInfoKeyEnum.PARENT]: null,
|
||||
};
|
||||
});
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateClassSpellListSpellsLookup(classes) {
|
||||
const lookup = {};
|
||||
classes.forEach((charClass) => {
|
||||
const spells = getSpells(charClass);
|
||||
spells.forEach((spell) => {
|
||||
const spellListId = SpellAccessors.getSpellListId(spell);
|
||||
if (spellListId !== null) {
|
||||
if (!lookup[spellListId]) {
|
||||
lookup[spellListId] = [];
|
||||
}
|
||||
lookup[spellListId].push({
|
||||
spell,
|
||||
charClass,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return lookup;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
*/
|
||||
export function generateBaseClassLookup(classes) {
|
||||
return keyBy(classes, (baseClass) => getMappingId(baseClass));
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import * as ClassAccessors from './accessors';
|
||||
import * as ClassDerivers from './derivers';
|
||||
import * as ClassGenerators from './generators';
|
||||
import * as ClassTypings from './typings';
|
||||
import * as ClassUtils from './utils';
|
||||
import * as ClassValidators from './validators';
|
||||
export * from './typings';
|
||||
export { ClassAccessors, ClassGenerators, ClassDerivers, ClassValidators, ClassUtils };
|
||||
export default Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, ClassAccessors), ClassGenerators), ClassTypings), ClassDerivers), ClassValidators), ClassUtils);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { difference } from 'lodash';
|
||||
import { getLevel, getOptionalClassFeatures, getSpellListIds } from './accessors';
|
||||
import { deriveConsolidatedClassFeatures, deriveSpellListIds } from './derivers';
|
||||
/**
|
||||
*
|
||||
* @param classes
|
||||
* @param newEnableOptionalClassFeatures
|
||||
*/
|
||||
export function getUpdateEnableOptionalClassFeaturesSpellListIdsToRemove(classes, newEnableOptionalClassFeatures) {
|
||||
const spellListIdsToRemove = [];
|
||||
classes.forEach((charClass) => {
|
||||
const existingSpellListIds = getSpellListIds(charClass);
|
||||
const newClassFeatures = deriveConsolidatedClassFeatures(charClass, getOptionalClassFeatures(charClass), newEnableOptionalClassFeatures);
|
||||
const newSpellListIds = deriveSpellListIds(newClassFeatures, getLevel(charClass));
|
||||
spellListIdsToRemove.push(...difference(existingSpellListIds, newSpellListIds));
|
||||
});
|
||||
return spellListIdsToRemove;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { getId, getSubclass } from './accessors';
|
||||
/**
|
||||
*
|
||||
* @param charClass
|
||||
* @param id
|
||||
*/
|
||||
export function isValidClassId(charClass, id) {
|
||||
var _a, _b;
|
||||
const subClassId = (_b = (_a = getSubclass(charClass)) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : -1;
|
||||
return id === getId(charClass) || id === subClassId;
|
||||
}
|
||||
Reference in New Issue
Block a user