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
@@ -20,6 +20,7 @@ import {
DefinitionPool,
DefinitionUtils,
EntitledEntity,
EntityRestrictionData,
FeatDefinitionContract,
FeatLookup,
InfusionChoice,
@@ -156,6 +157,7 @@ interface Props {
optionalClassFeatureLookup: OptionalClassFeatureLookup;
theme: CharacterTheme;
inventoryManager: InventoryManager;
entityRestrictionData: EntityRestrictionData;
}
interface State {
showClassFeatures: boolean;
@@ -407,6 +409,7 @@ export default class ClassManager extends React.PureComponent<Props, State> {
optionalClassFeatureLookup,
theme,
activeSourceCategories,
entityRestrictionData,
} = this.props;
return (
@@ -441,6 +444,7 @@ export default class ClassManager extends React.PureComponent<Props, State> {
onChangeReplacementPromise={onChangeReplacementPromise}
onRemoveSelectionPromise={onRemoveSelectionPromise}
ruleData={ruleData}
entityRestrictionData={entityRestrictionData}
/>
),
id: "optional-features",
@@ -49,6 +49,7 @@ import {
InventoryLookup,
ItemUtils,
InventoryManager,
EntityRestrictionData,
} from "@dndbeyond/character-rules-engine/es";
import { HpSummary } from "~/subApps/builder/components/HpSummary";
@@ -125,6 +126,7 @@ interface Props extends DispatchProp {
characterId: number;
activeSourceCategories: Array<number>;
createModal: (modalData: ModalData) => void;
entityRestrictionData: EntityRestrictionData;
}
class ClassesManage extends React.PureComponent<Props> {
@@ -931,6 +933,7 @@ class ClassesManage extends React.PureComponent<Props> {
theme,
activeSourceCategories,
inventoryManager,
entityRestrictionData,
} = this.props;
const levelsRemaining: number = Math.max(
@@ -1010,6 +1013,7 @@ class ClassesManage extends React.PureComponent<Props> {
classSpellListSpellsLookup={classSpellListSpellsLookup}
activeSourceCategories={activeSourceCategories}
inventoryManager={inventoryManager}
entityRestrictionData={entityRestrictionData}
/>
))}
{levelsRemaining !== 0 && (
@@ -1086,6 +1090,8 @@ export default ConnectedBuilderPage(
characterId: rulesEngineSelectors.getId(state),
activeSourceCategories:
rulesEngineSelectors.getActiveSourceCategories(state),
entityRestrictionData:
rulesEngineSelectors.getEntityRestrictionData(state),
};
}
);
@@ -1,10 +1,7 @@
import axios, { Canceler } from "axios";
import React from "react";
import {
MarketplaceCta,
LoadingPlaceholder,
} from "@dndbeyond/character-components/es";
import { LoadingPlaceholder } from "@dndbeyond/character-components/es";
import {
ApiAdapterUtils,
CharClass,
@@ -20,6 +17,7 @@ import {
ClassUtils,
HelperUtils,
RuleData,
EntityRestrictionData,
} from "@dndbeyond/character-rules-engine/es";
import { Link } from "~/components/Link";
@@ -58,6 +56,7 @@ interface OptionalFeatureManagerProps {
reject: () => void
) => void;
ruleData: RuleData;
entityRestrictionData: EntityRestrictionData;
}
interface OptionalFeatureManagerState {
loadingStatus: DataLoadingStatusEnum;
@@ -180,6 +179,7 @@ export class OptionalFeatureManager extends React.PureComponent<
onChangeReplacementPromise,
onRemoveSelectionPromise,
onSelection,
entityRestrictionData,
} = this.props;
let contentNode: React.ReactNode;
@@ -234,13 +234,41 @@ export class OptionalFeatureManager extends React.PureComponent<
const consolidatedOptionalOrigins = [
...availableOptionalFeatures,
...unEntitledOptionalClassFeatures,
].filter(
(feature) =>
!ClassFeatureUtils.getHideInContext(
feature,
Constants.AppContextTypeEnum.BUILDER
)
);
]
.filter(
(feature) =>
!ClassFeatureUtils.getHideInContext(
feature,
Constants.AppContextTypeEnum.BUILDER
)
)
.filter((feature) => {
//check if the feature is already selectec
const optionalFeatureMapping = HelperUtils.lookupDataOrFallback(
optionalClassFeatureLookup,
ClassFeatureUtils.getDefinitionKey(feature)
);
//always return the feature if it is already selected
if (optionalFeatureMapping) {
return true;
}
const sourceIds = ClassFeatureUtils.getSources(feature).map(
(source) => source.sourceId
);
// if there are no sources, we assume it is homebrew
if (sourceIds.length === 0) {
//return true if the user has homebrew content enabled
return entityRestrictionData.preferences.useHomebrewContent;
}
// filter out features that do not have any sources from the active sources lookup
return sourceIds.some((sourceId) =>
entityRestrictionData.activeSourceLookup.hasOwnProperty(sourceId)
);
});
if (!consolidatedOptionalOrigins.length) {
contentNode = this.renderOptionalFeatureCta();
@@ -294,7 +322,7 @@ export class OptionalFeatureManager extends React.PureComponent<
affectedFeatureDefinitionKey={
affectedFeatureDefinitionKey
}
isSelected={!!optionalFeatureMapping ?? false}
isSelected={!!optionalFeatureMapping}
onSelection={onSelection}
onChangeReplacementPromise={onChangeReplacementPromise}
onRemoveSelectionPromise={onRemoveSelectionPromise}
@@ -338,7 +366,7 @@ export class OptionalFeatureManager extends React.PureComponent<
affectedFeatureDefinitionKey={
affectedFeatureDefinitionKey
}
isSelected={!!optionalFeatureMapping ?? false}
isSelected={!!optionalFeatureMapping}
onSelection={onSelection}
onChangeReplacementPromise={onChangeReplacementPromise}
onRemoveSelectionPromise={onRemoveSelectionPromise}