"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.spawnEmptyCollectible = exports.spawnCollectibleFromPool = exports.spawnCollectible = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const constants_1 = require("../core/constants");
const collectibleTag_1 = require("./collectibleTag");
const collectibles_1 = require("./collectibles");
const entitiesSpecific_1 = require("./entitiesSpecific");
const players_1 = require("./players");
const rng_1 = require("./rng");
/**
 * Helper function to spawn a collectible.
 *
 * Use this instead of the `Game.Spawn` method because it handles the cases of Tainted Keeper
 * collectibles costing coins and prevents quest items from being rotated by Tainted Isaac's
 * rotation mechanic.
 *
 * If you want to spawn an unseeded collectible, you must explicitly pass `undefined` to the
 * `seedOrRNG` parameter.
 *
 * @param collectibleType The collectible type to spawn.
 * @param positionOrGridIndex The position or grid index to spawn the collectible at.
 * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
 *                  `RNG.Next` method will be called. If `undefined` is provided, it will default to
 *                  a random seed.
 * @param options Optional. Set to true to make the collectible a "There's Options" style
 *                collectible. Default is false.
 * @param forceFreeItem Optional. Set to true to disable the logic that gives the item a price for
 *                      Tainted Keeper. Default is false.
 * @param spawner Optional.
 */
function spawnCollectible(collectibleType, positionOrGridIndex, seedOrRNG, options = false, forceFreeItem = false, spawner) {
    if (seedOrRNG === undefined) {
        seedOrRNG = (0, rng_1.getRandomSeed)();
    }
    const seed = (0, rng_1.isRNG)(seedOrRNG) ? seedOrRNG.Next() : seedOrRNG;
    const collectible = (0, entitiesSpecific_1.spawnPickupWithSeed)(isaac_typescript_definitions_1.PickupVariant.COLLECTIBLE, collectibleType, positionOrGridIndex, seed, constants_1.VectorZero, spawner);
    if ((0, collectibleTag_1.isQuestCollectible)(collectible)) {
        (0, collectibles_1.preventCollectibleRotation)(collectible);
    }
    if (options) {
        collectible.OptionsPickupIndex = 1;
    }
    if ((0, players_1.anyPlayerIs)(isaac_typescript_definitions_1.PlayerType.KEEPER_B) &&
        !(0, collectibleTag_1.isQuestCollectible)(collectibleType) &&
        !forceFreeItem) {
        // When playing Tainted Keeper, collectibles are supposed to have a price, and manually spawned
        // items will not have a price, so we have to set it manually.
        // Setting the shop item ID in this way prevents the bug where the item will sometimes change to
        // 99 cents.
        collectible.ShopItemId = -1;
        // We can set the price to any arbitrary value; it will auto-update to the true price on the
        // next frame.
        collectible.Price = 15;
    }
    return collectible;
}
exports.spawnCollectible = spawnCollectible;
/**
 * Helper function to spawn a collectible from a specific item pool.
 *
 * Use this instead of the `Game.Spawn` method because it handles the cases of Tainted Keeper
 * collectibles costing coins and prevents quest items from being rotated by Tainted Isaac's
 * rotation mechanic.
 *
 * If you want to spawn an unseeded collectible, you must explicitly pass `undefined` to the
 * `seedOrRNG` parameter.
 *
 * In order to use this function, you must upgrade your mod with `ISCFeature.SPAWN_COLLECTIBLE`.
 *
 * @param itemPoolType The item pool to draw the collectible type from.
 * @param positionOrGridIndex The position or grid index to spawn the collectible at.
 * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
 *                  `RNG.Next` method will be called. If `undefined` is provided, it will default to
 *                  a random seed.
 * @param options Optional. Set to true to make the collectible a "There's Options" style
 *                collectible. Default is false.
 * @param forceFreeItem Optional. Set to true to disable the logic that gives the item a price for
 *                      Tainted Keeper. Default is false.
 * @param spawner Optional.
 */
function spawnCollectibleFromPool(itemPoolType, positionOrGridIndex, seedOrRNG, options = false, forceFreeItem = false, spawner) {
    const itemPool = cachedClasses_1.game.GetItemPool();
    const collectibleType = itemPool.GetCollectible(itemPoolType);
    return spawnCollectible(collectibleType, positionOrGridIndex, seedOrRNG, options, forceFreeItem, spawner);
}
exports.spawnCollectibleFromPool = spawnCollectibleFromPool;
/**
 * Helper function to spawn an empty collectible. Doing this is tricky since spawning a collectible
 * with `CollectibleType.NULL` will result in spawning a collectible with a random type from the
 * current room's item pool.
 *
 * Instead, this function arbitrarily spawns a collectible with `CollectibleType.BROKEN_SHOVEL_1`,
 * and then converts it to an empty pedestal afterward. (Broken Shovel is used instead of e.g. Sad
 * Onion because it is a quest collectible and quest collectibles will prevent Damocles from
 * duplicating the pedestal.)
 *
 * If you want to spawn an unseeded collectible, you must explicitly pass `undefined` to the
 * `seedOrRNG` parameter.
 *
 * @param positionOrGridIndex The position or grid index to spawn the empty collectible at.
 * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
 *                  `RNG.Next` method will be called. If `undefined` is provided, it will default to
 *                  a random seed.
 */
function spawnEmptyCollectible(positionOrGridIndex, seedOrRNG) {
    const collectible = spawnCollectible(isaac_typescript_definitions_1.CollectibleType.BROKEN_SHOVEL_1, positionOrGridIndex, seedOrRNG, false, true);
    (0, collectibles_1.setCollectibleEmpty)(collectible);
    return collectible;
}
exports.spawnEmptyCollectible = spawnEmptyCollectible;
