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:
2025-05-28 11:50:03 -07:00
commit 8df9031d27
3592 changed files with 319051 additions and 0 deletions
@@ -0,0 +1,35 @@
/**
*
* @param die
*/
export function getCount(die) {
return die.diceCount;
}
/**
*
* @param die
*/
export function getMultiplier(die) {
return die.diceMultiplier;
}
/**
*
* @param die
*/
export function getString(die) {
return die.diceString;
}
/**
*
* @param die
*/
export function getValue(die) {
return die.diceValue;
}
/**
*
* @param die
*/
export function getFixedValue(die) {
return die.fixedValue;
}
@@ -0,0 +1,21 @@
export var DiceAdjustmentTypeEnum;
(function (DiceAdjustmentTypeEnum) {
DiceAdjustmentTypeEnum["ADVANTAGE"] = "ADVANTAGE";
DiceAdjustmentTypeEnum["DISADVANTAGE"] = "DISADVANTAGE";
DiceAdjustmentTypeEnum["BONUS"] = "BONUS";
})(DiceAdjustmentTypeEnum || (DiceAdjustmentTypeEnum = {}));
export var UsableDiceAdjustmentTypeEnum;
(function (UsableDiceAdjustmentTypeEnum) {
UsableDiceAdjustmentTypeEnum["NONE"] = "NONE";
UsableDiceAdjustmentTypeEnum["ADVANTAGE"] = "ADVANTAGE";
UsableDiceAdjustmentTypeEnum["DISADVANTAGE"] = "DISADVANTAGE";
UsableDiceAdjustmentTypeEnum["ADVANTAGE_DISADVANTAGE"] = "ADVANTAGE_DISADVANTAGE";
})(UsableDiceAdjustmentTypeEnum || (UsableDiceAdjustmentTypeEnum = {}));
export var DiceAdjustmentRollTypeEnum;
(function (DiceAdjustmentRollTypeEnum) {
DiceAdjustmentRollTypeEnum["NONE"] = "NONE";
DiceAdjustmentRollTypeEnum["SAVE"] = "SAVE";
DiceAdjustmentRollTypeEnum["STAT_SAVE"] = "STAT_SAVE";
DiceAdjustmentRollTypeEnum["DEATH_SAVE"] = "DEATH_SAVE";
DiceAdjustmentRollTypeEnum["ABILITY_CHECK"] = "ABILITY_CHECK";
})(DiceAdjustmentRollTypeEnum || (DiceAdjustmentRollTypeEnum = {}));
@@ -0,0 +1,76 @@
import { DiceAdjustmentTypeEnum, UsableDiceAdjustmentTypeEnum } from './constants';
/**
*
* @param advantageAdjustments
* @param disadvantageAdjustments
*/
export function deriveUsableDiceAdjustmentType(advantageAdjustments, disadvantageAdjustments) {
const advantageCount = advantageAdjustments.length;
const disadvantageCount = disadvantageAdjustments.length;
const hasAdvantage = advantageCount > 0;
const hasDisadvantage = disadvantageCount > 0;
if (hasAdvantage && !hasDisadvantage) {
return UsableDiceAdjustmentTypeEnum.ADVANTAGE;
}
if (!hasAdvantage && hasDisadvantage) {
return UsableDiceAdjustmentTypeEnum.DISADVANTAGE;
}
if (hasAdvantage && hasDisadvantage) {
const restrictedAdvantageCount = advantageAdjustments.filter((adjustment) => adjustment.restriction).length;
const restrictedDisadvantageCount = disadvantageAdjustments.filter((adjustment) => adjustment.restriction).length;
const fullAdvantageCount = advantageCount - restrictedAdvantageCount;
const fullDisadvantageCount = disadvantageCount - restrictedDisadvantageCount;
const hasFullAdvantage = fullAdvantageCount > 0;
const hasFullDisadvantage = fullDisadvantageCount > 0;
const hasRestrictedAdvantage = restrictedAdvantageCount > 0;
const hasRestrictedDisadvantage = restrictedDisadvantageCount > 0;
// Have both full types, means it always cancels and we dont care about restrictions
if (hasFullAdvantage && hasFullDisadvantage) {
return UsableDiceAdjustmentTypeEnum.NONE;
}
// Have either restricted advantage or disadvantage, you could possible use either, or none
if (hasRestrictedAdvantage || hasRestrictedDisadvantage) {
return UsableDiceAdjustmentTypeEnum.ADVANTAGE_DISADVANTAGE;
}
}
return UsableDiceAdjustmentTypeEnum.NONE;
}
/**
*
* @param levelScale
*/
export function deriveMartialArtsDamageDie(levelScale) {
// 2025 Update: Keeping this default from previous logic where we didn't have the levelScale.
let dice = {
diceCount: 1,
diceMultiplier: null,
diceString: '',
diceValue: 4,
fixedValue: null,
};
if (levelScale.dice) {
dice = levelScale.dice;
}
return dice;
}
/**
*
* @param type
*/
export function deriveDiceAdjustmentTypeName(type) {
let name = '';
switch (type) {
case DiceAdjustmentTypeEnum.ADVANTAGE:
name = 'Advantage';
break;
case DiceAdjustmentTypeEnum.DISADVANTAGE:
name = 'Disadvantage';
break;
case DiceAdjustmentTypeEnum.BONUS:
name = 'Bonus';
break;
default:
//not implemented
}
return name;
}
@@ -0,0 +1,21 @@
import { ModifierDerivers } from '../Modifier';
import { DiceAdjustmentTypeEnum } from './constants';
/**
*
* @param bonusSavingThrowModifiers
* @param advantageSavingThrowModifiers
* @param disadvantageSavingThrowModifiers
*/
export function generateSavingThrowDiceAdjustments(bonusSavingThrowModifiers, advantageSavingThrowModifiers, disadvantageSavingThrowModifiers) {
let diceAdjustments = [];
bonusSavingThrowModifiers.forEach((modifier) => {
diceAdjustments.push(ModifierDerivers.deriveDiceAdjustment(modifier, DiceAdjustmentTypeEnum.BONUS));
});
advantageSavingThrowModifiers.forEach((modifier) => {
diceAdjustments.push(ModifierDerivers.deriveDiceAdjustment(modifier, DiceAdjustmentTypeEnum.ADVANTAGE));
});
disadvantageSavingThrowModifiers.forEach((modifier) => {
diceAdjustments.push(ModifierDerivers.deriveDiceAdjustment(modifier, DiceAdjustmentTypeEnum.DISADVANTAGE));
});
return diceAdjustments;
}
@@ -0,0 +1,12 @@
import * as DiceAccessors from './accessors';
import * as DiceConstants from './constants';
import * as DiceDerivers from './derivers';
import * as DiceGenerators from './generators';
import * as DiceRenderers from './renderers';
import * as DiceSimulators from './simulators';
import * as DiceTypings from './typings';
import * as DiceUtils from './utils';
export * from './constants';
export * from './typings';
export { DiceAccessors, DiceRenderers, DiceSimulators, DiceUtils, DiceDerivers, DiceGenerators };
export default Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, DiceAccessors), DiceRenderers), DiceSimulators), DiceUtils), DiceTypings), DiceConstants), DiceDerivers), DiceGenerators);
@@ -0,0 +1,35 @@
import { groupBy } from 'lodash';
import { FormatUtils } from '../Format';
import { getCount, getFixedValue, getValue } from './accessors';
/**
* Formats the specified dice to be a human readable string
* @param dice The dice that should be formatted
*/
export function renderDice(dice) {
if (Array.isArray(dice)) {
const diceGroups = groupBy(dice.map((die) => renderDie(die)));
return Object.keys(diceGroups)
.map((key) => `${key}${diceGroups[key].length > 1 ? ` (${diceGroups[key].length})` : ''}`)
.join(', ');
}
return renderDie(dice);
}
/**
* Formats the specified die to be a human readable string.
* @param die The die that should be formatted
*/
export function renderDie(die) {
if (die === null) {
return '';
}
const diceCount = getCount(die);
const diceValue = getValue(die);
const fixedValue = getFixedValue(die);
if (diceValue && diceCount) {
return `${diceCount}d${diceValue}${fixedValue ? FormatUtils.renderSignedNumber(fixedValue) : ''}`;
}
if (!diceValue && !diceCount && fixedValue) {
return FormatUtils.renderLocaleNumber(fixedValue);
}
return '';
}
@@ -0,0 +1,7 @@
/**
*
* @param props
*/
export function simulateDiceContract(props) {
return Object.assign({ diceCount: null, diceMultiplier: null, diceString: null, diceValue: null, fixedValue: null }, props);
}
@@ -0,0 +1,108 @@
import { sortBy } from 'lodash';
import { RuleDataAccessors } from '../RuleData';
import { getCount, getFixedValue, getValue } from './accessors';
/**
* Gets the lowest value for the specified die
* @param die The die used to produce the lowest value
*/
export function getDiceMinValue(die) {
const fixedValue = getFixedValue(die);
const count = getCount(die);
return (count ? count : 0) + (fixedValue ? fixedValue : 0);
}
/**
* Gets the highest value for the specified die
* @param die The die used to produce the highest value
*/
export function getDiceMaxValue(die) {
const fixedValue = getFixedValue(die);
let count = getCount(die);
if (count === null) {
count = 0;
}
const value = getValue(die);
const finalValue = value === null ? 0 : value;
return count * finalValue + (fixedValue ? fixedValue : 0);
}
/**
* Gets an array of all possible values produce by the specified die.
* @param die The die used to produce the range of values
*/
export function getDiceValuesRange(die) {
const minValue = getDiceMinValue(die);
const maxValue = getDiceMaxValue(die);
const values = [];
for (let i = minValue; i <= maxValue; i++) {
values.push(i);
}
return values;
}
/**
* Gets a random value from the specified die's range of values.
* @param die The die used to produce a random value
*/
export function getDiceRandomValue(die) {
const minValue = getDiceMinValue(die);
const maxValue = getDiceMaxValue(die);
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
/**
* Gets the average roll for a specific die value.
* @param dieValue The die used to produce the average value
*/
export function getAverageDieValue(dieValue) {
return dieValue / 2 + 0.5;
}
/**
* Gets the average roll, rounded up, for a specified die value.
* @param dieValue The die used to produce the fixed value
*/
export function getFixedDieValue(dieValue) {
return dieValue / 2 + 1;
}
/**
* Gets the damage die used when a weapon with the versatile property is wielded with two hands.
* @param dieValue The damage die used when the weapon is used normally
* @param ruleData The config data provided by the server
*/
export function getVersatileDieValue(dieValue, ruleData) {
const diceValues = RuleDataAccessors.getDiceValues(ruleData);
if (diceValues === null) {
return 0;
}
const versatileIdx = Math.min(diceValues.length - 1, diceValues.indexOf(dieValue) + 1);
return diceValues[versatileIdx];
}
/**
* Obtains the highest die from a specified list of dice.
* @param dice The dice to search through
*/
export function getHighestDie(dice) {
if (!dice.length) {
return null;
}
const highestDie = sortBy(dice, [
(die) => {
let diceCount = getCount(die);
diceCount = diceCount ? diceCount : 0;
let diceValue = getValue(die);
diceValue = diceValue ? diceValue : 0;
const fixedValue = getFixedValue(die);
return diceCount * getAverageDieValue(diceValue) + (fixedValue ? fixedValue : 0);
},
]).pop();
if (!highestDie) {
return null;
}
return highestDie;
}
/**
*
* @param diceContract
*/
export function getAverageDiceValue(diceContract) {
const fixedValue = diceContract.fixedValue ? diceContract.fixedValue : 0;
const diceValue = diceContract.diceValue !== null ? diceContract.diceValue : 0;
const diceCount = diceContract.diceCount !== null ? diceContract.diceCount : 0;
return Math.floor(getAverageDieValue(diceValue) * diceCount) + fixedValue;
}