New source found from dndbeyond.com

This commit is contained in:
2025-07-02 01:00:11 -07:00
parent 2c657770de
commit b7f7f4a655
24 changed files with 291 additions and 43 deletions
@@ -16,11 +16,12 @@ export function hack__generateHitPointParts(baseHp, overrideHp, bonusHp, tempHp,
removedHp,
};
}
export function hack__generateSpecialWeaponPropertiesEnabled(hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled) {
export function hack__generateSpecialWeaponPropertiesEnabled(hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled, replacementWeaponStats) {
return {
hexWeaponEnabled,
pactWeaponEnabled,
improvedPactWeaponEnabled,
dedicatedWeaponEnabled,
replacementWeaponStats,
};
}
@@ -540,3 +540,6 @@ export function getSpellListIds(charClass) {
export function getOptionalClassFeatures(charClass) {
return charClass.optionalClassFeatures;
}
export function getReplacementWeaponAbilityStats(charClass) {
return charClass.replacementWeaponAbilityStats;
}
@@ -4,7 +4,7 @@ import { ClassFeatureAccessors, ClassFeatureUtils, ClassFeatureValidators } from
import { DB_STRING_BOOK_OF_ANCIENT_SECRETS, DB_STRING_INFUSE_ITEM, FeatureTypeEnum, } from '../Core';
import { DataOriginGenerators } from '../DataOrigin';
import { HelperUtils } from '../Helper';
import { ModifierValidators } from '../Modifier';
import { ModifierAccessors, ModifierValidators } from '../Modifier';
import { OptionalClassFeatureAccessors } from '../OptionalClassFeature';
import { DefaultSpellCastingLearningStyle, SpellDerivers } from '../Spell';
import { getActiveId, getDefinitionClassFeatures, getDefinitionSpellcastingStatId, getId, getLevel, getMappingId, getSubclass, getClassFeatures, getDefinitionSpellCastingLearningStyle, } from './accessors';
@@ -166,6 +166,18 @@ export function deriveOrderedClassFeatures(classFeatures) {
(classFeature) => ClassFeatureAccessors.getName(classFeature),
]);
}
export function deriveReplacementWeaponAbilityStats(classModifiers) {
const replacementWeaponAbilityStats = [];
classModifiers.forEach((modifier) => {
if (ModifierValidators.isEnablesAbilityStatModifier(modifier)) {
const statId = ModifierAccessors.getEntityId(modifier) || 0;
if (statId && !replacementWeaponAbilityStats.includes(statId)) {
replacementWeaponAbilityStats.push(statId);
}
}
});
return replacementWeaponAbilityStats;
}
/**
*
* @param classFeatures
@@ -8,8 +8,8 @@ import { FormatUtils } from '../Format';
import { ModifierDerivers, ModifierValidators } from '../Modifier';
import { OptionAccessors } from '../Option';
import { SpellAccessors, SpellDerivers, SpellGenerators, } from '../Spell';
import { getActiveId, getBaseClassSpells, getClassFeatures, getDefinitionClassFeatures, getEnablesDedicatedWeapon, getEnablesHexWeapon, getEnablesPactWeapon, getId, getLevel, getMappingId, getName, getSlug, getSpellPrepareType, getSpellRules, getSpells, getSubclass, isPactMagicActive, isSpellcastingActive, isStartingClass, } from './accessors';
import { deriveActiveId, deriveClassFeatureGroups, deriveConsolidatedClassFeatures, deriveDedicatedHexAndPactWeaponEnabled, deriveIsPactMagicActive, deriveIsSpellcastingActive, deriveSpellCastingLearningStyle, deriveSpellListIds, deriveSpellRules, deriveSpells, deriveUniqueKey, } from './derivers';
import { getActiveId, getBaseClassSpells, getClassFeatures, getDefinitionClassFeatures, getEnablesDedicatedWeapon, getEnablesHexWeapon, getEnablesPactWeapon, getId, getLevel, getMappingId, getName, getReplacementWeaponAbilityStats, getSlug, getSpellPrepareType, getSpellRules, getSpells, getSubclass, isPactMagicActive, isSpellcastingActive, isStartingClass, } from './accessors';
import { deriveActiveId, deriveClassFeatureGroups, deriveConsolidatedClassFeatures, deriveDedicatedHexAndPactWeaponEnabled, deriveIsPactMagicActive, deriveIsSpellcastingActive, deriveReplacementWeaponAbilityStats, deriveSpellCastingLearningStyle, deriveSpellListIds, deriveSpellRules, deriveSpells, deriveUniqueKey, } from './derivers';
export function generateBaseCharClasses(charClasses, optionalClassFeatures, allClassSpells, allClassAlwaysPreparedSpells, allClassAlwaysKnownSpells, appContext, ruleData, classesLookupData, definitionPool, characterPreferences, characterId, choiceComponents, baseFeats) {
const orderedClasses = orderBy(charClasses, [(charClass) => isStartingClass(charClass), (charClass) => getName(charClass)], ['desc', 'asc']);
const hack__baseCharClasses = orderedClasses.map((charClass) => hack__generateHackBaseCharClass(charClass, optionalClassFeatures, ruleData, classesLookupData, characterPreferences.enableOptionalClassFeatures));
@@ -70,7 +70,7 @@ export function generateBaseCharClass(charClass, optionalClassFeatures, allClass
actions,
enablesDedicatedWeapon,
enablesHexWeapon,
enablesPactWeapon, slug: FormatUtils.cobaltSlugify(getName(charClass)), spellListIds: deriveSpellListIds(updatedFeatures, getLevel(charClass)), spellCastingLearningStyle: deriveSpellCastingLearningStyle(charClass) });
enablesPactWeapon, slug: FormatUtils.cobaltSlugify(getName(charClass)), spellListIds: deriveSpellListIds(updatedFeatures, getLevel(charClass)), spellCastingLearningStyle: deriveSpellCastingLearningStyle(charClass), replacementWeaponAbilityStats: deriveReplacementWeaponAbilityStats(classModifiers) });
}
export function generateClassFeatureLookup(baseCharClasses) {
const lookup = {};
@@ -209,6 +209,14 @@ export function generatePactWeaponEnabled(classes) {
});
return pactWeaponEnabled;
}
export function generateReplacementWeaponAbilityStats(classes) {
const replacementWeaponStats = [];
classes.forEach((charClass) => {
const classReplacementWeaponStats = getReplacementWeaponAbilityStats(charClass);
replacementWeaponStats.push(...classReplacementWeaponStats);
});
return replacementWeaponStats;
}
/**
*
* @param classes
@@ -1,3 +1,4 @@
import { AdjustmentTypeEnum } from '../Value';
export const FEET_IN_MILES = 5280;
export const POUNDS_IN_TON = 2000;
export var AppContextTypeEnum;
@@ -400,3 +401,11 @@ export const ABILITY_STAT_PHYSICAL_LIST = [
AbilityStatEnum.DEXTERITY,
AbilityStatEnum.CONSTITUTION,
];
export const STAT_REPLACEMENT_TYPE_LOOKUP = {
[AdjustmentTypeEnum.USE_STRENGTH]: AbilityStatEnum.STRENGTH,
[AdjustmentTypeEnum.USE_DEXTERITY]: AbilityStatEnum.DEXTERITY,
[AdjustmentTypeEnum.USE_CONSTITUTION]: AbilityStatEnum.CONSTITUTION,
[AdjustmentTypeEnum.USE_INTELLIGENCE]: AbilityStatEnum.INTELLIGENCE,
[AdjustmentTypeEnum.USE_WISDOM]: AbilityStatEnum.WISDOM,
[AdjustmentTypeEnum.USE_CHARISMA]: AbilityStatEnum.CHARISMA,
};
@@ -1,6 +1,7 @@
import { round } from 'lodash';
import { RuleDataAccessors } from '../RuleData';
import { CURRENCY_VALUE, FEET_IN_MILES } from './constants';
import { AdjustmentTypeEnum } from '../Value';
import { AbilityStatEnum, CURRENCY_VALUE, FEET_IN_MILES } from './constants';
export function convertFeetToMiles(number, precision = 2) {
return round(number / FEET_IN_MILES, precision);
}
@@ -41,3 +42,23 @@ export function getCurrencyTransactionAdjustment(multiplier, adjustments) {
});
return adjustedCurrency;
}
// returns the adjusment type that corresponds to a given stat id
// Only returns types that are defined in the STAT_REPLACEMENT_TYPE_LOOKUP
export function getAdjustmentTypeByStatId(statId) {
switch (statId) {
case AbilityStatEnum.STRENGTH:
return AdjustmentTypeEnum.USE_STRENGTH;
case AbilityStatEnum.DEXTERITY:
return AdjustmentTypeEnum.USE_DEXTERITY;
case AbilityStatEnum.CONSTITUTION:
return AdjustmentTypeEnum.USE_CONSTITUTION;
case AbilityStatEnum.INTELLIGENCE:
return AdjustmentTypeEnum.USE_INTELLIGENCE;
case AbilityStatEnum.WISDOM:
return AdjustmentTypeEnum.USE_WISDOM;
case AbilityStatEnum.CHARISMA:
return AdjustmentTypeEnum.USE_CHARISMA;
default:
return null;
}
}
@@ -1040,3 +1040,9 @@ export function getPrimarySourceCategoryId(item) {
export function getSecondarySourceCategoryIds(item) {
return item.secondarySourceCategoryIds;
}
export function getReplacementWeaponStats(item) {
return item.replacementWeaponStats;
}
export function getAppliedWeaponReplacementStats(item) {
return item.appliedWeaponReplacementStats;
}
@@ -512,7 +512,7 @@ export function deriveWeaponReach(item, modifiers, ruleData) {
* @param modifiers
* @param martialArtsLevel
*/
export function deriveAvailableWeaponAbilities(item, modifiers, martialArtsLevelScale, isDedicatedWeapon, isPactWeapon, isHexWeapon) {
export function deriveAvailableWeaponAbilities(item, modifiers, martialArtsLevelScale, isDedicatedWeapon, isPactWeapon, isHexWeapon, appliedWeaponReplacementStats) {
const availableAbilities = [];
const attackType = getAttackType(item);
if (attackType === AttackTypeRangeEnum.MELEE || hasWeaponProperty(item, WeaponPropertyEnum.FINESSE)) {
@@ -562,6 +562,22 @@ export function deriveAvailableWeaponAbilities(item, modifiers, martialArtsLevel
});
}
}
//handle Weapon Replacement Stats
if (appliedWeaponReplacementStats.length > 0) {
const enableAbilityStatReplacementModifiers = modifiers.filter((modifier) => ModifierValidators.isReplaceWeaponAbilityModifier(modifier));
enableAbilityStatReplacementModifiers.forEach((modifier) => {
//get the origin of the modifier
const dataOrigin = ModifierAccessors.getDataOrigin(modifier);
if (dataOrigin) {
const replacementAbilities = deriveReplacementWeaponAbilities(modifiers, dataOrigin);
replacementAbilities.forEach((ability) => {
if (!availableAbilities.includes(ability)) {
availableAbilities.push(ability);
}
});
}
});
}
return availableAbilities;
}
export function deriveReplacementWeaponAbilities(modifiers, enableModifierDataOrigin) {
@@ -13,7 +13,7 @@ import { keyBy, orderBy } from 'lodash';
import { TypeScriptUtils } from '../../utils';
import { CharacterDerivers } from '../Character';
import { ContainerTypeEnum } from '../Container';
import { StealthCheckTypeEnum } from '../Core';
import { STAT_REPLACEMENT_TYPE_LOOKUP, StealthCheckTypeEnum } from '../Core';
import { DataOriginDataInfoKeyEnum, DataOriginTypeEnum } from '../DataOrigin';
import { DefinitionHacks } from '../Definition';
import { DiceAccessors, DiceDerivers, DiceUtils } from '../Dice';
@@ -67,7 +67,7 @@ export function generateCustomItem(customItem, ruleData, characterId) {
limitedUse: null,
quantity: quantity !== null && quantity !== void 0 ? quantity : 1,
};
return Object.assign(Object.assign({}, simulatedContract), { avatarUrl: (_a = definition.avatarUrl) !== null && _a !== void 0 ? _a : '', armorClass: null, baseItemType: ItemBaseTypeEnum.GEAR, additionalDamages: [], versatileDamage: null, reach: null, canAttune: false, canBeDedicatedWeapon: false, canEquip: false, canHexWeapon: false, canOffhand: false, canPactWeapon: false, categoryInfo: null, definitionKey: '', hexWeaponEnabled: false, isDedicatedWeapon: false, isHexWeapon: false, isPactWeapon: false, metaItems: [], pactWeaponEnabled: false, toHit: null, damage: null, infusion: null, infusionActions: [], isOffhand: false, isAdamantine: false, isMagic: false, isSilvered: false, damageType: definition.damageType, displayAsAttack: false, isCustom: true, isCustomized: false, isDisplayAsAttack: false, proficiency: false, modifiers: [], originalContract: customItem, spells: [], type: null, name: (_b = definition.name) !== null && _b !== void 0 ? _b : 'Unidentified Item', cost: deriveCost(simulatedContract, {}), weight: deriveWeight(simulatedContract, {}), capacityWeight: deriveCapacityWeight(simulatedContract, {}), notes, properties: [], stealthCheck: StealthCheckTypeEnum.NONE, masteryName: null, primarySourceCategoryId: -1, secondarySourceCategoryIds: [] });
return Object.assign(Object.assign({}, simulatedContract), { avatarUrl: (_a = definition.avatarUrl) !== null && _a !== void 0 ? _a : '', armorClass: null, baseItemType: ItemBaseTypeEnum.GEAR, additionalDamages: [], versatileDamage: null, reach: null, canAttune: false, canBeDedicatedWeapon: false, canEquip: false, canHexWeapon: false, canOffhand: false, canPactWeapon: false, categoryInfo: null, definitionKey: '', hexWeaponEnabled: false, isDedicatedWeapon: false, isHexWeapon: false, isPactWeapon: false, metaItems: [], pactWeaponEnabled: false, toHit: null, damage: null, infusion: null, infusionActions: [], isOffhand: false, isAdamantine: false, isMagic: false, isSilvered: false, damageType: definition.damageType, displayAsAttack: false, isCustom: true, isCustomized: false, isDisplayAsAttack: false, proficiency: false, modifiers: [], originalContract: customItem, spells: [], type: null, name: (_b = definition.name) !== null && _b !== void 0 ? _b : 'Unidentified Item', cost: deriveCost(simulatedContract, {}), weight: deriveWeight(simulatedContract, {}), capacityWeight: deriveCapacityWeight(simulatedContract, {}), notes, properties: [], stealthCheck: StealthCheckTypeEnum.NONE, masteryName: null, primarySourceCategoryId: -1, secondarySourceCategoryIds: [], replacementWeaponStats: [], appliedWeaponReplacementStats: [] });
}
/**
*
@@ -97,8 +97,8 @@ export function generateWeaponBehaviorBaseItem(baseWeapon, parentItem, valueLook
* @param hack__characterSpecialWeaponPropertiesEnabled
*/
export function generateItems(items, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, ruleData, hack__characterSpecialWeaponPropertiesEnabled) {
const { hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled } = hack__characterSpecialWeaponPropertiesEnabled;
return items.map((item) => generateItem(item, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled));
const { hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled, replacementWeaponStats, } = hack__characterSpecialWeaponPropertiesEnabled;
return items.map((item) => generateItem(item, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled, replacementWeaponStats));
}
/**
*
@@ -116,7 +116,7 @@ export function generateItems(items, abilityLookup, proficiencyBonus, modifiers,
* @param ruleData
* @param dedicatedWeaponEnabled
*/
export function generateItem(item, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled) {
export function generateItem(item, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled, replacementWeaponStats) {
const mappingId = getMappingId(item);
const mappingIdString = ValueHacks.hack__toString(mappingId);
const mappingEntityTypeId = getMappingEntityTypeId(item);
@@ -139,6 +139,22 @@ export function generateItem(item, abilityLookup, proficiencyBonus, modifiers, e
!!ValueAccessors.getValue(dataLookup[AdjustmentTypeEnum.IS_PACT_WEAPON]);
}
const proficiency = deriveIsProficient(item, modifiers, isPactWeapon, typeValueLookup, ruleData);
//handle any replacement stats granted by modifiers from class features
const appliedWeaponReplacementStats = [];
let canUseWeaponReplacementStats = false;
if (replacementWeaponStats.length > 0 &&
(isBaseWeapon(item) || validateIsWeaponLike(item)) &&
!isAmmunition(item)) {
canUseWeaponReplacementStats = true;
// check if any of the replacement stats are being used
Object.keys(STAT_REPLACEMENT_TYPE_LOOKUP).forEach((adjustmentType) => {
const isUsingAdjustmentType = dataLookup.hasOwnProperty(adjustmentType) && !!ValueAccessors.getValue(dataLookup[adjustmentType]);
// if the adjustment type is being used, add it to the applied weapon replacement stats
if (isUsingAdjustmentType) {
appliedWeaponReplacementStats.push(STAT_REPLACEMENT_TYPE_LOOKUP[adjustmentType]);
}
});
}
let canHexWeapon = false;
let isHexWeapon = false;
if (hexWeaponEnabled && (isBaseWeapon(item) || validateIsWeaponLike(item)) && !isAmmunition(item)) {
@@ -185,7 +201,7 @@ export function generateItem(item, abilityLookup, proficiencyBonus, modifiers, e
const bonusToHitModifiers = modifiers.filter((modifier) => ModifierValidators.isValidBonusWeaponToHitModifier(modifier, item, ruleData));
const bonusToHitModifierTotal = ModifierDerivers.sumModifiers(bonusToHitModifiers, abilityLookup);
//get all the available ability stats for the weapon
const availableAbilities = deriveAvailableWeaponAbilities(item, modifiers, martialArtsLevelScale, isDedicatedWeapon, isPactWeapon, isHexWeapon);
const availableAbilities = deriveAvailableWeaponAbilities(item, modifiers, martialArtsLevelScale, isDedicatedWeapon, isPactWeapon, isHexWeapon, appliedWeaponReplacementStats);
// transform the available ability stats to have toHit and damage bonuses
const abilityPossibilities = CharacterDerivers.deriveAttackAbilityPossibilities(availableAbilities, modifiers, weaponProficiencyBonus, abilityLookup);
const bestAbility = HelperUtils.getLast(abilityPossibilities, ['toHit', 'modifier']);
@@ -267,7 +283,7 @@ export function generateItem(item, abilityLookup, proficiencyBonus, modifiers, e
hexWeaponEnabled,
pactWeaponEnabled, damage: newDamage, versatileDamage,
additionalDamages,
reach, masteryName: deriveMasteryName(item, modifiers), primarySourceCategoryId: derivePrimarySourceCategoryId(item, ruleData), secondarySourceCategoryIds: deriveSecondarySourceCategoryIds(item, ruleData) });
reach, masteryName: deriveMasteryName(item, modifiers), primarySourceCategoryId: derivePrimarySourceCategoryId(item, ruleData), secondarySourceCategoryIds: deriveSecondarySourceCategoryIds(item, ruleData), replacementWeaponStats: canUseWeaponReplacementStats ? replacementWeaponStats : [], appliedWeaponReplacementStats: canUseWeaponReplacementStats ? appliedWeaponReplacementStats : [] });
}
/**
*
@@ -341,7 +357,7 @@ function updateBaseItemSpells(item, spell) {
* @param characterId
*/
export function generateGearWeaponItems(items, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, ruleData, hack__characterSpecialWeaponPropertiesEnabled, characterId) {
const { hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled } = hack__characterSpecialWeaponPropertiesEnabled;
const { hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, dedicatedWeaponEnabled, replacementWeaponStats, } = hack__characterSpecialWeaponPropertiesEnabled;
return items
.filter(isGearContract)
.filter((item) => hasItemWeaponBehaviors(item))
@@ -352,7 +368,7 @@ export function generateGearWeaponItems(items, abilityLookup, proficiencyBonus,
if (simulatedBaseItem === null) {
return null;
}
return generateItem(simulatedBaseItem, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled);
return generateItem(simulatedBaseItem, abilityLookup, proficiencyBonus, modifiers, entityValueLookup, typeValueLookup, valueLookup, martialArtsLevelScale, hexWeaponEnabled, pactWeaponEnabled, improvedPactWeaponEnabled, ruleData, dedicatedWeaponEnabled, replacementWeaponStats);
})
.filter(TypeScriptUtils.isNotNullOrUndefined))
.reduce((acc, itemBehaviors) => {
@@ -20,5 +20,5 @@ export function simulateItem(itemDefinition, globalModifiers, valueLookupByType,
const reach = deriveWeaponReach(simulatedItem, globalModifiers, ruleData);
const proficiency = deriveIsProficient(simulatedItem, globalModifiers, false, valueLookupByType, ruleData);
return Object.assign(Object.assign({}, simulatedItem), { armorClass: deriveArmorClass(simulatedItem), proficiency, quantity: getBundleSize(simulatedItem), canBeDedicatedWeapon: false, canHexWeapon: false, canOffhand: false, canPactWeapon: false, hexWeaponEnabled: false, isDedicatedWeapon: false, isHexWeapon: false, isPactWeapon: false, masteryName: null, metaItems: [], pactWeaponEnabled: false, toHit: 0, damage: getDefinitionDamage(simulatedItem), categoryInfo: deriveCategoryInfo(simulatedItem, ruleData), stealthCheck: StealthCheckTypeEnum.NONE, additionalDamages,
reach, versatileDamage: null, primarySourceCategoryId: derivePrimarySourceCategoryId(simulatedItem, ruleData), secondarySourceCategoryIds: deriveSecondarySourceCategoryIds(simulatedItem, ruleData) });
reach, versatileDamage: null, primarySourceCategoryId: derivePrimarySourceCategoryId(simulatedItem, ruleData), secondarySourceCategoryIds: deriveSecondarySourceCategoryIds(simulatedItem, ruleData), appliedWeaponReplacementStats: [], replacementWeaponStats: [] });
}
@@ -220,6 +220,13 @@ export var ModifierSubTypeEnum;
// Warlock Feature
ModifierSubTypeEnum["ENABLE_PACT_WEAPON"] = "enable-pact-weapon";
ModifierSubTypeEnum["ENABLE_HEX_WEAPON"] = "enable-hex-weapon";
// Enable Feature (used in tandem with REPLACE_WEAPON_ABILITY modifier)
ModifierSubTypeEnum["ENABLE_STRENGTH"] = "enable-strength";
ModifierSubTypeEnum["ENABLE_DEXTERITY"] = "enable-dexterity";
ModifierSubTypeEnum["ENABLE_CONSTITUTION"] = "enable-constitution";
ModifierSubTypeEnum["ENABLE_INTELLIGENCE"] = "enable-intelligence";
ModifierSubTypeEnum["ENABLE_WISDOM"] = "enable-wisdom";
ModifierSubTypeEnum["ENABLE_CHARISMA"] = "enable-charisma";
})(ModifierSubTypeEnum || (ModifierSubTypeEnum = {}));
export const SIZE_LIST = [
ModifierSubTypeEnum.GARGANTUAN,
@@ -269,10 +276,7 @@ export const HEAVY_ARMOR_LIST = [
ModifierSubTypeEnum.POWERED_ARMOR,
ModifierSubTypeEnum.DIVERS_ARMOR,
];
export const SHIELDS_LIST = [
ModifierSubTypeEnum.SHIELD,
ModifierSubTypeEnum.POT_LID,
];
export const SHIELDS_LIST = [ModifierSubTypeEnum.SHIELD, ModifierSubTypeEnum.POT_LID];
export const ALL_ARMOR_LIST = [
...LIGHT_ARMOR_LIST,
...MEDIUM_ARMOR_LIST,
@@ -306,6 +306,23 @@ export function isEnableHexWeaponModifier(modifier) {
return (getType(modifier) === ModifierTypeEnum.ENABLE_FEATURE &&
getSubType(modifier) === ModifierSubTypeEnum.ENABLE_HEX_WEAPON);
}
export function isEnablesAbilityStatModifier(modifier) {
if (getType(modifier) !== ModifierTypeEnum.ENABLE_FEATURE) {
return false;
}
const subType = getSubType(modifier);
switch (subType) {
case ModifierSubTypeEnum.ENABLE_STRENGTH:
case ModifierSubTypeEnum.ENABLE_DEXTERITY:
case ModifierSubTypeEnum.ENABLE_CONSTITUTION:
case ModifierSubTypeEnum.ENABLE_INTELLIGENCE:
case ModifierSubTypeEnum.ENABLE_WISDOM:
case ModifierSubTypeEnum.ENABLE_CHARISMA:
return true;
default:
return false;
}
}
/**
*
* @param modifier
@@ -50,6 +50,12 @@ export var AdjustmentTypeEnum;
AdjustmentTypeEnum[AdjustmentTypeEnum["IS_DEDICATED_WEAPON"] = 48] = "IS_DEDICATED_WEAPON";
AdjustmentTypeEnum[AdjustmentTypeEnum["CAPACITY_OVERRIDE"] = 49] = "CAPACITY_OVERRIDE";
AdjustmentTypeEnum[AdjustmentTypeEnum["CAPACITY_WEIGHT_OVERRIDE"] = 50] = "CAPACITY_WEIGHT_OVERRIDE";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_STRENGTH"] = 51] = "USE_STRENGTH";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_DEXTERITY"] = 52] = "USE_DEXTERITY";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_CONSTITUTION"] = 53] = "USE_CONSTITUTION";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_INTELLIGENCE"] = 54] = "USE_INTELLIGENCE";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_WISDOM"] = 55] = "USE_WISDOM";
AdjustmentTypeEnum[AdjustmentTypeEnum["USE_CHARISMA"] = 56] = "USE_CHARISMA";
})(AdjustmentTypeEnum || (AdjustmentTypeEnum = {}));
export const ProficiencyAdjustmentTypeEnum = [
AdjustmentTypeEnum.IS_PROFICIENT,
@@ -88,6 +88,8 @@ export class ItemManager extends PartyManager {
this.isPactWeapon = () => ItemAccessors.isPactWeapon(this.item);
this.isDedicatedWeapon = () => ItemAccessors.isDedicatedWeapon(this.item);
this.isOffhand = () => ItemAccessors.isOffhand(this.item);
this.getReplacementWeaponStats = () => ItemAccessors.getReplacementWeaponStats(this.item);
this.getAppliedWeaponReplacementStats = () => ItemAccessors.getAppliedWeaponReplacementStats(this.item);
this.getBaseArmorName = () => ItemAccessors.getBaseArmorName(this.item);
this.getSubType = () => ItemAccessors.getSubType(this.item);
this.getQuantity = () => ItemAccessors.getQuantity(this.item);
@@ -167,6 +169,8 @@ export class ItemManager extends PartyManager {
return ItemNotes.getNoteComponents(this.item, weaponSpellDamageGroups, ruleData, abilityLookup, proficiencyBonus);
};
this.getMetaText = () => {
const appliedWeaponReplacementStats = this.getAppliedWeaponReplacementStats();
const ruleData = rulesEngineSelectors.getRuleData(this.state);
let metaItems = [];
if (this.isLegacy()) {
metaItems.push('Legacy');
@@ -184,6 +188,11 @@ export class ItemManager extends PartyManager {
if (this.isDedicatedWeapon()) {
metaItems.push('Dedicated Weapon');
}
if (appliedWeaponReplacementStats.length > 0) {
appliedWeaponReplacementStats.forEach((statId) => {
metaItems.push(`Using ${RuleDataUtils.getStatNameById(statId, ruleData, true)}`);
});
}
if (this.isOffhand()) {
metaItems.push('Dual Wield');
}
@@ -695,10 +695,20 @@ export const getPactWeaponEnabled = createSelector([getClasses], ClassGenerators
* @returns {boolean}
*/
export const getImprovedPactWeaponEnabled = createSelector([getClasses], ClassGenerators.generateImprovedPactWeaponEnabled);
/**
* @returns {boolean}
*/
export const getReplacementWeaponAbilityStats = createSelector([getClasses], ClassGenerators.generateReplacementWeaponAbilityStats);
/**
* TODO: add return here
*/
export const hack__getSpecialWeaponPropertiesEnabled = createSelector([getHexWeaponEnabled, getPactWeaponEnabled, getImprovedPactWeaponEnabled, getDedicatedWeaponEnabled], CharacterHacks.hack__generateSpecialWeaponPropertiesEnabled);
export const hack__getSpecialWeaponPropertiesEnabled = createSelector([
getHexWeaponEnabled,
getPactWeaponEnabled,
getImprovedPactWeaponEnabled,
getDedicatedWeaponEnabled,
getReplacementWeaponAbilityStats,
], CharacterHacks.hack__generateSpecialWeaponPropertiesEnabled);
/**
* TODO v5.1: should be able to remove this selector and all usages after mobile can support customItems as Items
* @returns {Array<Item>}