isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
211 lines (210 loc) • 9.03 kB
JavaScript
"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);
}