UNPKG

isaacscript-common

Version:

Helper functions and features for IsaacScript mods.

1,385 lines • 58.3 kB
"use strict"; // cspell:ignore addcharges Object.defineProperty(exports, "__esModule", { value: true }); exports.addCharges = addCharges; exports.angelRoom = angelRoom; exports.ascent = ascent; exports.bedroom = bedroom; exports.blackHearts = blackHearts; exports.blackMarket = blackMarket; exports.blind = blind; exports.bloodCharges = bloodCharges; exports.bm = bm; exports.bomb = bomb; exports.bombs = bombs; exports.boneHearts = boneHearts; exports.boss = boss; exports.bossNextRoom = bossNextRoom; exports.bossRoom = bossRoom; exports.bossRush = bossRush; exports.brokenHearts = brokenHearts; exports.card = card; exports.cards = cards; exports.cc = cc; exports.chaosCardTears = chaosCardTears; exports.character = character; exports.charge = charge; exports.cleanBedroom = cleanBedroom; exports.coin = coin; exports.coins = coins; exports.collectible = collectible; exports.crawlSpace = crawlSpace; exports.cursed = cursed; exports.d20 = d20; exports.d6 = d6; exports.dadsNote = dadsNote; exports.damage = damage; exports.darkness = darkness; exports.dd = dd; exports.devilRoom = devilRoom; exports.dirtyBedroom = dirtyBedroom; exports.disableCurses = disableCurses; exports.dogma = dogma; exports.down = down; exports.dungeon = dungeon; exports.effects = effects; exports.errorRoom = errorRoom; exports.eternalHearts = eternalHearts; exports.flies = flies; exports.flight = flight; exports.fool = fool; exports.getChallenge = getChallenge; exports.getCharge = getCharge; exports.getPosition = getPosition; exports.giant = giant; exports.gigaBomb = gigaBomb; exports.goldBomb = goldBomb; exports.goldHearts = goldHearts; exports.goldKey = goldKey; exports.goldPill = goldPill; exports.goldTrinket = goldTrinket; exports.goldenBomb = goldenBomb; exports.goldenHearts = goldenHearts; exports.goldenKey = goldenKey; exports.goldenPill = goldenPill; exports.goldenTrinket = goldenTrinket; exports.grid = grid; exports.grid2 = grid2; exports.gridCosts = gridCosts; exports.gridEntities = gridEntities; exports.hearts = hearts; exports.hitboxes = hitboxes; exports.horse = horse; exports.hush = hush; exports.iAmErrorRoom = iAmErrorRoom; exports.key = key; exports.keys = keys; exports.labyrinth = labyrinth; exports.left = left; exports.library = library; exports.list = list; exports.listAll = listAll; exports.listGrid = listGrid; exports.listGridAll = listGridAll; exports.lost = lost; exports.lowHP = lowHP; exports.luck = luck; exports.mana = mana; exports.map = map; exports.maxHearts = maxHearts; exports.maze = maze; exports.megaSatan = megaSatan; exports.miniboss = miniboss; exports.music = music; exports.noCurses = noCurses; exports.oneHP = oneHP; exports.pill = pill; exports.pills = pills; exports.planetarium = planetarium; exports.playSound = playSound; exports.pocket = pocket; exports.poop = poop; exports.poopMana = poopMana; exports.position = position; exports.redHearts = redHearts; exports.reloadRoom = reloadRoom; exports.right = right; exports.room = room; exports.rottenHearts = rottenHearts; exports.runTests = runTests; exports.s = s; exports.sacrificeRoom = sacrificeRoom; exports.secretRoom = secretRoom; exports.secretShop = secretShop; exports.seedStick = seedStick; exports.seeds = seeds; exports.setCharges = setCharges; exports.setPosition = setPosition; exports.shop = shop; exports.smelt = smelt; exports.soulCharges = soulCharges; exports.soulHearts = soulHearts; exports.sound = sound; exports.sounds = sounds; exports.spam = spam; exports.spawnCollectible = spawnCollectible; exports.spawnCollectibleAt = spawnCollectibleAt; exports.spawnGoldTrinket = spawnGoldTrinket; exports.spawnGoldenTrinket = spawnGoldenTrinket; exports.spawnGoldenTrinketAt = spawnGoldenTrinketAt; exports.spawnTrinket = spawnTrinket; exports.spawnTrinketAt = spawnTrinketAt; exports.speed = speed; exports.spikes = spikes; exports.startRoom = startRoom; exports.startingRoom = startingRoom; exports.superSecretRoom = superSecretRoom; exports.tears = tears; exports.tests = tests; exports.trapdoor = trapdoor; exports.treasureRoom = treasureRoom; exports.trinket = trinket; exports.ultraSecretRoom = ultraSecretRoom; exports.unknown = unknown; exports.unseed = unseed; exports.up = up; exports.warp = warp; exports.xl = xl; const isaac_typescript_definitions_1 = require("isaac-typescript-definitions"); const cachedEnumValues_1 = require("../../../../cachedEnumValues"); const cachedClasses_1 = require("../../../../core/cachedClasses"); const constants_1 = require("../../../../core/constants"); const constantsFirstLast_1 = require("../../../../core/constantsFirstLast"); const HealthType_1 = require("../../../../enums/HealthType"); const cards_1 = require("../../../../functions/cards"); const characters_1 = require("../../../../functions/characters"); const charge_1 = require("../../../../functions/charge"); const collectibles_1 = require("../../../../functions/collectibles"); const console_1 = require("../../../../functions/console"); const deepCopyTests_1 = require("../../../../functions/deepCopyTests"); const entitiesSpecific_1 = require("../../../../functions/entitiesSpecific"); const enums_1 = require("../../../../functions/enums"); const flag_1 = require("../../../../functions/flag"); const gridEntities_1 = require("../../../../functions/gridEntities"); const levelGrid_1 = require("../../../../functions/levelGrid"); const logMisc_1 = require("../../../../functions/logMisc"); const mergeTests_1 = require("../../../../functions/mergeTests"); const pickupsSpecific_1 = require("../../../../functions/pickupsSpecific"); const pills_1 = require("../../../../functions/pills"); const playerCollectibles_1 = require("../../../../functions/playerCollectibles"); const playerIndex_1 = require("../../../../functions/playerIndex"); const players_1 = require("../../../../functions/players"); const roomData_1 = require("../../../../functions/roomData"); const roomGrid_1 = require("../../../../functions/roomGrid"); const roomTransition_1 = require("../../../../functions/roomTransition"); const rooms_1 = require("../../../../functions/rooms"); const run_1 = require("../../../../functions/run"); const spawnCollectible_1 = require("../../../../functions/spawnCollectible"); const stage_1 = require("../../../../functions/stage"); const string_1 = require("../../../../functions/string"); const trinkets_1 = require("../../../../functions/trinkets"); const types_1 = require("../../../../functions/types"); const utils_1 = require("../../../../functions/utils"); const cardNameToTypeMap_1 = require("../../../../maps/cardNameToTypeMap"); const characterNameToTypeMap_1 = require("../../../../maps/characterNameToTypeMap"); const collectibleNameToTypeMap_1 = require("../../../../maps/collectibleNameToTypeMap"); const pillNameToEffectMap_1 = require("../../../../maps/pillNameToEffectMap"); const roomNameToTypeMap_1 = require("../../../../maps/roomNameToTypeMap"); const trinketNameToTypeMap_1 = require("../../../../maps/trinketNameToTypeMap"); const roomTypeNames_1 = require("../../../../objects/roomTypeNames"); const subroutines_1 = require("./subroutines"); const v_1 = require("./v"); /** * Adds a single charge to the player's specified active item. You must provide the active slot * number. Provide a second number to give a custom amount of charges. (You can use negative numbers * to remove charge.) */ function addCharges(params) { if (params === "") { print("You must specify a slot number. (Use 0 for the primary slot, 1 for the Schoolbag slot, 2 for the pocket item slot, and 3 for the Dice Bag slot.)"); return; } const args = params.split(" "); if (args.length !== 1 && args.length !== 2) { print(`Invalid amount of arguments: ${args.length}`); return; } const [activeSlotString, numChargeString] = args; if (activeSlotString === undefined) { return; } const activeSlot = (0, types_1.parseIntSafe)(activeSlotString); if (activeSlot === undefined || !(0, enums_1.isEnumValue)(activeSlot, isaac_typescript_definitions_1.ActiveSlot)) { print(`Invalid slot number: ${activeSlot}`); return; } let numCharges = 1; if (numChargeString !== undefined) { const numChargesAttempt = (0, types_1.parseIntSafe)(numChargeString); if (numChargesAttempt === undefined) { print(`Invalid charge amount: ${numChargeString}`); return; } numCharges = numChargesAttempt; } const player = Isaac.GetPlayer(); (0, charge_1.addCharge)(player, activeSlot, numCharges); } /** * Warps to the Angel Room for the floor. If the Devil Room has already been visited or initialized, * this will uninitialize it and make an Angel Room instead. */ function angelRoom() { (0, subroutines_1.devilAngel)(false); } /** Activates the flags for the Ascent (i.e. Backwards Path). */ function ascent() { cachedClasses_1.game.SetStateFlag(isaac_typescript_definitions_1.GameStateFlag.BACKWARDS_PATH_INIT, true); cachedClasses_1.game.SetStateFlag(isaac_typescript_definitions_1.GameStateFlag.BACKWARDS_PATH, true); print("Set Ascent flags."); } /** Warps to the first Clean Bedroom or Dirty Bedroom on the floor. */ function bedroom() { const cleanBedroomGridIndexes = (0, levelGrid_1.getRoomGridIndexesForType)(isaac_typescript_definitions_1.RoomType.CLEAN_BEDROOM); if (cleanBedroomGridIndexes.length > 0) { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.CLEAN_BEDROOM); return; } const dirtyBedroomGridIndexes = (0, levelGrid_1.getRoomGridIndexesForType)(isaac_typescript_definitions_1.RoomType.DIRTY_BEDROOM); if (dirtyBedroomGridIndexes.length > 0) { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.DIRTY_BEDROOM); return; } print("There are no Clean Bedrooms or Dirty Bedrooms on this floor."); } /** * Gives a half black heart. Provide a number to give a custom amount of hearts. (You can use * negative numbers to remove hearts.) */ function blackHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.BLACK); } /** Warps to the Black Market for the floor. */ function blackMarket() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.BLACK_MARKET); } /** Toggles permanent Curse of the Blind. */ function blind() { v_1.v.persistent.blind = !v_1.v.persistent.blind; (0, console_1.printEnabled)(v_1.v.persistent.blind, "permanent Curse of the Blind"); } /** * Gives a blood charge. This only affects Bethany. Provide a number to give a custom amount of * charges. (You can use negative numbers to remove charges.) */ function bloodCharges(params) { let charges = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid charge amount: ${num}`); return; } charges = num; } const player = Isaac.GetPlayer(); player.AddBloodCharge(charges); } /** Alias for the "blackMarket" command. */ function bm() { blackMarket(); } /** * Gives a bomb. Provide a number to give a custom amount of bombs. (You can use negative numbers to * remove bombs.) */ function bomb(params) { let numBombs = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid bomb amount: ${num}`); return; } numBombs = num; } const player = Isaac.GetPlayer(); player.AddBombs(numBombs); } /** * Gives 99 bombs. Provide a number to give a custom amount of bombs. (You can use negative numbers * to remove bombs.) */ function bombs(params) { let numBombs = 99; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid bomb amount: ${num}`); return; } numBombs = num; } const player = Isaac.GetPlayer(); player.AddBombs(numBombs); } /** * Gives a bone heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function boneHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.BONE); } /** Alias for the "bossRoom" command. */ function boss() { bossRoom(); } /** Warps to the room next to the first Boss Room on the floor. */ function bossNextRoom() { (0, subroutines_1.warpNextToRoomType)(isaac_typescript_definitions_1.RoomType.BOSS); } /** Warps to the first Boss Room on the floor (or the Delirium Boss Room if on The Void). */ function bossRoom() { // Most of the logic here is copied from the "warpToRoomType" function. const roomType = isaac_typescript_definitions_1.RoomType.BOSS; const roomGridIndexes = (0, levelGrid_1.getRoomGridIndexesForType)(roomType); let roomGridIndex = roomGridIndexes[0]; if ((0, stage_1.onStage)(isaac_typescript_definitions_1.LevelStage.VOID)) { roomGridIndex = roomGridIndexes.find((thisRoomGridIndex) => (0, roomData_1.getRoomData)(thisRoomGridIndex)?.Subtype === isaac_typescript_definitions_1.BossID.DELIRIUM); } const roomTypeName = roomTypeNames_1.ROOM_TYPE_NAMES[isaac_typescript_definitions_1.RoomType.BOSS]; if (roomGridIndex === undefined) { print(`There are no ${roomTypeName}s on this floor.`); return; } (0, rooms_1.changeRoom)(roomGridIndex); print(`Warped to room type: ${roomTypeName} (${roomType})`); } /** Warps to the Boss Rush for the floor. */ function bossRush() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.BOSS_RUSH); } /** * Gives a broken heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function brokenHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.BROKEN); } /** * Gives the specified card. Accepts either the card type or the partial name of the card. * * For example: * - card 5 - Gives The Emperor. * - card spa - Gives 2 of Spades. */ function card(params) { if (params === "") { print("You must specify a card name or number."); return; } let cardType; const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { const match = (0, string_1.getMapPartialMatch)(params, cardNameToTypeMap_1.CARD_NAME_TO_TYPE_MAP); if (match === undefined) { print(`Unknown card: ${params}`); return; } cardType = match[1]; } else { if (!(0, cards_1.isValidCardType)(num)) { print(`Invalid card type: ${num}`); return; } cardType = num; } const cardName = (0, cards_1.getCardName)(cardType); Isaac.ExecuteCommand(`g k${cardType}`); print(`Gave card: ${cardName} (${cardType})`); } /** Spawns every card on the ground, starting at the top-left-most tile. */ function cards() { let cardType = constantsFirstLast_1.FIRST_CARD_TYPE; for (let y = 0; y <= 6; y++) { for (let x = 0; x <= 12; x++) { if (cardType > constantsFirstLast_1.LAST_VANILLA_CARD_TYPE) { return; } const worldPosition = (0, roomGrid_1.gridCoordinatesToWorldPosition)(x, y); (0, pickupsSpecific_1.spawnCard)(cardType, worldPosition); cardType++; // eslint-disable-line complete/strict-enums } } } /** Alias for the "chaosCardTears" command. */ function cc() { chaosCardTears(); } /** * Toggles Chaos Card tears for the player. Useful for killing enemies very fast without using * "debug 10". */ function chaosCardTears() { v_1.v.persistent.chaosCardTears = !v_1.v.persistent.chaosCardTears; (0, console_1.printEnabled)(v_1.v.persistent.chaosCardTears, "Chaos Card tears"); } /** * Restart as the specified character. Accepts either the character sub-type or the partial name of * the character. * * For example: * - character 2 - Restarts as Cain. * - character ta - Restarts as Tainted Azazel. */ function character(params) { if (params === "") { print("You must specify a character name or number."); return; } let playerType; const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { const match = (0, string_1.getMapPartialMatch)(params, characterNameToTypeMap_1.CHARACTER_NAME_TO_TYPE_MAP); if (match === undefined) { print(`Unknown character: ${params}`); return; } playerType = match[1]; } else { if (!(0, enums_1.isEnumValue)(num, isaac_typescript_definitions_1.PlayerType) || num === isaac_typescript_definitions_1.PlayerType.POSSESSOR) { print(`Invalid character number: ${num}`); return; } playerType = num; } const characterName = (0, characters_1.getCharacterName)(playerType); (0, run_1.restart)(playerType); print(`Restarting as character: ${characterName} (${playerType})`); } /** Alias for the "addCharges" command. */ function charge(params) { addCharges(params); } /** Warps to the first Clean Bedroom on the floor. */ function cleanBedroom() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.CLEAN_BEDROOM); } /** * Gives a coin. Provide a number to give a custom amount of coins. (You can use negative numbers to * remove coins.) */ function coin(params) { let numCoins = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid coin amount: ${num}`); return; } numCoins = num; } const player = Isaac.GetPlayer(); player.AddCoins(numCoins); } /** * Gives 999 coins. Provide a number to give a custom amount of coins. (You can use negative numbers * to remove coins.) */ function coins(params) { let numCoins = 999; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid coin amount: ${num}`); return; } numCoins = num; } const player = Isaac.GetPlayer(); player.AddCoins(numCoins); } /** Alias for the "spawnCollectible" command. */ function collectible(params) { spawnCollectible(params); } /** Creates a crawl space next to the player. */ function crawlSpace() { (0, subroutines_1.spawnTrapdoorOrCrawlSpace)(false); } /** Toggles permanent Curse of the Cursed. */ function cursed() { v_1.v.persistent.cursed = !v_1.v.persistent.cursed; (0, console_1.printEnabled)(v_1.v.persistent.cursed, "permanent Curse of the Cursed"); } /** Uses the D20. */ function d20() { const player = Isaac.GetPlayer(); (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.D20); } /** Uses the D6. */ function d6() { const player = Isaac.GetPlayer(); (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.D6); } /** Warps to the Mausoleum 2 Boss Room that has Dad's Note in it. */ function dadsNote() { cachedClasses_1.game.SetStateFlag(isaac_typescript_definitions_1.GameStateFlag.BACKWARDS_PATH_INIT, true); (0, stage_1.setStage)(isaac_typescript_definitions_1.LevelStage.DEPTHS_2, isaac_typescript_definitions_1.StageType.REPENTANCE); bossRoom(); } /** * Toggles a set damage stat for the player. You can provide an optional argument to this command in * order to set the damage to a specific amount. Default is 500. */ function damage(params) { if (params !== "") { const num = tonumber(params); // Can be a float. if (num === undefined) { print(`Invalid damage amount: ${params}`); return; } v_1.v.persistent.damageAmount = num; } v_1.v.persistent.damage = !v_1.v.persistent.damage; const player = Isaac.GetPlayer(); player.AddCacheFlags(isaac_typescript_definitions_1.CacheFlag.DAMAGE); player.EvaluateItems(); (0, console_1.printEnabled)(v_1.v.persistent.damage, "set damage"); } /** Toggles permanent Curse of Darkness. */ function darkness() { v_1.v.persistent.darkness = !v_1.v.persistent.darkness; (0, console_1.printEnabled)(v_1.v.persistent.darkness, "permanent Curse of Darkness"); } /** Alias for the "devil" command. */ function dd() { devilRoom(); } /** * Warps to the Devil Room for the floor. If the Angel Room has already been visited or initialized, * this will uninitialize it and make an Devil Room instead. */ function devilRoom() { (0, subroutines_1.devilAngel)(true); } /** Warps to the first Dirty Bedroom on the floor. */ function dirtyBedroom() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.DIRTY_BEDROOM); } /** Toggles whether curses can appear. */ function disableCurses() { v_1.v.persistent.disableCurses = !v_1.v.persistent.disableCurses; (0, console_1.printEnabled)(!v_1.v.persistent.disableCurses, "curses"); } /** Warps to the Dogma Boss Room. */ function dogma() { (0, stage_1.setStage)(isaac_typescript_definitions_1.LevelStage.HOME, isaac_typescript_definitions_1.StageType.WRATH_OF_THE_LAMB); (0, rooms_1.changeRoom)(constants_1.DOGMA_ROOM_GRID_INDEX); } /** Moves the player 0.5 units down. Provide a number to move a custom amount of units. */ function down(params) { (0, subroutines_1.movePlayer)(params, isaac_typescript_definitions_1.Direction.DOWN); } /** Warps to the Dungeon (i.e. the crawl space room) for the floor. */ function dungeon() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.DUNGEON); } /** Logs the player's current temporary effects to the "log.txt" file. */ function effects() { const player = Isaac.GetPlayer(); (0, logMisc_1.logPlayerEffects)(player); print('Logged the player\'s effects to the "log.txt" file.'); } /** Alias for the "iAmError" command. */ function errorRoom() { iAmErrorRoom(); } /** * Gives an eternal heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function eternalHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.ETERNAL); } /** Grants the maximum amount of blue flies to the player. */ function flies() { const player = Isaac.GetPlayer(); player.AddBlueFlies(constants_1.MAX_NUM_FAMILIARS, player.Position, undefined); } /** Toggles flight for the player. */ function flight(params) { const player = Isaac.GetPlayer(); v_1.v.persistent.flight = !v_1.v.persistent.flight; // Optionally, allow the toggle to be overridden by a parameter. if (params === "true") { v_1.v.persistent.flight = true; } else if (params === "false") { v_1.v.persistent.flight = false; } player.AddCacheFlags(isaac_typescript_definitions_1.CacheFlag.FLYING); player.EvaluateItems(); const collectibleUsedToShowFlight = isaac_typescript_definitions_1.CollectibleType.FATE; if (v_1.v.persistent.flight) { (0, playerCollectibles_1.addCollectibleCostume)(player, collectibleUsedToShowFlight); } else { (0, playerCollectibles_1.removeCollectibleCostume)(player, collectibleUsedToShowFlight); } (0, console_1.printEnabled)(v_1.v.persistent.flight, "flight"); } /** Alias for the "startingRoom" command. */ function fool() { startingRoom(); } /** Displays the current challenge, if any. */ function getChallenge() { const challenge = Isaac.GetChallenge(); const challengeName = isaac_typescript_definitions_1.Challenge[challenge]; const challengeDescription = // Handle modded challenges. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition challengeName === undefined ? `${challenge} (custom)` : `Challenge.${challengeName} (${challenge})`; print(`The current challenge is: ${challengeDescription}`); } /** Prints the charge for the specified slot. By default, will use `ActiveSlot.PRIMARY`. */ function getCharge(params) { let activeSlot = isaac_typescript_definitions_1.ActiveSlot.PRIMARY; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined || !(0, enums_1.isEnumValue)(num, isaac_typescript_definitions_1.ActiveSlot)) { print(`Invalid slot number: ${params}`); return; } activeSlot = num; } const player = Isaac.GetPlayer(); const totalCharge = (0, charge_1.getTotalCharge)(player, activeSlot); print(`Total charge for ActiveSlot.${isaac_typescript_definitions_1.ActiveSlot[activeSlot]} (${activeSlot}) is: ${totalCharge}`); } /** Prints the current position of all players. */ function getPosition() { for (const player of (0, playerIndex_1.getPlayers)()) { const playerName = (0, players_1.getPlayerName)(player); print(`Player position for ${playerName}: (${player.Position.X}, ${player.Position.Y})`); } } /** Toggles permanent Curse of the Giant. */ function giant() { v_1.v.persistent.giant = !v_1.v.persistent.giant; (0, console_1.printEnabled)(v_1.v.persistent.giant, "permanent Curse of the Giant"); } /** * Gives a Giga Bomb. Provide a number to give a custom amount of Giga Bombs. (You can use negative * numbers to remove bombs.) */ function gigaBomb(params) { let numBombs = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid Giga Bomb amount: ${num}`); return; } numBombs = num; } const player = Isaac.GetPlayer(); player.AddGigaBombs(numBombs); } /** Alias for the "goldenBomb" command. */ function goldBomb() { goldenBomb(); } /** Alias for the "goldenHearts" command. */ function goldHearts(params) { goldenHearts(params); } /** Alias for the "goldenKey" command. */ function goldKey() { goldenKey(); } /** Alias for the "goldenPill" command. */ function goldPill() { goldenPill(); } /** Alias for the "spawnGoldenTrinket" command. */ function goldTrinket(params) { spawnGoldenTrinket(params); } /** Gives the player a golden bomb. */ function goldenBomb() { const player = Isaac.GetPlayer(); player.AddGoldenBomb(); } /** * Gives a golden heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function goldenHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.GOLDEN); } /** Gives the player a golden key. */ function goldenKey() { const player = Isaac.GetPlayer(); player.AddGoldenKey(); } /** Gives the player a golden pill. */ function goldenPill() { const player = Isaac.GetPlayer(); player.AddPill(isaac_typescript_definitions_1.PillColor.GOLD); } /** Alias for the "spawnGoldenTrinket" command. */ function goldenTrinket(params) { spawnGoldenTrinket(params); } /** * Alias for the "debug 11" command. Useful for seeing the coordinates and grid index of each tile * in the room. */ function grid() { Isaac.ExecuteCommand("debug 11"); } /** Alias for the "gridCosts" command. */ function grid2() { gridCosts(); } /** Alias for the "debug 2" command. Useful for seeing the grid costs of each tile in the room. */ function gridCosts() { Isaac.ExecuteCommand("debug 2"); } /** Spawns every grid entity, starting at the top-left-most tile. */ function gridEntities() { let gridEntityTypeIndex = -1; for (let y = 0; y <= 6; y++) { for (let x = 0; x <= 12; x++) { gridEntityTypeIndex++; const gridEntityType = cachedEnumValues_1.GRID_ENTITY_TYPE_VALUES[gridEntityTypeIndex]; if (gridEntityType === undefined) { return; } const worldPosition = (0, roomGrid_1.gridCoordinatesToWorldPosition)(x, y); (0, gridEntities_1.spawnGridEntity)(gridEntityType, worldPosition); } } } /** * Gives a half red heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function hearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.RED); } /** Alias for the "debug 6" command. */ function hitboxes() { Isaac.ExecuteCommand("debug 6"); } /** The same thing as the `pill` command, but gives a horse pill instead of a normal pill. */ function horse(params) { pill(params, true); } /** Warps to the Blue Womb Boss Room. */ function hush() { (0, stage_1.setStage)(isaac_typescript_definitions_1.LevelStage.BLUE_WOMB, isaac_typescript_definitions_1.StageType.ORIGINAL); bossRoom(); } /** Warps to the I AM ERROR room for the floor. */ function iAmErrorRoom() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.ERROR); } /** * Gives a key. Provide a number to give a custom amount of key. (You can use negative numbers to * remove keys.) */ function key(params) { let numKeys = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid key amount: ${num}`); return; } numKeys = num; } const player = Isaac.GetPlayer(); player.AddKeys(numKeys); } /** * Gives 99 keys. Provide a number to give a custom amount of coins. (You can use negative numbers * to remove keys.) */ function keys(params) { let numKeys = 99; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid key amount: ${num}`); return; } numKeys = num; } const player = Isaac.GetPlayer(); player.AddKeys(numKeys); } /** Toggles permanent Curse of the Labyrinth. */ function labyrinth() { v_1.v.persistent.labyrinth = !v_1.v.persistent.labyrinth; (0, console_1.printEnabled)(v_1.v.persistent.labyrinth, "permanent Curse of the Labyrinth"); } /** Moves the player 0.5 units left. Provide a number to move a custom amount of units. */ function left(params) { (0, subroutines_1.movePlayer)(params, isaac_typescript_definitions_1.Direction.LEFT); } /** Warps to the first Library on the floor. */ function library() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.LIBRARY); } /** * Logs the entities in the room to the "log.txt" file. Provide a number to only log that specific * `EntityType`. * * By default, this command will exclude background effects. If that is not desired, use the * "listAll" command instead. */ function list(params) { (0, subroutines_1.listEntities)(params, false); } /** * Logs the entities in the room to the "log.txt" file. Provide a number to only log that specific * `EntityType`. */ function listAll(params) { (0, subroutines_1.listEntities)(params, true); } /** * Logs the grid entities in the room to the "log.txt" file. Provide a number to only log that * specific `GridEntityType`. * * By default, this command will exclude walls. If that is not desired, use the "listGridAll" * command instead. */ function listGrid(params) { (0, subroutines_1.listGridEntities)(params, false); } /** * Logs the grid entities in the room to the "log.txt" file. Provide a number to only log that * specific `GridEntityType`. */ function listGridAll(params) { (0, subroutines_1.listGridEntities)(params, true); } /** Toggles permanent Curse of the Lost. */ function lost() { v_1.v.persistent.lost = !v_1.v.persistent.lost; (0, console_1.printEnabled)(v_1.v.persistent.lost, "permanent Curse of the Lost"); } /** Alias for the "1hp" command. */ function lowHP() { oneHP(); } /** Alias for "debug 9". */ function luck() { Isaac.ExecuteCommand("debug 9"); } /** Alias for the "poopMana" command. */ function mana(params) { poopMana(params); } /** Completely reveals the entire map, including the Ultra Secret Room. */ function map() { const level = cachedClasses_1.game.GetLevel(); const displayFlags = (0, flag_1.addFlag)(isaac_typescript_definitions_1.DisplayFlag.VISIBLE, // 1 << 0 isaac_typescript_definitions_1.DisplayFlag.SHADOW, // 1 << 1 isaac_typescript_definitions_1.DisplayFlag.SHOW_ICON); for (const roomGridIndex of (0, utils_1.iRange)(constants_1.MAX_LEVEL_GRID_INDEX)) { const roomDesc = level.GetRoomByIdx(roomGridIndex); roomDesc.DisplayFlags = displayFlags; } // We must call the "Level.UpdateVisibility" method for the changes to be visible. level.UpdateVisibility(); } /** * Gives a heart container. Provide a number to give a custom amount of heart containers. (You can * use negative numbers to remove heart containers.) */ function maxHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.MAX_HEARTS); } /** Toggles permanent Curse of the Maze. */ function maze() { v_1.v.persistent.maze = !v_1.v.persistent.maze; (0, console_1.printEnabled)(v_1.v.persistent.maze, "permanent Curse of the Maze"); } /** Warps to the Mega Satan room on the floor. (Every floor has a Mega Satan room.) */ function megaSatan() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.MEGA_SATAN); } /** Warps to the first Miniboss Room on the floor. */ function miniboss() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.MINI_BOSS); } /** Logs the currently playing music track to the "log.txt" file. */ function music() { (0, logMisc_1.logMusic)(); print('Logged the currently playing music track to the "log.txt" file.'); } /** Alias for the "disableCurses" command. */ function noCurses() { disableCurses(); } /** Sets every NPC in the room to 1 HP. */ function oneHP() { for (const npc of (0, entitiesSpecific_1.getNPCs)()) { npc.HitPoints = 1; } print("Set every NPC to 1 HP."); } /** * Gives a pill with the specified pill effect. Accepts either the effect ID or the partial name of * the effect. * * For example: * * - `pill 5` - Gives a "Full Health" pill. * - `pill suns` - Gives a "Feels like I'm walking on sunshine" pill. */ function pill(params, isHorse = false) { if (params === "") { print("You must specify a pill name or number."); return; } let pillEffect; const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { const match = (0, string_1.getMapPartialMatch)(params, pillNameToEffectMap_1.PILL_NAME_TO_EFFECT_MAP); if (match === undefined) { print(`Unknown pill effect: ${params}`); return; } pillEffect = match[1]; } else { if (!(0, pills_1.isValidPillEffect)(num)) { print(`Invalid pill effect ID: ${num}`); return; } pillEffect = num; } const pillEffectName = (0, pills_1.getPillEffectName)(pillEffect); Isaac.ExecuteCommand(`g p${pillEffect}`); if (isHorse) { const player = Isaac.GetPlayer(); const pillColor = player.GetPill(isaac_typescript_definitions_1.PocketItemSlot.SLOT_1); const horsePillColor = (0, pills_1.getHorsePillColor)(pillColor); player.SetPill(isaac_typescript_definitions_1.PocketItemSlot.SLOT_1, horsePillColor); } if (isHorse) { print(`Gave horse pill: ${pillEffectName} (${pillEffect})`); } else { print(`Gave pill: ${pillEffectName} (${pillEffect})`); } } /** Spawns every pill on the ground, starting at the top-left-most tile. */ function pills() { let y; let pillColor; y = 1; pillColor = constantsFirstLast_1.FIRST_PILL_COLOR; for (let x = 0; x <= 12; x++) { if (pillColor >= isaac_typescript_definitions_1.PillColor.GOLD) { break; } const worldPosition = (0, roomGrid_1.gridCoordinatesToWorldPosition)(x, y); (0, pickupsSpecific_1.spawnPill)(pillColor, worldPosition); pillColor++; // eslint-disable-line complete/strict-enums } y = 2; pillColor = constantsFirstLast_1.FIRST_HORSE_PILL_COLOR; for (let x = 0; x <= 12; x++) { if (pillColor >= isaac_typescript_definitions_1.PillColor.HORSE_GOLD) { break; } const worldPosition = (0, roomGrid_1.gridCoordinatesToWorldPosition)(x, y); (0, pickupsSpecific_1.spawnPill)(pillColor, worldPosition); pillColor++; // eslint-disable-line complete/strict-enums } y = 3; const worldPosition1 = (0, roomGrid_1.gridCoordinatesToWorldPosition)(0, y); (0, pickupsSpecific_1.spawnPill)(isaac_typescript_definitions_1.PillColor.GOLD, worldPosition1); const worldPosition2 = (0, roomGrid_1.gridCoordinatesToWorldPosition)(1, y); (0, pickupsSpecific_1.spawnPill)(isaac_typescript_definitions_1.PillColor.HORSE_GOLD, worldPosition2); } /** Warps to the first Planetarium on the floor. */ function planetarium() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.PLANETARIUM); } /** Alias for the "sound" command. */ function playSound(params) { sound(params); } /** Sets the player's pocket item to the specified collectible type. */ function pocket(params) { if (params === "") { print("You must supply a collectible type to put as the pocket item."); return; } const collectibleType = (0, types_1.parseIntSafe)(params); if (collectibleType === undefined || !(0, collectibles_1.isValidCollectibleType)(collectibleType)) { print(`Invalid collectible type: ${collectibleType}`); return; } const player = Isaac.GetPlayer(); player.SetPocketActiveItem(collectibleType, isaac_typescript_definitions_1.ActiveSlot.POCKET); } /** Creates a poop grid entity next to the player. */ function poop() { const roomClass = cachedClasses_1.game.GetRoom(); const player = Isaac.GetPlayer(); const tilePosition = roomClass.FindFreeTilePosition(player.Position, 0); (0, gridEntities_1.spawnGridEntity)(isaac_typescript_definitions_1.GridEntityType.POOP, tilePosition); } /** * Gives a poop mana charge. This only affects Tainted Blue Baby. Provide a number to give a custom * amount of charges. (You can use negative numbers to remove charges.) */ function poopMana(params) { let charges = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid mana amount: ${num}`); return; } charges = num; } const player = Isaac.GetPlayer(); player.AddPoopMana(charges); } /** Alias for the "getPosition" command. */ function position() { getPosition(); } /** Alias for the "hearts" command. */ function redHearts(params) { hearts(params); } /** Starts a room transition to the same room that you are already in. */ function reloadRoom() { (0, roomTransition_1.reloadRoom)(); } /** Moves the player 0.5 units right. Provide a number to move a custom amount of units. */ function right(params) { (0, subroutines_1.movePlayer)(params, isaac_typescript_definitions_1.Direction.RIGHT); } /** Logs information about the room to the "log.txt" file. */ function room() { (0, logMisc_1.logRoom)(); print('Logged room information to the "log.txt" file.'); } /** * Gives a rotten heart. Provide a number to give a custom amount of hearts. (You can use negative * numbers to remove hearts.) */ function rottenHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.ROTTEN); } /** * Run the suite of tests that prove that the "deepCopy" helper function and the "merge" function * work properly. For more information, see the `runDeepCopyTests` and the `runMergeTests` * functions. * * In general, running the tests is only useful if you are troubleshooting the save data manager. */ function runTests() { (0, deepCopyTests_1.runDeepCopyTests)(); (0, mergeTests_1.runMergeTests)(); } /** * Alias for the "stage" command. * * For example: * - s 3 - Warps to Caves 1. * - s 1c - Warps to Downpour 1. */ function s(params) { if (params === "") { print("You must specify a stage number."); return; } const finalCharacter = params.slice(-1); let stageString; let stageTypeLetter; if (finalCharacter === "a" || finalCharacter === "b" || finalCharacter === "c" || finalCharacter === "d") { // e.g. "s 11a" for going to The Chest stageString = params.slice(0, -1); stageTypeLetter = finalCharacter; } else { // e.g. "s 11" for going to the Dark Room stageString = params; stageTypeLetter = ""; } const stage = (0, types_1.parseIntSafe)(stageString); if (stage === undefined || !(0, enums_1.isEnumValue)(stage, isaac_typescript_definitions_1.StageType)) { print(`Invalid stage number: ${stage}`); return; } Isaac.ExecuteCommand(`stage ${stage}${stageTypeLetter}`); } /** Warps to the first Sacrifice Room on the floor. */ function sacrificeRoom() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SACRIFICE); } /** Warps to the first Secret Room on the floor. */ function secretRoom() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SECRET); } /** Warps to the Secret Shop that you would normally get to with a Member Card. */ function secretShop() { (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.SECRET_SHOP); } /** Changes to a seeded run, using the seed of the current run. */ function seedStick() { const seedsClass = cachedClasses_1.game.GetSeeds(); const startSeedString = seedsClass.GetStartSeedString(); Isaac.ExecuteCommand(`seed ${startSeedString}`); print(`Sticking to seed: ${startSeedString}`); } /** Logs all of the current run's seed effects to the "log.txt" file. */ function seeds() { (0, logMisc_1.logSeedEffects)(); print('Logged the seed effects to the "log.txt" file.'); } /** * Sets a charge to the player's specified active item. You must provide the active slot number and * the number of charges to set. */ function setCharges(params) { if (params === "") { print("You must specify a slot number and a charge amount. (Use 0 for the primary slot, 1 for the Schoolbag slot, 2 for the pocket item slot, and 3 for the Dice Bag slot.)"); return; } const args = params.split(" "); if (args.length === 1) { print("You must specify the amount of charge to set."); return; } if (args.length !== 2) { print(`Invalid amount of arguments: ${args.length}`); return; } const [activeSlotString, chargeString] = args; if (activeSlotString === undefined || chargeString === undefined) { return; } const activeSlot = (0, types_1.parseIntSafe)(activeSlotString); if (activeSlot === undefined || !(0, enums_1.isEnumValue)(activeSlot, isaac_typescript_definitions_1.ActiveSlot)) { print(`Invalid slot number: ${activeSlotString}`); return; } const chargeNum = (0, types_1.parseIntSafe)(chargeString); if (chargeNum === undefined) { print(`Invalid charge amount: ${chargeString}`); return; } if (chargeNum < 0) { print(`Invalid charge amount: ${chargeNum}`); return; } const player = Isaac.GetPlayer(); player.SetActiveCharge(chargeNum, activeSlot); } /** * Moves the first player to the specified position. * * For example: * - setPosition 100 50 */ function setPosition(params) { if (params === "") { print('You must specify a position. (e.g. "setPosition 100 50")'); return; } const args = params.split(" "); if (args.length !== 2) { print('You must specify a position. (e.g. "setPosition 100 50")'); return; } const [xString, yString] = args; if (xString === undefined || yString === undefined) { return; } const x = (0, types_1.parseIntSafe)(xString); if (x === undefined) { print(`Invalid x value: ${xString}`); return; } const y = (0, types_1.parseIntSafe)(yString); if (y === undefined) { print(`Invalid y value: ${yString}`); return; } const player = Isaac.GetPlayer(); const newPosition = Vector(x, y); player.Position = newPosition; } /** Warps to the first shop on the floor. */ function shop() { (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SHOP); } /** Uses the Smelter to smelt the current player's trinket. */ function smelt() { const player = Isaac.GetPlayer(); (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.SMELTER); } /** * Gives a soul charge. This only affects Tainted Bethany. Provide a number to give a custom amount * of charges. (You can use negative numbers to remove charges.) */ function soulCharges(params) { let charges = 1; if (params !== "") { const num = (0, types_1.parseIntSafe)(params); if (num === undefined) { print(`Invalid charges amount: ${num}`); return; } charges = num; } const player = Isaac.GetPlayer(); player.AddSoulCharge(charges); } /** * Gives a half soul heart. Provide a number to give a custom amount of hearts. (You can use * negative numbers to remove hearts.) */ function soulHearts(params) { (0, subroutines_1.addHeart)(params, HealthType_1.HealthType.SOUL); } /** * Play the supplied sound effect. * * For example: * - sound 1 - Plays the 1-Up sound effect. */ function sound(params) { const soundEffect = (0, types_1.parseIntSafe)(params); if (soundEffect === undefined || !(0, enums_1.isEnumValue)(soundEffect, isaac_typescript_definitions_1.SoundEffect)) { print(`Invalid sound effect ID: ${soundEffect}.`); return; } cachedClasses_1.sfxManager.Play(soundEffect); } /** Logs all of the currently playing sound effects to the "log.txt" file. */ function sounds() { (0, logMisc_1.logSounds)(); print('Logged the currently playing sound effects to the "log.txt" file.'); } /** * Toggles spamming Blood Rights on every frame. Useful for killing enemies very fast without using * "debug 10". */ function spam() { v_1.v.persistent.spamBloodRights = !v_1.v.persistent.spamBloodRights; (0, console_1.printEnabled)(v_1.v.persistent.spamBloodRights, "spamming Blood Rights"); } /** * Spawns a collectible in the center of the room. You must specify the collectible name or the * number corresponding to the collectible type. * * For example, all of the following commands would spawn Spoon Bender: * * ```text * spawnCollectible spoon bender * spawnCollectible spoon * spawnCollectible spo * spawnCollectible 3 * ``` */ function spawnCollectible(params) { if (params === "") { print("You must specify the collectible name or the number corresponding to the collectible type."); return; } const num = (0, types_1.parseIntSafe)(params); let collectibleType; if (num === undefined) { const match = (0, string_1.getMapPartialMatch)(params, collectibleNameToTypeMap_1.COLLECTIBLE_NAME_TO_TYPE_MAP); if (match === undefined) { print(`Unknown collectible: ${params}`); return; } collectibleType = match[1]; } else { if (!(0, collectibles_1.isValidCollectibleType)(num)) { print(`Invalid collectible type: ${num}`); } collectibleType = num; } const roomClass = cachedClasses_1.game.GetRoom(); const centerPos = roomClass.GetCenterPos(); (0, spawnCollectible_1.spawnCollectible)(collectibleType, centerPos, undefined); } /** * Spawns a collectible at a specific grid tile location. You must specify the number corresponding * to the collectible type and the number corresponding to the grid tile location. * * For example, this would spawn Spoon Bender in the top-left corner of a 1x1 room: * * ```text * spawnCollectibleAt 3 16 * ``` * * (You can use the "grid" command to toggle displaying the numerical grid indexes corresponding to * a grid tile.) */ function spawnCollectibleAt(params) { if (params === "") { print("You must specify the number corresponding to the collectible type and the number corresponding to the grid tile location."); return; } const args = params.split(" "); if (args.length !== 2) { print("You must specify the number corresponding to the collectible type and the number corresponding to the grid tile location."); return; } const [collectibleTypeString, gridIndexString] = args; if (collectibleTypeString === undefined || gridIndexString === undefined) { return; } const collectibleType = (0, types_1.parseIntSafe)(collectibleTypeString); if (collectibleType === undefined || !(0, collectibles_1.isValidCollectibleType)(collectibleType)) { print(`Invalid collectible type: ${args[0]}`); return; } const gridIndex = (0, types_1.parseIntSafe)(gridIndexString); if (gridIndex === undefined || gridIndex < 0) { print(`Failed to parse the grid index of: ${args[1]}`); return; } (0, spawnCollectible_1.spawnCollectible)(collectibleType, gridIndex, undefined); } /** Alias for the `spawnGoldenTrinket` command. */ function spawnGoldTrinket(params) { spawnGoldenTrinket(params); } /** * The same thing as the `spawnTrinket` command but spawns a golden version of the specified * trinket. */ function spawnGoldenTrinket(params) { spawnTrinket(params, true); } /** * The same thing as the `spawnTrinketAt` command but spawns a golden version of