"use strict";
// cspell:ignore addcharges
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPosition = exports.getCharge = exports.getChallenge = exports.fool = exports.flight = exports.flies = exports.eternalHearts = exports.errorRoom = exports.effects = exports.dungeon = exports.down = exports.dogma = exports.disableCurses = exports.dirtyBedroom = exports.devilRoom = exports.dd = exports.darkness = exports.damage = exports.dadsNote = exports.d6 = exports.d20 = exports.cursed = exports.crawlSpace = exports.collectible = exports.coins = exports.coin = exports.cleanBedroom = exports.charge = exports.character = exports.chaosCardTears = exports.cc = exports.cards = exports.card = exports.brokenHearts = exports.bossRush = exports.bossRoom = exports.bossNextRoom = exports.boss = exports.boneHearts = exports.bombs = exports.bomb = exports.bm = exports.bloodCharges = exports.blind = exports.blackMarket = exports.blackHearts = exports.bedroom = exports.ascent = exports.angelRoom = exports.addCharges = void 0;
exports.right = exports.reloadRoom = exports.redHearts = exports.position = exports.poopMana = exports.poop = exports.pocket = exports.playSound = exports.planetarium = exports.pills = exports.pill = exports.oneHP = exports.noCurses = exports.music = exports.miniboss = exports.maze = exports.maxHearts = exports.map = exports.mana = exports.luck = exports.lowHP = exports.lost = exports.listGridAll = exports.listGrid = exports.listAll = exports.list = exports.library = exports.left = exports.labyrinth = exports.keys = exports.key = exports.iAmErrorRoom = exports.hush = exports.horse = exports.hitboxes = exports.hearts = exports.gridEntities = exports.gridCosts = exports.grid2 = exports.grid = exports.goldenTrinket = exports.goldenKey = exports.goldenHearts = exports.goldenBomb = exports.goldTrinket = exports.goldKey = exports.goldHearts = exports.goldBomb = exports.gigaBomb = exports.giant = void 0;
exports.xl = exports.warp = exports.up = exports.unseed = exports.unknown = exports.ultraSecretRoom = exports.trinket = exports.treasureRoom = exports.trapdoor = exports.tests = exports.tears = exports.superSecretRoom = exports.startingRoom = exports.startRoom = exports.spikes = exports.speed = exports.spawnTrinketAt = exports.spawnTrinket = exports.spawnGoldenTrinketAt = exports.spawnGoldenTrinket = exports.spawnGoldTrinket = exports.spawnCollectibleAt = exports.spawnCollectible = exports.spam = exports.sounds = exports.sound = exports.soulHearts = exports.soulCharges = exports.smelt = exports.shop = exports.setPosition = exports.setCharges = exports.seeds = exports.seedStick = exports.secretShop = exports.secretRoom = exports.sacrificeRoom = exports.s = exports.runTests = exports.rottenHearts = exports.room = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../../../../arrays/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);
}
exports.addCharges = addCharges;
/**
 * 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);
}
exports.angelRoom = angelRoom;
/** 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.");
}
exports.ascent = ascent;
/** 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.");
}
exports.bedroom = bedroom;
/**
 * 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);
}
exports.blackHearts = blackHearts;
/** Warps to the Black Market for the floor. */
function blackMarket() {
    (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.BLACK_MARKET);
}
exports.blackMarket = blackMarket;
/** 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");
}
exports.blind = 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);
}
exports.bloodCharges = bloodCharges;
/** Alias for the "blackMarket" command. */
function bm() {
    blackMarket();
}
exports.bm = bm;
/**
 * 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);
}
exports.bomb = bomb;
/**
 * 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);
}
exports.bombs = bombs;
/**
 * 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);
}
exports.boneHearts = boneHearts;
/** Alias for the "bossRoom" command. */
function boss() {
    bossRoom();
}
exports.boss = boss;
/** 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);
}
exports.bossNextRoom = bossNextRoom;
/** 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})`);
}
exports.bossRoom = bossRoom;
/** Warps to the Boss Rush for the floor. */
function bossRush() {
    (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.BOSS_RUSH);
}
exports.bossRush = bossRush;
/**
 * 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);
}
exports.brokenHearts = brokenHearts;
/**
 * 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})`);
}
exports.card = card;
/** 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 isaacscript/strict-enums
        }
    }
}
exports.cards = cards;
/** Alias for the "chaosCardTears" command. */
function cc() {
    chaosCardTears();
}
exports.cc = cc;
/**
 * 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");
}
exports.chaosCardTears = chaosCardTears;
/**
 * 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})`);
}
exports.character = character;
/** Alias for the "addCharges" command. */
function charge(params) {
    addCharges(params);
}
exports.charge = charge;
/** Warps to the first Clean Bedroom on the floor. */
function cleanBedroom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.CLEAN_BEDROOM);
}
exports.cleanBedroom = cleanBedroom;
/**
 * 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);
}
exports.coin = coin;
/**
 * 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);
}
exports.coins = coins;
/** Alias for the "spawnCollectible" command. */
function collectible(params) {
    spawnCollectible(params);
}
exports.collectible = collectible;
/** Creates a crawl space next to the player. */
function crawlSpace() {
    (0, subroutines_1.spawnTrapdoorOrCrawlSpace)(false);
}
exports.crawlSpace = crawlSpace;
/** 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");
}
exports.cursed = cursed;
/** Uses the D20. */
function d20() {
    const player = Isaac.GetPlayer();
    (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.D20);
}
exports.d20 = d20;
/** Uses the D6. */
function d6() {
    const player = Isaac.GetPlayer();
    (0, playerCollectibles_1.useActiveItemTemp)(player, isaac_typescript_definitions_1.CollectibleType.D6);
}
exports.d6 = 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();
}
exports.dadsNote = dadsNote;
/**
 * 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");
}
exports.damage = 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");
}
exports.darkness = darkness;
/** Alias for the "devil" command. */
function dd() {
    devilRoom();
}
exports.dd = dd;
/**
 * 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);
}
exports.devilRoom = devilRoom;
/** Warps to the first Dirty Bedroom on the floor. */
function dirtyBedroom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.DIRTY_BEDROOM);
}
exports.dirtyBedroom = dirtyBedroom;
/** 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");
}
exports.disableCurses = disableCurses;
/** 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);
}
exports.dogma = dogma;
/** 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);
}
exports.down = 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);
}
exports.dungeon = 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.');
}
exports.effects = effects;
/** Alias for the "iAmError" command. */
function errorRoom() {
    iAmErrorRoom();
}
exports.errorRoom = errorRoom;
/**
 * 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);
}
exports.eternalHearts = eternalHearts;
/** 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);
}
exports.flies = flies;
/** 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");
}
exports.flight = flight;
/** Alias for the "startingRoom" command. */
function fool() {
    startingRoom();
}
exports.fool = fool;
/** 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}`);
}
exports.getChallenge = getChallenge;
/** 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}`);
}
exports.getCharge = getCharge;
/** 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})`);
    }
}
exports.getPosition = getPosition;
/** 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");
}
exports.giant = 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);
}
exports.gigaBomb = gigaBomb;
/** Alias for the "goldenBomb" command. */
function goldBomb() {
    goldenBomb();
}
exports.goldBomb = goldBomb;
/** Alias for the "goldenHearts" command. */
function goldHearts(params) {
    goldenHearts(params);
}
exports.goldHearts = goldHearts;
/** Alias for the "goldenKey" command. */
function goldKey() {
    goldenKey();
}
exports.goldKey = goldKey;
/** Alias for the "spawnGoldenTrinket" command. */
function goldTrinket(params) {
    spawnGoldenTrinket(params);
}
exports.goldTrinket = goldTrinket;
/** Gives the player a golden bomb. */
function goldenBomb() {
    const player = Isaac.GetPlayer();
    player.AddGoldenBomb();
}
exports.goldenBomb = goldenBomb;
/**
 * 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);
}
exports.goldenHearts = goldenHearts;
/** Gives the player a golden key. */
function goldenKey() {
    const player = Isaac.GetPlayer();
    player.AddGoldenKey();
}
exports.goldenKey = goldenKey;
/** Alias for the "spawnGoldenTrinket" command. */
function goldenTrinket(params) {
    spawnGoldenTrinket(params);
}
exports.goldenTrinket = goldenTrinket;
/**
 * 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");
}
exports.grid = grid;
/** Alias for the "gridCosts" command. */
function grid2() {
    gridCosts();
}
exports.grid2 = grid2;
/** Alias for the "debug 2" command. Useful for seeing the grid costs of each tile in the room. */
function gridCosts() {
    Isaac.ExecuteCommand("debug 2");
}
exports.gridCosts = gridCosts;
/** 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);
        }
    }
}
exports.gridEntities = gridEntities;
/**
 * 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);
}
exports.hearts = hearts;
/** Alias for the "debug 6" command. */
function hitboxes() {
    Isaac.ExecuteCommand("debug 6");
}
exports.hitboxes = hitboxes;
/** The same thing as the `pill` command, but gives a horse pill instead of a normal pill. */
function horse(params) {
    pill(params, true);
}
exports.horse = horse;
/** 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();
}
exports.hush = hush;
/** Warps to the I AM ERROR room for the floor. */
function iAmErrorRoom() {
    (0, rooms_1.changeRoom)(isaac_typescript_definitions_1.GridRoom.ERROR);
}
exports.iAmErrorRoom = iAmErrorRoom;
/**
 * 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);
}
exports.key = key;
/**
 * 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);
}
exports.keys = keys;
/** 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");
}
exports.labyrinth = 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);
}
exports.left = left;
/** Warps to the first Library on the floor. */
function library() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.LIBRARY);
}
exports.library = 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);
}
exports.list = list;
/**
 * 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);
}
exports.listAll = listAll;
/**
 * 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);
}
exports.listGrid = listGrid;
/**
 * 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);
}
exports.listGridAll = listGridAll;
/** 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");
}
exports.lost = lost;
/** Alias for the "1hp" command. */
function lowHP() {
    oneHP();
}
exports.lowHP = lowHP;
/** Alias for "debug 9". */
function luck() {
    Isaac.ExecuteCommand("debug 9");
}
exports.luck = luck;
/** Alias for the "poopMana" command. */
function mana(params) {
    poopMana(params);
}
exports.mana = mana;
/** 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();
}
exports.map = map;
/**
 * 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);
}
exports.maxHearts = maxHearts;
/** 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");
}
exports.maze = maze;
/** Warps to the first Miniboss Room on the floor. */
function miniboss() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.MINI_BOSS);
}
exports.miniboss = miniboss;
/** 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.');
}
exports.music = music;
/** Alias for the "disableCurses" command. */
function noCurses() {
    disableCurses();
}
exports.noCurses = noCurses;
/** 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.");
}
exports.oneHP = oneHP;
/**
 * 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})`);
    }
}
exports.pill = pill;
/** 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 isaacscript/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 isaacscript/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);
}
exports.pills = pills;
/** Warps to the first Planetarium on the floor. */
function planetarium() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.PLANETARIUM);
}
exports.planetarium = planetarium;
/** Alias for the "sound" command. */
function playSound(params) {
    sound(params);
}
exports.playSound = playSound;
/** 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);
}
exports.pocket = 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);
}
exports.poop = poop;
/**
 * 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);
}
exports.poopMana = poopMana;
/** Alias for the "getPosition" command. */
function position() {
    getPosition();
}
exports.position = position;
/** Alias for the "hearts" command. */
function redHearts(params) {
    hearts(params);
}
exports.redHearts = redHearts;
/** Starts a room transition to the same room that you are already in. */
function reloadRoom() {
    (0, roomTransition_1.reloadRoom)();
}
exports.reloadRoom = 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);
}
exports.right = 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.');
}
exports.room = room;
/**
 * 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);
}
exports.rottenHearts = rottenHearts;
/**
 * 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)();
}
exports.runTests = runTests;
/**
 * 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}`);
}
exports.s = s;
/** Warps to the first Sacrifice Room on the floor. */
function sacrificeRoom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SACRIFICE);
}
exports.sacrificeRoom = sacrificeRoom;
/** Warps to the first Secret Room on the floor. */
function secretRoom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SECRET);
}
exports.secretRoom = secretRoom;
/** 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);
}
exports.secretShop = secretShop;
/** 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}`);
}
exports.seedStick = seedStick;
/** 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.');
}
exports.seeds = seeds;
/**
 * 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);
}
exports.setCharges = setCharges;
/**
 * 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;
}
exports.setPosition = setPosition;
/** Warps to the first shop on the floor. */
function shop() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SHOP);
}
exports.shop = 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);
}
exports.smelt = smelt;
/**
 * 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);
}
exports.soulCharges = soulCharges;
/**
 * 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);
}
exports.soulHearts = soulHearts;
/**
 * 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);
}
exports.sound = sound;
/** 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.');
}
exports.sounds = sounds;
/**
 * 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");
}
exports.spam = spam;
/**
 * 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);
}
exports.spawnCollectible = spawnCollectible;
/**
 * 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);
}
exports.spawnCollectibleAt = spawnCollectibleAt;
/** Alias for the `spawnGoldenTrinket` command. */
function spawnGoldTrinket(params) {
    spawnGoldenTrinket(params);
}
exports.spawnGoldTrinket = spawnGoldTrinket;
/**
 * The same thing as the `spawnTrinket` command but spawns a golden version of the specified
 * trinket.
 */
