"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setUnseeded = exports.setRunSeed = exports.restart = exports.onVictoryLap = exports.onSetSeed = exports.getSeedEffects = exports.anySeedEffectEnabled = exports.anyEasterEggEnabled = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const cachedClasses_1 = require("../core/cachedClasses");
const characters_1 = require("./characters");
const log_1 = require("./log");
const types_1 = require("./types");
/** Alias for the `anySeedEffectEnabled` function. */
function anyEasterEggEnabled(exceptions) {
    return anySeedEffectEnabled(exceptions);
}
exports.anyEasterEggEnabled = anyEasterEggEnabled;
/**
 * Helper function to see if any seed effects (i.e. Easter Eggs) are enabled for the current run.
 *
 * @param exceptions Optional. An array of seed effects to ignore.
 */
function anySeedEffectEnabled(exceptions) {
    const seeds = cachedClasses_1.game.GetSeeds();
    if (exceptions === undefined) {
        const numSeedEffects = seeds.CountSeedEffects();
        return numSeedEffects > 0;
    }
    const exceptionsSet = new Set(exceptions);
    return cachedEnumValues_1.SEED_EFFECTS.some((seedEffect) => seeds.HasSeedEffect(seedEffect) && !exceptionsSet.has(seedEffect));
}
exports.anySeedEffectEnabled = anySeedEffectEnabled;
/**
 * Helper function to get the seed effects (i.e. Easter Eggs) that are enabled for the current run.
 */
function getSeedEffects() {
    const seeds = cachedClasses_1.game.GetSeeds();
    return cachedEnumValues_1.SEED_EFFECTS.filter((seedEffect) => seedEffect !== isaac_typescript_definitions_1.SeedEffect.NORMAL && seeds.HasSeedEffect(seedEffect));
}
exports.getSeedEffects = getSeedEffects;
/**
 * Helper function to check whether the player is playing on a set seed (i.e. that they entered in a
 * specific seed by pressing tab on the character selection screen). When the player resets the game
 * on a set seed, the game will not switch to a different seed.
 *
 * Under the hood, this checks if the current challenge is `Challenge.NULL` and the
 * `Seeds.IsCustomRun` method.
 */
function onSetSeed() {
    const seeds = cachedClasses_1.game.GetSeeds();
    const customRun = seeds.IsCustomRun();
    const challenge = Isaac.GetChallenge();
    return challenge === isaac_typescript_definitions_1.Challenge.NULL && customRun;
}
exports.onSetSeed = onSetSeed;
/**
 * Helper function to check whether the player is on a Victory Lap (i.e. they answered "yes" to the
 * popup that happens after defeating The Lamb).
 */
function onVictoryLap() {
    const numVictoryLaps = cachedClasses_1.game.GetVictoryLap();
    return numVictoryLaps > 0;
}
exports.onVictoryLap = onVictoryLap;
/**
 * Helper function to restart the run using the console command of "restart". If the player is
 * playing a seeded run, then it will restart the game to the beginning of the seed. Otherwise, it
 * will put the player on a run with an entirely new seed.
 *
 * You can optionally specify a `PlayerType` to restart the game as that character.
 */
function restart(character) {
    if (character === undefined) {
        const command = "restart";
        (0, log_1.log)(`Restarting the run with a console command of: ${command}`);
        Isaac.ExecuteCommand(command);
        return;
    }
    if (character < isaac_typescript_definitions_1.PlayerType.ISAAC) {
        error(`Restarting as a character of ${character} would crash the game.`);
    }
    const command = `restart ${character}`;
    const characterName = (0, characters_1.getCharacterName)(character);
    (0, log_1.log)(`Restarting the run as ${characterName} (${character}) with a console command of: ${command}`);
    Isaac.ExecuteCommand(command);
}
exports.restart = restart;
/**
 * Helper function to restart the run on a particular starting seed.
 *
 * Under the hood, this function executes the `seed` console command.
 *
 * @param startSeedOrStartSeedString Either the numerical start seed (e.g. 268365970) or the start
 *                                 seed string (e.g. "AAJ2 8V9C").
 */
function setRunSeed(startSeedOrStartSeedString) {
    const startSeedString = (0, types_1.isString)(startSeedOrStartSeedString)
        ? startSeedOrStartSeedString
        : Seeds.Seed2String(startSeedOrStartSeedString);
    const command = `seed ${startSeedString}`;
    (0, log_1.log)(`Restarting the run to set a seed with a console command of: ${command}`);
    Isaac.ExecuteCommand(command);
}
exports.setRunSeed = setRunSeed;
/**
 * Helper function to change the run status to that of an unseeded run with a new random seed.
 *
 * This is useful to revert the behavior where playing on a set seed and restarting the game will
 * not take you to a new seed.
 *
 * Under the hood, this function calls the `Seeds.Reset` method and the
 * `Seeds.Restart(Challenge.NULL)` method.
 */
function setUnseeded() {
    const seeds = cachedClasses_1.game.GetSeeds();
    // Invoking the `Seeds.Reset` method will cause the start seed to be set to 0. Subsequently, the
    // `Seeds.GetStartSeed` method will return 0, and can cause crashes (due to RNG objects not being
    // able to handle a seed of 0). It also causes the log to be spammed with: "[ASSERT] - Error: Game
    // Start Seed was not set." Thus, we must immediately re-initialize the game start seed by using
    // the `Seeds.Restart` method.
    seeds.Reset();
    seeds.Restart(isaac_typescript_definitions_1.Challenge.NULL);
}
exports.setUnseeded = setUnseeded;
