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,79 @@
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
* @param startIdx
|
||||
* @param pieceIdx
|
||||
* @param pieceCharIdx
|
||||
* @param pieces
|
||||
*/
|
||||
export function checkQueryPiece(input, startIdx, pieceIdx, pieceCharIdx, pieces) {
|
||||
let i;
|
||||
let ch;
|
||||
let length = input.length;
|
||||
for (i = startIdx; i < length; i++) {
|
||||
ch = input.charAt(i);
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
case '-':
|
||||
case '.':
|
||||
case '"':
|
||||
continue; //ignore spaces, dashes, periods, and double quotes
|
||||
default:
|
||||
if (pieceIdx < pieces.length) {
|
||||
let piece = pieces[pieceIdx];
|
||||
if (pieceCharIdx < piece.length && ch === piece.charAt(pieceCharIdx)) {
|
||||
//if current character matches, check next character in piece
|
||||
if (checkQueryPiece(input, i + 1, pieceIdx, pieceCharIdx + 1, pieces)) {
|
||||
return true;
|
||||
}
|
||||
//if path for next character doesn't match, try path from start of next piece
|
||||
if (checkQueryPiece(input, i + 1, pieceIdx + 1, 0, pieces)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (pieceCharIdx === 0) {
|
||||
//if first character of piece doesn't match, allow skipping that piece
|
||||
if (checkQueryPiece(input, i, pieceIdx + 1, 0, pieces)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false; //no match if no path above reaches end of input string
|
||||
}
|
||||
}
|
||||
return true; //match if reached end of input string
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param query
|
||||
* @param primaryText
|
||||
* @param tags
|
||||
*/
|
||||
export function doesQueryMatchData(query, primaryText, tags = []) {
|
||||
let input = query.toLowerCase().trim();
|
||||
if (!input) {
|
||||
// if there is no query don't filter anything
|
||||
return true;
|
||||
}
|
||||
let processedPrimaryText = primaryText ? primaryText.replace(/["+]/g, '').toLowerCase().trim() : '';
|
||||
let processedTags = tags && tags.length ? tags.map((tag) => (tag ? tag.toLowerCase().trim() : tag)) : [];
|
||||
let pieces = processedPrimaryText.split(/[ -]/);
|
||||
if (checkQueryPiece(input, 0, 0, 0, pieces)) {
|
||||
//don't filter out item if heading matches
|
||||
return true;
|
||||
}
|
||||
// if heading isn't a match, see if input is an exact match for associated tags
|
||||
if (!processedTags.length) {
|
||||
// filter out item if no tags specified
|
||||
return false;
|
||||
}
|
||||
let tagMatch = false;
|
||||
processedTags.forEach((tag) => {
|
||||
if (tagMatch || !tag) {
|
||||
return;
|
||||
}
|
||||
let pieces = tag.split(/[ -]/);
|
||||
tagMatch = checkQueryPiece(input, 0, 0, 0, pieces);
|
||||
});
|
||||
return tagMatch;
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
import { ExpressionOperators, StatementOperators } from '@dndbeyond/character-gfs';
|
||||
import { ModifierAccessors, ModifierTypeEnum, ModifierValidators } from "../../../engine/Modifier";
|
||||
import { RuleDataUtils } from "../../../engine/RuleData";
|
||||
export function transformAbilityScores(validGlobalModifiers, baseStats, ruleData) {
|
||||
const abilityScoreModifiers = validGlobalModifiers.filter((modifier) => {
|
||||
return (ModifierValidators.isValidStatScoreModifier(modifier, 1) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 2) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 3) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 4) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 5) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 6));
|
||||
});
|
||||
const baseAbilityScores = baseStats.flatMap((stat) => {
|
||||
var _a, _b, _c;
|
||||
if (stat.id) {
|
||||
const statName = (_b = (_a = RuleDataUtils.getStatNameById(stat.id, ruleData, true)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
|
||||
stat.value = (_c = stat.value) !== null && _c !== void 0 ? _c : 0;
|
||||
// Math.floor((stat.value - 10) / 2)
|
||||
return [
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'value'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [stat.value],
|
||||
operands: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'modifier'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.FLOOR,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.MULTIPLY,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [0.5],
|
||||
operands: null,
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.ADD,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [-10],
|
||||
operands: null,
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.DYNAMIC_VALUE,
|
||||
values: ['attributes', statName, 'value'],
|
||||
operands: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'max'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [20],
|
||||
operands: null,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
const gfsAbilityScores = abilityScoreModifiers.map((abilityScoreModifier) => {
|
||||
var _a, _b, _c, _d;
|
||||
const modifierType = ModifierAccessors.getType(abilityScoreModifier);
|
||||
switch (modifierType) {
|
||||
case ModifierTypeEnum.SET:
|
||||
return {
|
||||
precedence: 0.5,
|
||||
target: [
|
||||
'attributes',
|
||||
(_a = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _a === void 0 ? void 0 : _a.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [ModifierAccessors.getValue(abilityScoreModifier)],
|
||||
},
|
||||
};
|
||||
case ModifierTypeEnum.BONUS:
|
||||
default:
|
||||
return {
|
||||
precedence: 0.5,
|
||||
target: [
|
||||
'attributes',
|
||||
(_b = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _b === void 0 ? void 0 : _b.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.ADD,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.DYNAMIC_VALUE,
|
||||
operands: null,
|
||||
values: [
|
||||
'attributes',
|
||||
(_c = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _c === void 0 ? void 0 : _c.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [(_d = ModifierAccessors.getValue(abilityScoreModifier)) !== null && _d !== void 0 ? _d : 0],
|
||||
operands: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
const generatedFeature = {
|
||||
meta: {
|
||||
name: 'Generated Ability Scores',
|
||||
category: 'Generated',
|
||||
},
|
||||
statements: [...baseAbilityScores, ...gfsAbilityScores],
|
||||
featureId: 'generated-ability-scores',
|
||||
labels: [],
|
||||
sources: [],
|
||||
subfeatures: [],
|
||||
acceptableInputs: {},
|
||||
primarySource: null,
|
||||
secondarySources: [],
|
||||
};
|
||||
return { baseAbilityScores, gfsAbilityScores, generatedFeature };
|
||||
}
|
||||
Reference in New Issue
Block a user