function spawnGoldenTrinket(params) {
    spawnTrinket(params, true);
}
exports.spawnGoldenTrinket = spawnGoldenTrinket;
/**
 * The same thing as the `spawnTrinketAt` command but spawns a golden version of the specified
 * trinket.
 */
function spawnGoldenTrinketAt(params) {
    spawnTrinketAt(params, true);
}
exports.spawnGoldenTrinketAt = spawnGoldenTrinketAt;
/**
 * Spawns a trinket in the center of the room. You must specify the trinket name or the number
 * corresponding to the trinket type.
 *
 * For example, all of the following commands would spawn the Wiggle Worm trinket:
 *
 * ```text
 * spawnTrinket wiggle worm
 * spawnTrinket wiggle
 * spawnTrinket wig
 * spawnTrinket 10
 * ```
 *
 * Also see the `spawnGoldenTrinket` command.
 */
function spawnTrinket(params, golden = false) {
    if (params === "") {
        print("You must specify the name or number corresponding to the trinket type.");
        return;
    }
    const num = (0, types_1.parseIntSafe)(params);
    let trinketType;
    if (num === undefined) {
        const match = (0, string_1.getMapPartialMatch)(params, trinketNameToTypeMap_1.TRINKET_NAME_TO_TYPE_MAP);
        if (match === undefined) {
            print(`Unknown trinket: ${params}`);
            return;
        }
        trinketType = match[1];
    }
    else {
        if (!(0, trinkets_1.isValidTrinketType)(num)) {
            print(`Invalid trinket type: ${num}`);
            return;
        }
        trinketType = num;
    }
    const roomClass = cachedClasses_1.game.GetRoom();
    const centerPos = roomClass.GetCenterPos();
    const goldenTrinketType = (0, trinkets_1.getGoldenTrinketType)(trinketType);
    const trinketTypeToSpawn = golden ? goldenTrinketType : trinketType;
    (0, pickupsSpecific_1.spawnTrinket)(trinketTypeToSpawn, centerPos);
}
exports.spawnTrinket = spawnTrinket;
/**
 * Spawns a trinket at a specific grid tile location. You must specify the number corresponding to
 * the trinket type and the number corresponding to the grid tile location.
 *
 * For example, this would spawn Wiggle Worm in the top-left corner of a 1x1 room:
 *
 * ```text
 * spawnTrinketAt 10 16
 * ```
 *
 * (You can use the "grid" command to toggle displaying the numerical grid indexes corresponding to
 * a grid tile.)
 */
