253 lines
13 KiB
JavaScript
253 lines
13 KiB
JavaScript
import { characterActions } from "../actions";
|
|
import { ContainerAccessors, ContainerTypeEnum, ContainerValidators } from "../engine/Container";
|
|
import { LimitedUseAccessors } from "../engine/LimitedUse";
|
|
import { RuleDataUtils } from "../engine/RuleData";
|
|
import { rulesEngineSelectors } from "../selectors";
|
|
import { EntityTypeEnum, DefaultCharacterName } from '../engine/Core';
|
|
import { DefinitionHacks } from '../engine/Definition';
|
|
import { ItemAccessors, ItemNotes, ItemUtils, ItemValidators } from '../engine/Item';
|
|
import { ContainerManager } from './ContainerManager';
|
|
import { PartyManager } from './PartyManager';
|
|
const itemMangerMap = new Map();
|
|
export const getItem = (itemId) => {
|
|
const itemManager = itemMangerMap.get(itemId);
|
|
if (!itemManager) {
|
|
throw new Error(`ItemManager for item ${itemId} is null`);
|
|
}
|
|
return itemManager;
|
|
};
|
|
export const getItemManager = (params) => {
|
|
const { item } = params;
|
|
const itemId = ItemAccessors.getMappingId(item);
|
|
if (itemMangerMap.has(itemId)) {
|
|
const itemManager = itemMangerMap.get(itemId);
|
|
if (!itemManager) {
|
|
throw new Error(`ItemManager for item ${itemId} is null`);
|
|
}
|
|
if (itemManager.item === item) {
|
|
return itemManager;
|
|
}
|
|
}
|
|
const newItemManger = new ItemManager(params);
|
|
itemMangerMap.set(itemId, newItemManger);
|
|
return newItemManger;
|
|
};
|
|
export class ItemManager extends PartyManager {
|
|
constructor(params) {
|
|
super(params);
|
|
// Actions
|
|
this.handleAdd = ({ amount, containerDefinitionKey }, onSuccess, onError) => {
|
|
var _a;
|
|
// const container = this.requiresContainer();
|
|
let itemDestinationContainerDefinitionKey = containerDefinitionKey;
|
|
// TODO: IS THERE A SELECTOR FOR THIS? -> move to container manager?
|
|
const containers = rulesEngineSelectors.getInventoryContainers(this.state);
|
|
// Default to the character container if none is passed
|
|
if (!itemDestinationContainerDefinitionKey) {
|
|
itemDestinationContainerDefinitionKey = ContainerAccessors.getDefinitionKey((_a = containers.find(ContainerValidators.isCharacterContainer)) !== null && _a !== void 0 ? _a : containers[0]);
|
|
}
|
|
const isShared = ContainerManager.isSharedContainerDefinitionKey(this.state, itemDestinationContainerDefinitionKey);
|
|
this.dispatch(characterActions.itemCreate(this.item, amount, this.handleAcceptOnSuccess(isShared, onSuccess), this.handleRejectOnError(onError), containerDefinitionKey));
|
|
};
|
|
this.handleRemove = (onSuccess, onError) => {
|
|
const isShared = this.isShared();
|
|
if (this.isCustom()) {
|
|
this.dispatch(characterActions.customItemDestroy(this.getDefinitionId(), this.getMappingId(), isShared ? this.getPartyId() : null, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
|
}
|
|
else {
|
|
const isContainer = this.isContainer();
|
|
const infusion = this.getInfusion();
|
|
this.dispatch(characterActions.itemDestroy(this.getMappingId(), isContainer && infusion ? false : true, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
|
}
|
|
};
|
|
this.handleMove = ({ containerDefinitionKey }, onSuccess, onError) => {
|
|
const definitionKeyId = DefinitionHacks.hack__getDefinitionKeyId(containerDefinitionKey);
|
|
const definitionKeyType = DefinitionHacks.hack__getDefinitionKeyType(containerDefinitionKey);
|
|
if (definitionKeyId && definitionKeyType) {
|
|
const isShared = this.requiresContainer().isSharedOtherContainerDefinitionKey(containerDefinitionKey) || this.isShared();
|
|
this.dispatch(characterActions.itemMoveSet(this.getMappingId(), definitionKeyId, definitionKeyType, this.handleAcceptOnSuccess(isShared, onSuccess)));
|
|
}
|
|
};
|
|
this.handleEquip = (onSuccess, onError) => {
|
|
const characterId = rulesEngineSelectors.getId(this.state);
|
|
this.dispatch(characterActions.itemEquippedSet(ItemAccessors.getMappingId(this.item), true, characterId, EntityTypeEnum.CHARACTER, this.handleAcceptOnSuccess(this.isShared(), onSuccess)));
|
|
};
|
|
this.handleUnequip = (onSuccess, onError) => {
|
|
this.dispatch(characterActions.itemEquippedSet(ItemAccessors.getMappingId(this.item), false, null, null, this.handleAcceptOnSuccess(this.isShared(), onSuccess)));
|
|
};
|
|
this.handleItemLimitedUseSet = (uses) => {
|
|
this.dispatch(characterActions.itemChargesSet(this.getMappingId(), uses, this.handleAcceptOnSuccess(this.isShared())));
|
|
};
|
|
this.getItem = () => this.item;
|
|
// Accessors
|
|
this.getUniqueKey = () => `${ItemAccessors.getUniqueKey(this.item)}-${this.requiresContainer().getDefinitionKey()}`;
|
|
this.isEquipped = () => ItemAccessors.isEquipped(this.item);
|
|
this.getMappingId = () => ItemAccessors.getMappingId(this.item);
|
|
this.getType = () => ItemAccessors.getType(this.item);
|
|
this.isHexWeapon = () => ItemAccessors.isHexWeapon(this.item);
|
|
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);
|
|
this.isStackable = () => ItemAccessors.isStackable(this.item);
|
|
this.getWeight = () => ItemAccessors.getWeight(this.item);
|
|
this.getCost = () => ItemAccessors.getCost(this.item);
|
|
this.getAvatarUrl = () => ItemAccessors.getAvatarUrl(this.item);
|
|
this.isContainer = () => ItemAccessors.isContainer(this.item);
|
|
this.getName = () => ItemAccessors.getName(this.item);
|
|
this.isCustom = () => ItemAccessors.isCustom(this.item);
|
|
this.getDefinitionId = () => ItemAccessors.getDefinitionId(this.item);
|
|
this.getInfusion = () => ItemAccessors.getInfusion(this.item);
|
|
this.getContainerDefinitionKey = () => ItemAccessors.getContainerDefinitionKey(this.item);
|
|
this.hasProficiency = () => ItemAccessors.hasProficiency(this.item);
|
|
this.isMagic = () => ItemAccessors.isMagic(this.item);
|
|
this.getDefintionFilterType = () => ItemAccessors.getDefintionFilterType(this.item);
|
|
this.isPack = () => ItemAccessors.isPack(this.item);
|
|
this.getBundleSize = () => ItemAccessors.getBundleSize(this.item);
|
|
this.getAttackType = () => ItemAccessors.getAttackType(this.item);
|
|
this.isAdamantine = () => ItemAccessors.isAdamantine(this.item);
|
|
this.isSilvered = () => ItemAccessors.isSilvered(this.item);
|
|
this.isCustomized = () => ItemAccessors.isCustomized(this.item);
|
|
this.getRange = () => ItemAccessors.getRange(this.item);
|
|
this.getLongRange = () => ItemAccessors.getLongRange(this.item);
|
|
this.getReach = () => ItemAccessors.getReach(this.item);
|
|
this.getToHit = () => ItemAccessors.getToHit(this.item);
|
|
this.getDamage = () => ItemAccessors.getDamage(this.item);
|
|
this.getVersatileDamage = () => ItemAccessors.getVersatileDamage(this.item);
|
|
this.getDamageType = () => ItemAccessors.getDamageType(this.item);
|
|
this.getMasteryName = () => ItemAccessors.getMasteryName(this.item);
|
|
this.isLegacy = () => ItemAccessors.isLegacy(this.item);
|
|
this.getPrimarySourceCategoryId = () => ItemAccessors.getPrimarySourceCategoryId(this.item);
|
|
this.getSecondarySourceCategoryIds = () => ItemAccessors.getSecondarySourceCategoryIds(this.item);
|
|
this.getAllSourceCategoryIds = () => ItemUtils.getAllSourceCategoryIds(this.item);
|
|
// Validator
|
|
this.isShared = () => this.requiresContainer().isShared();
|
|
this.isArmorContract = () => ItemUtils.isArmorContract(this.item);
|
|
this.isGearContract = () => ItemUtils.isGearContract(this.item);
|
|
this.isWeaponContract = () => ItemUtils.isWeaponContract(this.item);
|
|
this.canEquipUnequipItem = () => {
|
|
const isShared = this.isShared();
|
|
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 canEquip;
|
|
};
|
|
this.isEquippedToCurrentCharacter = () => {
|
|
const characterId = rulesEngineSelectors.getId(this.state);
|
|
return ItemValidators.isEquippedToCurrentCharacter(this.item, characterId);
|
|
};
|
|
// Utils
|
|
this.getRarityLevel = () => ItemUtils.getRarityLevel(this.item);
|
|
this.generateContainerDefinitionKey = () => {
|
|
return DefinitionHacks.hack__generateDefinitionKey(ContainerTypeEnum.ITEM, this.getMappingId());
|
|
};
|
|
this.getEquippedCharacterName = () => {
|
|
var _a;
|
|
const equippedEntityId = ItemAccessors.getEquippedEntityId(this.item);
|
|
if (this.isEquippedToCurrentCharacter()) {
|
|
return (_a = rulesEngineSelectors.getName(this.state)) !== null && _a !== void 0 ? _a : '';
|
|
}
|
|
if (equippedEntityId) {
|
|
return this.getPartyMemberName(equippedEntityId);
|
|
}
|
|
return DefaultCharacterName;
|
|
};
|
|
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);
|
|
};
|
|
this.getMetaText = () => {
|
|
const appliedWeaponReplacementStats = this.getAppliedWeaponReplacementStats();
|
|
const ruleData = rulesEngineSelectors.getRuleData(this.state);
|
|
let metaItems = [];
|
|
if (this.isLegacy()) {
|
|
metaItems.push('Legacy');
|
|
}
|
|
const type = this.getType();
|
|
if (type !== null) {
|
|
metaItems.push(type);
|
|
}
|
|
if (this.isHexWeapon()) {
|
|
metaItems.push('Hex Weapon');
|
|
}
|
|
if (this.isPactWeapon()) {
|
|
metaItems.push('Pact Weapon');
|
|
}
|
|
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');
|
|
}
|
|
if (this.isArmorContract()) {
|
|
let baseArmorName = this.getBaseArmorName();
|
|
if (baseArmorName) {
|
|
metaItems.push(baseArmorName);
|
|
}
|
|
}
|
|
else if (this.isGearContract()) {
|
|
let subType = this.getSubType();
|
|
if (subType) {
|
|
metaItems.push(subType);
|
|
}
|
|
}
|
|
if (this.getMasteryName()) {
|
|
metaItems.push('Mastery');
|
|
}
|
|
if (this.isEquipped() && !this.isEquippedToCurrentCharacter()) {
|
|
metaItems.push(`Equipped by ${this.getEquippedCharacterName()}`);
|
|
}
|
|
return metaItems;
|
|
};
|
|
this.getNumberUsed = () => {
|
|
const limitedUse = ItemAccessors.getLimitedUse(this.item);
|
|
if (limitedUse !== null) {
|
|
return LimitedUseAccessors.getNumberUsed(limitedUse);
|
|
}
|
|
return null;
|
|
};
|
|
this.getAttackTypeName = () => {
|
|
const attackType = this.getAttackType();
|
|
let attackTypeName = '';
|
|
if (attackType) {
|
|
attackTypeName = RuleDataUtils.getAttackTypeRangeName(attackType);
|
|
}
|
|
return attackTypeName;
|
|
};
|
|
this.getMasteryAction = () => {
|
|
const actions = rulesEngineSelectors.getActions(this.state);
|
|
return ItemUtils.getMasteryAction(this.item, actions);
|
|
};
|
|
this.item = params.item;
|
|
this.container = params.container || null;
|
|
}
|
|
/**
|
|
*
|
|
* @description This method is used to throw an error incase the manager was not created with a container
|
|
*/
|
|
requiresContainer() {
|
|
if (this.container === null) {
|
|
throw new Error('Item does not have a container');
|
|
}
|
|
return this.container;
|
|
}
|
|
}
|
|
ItemManager.getItem = getItem;
|