isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
581 lines (580 loc) • 29.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.clearCollectibleSprite = clearCollectibleSprite;
exports.collectibleHasCacheFlag = collectibleHasCacheFlag;
exports.collectibleSpriteEquals = collectibleSpriteEquals;
exports.getCollectibleChargeType = getCollectibleChargeType;
exports.getCollectibleDescription = getCollectibleDescription;
exports.getCollectibleDevilCoinPrice = getCollectibleDevilCoinPrice;
exports.getCollectibleDevilHeartPrice = getCollectibleDevilHeartPrice;
exports.getCollectibleGfxFilename = getCollectibleGfxFilename;
exports.getCollectibleInitCharge = getCollectibleInitCharge;
exports.getCollectibleItemType = getCollectibleItemType;
exports.getCollectibleMaxCharges = getCollectibleMaxCharges;
exports.getCollectibleName = getCollectibleName;
exports.getCollectiblePedestalType = getCollectiblePedestalType;
exports.getCollectibleQuality = getCollectibleQuality;
exports.getCollectibleTags = getCollectibleTags;
exports.getVanillaCollectibleTypesOfQuality = getVanillaCollectibleTypesOfQuality;
exports.isActiveCollectible = isActiveCollectible;
exports.isBlindCollectible = isBlindCollectible;
exports.isFamiliarCollectible = isFamiliarCollectible;
exports.isGlitchedCollectible = isGlitchedCollectible;
exports.isHiddenCollectible = isHiddenCollectible;
exports.isModdedCollectibleType = isModdedCollectibleType;
exports.isPassiveOrFamiliarCollectible = isPassiveOrFamiliarCollectible;
exports.isQuality = isQuality;
exports.isSingleUseCollectible = isSingleUseCollectible;
exports.isValidCollectibleType = isValidCollectibleType;
exports.isVanillaCollectibleType = isVanillaCollectibleType;
exports.newCollectibleSprite = newCollectibleSprite;
exports.preventCollectibleRotation = preventCollectibleRotation;
exports.removeCollectiblePickupDelay = removeCollectiblePickupDelay;
exports.setCollectibleBlind = setCollectibleBlind;
exports.setCollectibleEmpty = setCollectibleEmpty;
exports.setCollectibleGlitched = setCollectibleGlitched;
exports.setCollectiblePedestalType = setCollectiblePedestalType;
exports.setCollectibleSprite = setCollectibleSprite;
exports.setCollectibleSubType = setCollectibleSubType;
exports.setCollectiblesRerolledForItemTracker = setCollectiblesRerolledForItemTracker;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const constants_1 = require("../core/constants");
const constantsFirstLast_1 = require("../core/constantsFirstLast");
const constantsVanilla_1 = require("../core/constantsVanilla");
const collectibleDescriptions_1 = require("../objects/collectibleDescriptions");
const collectibleNames_1 = require("../objects/collectibleNames");
const singleUseActiveCollectibleTypesSet_1 = require("../sets/singleUseActiveCollectibleTypesSet");
const entities_1 = require("./entities");
const flag_1 = require("./flag");
const pickupVariants_1 = require("./pickupVariants");
const sprites_1 = require("./sprites");
const types_1 = require("./types");
const utils_1 = require("./utils");
const COLLECTIBLE_ANM2_PATH = "gfx/005.100_collectible.anm2";
const DEFAULT_COLLECTIBLE_PRICE = 15;
/** Glitched items start at id 4294967295 (the final 32-bit integer) and increment backwards. */
const GLITCHED_ITEM_THRESHOLD = 4_000_000_000;
const QUALITY_TO_VANILLA_COLLECTIBLE_TYPES_MAP = (() => {
const qualityToCollectibleTypesMap = new Map();
for (const quality of constants_1.QUALITIES) {
const collectibleTypes = [];
for (const collectibleType of constantsVanilla_1.VANILLA_COLLECTIBLE_TYPES) {
const collectibleTypeQuality = getCollectibleQuality(collectibleType);
if (collectibleTypeQuality === quality) {
collectibleTypes.push(collectibleType);
}
}
qualityToCollectibleTypesMap.set(quality, collectibleTypes);
}
return qualityToCollectibleTypesMap;
})();
/** The `isBlindCollectible` function needs a reference sprite to work properly. */
const questionMarkSprite = (() => {
const sprite = Sprite();
sprite.Load("gfx/005.100_collectible.anm2", false);
sprite.ReplaceSpritesheet(1, "gfx/items/collectibles/questionmark.png");
sprite.LoadGraphics();
return sprite;
})();
function clearCollectibleSprite(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "clearCollectibleSprite" function was given a non-collectible: ${entityID}`);
}
setCollectibleSprite(collectible, undefined);
}
/** Helper function to check in the item config if a given collectible has a given cache flag. */
function collectibleHasCacheFlag(collectibleOrCollectibleType, cacheFlag) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "collectibleHasCacheFlag");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return false;
}
return (0, flag_1.hasFlag)(itemConfigItem.CacheFlags, cacheFlag);
}
/** Helper function to check if two collectible sprites have the same sprite sheet loaded. */
function collectibleSpriteEquals(sprite1, sprite2) {
// We start at negative 40 texels upwards, as by default we assume a collectible that is sitting
// on a pedestal. We finish at positive 10 texels downwards, in order to make comparing shop items
// more accurate.
const xStart = -1;
const xFinish = 1;
const xIncrement = 1;
const yStart = -40;
const yFinish = 10;
const yIncrement = 3;
return (0, sprites_1.spriteEquals)(sprite1, sprite2, isaac_typescript_definitions_1.CollectibleSpriteLayer.HEAD, xStart, xFinish, xIncrement, yStart, yFinish, yIncrement);
}
/**
* Helper function to get the charge type that a collectible has. Returns
* `ItemConfigChargeType.NORMAL` if the provided collectible type was not valid.
*/
function getCollectibleChargeType(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleChargeType");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return isaac_typescript_definitions_1.ItemConfigChargeType.NORMAL;
}
return itemConfigItem.ChargeType;
}
/**
* Helper function to get the in-game description for a collectible. Returns "Unknown" if the
* provided collectible type was not valid.
*
* This function works for both vanilla and modded collectibles.
*/
function getCollectibleDescription(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleDescription");
// "ItemConfigItem.Description" is bugged with vanilla items on patch v1.7.6, so we use a
// hard-coded map as a workaround.
const collectibleDescription = collectibleDescriptions_1.COLLECTIBLE_DESCRIPTIONS[collectibleType];
if (collectibleDescription !== undefined) {
return collectibleDescription;
}
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem !== undefined) {
return itemConfigItem.Description;
}
return collectibleDescriptions_1.DEFAULT_COLLECTIBLE_DESCRIPTION;
}
/**
* Helper function to get the coin cost that a collectible item would be if it were being offered in
* a Devil Room deal. Returns 0 if passed `CollectibleType.NULL`.
*/
function getCollectibleDevilCoinPrice(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleDescription");
if (collectibleType === isaac_typescript_definitions_1.CollectibleType.NULL) {
return 0;
}
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return DEFAULT_COLLECTIBLE_PRICE;
}
return itemConfigItem.DevilPrice * DEFAULT_COLLECTIBLE_PRICE;
}
/**
* Helper function to get the heart cost that a collectible item would be if it were being offered
* in a Devil Room deal. Returns 0 if passed `CollectibleType.NULL`.
*/
function getCollectibleDevilHeartPrice(collectibleOrCollectibleType, player) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleDevilHeartPrice");
const maxHearts = player.GetMaxHearts();
if (collectibleType === isaac_typescript_definitions_1.CollectibleType.NULL) {
return 0;
}
if (maxHearts === 0) {
return isaac_typescript_definitions_1.PickupPrice.THREE_SOUL_HEARTS;
}
const defaultCollectiblePrice = isaac_typescript_definitions_1.PickupPrice.ONE_HEART;
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return defaultCollectiblePrice;
}
const twoHeartPrice = maxHearts === 2
? isaac_typescript_definitions_1.PickupPrice.ONE_HEART_AND_TWO_SOUL_HEARTS
: isaac_typescript_definitions_1.PickupPrice.TWO_HEARTS;
return itemConfigItem.DevilPrice === 2
? twoHeartPrice
: isaac_typescript_definitions_1.PickupPrice.ONE_HEART;
}
/**
* Helper function to get the path to a collectible PNG file. Returns the path to the question mark
* sprite (i.e. from Curse of the Blind) if the provided collectible type was not valid.
*
* If you intentionally want the path to the question mark sprite, pass -1 as the collectible type.
*
* Note that this does not return the file name, but the full path to the collectible's PNG file.
* The function is named "GfxFilename" to correspond to the associated `ItemConfigItem.GfxFileName`
* field.
*/
function getCollectibleGfxFilename(collectibleOrCollectibleType) {
if (collectibleOrCollectibleType === -1) {
return constants_1.BLIND_ITEM_PNG_PATH;
}
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleGfxFilename");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return constants_1.BLIND_ITEM_PNG_PATH;
}
return itemConfigItem.GfxFileName;
}
/**
* Helper function to get the initial amount of charges that a collectible has. In most cases, when
* picking up an active collectible for the first time, it will be fully charged, which corresponds
* to an `InitCharge` value of -1. However, in some cases, this may be different. For example,
* Eden's Soul starts without any charges, so it has an `InitCharge` value of 0.
*
* This function returns 0 if the provided collectible type was not valid. This function returns -1
* if the provided collectible type was not an active collectible.
*/
function getCollectibleInitCharge(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleInitCharge");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return 0;
}
return itemConfigItem.InitCharge;
}
/**
* Helper function to get the `ItemType` of a collectible. Returns `ItemType.ITEM_NULL` if the
* provided collectible type was not valid.
*/
function getCollectibleItemType(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleItemType");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return isaac_typescript_definitions_1.ItemType.NULL;
}
return itemConfigItem.Type;
}
/**
* Helper function to get the maximum amount of charges that a collectible has. Returns 0 if the
* provided collectible type was not valid.
*/
function getCollectibleMaxCharges(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleMaxCharges");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return 0;
}
return itemConfigItem.MaxCharges;
}
/**
* Helper function to get the name of a collectible. Returns "Unknown" if the provided collectible
* type is not valid.
*
* This function works for both vanilla and modded collectibles.
*
* For example, `getCollectibleName(CollectibleType.SAD_ONION)` would return "Sad Onion".
*/
function getCollectibleName(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleName");
// "ItemConfigItem.Name" is bugged with vanilla items on patch v1.7.6, so we use a hard-coded map
// as a workaround.
const collectibleName = collectibleNames_1.COLLECTIBLE_NAMES[collectibleType];
if (collectibleName !== undefined) {
return collectibleName;
}
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem !== undefined) {
return itemConfigItem.Name;
}
return collectibleNames_1.DEFAULT_COLLECTIBLE_NAME;
}
/**
* Helper function to get the "pedestal type" of a collectible. For example, it might be sitting on
* top of a broken Blood Donation Machine, or it might be sitting on top of an opened Spiked Chest.
*/
function getCollectiblePedestalType(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "getCollectiblePedestalType" function was given a non-collectible: ${entityID}`);
}
const sprite = collectible.GetSprite();
return sprite.GetOverlayFrame();
}
/**
* Helper function to get a collectible's quality, which ranges from 0 to 4 (inclusive). For
* example, Mom's Knife has a quality of 4. Returns 0 if the provided collectible type was not
* valid.
*/
function getCollectibleQuality(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleQuality");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
if (itemConfigItem === undefined) {
return 0;
}
return itemConfigItem.Quality;
}
/**
* Helper function to get the tags of a collectible (which is the composition of zero or more
* `ItemConfigTag`). Returns 0 if the provided collectible type is not valid.
*
* For example:
*
* ```ts
* const collectibleType = CollectibleType.SAD_ONION;
* const itemConfigTags = getCollectibleTags(collectibleType); // itemConfigTags is "18350080"
* ```
*/
function getCollectibleTags(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "getCollectibleTags");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
return itemConfigItem === undefined ? isaac_typescript_definitions_1.ItemConfigTagZero : itemConfigItem.Tags;
}
/**
* Returns an array containing every vanilla collectible type with the given quality.
*
* Note that this function will only return vanilla collectible types. To handle modded collectible
* types, use the `getCollectibleTypesOfQuality` helper function instead.
*/
function getVanillaCollectibleTypesOfQuality(quality) {
const collectibleTypes = QUALITY_TO_VANILLA_COLLECTIBLE_TYPES_MAP.get(quality);
(0, utils_1.assertDefined)(collectibleTypes, `Failed to find the vanilla collectible types corresponding to quality: ${quality}`);
return collectibleTypes;
}
/** Returns true if the item type in the item config is equal to `ItemType.ACTIVE`. */
function isActiveCollectible(collectibleType) {
const itemType = getCollectibleItemType(collectibleType);
return itemType === isaac_typescript_definitions_1.ItemType.ACTIVE;
}
/**
* Returns true if the collectible has a red question mark sprite.
*
* Note that this function will not work properly in a render callback with the `RenderMode` set to
* `RenderMode.WATER_REFLECT`. If this is detected, this function will throw a run-time error.
*/
function isBlindCollectible(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "isBlindCollectible" function was given a non-collectible: ${entityID}`);
}
const room = cachedClasses_1.game.GetRoom();
const renderMode = room.GetRenderMode();
if (renderMode === isaac_typescript_definitions_1.RenderMode.WATER_REFLECT) {
error('The "isBlindCollectible" function will not work properly in a render callback with the render mode equal to "RenderMode.WATER_REFLECT". Make sure that you properly account for this case if you are calling this function in a render callback.');
}
const sprite = collectible.GetSprite();
const animation = sprite.GetAnimation();
const frame = sprite.GetFrame();
questionMarkSprite.SetFrame(animation, frame);
return collectibleSpriteEquals(sprite, questionMarkSprite);
}
/** Returns true if the item type in the item config is equal to `ItemType.FAMILIAR`. */
function isFamiliarCollectible(collectibleType) {
const itemType = getCollectibleItemType(collectibleType);
return itemType === isaac_typescript_definitions_1.ItemType.FAMILIAR;
}
/**
* Returns whether the given collectible is a "glitched" item. All items are replaced by glitched
* items once a player has TMTRAINER. However, glitched items can also "naturally" appear in secret
* rooms and I AM ERROR rooms if the "Corrupted Data" achievement is unlocked.
*
* Under the hood, this checks if the sub-type of the collectible is greater than 4,000,000,000.
*/
function isGlitchedCollectible(collectible) {
return (collectible.Variant === isaac_typescript_definitions_1.PickupVariant.COLLECTIBLE
&& collectible.SubType > GLITCHED_ITEM_THRESHOLD);
}
/**
* Returns true if the collectible has the "Hidden" attribute in the item config.
*
* Hidden collectibles will not show up in any pools and Eden will not start with them.
*/
function isHiddenCollectible(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "isHiddenCollectible");
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(collectibleType);
return itemConfigItem !== undefined && itemConfigItem.Hidden;
}
function isModdedCollectibleType(collectibleType) {
return !isVanillaCollectibleType(collectibleType);
}
/**
* Returns true if the item type in the item config is equal to `ItemType.ITEM_PASSIVE` or
* `ItemType.ITEM_FAMILIAR`.
*/
function isPassiveOrFamiliarCollectible(collectibleOrCollectibleType) {
const collectibleType = getCollectibleTypeFromArg(collectibleOrCollectibleType, "isPassiveCollectible");
const itemType = getCollectibleItemType(collectibleType);
return itemType === isaac_typescript_definitions_1.ItemType.PASSIVE || itemType === isaac_typescript_definitions_1.ItemType.FAMILIAR;
}
/** Helper function to check if a collectible type is a particular quality. */
function isQuality(collectibleOrCollectibleType, quality) {
const actualQuality = getCollectibleQuality(collectibleOrCollectibleType);
return quality === actualQuality;
}
/**
* Helper function to determine if a particular collectible will disappear from the player's
* inventory upon use. Note that this will not work will modded collectibles, as there is no way to
* dynamically know if a modded collectible will disappear.
*/
function isSingleUseCollectible(collectibleType) {
return singleUseActiveCollectibleTypesSet_1.SINGLE_USE_ACTIVE_COLLECTIBLE_TYPES_SET.has(collectibleType);
}
function isValidCollectibleType(collectibleType) {
const potentialCollectibleType = (0, types_1.asCollectibleType)(collectibleType);
const itemConfigItem = cachedClasses_1.itemConfig.GetCollectible(potentialCollectibleType);
return itemConfigItem !== undefined;
}
function isVanillaCollectibleType(collectibleType) {
return collectibleType <= constantsFirstLast_1.LAST_VANILLA_COLLECTIBLE_TYPE;
}
/**
* Helper function to generate a new sprite based on a collectible. If the provided collectible type
* is invalid, a sprite with a Curse of the Blind question mark will be returned.
*
* If you intentionally want a question mark sprite, pass -1 as the collectible type.
*/
function newCollectibleSprite(collectibleType) {
const sprite = Sprite();
sprite.Load(COLLECTIBLE_ANM2_PATH, false);
// We want to clear the pedestal layers so that the returned sprite only has the collectible
// image. We can't use the `Sprite.Reset` method for this purpose because that would unload the
// anm2 file.
(0, sprites_1.clearSprite)(sprite);
const gfxFileName = getCollectibleGfxFilename(collectibleType);
sprite.ReplaceSpritesheet(isaac_typescript_definitions_1.CollectibleSpriteLayer.HEAD, gfxFileName);
sprite.LoadGraphics();
const defaultAnimation = sprite.GetDefaultAnimation();
sprite.Play(defaultAnimation, true);
return sprite;
}
/**
* Helper function to remove the rotation behavior from a collectible. This will happen by default
* when collectibles are spawned when playing as Tainted Isaac or when having Binge Eater.
*
* Under the hood, this is accomplished by morphing the collectible with the `ignoreModifiers`
* argument set to true.
*/
function preventCollectibleRotation(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "preventCollectibleRotation" function was given a non-collectible: ${entityID}`);
}
collectible.Morph(collectible.Type, collectible.Variant, collectible.SubType, true, true, true);
}
/**
* Helper function to remove all pickup delay on a collectible. By default, collectibles have a 20
* frame delay before they can be picked up by a player.
*/
function removeCollectiblePickupDelay(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "removeCollectiblePickupDelay" function was given a non-collectible: ${entityID}`);
}
collectible.Wait = 0;
}
/**
* Helper function to set a collectible sprite to a question mark (i.e. how collectibles look when
* the player has Curse of the Blind).
*/
function setCollectibleBlind(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectibleBlind" function was given a non-collectible: ${entityID}`);
}
setCollectibleSprite(collectible, constants_1.BLIND_ITEM_PNG_PATH);
}
/**
* Helper function to remove the collectible from a collectible pedestal and make it appear as if a
* player has already taken the item. This is accomplished by changing the sub-type to
* `CollectibleType.NULL` and then setting the sprite to an empty/missing PNG file.
*
* For more information, see the documentation for the "clearSprite" helper function.
*/
function setCollectibleEmpty(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectibleEmpty" function was given a non-collectible: ${entityID}`);
}
collectible.SubType = isaac_typescript_definitions_1.CollectibleType.NULL;
clearCollectibleSprite(collectible);
}
/**
* Helper function to change a collectible into a "glitched" item (like the ones that appear when
* the player has TMTRAINER).
*/
function setCollectibleGlitched(collectible) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectibleGlitched" function was given a non-collectible: ${entityID}`);
}
// We need to generate a new glitched item. Thus, we temporarily give the player TMTRAINER, if
// necessary.
const player = Isaac.GetPlayer();
const hasTMTRAINER = player.HasCollectible(isaac_typescript_definitions_1.CollectibleType.TMTRAINER);
if (!hasTMTRAINER) {
player.AddCollectible(isaac_typescript_definitions_1.CollectibleType.TMTRAINER, 0, false);
}
const itemPool = cachedClasses_1.game.GetItemPool();
const collectibleType = itemPool.GetCollectible(constants_1.DEFAULT_ITEM_POOL_TYPE);
setCollectibleSubType(collectible, collectibleType);
if (!hasTMTRAINER) {
player.RemoveCollectible(isaac_typescript_definitions_1.CollectibleType.TMTRAINER);
}
}
/**
* Helper function to set the "pedestal type" of a collectible. For example, it might be sitting on
* top of a broken Blood Donation Machine and you want to change it to be sitting on top of an
* opened Spiked Chest.
*/
function setCollectiblePedestalType(collectible, collectiblePedestalType) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectiblePedestalType" function was given a non-collectible: ${entityID}`);
}
const sprite = collectible.GetSprite();
const overlayAnimation = sprite.GetOverlayAnimation();
sprite.SetOverlayFrame(overlayAnimation, collectiblePedestalType);
}
/**
* Helper function to change the sprite of a collectible pedestal entity.
*
* For more information about removing the collectible sprite, see the documentation for the
* "clearSprite" helper function.
*
* @param collectible The collectible whose sprite you want to modify.
* @param pngPath Equal to either the spritesheet path to load (e.g.
* "gfx/items/collectibles/collectibles_001_thesadonion.png") or undefined. If
* undefined, the sprite will be removed, making it appear like the collectible has
* already been taken by the player.
*/
function setCollectibleSprite(collectible, pngPath) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectibleSprite" function was given a non-collectible: ${entityID}`);
}
const sprite = collectible.GetSprite();
if (pngPath === undefined) {
// We want to remove the little circle that appears on top of the pedestal, which is why we also
// clear `CollectibleSpriteLayer.ITEM_SHADOW`.
(0, sprites_1.clearSprite)(sprite, isaac_typescript_definitions_1.CollectibleSpriteLayer.HEAD, isaac_typescript_definitions_1.CollectibleSpriteLayer.ITEM_SHADOW);
}
else {
sprite.ReplaceSpritesheet(isaac_typescript_definitions_1.CollectibleSpriteLayer.HEAD, pngPath);
sprite.LoadGraphics();
}
}
/**
* Helper function to change the collectible on a pedestal. Simply updating the `SubType` field is
* not sufficient because the sprite will not change.
*/
function setCollectibleSubType(collectible, newCollectibleType) {
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "setCollectibleSubType" function was given a non-collectible: ${entityID}`);
}
// You cannot morph a pedestal to "CollectibleType.NULL"; it would instead create a new random
// collectible item.
if (newCollectibleType === isaac_typescript_definitions_1.CollectibleType.NULL) {
setCollectibleEmpty(collectible);
return;
}
// The naive way to change a collectible's sub-type is to set it directly. However, doing this
// will not update the sprite. Manually updating the sprite works in most situations, but does not
// work when the pedestal is empty. Instead, we can simply morph the collectible, which seems to
// work in all situations.
collectible.Morph(isaac_typescript_definitions_1.EntityType.PICKUP, isaac_typescript_definitions_1.PickupVariant.COLLECTIBLE, newCollectibleType, true, true, true);
}
/**
* Helper function to put a message in the log.txt file to let the Rebirth Item Tracker know that
* the build has been rerolled.
*/
function setCollectiblesRerolledForItemTracker() {
// This cannot use the "log" function since the prefix will prevent the Rebirth Item Tracker from
// recognizing the message. The number here does not matter since the tracker does not check for a
// specific number.
Isaac.DebugString("Added 3 Collectibles");
}
function getCollectibleTypeFromArg(collectibleOrCollectibleType, functionName) {
if ((0, types_1.isInteger)(collectibleOrCollectibleType)) {
return collectibleOrCollectibleType;
}
const collectible = collectibleOrCollectibleType;
if (!(0, pickupVariants_1.isCollectible)(collectible)) {
const entityID = (0, entities_1.getEntityID)(collectible);
error(`The "${functionName}" function was given a non-collectible: ${entityID}`);
}
return collectible.SubType;
}