function spawnTrinketAt(params, golden = false) {
    if (params === "") {
        print("You must specify the number corresponding to the trinket 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 trinket type and the number corresponding to the grid tile location.");
        return;
    }
    const [trinketTypeString, gridIndexString] = args;
    if (trinketTypeString === undefined || gridIndexString === undefined) {
        return;
    }
    const trinketType = (0, types_1.parseIntSafe)(trinketTypeString);
    if (trinketType === undefined || !(0, trinkets_1.isValidTrinketType)(trinketType)) {
        print(`Invalid trinket type: ${trinketTypeString}`);
        return;
    }
    const gridIndex = (0, types_1.parseIntSafe)(gridIndexString);
    if (gridIndex === undefined || gridIndex < 0) {
        print(`Failed to parse the grid index of: ${args[1]}`);
        return;
    }
    const goldenTrinketType = (0, trinkets_1.getGoldenTrinketType)(trinketType);
    const trinketTypeToSpawn = golden ? goldenTrinketType : trinketType;
    (0, pickupsSpecific_1.spawnTrinket)(trinketTypeToSpawn, gridIndex);
}
exports.spawnTrinketAt = spawnTrinketAt;
/**
 * Toggles a set movement speed and flight for the player. You can provide an optional argument to
 * this command in order to set the speed to a specific amount. Default is 2.0 (which is the maximum
 * that the stat can be set to).
 */
