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,187 @@
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getBaseScore(ability) {
|
||||
return ability.baseScore;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getClassBonuses(ability) {
|
||||
return ability.classBonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getEntityTypeId(ability) {
|
||||
return ability.entityTypeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getId(ability) {
|
||||
return ability.id;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getIsMaxed(ability) {
|
||||
return ability.isMaxed;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getLabel(ability) {
|
||||
return ability.label;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getMaxStatScore(ability) {
|
||||
return ability.maxStatScore;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getMiscBonus(ability) {
|
||||
return ability.miscBonus;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getModifier(ability) {
|
||||
return ability.modifier;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getName(ability) {
|
||||
return ability.name;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getOtherBonus(ability) {
|
||||
return ability.otherBonus;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getOverrideScore(ability) {
|
||||
return ability.overrideScore;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getRacialBonus(ability) {
|
||||
return ability.racialBonus;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getScore(ability) {
|
||||
return ability.score;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getSetScore(ability) {
|
||||
return ability.setScore;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getStackingBonus(ability) {
|
||||
return ability.stackingBonus;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getStatKey(ability) {
|
||||
return ability.statKey;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getTotalScore(ability) {
|
||||
return ability.totalScore;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getProficiency(ability) {
|
||||
return ability.proficiency;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getProficiencyLevel(ability) {
|
||||
return ability.proficiencyLevel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getIsSaveModifierModified(ability) {
|
||||
return ability.isSaveModifierModified;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getIsSaveOverridden(ability) {
|
||||
return ability.isSaveOverridden;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getIsSaveProficiencyModified(ability) {
|
||||
return ability.isSaveProficiencyModified;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getSave(ability) {
|
||||
return ability.save;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
export function getSaveBonuses(ability) {
|
||||
return ability.saveBonuses;
|
||||
}
|
||||
export function getAllStatBonusSuppliers(ability) {
|
||||
return ability.allStatBonusSuppliers;
|
||||
}
|
||||
export function getStatSetScoreSuppliers(ability) {
|
||||
return ability.statSetScoreSuppliers;
|
||||
}
|
||||
export function getStatMaxBonusSuppliers(ability) {
|
||||
return ability.statMaxBonusSuppliers;
|
||||
}
|
||||
export function getStackingBonusSuppliers(ability) {
|
||||
return ability.stackingBonusSuppliers;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
import { CharacterDerivers } from '../Character';
|
||||
import { ProficiencyLevelEnum } from '../Core';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { ModifierAccessors, ModifierValidators } from '../Modifier';
|
||||
import { getId, getModifier, getScore } from './accessors';
|
||||
/**
|
||||
*
|
||||
* @param abilityId
|
||||
* @param modifiers
|
||||
* @returns TODORETURN
|
||||
*/
|
||||
export function deriveHighestSetAbilityScore(abilityId, modifiers) {
|
||||
const statSetScoreModifiers = modifiers.filter((modifier) => ModifierValidators.isValidSetStatScoreModifier(modifier, abilityId));
|
||||
const statSetScoreModifierValues = statSetScoreModifiers
|
||||
.map((modifier) => ModifierAccessors.getValue(modifier))
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
if (!statSetScoreModifierValues.length) {
|
||||
return 0;
|
||||
}
|
||||
return Math.max(...statSetScoreModifierValues);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* @param abilityLookup
|
||||
* @param defaultValue
|
||||
*/
|
||||
export function deriveStatModifier(id, abilityLookup, defaultValue = 0) {
|
||||
if (id === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
const ability = HelperUtils.lookupDataOrFallback(abilityLookup, id);
|
||||
if (ability === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
const modifier = getModifier(ability);
|
||||
if (modifier === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return modifier;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* @param abilityLookup
|
||||
* @param defaultValue
|
||||
*/
|
||||
export function deriveStatScore(id, abilityLookup, defaultValue = 0) {
|
||||
if (id === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
const ability = HelperUtils.lookupDataOrFallback(abilityLookup, id);
|
||||
if (ability === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
const score = getScore(ability);
|
||||
if (score === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param hasSaveProficiency
|
||||
* @param proficiencyLevelOverride
|
||||
*/
|
||||
export function deriveProficiencyLevel(hasSaveProficiency, proficiencyLevelOverride) {
|
||||
let proficiencyLevel = hasSaveProficiency
|
||||
? ProficiencyLevelEnum.FULL
|
||||
: ProficiencyLevelEnum.NONE;
|
||||
if (proficiencyLevelOverride !== null) {
|
||||
proficiencyLevel = proficiencyLevelOverride;
|
||||
}
|
||||
return proficiencyLevel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param abilityScore
|
||||
* @param modifiers
|
||||
* @param proficiencyBonus
|
||||
* @param proficiencyLevelOverride
|
||||
* @param saveOverride
|
||||
* @param statBonusSaveModifierTotal
|
||||
* @param magicBonus
|
||||
* @param miscBonus
|
||||
*/
|
||||
export function deriveAbilitySaveInfo(abilityScore, modifiers, proficiencyBonus, proficiencyLevelOverride, saveOverride, statBonusSaveModifierTotal, magicBonus, miscBonus) {
|
||||
const abilityId = getId(abilityScore);
|
||||
const statProficiencySaveModifiers = modifiers.filter((modifier) => ModifierValidators.isValidProficiencySaveModifier(modifier, abilityId));
|
||||
const hasSaveProficiency = statProficiencySaveModifiers.length > 0;
|
||||
const proficiencyLevel = deriveProficiencyLevel(hasSaveProficiency, proficiencyLevelOverride);
|
||||
const proficiencyBonusAmount = CharacterDerivers.deriveProficiencyBonusAmount(proficiencyLevel, proficiencyBonus);
|
||||
let save = 0;
|
||||
let saveBonuses = 0;
|
||||
if (saveOverride !== null) {
|
||||
save = saveOverride;
|
||||
}
|
||||
else {
|
||||
saveBonuses = statBonusSaveModifierTotal + magicBonus + miscBonus;
|
||||
const modifier = getModifier(abilityScore);
|
||||
save = (modifier ? modifier : 0) + saveBonuses + proficiencyBonusAmount;
|
||||
}
|
||||
const isSaveOverridden = saveOverride !== null;
|
||||
return {
|
||||
proficiency: hasSaveProficiency,
|
||||
proficiencyLevel,
|
||||
isSaveProficiencyModified: proficiencyLevelOverride !== null,
|
||||
isSaveModifierModified: !!miscBonus || !!magicBonus || isSaveOverridden,
|
||||
save,
|
||||
saveBonuses,
|
||||
isSaveOverridden,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
import { groupBy } from 'lodash';
|
||||
import keyBy from 'lodash/keyBy';
|
||||
import { ProficiencyLevelEnum } from '../Core';
|
||||
import { DataOriginGenerators, DataOriginTypeEnum } from '../DataOrigin';
|
||||
import { ModifierDerivers, ModifierGenerators, ModifierValidators } from '../Modifier';
|
||||
import { RuleDataAccessors } from '../RuleData';
|
||||
import { ValueHacks, ValueUtils } from '../Value';
|
||||
import { getEntityTypeId, getId } from './accessors';
|
||||
import { deriveAbilitySaveInfo, deriveHighestSetAbilityScore } from './derivers';
|
||||
import { getBestAbilityScore, getStatScoreModifier } from './utils';
|
||||
/**
|
||||
*
|
||||
* @param abilities
|
||||
*/
|
||||
export function generateAbilityLookup(abilities) {
|
||||
return keyBy(abilities, 'id');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param abilities
|
||||
*/
|
||||
export function generateAbilityKeyLookup(abilities) {
|
||||
return keyBy(abilities, 'name');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param stat
|
||||
* @param baseStats
|
||||
* @param bonusStats
|
||||
* @param overrideStats
|
||||
* @param raceModifiers
|
||||
* @param classesModifiers
|
||||
* @param miscModifiers
|
||||
* @param modifiers
|
||||
* @param proficiencyBonus
|
||||
* @param ruleData
|
||||
* @param modifierData
|
||||
*/
|
||||
export function generateBaseAbility(stat, baseStats, bonusStats, overrideStats, raceModifiers, classesModifiers, miscModifiers, modifiers, proficiencyBonus, ruleData, modifierData) {
|
||||
const statKey = stat.key === null ? '' : stat.key.toLowerCase();
|
||||
const abilityId = stat.id;
|
||||
const entityTypeId = stat.entityTypeId;
|
||||
const baseStat = baseStats.find((ability) => ability.id === abilityId);
|
||||
const bonusStat = bonusStats.find((ability) => ability.id === abilityId);
|
||||
const overrideStat = overrideStats.find((ability) => ability.id === abilityId);
|
||||
const racialBonus = ModifierDerivers.deriveTotalValue(ModifierGenerators.generateBonusStatScoreModifiers(raceModifiers, abilityId), modifierData);
|
||||
const classBonuses = ModifierDerivers.deriveTotalValue(ModifierGenerators.generateBonusStatScoreModifiers(classesModifiers, abilityId), modifierData);
|
||||
const miscBonus = ModifierDerivers.deriveTotalValue(ModifierGenerators.generateBonusStatScoreModifiers(miscModifiers, abilityId), modifierData);
|
||||
// generate all stat bonus suppliers
|
||||
const allStatBonusModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusStatScoreModifier(modifier, abilityId));
|
||||
const allStatBonusSuppliers = generateAbilityScoreSupplierData(allStatBonusModifiers, 'bonus', modifierData);
|
||||
//generate setScore and all setScore suppliers
|
||||
const setScore = deriveHighestSetAbilityScore(abilityId, miscModifiers);
|
||||
const statSetScoreModifiers = modifiers.filter((modifier) => ModifierValidators.isValidSetStatScoreModifier(modifier, abilityId));
|
||||
const statSetScoreSuppliers = generateAbilityScoreSupplierData(statSetScoreModifiers, 'set', modifierData);
|
||||
//generate maxStatBonus and all maxStatBonus suppliers
|
||||
const statMaxBonusModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusStatMaxModifier(modifier, abilityId));
|
||||
const statMaxBonus = ModifierDerivers.deriveTotalValue(statMaxBonusModifiers, modifierData);
|
||||
const statMaxBonusSuppliers = generateAbilityScoreSupplierData(statMaxBonusModifiers, 'max', modifierData);
|
||||
//generate stackingBonus and all stackingBonus suppliers
|
||||
const stackingBonusModifiers = modifiers.filter((modifier) => ModifierValidators.isValidStackingBonusStatScoreModifier(modifier, abilityId));
|
||||
const stackingBonus = ModifierDerivers.deriveTotalValue(stackingBonusModifiers, modifierData);
|
||||
const stackingBonusSuppliers = generateAbilityScoreSupplierData(stackingBonusModifiers, 'stacking', modifierData);
|
||||
// calculate baseScore, otherBonus, overrideScore, totalBonusScore, finalScore, and modifier
|
||||
const baseScore = baseStat ? baseStat.value : null;
|
||||
const otherBonus = bonusStat ? bonusStat.value : null;
|
||||
let overrideScore = overrideStat ? overrideStat.value : null;
|
||||
if (overrideScore === 0) {
|
||||
overrideScore = null;
|
||||
}
|
||||
let totalBonusScore = null;
|
||||
let finalScore = null;
|
||||
let modifier = null;
|
||||
let maxStatScore = ruleData.basicMaxStatScore;
|
||||
if (baseScore !== null) {
|
||||
totalBonusScore = baseScore + racialBonus + classBonuses + miscBonus;
|
||||
maxStatScore = ruleData.basicMaxStatScore + statMaxBonus;
|
||||
totalBonusScore = Math.min(maxStatScore, totalBonusScore);
|
||||
totalBonusScore += otherBonus ? otherBonus : 0;
|
||||
finalScore = getBestAbilityScore(totalBonusScore, setScore, ruleData);
|
||||
if (overrideScore) {
|
||||
finalScore = overrideScore;
|
||||
}
|
||||
if (stackingBonus > 0) {
|
||||
finalScore = Math.min(maxStatScore, finalScore + stackingBonus);
|
||||
}
|
||||
finalScore = Math.max(ruleData.minStatScore, Math.min(ruleData.maxStatScore, finalScore));
|
||||
modifier = getStatScoreModifier(finalScore, ruleData);
|
||||
}
|
||||
return {
|
||||
label: stat.name,
|
||||
id: stat.id,
|
||||
entityTypeId,
|
||||
name: statKey,
|
||||
statKey,
|
||||
totalScore: finalScore,
|
||||
score: finalScore,
|
||||
maxStatScore,
|
||||
isMaxed: !!finalScore && finalScore >= maxStatScore,
|
||||
modifier,
|
||||
baseScore,
|
||||
racialBonus,
|
||||
classBonuses,
|
||||
miscBonus,
|
||||
setScore,
|
||||
stackingBonus,
|
||||
otherBonus,
|
||||
overrideScore,
|
||||
allStatBonusSuppliers,
|
||||
statSetScoreSuppliers,
|
||||
statMaxBonusSuppliers,
|
||||
stackingBonusSuppliers,
|
||||
};
|
||||
}
|
||||
export function generateAbilityScoreSupplierData(abilityModifiers, type, modifierData) {
|
||||
const supplierGroups = groupBy(abilityModifiers, (modifier) => `${modifier.componentId}-${modifier.componentTypeId}`);
|
||||
return Object.keys(supplierGroups).map((groupKey) => {
|
||||
var _a;
|
||||
const modifiers = supplierGroups[groupKey];
|
||||
const totalValue = ModifierDerivers.deriveTotalValue(modifiers, modifierData);
|
||||
let dataOrigin = (_a = modifiers[0]) === null || _a === void 0 ? void 0 : _a.dataOrigin;
|
||||
let expandedOriginRef = null;
|
||||
if (dataOrigin && dataOrigin.type === DataOriginTypeEnum.FEAT) {
|
||||
expandedOriginRef = DataOriginGenerators.generateDataOriginRef(dataOrigin.type, groupKey);
|
||||
}
|
||||
return {
|
||||
key: groupKey,
|
||||
dataOrigin,
|
||||
expandedOriginRef,
|
||||
type,
|
||||
value: totalValue,
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param abilityScore
|
||||
* @param proficiencyBonus
|
||||
* @param modifiers
|
||||
* @param valueLookup
|
||||
* @param modifierData
|
||||
*/
|
||||
export function generateAbility(abilityScore, proficiencyBonus, modifiers, valueLookup, modifierData) {
|
||||
const abilityId = getId(abilityScore);
|
||||
const abilityIdString = ValueHacks.hack__toString(abilityId);
|
||||
const abilityEntityTypeId = getEntityTypeId(abilityScore);
|
||||
const abilityEntityTypeIdString = ValueHacks.hack__toString(abilityEntityTypeId);
|
||||
const miscBonus = ValueUtils.getSavingThrowMiscBonusValue(valueLookup, abilityIdString, abilityEntityTypeIdString);
|
||||
const magicBonus = ValueUtils.getSavingThrowMagicBonusValue(valueLookup, abilityIdString, abilityEntityTypeIdString);
|
||||
const saveOverride = ValueUtils.getSavingThrowOverrideValue(valueLookup, abilityIdString, abilityEntityTypeIdString);
|
||||
const proficiencyLevelOverride = ValueUtils.getSavingThrowProficiencyLevelValue(valueLookup, abilityIdString, abilityEntityTypeIdString);
|
||||
const statBonusSaveModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusSaveModifier(modifier, abilityId));
|
||||
const statBonusSaveModifierTotal = ModifierDerivers.deriveTotalValue(statBonusSaveModifiers, modifierData, 1);
|
||||
const abilitySaveInfo = deriveAbilitySaveInfo(abilityScore, modifiers, proficiencyBonus, proficiencyLevelOverride, saveOverride, statBonusSaveModifierTotal, magicBonus, miscBonus);
|
||||
return Object.assign(Object.assign({}, abilityScore), abilitySaveInfo);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param baseStats
|
||||
* @param bonusStats
|
||||
* @param overrideStats
|
||||
* @param raceModifiers
|
||||
* @param classesModifiers
|
||||
* @param miscModifiers
|
||||
* @param modifiers
|
||||
* @param proficiencyBonus
|
||||
* @param modifierData
|
||||
* @param ruleData
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function generateAbilities(baseStats, bonusStats, overrideStats, raceModifiers, classesModifiers, miscModifiers, modifiers, proficiencyBonus, modifierData, ruleData, valueLookup) {
|
||||
const abilityScores = RuleDataAccessors.getStats(ruleData).map((stat) => generateBaseAbility(stat, baseStats, bonusStats, overrideStats, raceModifiers, classesModifiers, miscModifiers, modifiers, proficiencyBonus, ruleData, modifierData));
|
||||
const simulatedAbilities = abilityScores.map((ability) => (Object.assign(Object.assign({}, ability), { proficiency: false, proficiencyLevel: ProficiencyLevelEnum.NONE, isSaveProficiencyModified: false, isSaveModifierModified: false, save: 0, saveBonuses: 0, isSaveOverridden: false })));
|
||||
const abilityScoresLookup = generateAbilityLookup(simulatedAbilities);
|
||||
const updatedModifierData = Object.assign(Object.assign({}, modifierData), { abilityLookup: abilityScoresLookup });
|
||||
return abilityScores.map((abilityScore) => generateAbility(abilityScore, proficiencyBonus, modifiers, valueLookup, updatedModifierData));
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import * as AbilityAccessors from './accessors';
|
||||
import * as AbilityDerivers from './derivers';
|
||||
import * as AbilityGenerators from './generators';
|
||||
import * as AbilityTypings from './typings';
|
||||
import * as AbilityUtils from './utils';
|
||||
export * from './typings';
|
||||
export { AbilityAccessors, AbilityDerivers, AbilityGenerators, AbilityUtils };
|
||||
export default Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, AbilityAccessors), AbilityDerivers), AbilityGenerators), AbilityTypings), AbilityUtils);
|
||||
@@ -0,0 +1,19 @@
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { RuleDataAccessors } from '../RuleData';
|
||||
/**
|
||||
*
|
||||
* @param score
|
||||
* @param ruleData
|
||||
*/
|
||||
export function getStatScoreModifier(score, ruleData) {
|
||||
return HelperUtils.lookupDataOrFallback(RuleDataAccessors.getStatModifiersLookup(ruleData), score, 0);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param totalBonusScore
|
||||
* @param highestSetScore
|
||||
* @param ruleData
|
||||
*/
|
||||
export function getBestAbilityScore(totalBonusScore, highestSetScore, ruleData) {
|
||||
return Math.min(RuleDataAccessors.getMaxStatScore(ruleData), Math.max(totalBonusScore, highestSetScore));
|
||||
}
|
||||
Reference in New Issue
Block a user