UNPKG

isaacscript-common

Version:

Helper functions and features for IsaacScript mods.

211 lines (210 loc) • 9.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGoldenTrinketType = getGoldenTrinketType; exports.getMysteriousPaperEffectForFrame = getMysteriousPaperEffectForFrame; exports.getNormalTrinketType = getNormalTrinketType; exports.getTrinketDescription = getTrinketDescription; exports.getTrinketGfxFilename = getTrinketGfxFilename; exports.getTrinketName = getTrinketName; exports.isGoldenTrinketType = isGoldenTrinketType; exports.isModdedTrinketType = isModdedTrinketType; exports.isValidTrinketType = isValidTrinketType; exports.isVanillaTrinketType = isVanillaTrinketType; exports.newTrinketSprite = newTrinketSprite; exports.setTrinketSprite = setTrinketSprite; exports.trinketHasCacheFlag = trinketHasCacheFlag; 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 MysteriousPaperEffect_1 = require("../enums/MysteriousPaperEffect"); const trinketDescriptions_1 = require("../objects/trinketDescriptions"); const trinketNames_1 = require("../objects/trinketNames"); const entities_1 = require("./entities"); const enums_1 = require("./enums"); const flag_1 = require("./flag"); const pickupVariants_1 = require("./pickupVariants"); const sprites_1 = require("./sprites"); const types_1 = require("./types"); /** * Add this to a `TrinketType` to get the corresponding golden trinket type. * * Corresponds to the vanilla `PillColor.TRINKET_GOLDEN_FLAG` value. * * 1 << 15 */ const GOLDEN_TRINKET_ADJUSTMENT = 32_768; const NUM_MYSTERIOUS_PAPER_EFFECTS = (0, enums_1.getEnumLength)(MysteriousPaperEffect_1.MysteriousPaperEffect); const TRINKET_ANM2_PATH = "gfx/005.350_trinket.anm2"; const TRINKET_SPRITE_LAYER = 0; /** * Helper function to get the corresponding golden trinket type from a normal trinket type. * * If the provided trinket type is already a golden trinket type, then the trinket type will be * returned unmodified. * * For example, passing `TrinketType.SWALLOWED_PENNY` would result in 32769, which is the value that * corresponds to the golden trinket sub-type for Swallowed Penny. */ function getGoldenTrinketType(trinketType) { return isGoldenTrinketType(trinketType) ? trinketType : trinketType + GOLDEN_TRINKET_ADJUSTMENT; } /** * Helper function to get the current effect that the Mysterious Paper trinket is providing to the * player. Returns undefined if the player does not have the Mysterious Paper trinket. * * The Mysterious Paper trinket has four different effects: * * - The Polaroid (collectible) * - The Negative (collectible) * - A Missing Page (trinket) * - Missing Poster (trinket) * * It rotates between these four effects on every frame. Note that Mysterious Paper will cause the * `EntityPlayer.HasCollectible` and `EntityPlayer.HasTrinket` methods to return true for the * respective items on the particular frame, with the exception of the Missing Poster. (The player * will never "have" the Missing Poster, even on the correct corresponding frame.) * * @param player The player to look at. * @param frameCount Optional. The frame count that corresponds to time the effect will be active. * Default is the current frame. */ function getMysteriousPaperEffectForFrame(player, frameCount) { frameCount ??= player.FrameCount; if (!player.HasTrinket(isaac_typescript_definitions_1.TrinketType.MYSTERIOUS_PAPER)) { return undefined; } return frameCount % NUM_MYSTERIOUS_PAPER_EFFECTS; } /** * Helper function to get the corresponding normal trinket type from a golden trinket type. * * If the provided trinket type is already a normal trinket type, then the trinket type will be * returned unmodified. */ function getNormalTrinketType(trinketType) { return isGoldenTrinketType(trinketType) ? trinketType - GOLDEN_TRINKET_ADJUSTMENT : trinketType; } /** * Helper function to get the in-game description for a trinket. Returns "Unknown" if the provided * trinket type was not valid. * * This function works for both vanilla and modded trinkets. */ function getTrinketDescription(trinketType) { // "ItemConfigItem.Description" is bugged with vanilla items on patch v1.7.6, so we use a // hard-coded object as a workaround. const trinketDescription = trinketDescriptions_1.TRINKET_DESCRIPTIONS[trinketType]; if (trinketDescription !== undefined) { return trinketDescription; } const itemConfigItem = cachedClasses_1.itemConfig.GetTrinket(trinketType); if (itemConfigItem !== undefined) { return itemConfigItem.Description; } return trinketDescriptions_1.DEFAULT_TRINKET_DESCRIPTION; } /** * Helper function to get the path to a trinket PNG file. Returns the path to the question mark * sprite (i.e. from Curse of the Blind) if the provided trinket type was not valid. * * Note that this does not return the file name, but the full path to the trinket's PNG file. The * function is named "GfxFilename" to correspond to the associated `ItemConfigItem.GfxFileName` * field. */ function getTrinketGfxFilename(trinketType) { const itemConfigItem = cachedClasses_1.itemConfig.GetTrinket(trinketType); if (itemConfigItem === undefined) { return constants_1.BLIND_ITEM_PNG_PATH; } return itemConfigItem.GfxFileName; } /** * Helper function to get the name of a trinket. Returns "Unknown" if the provided trinket type is * not valid. * * This function works for both vanilla and modded trinkets. * * For example, `getTrinketName(TrinketType.SWALLOWED_PENNY)` would return "Swallowed Penny". */ function getTrinketName(trinketType) { // "ItemConfigItem.Name" is bugged with vanilla items on patch v1.7.6, so we use a hard-coded // object as a workaround. const trinketName = trinketNames_1.TRINKET_NAMES[trinketType]; if (trinketName !== undefined) { return trinketName; } const itemConfigItem = cachedClasses_1.itemConfig.GetTrinket(trinketType); if (itemConfigItem !== undefined) { return itemConfigItem.Name; } return trinketNames_1.DEFAULT_TRINKET_NAME; } function isGoldenTrinketType(trinketType) { return (0, types_1.asNumber)(trinketType) > GOLDEN_TRINKET_ADJUSTMENT; } function isModdedTrinketType(trinketType) { return !isVanillaTrinketType(trinketType); } function isValidTrinketType(trinketType) { const potentialTrinketType = (0, types_1.asTrinketType)(trinketType); const itemConfigItem = cachedClasses_1.itemConfig.GetTrinket(potentialTrinketType); return itemConfigItem !== undefined; } function isVanillaTrinketType(trinketType) { return trinketType <= constantsFirstLast_1.LAST_VANILLA_TRINKET_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. */ function newTrinketSprite(trinketType) { const sprite = Sprite(); sprite.Load(TRINKET_ANM2_PATH, false); const gfxFileName = getTrinketGfxFilename(trinketType); sprite.ReplaceSpritesheet(TRINKET_SPRITE_LAYER, gfxFileName); sprite.LoadGraphics(); const defaultAnimation = sprite.GetDefaultAnimation(); sprite.Play(defaultAnimation, true); return sprite; } /** * Helper function to change the sprite of a trinket entity. * * For more information about removing the trinket sprite, see the documentation for the * "clearSprite" helper function. * * @param trinket The trinket whose sprite you want to modify. * @param pngPath Equal to either the spritesheet path to load (e.g. * "gfx/items/trinkets/trinket_001_swallowedpenny.png") or undefined. If undefined, * the sprite will be removed, making the trinket effectively invisible (except for * the shadow underneath it). */ function setTrinketSprite(trinket, pngPath) { if (!(0, pickupVariants_1.isTrinket)(trinket)) { const entityID = (0, entities_1.getEntityID)(trinket); error(`The "setTrinketSprite" function was given a non-trinket: ${entityID}`); } const sprite = trinket.GetSprite(); if (pngPath === undefined) { // We use `clearSpriteLayer` instead of `Sprite.Reset` to maintain parity with the // `setCollectibleSprite` function. (0, sprites_1.clearSprite)(sprite); } else { sprite.ReplaceSpritesheet(TRINKET_SPRITE_LAYER, pngPath); sprite.LoadGraphics(); } } /** Helper function to check in the item config if a given trinket has a given cache flag. */ function trinketHasCacheFlag(trinketType, cacheFlag) { const itemConfigItem = cachedClasses_1.itemConfig.GetTrinket(trinketType); if (itemConfigItem === undefined) { return false; } return (0, flag_1.hasFlag)(itemConfigItem.CacheFlags, cacheFlag); }