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,42 @@
|
||||
import { ActionAccessors } from '../../Action';
|
||||
import { ActivationAccessors } from '../../Activation';
|
||||
import { ActivatableTypeEnum } from '../../Core';
|
||||
import { OptionAccessors } from '../../Option';
|
||||
/**
|
||||
*
|
||||
* @param options
|
||||
* @param parentEntity
|
||||
*/
|
||||
export function deriveActivatableOptions(options, parentEntity) {
|
||||
const activatables = [];
|
||||
options.forEach((option) => {
|
||||
const actions = OptionAccessors.getActions(option);
|
||||
if (actions.length) {
|
||||
activatables.push(...deriveActivatableActions(actions, parentEntity));
|
||||
}
|
||||
});
|
||||
return activatables;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param actions
|
||||
* @param parentEntity
|
||||
*/
|
||||
export function deriveActivatableActions(actions, parentEntity) {
|
||||
const activatables = [];
|
||||
actions.forEach((action) => {
|
||||
const activation = ActionAccessors.getActivation(action);
|
||||
if (activation !== null && ActivationAccessors.getType(activation) !== null) {
|
||||
activatables.push({
|
||||
type: ActivatableTypeEnum.ACTION,
|
||||
sortText: ActionAccessors.getName(action),
|
||||
activation,
|
||||
key: ActionAccessors.getUniqueKey(action),
|
||||
limitedUse: ActionAccessors.getLimitedUse(action),
|
||||
entity: action,
|
||||
parentEntity,
|
||||
});
|
||||
}
|
||||
});
|
||||
return activatables;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
*
|
||||
* @param armorClassSources
|
||||
* @param initialValue
|
||||
*/
|
||||
export function deriveArmorClassSupplierTotal(armorClassSources, initialValue = 0) {
|
||||
return armorClassSources.reduce((acc, armorClassSource) => {
|
||||
if (armorClassSource.amount) {
|
||||
acc += armorClassSource.amount;
|
||||
}
|
||||
return acc;
|
||||
}, initialValue);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { AbilityAccessors } from '../../Ability';
|
||||
import { ModifierDerivers, ModifierValidators } from '../../Modifier';
|
||||
/**
|
||||
*
|
||||
* @param proficiencyBonus
|
||||
* @param abilityModifier
|
||||
*/
|
||||
export function deriveAttackSaveValue(proficiencyBonus, abilityModifier) {
|
||||
return 8 + proficiencyBonus + abilityModifier;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param proficiencyBonus
|
||||
* @param abilityModifier
|
||||
*/
|
||||
export function deriveAttackModifier(proficiencyBonus, abilityModifier) {
|
||||
return proficiencyBonus + abilityModifier;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param availableAbilities
|
||||
* @param modifiers
|
||||
* @param proficiencyBonus
|
||||
* @param abilityLookup
|
||||
*/
|
||||
export function deriveAttackAbilityPossibilities(availableAbilities, modifiers, proficiencyBonus, abilityLookup) {
|
||||
return availableAbilities.map((abilityId) => {
|
||||
const ability = abilityLookup[abilityId];
|
||||
// get bonus stat attack modifiers
|
||||
const bonusStatToHitModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusStatAttackModifier(modifier, abilityId));
|
||||
const bonusStatToHitModifierTotal = ModifierDerivers.sumModifiers(bonusStatToHitModifiers, abilityLookup);
|
||||
// get damage stat attack modifiers
|
||||
const damageStatAttackModifiers = modifiers.filter((modifier) => ModifierValidators.isValidDamageStatAttackModifier(modifier, abilityId));
|
||||
const damageStatAttackModifierTotal = ModifierDerivers.sumModifiers(damageStatAttackModifiers, abilityLookup);
|
||||
const abilityModifier = ability ? AbilityAccessors.getModifier(ability) : null;
|
||||
const modifier = abilityModifier ? abilityModifier : 0;
|
||||
const toHit = modifier + proficiencyBonus + bonusStatToHitModifierTotal;
|
||||
return {
|
||||
abilityId,
|
||||
toHit,
|
||||
modifier,
|
||||
damageBonus: damageStatAttackModifierTotal + modifier,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { DiceAdjustmentTypeEnum } from '../../Dice';
|
||||
import { ModifierDerivers, ModifierValidators } from '../../Modifier';
|
||||
/**
|
||||
*
|
||||
* @param modifiers
|
||||
*/
|
||||
export function deriveAdvantageDeathSavesAdjustments(modifiers) {
|
||||
return modifiers
|
||||
.filter((modifier) => ModifierValidators.isAdvantageDeathSavesModifier(modifier))
|
||||
.map((modifier) => ModifierDerivers.deriveDiceAdjustment(modifier, DiceAdjustmentTypeEnum.ADVANTAGE));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param modifiers
|
||||
*/
|
||||
export function deriveDisadvantageDeathSavesAdjustments(modifiers) {
|
||||
return modifiers
|
||||
.filter((modifier) => ModifierValidators.isDisadvantageDeathSavesModifier(modifier))
|
||||
.map((modifier) => ModifierDerivers.deriveDiceAdjustment(modifier, DiceAdjustmentTypeEnum.DISADVANTAGE));
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { DataOriginGenerators, DataOriginTypeEnum } from '../../DataOrigin';
|
||||
/**
|
||||
*
|
||||
* @param adjustment
|
||||
*/
|
||||
export function deriveCustomDefenseAdjustmentDataOrigin(adjustment) {
|
||||
return DataOriginGenerators.generateDataOrigin(DataOriginTypeEnum.CUSTOM, adjustment.source ? adjustment.source : 'Custom');
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param adjustment
|
||||
*/
|
||||
export function deriveCustomConditionDefenseAdjustmentDataOrigin(adjustment) {
|
||||
return DataOriginGenerators.generateDataOrigin(DataOriginTypeEnum.CUSTOM, adjustment.source ? adjustment.source : 'Custom');
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { ItemAccessors, ItemValidators } from '../../Item';
|
||||
import { LimitedUseDerivers } from '../../LimitedUse';
|
||||
import { ModifierAccessors } from '../../Modifier';
|
||||
import { ProtectionAvailabilityStatusEnum } from '../constants';
|
||||
/**
|
||||
*
|
||||
* @param limitedUse
|
||||
* @param abilityLookup
|
||||
* @param ruleData
|
||||
* @param proficiencyBonus
|
||||
*/
|
||||
export function deriveProtectionSupplierAvailabilityStatus(limitedUse, abilityLookup, ruleData, proficiencyBonus) {
|
||||
let availabilityStatus = ProtectionAvailabilityStatusEnum.AVAILABLE;
|
||||
if (!LimitedUseDerivers.deriveHasUsesAvailable(limitedUse, abilityLookup, ruleData, proficiencyBonus)) {
|
||||
availabilityStatus = ProtectionAvailabilityStatusEnum.NO_LIMITED_USE_REMAINING;
|
||||
}
|
||||
return availabilityStatus;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param item
|
||||
* @param modifier
|
||||
* @param limitedUse
|
||||
* @param abilityLookup
|
||||
* @param ruleData
|
||||
* @param proficiencyBonus
|
||||
* @param characterId
|
||||
*/
|
||||
export function deriveItemProtectionSupplierAvailabilityStatus(item, modifier, limitedUse, abilityLookup, ruleData, proficiencyBonus, characterId) {
|
||||
if (ItemAccessors.canEquip(item)) {
|
||||
const isEquippedToCurrentCharacter = ItemValidators.isEquippedToCurrentCharacter(item, characterId);
|
||||
if (!isEquippedToCurrentCharacter) {
|
||||
return ProtectionAvailabilityStatusEnum.ITEM_NOT_EQUIPPED;
|
||||
}
|
||||
if (ModifierAccessors.requiresAttunement(modifier) && !ItemAccessors.isAttuned(item)) {
|
||||
return ProtectionAvailabilityStatusEnum.ITEM_NOT_ATTUNED;
|
||||
}
|
||||
}
|
||||
if (!LimitedUseDerivers.deriveHasUsesAvailable(limitedUse, abilityLookup, ruleData, proficiencyBonus)) {
|
||||
return ProtectionAvailabilityStatusEnum.NO_LIMITED_USE_REMAINING;
|
||||
}
|
||||
return ProtectionAvailabilityStatusEnum.AVAILABLE;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { ProficiencyLevelEnum, ProficiencyRoundingEnum } from '../../Core';
|
||||
import { ModifierDerivers, ModifierValidators } from '../../Modifier';
|
||||
import { RuleDataUtils } from '../../RuleData';
|
||||
/**
|
||||
*
|
||||
* @param level
|
||||
* @param modifiers
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveProficiencyBonus(level, modifiers, ruleData) {
|
||||
const levelBonus = RuleDataUtils.getLevelProficiencyBonus(level, ruleData);
|
||||
const bonusProficiencyBonusModifiers = modifiers.filter((modifier) => ModifierValidators.isBonusProficiencyBonusModifier(modifier));
|
||||
const modifierBonusTotal = ModifierDerivers.sumModifiers(bonusProficiencyBonusModifiers);
|
||||
return levelBonus + modifierBonusTotal;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param proficiencyLevel
|
||||
* @param proficiencyBonus
|
||||
* @param proficiencyRounding
|
||||
*/
|
||||
export function deriveProficiencyBonusAmount(proficiencyLevel, proficiencyBonus, proficiencyRounding = ProficiencyRoundingEnum.DOWN) {
|
||||
let proficiencyBonusAmount = 0;
|
||||
switch (proficiencyLevel) {
|
||||
case ProficiencyLevelEnum.EXPERT:
|
||||
proficiencyBonusAmount = proficiencyBonus * 2;
|
||||
break;
|
||||
case ProficiencyLevelEnum.FULL:
|
||||
proficiencyBonusAmount = proficiencyBonus;
|
||||
break;
|
||||
case ProficiencyLevelEnum.HALF:
|
||||
if (proficiencyRounding === ProficiencyRoundingEnum.UP) {
|
||||
proficiencyBonusAmount = Math.ceil(proficiencyBonus / 2);
|
||||
}
|
||||
else {
|
||||
proficiencyBonusAmount = Math.floor(proficiencyBonus / 2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// not implemented
|
||||
}
|
||||
return proficiencyBonusAmount;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { RuleDataAccessors } from '../../RuleData';
|
||||
/**
|
||||
*
|
||||
* @param xp
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveXpLevel(xp, ruleData) {
|
||||
let level = 0;
|
||||
if (xp === 0) {
|
||||
return 1;
|
||||
}
|
||||
if (xp >= deriveMaxXp(ruleData)) {
|
||||
return RuleDataAccessors.getMaxCharacterLevel(ruleData);
|
||||
}
|
||||
const levelExperiencePoints = RuleDataAccessors.getLevelExperiencePoints(ruleData);
|
||||
levelExperiencePoints.forEach((levelXpAmount, levelIdx) => {
|
||||
if (level === 0 && xp < levelXpAmount) {
|
||||
level = levelIdx;
|
||||
}
|
||||
});
|
||||
return level;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param level
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveCurrentLevelXp(level, ruleData) {
|
||||
const levelExperiencePoints = RuleDataAccessors.getLevelExperiencePoints(ruleData);
|
||||
return levelExperiencePoints[Math.max(0, level - 1)];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param level
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveNextLevelXp(level, ruleData) {
|
||||
const levelExperiencePoints = RuleDataAccessors.getLevelExperiencePoints(ruleData);
|
||||
return levelExperiencePoints[Math.min(levelExperiencePoints.length - 1, level)];
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param ruleData
|
||||
*/
|
||||
export function deriveMaxXp(ruleData) {
|
||||
const levelExperiencePoints = RuleDataAccessors.getLevelExperiencePoints(ruleData);
|
||||
return levelExperiencePoints[levelExperiencePoints.length - 1];
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { SaveTypeEnum } from '../../Core';
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
export function deriveSaveTypeName(type) {
|
||||
let name = '';
|
||||
switch (type) {
|
||||
case SaveTypeEnum.ADVANTAGE:
|
||||
name = 'Advantage';
|
||||
break;
|
||||
case SaveTypeEnum.DISADVANTAGE:
|
||||
name = 'Disadvantage';
|
||||
break;
|
||||
case SaveTypeEnum.BONUS:
|
||||
name = 'Bonus';
|
||||
break;
|
||||
default:
|
||||
//not implemented
|
||||
}
|
||||
return name;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { AbilitySkillEnum } from '../../Core';
|
||||
import { ModifierDerivers, ModifierValidators } from '../../Modifier';
|
||||
import { SkillAccessors } from '../../Skill';
|
||||
/**
|
||||
*
|
||||
* @param skillModifier
|
||||
* @param bonuses
|
||||
*/
|
||||
export function derivePassiveSkill(skillModifier, bonuses = 0) {
|
||||
return 10 + skillModifier + bonuses;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param skills
|
||||
* @param modifiers
|
||||
* @param abilityLookup
|
||||
*/
|
||||
export function derivePassivePerception(skills, modifiers, abilityLookup) {
|
||||
const skill = skills.find((skill) => SkillAccessors.getId(skill) === AbilitySkillEnum.PERCEPTION);
|
||||
const skillModifier = skill ? SkillAccessors.getModifier(skill) : null;
|
||||
if (!skill || skillModifier === null) {
|
||||
return 0;
|
||||
}
|
||||
const bonusModifiers = modifiers.filter((modifier) => ModifierValidators.isBonusPassivePerceptionModifier(modifier));
|
||||
const bonusModifierTotal = ModifierDerivers.sumModifiers(bonusModifiers, abilityLookup);
|
||||
return derivePassiveSkill(skillModifier, bonusModifierTotal);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param skills
|
||||
* @param modifiers
|
||||
* @param abilityLookup
|
||||
*/
|
||||
export function derivePassiveInvestigation(skills, modifiers, abilityLookup) {
|
||||
const skill = skills.find((skill) => SkillAccessors.getId(skill) === AbilitySkillEnum.INVESTIGATION);
|
||||
const skillModifier = skill ? SkillAccessors.getModifier(skill) : null;
|
||||
if (!skill || skillModifier === null) {
|
||||
return 0;
|
||||
}
|
||||
const bonusModifiers = modifiers.filter((modifier) => ModifierValidators.isBonusPassiveInvestigationModifier(modifier));
|
||||
const bonusModifierTotal = ModifierDerivers.sumModifiers(bonusModifiers, abilityLookup);
|
||||
return derivePassiveSkill(skillModifier, bonusModifierTotal);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param skills
|
||||
* @param modifiers
|
||||
* @param abilityLookup
|
||||
*/
|
||||
export function derivePassiveInsight(skills, modifiers, abilityLookup) {
|
||||
const skill = skills.find((skill) => SkillAccessors.getId(skill) === AbilitySkillEnum.INSIGHT);
|
||||
const skillModifier = skill ? SkillAccessors.getModifier(skill) : null;
|
||||
if (!skill || skillModifier === null) {
|
||||
return 0;
|
||||
}
|
||||
const bonusModifiers = modifiers.filter((modifier) => ModifierValidators.isBonusPassiveInsightModifier(modifier));
|
||||
const bonusModifierTotal = ModifierDerivers.sumModifiers(bonusModifiers, abilityLookup);
|
||||
return derivePassiveSkill(skillModifier, bonusModifierTotal);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { PreferenceEncumbranceTypeEnum, WeightSpeedTypeEnum } from '../../Core';
|
||||
import { getCarryCapacity, getEncumberedWeight, getHeavilyEncumberedWeight } from '../utils';
|
||||
/**
|
||||
*
|
||||
* @param currentWeight
|
||||
* @param strScore
|
||||
* @param size
|
||||
* @param preferences
|
||||
* @param modifiers
|
||||
*/
|
||||
export function deriveCurrentWeightSpeedType(currentWeight, strScore, size, preferences, modifiers) {
|
||||
if (preferences !== null) {
|
||||
if (preferences.encumbranceType === PreferenceEncumbranceTypeEnum.VARIANT) {
|
||||
if (currentWeight > getHeavilyEncumberedWeight(strScore, size, modifiers)) {
|
||||
return WeightSpeedTypeEnum.HEAVILY_ENCUMBERED;
|
||||
}
|
||||
else if (currentWeight > getEncumberedWeight(strScore, size, modifiers)) {
|
||||
return WeightSpeedTypeEnum.ENCUMBERED;
|
||||
}
|
||||
}
|
||||
else if (preferences.encumbranceType === PreferenceEncumbranceTypeEnum.ENCUMBRANCE) {
|
||||
if (currentWeight > getCarryCapacity(strScore, size, modifiers)) {
|
||||
return WeightSpeedTypeEnum.OVER_CARRYING_CAPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
return WeightSpeedTypeEnum.NORMAL;
|
||||
}
|
||||
Reference in New Issue
Block a user