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;