isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
165 lines (164 loc) • 6.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getActivePocketItemSlot = getActivePocketItemSlot;
exports.getFirstCard = getFirstCard;
exports.getFirstCardOrPill = getFirstCardOrPill;
exports.getFirstPill = getFirstPill;
exports.getPocketItems = getPocketItems;
exports.hasOpenPocketItemSlot = hasOpenPocketItemSlot;
exports.isFirstSlotPocketActiveItem = isFirstSlotPocketActiveItem;
exports.pocketItemsEquals = pocketItemsEquals;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const PocketItemType_1 = require("../enums/PocketItemType");
const players_1 = require("./players");
/**
* Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
* in, if any. Returns undefined if the player does not have a pocket active item.
*/
function getActivePocketItemSlot(player) {
const pocketItems = getPocketItems(player);
for (const pocketItem of pocketItems) {
if (pocketItem.type === PocketItemType_1.PocketItemType.ACTIVE_ITEM) {
return pocketItem.slot;
}
}
return undefined;
}
/** Helper item to get the first card that a player is holding in their pocket item slots. */
function getFirstCard(player) {
const pocketItems = getPocketItems(player);
return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.CARD);
}
/**
* Helper item to get the first card or pill that a player is holding in their pocket item slots.
*/
function getFirstCardOrPill(player) {
const pocketItems = getPocketItems(player);
return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.CARD
|| pocketItem.type === PocketItemType_1.PocketItemType.PILL);
}
/** Helper item to get the first pill that a player is holding in their pocket item slots. */
function getFirstPill(player) {
const pocketItems = getPocketItems(player);
return pocketItems.find((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.PILL);
}
/**
* Use this helper function as a workaround for the `EntityPlayer.GetPocketItem` method not working
* correctly.
*
* Note that due to API limitations, there is no way to determine the location of a Dice Bag trinket
* dice. Furthermore, when the player has a Dice Bag trinket dice and a pocket active at the same
* time, there is no way to determine the location of the pocket active item. If this function
* cannot determine the identity of a particular slot, it will mark the type of the slot as
* `PocketItemType.UNDETERMINABLE`.
*/
function getPocketItems(player) {
const pocketItem = player.GetActiveItem(isaac_typescript_definitions_1.ActiveSlot.POCKET);
const hasPocketItem = pocketItem !== isaac_typescript_definitions_1.CollectibleType.NULL;
const pocketItem2 = player.GetActiveItem(isaac_typescript_definitions_1.ActiveSlot.POCKET_SINGLE_USE);
const hasPocketItem2 = pocketItem2 !== isaac_typescript_definitions_1.CollectibleType.NULL;
const maxPocketItems = player.GetMaxPocketItems();
const pocketItems = [];
let pocketItemIdentified = false;
let pocketItem2Identified = false;
for (const slot of cachedEnumValues_1.POCKET_ITEM_SLOT_VALUES) {
const cardType = player.GetCard(slot);
const pillColor = player.GetPill(slot);
if (cardType !== isaac_typescript_definitions_1.CardType.NULL) {
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.CARD,
subType: cardType,
});
}
else if (pillColor !== isaac_typescript_definitions_1.PillColor.NULL) {
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.PILL,
subType: pillColor,
});
}
else if (hasPocketItem && !hasPocketItem2 && !pocketItemIdentified) {
pocketItemIdentified = true;
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.ACTIVE_ITEM,
subType: pocketItem,
});
}
else if (!hasPocketItem && hasPocketItem2 && !pocketItem2Identified) {
pocketItem2Identified = true;
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.DICE_BAG_DICE,
subType: pocketItem2,
});
}
else if (hasPocketItem && hasPocketItem2) {
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.UNDETERMINABLE,
subType: 0,
});
}
else {
pocketItems.push({
slot,
type: PocketItemType_1.PocketItemType.EMPTY,
subType: 0,
});
}
if (slot + 1 === maxPocketItems) {
break;
}
}
return pocketItems;
}
/**
* Returns whether the player can hold an additional pocket item, beyond what they are currently
* carrying. This takes into account items that modify the max number of pocket items, like Starter
* Deck.
*
* If the player is the Tainted Soul, this always returns false, since that character cannot pick up
* items. (Only Tainted Forgotten can pick up items.)
*/
function hasOpenPocketItemSlot(player) {
if ((0, players_1.isCharacter)(player, isaac_typescript_definitions_1.PlayerType.SOUL_B)) {
return false;
}
const pocketItems = getPocketItems(player);
return pocketItems.some((pocketItem) => pocketItem.type === PocketItemType_1.PocketItemType.EMPTY);
}
/**
* Helper function to determine whether the player's "active" pocket item slot is set to their
* pocket active item.
*/
function isFirstSlotPocketActiveItem(player) {
const pocketItems = getPocketItems(player);
const firstPocketItem = pocketItems[0];
if (firstPocketItem === undefined) {
return false;
}
return firstPocketItem.type === PocketItemType_1.PocketItemType.ACTIVE_ITEM;
}
/** Helper function to see if two sets of pocket item descriptions are identical. */
function pocketItemsEquals(pocketItems1, pocketItems2) {
if (pocketItems1.length !== pocketItems2.length) {
return false;
}
// eslint-disable-next-line unicorn/no-for-loop
for (let i = 0; i < pocketItems1.length; i++) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const pocketItem1 = pocketItems1[i];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const pocketItem2 = pocketItems2[i];
const keys = Object.keys(pocketItem1);
for (const key of keys) {
if (pocketItem1[key] !== pocketItem2[key]) {
return false;
}
}
}
return true;
}