function speed(params) {
    const player = Isaac.GetPlayer();
    if (params !== "") {
        const num = tonumber(params); // Can be a float.
        if (num === undefined) {
            print(`Invalid speed amount: ${params}`);
            return;
        }
        v_1.v.persistent.damageAmount = num;
    }
    v_1.v.persistent.speed = !v_1.v.persistent.speed;
    player.AddCacheFlags(isaac_typescript_definitions_1.CacheFlag.SPEED);
    player.EvaluateItems();
    const value = tostring(v_1.v.persistent.speed);
    flight(value);
    (0, console_1.printEnabled)(v_1.v.persistent.speed, "set speed");
}
exports.speed = speed;
/** Creates a spikes grid entity next to the player. */
function spikes() {
    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.SPIKES, tilePosition);
}
exports.spikes = spikes;
/** Alias for the "startingRoom" command. */
function startRoom() {
    startingRoom();
}
exports.startRoom = startRoom;
/** Warps to the starting room of the floor. */
function startingRoom() {
    const level = cachedClasses_1.game.GetLevel();
    const startingRoomIndex = level.GetStartingRoomIndex();
    (0, rooms_1.changeRoom)(startingRoomIndex);
}
exports.startingRoom = startingRoom;
/** Warps to the first Super Secret Room on the floor. */
function superSecretRoom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.SUPER_SECRET);
}
exports.superSecretRoom = superSecretRoom;
/**
 * Toggles a set tear delay (e.g. fire rate) for the player. You can provide an optional argument to
 * this command in order to set the tear delay to a specific amount. Default is 1 (which is
 * equivalent to the Soy Milk tear rate).
 */
