New source found from dndbeyond.com
This commit is contained in:
@@ -4,7 +4,7 @@ import { AbilityScoreStatTypeEnum } from "../engine/Core";
|
||||
import { HelperUtils } from "../engine/Helper";
|
||||
import { RuleDataAccessors } from "../engine/RuleData";
|
||||
import { rulesEngineSelectors } from "../selectors";
|
||||
import { FeaturesManager } from './FeaturesManager';
|
||||
import { BaseManager } from './BaseManager';
|
||||
export const abilityDefinitionMap = new Map();
|
||||
const abilityMangerMap = new Map();
|
||||
export const getAbilityManager = (params) => {
|
||||
@@ -23,7 +23,7 @@ export const getAbilityManager = (params) => {
|
||||
abilityMangerMap.set(abilityId, newAbilityManager);
|
||||
return newAbilityManager;
|
||||
};
|
||||
export class AbilityManager extends FeaturesManager {
|
||||
export class AbilityManager extends BaseManager {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
//Accessors
|
||||
@@ -87,7 +87,6 @@ export class AbilityManager extends FeaturesManager {
|
||||
getCompendiumText() {
|
||||
const abilityRuleData = this.getAbilityRuleData();
|
||||
// TODO: we should accessor all the things?
|
||||
// maybe gfs will be the time to do it?
|
||||
return abilityRuleData.compendiumText;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
import { orderBy } from 'lodash';
|
||||
import { AbilityAccessors } from "../engine/Ability";
|
||||
import { FeatureFlagEnum } from "../engine/FeatureFlagInfo";
|
||||
import { characterSelectors, featureFlagInfoSelectors, rulesEngineSelectors } from "../selectors";
|
||||
import { rulesEngineSelectors } from "../selectors";
|
||||
import { getAbilityManager } from './AbilityManager';
|
||||
import { FeatureFlagManager } from './FeatureFlagManager';
|
||||
// import { BlessingManager, getBlessingManager } from './FeatureManager';
|
||||
import { FeaturesManager } from './FeaturesManager';
|
||||
import { transformAbilityScores } from './utils/modifierTransformers';
|
||||
export class AttributesManager extends FeaturesManager {
|
||||
import { BaseManager } from './BaseManager';
|
||||
export class AttributesManager extends BaseManager {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.getHighestAbilityScore = (abilities) => {
|
||||
@@ -28,31 +23,9 @@ export class AttributesManager extends FeaturesManager {
|
||||
getAbilities() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const abilities = rulesEngineSelectors.getAbilities(this.state);
|
||||
const featureFlagsManager = new FeatureFlagManager(featureFlagInfoSelectors.getFeatureFlagInfo(this.state));
|
||||
const hasAccessToBlessing = featureFlagsManager.getFlag(FeatureFlagEnum.RELEASE_GATE_GFS_BLESSINGS_UI);
|
||||
if (!hasAccessToBlessing) {
|
||||
return abilities.map((ability) => {
|
||||
return getAbilityManager(Object.assign(Object.assign({}, this.params), { ability }));
|
||||
});
|
||||
}
|
||||
else {
|
||||
// TODO: GFS this is all the wrong place
|
||||
// it should just be
|
||||
// const abilities = getCharacter.abilities ...
|
||||
const validGlobalModifiers = this.getValidGlobalModifiers();
|
||||
const baseStats = characterSelectors.getStats(this.state);
|
||||
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
||||
const { generatedFeature } = transformAbilityScores(validGlobalModifiers, baseStats, ruleData);
|
||||
// TODO: GFS THERE IS SOME MORE TO DO HERE
|
||||
const characterFeatureManagers = yield this.getCharacterFeatures();
|
||||
// TODO: GFS this should be part of the process and I should just ask for the the object here.
|
||||
const myAbilityState = this.processCharacter(generatedFeature);
|
||||
return abilities.map((ability) => {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
const name = (_b = (_a = AbilityAccessors.getLabel(ability)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'The ability with no name';
|
||||
return getAbilityManager(Object.assign(Object.assign({}, this.params), { ability: Object.assign(Object.assign({}, ability), { maxStatScore: (_c = myAbilityState.attributes[name].max) !== null && _c !== void 0 ? _c : null, modifier: (_d = myAbilityState.attributes[name].modifier) !== null && _d !== void 0 ? _d : null, score: (_e = myAbilityState.attributes[name].value) !== null && _e !== void 0 ? _e : null, totalScore: (_f = myAbilityState.attributes[name].value) !== null && _f !== void 0 ? _f : null }) }));
|
||||
});
|
||||
}
|
||||
return abilities.map((ability) => {
|
||||
return getAbilityManager(Object.assign(Object.assign({}, this.params), { ability }));
|
||||
});
|
||||
});
|
||||
}
|
||||
getAbilitiesWithoutBlessings() {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { HelperUtils } from "../engine/Helper";
|
||||
import { getCurrentRulesEngineConfig } from '../config/utils';
|
||||
export const subscriptionsMap = new Map();
|
||||
export class BaseManager {
|
||||
constructor(params = {}) {
|
||||
this.randomId = 0; // helpful for debugging
|
||||
@@ -50,3 +52,26 @@ export class BaseManager {
|
||||
};
|
||||
}
|
||||
}
|
||||
// manage subscriptions
|
||||
BaseManager.subscribeToUpdates = ({ onUpdate, shouldInit = true }) => {
|
||||
// TODO: maybe from lib.
|
||||
const mapKey = HelperUtils.generateGuid();
|
||||
// connect to redux for updates
|
||||
let unsubscribe;
|
||||
if (getCurrentRulesEngineConfig().store) {
|
||||
const store = getCurrentRulesEngineConfig().store;
|
||||
unsubscribe = store === null || store === void 0 ? void 0 : store.subscribe(() => {
|
||||
onUpdate();
|
||||
});
|
||||
}
|
||||
subscriptionsMap.set(mapKey, onUpdate);
|
||||
if (shouldInit) {
|
||||
onUpdate();
|
||||
}
|
||||
return () => {
|
||||
subscriptionsMap.delete(mapKey);
|
||||
if (unsubscribe) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,27 +15,10 @@ 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 {
|
||||
import { BaseManager } from './BaseManager';
|
||||
export class CharacterFeaturesManager extends BaseManager {
|
||||
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) {
|
||||
@@ -43,7 +26,6 @@ export class CharacterFeaturesManager extends FeaturesManager {
|
||||
}
|
||||
};
|
||||
this.params = params;
|
||||
this.blessingManagers = [];
|
||||
}
|
||||
mapFeatsToManagers(feats) {
|
||||
return feats.map((feat) => getFeatManager(Object.assign(Object.assign({}, this.params), { feat })));
|
||||
@@ -127,16 +109,6 @@ export class CharacterFeaturesManager extends FeaturesManager {
|
||||
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) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { characterActions, serviceDataActions } from '../actions';
|
||||
import { ConfigUtils } from '../config';
|
||||
import { rulesEngineConfig } from '../config/utils';
|
||||
import { ContainerAccessors } from '../engine/Container';
|
||||
import { ContainerAccessors, ContainerValidators } from '../engine/Container';
|
||||
import { CoreUtils, CURRENCY_VALUE } from '../engine/Core';
|
||||
import { DefinitionHacks } from '../engine/Definition';
|
||||
import { FormatUtils } from '../engine/Format';
|
||||
@@ -22,6 +22,7 @@ export class CoinManager extends InventoryManager {
|
||||
if (!isEmpty && container) {
|
||||
const destinationEntityTypeId = ContainerAccessors.getContainerType(container);
|
||||
const destinationEntityId = ContainerAccessors.getMappingId(container);
|
||||
const isDestinationContainerShared = ContainerValidators.validateIsShared(DefinitionHacks.hack__generateDefinitionKey(destinationEntityTypeId, destinationEntityId), containerLookup);
|
||||
const currentCoins = this.getContainerCoin(containerDefinitionKey);
|
||||
if (multiplier === 1) {
|
||||
const validAddCoin = this.calculateAddCoinPayload(currentCoins, coin.cp || 0, coin.ep || 0, coin.gp || 0, coin.pp || 0, coin.sp || 0);
|
||||
@@ -39,6 +40,11 @@ export class CoinManager extends InventoryManager {
|
||||
}
|
||||
this.dispatch(characterActions.currencyTransactionSet(Object.assign(Object.assign({}, adjustedCurrency), { destinationEntityId: destinationEntityId, destinationEntityTypeId: destinationEntityTypeId }), () => {
|
||||
typeof onSuccess === 'function' && onSuccess();
|
||||
if (isDestinationContainerShared) {
|
||||
const data = {};
|
||||
const eventType = this.EVENT_TYPES.ITEM_SHARED_FULFILLED;
|
||||
this.sendMessage({ data, eventType });
|
||||
}
|
||||
}, () => {
|
||||
typeof onError === 'function' && onError();
|
||||
}));
|
||||
@@ -238,25 +244,6 @@ export class CoinManager extends InventoryManager {
|
||||
}
|
||||
};
|
||||
// Validators
|
||||
this.canAddCoin = (coin, containerDefinitionKey) => {
|
||||
const containerLookup = rulesEngineSelectors.getContainerLookup(this.state);
|
||||
const container = HelperUtils.lookupDataOrFallback(containerLookup, containerDefinitionKey);
|
||||
const isShared = container ? ContainerAccessors.isShared(container) : false;
|
||||
if (isShared && this.isSharingTurnedDeleteOnly()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.canRemoveCoin = (coin, containerDefinitionKey) => {
|
||||
const containerLookup = rulesEngineSelectors.getContainerLookup(this.state);
|
||||
const container = HelperUtils.lookupDataOrFallback(containerLookup, containerDefinitionKey);
|
||||
const isShared = container ? ContainerAccessors.isShared(container) : false;
|
||||
if (isShared && this.isSharingTurnedDeleteOnly()) {
|
||||
let hasNegatives = Object.values(coin).some((value) => value < 0);
|
||||
return !hasNegatives;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.canUseCointainers = () => {
|
||||
const rulesEngineConfig = ConfigUtils.getCurrentRulesEngineConfig();
|
||||
const preferences = rulesEngineSelectors.getPreferences(this.state);
|
||||
|
||||
@@ -144,6 +144,7 @@ export class ContainerManager extends MessageManager {
|
||||
this.getCoin = () => ContainerAccessors.getCoin(this.container);
|
||||
// Validators
|
||||
this.isCharacterContainer = () => ContainerValidators.isCharacterContainer(this.container);
|
||||
this.isPartyContainer = () => ContainerValidators.isPartyContainer(this.container);
|
||||
this.isSharedOtherContainerDefinitionKey = (otherContainerDefinitionKey) => {
|
||||
const containerLookup = rulesEngineSelectors.getContainerLookup(this.state);
|
||||
return ContainerValidators.validateIsShared(otherContainerDefinitionKey, containerLookup);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
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 { ApiRequests } from "../api";
|
||||
export class FeatureManager {
|
||||
constructor(params) {
|
||||
this.handleAcceptOnSuccess = (onSuccess) => {
|
||||
typeof onSuccess === 'function' && onSuccess();
|
||||
};
|
||||
this.handleRejectOnError = (onError) => {
|
||||
typeof onError === 'function' && onError();
|
||||
};
|
||||
this.handleAdd = (onSuccess, onError) => __awaiter(this, void 0, void 0, function* () {
|
||||
yield ApiRequests.postCharacterFeature({ featureId: this.getId() });
|
||||
this.bustCache();
|
||||
this.handleAcceptOnSuccess(onSuccess);
|
||||
this.runSubscriptions();
|
||||
});
|
||||
this.handleRemove = (onSuccess, onError) => __awaiter(this, void 0, void 0, function* () {
|
||||
// featureManagerMap.delete(this.getId()); //TODO GFS do we still need to do it this way
|
||||
yield ApiRequests.deleteCharacterFeature({ featureId: this.getId() });
|
||||
this.bustCache();
|
||||
this.handleAcceptOnSuccess(onSuccess);
|
||||
this.runSubscriptions();
|
||||
});
|
||||
//Accessors
|
||||
this.getId = () => this.feature.featureId;
|
||||
this.getStatements = () => this.feature.statements;
|
||||
this.getFeature = () => this.feature;
|
||||
// Label accessors
|
||||
// TODO what are the default/standard ones?
|
||||
//TODO GFS: talk about role.toLowerCase
|
||||
this.getName = () => { var _a, _b; return (_b = (_a = this.feature.labels.find((label) => label.role.toLowerCase() === 'name')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 'FEATURE WITH NO NAME'; }; //TODO GFS ENUMS for all of these
|
||||
this.getDescription = () => { var _a, _b; return (_b = (_a = this.feature.labels.find((label) => label.role.toLowerCase() === 'description')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''; };
|
||||
this.params = params;
|
||||
this.feature = params.feature;
|
||||
this.runSubscriptions = params.runSubscriptions;
|
||||
this.bustCache = params.bustCache;
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
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 { generateCharacterState } from '@dndbeyond/character-gfs';
|
||||
import { ApiRequests } from "../api";
|
||||
import { ApiAdapterUtils } from "../apiAdapter";
|
||||
import { getCurrentRulesEngineConfig } from "../config/utils";
|
||||
import { HelperUtils } from "../engine/Helper";
|
||||
import { apiCreatorSelectors, rulesEngineSelectors } from "../selectors";
|
||||
import { TypeScriptUtils } from "../utils";
|
||||
import { FeatureManager } from './FeatureManager';
|
||||
import { MessageManager } from './MessageManager';
|
||||
export const featureMap = new Map();
|
||||
export const subscriptionsMap = new Map();
|
||||
const featureManagerMap = new Map();
|
||||
export const getFeatureManager = (params) => {
|
||||
const { feature } = params;
|
||||
const featureId = feature.featureId; //TODO GFS Accessors?
|
||||
if (featureManagerMap.has(featureId)) {
|
||||
const FeatureManager = featureManagerMap.get(featureId);
|
||||
if (!FeatureManager) {
|
||||
throw new Error(`FeatureManager for feature ${featureId} is null`);
|
||||
}
|
||||
if (FeatureManager.params.feature === feature) {
|
||||
return FeatureManager;
|
||||
}
|
||||
}
|
||||
const newFeatureManager = new FeatureManager(params);
|
||||
featureManagerMap.set(featureId, newFeatureManager);
|
||||
return newFeatureManager;
|
||||
};
|
||||
// we want this cached across all instances of the FeaturesManager
|
||||
let rootCharacterFeatureManagers = null; // needs
|
||||
let allCharacterFeatureManagers = null; // needs
|
||||
let availableFeaturesResponseData = null; // not required to bust
|
||||
export class FeaturesManager extends MessageManager {
|
||||
constructor(params = {}) {
|
||||
super(params);
|
||||
// these values are used for caching and may need to be busted when the character changes
|
||||
this.randomId = 0; // helpful for debugging
|
||||
this.runSubscriptions = () => {
|
||||
subscriptionsMap.forEach((cb) => cb());
|
||||
};
|
||||
this.transformLoadedFeatures = (features) => {
|
||||
return features.map((feature) => {
|
||||
featureMap.set(feature.featureId, feature);
|
||||
return getFeatureManager({ feature, runSubscriptions: this.runSubscriptions, bustCache: this.bustCache });
|
||||
});
|
||||
};
|
||||
this.getAvailableFeatures = (additionalConfig) => __awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
if (availableFeaturesResponseData) {
|
||||
return availableFeaturesResponseData;
|
||||
}
|
||||
const loadFeatures = apiCreatorSelectors.makeLoadAvailableFeatures(this.state);
|
||||
const response = yield loadFeatures(additionalConfig);
|
||||
availableFeaturesResponseData = (_a = ApiAdapterUtils.getResponseData(response)) !== null && _a !== void 0 ? _a : [];
|
||||
availableFeaturesResponseData.map((feature) => {
|
||||
featureMap.set(feature.featureId, feature);
|
||||
});
|
||||
return availableFeaturesResponseData;
|
||||
});
|
||||
this.getFeaturesShoppe = (additionalConfig) => __awaiter(this, void 0, void 0, function* () {
|
||||
let data = yield this.getAvailableFeatures(additionalConfig);
|
||||
if (data) {
|
||||
return this.transformLoadedFeatures(data);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
this.getAllCharacterFeatures = (rootCharacterFeatureIds) => __awaiter(this, void 0, void 0, function* () {
|
||||
var _b;
|
||||
if (allCharacterFeatureManagers) {
|
||||
return allCharacterFeatureManagers;
|
||||
}
|
||||
const allFeaturesAndSubFeatureResponse = yield ApiRequests.postFeaturesAndSubfeatures({
|
||||
featureIds: rootCharacterFeatureIds,
|
||||
});
|
||||
const allFeaturesAndSubFeatureData = (_b = ApiAdapterUtils.getResponseData(allFeaturesAndSubFeatureResponse)) !== null && _b !== void 0 ? _b : [];
|
||||
allFeaturesAndSubFeatureData.map((feature) => {
|
||||
featureMap.set(feature.featureId, feature);
|
||||
});
|
||||
const allFeaturesAndSubFeatureIds = allFeaturesAndSubFeatureData.map((feature) => feature.featureId);
|
||||
allCharacterFeatureManagers = allFeaturesAndSubFeatureIds
|
||||
.map((id) => {
|
||||
const feature = featureMap.get(id);
|
||||
return feature
|
||||
? getFeatureManager({ feature, runSubscriptions: this.runSubscriptions, bustCache: this.bustCache })
|
||||
: null;
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
return allCharacterFeatureManagers || [];
|
||||
});
|
||||
this.bustCache = () => __awaiter(this, void 0, void 0, function* () {
|
||||
availableFeaturesResponseData = null;
|
||||
rootCharacterFeatureManagers = null;
|
||||
allCharacterFeatureManagers = null;
|
||||
});
|
||||
this.getCharacterFeatures = () => __awaiter(this, void 0, void 0, function* () {
|
||||
var _c;
|
||||
if (rootCharacterFeatureManagers) {
|
||||
return rootCharacterFeatureManagers;
|
||||
}
|
||||
const characterId = rulesEngineSelectors.getId(this.state);
|
||||
const characterFeatureResponse = yield ApiRequests.getCharacterFeatures({ characterId });
|
||||
const characterFeatureData = (_c = ApiAdapterUtils.getResponseData(characterFeatureResponse)) !== null && _c !== void 0 ? _c : [];
|
||||
const characterFeatureIds = characterFeatureData.map((feature) => feature.id);
|
||||
if (characterFeatureIds.length > 0) {
|
||||
yield this.getAvailableFeatures({
|
||||
params: {
|
||||
category: 'blessing',
|
||||
},
|
||||
});
|
||||
yield this.getAllCharacterFeatures(characterFeatureIds);
|
||||
}
|
||||
rootCharacterFeatureManagers = characterFeatureIds
|
||||
.map((id) => {
|
||||
const feature = featureMap.get(id);
|
||||
return feature
|
||||
? getFeatureManager({ feature, runSubscriptions: this.runSubscriptions, bustCache: this.bustCache })
|
||||
: null;
|
||||
})
|
||||
.filter(TypeScriptUtils.isNotNullOrUndefined);
|
||||
return rootCharacterFeatureManagers;
|
||||
});
|
||||
this.processCharacter = (generatedFeature) => {
|
||||
featureMap.set(generatedFeature.featureId, generatedFeature);
|
||||
return generateCharacterState({
|
||||
rootFeatureIds: [
|
||||
generatedFeature.featureId,
|
||||
...((rootCharacterFeatureManagers === null || rootCharacterFeatureManagers === void 0 ? void 0 : rootCharacterFeatureManagers.map((featureManager) => featureManager.getId())) || []),
|
||||
],
|
||||
featureMap,
|
||||
});
|
||||
};
|
||||
this.randomId = Math.floor(Math.random() * 1000000);
|
||||
}
|
||||
}
|
||||
// manage subscriptions
|
||||
FeaturesManager.subscribeToUpdates = ({ onUpdate, shouldInit = true }) => {
|
||||
// TODO: maybe from lib.
|
||||
const mapKey = HelperUtils.generateGuid();
|
||||
// connect to redux for updates
|
||||
let unsubscribe;
|
||||
if (getCurrentRulesEngineConfig().store) {
|
||||
const store = getCurrentRulesEngineConfig().store;
|
||||
unsubscribe = store === null || store === void 0 ? void 0 : store.subscribe(() => {
|
||||
onUpdate();
|
||||
});
|
||||
}
|
||||
subscriptionsMap.set(mapKey, onUpdate);
|
||||
if (shouldInit) {
|
||||
onUpdate();
|
||||
}
|
||||
return () => {
|
||||
subscriptionsMap.delete(mapKey);
|
||||
if (unsubscribe) {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
};
|
||||
import * as ApiAdapterUtils from "../apiAdapter/utils";
|
||||
import { characterActions } from '../actions';
|
||||
import { ContainerAccessors, ContainerGenerators, ContainerTypeEnum, ContainerUtils, ContainerValidators, } from '../engine/Container';
|
||||
import { ContainerGenerators, ContainerTypeEnum, ContainerUtils, ContainerValidators, } from '../engine/Container';
|
||||
import { EntityTypeEnum, DefaultCharacterName } from '../engine/Core';
|
||||
import { DefinitionHacks } from '../engine/Definition';
|
||||
import { HelperUtils } from '../engine/Helper';
|
||||
@@ -19,6 +19,15 @@ import { ValueHacks } from '../engine/Value';
|
||||
import { apiCreatorSelectors, characterSelectors, rulesEngineSelectors } from '../selectors';
|
||||
import { getContainerManager } from './ContainerManager';
|
||||
import { PartyManager } from './PartyManager';
|
||||
let inventoryManager = null;
|
||||
let itemShoppe = null;
|
||||
export function getInventoryManager(params) {
|
||||
if (inventoryManager) {
|
||||
return inventoryManager;
|
||||
}
|
||||
inventoryManager = new InventoryManager(params);
|
||||
return inventoryManager;
|
||||
}
|
||||
export class InventoryManager extends PartyManager {
|
||||
constructor(params) {
|
||||
super(params);
|
||||
@@ -89,9 +98,11 @@ export class InventoryManager extends PartyManager {
|
||||
this.dispatch(characterActions.customItemDestroy(ItemAccessors.getDefinitionId(item), ItemAccessors.getMappingId(item), isShared ? this.getPartyId() : null, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
}
|
||||
else {
|
||||
const itemPlans = rulesEngineSelectors.getAvailableItemPlans(this.state);
|
||||
const isContainer = ItemAccessors.isContainer(item);
|
||||
const infusion = ItemAccessors.getInfusion(item);
|
||||
this.dispatch(characterActions.itemDestroy(ItemAccessors.getMappingId(item), isContainer && infusion ? false : true, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
const itemPlan = ItemUtils.getItemPlan(item, itemPlans);
|
||||
this.dispatch(characterActions.itemDestroy(ItemAccessors.getMappingId(item), isContainer && (infusion || itemPlan) ? false : true, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
}
|
||||
};
|
||||
/**
|
||||
@@ -158,9 +169,19 @@ export class InventoryManager extends PartyManager {
|
||||
this.dispatch(characterActions.itemCustomizationsDelete(ItemAccessors.getMappingId(item), ItemAccessors.getMappingEntityTypeId(item), isShared ? this.getPartyId() : null, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
};
|
||||
// Validators
|
||||
this.canAddToContainer = (container) => {
|
||||
const isShared = ContainerAccessors.isShared(container);
|
||||
return !isShared || this.isSharingTurnedOn();
|
||||
// check for party inventory restrictions for isClaimable if its a shared item
|
||||
this.isClaimRestricted = (item) => {
|
||||
const isShared = this.isShared(item);
|
||||
if (!isShared) {
|
||||
return false;
|
||||
}
|
||||
const partyInventoryRestrictions = ItemAccessors.getPartyInventoryRestrictions(item);
|
||||
if ((partyInventoryRestrictions === null || partyInventoryRestrictions === void 0 ? void 0 : partyInventoryRestrictions.length) > 0) {
|
||||
if (partyInventoryRestrictions.some((restriction) => !restriction.isClaimable && restriction.characterId !== rulesEngineSelectors.getId(this.state))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -170,10 +191,7 @@ export class InventoryManager extends PartyManager {
|
||||
const canEquip = ItemAccessors.canEquip(item);
|
||||
const isEquipped = ItemAccessors.isEquipped(item);
|
||||
if (isShared && canEquip) {
|
||||
if (this.isSharingTurnedOn() || (this.isSharingTurnedDeleteOnly() && isEquipped)) {
|
||||
return isEquipped ? this.isEquippedToCurrentCharacter(item) : true;
|
||||
}
|
||||
return false;
|
||||
return isEquipped ? this.isEquippedToCurrentCharacter(item) : true;
|
||||
}
|
||||
return canEquip;
|
||||
};
|
||||
@@ -184,9 +202,6 @@ export class InventoryManager extends PartyManager {
|
||||
const isAttuned = ItemAccessors.isAttuned(item);
|
||||
if (!isAttuned) {
|
||||
if (isShared) {
|
||||
if (this.isSharingTurnedDeleteOnly()) {
|
||||
return false;
|
||||
}
|
||||
return this.isEquippedToCurrentCharacter(item) && !hasMaxAttunedItems && canAttune;
|
||||
}
|
||||
return !hasMaxAttunedItems && canAttune;
|
||||
@@ -199,30 +214,18 @@ export class InventoryManager extends PartyManager {
|
||||
}
|
||||
};
|
||||
this.canModifyQuantity = (item) => {
|
||||
const isShared = this.isShared(item);
|
||||
const isStackable = ItemAccessors.isStackable(item);
|
||||
if (isShared && isStackable) {
|
||||
return this.isSharingTurnedOn();
|
||||
}
|
||||
return isStackable;
|
||||
};
|
||||
this.canCustomizeItem = (item) => {
|
||||
const isShared = this.isShared(item);
|
||||
if (isShared) {
|
||||
return this.isSharingTurnedOn();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.canUseItemCharges = (item) => {
|
||||
const isShared = this.isShared(item);
|
||||
if (isShared) {
|
||||
return this.isSharingTurnedOn();
|
||||
}
|
||||
return !!ItemAccessors.getLimitedUse(item);
|
||||
};
|
||||
this.canRemoveItem = (item) => {
|
||||
const isShared = this.isShared(item);
|
||||
if (isShared) {
|
||||
if (this.isClaimRestricted(item)) {
|
||||
return false;
|
||||
}
|
||||
const infusion = ItemAccessors.getInfusion(item);
|
||||
if (infusion) {
|
||||
const infusionCharacterId = InfusionAccessors.getCharacterId(infusion);
|
||||
@@ -230,16 +233,22 @@ export class InventoryManager extends PartyManager {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return ItemAccessors.isEquipped(item)
|
||||
? this.isSharingTurnedOnOrDeleteOnly() && this.isEquippedToCurrentCharacter(item)
|
||||
: this.isSharingTurnedOnOrDeleteOnly();
|
||||
return ItemAccessors.isEquipped(item) ? this.isEquippedToCurrentCharacter(item) : true;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.canMoveItem = (item) => {
|
||||
// If you are changing this, you may want to change the canRemoveItem above
|
||||
const isContainer = ItemAccessors.isContainer(item);
|
||||
if (isContainer) {
|
||||
return false;
|
||||
}
|
||||
const isShared = this.isShared(item);
|
||||
if (isShared) {
|
||||
if (this.isClaimRestricted(item)) {
|
||||
return false;
|
||||
}
|
||||
//Might be able to remove this in favor of the above restriction check
|
||||
const infusion = ItemAccessors.getInfusion(item);
|
||||
if (infusion) {
|
||||
const infusionCharacterId = InfusionAccessors.getCharacterId(infusion);
|
||||
@@ -247,26 +256,23 @@ export class InventoryManager extends PartyManager {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return ItemAccessors.isEquipped(item)
|
||||
? this.isSharingTurnedOnOrDeleteOnly() && this.isEquippedToCurrentCharacter(item)
|
||||
: this.isSharingTurnedOnOrDeleteOnly();
|
||||
}
|
||||
else if (this.isSharingTurnedDeleteOnly()) {
|
||||
const localContainers = rulesEngineSelectors.getCharacterInventoryContainers(this.state);
|
||||
return localContainers.length > 1;
|
||||
return ItemAccessors.isEquipped(item) ? this.isEquippedToCurrentCharacter(item) : true;
|
||||
}
|
||||
const containerLookup = rulesEngineSelectors.getContainerLookup(this.state);
|
||||
return Object.keys(containerLookup).length > 1;
|
||||
};
|
||||
this.canShareItem = (item) => {
|
||||
//Can a container item be moved into the party inventory?
|
||||
this.canShareContainer = (item) => {
|
||||
//check that the item is a container
|
||||
const isContainer = ItemAccessors.isContainer(item);
|
||||
if (!isContainer) {
|
||||
return false;
|
||||
}
|
||||
const isShared = this.isShared(item);
|
||||
return !isShared && this.isSharingTurnedOn();
|
||||
return !isShared;
|
||||
};
|
||||
this.canClaimItem = (item) => {
|
||||
//Can a container item be "claimed" out of the party inventory?
|
||||
this.canClaimContainer = (item) => {
|
||||
const isContainer = ItemAccessors.isContainer(item);
|
||||
if (!isContainer || (ItemAccessors.isEquipped(item) && !this.isEquippedToCurrentCharacter(item))) {
|
||||
return false;
|
||||
@@ -278,6 +284,9 @@ export class InventoryManager extends PartyManager {
|
||||
const definitionKey = DefinitionHacks.hack__generateDefinitionKey(EntityTypeEnum.ITEM, ItemAccessors.getMappingId(item));
|
||||
const container = HelperUtils.lookupDataOrFallback(containerLookup, definitionKey);
|
||||
if (container) {
|
||||
if (this.isClaimRestricted(item)) {
|
||||
return false;
|
||||
}
|
||||
const infusion = ItemAccessors.getInfusion(item);
|
||||
if (infusion) {
|
||||
const infusionCharacterId = InfusionAccessors.getCharacterId(infusion);
|
||||
@@ -292,7 +301,7 @@ export class InventoryManager extends PartyManager {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return this.isSharingTurnedOnOrDeleteOnly();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -370,6 +379,11 @@ export class InventoryManager extends PartyManager {
|
||||
getInventoryShoppe({ onSuccess, additionalApiConfig, }) {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// If we already have the item shoppe, return it
|
||||
if (itemShoppe) {
|
||||
onSuccess(itemShoppe);
|
||||
return itemShoppe;
|
||||
}
|
||||
const characterId = characterSelectors.getId(this.state);
|
||||
const loadItems = apiCreatorSelectors.makeLoadAvailableItems(this.state);
|
||||
//set up pagination params
|
||||
@@ -404,6 +418,7 @@ export class InventoryManager extends PartyManager {
|
||||
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
||||
const shoppeContainer = ContainerGenerators.generateContainer(-1, ContainerTypeEnum.SHOPPE, 'Item Shoppe', transformedItems, false, null, null, characterId, null, ruleData);
|
||||
const shoppeManager = getContainerManager(Object.assign(Object.assign({}, this.params), { container: shoppeContainer, overrideItems: transformedItems }));
|
||||
itemShoppe = shoppeManager;
|
||||
onSuccess(shoppeManager);
|
||||
return shoppeManager;
|
||||
});
|
||||
|
||||
@@ -57,7 +57,8 @@ export class ItemManager extends PartyManager {
|
||||
else {
|
||||
const isContainer = this.isContainer();
|
||||
const infusion = this.getInfusion();
|
||||
this.dispatch(characterActions.itemDestroy(this.getMappingId(), isContainer && infusion ? false : true, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
const itemPlan = this.getItemPlan();
|
||||
this.dispatch(characterActions.itemDestroy(this.getMappingId(), isContainer && (infusion || itemPlan) ? false : true, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
||||
}
|
||||
};
|
||||
this.handleMove = ({ containerDefinitionKey }, onSuccess, onError) => {
|
||||
@@ -124,6 +125,13 @@ export class ItemManager extends PartyManager {
|
||||
this.getPrimarySourceCategoryId = () => ItemAccessors.getPrimarySourceCategoryId(this.item);
|
||||
this.getSecondarySourceCategoryIds = () => ItemAccessors.getSecondarySourceCategoryIds(this.item);
|
||||
this.getAllSourceCategoryIds = () => ItemUtils.getAllSourceCategoryIds(this.item);
|
||||
this.getDefinitionKey = () => { var _a; return (_a = ItemAccessors.getDefinition(this.item)) === null || _a === void 0 ? void 0 : _a.definitionKey; };
|
||||
this.getOriginDefinitionKey = () => ItemAccessors.getOriginDefinitionKey(this.item);
|
||||
this.getDescription = () => ItemAccessors.getDescription(this.item);
|
||||
this.getRarity = () => ItemAccessors.getRarity(this.item);
|
||||
this.canAttune = () => ItemAccessors.canAttune(this.item);
|
||||
this.getAttunementDescription = () => ItemAccessors.getAttunementDescription(this.item);
|
||||
this.getPartyInventoryRestrictions = () => ItemAccessors.getPartyInventoryRestrictions(this.item);
|
||||
// Validator
|
||||
this.isShared = () => this.requiresContainer().isShared();
|
||||
this.isArmorContract = () => ItemUtils.isArmorContract(this.item);
|
||||
@@ -134,10 +142,7 @@ export class ItemManager extends PartyManager {
|
||||
const canEquip = ItemAccessors.canEquip(this.item);
|
||||
const isEquipped = ItemAccessors.isEquipped(this.item);
|
||||
if (isShared && canEquip) {
|
||||
if (this.isSharingTurnedOn() || (this.isSharingTurnedDeleteOnly() && isEquipped)) {
|
||||
return isEquipped ? this.isEquippedToCurrentCharacter() : true;
|
||||
}
|
||||
return false;
|
||||
return isEquipped ? this.isEquippedToCurrentCharacter() : true;
|
||||
}
|
||||
return canEquip;
|
||||
};
|
||||
@@ -145,6 +150,7 @@ export class ItemManager extends PartyManager {
|
||||
const characterId = rulesEngineSelectors.getId(this.state);
|
||||
return ItemValidators.isEquippedToCurrentCharacter(this.item, characterId);
|
||||
};
|
||||
this.isReplicated = () => ItemUtils.isReplicated(this.item);
|
||||
// Utils
|
||||
this.getRarityLevel = () => ItemUtils.getRarityLevel(this.item);
|
||||
this.generateContainerDefinitionKey = () => {
|
||||
@@ -161,12 +167,61 @@ export class ItemManager extends PartyManager {
|
||||
}
|
||||
return DefaultCharacterName;
|
||||
};
|
||||
this.getItemPlan = () => {
|
||||
const itemPlans = rulesEngineSelectors.getAvailableItemPlans(this.state);
|
||||
return ItemUtils.getItemPlan(this.item, itemPlans);
|
||||
};
|
||||
this.getNotes = () => {
|
||||
const weaponSpellDamageGroups = rulesEngineSelectors.getWeaponSpellDamageGroups(this.state);
|
||||
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
||||
const abilityLookup = rulesEngineSelectors.getAbilityLookup(this.state);
|
||||
const proficiencyBonus = rulesEngineSelectors.getProficiencyBonus(this.state);
|
||||
return ItemNotes.getNoteComponents(this.item, weaponSpellDamageGroups, ruleData, abilityLookup, proficiencyBonus);
|
||||
return ItemNotes.getNoteComponents(this.item, weaponSpellDamageGroups, ruleData, abilityLookup, proficiencyBonus, this.getItemPlan());
|
||||
};
|
||||
this.getIntroText = () => {
|
||||
const strings = [];
|
||||
const subType = this.getSubType();
|
||||
const rarity = this.getRarity();
|
||||
const attunementDescription = this.getAttunementDescription();
|
||||
let type = this.getType();
|
||||
if (this.isWeaponContract()) {
|
||||
if (this.isMagic()) {
|
||||
type = `Weapon (${type})`;
|
||||
}
|
||||
else {
|
||||
type = 'Weapon';
|
||||
}
|
||||
}
|
||||
else if (this.isArmorContract()) {
|
||||
if (this.isMagic()) {
|
||||
type = `Armor (${this.getBaseArmorName()})`;
|
||||
}
|
||||
else {
|
||||
type = 'Armor';
|
||||
}
|
||||
}
|
||||
else if (this.isGearContract()) {
|
||||
type = subType || type;
|
||||
}
|
||||
else if (this.isCustom()) {
|
||||
type = 'Custom';
|
||||
}
|
||||
if (this.isLegacy()) {
|
||||
strings.push('Legacy • ');
|
||||
}
|
||||
if (type) {
|
||||
strings.push(type);
|
||||
}
|
||||
if (!this.isCustom() && rarity) {
|
||||
strings.push(`, ${rarity}`);
|
||||
}
|
||||
if (this.canAttune()) {
|
||||
strings.push(` (requires attunement${attunementDescription ? ` by a ${attunementDescription}` : ''})`);
|
||||
}
|
||||
if (this.isContainer()) {
|
||||
strings.push(', container');
|
||||
}
|
||||
return strings.join('');
|
||||
};
|
||||
this.getMetaText = () => {
|
||||
const appliedWeaponReplacementStats = this.getAppliedWeaponReplacementStats();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { serviceDataActions } from '../actions';
|
||||
import { CampaignAccessors, CampaignUtils } from '../engine/Campaign';
|
||||
import { PartyInventorySharingStateEnum } from '../engine/Campaign/constants';
|
||||
import { serviceDataSelectors } from '../selectors';
|
||||
import { MessageManager } from './MessageManager';
|
||||
export class PartyManager extends MessageManager {
|
||||
@@ -28,11 +27,6 @@ export class PartyManager extends MessageManager {
|
||||
};
|
||||
};
|
||||
// Accessors
|
||||
this.getSharingState = () => {
|
||||
var _a;
|
||||
const partyInfo = serviceDataSelectors.getPartyInfo(this.state);
|
||||
return (_a = (partyInfo && CampaignAccessors.getSharingState(partyInfo))) !== null && _a !== void 0 ? _a : PartyInventorySharingStateEnum.OFF; // if we get null return off
|
||||
};
|
||||
this.getPartyId = () => {
|
||||
const partyInfo = serviceDataSelectors.getPartyInfo(this.state);
|
||||
return partyInfo ? CampaignAccessors.getId(partyInfo) : null;
|
||||
@@ -44,11 +38,6 @@ export class PartyManager extends MessageManager {
|
||||
}
|
||||
return '';
|
||||
};
|
||||
// Validators
|
||||
this.isSharingTurnedOn = () => this.getSharingState() === PartyInventorySharingStateEnum.ON;
|
||||
this.isSharingTurnedOff = () => this.getSharingState() === PartyInventorySharingStateEnum.OFF;
|
||||
this.isSharingTurnedDeleteOnly = () => this.getSharingState() === PartyInventorySharingStateEnum.DELETE_ONLY;
|
||||
this.isSharingTurnedOnOrDeleteOnly = () => CampaignUtils.isSharingStateActive(this.getSharingState());
|
||||
this.addSubscriptions({
|
||||
[this.EVENT_TYPES.ITEM_SHARED_FULFILLED]: this.updateSharedInventory,
|
||||
});
|
||||
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
import { ExpressionOperators, StatementOperators } from '@dndbeyond/character-gfs';
|
||||
import { ModifierAccessors, ModifierTypeEnum, ModifierValidators } from "../../../engine/Modifier";
|
||||
import { RuleDataUtils } from "../../../engine/RuleData";
|
||||
export function transformAbilityScores(validGlobalModifiers, baseStats, ruleData) {
|
||||
const abilityScoreModifiers = validGlobalModifiers.filter((modifier) => {
|
||||
return (ModifierValidators.isValidStatScoreModifier(modifier, 1) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 2) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 3) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 4) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 5) ||
|
||||
ModifierValidators.isValidStatScoreModifier(modifier, 6));
|
||||
});
|
||||
const baseAbilityScores = baseStats.flatMap((stat) => {
|
||||
var _a, _b, _c;
|
||||
if (stat.id) {
|
||||
const statName = (_b = (_a = RuleDataUtils.getStatNameById(stat.id, ruleData, true)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : '';
|
||||
stat.value = (_c = stat.value) !== null && _c !== void 0 ? _c : 0;
|
||||
// Math.floor((stat.value - 10) / 2)
|
||||
return [
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'value'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [stat.value],
|
||||
operands: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'modifier'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.FLOOR,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.MULTIPLY,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [0.5],
|
||||
operands: null,
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.ADD,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [-10],
|
||||
operands: null,
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.DYNAMIC_VALUE,
|
||||
values: ['attributes', statName, 'value'],
|
||||
operands: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
precedence: 0.5,
|
||||
target: ['attributes', statName, 'max'],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [20],
|
||||
operands: null,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
const gfsAbilityScores = abilityScoreModifiers.map((abilityScoreModifier) => {
|
||||
var _a, _b, _c, _d;
|
||||
const modifierType = ModifierAccessors.getType(abilityScoreModifier);
|
||||
switch (modifierType) {
|
||||
case ModifierTypeEnum.SET:
|
||||
return {
|
||||
precedence: 0.5,
|
||||
target: [
|
||||
'attributes',
|
||||
(_a = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _a === void 0 ? void 0 : _a.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [ModifierAccessors.getValue(abilityScoreModifier)],
|
||||
},
|
||||
};
|
||||
case ModifierTypeEnum.BONUS:
|
||||
default:
|
||||
return {
|
||||
precedence: 0.5,
|
||||
target: [
|
||||
'attributes',
|
||||
(_b = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _b === void 0 ? void 0 : _b.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
operator: StatementOperators.SET,
|
||||
operand: {
|
||||
operator: ExpressionOperators.ADD,
|
||||
values: null,
|
||||
operands: [
|
||||
{
|
||||
operator: ExpressionOperators.DYNAMIC_VALUE,
|
||||
operands: null,
|
||||
values: [
|
||||
'attributes',
|
||||
(_c = ModifierAccessors.getSubType(abilityScoreModifier)) === null || _c === void 0 ? void 0 : _c.replace('-score', ''),
|
||||
'value',
|
||||
],
|
||||
},
|
||||
{
|
||||
operator: ExpressionOperators.STATIC_VALUE,
|
||||
values: [(_d = ModifierAccessors.getValue(abilityScoreModifier)) !== null && _d !== void 0 ? _d : 0],
|
||||
operands: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
const generatedFeature = {
|
||||
meta: {
|
||||
name: 'Generated Ability Scores',
|
||||
category: 'Generated',
|
||||
},
|
||||
statements: [...baseAbilityScores, ...gfsAbilityScores],
|
||||
featureId: 'generated-ability-scores',
|
||||
labels: [],
|
||||
sources: [],
|
||||
subfeatures: [],
|
||||
acceptableInputs: {},
|
||||
primarySource: null,
|
||||
secondarySources: [],
|
||||
};
|
||||
return { baseAbilityScores, gfsAbilityScores, generatedFeature };
|
||||
}
|
||||
Reference in New Issue
Block a user