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,253 @@
|
||||
import { DefinitionGenerators } from '../Definition';
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getAvatarUrl(race) {
|
||||
return race.avatarUrl;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getLargeAvatarUrl(race) {
|
||||
return race.largeAvatarUrl;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getPortraitAvatarUrl(race) {
|
||||
return race.portraitAvatarUrl;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getMoreDetailsUrl(race) {
|
||||
return race.moreDetailsUrl;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getBaseName(race) {
|
||||
return race.baseName;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getBaseRaceId(race) {
|
||||
return race.baseRaceId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getBaseRaceName(race) {
|
||||
return race.baseRaceName;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getBaseRaceTypeId(race) {
|
||||
return race.baseRaceTypeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getDescription(race) {
|
||||
return race.description;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getEntityRaceId(race) {
|
||||
return race.entityRaceId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getEntityRaceTypeId(race) {
|
||||
return race.entityRaceTypeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getFeatIds(race) {
|
||||
var _a;
|
||||
return (_a = race.featIds) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getFullName(race) {
|
||||
return race.fullName;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getGroupIds(race) {
|
||||
var _a;
|
||||
return (_a = race.groupIds) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getIsHomebrew(race) {
|
||||
return race.isHomebrew;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getIsSubRace(race) {
|
||||
return race.isSubRace;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSizeInfo(race) {
|
||||
return race.sizeInfo;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSize(race) {
|
||||
return race.size;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSizeId(race) {
|
||||
return race.sizeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSubRaceShortName(race) {
|
||||
return race.subRaceShortName;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getDefinitionRacialTraits(race) {
|
||||
var _a;
|
||||
return (_a = race.racialTraits) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getType(race) {
|
||||
return race.type;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getVisibleRacialTraits(race) {
|
||||
return race.visibleRacialTraits;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getWeightSpeeds(race) {
|
||||
return race.weightSpeeds;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getRacialTraits(race) {
|
||||
return race.racialTraits;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getFeats(race) {
|
||||
return race.feats;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getModifiers(race) {
|
||||
return race.modifiers;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getActions(race) {
|
||||
return race.actions;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSpells(race) {
|
||||
return race.spells;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getDefinitionSources(race) {
|
||||
var _a;
|
||||
return (_a = race.sources) !== null && _a !== void 0 ? _a : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSources(race) {
|
||||
return getDefinitionSources(race);
|
||||
}
|
||||
/**
|
||||
* This will be replaced once we have definitionKey on the entity, so no need to derive it
|
||||
* @param race
|
||||
*/
|
||||
export function getDefinitionKey(race) {
|
||||
return DefinitionGenerators.generateDefinitionKey(getEntityRaceTypeId(race).toString(), getEntityRaceId(race).toString());
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getSpellListIds(race) {
|
||||
return race.spellListIds;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getOptionalOrigins(race) {
|
||||
return race.optionalOrigins;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function getCalledOutRacialTraits(race) {
|
||||
return race.calledOutRacialTraits;
|
||||
}
|
||||
export function getIsLegacy(race) {
|
||||
return race.isLegacy;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export var RaceTypeEnum;
|
||||
(function (RaceTypeEnum) {
|
||||
RaceTypeEnum[RaceTypeEnum["BASE_RACE"] = 1] = "BASE_RACE";
|
||||
RaceTypeEnum[RaceTypeEnum["SUB_RACE"] = 2] = "SUB_RACE";
|
||||
RaceTypeEnum[RaceTypeEnum["VARIANT"] = 3] = "VARIANT";
|
||||
})(RaceTypeEnum || (RaceTypeEnum = {}));
|
||||
@@ -0,0 +1,212 @@
|
||||
import { groupBy, orderBy } from 'lodash';
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
import { CreatureSizeEnum, CreatureSizeNameEnum, FeatureTypeEnum } from '../Core';
|
||||
import { FormatUtils } from '../Format';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { ModifierAccessors, ModifierSubTypeEnum, ModifierValidators, STAT_ABILITY_SCORE_LIST, } from '../Modifier';
|
||||
import { OptionalOriginAccessors } from '../OptionalOrigin';
|
||||
import { RacialTraitAccessors, RacialTraitDerivers, RacialTraitValidators } from '../RacialTrait';
|
||||
import { RuleDataUtils } from '../RuleData';
|
||||
import { getDefinitionRacialTraits } from './accessors';
|
||||
import { hack__deriveRaceSize } from './hacks';
|
||||
/**
|
||||
* has mirrored deriver ClassDerivers.deriveConsolidatedClassFeatures
|
||||
* - most likely update together
|
||||
*
|
||||
* @param race
|
||||
* @param optionalOrigins
|
||||
* @param enableOptionalOrigins
|
||||
*/
|
||||
export function deriveConsolidatedRacialTraits(race, optionalOrigins, enableOptionalOrigins) {
|
||||
//filtering because after generating Race, this function is used in getUpdateEnableOptionalOriginsSpellListIdsToRemove
|
||||
// to determine updated look of race and we don't store original definition info for race
|
||||
const originalDefinitionRacialTraits = getDefinitionRacialTraits(race).filter((trait) => RacialTraitAccessors.getFeatureType(trait) === FeatureTypeEnum.GRANTED);
|
||||
if (!enableOptionalOrigins) {
|
||||
return originalDefinitionRacialTraits;
|
||||
}
|
||||
const additionalRacialTraits = [];
|
||||
const definitionKeysToRemove = new Set();
|
||||
optionalOrigins.forEach((optionalOrigin) => {
|
||||
const racialTrait = OptionalOriginAccessors.getRacialTrait(optionalOrigin);
|
||||
if (racialTrait === null) {
|
||||
return;
|
||||
}
|
||||
const featureType = RacialTraitAccessors.getFeatureType(racialTrait);
|
||||
switch (featureType) {
|
||||
case FeatureTypeEnum.REPLACEMENT: {
|
||||
const affectedDefinitionKey = OptionalOriginAccessors.getAffectedRacialTraitDefinitionKey(optionalOrigin);
|
||||
const affectedFeatureKeys = RacialTraitAccessors.getAffectedFeatureDefinitionKeys(racialTrait);
|
||||
//verify this is a valid replacement
|
||||
if (affectedDefinitionKey &&
|
||||
affectedFeatureKeys.includes(affectedDefinitionKey) &&
|
||||
RacialTraitValidators.isValidRaceRacialTrait(race, racialTrait)) {
|
||||
definitionKeysToRemove.add(affectedDefinitionKey);
|
||||
additionalRacialTraits.push(racialTrait);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FeatureTypeEnum.ADDITIONAL:
|
||||
case FeatureTypeEnum.GRANTED:
|
||||
default:
|
||||
if (RacialTraitValidators.isValidRaceRacialTrait(race, racialTrait)) {
|
||||
additionalRacialTraits.push(racialTrait);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
//remove definitionKeysToRemove
|
||||
const filteredDefinitionRacialTraits = originalDefinitionRacialTraits.filter((trait) => !definitionKeysToRemove.has(RacialTraitAccessors.getDefinitionKey(trait)));
|
||||
return [...filteredDefinitionRacialTraits, ...additionalRacialTraits];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param racialTraits
|
||||
* @param appContext
|
||||
*/
|
||||
export function deriveVisibleRacialTraits(racialTraits, appContext) {
|
||||
return racialTraits.filter((racialTrait) => !RacialTraitDerivers.deriveHideInContext(racialTrait, appContext));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param racialTraits
|
||||
*/
|
||||
export function deriveOrderedRacialTraits(racialTraits) {
|
||||
return orderBy(racialTraits, [
|
||||
(racialTrait) => RacialTraitAccessors.getDisplayOrder(racialTrait),
|
||||
(racialTrait) => RacialTraitAccessors.getName(racialTrait),
|
||||
]);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param racialTraits
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveCalledOutRacialTraits(racialTraits, ruleData) {
|
||||
const filteredTraits = racialTraits.filter((trait) => RacialTraitAccessors.isCalledOut(trait));
|
||||
const orderedTraits = deriveOrderedRacialTraits(filteredTraits);
|
||||
const calledOutTraitNames = [];
|
||||
const abilityScoreIncreases = [];
|
||||
const abilityScoreIncreasesToChoose = [];
|
||||
const modifierLookupBySubType = {};
|
||||
orderedTraits.forEach((trait) => {
|
||||
const name = RacialTraitAccessors.getName(trait);
|
||||
const modifiers = RacialTraitAccessors.getModifiers(trait);
|
||||
if (modifiers.length) {
|
||||
//aggregate all ability score related modifiers into a lookup
|
||||
let abilityModifiersCount = 0;
|
||||
modifiers.forEach((modifier) => {
|
||||
const statId = ModifierAccessors.getEntityId(modifier);
|
||||
if ((statId && ModifierValidators.isValidBonusStatScoreModifier(modifier, statId)) ||
|
||||
ModifierValidators.isValidBonusChooseAbilityScoreModifier(modifier)) {
|
||||
abilityModifiersCount++;
|
||||
const modifierSubType = ModifierAccessors.getSubType(modifier);
|
||||
if (!modifierSubType) {
|
||||
return;
|
||||
}
|
||||
if (!modifierLookupBySubType.hasOwnProperty(modifierSubType)) {
|
||||
modifierLookupBySubType[modifierSubType] = [];
|
||||
}
|
||||
modifierLookupBySubType[modifierSubType].push(modifier);
|
||||
}
|
||||
});
|
||||
if (abilityModifiersCount === 0) {
|
||||
calledOutTraitNames.push(name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
calledOutTraitNames.push(name);
|
||||
}
|
||||
});
|
||||
let hasAllAbilityStatScoreGrantedBonuses = false;
|
||||
const modifierSubTypeStrings = Object.keys(modifierLookupBySubType);
|
||||
const filteredSubTypeStrings = modifierSubTypeStrings.filter((subType) => subType !== ModifierSubTypeEnum.CHOOSE_AN_ABILITY_SCORE);
|
||||
if (filteredSubTypeStrings.length === STAT_ABILITY_SCORE_LIST.length &&
|
||||
filteredSubTypeStrings.every((subType) => STAT_ABILITY_SCORE_LIST.includes(subType))) {
|
||||
//TODO should check all the values are the same (this is only applies to Humans right now)
|
||||
hasAllAbilityStatScoreGrantedBonuses = true;
|
||||
abilityScoreIncreases.push(`+1 to All Ability Scores`);
|
||||
}
|
||||
modifierSubTypeStrings.forEach((modifierSubType) => {
|
||||
const modifiers = HelperUtils.lookupDataOrFallback(modifierLookupBySubType, modifierSubType);
|
||||
if (modifiers !== null) {
|
||||
if (modifierSubType === ModifierSubTypeEnum.CHOOSE_AN_ABILITY_SCORE) {
|
||||
const modifiersByValueLookup = groupBy(modifiers, (modifier) => ModifierAccessors.getValue(modifier));
|
||||
Object.keys(modifiersByValueLookup).forEach((value) => {
|
||||
const lookupModifiers = HelperUtils.lookupDataOrFallback(modifiersByValueLookup, value);
|
||||
if (lookupModifiers !== null) {
|
||||
const numberOfModifiers = lookupModifiers.length;
|
||||
abilityScoreIncreasesToChoose.push(`+${value} to ${FormatUtils.upperCaseFirstLetterOnly(FormatUtils.convertSingleDigitIntToWord(numberOfModifiers))} Other Ability Score${numberOfModifiers > 1 ? 's' : ''}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (!hasAllAbilityStatScoreGrantedBonuses) {
|
||||
const statId = ModifierAccessors.getEntityId(modifiers[0]);
|
||||
if (!statId) {
|
||||
return;
|
||||
}
|
||||
const modifiersValueTotal = modifiers.reduce((acc, modifier) => {
|
||||
const value = ModifierAccessors.getValue(modifier);
|
||||
if (value !== null) {
|
||||
acc += value;
|
||||
}
|
||||
return acc;
|
||||
}, 0);
|
||||
abilityScoreIncreases.push(`+${modifiersValueTotal} ${RuleDataUtils.getStatNameById(statId, ruleData, true)}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
return [...abilityScoreIncreases, ...abilityScoreIncreasesToChoose, ...calledOutTraitNames];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param racialTraits
|
||||
*/
|
||||
export function deriveSpellListIds(racialTraits) {
|
||||
const spellListIds = [];
|
||||
racialTraits.forEach((feature) => {
|
||||
spellListIds.push(...RacialTraitAccessors.getSpellListIds(feature));
|
||||
});
|
||||
return spellListIds;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param experienceInfo
|
||||
* @param raceModifiers
|
||||
*/
|
||||
export function deriveRaceSize(race, experienceInfo, raceModifiers) {
|
||||
//temp hack handles specific race size for granted level size changes - need to set up logic for that
|
||||
let [sizeId, size] = hack__deriveRaceSize(race, experienceInfo);
|
||||
let sizeModifiersIds = raceModifiers
|
||||
.filter(ModifierValidators.isSizeModifier)
|
||||
.map(ModifierAccessors.getEntityId)
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
let largestSizeModifierId = sizeModifiersIds.length ? Math.max(...sizeModifiersIds) : null;
|
||||
if (largestSizeModifierId !== null) {
|
||||
sizeId = largestSizeModifierId;
|
||||
size = deriveRaceSizeName(sizeId);
|
||||
}
|
||||
return [sizeId, size];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param sizeId
|
||||
*/
|
||||
export function deriveRaceSizeName(sizeId) {
|
||||
switch (sizeId) {
|
||||
case CreatureSizeEnum.TINY:
|
||||
return CreatureSizeNameEnum.TINY;
|
||||
case CreatureSizeEnum.SMALL:
|
||||
return CreatureSizeNameEnum.SMALL;
|
||||
case CreatureSizeEnum.MEDIUM:
|
||||
return CreatureSizeNameEnum.MEDIUM;
|
||||
case CreatureSizeEnum.LARGE:
|
||||
return CreatureSizeNameEnum.LARGE;
|
||||
case CreatureSizeEnum.HUGE:
|
||||
return CreatureSizeNameEnum.HUGE;
|
||||
case CreatureSizeEnum.GARGANTUAN:
|
||||
return CreatureSizeNameEnum.GARGANTUAN;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import { CreatureRuleGenerators } from '../CreatureRule';
|
||||
import { DataOriginDataInfoKeyEnum, DataOriginGenerators, DataOriginTypeEnum, } from '../DataOrigin';
|
||||
import { OptionAccessors } from '../Option';
|
||||
import { RacialTraitAccessors, RacialTraitGenerators } from '../RacialTrait';
|
||||
import { RuleDataUtils } from '../RuleData';
|
||||
import { getRacialTraits, getSpellListIds, getVisibleRacialTraits } from './accessors';
|
||||
import { deriveCalledOutRacialTraits, deriveConsolidatedRacialTraits, deriveOrderedRacialTraits, deriveRaceSize, deriveSpellListIds, deriveVisibleRacialTraits, } from './derivers';
|
||||
import { hack__filterOutAsi } from './hacks';
|
||||
/**
|
||||
*
|
||||
* @param optionLookup
|
||||
* @param actionLookup
|
||||
* @param choiceLookup
|
||||
* @param modifierLookup
|
||||
* @param spellLookup
|
||||
* @param featLookup
|
||||
* @param valueLookup
|
||||
* @param spellListDataOriginLookup
|
||||
*/
|
||||
export function generateRaceLookupData(optionLookup, actionLookup, choiceLookup, modifierLookup, spellLookup, featLookup, valueLookup, spellListDataOriginLookup) {
|
||||
return {
|
||||
actionLookup,
|
||||
choiceLookup,
|
||||
featLookup,
|
||||
modifierLookup,
|
||||
optionLookup,
|
||||
spellListDataOriginLookup,
|
||||
spellLookup,
|
||||
valueLookup,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param optionalOrigins
|
||||
* @param raceLookupData
|
||||
* @param experienceInfo
|
||||
* @param appContext
|
||||
* @param ruleData
|
||||
* @param definitionPool
|
||||
* @param characterPreferences
|
||||
*/
|
||||
export function generateRace(race, optionalOrigins, raceLookupData, experienceInfo, appContext, ruleData, definitionPool, characterPreferences, isInitialAsiFromFeat) {
|
||||
if (!race) {
|
||||
return race;
|
||||
}
|
||||
const raceModifiers = [];
|
||||
const raceSpells = [];
|
||||
const raceFeats = [];
|
||||
const raceActions = [];
|
||||
// Process racial traits:
|
||||
// Consolidate from multiple sources, apply filtering, apply ordering,
|
||||
// then generate the hydrated RacialTrait from the contracts.
|
||||
const traitContracts = deriveOrderedRacialTraits(hack__filterOutAsi(deriveConsolidatedRacialTraits(race, optionalOrigins, characterPreferences.enableOptionalOrigins), isInitialAsiFromFeat));
|
||||
const generatedRacialTraits = traitContracts.map((racialTrait) => {
|
||||
const generatedRacialTrait = RacialTraitGenerators.generateRacialTrait(race, racialTrait, raceLookupData.optionLookup, raceLookupData.actionLookup, raceLookupData.choiceLookup, raceLookupData.modifierLookup, raceLookupData.spellLookup, raceLookupData.featLookup, raceLookupData.valueLookup, raceLookupData.spellListDataOriginLookup, ruleData, definitionPool);
|
||||
raceModifiers.push(...RacialTraitAccessors.getModifiers(generatedRacialTrait));
|
||||
raceSpells.push(...RacialTraitAccessors.getSpells(generatedRacialTrait));
|
||||
raceFeats.push(...RacialTraitAccessors.getFeats(generatedRacialTrait));
|
||||
raceActions.push(...RacialTraitAccessors.getActions(generatedRacialTrait));
|
||||
RacialTraitAccessors.getOptions(generatedRacialTrait).forEach((option) => {
|
||||
raceSpells.push(...OptionAccessors.getSpells(option));
|
||||
raceFeats.push(...OptionAccessors.getFeats(option));
|
||||
raceActions.push(...OptionAccessors.getActions(option));
|
||||
raceModifiers.push(...OptionAccessors.getModifiers(option));
|
||||
});
|
||||
return generatedRacialTrait;
|
||||
});
|
||||
const visibleRacialTraits = deriveVisibleRacialTraits(generatedRacialTraits, appContext);
|
||||
const [sizeId, size] = deriveRaceSize(race, experienceInfo, raceModifiers);
|
||||
const sizeInfo = RuleDataUtils.getCreatureSizeInfo(sizeId, ruleData);
|
||||
return Object.assign(Object.assign({}, race), { modifiers: raceModifiers, racialTraits: generatedRacialTraits, optionalOrigins,
|
||||
visibleRacialTraits, calledOutRacialTraits: deriveCalledOutRacialTraits(generatedRacialTraits, ruleData), spells: raceSpells, feats: raceFeats, actions: raceActions, sizeInfo,
|
||||
sizeId,
|
||||
size, spellListIds: deriveSpellListIds(generatedRacialTraits) });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param xpInfo
|
||||
* @param ruleData
|
||||
*/
|
||||
export function generateRaceCreatureRules(race, xpInfo, ruleData) {
|
||||
const rules = [];
|
||||
if (!race) {
|
||||
return rules;
|
||||
}
|
||||
getRacialTraits(race).forEach((racialTrait) => {
|
||||
const dataOrigin = DataOriginGenerators.generateDataOrigin(DataOriginTypeEnum.RACE, racialTrait, race);
|
||||
const featureRules = RacialTraitAccessors.getCreatureRules(racialTrait);
|
||||
featureRules.forEach((rule) => {
|
||||
rules.push(CreatureRuleGenerators.generateRule(rule, dataOrigin, xpInfo, ruleData));
|
||||
});
|
||||
const options = RacialTraitAccessors.getOptions(racialTrait);
|
||||
options.forEach((option) => {
|
||||
const optionRules = OptionAccessors.getCreatureRules(option);
|
||||
optionRules.forEach((rule) => {
|
||||
rules.push(CreatureRuleGenerators.generateRule(rule, dataOrigin, xpInfo, ruleData));
|
||||
});
|
||||
});
|
||||
});
|
||||
return rules;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function generateRaceModifiers(race) {
|
||||
const modifiers = [];
|
||||
if (race === null) {
|
||||
return modifiers;
|
||||
}
|
||||
getRacialTraits(race).forEach((racialTrait) => {
|
||||
modifiers.push(...RacialTraitAccessors.getModifiers(racialTrait));
|
||||
RacialTraitAccessors.getOptions(racialTrait).forEach((option) => {
|
||||
modifiers.push(...OptionAccessors.getModifiers(option));
|
||||
});
|
||||
});
|
||||
return modifiers;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function generateRefRaceData(race) {
|
||||
let data = {};
|
||||
if (race !== null) {
|
||||
getRacialTraits(race).forEach((racialTrait) => {
|
||||
data[RacialTraitAccessors.getUniqueKey(racialTrait)] = {
|
||||
[DataOriginDataInfoKeyEnum.PRIMARY]: racialTrait,
|
||||
[DataOriginDataInfoKeyEnum.PARENT]: race,
|
||||
};
|
||||
});
|
||||
}
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
*/
|
||||
export function generateGlobalSpellListIds(race) {
|
||||
return race ? getSpellListIds(race) : [];
|
||||
}
|
||||
export function generateCurrentLevelRacialTraits(race, characterLevel) {
|
||||
const traits = race ? getVisibleRacialTraits(race) : [];
|
||||
return traits.filter((trait) => {
|
||||
const requiredLevel = RacialTraitAccessors.getRequiredLevel(trait);
|
||||
return characterLevel >= requiredLevel;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { CreatureSizeEnum, CreatureSizeNameEnum, DB_STRING_VERDAN, INITIAL_ASI_TAG_NAME, } from '../Core';
|
||||
import { RacialTraitAccessors } from '../RacialTrait';
|
||||
import { getSize, getSizeId } from './accessors';
|
||||
//temp hack handles specific race size for granted level size changes - need to set up logic for that
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param experienceInfo
|
||||
*/
|
||||
export function hack__deriveRaceSize(race, experienceInfo) {
|
||||
let sizeId = getSizeId(race);
|
||||
let size = getSize(race);
|
||||
if (race.baseName === DB_STRING_VERDAN && experienceInfo.currentLevel >= 5 && !race.isHomebrew) {
|
||||
sizeId = CreatureSizeEnum.MEDIUM;
|
||||
size = CreatureSizeNameEnum.MEDIUM;
|
||||
}
|
||||
return [sizeId, size];
|
||||
}
|
||||
export function hack__filterOutAsi(traits, isInitialAsiFromFeat) {
|
||||
if (!isInitialAsiFromFeat) {
|
||||
// no changes needed if the initial ASI isn't coming from a Background Feat
|
||||
return traits;
|
||||
}
|
||||
// Keep traits that aren't the initial ASI
|
||||
return traits.filter((trait) => !RacialTraitAccessors.getCategories(trait).some((cat) => cat.tagName === INITIAL_ASI_TAG_NAME));
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import * as RaceAccessors from './accessors';
|
||||
import * as RaceConstants from './constants';
|
||||
import * as RaceDerivers from './derivers';
|
||||
import * as RaceGenerators from './generators';
|
||||
import * as RaceHacks from './hacks';
|
||||
import * as RaceTypings from './typings';
|
||||
import * as RaceUtils from './utils';
|
||||
import * as RaceValidators from './validators';
|
||||
export * from './constants';
|
||||
export * from './typings';
|
||||
export { RaceAccessors, RaceDerivers, RaceGenerators, RaceUtils, RaceHacks, RaceValidators };
|
||||
export default Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, RaceAccessors), RaceConstants), RaceDerivers), RaceGenerators), RaceHacks), RaceTypings), RaceUtils), RaceValidators);
|
||||
@@ -0,0 +1,14 @@
|
||||
import { difference } from 'lodash';
|
||||
import { getOptionalOrigins, getSpellListIds } from './accessors';
|
||||
import { deriveConsolidatedRacialTraits, deriveSpellListIds } from './derivers';
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param newEnableOptionalOrigins
|
||||
*/
|
||||
export function getUpdateEnableOptionalOriginsSpellListIdsToRemove(race, newEnableOptionalOrigins) {
|
||||
const existingSpellListIds = getSpellListIds(race);
|
||||
const newRacialTraits = deriveConsolidatedRacialTraits(race, getOptionalOrigins(race), newEnableOptionalOrigins);
|
||||
const newSpellListIds = deriveSpellListIds(newRacialTraits);
|
||||
return difference(existingSpellListIds, newSpellListIds);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { getBaseRaceId, getEntityRaceId } from './accessors';
|
||||
/**
|
||||
*
|
||||
* @param race
|
||||
* @param id
|
||||
*/
|
||||
export function isValidRaceId(race, id) {
|
||||
return id === getBaseRaceId(race) || id === getEntityRaceId(race);
|
||||
}
|
||||
Reference in New Issue
Block a user