function tears(params) {
    if (params !== "") {
        const num = tonumber(params); // Can be a float.
        if (num === undefined) {
            print(`Invalid tear delay amount: ${params}`);
            return;
        }
        v_1.v.persistent.tearsAmount = num;
    }
    v_1.v.persistent.tears = !v_1.v.persistent.tears;
    const player = Isaac.GetPlayer();
    player.AddCacheFlags(isaac_typescript_definitions_1.CacheFlag.FIRE_DELAY);
    player.EvaluateItems();
    (0, console_1.printEnabled)(v_1.v.persistent.damage, "set tear delay");
}
exports.tears = tears;
/** Alias for the "runTests" command. */
function tests() {
    runTests();
}
exports.tests = tests;
/** Creates a trapdoor next to the player. */
function trapdoor() {
    (0, subroutines_1.spawnTrapdoorOrCrawlSpace)(true);
}
exports.trapdoor = trapdoor;
/** Warps to the first Treasure Room on the floor. */
function treasureRoom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.TREASURE);
}
exports.treasureRoom = treasureRoom;
/** Alias for the "spawnTrinket" command. */
function trinket(params) {
    spawnTrinket(params);
}
exports.trinket = trinket;
/** Warps to the first Ultra Secret Room on the floor. */
function ultraSecretRoom() {
    (0, subroutines_1.warpToRoomType)(isaac_typescript_definitions_1.RoomType.ULTRA_SECRET);
}
exports.ultraSecretRoom = ultraSecretRoom;
/** Toggles permanent Curse of the Unknown. */
function unknown() {
    v_1.v.persistent.unknown = !v_1.v.persistent.unknown;
    (0, console_1.printEnabled)(v_1.v.persistent.unknown, "permanent Curse of the Unknown");
}
exports.unknown = unknown;
/** If currently on a set seed, changes to an unseeded state and restarts the game. */
function unseed() {
    if (!(0, run_1.onSetSeed)()) {
        print("You are not on a set seed, so you cannot unseed the run.");
        return;
    }
    (0, run_1.setUnseeded)();
    (0, run_1.restart)();
}
exports.unseed = unseed;
/** Moves the player 0.5 units up. Provide a number to move a custom amount of units. */
function up(params) {
    (0, subroutines_1.movePlayer)(params, isaac_typescript_definitions_1.Direction.UP);
}
exports.up = up;
/**
 * Warps to the specified room type. Accepts either the room type number or the partial name of the
 * room type.
 *
 * For example:
 * - warp 5 - Warps to the first Boss Room on the floor, if any.
 * - warp tr - Warps to the first Treasure Room on the floor, if any.
 */
function warp(params) {
    if (params === "") {
        print("You must specify a room type name or number.");
        return;
    }
    let roomType;
    const num = (0, types_1.parseIntSafe)(params);
    if (num === undefined) {
        const match = (0, string_1.getMapPartialMatch)(params, roomNameToTypeMap_1.ROOM_NAME_TO_TYPE_MAP);
        if (match === undefined) {
            print(`Unknown room type: ${params}`);
            return;
        }
        roomType = match[1];
    }
    else {
        if (!(0, enums_1.isEnumValue)(num, isaac_typescript_definitions_1.RoomType)) {
            print(`Invalid room type: ${num}`);
            return;
        }
        roomType = num;
    }
    (0, subroutines_1.warpToRoomType)(roomType);
}
exports.warp = warp;
/** Alias for the "labyrinth" command. */
function xl() {
    labyrinth();
}
exports.xl = xl;
