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,186 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import { orderBy } from 'lodash';
|
||||
import { characterActions } from "../actions";
|
||||
import { ApiAdapterUtils } from "../apiAdapter";
|
||||
import { CharacterUtils } from "../engine/Character";
|
||||
import { FeatAccessors, FeatSimulators } from "../engine/Feat";
|
||||
import { HelperUtils } from "../engine/Helper";
|
||||
import { featDefinitionMap, getFeatManager } from "./FeatManager";
|
||||
import { apiCreatorSelectors, rulesEngineSelectors } from "../selectors";
|
||||
import { FeaturesManager } from './FeaturesManager';
|
||||
export class CharacterFeaturesManager extends FeaturesManager {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
//TODO GFS THIS!!!!
|
||||
this.getBlessings = () => __awaiter(this, void 0, void 0, function* () {
|
||||
// TODO get the blessings only?
|
||||
/**
|
||||
* this could be on the character obj under blessings key
|
||||
*/
|
||||
const blessingManagers = yield this.getCharacterFeatures();
|
||||
this.blessingManagers = blessingManagers;
|
||||
return blessingManagers;
|
||||
});
|
||||
this.getBlessing = (id) => { var _a; return (_a = this.blessingManagers.find((blessing) => id === blessing.getId())) !== null && _a !== void 0 ? _a : null; };
|
||||
// TODO is there value in moving these to hasFeatures and hasBlessings
|
||||
this.hasBlessings = () => __awaiter(this, void 0, void 0, function* () {
|
||||
const blessings = yield this.getBlessings();
|
||||
return blessings.length > 0;
|
||||
});
|
||||
this.hasBlessing = (blessing) => !!this.blessingManagers.find((characterBlessing) => characterBlessing.getId() === blessing.getId());
|
||||
this.handlePreferenceChange = (preferenceKey, value) => {
|
||||
const typedPrefKey = CharacterUtils.getPreferenceKey(preferenceKey);
|
||||
if (typedPrefKey !== null) {
|
||||
this.dispatch(characterActions.preferenceChoose(typedPrefKey, value));
|
||||
}
|
||||
};
|
||||
this.params = params;
|
||||
this.blessingManagers = [];
|
||||
}
|
||||
mapFeatsToManagers(feats) {
|
||||
return feats.map((feat) => getFeatManager(Object.assign(Object.assign({}, this.params), { feat })));
|
||||
}
|
||||
/**
|
||||
* Gets feat managers for all of the feats on the character.
|
||||
*/
|
||||
getFeats() {
|
||||
const feats = rulesEngineSelectors.getFeats(this.state);
|
||||
return this.mapFeatsToManagers(feats);
|
||||
}
|
||||
/**
|
||||
* Gets feat managers for all feats except those tagged as being data origin only.
|
||||
*/
|
||||
getStandardFeats() {
|
||||
const feats = rulesEngineSelectors.getStandardFeats(this.state);
|
||||
return this.mapFeatsToManagers(feats);
|
||||
}
|
||||
/**
|
||||
* Gets feat managers for feats with the designated primary data origin,
|
||||
* but only for feats that are tagged as being data origin only.
|
||||
* Useful for secret feats that come from Class Features or Racial Traits
|
||||
*/
|
||||
getDataOriginOnlyFeatsByPrimary(primaryType, primaryId) {
|
||||
var _a;
|
||||
const lookup = rulesEngineSelectors.getDataOriginOnlyFeatLookup(this.state);
|
||||
const feats = (_a = lookup.byPrimary[primaryType][primaryId]) !== null && _a !== void 0 ? _a : [];
|
||||
return this.mapFeatsToManagers(feats);
|
||||
}
|
||||
/**
|
||||
* Gets feat managers for feats with the designated parent data origin,
|
||||
* but only for feats that are tagged as being data origin only.
|
||||
* Useful for secret feats that come from Backgrounds via Feat Lists
|
||||
*/
|
||||
getDataOriginOnlyFeatsByParent(parentType, parentId) {
|
||||
var _a;
|
||||
const lookup = rulesEngineSelectors.getDataOriginOnlyFeatLookup(this.state);
|
||||
const feats = (_a = lookup.byParent[parentType][parentId]) !== null && _a !== void 0 ? _a : [];
|
||||
return this.mapFeatsToManagers(feats);
|
||||
}
|
||||
getFeatLookup() {
|
||||
return HelperUtils.generateNonNullLookup(this.getFeats(), (feat) => feat.getId());
|
||||
}
|
||||
getFeatById(id) {
|
||||
return HelperUtils.lookupDataOrFallback(this.getFeatLookup(), id);
|
||||
}
|
||||
updateFeatShoppe(currentShoppe) {
|
||||
const feats = currentShoppe.map((manager) => {
|
||||
const currentManager = this.getFeatById(manager.getId());
|
||||
if (currentManager) {
|
||||
return currentManager;
|
||||
}
|
||||
else {
|
||||
const featDefinitionContract = featDefinitionMap.get(manager.getId());
|
||||
if (featDefinitionContract) {
|
||||
const simFeat = FeatSimulators.simulateFeat(featDefinitionContract);
|
||||
return getFeatManager(Object.assign(Object.assign({}, this.params), { feat: simFeat }));
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
});
|
||||
return feats;
|
||||
}
|
||||
transformLoadedFeats(data) {
|
||||
const feats = data.map((definition) => {
|
||||
featDefinitionMap.set(definition.id, definition);
|
||||
const simFeat = FeatSimulators.simulateFeat(definition);
|
||||
const featManager = this.getFeatById(FeatAccessors.getId(simFeat));
|
||||
return featManager ? featManager : getFeatManager(Object.assign(Object.assign({}, this.params), { feat: simFeat }));
|
||||
});
|
||||
return orderBy(feats, (feat) => feat.getName());
|
||||
}
|
||||
getFeatShoppe(additionalConfig) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const loadFeats = apiCreatorSelectors.makeLoadAvailableFeats(this.state);
|
||||
const response = yield loadFeats(additionalConfig);
|
||||
let data = ApiAdapterUtils.getResponseData(response);
|
||||
if (data) {
|
||||
return this.transformLoadedFeats(data);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
}
|
||||
getBlessingShoppe(additionalConfig) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const blessings = yield this.getFeaturesShoppe({
|
||||
params: {
|
||||
category: 'blessing',
|
||||
},
|
||||
});
|
||||
return orderBy(blessings, (blessing) => blessing.getName());
|
||||
});
|
||||
}
|
||||
//UTILS
|
||||
// filter to only allow one of each simulated repeatable feat group
|
||||
filterUniqueSimulatedRepeatableFeats(feats, parentFeats) {
|
||||
const tracker = new Set();
|
||||
return feats.filter((feat) => {
|
||||
if (!feat.isSimulatedRepeatableFeat()) {
|
||||
return true;
|
||||
}
|
||||
const repeatableGroupId = feat.getRepeatableGroupId();
|
||||
if (repeatableGroupId !== null) {
|
||||
// find the parent of repeatable feat group
|
||||
const parentFeat = parentFeats.find((f) => f.getId() === repeatableGroupId);
|
||||
// don't include repeatable feats if the parent is not added
|
||||
if (parentFeat === null || parentFeat === void 0 ? void 0 : parentFeat.isSimulatedRepeatableFeat()) {
|
||||
return parentFeat.getId() === feat.getId();
|
||||
}
|
||||
if (tracker.has(repeatableGroupId)) {
|
||||
return false;
|
||||
}
|
||||
tracker.add(repeatableGroupId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
//get an array of feats that are available to be added to the character
|
||||
getAvailableFeats(feats) {
|
||||
const available = feats.filter((feat) => feat.canAdd());
|
||||
const allRepeatableParentFeats = feats.filter((feat) => feat.isRepeatableFeatParent());
|
||||
return this.filterUniqueSimulatedRepeatableFeats(available, allRepeatableParentFeats);
|
||||
}
|
||||
//get an array of feats that are not available to be added to the character due to prerequisites not being met
|
||||
getUnavailableFeats(feats) {
|
||||
const getUnavailableFeats = feats.filter((feat) => !feat.canAdd());
|
||||
const allRepeatableParentFeats = feats.filter((feat) => feat.isRepeatableFeatParent());
|
||||
return this.filterUniqueSimulatedRepeatableFeats(getUnavailableFeats, allRepeatableParentFeats);
|
||||
}
|
||||
// PREFERENCES
|
||||
getEnforceFeatRules() {
|
||||
const preferences = rulesEngineSelectors.getCharacterPreferences(this.state);
|
||||
return preferences.enforceFeatRules;
|
||||
}
|
||||
setEnforceFeatRules(value) {
|
||||
const preferenceKey = 'enforceFeatRules';
|
||||
this.handlePreferenceChange(preferenceKey, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user