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,849 @@
|
||||
import { StatBlockTypeEnum } from './constants';
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getUniqueKey(creature) {
|
||||
return `${getMappingId(creature)}-${getMappingEntityTypeId(creature)}`;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getMappingId(creature) {
|
||||
return creature.id;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getMappingEntityTypeId(creature) {
|
||||
return creature.entityTypeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function isActive(creature) {
|
||||
return creature.isActive;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getRemoveHitPoints(creature) {
|
||||
return creature.removedHitPoints;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getTemporaryHitPoints(creature) {
|
||||
var _a;
|
||||
return (_a = creature.temporaryHitPoints) !== null && _a !== void 0 ? _a : 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getGroupId(creature) {
|
||||
return creature.groupId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getId(creature) {
|
||||
return getDefinitionId(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getEntityTypeId(creature) {
|
||||
return getDefinitionEntityTypeId(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionEntityTypeId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.entityTypeId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getName(creature) {
|
||||
var _a;
|
||||
return (_a = creature.name) !== null && _a !== void 0 ? _a : getDefinitionName(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionAlignmentId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.alignmentId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getAlignmentId(creature) {
|
||||
return creature.alignmentId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSizeId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.sizeId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSizeId(creature) {
|
||||
return creature.sizeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSizeInfo(creature) {
|
||||
return creature.sizeInfo;
|
||||
}
|
||||
export function getDefinitionTypeId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.typeId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getTypeId(creature) {
|
||||
return creature.typeId;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionArmorClass(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.armorClass) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionName(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
export function getArmorClassDescription(creature) {
|
||||
return getDefinitionArmorClassDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionArmorClassDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.armorClassDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
export function getAverageHitPoints(creature) {
|
||||
return getDefinitionAverageHitPoints(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionAverageHitPoints(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.averageHitPoints) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionStats(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.stats) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getStats(creature) {
|
||||
return creature.stats;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getChallengeInfo(creature) {
|
||||
return creature.challengeInfo;
|
||||
}
|
||||
export function getLairChallengeInfo(creature) {
|
||||
return creature.lairChallengeInfo;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param fallback
|
||||
*/
|
||||
export function getChallengeProficiencyBonus(creature, fallback = 0) {
|
||||
var _a;
|
||||
const challengeInfo = getChallengeInfo(creature);
|
||||
return (_a = challengeInfo === null || challengeInfo === void 0 ? void 0 : challengeInfo.proficiencyBonus) !== null && _a !== void 0 ? _a : fallback;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getHitPointDice(creature) {
|
||||
return getDefinitionHitPointDice(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionHitPointDice(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.hitPointDice) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getMovements(creature) {
|
||||
return getDefinitionMovements(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionMovements(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.movements) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getMovementIds(creature) {
|
||||
return creature.movementIds;
|
||||
}
|
||||
export function getMovementNames(creature) {
|
||||
return creature.movementNames;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionDamageAdjustments(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.damageAdjustments) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDamageAdjustments(creature) {
|
||||
return creature.damageAdjustments;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDamageVulnerabilities(creature) {
|
||||
return creature.damageVulnerabilities;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDamageImmunities(creature) {
|
||||
return creature.damageImmunities;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDamageResistances(creature) {
|
||||
return creature.damageResistances;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionConditionImmunities(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.conditionImmunities) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getConditionImmunities(creature) {
|
||||
return creature.conditionImmunities;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSubTypes(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.subTypes) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSubTypes(creature) {
|
||||
return creature.subTypes;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getEnvironments(creature) {
|
||||
return getDefinitionEnvironments(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionEnvironments(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.environments) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getTags(creature) {
|
||||
return getDefinitionTags(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionTags(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.tags) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSwarmInfo(creature) {
|
||||
return getDefinitionSwarmInfo(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSwarmInfo(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.swarm) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSkills(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.skills) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSkills(creature) {
|
||||
return creature.skills;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSavingThrows(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.savingThrows) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSavingThrows(creature) {
|
||||
return creature.savingThrows;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSenses(creature) {
|
||||
return getDefinitionSenses(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSenses(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.senses) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionPassivePerception(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.passivePerception) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getPassivePerception(creature) {
|
||||
return creature.passivePerception;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLanguageDescription(creature) {
|
||||
return getDefinitionLanguageDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLanguageDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.languageDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLanguageNote(creature) {
|
||||
return getDefinitionLanguageNote(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLanguageNote(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.languageNote) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLanguages(creature) {
|
||||
return getDefinitionLanguages(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLanguages(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.languages) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function isHomebrew(creature) {
|
||||
return getDefinitionIsHomebrew(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionIsHomebrew(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.isHomebrew) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getVersion(creature) {
|
||||
return getDefinitionVersion(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionVersion(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getChallengeRatingId(creature) {
|
||||
return getDefinitionChallengeRatingId(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionChallengeRatingId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.challengeRatingId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
export function getLairChallengeRatingId(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.lairChallengeRatingId) !== null && _b !== void 0 ? _b : -1;
|
||||
}
|
||||
export function getInitiative(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.initiative) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function isSwarm(creature) {
|
||||
return getSwarmInfo(creature) !== null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function isLegendary(creature) {
|
||||
return getDefinitionIsLegendary(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionIsLegendary(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.isLegendary) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function hasLair(creature) {
|
||||
return getDefinitionHasLair(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionHasLair(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.hasLair) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getAvatarUrl(creature) {
|
||||
return getDefinitionAvatarUrl(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionAvatarUrl(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.avatarUrl) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLargeAvatarUrl(creature) {
|
||||
return getDefinitionLargeAvatarUrl(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLargeAvatarUrl(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.largeAvatarUrl) !== null && _b !== void 0 ? _b : '';
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getBasicAvatarUrl(creature) {
|
||||
return getDefinitionBasicAvatarUrl(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionBasicAvatarUrl(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.basicAvatarUrl) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSpecialTraitsDescription(creature) {
|
||||
return getDefinitionSpecialTraitsDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSpecialTraitsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.specialTraitsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getActionsDescription(creature) {
|
||||
return getDefinitionActionsDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionActionsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.actionsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
export function getBonusActionsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.bonusActionsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getReactionsDescription(creature) {
|
||||
return getDefinitionReactionsDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionReactionsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.reactionsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLegendaryActionsDescription(creature) {
|
||||
return getDefinitionLegendaryActionsDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLegendaryActionsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.legendaryActionsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getCharacteristicsDescription(creature) {
|
||||
return getDefinitionCharacteristicsDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionCharacteristicsDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.characteristicsDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLairDescription(creature) {
|
||||
return getDefinitionLairDescription(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionLairDescription(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.lairDescription) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getArmorClass(creature) {
|
||||
return creature.armorClass;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getGroupInfo(creature) {
|
||||
return creature.groupInfo;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getEnvironmentTags(creature) {
|
||||
return creature.environmentTags;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSubTypeTags(creature) {
|
||||
return creature.subTypeTags;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getTypeTag(creature) {
|
||||
return creature.typeTag;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getHitPointInfo(creature) {
|
||||
return creature.hitPointInfo;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getNotes(creature) {
|
||||
return creature.notes;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getGroupActionSnippet(creature) {
|
||||
var _a;
|
||||
const groupInfo = getGroupInfo(creature);
|
||||
return (_a = groupInfo === null || groupInfo === void 0 ? void 0 : groupInfo.actionSnippet) !== null && _a !== void 0 ? _a : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getLevel(creature) {
|
||||
return creature.level;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getInfusion(creature) {
|
||||
return creature.infusion;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getFlags(creature) {
|
||||
return creature.flags;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionSources(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.sources) !== null && _b !== void 0 ? _b : [];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSources(creature) {
|
||||
return getDefinitionSources(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function isCustomized(creature) {
|
||||
return creature.isCustomized;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getDefinitionHideCr(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.hideCr) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getHideCr(creature) {
|
||||
return getDefinitionHideCr(creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getGear(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.gear) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSlug(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.slug) !== null && _b !== void 0 ? _b : null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getStatBlockType(creature) {
|
||||
var _a, _b;
|
||||
return (_b = (_a = creature.definition) === null || _a === void 0 ? void 0 : _a.statBlockType) !== null && _b !== void 0 ? _b : StatBlockTypeEnum.CORE_RULES_2014;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getInitialTempHp(creature) {
|
||||
return creature.initialTempHp;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getUseOwnerHp(creature) {
|
||||
return creature.useOwnerHp;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { AdjustmentTypeEnum } from '../Value';
|
||||
export var CreatureGroupFlagEnum;
|
||||
(function (CreatureGroupFlagEnum) {
|
||||
CreatureGroupFlagEnum["ARMOR_ADD_PROFICIENCY_BONUS"] = "ACPB";
|
||||
CreatureGroupFlagEnum["ATTACK_ROLLS_ADD_PROFICIENCY_BONUS"] = "ARPB";
|
||||
CreatureGroupFlagEnum["DAMAGE_ROLLS_ADD_PROFICIENCY_BONUS"] = "DRPB";
|
||||
CreatureGroupFlagEnum["PROFICIENT_SKILLS_ADD_PROFICIENCY_BONUS"] = "PSPB";
|
||||
CreatureGroupFlagEnum["PROFICIENT_SAVING_THROWS_ADD_PROFICIENCY_BONUS"] = "STPB";
|
||||
CreatureGroupFlagEnum["MAX_HIT_POINTS_LEVEL_MULTIPLIER_OPTION"] = "HPLM";
|
||||
CreatureGroupFlagEnum["EVALUATE_OWNER_SKILL_PROFICIENCIES"] = "EOSKP";
|
||||
CreatureGroupFlagEnum["EVALUATE_OWNER_SAVE_PROFICIENCIES"] = "EOSVP";
|
||||
CreatureGroupFlagEnum["EVALUATE_OWNER_PASSIVE_PERCEPTION"] = "EOPP";
|
||||
CreatureGroupFlagEnum["EVALUATE_UPDATED_PASSIVE_PERCEPTION"] = "EUPP";
|
||||
CreatureGroupFlagEnum["CANNOT_BE_SWARM"] = "CBS";
|
||||
CreatureGroupFlagEnum["CANNOT_USE_LEGENDARY_ACTIONS"] = "CULGA";
|
||||
CreatureGroupFlagEnum["CANNOT_USE_LAIR_ACTIONS"] = "CULRA";
|
||||
CreatureGroupFlagEnum["ARTIFICER_HP_MULTIPLIER"] = "AHM";
|
||||
CreatureGroupFlagEnum["MAX_HIT_POINTS_ADD_INT_MODIFIER"] = "MHPAIM";
|
||||
CreatureGroupFlagEnum["MAX_HIT_POINTS_ADD_MONSTER_CON_MODIFIER"] = "MHPAMCM";
|
||||
CreatureGroupFlagEnum["USE_CHALLENGE_RATING_AS_LEVEL"] = "UCRAL";
|
||||
CreatureGroupFlagEnum["MAX_HIT_POINTS_BASE_ARTIFICER_LEVEL"] = "MHPBAL";
|
||||
CreatureGroupFlagEnum["USE_OWNER_MAX_HIT_POINTS"] = "UOMHP";
|
||||
CreatureGroupFlagEnum["TEMP_HIT_POINTS_BASE_DRUID_LEVEL"] = "THPBDL";
|
||||
CreatureGroupFlagEnum["TEMP_HIT_POINTS_BASE_DRUID_LEVEL_MULTIPLIER"] = "THPBDLM";
|
||||
CreatureGroupFlagEnum["ARMOR_ADD_OWNER_WIS_PLUS_FIXED_VALUE"] = "AAOWPFV";
|
||||
})(CreatureGroupFlagEnum || (CreatureGroupFlagEnum = {}));
|
||||
export const CREATURE_CUSTOMIZATION_ADJUSTMENT_TYPES = [
|
||||
AdjustmentTypeEnum.CREATURE_SIZE,
|
||||
AdjustmentTypeEnum.CREATURE_TYPE_OVERRIDE,
|
||||
AdjustmentTypeEnum.CREATURE_ALIGNMENT,
|
||||
AdjustmentTypeEnum.CREATURE_AC,
|
||||
AdjustmentTypeEnum.CREATURE_HIT_POINTS,
|
||||
AdjustmentTypeEnum.CREATURE_NOTES,
|
||||
];
|
||||
export const DB_STRING_GROUP_SIDEKICK = 'Sidekick';
|
||||
export const DB_STRING_TAG_SIDEKICK = 'Sidekick';
|
||||
export var StatBlockTypeEnum;
|
||||
(function (StatBlockTypeEnum) {
|
||||
StatBlockTypeEnum[StatBlockTypeEnum["CORE_RULES_2014"] = 0] = "CORE_RULES_2014";
|
||||
StatBlockTypeEnum[StatBlockTypeEnum["CORE_RULES_2024"] = 1] = "CORE_RULES_2024";
|
||||
})(StatBlockTypeEnum || (StatBlockTypeEnum = {}));
|
||||
@@ -0,0 +1,653 @@
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
import { AbilityAccessors, AbilityUtils } from '../Ability';
|
||||
import { CharacterDerivers } from '../Character';
|
||||
import { AbilitySkillEnum, AbilityStatEnum, ProficiencyLevelEnum, } from '../Core';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { InfusionAccessors } from '../Infusion';
|
||||
import { RuleDataAccessors, RuleDataUtils } from '../RuleData';
|
||||
import { SkillAccessors } from '../Skill';
|
||||
import { AdjustmentTypeEnum, ValueHacks, ValueUtils, ValueValidators } from '../Value';
|
||||
import { getAverageHitPoints, getChallengeProficiencyBonus, getChallengeRatingId, getDamageAdjustments, getDefinitionAlignmentId, getDefinitionArmorClass, getDefinitionConditionImmunities, getDefinitionDamageAdjustments, getDefinitionPassivePerception, getDefinitionSavingThrows, getDefinitionSizeId, getDefinitionSkills, getDefinitionStats, getDefinitionSubTypes, getDefinitionTypeId, getEnvironments, getId, getLairChallengeRatingId, getMappingEntityTypeId, getMappingId, getMovements, getRemoveHitPoints, getTemporaryHitPoints, getTypeId, } from './accessors';
|
||||
import { CREATURE_CUSTOMIZATION_ADJUSTMENT_TYPES, CreatureGroupFlagEnum } from './constants';
|
||||
import { getStatInfo, hasGroupFlag, shouldReplaceWithOwnerStat } from './utils';
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function derivePreOwnerHitPointInfo(creature) {
|
||||
const finalTotalHp = Math.max(getAverageHitPoints(creature), 0);
|
||||
const finalBaseHp = finalTotalHp;
|
||||
const finalRemovedHp = Math.min(finalTotalHp, getRemoveHitPoints(creature));
|
||||
return {
|
||||
baseHp: finalBaseHp,
|
||||
tempHp: 0,
|
||||
removedHp: finalRemovedHp,
|
||||
bonusHp: 0,
|
||||
overrideHp: 0,
|
||||
totalHp: finalTotalHp,
|
||||
remainingHp: finalTotalHp - finalRemovedHp,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param valueLookup
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveHitPointInfo(creature, ownerData, valueLookup, ruleData) {
|
||||
const flagLevelMultiplierHpPossibilities = [];
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.MAX_HIT_POINTS_LEVEL_MULTIPLIER_OPTION)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.MAX_HIT_POINTS_LEVEL_MULTIPLIER_OPTION, ruleData);
|
||||
if (flagInfo) {
|
||||
const contextClassLevel = flagInfo.valueContextId === null ? 0 : ownerData.classLevelLookup[flagInfo.valueContextId];
|
||||
const contextValue = flagInfo.value === null ? 1 : flagInfo.value;
|
||||
flagLevelMultiplierHpPossibilities.push((contextClassLevel ? contextClassLevel : 0) * contextValue);
|
||||
}
|
||||
}
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.ARTIFICER_HP_MULTIPLIER)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.ARTIFICER_HP_MULTIPLIER, ruleData);
|
||||
if (flagInfo) {
|
||||
const contextClassLevel = flagInfo.valueContextId === null ? 0 : ownerData.classLevelLookup[flagInfo.valueContextId];
|
||||
const contextValue = flagInfo.value === null ? 1 : flagInfo.value;
|
||||
flagLevelMultiplierHpPossibilities.push((contextClassLevel ? contextClassLevel : 0) * contextValue);
|
||||
}
|
||||
}
|
||||
const definitionTotalHp = getAverageHitPoints(creature);
|
||||
let finalTotalHp = Math.max(definitionTotalHp, ...flagLevelMultiplierHpPossibilities);
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.MAX_HIT_POINTS_BASE_ARTIFICER_LEVEL)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.MAX_HIT_POINTS_BASE_ARTIFICER_LEVEL, ruleData);
|
||||
if (flagInfo && flagInfo.valueContextId !== null) {
|
||||
finalTotalHp = HelperUtils.lookupDataOrFallback(ownerData.classLevelLookup, flagInfo.valueContextId, finalTotalHp);
|
||||
}
|
||||
}
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.MAX_HIT_POINTS_ADD_INT_MODIFIER)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.MAX_HIT_POINTS_ADD_INT_MODIFIER, ruleData);
|
||||
if (flagInfo) {
|
||||
const contextStatModifier = flagInfo.valueContextId === null ? null : ownerData.abilityLookup[flagInfo.valueContextId];
|
||||
let finalModifier = 0;
|
||||
if (contextStatModifier && contextStatModifier.modifier) {
|
||||
finalModifier = contextStatModifier.modifier;
|
||||
}
|
||||
finalTotalHp = HelperUtils.clampInt(finalTotalHp + finalModifier, RuleDataAccessors.getMinimumHpTotal(ruleData));
|
||||
}
|
||||
}
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.MAX_HIT_POINTS_ADD_MONSTER_CON_MODIFIER)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.MAX_HIT_POINTS_ADD_MONSTER_CON_MODIFIER, ruleData);
|
||||
if (flagInfo !== null && flagInfo.valueContextId) {
|
||||
let contextStatModifier = 0;
|
||||
const contextStatInfo = getStatInfo(creature, flagInfo.valueContextId);
|
||||
if (contextStatInfo !== null && contextStatInfo.modifier !== null) {
|
||||
contextStatModifier = contextStatInfo.modifier;
|
||||
}
|
||||
finalTotalHp = HelperUtils.clampInt(finalTotalHp + contextStatModifier, ruleData.minimumHpTotal);
|
||||
}
|
||||
}
|
||||
//if there is an override for the creature's hit points, use that instead
|
||||
const hpOverride = deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_HIT_POINTS, null, valueLookup);
|
||||
if (hpOverride) {
|
||||
finalTotalHp = hpOverride;
|
||||
}
|
||||
const tempHp = getTemporaryHitPoints(creature);
|
||||
const finalRemovedHp = Math.min(finalTotalHp, getRemoveHitPoints(creature));
|
||||
return {
|
||||
baseHp: finalTotalHp,
|
||||
tempHp,
|
||||
removedHp: finalRemovedHp,
|
||||
bonusHp: 0,
|
||||
overrideHp: 0,
|
||||
totalHp: finalTotalHp,
|
||||
remainingHp: finalTotalHp - finalRemovedHp,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveInitialTempHp(creature, ownerData, ruleData) {
|
||||
let initialTempHp = 0;
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.TEMP_HIT_POINTS_BASE_DRUID_LEVEL)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.TEMP_HIT_POINTS_BASE_DRUID_LEVEL, ruleData);
|
||||
if (flagInfo) {
|
||||
//find the level of the class or subclass id that matches the valueContextId and use it as the initial temp hp
|
||||
const contextClassLevel = flagInfo.valueContextId === null ? 0 : ownerData.classLevelLookup[flagInfo.valueContextId];
|
||||
initialTempHp = contextClassLevel;
|
||||
}
|
||||
}
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.TEMP_HIT_POINTS_BASE_DRUID_LEVEL_MULTIPLIER)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.TEMP_HIT_POINTS_BASE_DRUID_LEVEL_MULTIPLIER, ruleData);
|
||||
if (flagInfo) {
|
||||
//find the level of the class or subclass id that matches the valueContextId and multiply it by the contextValue
|
||||
const contextClassLevel = flagInfo.valueContextId === null ? 0 : ownerData.classLevelLookup[flagInfo.valueContextId];
|
||||
//only multiply the tempHp if the there is a contextClassLevel
|
||||
if (contextClassLevel > 0) {
|
||||
const contextValue = flagInfo.value === null ? 1 : flagInfo.value;
|
||||
initialTempHp = contextClassLevel * contextValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return initialTempHp;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function deriveUseOwnerHp(creature) {
|
||||
//If this is true, the CreaturePane will use the player HP tracker instead of the Creature HP tracker and MaxHP override should be hidden from creature customization
|
||||
return hasGroupFlag(creature, CreatureGroupFlagEnum.USE_OWNER_MAX_HIT_POINTS);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param skill
|
||||
* @param ownerData
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveOwnerSkillModifier(creature, skill, ownerData, ruleData) {
|
||||
var _a, _b, _c;
|
||||
const skillInfo = RuleDataUtils.getSkillInfo(skill.id, ruleData);
|
||||
let statModifier = 0;
|
||||
let proficiencyBonus = ownerData.proficiencyBonus;
|
||||
let otherBonuses = 0;
|
||||
if (skillInfo) {
|
||||
const statInfo = getStatInfo(creature, skillInfo.stat);
|
||||
const ownerSkill = HelperUtils.lookupDataOrFallback(ownerData.skillLookup, skill.id);
|
||||
statModifier = (_a = statInfo === null || statInfo === void 0 ? void 0 : statInfo.monster.modifier) !== null && _a !== void 0 ? _a : 0;
|
||||
if (ownerSkill !== null) {
|
||||
const ownerProficiencyLevel = SkillAccessors.getProficiencyLevel(ownerSkill);
|
||||
// Creature gives proficiency bonus if the owner doesn't have any
|
||||
let proficiencyLevel = ProficiencyLevelEnum.FULL;
|
||||
if (ownerProficiencyLevel !== ProficiencyLevelEnum.NONE) {
|
||||
proficiencyLevel = ownerProficiencyLevel;
|
||||
}
|
||||
proficiencyBonus = CharacterDerivers.deriveProficiencyBonusAmount(proficiencyLevel, ownerData.proficiencyBonus);
|
||||
if (shouldReplaceWithOwnerStat(creature, skillInfo.stat)) {
|
||||
if (SkillAccessors.getIsOverridden(ownerSkill)) {
|
||||
statModifier = (_b = SkillAccessors.getModifier(ownerSkill)) !== null && _b !== void 0 ? _b : 0;
|
||||
proficiencyBonus = 0;
|
||||
}
|
||||
else {
|
||||
statModifier = SkillAccessors.getStatModifier(ownerSkill);
|
||||
otherBonuses = SkillAccessors.getModifierBonuses(ownerSkill);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const statInfo = getStatInfo(creature, skillInfo.stat);
|
||||
statModifier = (_c = statInfo === null || statInfo === void 0 ? void 0 : statInfo.monster.modifier) !== null && _c !== void 0 ? _c : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return statModifier + proficiencyBonus + otherBonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param stat
|
||||
* @param ownerData
|
||||
*/
|
||||
export function deriveOwnerSaveModifier(creature, stat, ownerData) {
|
||||
var _a, _b, _c;
|
||||
const statInfo = getStatInfo(creature, stat.id);
|
||||
let statModifier = 0;
|
||||
let proficiencyBonus = ownerData.proficiencyBonus;
|
||||
let otherBonuses = 0;
|
||||
const ownerAbility = HelperUtils.lookupDataOrFallback(ownerData.abilityLookup, stat.id);
|
||||
if (ownerAbility !== null) {
|
||||
const ownerProficiencyLevel = AbilityAccessors.getProficiencyLevel(ownerAbility);
|
||||
// Creature gives proficiency bonus if the owner doesn't have any
|
||||
let proficiencyLevel = ProficiencyLevelEnum.FULL;
|
||||
if (ownerProficiencyLevel !== ProficiencyLevelEnum.NONE) {
|
||||
proficiencyLevel = ownerProficiencyLevel;
|
||||
}
|
||||
proficiencyBonus = CharacterDerivers.deriveProficiencyBonusAmount(proficiencyLevel, ownerData.proficiencyBonus);
|
||||
if (shouldReplaceWithOwnerStat(creature, stat.id)) {
|
||||
if (AbilityAccessors.getIsSaveOverridden(ownerAbility)) {
|
||||
statModifier = (_a = AbilityAccessors.getSave(ownerAbility)) !== null && _a !== void 0 ? _a : 0;
|
||||
proficiencyBonus = 0;
|
||||
}
|
||||
else {
|
||||
statModifier = (_b = AbilityAccessors.getModifier(ownerAbility)) !== null && _b !== void 0 ? _b : 0;
|
||||
otherBonuses = AbilityAccessors.getSaveBonuses(ownerAbility);
|
||||
}
|
||||
}
|
||||
else {
|
||||
statModifier = (_c = statInfo === null || statInfo === void 0 ? void 0 : statInfo.monster.modifier) !== null && _c !== void 0 ? _c : 0;
|
||||
}
|
||||
}
|
||||
return statModifier + proficiencyBonus + otherBonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param skill
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveCreatureSkillModifier(creature, skill, ruleData) {
|
||||
var _a, _b;
|
||||
const skillInfo = RuleDataUtils.getSkillInfo(skill.skillId, ruleData);
|
||||
let statModifier = 0;
|
||||
if (skillInfo) {
|
||||
const statInfo = getStatInfo(creature, skillInfo.stat);
|
||||
statModifier = (_a = statInfo === null || statInfo === void 0 ? void 0 : statInfo.monster.modifier) !== null && _a !== void 0 ? _a : 0;
|
||||
}
|
||||
const proficiencyBonus = getChallengeProficiencyBonus(creature);
|
||||
const otherBonuses = (_b = skill.additionalBonus) !== null && _b !== void 0 ? _b : 0;
|
||||
return statModifier + proficiencyBonus + otherBonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param savingThrow
|
||||
*/
|
||||
export function deriveCreatureSaveModifier(creature, savingThrow) {
|
||||
var _a, _b;
|
||||
const statInfo = getStatInfo(creature, savingThrow.statId);
|
||||
const statModifier = (_a = statInfo === null || statInfo === void 0 ? void 0 : statInfo.monster.modifier) !== null && _a !== void 0 ? _a : 0;
|
||||
const proficiencyBonus = getChallengeProficiencyBonus(creature);
|
||||
const otherBonuses = (_b = savingThrow.bonusModifier) !== null && _b !== void 0 ? _b : 0;
|
||||
return statModifier + proficiencyBonus + otherBonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveSkills(creature, ownerData, ruleData) {
|
||||
const skills = RuleDataAccessors.getAbilitySkills(ruleData);
|
||||
return skills
|
||||
.map((skillInfo) => {
|
||||
var _a;
|
||||
const statInfo = RuleDataUtils.getStatInfo(skillInfo.stat, ruleData);
|
||||
const creatureSkill = getDefinitionSkills(creature).find((skill) => skill.skillId === skillInfo.id);
|
||||
const isCreatureProficient = !!creatureSkill;
|
||||
const potentialModifiers = [];
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.EVALUATE_OWNER_SKILL_PROFICIENCIES)) {
|
||||
const ownerSkill = HelperUtils.lookupDataOrFallback(ownerData.skillLookup, skillInfo.id);
|
||||
const isOwnerProficient = ownerSkill !== null && SkillAccessors.getProficiencyLevel(ownerSkill) !== ProficiencyLevelEnum.NONE;
|
||||
if (isCreatureProficient || isOwnerProficient) {
|
||||
potentialModifiers.push(deriveOwnerSkillModifier(creature, skillInfo, ownerData, ruleData));
|
||||
}
|
||||
// Can potentially use creatures modifier if the owner is "proficient"
|
||||
if (creatureSkill && isCreatureProficient && isOwnerProficient) {
|
||||
potentialModifiers.push(deriveCreatureSkillModifier(creature, creatureSkill, ruleData));
|
||||
}
|
||||
}
|
||||
else if (creatureSkill && isCreatureProficient) {
|
||||
potentialModifiers.push(deriveCreatureSkillModifier(creature, creatureSkill, ruleData));
|
||||
}
|
||||
// if we didn't generate any potential modifiers, exit early and null will be filtered out
|
||||
if (!potentialModifiers.length) {
|
||||
return null;
|
||||
}
|
||||
const modifier = Math.max(...potentialModifiers);
|
||||
let bonuses = 0;
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.PROFICIENT_SKILLS_ADD_PROFICIENCY_BONUS)) {
|
||||
bonuses += ownerData.proficiencyBonus;
|
||||
}
|
||||
return {
|
||||
id: skillInfo.id,
|
||||
modifier: modifier + bonuses,
|
||||
statKey: (_a = statInfo === null || statInfo === void 0 ? void 0 : statInfo.key) !== null && _a !== void 0 ? _a : 'UNK',
|
||||
};
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveSavingThrows(creature, ownerData, ruleData) {
|
||||
const stats = RuleDataAccessors.getStats(ruleData);
|
||||
return stats
|
||||
.map((stat) => {
|
||||
var _a;
|
||||
const creatureSavingThrow = getDefinitionSavingThrows(creature).find((savingThrow) => savingThrow.statId === stat.id);
|
||||
const isCreatureProficient = !!creatureSavingThrow;
|
||||
const potentialModifiers = [];
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.EVALUATE_OWNER_SAVE_PROFICIENCIES)) {
|
||||
const ownerAbility = HelperUtils.lookupDataOrFallback(ownerData.abilityLookup, stat.id);
|
||||
const isOwnerProficient = ownerAbility !== null &&
|
||||
AbilityAccessors.getProficiencyLevel(ownerAbility) !== ProficiencyLevelEnum.NONE;
|
||||
if (isCreatureProficient || isOwnerProficient) {
|
||||
potentialModifiers.push(deriveOwnerSaveModifier(creature, stat, ownerData));
|
||||
}
|
||||
// Can potentially use creatures modifier if the owner is "proficient"
|
||||
if (creatureSavingThrow && isCreatureProficient && isOwnerProficient) {
|
||||
potentialModifiers.push(deriveCreatureSaveModifier(creature, creatureSavingThrow));
|
||||
}
|
||||
}
|
||||
else if (creatureSavingThrow && isCreatureProficient) {
|
||||
potentialModifiers.push(deriveCreatureSaveModifier(creature, creatureSavingThrow));
|
||||
}
|
||||
// if we didn't generate any potential modifiers, exit early and null will be filtered out
|
||||
if (!potentialModifiers.length) {
|
||||
return null;
|
||||
}
|
||||
const modifier = Math.max(...potentialModifiers);
|
||||
let bonuses = 0;
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.PROFICIENT_SAVING_THROWS_ADD_PROFICIENCY_BONUS)) {
|
||||
bonuses += ownerData.proficiencyBonus;
|
||||
}
|
||||
return {
|
||||
statId: stat.id,
|
||||
modifier: modifier + bonuses,
|
||||
statKey: (_a = stat.key) !== null && _a !== void 0 ? _a : '',
|
||||
};
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveStats(creature, ownerData, ruleData) {
|
||||
return getDefinitionStats(creature).map((stat) => {
|
||||
var _a;
|
||||
const originalScore = stat.value;
|
||||
let score = stat.value;
|
||||
if (shouldReplaceWithOwnerStat(creature, stat.statId)) {
|
||||
const ownerAbility = HelperUtils.lookupDataOrFallback(ownerData.abilityLookup, stat.statId);
|
||||
if (ownerAbility !== null) {
|
||||
score = AbilityAccessors.getScore(ownerAbility);
|
||||
}
|
||||
}
|
||||
const statInfo = RuleDataUtils.getStatInfo(stat.statId, ruleData);
|
||||
const statKey = (_a = statInfo === null || statInfo === void 0 ? void 0 : statInfo.key) !== null && _a !== void 0 ? _a : null;
|
||||
const modifier = score === null ? null : AbilityUtils.getStatScoreModifier(score, ruleData);
|
||||
const originalModifier = originalScore === null ? null : AbilityUtils.getStatScoreModifier(originalScore, ruleData);
|
||||
return {
|
||||
id: stat.statId,
|
||||
score,
|
||||
modifier,
|
||||
statKey,
|
||||
monster: {
|
||||
score: originalScore,
|
||||
modifier: originalModifier,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveDamageAdjustments(creature, ruleData) {
|
||||
return getDefinitionDamageAdjustments(creature)
|
||||
.map((damageAdjustmentId) => RuleDataUtils.getDamageAdjustmentInfo(damageAdjustmentId, ruleData))
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveConditionImmunities(creature, ruleData) {
|
||||
return getDefinitionConditionImmunities(creature)
|
||||
.map((conditionId) => RuleDataUtils.getConditionInfo(conditionId, ruleData))
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param damageAdjustmentType
|
||||
* @param creature
|
||||
*/
|
||||
export function deriveDamageAdjustmentType(damageAdjustmentType, creature) {
|
||||
return getDamageAdjustments(creature).filter((damageAdjustment) => damageAdjustment.type === damageAdjustmentType);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveSubTypes(creature, ruleData) {
|
||||
const subTypes = getDefinitionSubTypes(creature);
|
||||
return subTypes
|
||||
.map((subTypeId) => RuleDataUtils.getMonsterSubTypeInfo(subTypeId, ruleData))
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param skillLookup
|
||||
* @param ruleData
|
||||
*/
|
||||
export function derivePassivePerception(creature, ownerData, skillLookup, ruleData) {
|
||||
if (!hasGroupFlag(creature, CreatureGroupFlagEnum.EVALUATE_UPDATED_PASSIVE_PERCEPTION)) {
|
||||
return getDefinitionPassivePerception(creature);
|
||||
}
|
||||
let skillModifier = 0;
|
||||
const perceptionInfo = skillLookup[AbilitySkillEnum.PERCEPTION];
|
||||
if (perceptionInfo) {
|
||||
skillModifier = perceptionInfo.modifier;
|
||||
}
|
||||
else {
|
||||
// fallback to perception's stat modifier if perception isn't called out
|
||||
const skillInfo = RuleDataUtils.getSkillInfo(AbilitySkillEnum.PERCEPTION, ruleData);
|
||||
if (skillInfo) {
|
||||
const statInfo = getStatInfo(creature, skillInfo.stat);
|
||||
skillModifier = statInfo && statInfo.modifier !== null ? statInfo.modifier : 0;
|
||||
}
|
||||
}
|
||||
const derivedPassivePerception = CharacterDerivers.derivePassiveSkill(skillModifier);
|
||||
const passivePerceptionPossibilities = [derivedPassivePerception];
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.EVALUATE_OWNER_PASSIVE_PERCEPTION)) {
|
||||
if (ownerData.passivePerception !== null) {
|
||||
passivePerceptionPossibilities.push(ownerData.passivePerception);
|
||||
}
|
||||
}
|
||||
return Math.max(...passivePerceptionPossibilities);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveEnvironmentTags(creature, ruleData) {
|
||||
const envs = getEnvironments(creature);
|
||||
return envs
|
||||
.map((envId) => {
|
||||
const envInfo = RuleDataUtils.getEnvironmentInfo(envId, ruleData);
|
||||
if (envInfo) {
|
||||
return envInfo.name;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveSubTypeTags(creature, ruleData) {
|
||||
const subTypes = getDefinitionSubTypes(creature);
|
||||
return subTypes
|
||||
.map((subTypeId) => {
|
||||
const info = RuleDataUtils.getMonsterSubTypeInfo(subTypeId, ruleData);
|
||||
if (info) {
|
||||
return info.name;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveTypeTag(creature, ruleData) {
|
||||
return RuleDataUtils.getMonsterTypeName(getTypeId(creature), ruleData, null);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function deriveMovementIds(creature) {
|
||||
return getMovements(creature).map((movement) => movement.movementId);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveMovementNames(creature, ruleData) {
|
||||
return getMovements(creature).map((movement) => RuleDataUtils.getMovementDescription(movement.movementId, ruleData));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveArmorClass(creature, ownerData, valueLookup, ruleData) {
|
||||
var _a;
|
||||
const armorOverride = deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_AC, null, valueLookup);
|
||||
if (armorOverride) {
|
||||
return armorOverride;
|
||||
}
|
||||
let bonuses = 0;
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.ARMOR_ADD_PROFICIENCY_BONUS)) {
|
||||
bonuses += ownerData.proficiencyBonus;
|
||||
}
|
||||
let armorClass = getDefinitionArmorClass(creature);
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.ARMOR_ADD_OWNER_WIS_PLUS_FIXED_VALUE)) {
|
||||
const flagInfo = RuleDataUtils.getCreatureGroupFlagInfo(CreatureGroupFlagEnum.ARMOR_ADD_OWNER_WIS_PLUS_FIXED_VALUE, ruleData);
|
||||
if (flagInfo) {
|
||||
const contextClassLevel = flagInfo.valueContextId === null ? 0 : ownerData.classLevelLookup[flagInfo.valueContextId];
|
||||
//Check if the owner has a matching class or subclass to the contextValueId
|
||||
if (contextClassLevel > 0) {
|
||||
const ownerWisdomModifier = (_a = ownerData.abilityLookup[AbilityStatEnum.WISDOM].modifier) !== null && _a !== void 0 ? _a : 0;
|
||||
const contextValue = flagInfo.value === null ? 0 : flagInfo.value;
|
||||
//AC will should be the highest value between the current AC and the owner's wisdom modifier + the context value
|
||||
armorClass = Math.max(armorClass, contextValue + ownerWisdomModifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Add any final bonuses to the AC;
|
||||
return armorClass + bonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueTypeId
|
||||
* @param fallback
|
||||
* @param valueLookup
|
||||
*/
|
||||
function deriveOverridenValue(creature, valueTypeId, fallback, valueLookup) {
|
||||
if (valueLookup) {
|
||||
const override = ValueUtils.getKeyValue(valueLookup, valueTypeId, ValueHacks.hack__toString(getMappingId(creature)), ValueHacks.hack__toString(getMappingEntityTypeId(creature)));
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveSizeId(creature, valueLookup) {
|
||||
return deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_SIZE, getDefinitionSizeId(creature), valueLookup);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveTypeId(creature, valueLookup) {
|
||||
return deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_TYPE_OVERRIDE, getDefinitionTypeId(creature), valueLookup);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveAlignmentId(creature, valueLookup) {
|
||||
return deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_ALIGNMENT, getDefinitionAlignmentId(creature), valueLookup);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveNotes(creature, valueLookup) {
|
||||
return deriveOverridenValue(creature, AdjustmentTypeEnum.CREATURE_NOTES, null, valueLookup);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveLevel(creature, ruleData) {
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.USE_CHALLENGE_RATING_AS_LEVEL)) {
|
||||
const challengeInfo = RuleDataUtils.getChallengeInfo(getChallengeRatingId(creature), ruleData);
|
||||
const level = challengeInfo ? challengeInfo.value : 0;
|
||||
const maxCharLevel = RuleDataAccessors.getMaxCharacterLevel(ruleData);
|
||||
return HelperUtils.clampInt(level, 1, maxCharLevel);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveChallengeInfo(creature, ruleData) {
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.USE_CHALLENGE_RATING_AS_LEVEL)) {
|
||||
return null;
|
||||
}
|
||||
return RuleDataUtils.getChallengeInfo(getChallengeRatingId(creature), ruleData);
|
||||
}
|
||||
export function deriveLairChallengeInfo(creature, ruleData) {
|
||||
if (hasGroupFlag(creature, CreatureGroupFlagEnum.USE_CHALLENGE_RATING_AS_LEVEL)) {
|
||||
return null;
|
||||
}
|
||||
return RuleDataUtils.getChallengeInfo(getLairChallengeRatingId(creature), ruleData);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param groupInfo
|
||||
* @param infusion
|
||||
*/
|
||||
export function deriveFlags(creature, groupInfo, infusion) {
|
||||
const flags = [];
|
||||
if (groupInfo && groupInfo.flags !== null) {
|
||||
flags.push(...groupInfo.flags);
|
||||
}
|
||||
if (infusion) {
|
||||
const creatureData = InfusionAccessors.getCreatureData(infusion);
|
||||
if (creatureData) {
|
||||
const foundCreatureData = creatureData.find((creatureDataEntry) => creatureDataEntry.monsterId === getId(creature));
|
||||
if (foundCreatureData && foundCreatureData.flags !== null) {
|
||||
flags.push(...foundCreatureData.flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param valueLookup
|
||||
*/
|
||||
export function deriveIsCustomized(creature, valueLookup) {
|
||||
let isCustomized = ValueValidators.validateHasCustomization(CREATURE_CUSTOMIZATION_ADJUSTMENT_TYPES, valueLookup, ValueHacks.hack__toString(getMappingId(creature)), ValueHacks.hack__toString(getMappingEntityTypeId(creature)));
|
||||
if (!isCustomized) {
|
||||
if (creature.name !== null && creature.name !== '') {
|
||||
isCustomized = true;
|
||||
}
|
||||
}
|
||||
return isCustomized;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { keyBy } from 'lodash';
|
||||
import { ClassGenerators } from '../Class';
|
||||
import { DamageAdjustmentTypeEnum } from '../Core';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { RuleDataUtils } from '../RuleData';
|
||||
import { getDefinitionArmorClass, getGroupId, getMappingId } from './accessors';
|
||||
import { deriveAlignmentId, deriveArmorClass, deriveChallengeInfo, deriveConditionImmunities, deriveDamageAdjustments, deriveDamageAdjustmentType, deriveEnvironmentTags, deriveFlags, deriveHitPointInfo, deriveInitialTempHp, deriveUseOwnerHp, deriveIsCustomized, deriveLairChallengeInfo, deriveLevel, deriveMovementIds, deriveMovementNames, deriveNotes, derivePassivePerception, derivePreOwnerHitPointInfo, deriveSavingThrows, deriveSizeId, deriveSkills, deriveStats, deriveSubTypes, deriveSubTypeTags, deriveTypeId, deriveTypeTag, } from './derivers';
|
||||
/**
|
||||
*
|
||||
* @param creatures
|
||||
* @param ownerData
|
||||
* @param valueLookup
|
||||
* @param creatureInfusionLookup
|
||||
* @param ruleData
|
||||
*/
|
||||
export function generateCreatures(creatures, ownerData, valueLookup, creatureInfusionLookup, ruleData) {
|
||||
return creatures.map((creature) => generateCreature(creature, ownerData, valueLookup, creatureInfusionLookup, ruleData));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
* @param valueLookup
|
||||
* @param creatureInfusionLookup
|
||||
*/
|
||||
export function generateBaseCreature(creature, ruleData, valueLookup = {}, creatureInfusionLookup = {}) {
|
||||
const sizeId = deriveSizeId(creature, valueLookup);
|
||||
const groupInfo = RuleDataUtils.getCreatureGroupInfo(getGroupId(creature), ruleData);
|
||||
const infusion = HelperUtils.lookupDataOrFallback(creatureInfusionLookup, getMappingId(creature));
|
||||
return Object.assign(Object.assign({}, creature), { sizeId,
|
||||
infusion,
|
||||
groupInfo, typeId: deriveTypeId(creature, valueLookup), alignmentId: deriveAlignmentId(creature, valueLookup), flags: deriveFlags(creature, groupInfo, infusion), sizeInfo: RuleDataUtils.getCreatureSizeInfo(sizeId, ruleData), damageAdjustments: deriveDamageAdjustments(creature, ruleData), conditionImmunities: deriveConditionImmunities(creature, ruleData), subTypes: deriveSubTypes(creature, ruleData), environmentTags: deriveEnvironmentTags(creature, ruleData), subTypeTags: deriveSubTypeTags(creature, ruleData), hitPointInfo: derivePreOwnerHitPointInfo(creature), movementIds: deriveMovementIds(creature), movementNames: deriveMovementNames(creature, ruleData), armorClass: getDefinitionArmorClass(creature), notes: deriveNotes(creature, valueLookup) });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ownerData
|
||||
* @param valueLookup
|
||||
* @param creatureInfusionLookup
|
||||
* @param ruleData
|
||||
*/
|
||||
export function generateCreature(creature, ownerData, valueLookup, creatureInfusionLookup, ruleData) {
|
||||
// Generate all base non dependent, but still relevant data on the creature
|
||||
const baseCreature = generateBaseCreature(creature, ruleData, valueLookup, creatureInfusionLookup);
|
||||
// Generate all dependent data that is used to derive other properties
|
||||
const stats = deriveStats(baseCreature, ownerData, ruleData);
|
||||
const creatureStageOne = Object.assign(Object.assign({}, baseCreature), { stats, statLookup: keyBy(stats, 'id'), level: deriveLevel(baseCreature, ruleData), challengeInfo: deriveChallengeInfo(baseCreature, ruleData), lairChallengeInfo: deriveLairChallengeInfo(baseCreature, ruleData), typeTag: deriveTypeTag(baseCreature, ruleData) });
|
||||
const savingThrows = deriveSavingThrows(creatureStageOne, ownerData, ruleData);
|
||||
const skills = deriveSkills(creatureStageOne, ownerData, ruleData);
|
||||
const skillLookup = keyBy(skills, 'id');
|
||||
// return final generated creature with full derived data
|
||||
return Object.assign(Object.assign({}, creatureStageOne), { damageVulnerabilities: deriveDamageAdjustmentType(DamageAdjustmentTypeEnum.VULNERABILITY, creatureStageOne), damageResistances: deriveDamageAdjustmentType(DamageAdjustmentTypeEnum.RESISTANCE, creatureStageOne), damageImmunities: deriveDamageAdjustmentType(DamageAdjustmentTypeEnum.IMMUNITY, creatureStageOne), savingThrows, savingThrowLookup: keyBy(savingThrows, 'statId'), skills,
|
||||
skillLookup, passivePerception: derivePassivePerception(creatureStageOne, ownerData, skillLookup, ruleData), armorClass: deriveArmorClass(creatureStageOne, ownerData, valueLookup, ruleData), hitPointInfo: deriveHitPointInfo(creatureStageOne, ownerData, valueLookup, ruleData), initialTempHp: deriveInitialTempHp(creatureStageOne, ownerData, ruleData), useOwnerHp: deriveUseOwnerHp(creatureStageOne), isCustomized: deriveIsCustomized(creatureStageOne, valueLookup) });
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param classLevelLookup
|
||||
* @param skillLookup
|
||||
* @param proficiencyBonus
|
||||
* @param abilityLookup
|
||||
* @param passivePerception
|
||||
*/
|
||||
export function generateCreatureOwnerData(classes, skillLookup, proficiencyBonus, abilityLookup, passivePerception) {
|
||||
return {
|
||||
abilityLookup,
|
||||
proficiencyBonus,
|
||||
skillLookup,
|
||||
classLevelLookup: ClassGenerators.generateClassLevelLookup(classes),
|
||||
passivePerception,
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creatures
|
||||
*/
|
||||
export function generateCreatureLookup(creatures) {
|
||||
return keyBy(creatures, (creature) => getMappingId(creature));
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import * as CreatureAccessors from './accessors';
|
||||
import * as CreatureConstants from './constants';
|
||||
import * as CreatureDerivers from './derivers';
|
||||
import * as CreatureGenerators from './generators';
|
||||
import * as CreatureNotes from './notes';
|
||||
import * as CreatureRenderers from './renderers';
|
||||
import * as CreatureSimulators from './simulators';
|
||||
import * as CreatureTypings from './typings';
|
||||
import * as CreatureUtils from './utils';
|
||||
export * from './typings';
|
||||
export * from './constants';
|
||||
export { CreatureAccessors, CreatureDerivers, CreatureGenerators, CreatureNotes, CreatureSimulators, CreatureUtils };
|
||||
export default Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, CreatureAccessors), CreatureConstants), CreatureDerivers), CreatureGenerators), CreatureNotes), CreatureTypings), CreatureSimulators), CreatureUtils), CreatureRenderers);
|
||||
@@ -0,0 +1,34 @@
|
||||
import { TypeScriptUtils } from '../../utils';
|
||||
import { InfusionAccessors } from '../Infusion';
|
||||
import { NoteGenerators } from '../Note';
|
||||
import { getEnvironmentTags, getInfusion, getNotes, getTags } from './accessors';
|
||||
export function getTagNoteComponents(creature) {
|
||||
const tags = getTags(creature);
|
||||
return NoteGenerators.createGroup(tags.map((tag) => NoteGenerators.createPlainText(tag)), ', ');
|
||||
}
|
||||
export function getEnvironmentNoteComponents(creature) {
|
||||
const envTags = getEnvironmentTags(creature);
|
||||
return NoteGenerators.createGroup(envTags.map((tag) => NoteGenerators.createPlainText(tag)), ', ');
|
||||
}
|
||||
function getUserNoteComponent(creature) {
|
||||
const notes = getNotes(creature);
|
||||
if (notes) {
|
||||
return NoteGenerators.createPlainText(notes);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function getInfusionNoteComponent(creature) {
|
||||
const infusion = getInfusion(creature);
|
||||
if (infusion) {
|
||||
return NoteGenerators.createPlainText(`Infusion: ${InfusionAccessors.getName(infusion)}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
export function getNoteComponents(creature, ruleData) {
|
||||
const notes = [];
|
||||
notes.push(getUserNoteComponent(creature));
|
||||
notes.push(getInfusionNoteComponent(creature));
|
||||
notes.push(getTagNoteComponents(creature));
|
||||
notes.push(getEnvironmentNoteComponents(creature));
|
||||
return notes.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
import { DiceRenderers } from '../Dice';
|
||||
import { FormatUtils } from '../Format';
|
||||
import { RuleDataUtils } from '../RuleData';
|
||||
import { getAlignmentId, getArmorClass, getArmorClassDescription, getChallengeInfo, getDefinitionName, getHideCr, getHitPointDice, getHitPointInfo, getInitiative, getLairChallengeInfo, getLanguageNote, getLanguages, getLevel, getMovements, getName, getPassivePerception, getSavingThrows, getSenses, getSizeId, getSkills, getStatBlockType, getSubTypes, getTypeId, } from './accessors';
|
||||
import { StatBlockTypeEnum } from './constants';
|
||||
import { getTypeName } from './utils';
|
||||
//Render a formatted meta text string for a given Creature
|
||||
export function renderMetaText(creature, ruleData, useBaseMonsterType) {
|
||||
var _a, _b;
|
||||
//CreatureLevel
|
||||
const creatureLevel = getLevel(creature);
|
||||
const level = creatureLevel !== null ? `${FormatUtils.ordinalize(creatureLevel)}-level` : '';
|
||||
//CreatureSize
|
||||
const sizeInfo = RuleDataUtils.getCreatureSizeInfo(getSizeId(creature), ruleData);
|
||||
const size = (_a = sizeInfo === null || sizeInfo === void 0 ? void 0 : sizeInfo.name) !== null && _a !== void 0 ? _a : '';
|
||||
//CreatureType
|
||||
let type = '';
|
||||
if (useBaseMonsterType) {
|
||||
const typeInfo = RuleDataUtils.getMonsterTypeInfo(getTypeId(creature), ruleData);
|
||||
if (typeInfo === null || typeInfo === void 0 ? void 0 : typeInfo.name) {
|
||||
type = typeInfo.name;
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = getTypeName(creature, ruleData);
|
||||
}
|
||||
//CreatureAlignment
|
||||
const alignmentInfo = RuleDataUtils.getAlignmentInfo(getAlignmentId(creature), ruleData);
|
||||
const alignment = (_b = alignmentInfo === null || alignmentInfo === void 0 ? void 0 : alignmentInfo.name) !== null && _b !== void 0 ? _b : '';
|
||||
//Extra Text
|
||||
let extraTextChunks = [];
|
||||
//If the creature has a customized name that is differenct than the definition name, add the definition name
|
||||
if (getName(creature) !== getDefinitionName(creature)) {
|
||||
extraTextChunks.push(getDefinitionName(creature));
|
||||
}
|
||||
//Add any subtypes
|
||||
const subTypes = getSubTypes(creature);
|
||||
if (subTypes.length) {
|
||||
subTypes.forEach((monsterInfo) => {
|
||||
if (monsterInfo.name !== null) {
|
||||
extraTextChunks.push(monsterInfo.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
const extraText = extraTextChunks.join(', ');
|
||||
return `${level} ${size} ${type}${extraText ? ` (${extraText})` : ''}${alignment ? `, ${alignment}` : ''}`.trim();
|
||||
}
|
||||
//Render a Creature's Armor Class with any additional description added
|
||||
export function renderArmorClass(creature) {
|
||||
return `${getArmorClass(creature)} ${getArmorClassDescription(creature)}`.trim();
|
||||
}
|
||||
//Render a Creature's initative info: bonus (score)
|
||||
export function renderInitiativeInfo(creature) {
|
||||
const initiativeInfo = getInitiative(creature);
|
||||
if (initiativeInfo === null || initiativeInfo === void 0 ? void 0 : initiativeInfo.bonus) {
|
||||
const { bonus, score } = initiativeInfo;
|
||||
return `${FormatUtils.renderSignedNumber(bonus)} ${score ? `(${initiativeInfo.score})` : ''}`.trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//Render a Creature's total Hit Points and Hit Point Dice
|
||||
export function renderHitPointInfo(creature) {
|
||||
const totalHp = getHitPointInfo(creature).totalHp;
|
||||
const hitPointDice = getHitPointDice(creature);
|
||||
const hpDiceText = hitPointDice ? ` (${DiceRenderers.renderDice(getHitPointDice(creature))})` : '';
|
||||
return `${totalHp}${hpDiceText}`;
|
||||
}
|
||||
//Render a Creature's Speed info
|
||||
export function renderSpeedInfo(creature, ruleData) {
|
||||
const movements = getMovements(creature);
|
||||
if (movements.length) {
|
||||
const movementDisplays = movements.map((movement, idx) => {
|
||||
let label = '';
|
||||
if (idx !== 0) {
|
||||
label = RuleDataUtils.getMovementName(movement.movementId, ruleData);
|
||||
}
|
||||
return `${label} ${FormatUtils.renderDistance(movement.speed)} ${movement.notes ? movement.notes : ''}`.trim();
|
||||
});
|
||||
return movementDisplays.join(', ');
|
||||
}
|
||||
return '--';
|
||||
}
|
||||
//Render a Creature's Saving Throws info
|
||||
export function renderSavingThrows(creature) {
|
||||
const savingThrows = getSavingThrows(creature);
|
||||
if (!savingThrows.length) {
|
||||
return null;
|
||||
}
|
||||
const savingThrowDisplays = savingThrows.map((savingThrow) => {
|
||||
return `${savingThrow.statKey} ${FormatUtils.renderSignedNumber(savingThrow.modifier)}`;
|
||||
});
|
||||
return savingThrowDisplays.join(', ');
|
||||
}
|
||||
//Render a Creature's Skills info
|
||||
export function renderSkills(creature, ruleData) {
|
||||
const skills = getSkills(creature);
|
||||
if (!skills.length) {
|
||||
return null;
|
||||
}
|
||||
const skillDisplays = skills.map((skill) => {
|
||||
const skillInfo = RuleDataUtils.getSkillInfo(skill.id, ruleData);
|
||||
const name = (skillInfo === null || skillInfo === void 0 ? void 0 : skillInfo.name) ? skillInfo.name : '';
|
||||
const modifier = skill.modifier;
|
||||
return `${name} ${FormatUtils.renderSignedNumber(modifier)}`;
|
||||
});
|
||||
return skillDisplays.join(', ');
|
||||
}
|
||||
//Render a Creature's Senses info
|
||||
export function renderSensesInfo(creature, ruleData) {
|
||||
const senses = getSenses(creature);
|
||||
const senseDisplays = senses.map((sense) => {
|
||||
const senseInfo = RuleDataUtils.getSenseInfo(sense.senseId, ruleData);
|
||||
const senseName = senseInfo ? senseInfo.name : '';
|
||||
return `${senseName} ${sense.notes}`;
|
||||
});
|
||||
const senseDisplay = senseDisplays.length ? `${senseDisplays.join(', ')}, ` : '';
|
||||
const passivePerception = getPassivePerception(creature);
|
||||
return `${senseDisplay}Passive Perception ${passivePerception}`;
|
||||
}
|
||||
//Render a Creature's Languages info
|
||||
export function renderLanguages(creature, ruleData) {
|
||||
const languages = getLanguages(creature);
|
||||
const languageNote = getLanguageNote(creature);
|
||||
let languageText = '';
|
||||
if (languages.length || languageNote) {
|
||||
let languageDisplays = languages.map((language) => {
|
||||
const name = RuleDataUtils.getLanguageName(language.languageId, ruleData);
|
||||
return `${name} ${language.notes}`.trim();
|
||||
});
|
||||
if (languageNote) {
|
||||
languageDisplays.push(languageNote);
|
||||
}
|
||||
languageText = languageDisplays.join(', ');
|
||||
}
|
||||
else {
|
||||
languageText = '--';
|
||||
}
|
||||
return languageText;
|
||||
}
|
||||
//Render a Creature's Challenge Rating info, adjusted for 2014 vs 2024 version
|
||||
export function renderChallengeRatingInfo(creature) {
|
||||
const challengeInfo = getChallengeInfo(creature);
|
||||
const hideCr = getHideCr(creature);
|
||||
const statBlockType = getStatBlockType(creature);
|
||||
if (!challengeInfo || hideCr) {
|
||||
return null;
|
||||
}
|
||||
if (statBlockType === StatBlockTypeEnum.CORE_RULES_2024) {
|
||||
const PBtext = `; PB ${FormatUtils.renderSignedNumber(challengeInfo.proficiencyBonus)}`;
|
||||
const lairChallengeInfo = getLairChallengeInfo(creature);
|
||||
const lairCRText = (lairChallengeInfo === null || lairChallengeInfo === void 0 ? void 0 : lairChallengeInfo.xp)
|
||||
? `, or ${FormatUtils.renderLocaleNumber(lairChallengeInfo.xp)} in lair`
|
||||
: '';
|
||||
return `${FormatUtils.renderChallengeRating(challengeInfo.value)} (XP ${FormatUtils.renderLocaleNumber(challengeInfo.xp)}${lairCRText}${PBtext})`;
|
||||
}
|
||||
return `${FormatUtils.renderChallengeRating(challengeInfo.value)} (${FormatUtils.renderLocaleNumber(challengeInfo.xp)} XP)`;
|
||||
}
|
||||
//render a Creature's Proficiency Bonus
|
||||
export function renderProficiencyBonus(creature) {
|
||||
const challengeInfo = getChallengeInfo(creature);
|
||||
const hideCr = getHideCr(creature);
|
||||
if (!challengeInfo || hideCr) {
|
||||
return null;
|
||||
}
|
||||
return FormatUtils.renderSignedNumber(challengeInfo.proficiencyBonus);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { deriveChallengeInfo, deriveLairChallengeInfo, deriveLevel, deriveTypeTag } from './derivers';
|
||||
import { generateBaseCreature } from './generators';
|
||||
/**
|
||||
*
|
||||
* @param creatureDefinition
|
||||
* @param groupId
|
||||
* @param ruleData
|
||||
*/
|
||||
export function simulateCreature(creatureDefinition, groupId, ruleData) {
|
||||
const creature = {
|
||||
definition: Object.assign({}, creatureDefinition),
|
||||
description: null,
|
||||
entityTypeId: -1,
|
||||
groupId,
|
||||
id: -1,
|
||||
isActive: false,
|
||||
name: null,
|
||||
removedHitPoints: 0,
|
||||
temporaryHitPoints: 0,
|
||||
};
|
||||
const baseCreature = generateBaseCreature(creature, ruleData);
|
||||
return Object.assign(Object.assign({}, baseCreature), { level: deriveLevel(baseCreature, ruleData), challengeInfo: deriveChallengeInfo(baseCreature, ruleData), lairChallengeInfo: deriveLairChallengeInfo(baseCreature, ruleData), typeTag: deriveTypeTag(baseCreature, ruleData), statLookup: {}, stats: [], damageImmunities: [], damageResistances: [], damageVulnerabilities: [], passivePerception: null, savingThrowLookup: {}, savingThrows: [], skillLookup: {}, skills: [], isCustomized: false, hitPointInfo: Object.assign({}, baseCreature.hitPointInfo), initialTempHp: 0, useOwnerHp: false });
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
import { orderBy } from 'lodash';
|
||||
import { HelperUtils } from '../Helper';
|
||||
import { InfusionAccessors } from '../Infusion';
|
||||
import { RuleDataUtils } from '../RuleData';
|
||||
import { getEnvironmentTags, getFlags, getGroupInfo, getInfusion, getMovements, getSavingThrows, getStats, getSubTypeTags, getSwarmInfo, getTags, getTypeId, getTypeTag, isSwarm, } from './accessors';
|
||||
import { CreatureGroupFlagEnum } from './constants';
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param ruleData
|
||||
* @param includeMultiParenthesis
|
||||
*/
|
||||
export function getTypeName(creature, ruleData, includeMultiParenthesis = true) {
|
||||
const groupInfo = getGroupInfo(creature);
|
||||
const typeId = getTypeId(creature);
|
||||
let prefix = '';
|
||||
let typeName = RuleDataUtils.getMonsterTypeName(typeId, ruleData);
|
||||
if (!typeName) {
|
||||
typeName = '';
|
||||
}
|
||||
if (isSwarm(creature)) {
|
||||
const swarmInfo = getSwarmInfo(creature);
|
||||
if (swarmInfo) {
|
||||
const sizeInfo = RuleDataUtils.getCreatureSizeInfo(swarmInfo.sizeId, ruleData);
|
||||
typeName = RuleDataUtils.getMonsterTypeName(swarmInfo.typeId, ruleData, undefined, true);
|
||||
if (!typeName) {
|
||||
typeName = '';
|
||||
}
|
||||
if (sizeInfo) {
|
||||
prefix = `swarm of ${sizeInfo.name} `;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (groupInfo && groupInfo.monsterTypes !== null && groupInfo.monsterTypes.length) {
|
||||
if (groupInfo.monsterTypes.includes(typeId)) {
|
||||
typeName = RuleDataUtils.getMonsterTypeName(typeId, ruleData, undefined, isSwarm(creature));
|
||||
if (!typeName) {
|
||||
typeName = '';
|
||||
}
|
||||
}
|
||||
else {
|
||||
let displayName = '';
|
||||
groupInfo.monsterTypes.forEach((monsterTypeId, idx) => {
|
||||
const parts = [];
|
||||
if (idx !== 0) {
|
||||
parts.push(', ');
|
||||
}
|
||||
if (groupInfo && groupInfo.monsterTypes !== null && idx === groupInfo.monsterTypes.length - 1) {
|
||||
parts.push('or ');
|
||||
}
|
||||
const monsterTypeName = RuleDataUtils.getMonsterTypeName(monsterTypeId, ruleData, undefined, isSwarm(creature));
|
||||
if (monsterTypeName) {
|
||||
parts.push(monsterTypeName);
|
||||
}
|
||||
displayName += parts.join('');
|
||||
});
|
||||
if (includeMultiParenthesis) {
|
||||
typeName = `(${displayName})`;
|
||||
}
|
||||
else {
|
||||
typeName = displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return `${prefix}${typeName}`.trim();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getHighestMovementInfo(creature) {
|
||||
return HelperUtils.getLast(getMovements(creature), 'speed');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function getSearchTags(creature) {
|
||||
const tags = [...getEnvironmentTags(creature), ...getTags(creature), ...getSubTypeTags(creature)];
|
||||
const typeTag = getTypeTag(creature);
|
||||
if (typeTag) {
|
||||
tags.push(typeTag);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param flag
|
||||
*/
|
||||
export function hasGroupFlag(creature, flag) {
|
||||
return getFlags(creature).includes(flag);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param stat
|
||||
*/
|
||||
export function shouldReplaceWithOwnerStat(creature, stat) {
|
||||
var _a, _b;
|
||||
const groupInfo = getGroupInfo(creature);
|
||||
return (_b = (_a = groupInfo === null || groupInfo === void 0 ? void 0 : groupInfo.ownerStats) === null || _a === void 0 ? void 0 : _a.includes(stat)) !== null && _b !== void 0 ? _b : false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param inventoryLookup
|
||||
*/
|
||||
export function getInfusionItem(creature, inventoryLookup) {
|
||||
const infusion = getInfusion(creature);
|
||||
if (infusion) {
|
||||
return HelperUtils.lookupDataOrFallback(inventoryLookup, InfusionAccessors.getInventoryMappingId(infusion));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param statId
|
||||
*/
|
||||
export function getStatInfo(creature, statId) {
|
||||
return HelperUtils.lookupDataOrFallback(creature.statLookup, statId);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
* @param skillId
|
||||
*/
|
||||
export function getSkill(creature, skillId) {
|
||||
return HelperUtils.lookupDataOrFallback(creature.skillLookup, skillId);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param flagKey
|
||||
* @param creature
|
||||
*/
|
||||
export function hasFlag(flagKey, creature) {
|
||||
const groupInfo = getGroupInfo(creature);
|
||||
if (groupInfo !== null) {
|
||||
return Boolean(HelperUtils.lookupDataOrFallback(groupInfo.flagInfoLookup, flagKey));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function canUseLairActions(creature) {
|
||||
return !hasFlag(CreatureGroupFlagEnum.CANNOT_USE_LAIR_ACTIONS, creature);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param creature
|
||||
*/
|
||||
export function canUseLegendaryActions(creature) {
|
||||
return !hasFlag(CreatureGroupFlagEnum.CANNOT_USE_LEGENDARY_ACTIONS, creature);
|
||||
}
|
||||
export function getAbilities(creature) {
|
||||
const stats = getStats(creature);
|
||||
const savingThrows = getSavingThrows(creature);
|
||||
const abilities = stats.map((stat) => {
|
||||
var _a, _b;
|
||||
const { id, modifier, score, statKey } = stat;
|
||||
const saveModifier = (_b = (_a = savingThrows.find((save) => save.statId === id)) === null || _a === void 0 ? void 0 : _a.modifier) !== null && _b !== void 0 ? _b : modifier;
|
||||
return {
|
||||
id,
|
||||
modifier: modifier !== null && modifier !== void 0 ? modifier : 0,
|
||||
score: score !== null && score !== void 0 ? score : 0,
|
||||
statKey: statKey !== null && statKey !== void 0 ? statKey : '',
|
||||
saveModifier: saveModifier !== null && saveModifier !== void 0 ? saveModifier : 0,
|
||||
};
|
||||
});
|
||||
return orderBy(abilities, 'id');
|
||||
}
|
||||
Reference in New Issue
Block a user