"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVanillaCharacter = exports.isModdedCharacter = exports.isMainCharacter = exports.isFlyingCharacter = exports.getMainCharacter = exports.getCharacterStartingTrinketType = exports.getCharacterStartingCollectibleTypes = exports.getCharacterSpritePNGFilePath = exports.getCharacterName = exports.getCharacterMaxHeartContainers = exports.getCharacterDeathAnimationName = exports.getCharacterDamageMultiplier = exports.doesCharacterStartWithActiveItem = exports.doesCharacterGetBlackHeartFromEternalHeart = exports.canCharacterTakeFreeDevilDeals = exports.canCharacterHaveSoulHearts = exports.canCharacterHaveRedHearts = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const constants_1 = require("../core/constants");
const constantsFirstLast_1 = require("../core/constantsFirstLast");
const characterDamageMultipliers_1 = require("../objects/characterDamageMultipliers");
const characterNames_1 = require("../objects/characterNames");
const characterSpritePNGFileNames_1 = require("../objects/characterSpritePNGFileNames");
const characterStartingCollectibleTypes_1 = require("../objects/characterStartingCollectibleTypes");
const characterStartingTrinketTypes_1 = require("../objects/characterStartingTrinketTypes");
const charactersThatStartWithAnActiveItemSet_1 = require("../sets/charactersThatStartWithAnActiveItemSet");
const charactersWithBlackHeartFromEternalHeartSet_1 = require("../sets/charactersWithBlackHeartFromEternalHeartSet");
const charactersWithFreeDevilDealsSet_1 = require("../sets/charactersWithFreeDevilDealsSet");
const charactersWithNoRedHeartsSet_1 = require("../sets/charactersWithNoRedHeartsSet");
const charactersWithNoSoulHeartsSet_1 = require("../sets/charactersWithNoSoulHeartsSet");
const lostStyleCharactersSet_1 = require("../sets/lostStyleCharactersSet");
const ReadonlySet_1 = require("../types/ReadonlySet");
const FLYING_CHARACTERS_SET = new ReadonlySet_1.ReadonlySet(constants_1.FLYING_CHARACTERS);
const MAIN_CHARACTERS_SET = new ReadonlySet_1.ReadonlySet(constants_1.MAIN_CHARACTERS);
const PNG_PATH_PREFIX = "characters/costumes";
/**
 * Helper function to determine if the given character can have red heart containers. Returns true
 * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
 * though coin containers are not technically the same as red heart containers. Returns false for
 * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
 */
function canCharacterHaveRedHearts(character) {
    return !charactersWithNoRedHeartsSet_1.CHARACTERS_WITH_NO_RED_HEARTS_SET.has(character);
}
exports.canCharacterHaveRedHearts = canCharacterHaveRedHearts;
/**
 * Helper function to determine if the given character can have soul hearts. Returns true for
 * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
 * false for The Lost and Tainted Lost.
 */
function canCharacterHaveSoulHearts(character) {
    return !charactersWithNoSoulHeartsSet_1.CHARACTERS_WITH_NO_SOUL_HEARTS_SET.has(character);
}
exports.canCharacterHaveSoulHearts = canCharacterHaveSoulHearts;
/**
 * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
 * Lost, Tainted Lost, etc.)
 */
function canCharacterTakeFreeDevilDeals(character) {
    return charactersWithFreeDevilDealsSet_1.CHARACTERS_WITH_FREE_DEVIL_DEALS_SET.has(character);
}
exports.canCharacterTakeFreeDevilDeals = canCharacterTakeFreeDevilDeals;
/**
 * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
 * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
 * Otherwise, returns false.
 */
function doesCharacterGetBlackHeartFromEternalHeart(character) {
    return charactersWithBlackHeartFromEternalHeartSet_1.CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET.has(character);
}
exports.doesCharacterGetBlackHeartFromEternalHeart = doesCharacterGetBlackHeartFromEternalHeart;
/**
 * Helper function to determine if the specified character starts with an active item.
 *
 * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
 * is considered to starts with the D6, but this is not the case on a brand new save file).
 */
function doesCharacterStartWithActiveItem(character) {
    return charactersThatStartWithAnActiveItemSet_1.CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET.has(character);
}
exports.doesCharacterStartWithActiveItem = doesCharacterStartWithActiveItem;
/**
 * Helper function to get the numerical damage multiplier for a character.
 *
 * @param character The character to get.
 * @param hasWhoreOfBabylon Optional. Whether the character has the Whore of Babylon effect
 *                          currently active. Defaults to false. This is necessary because Eve's
 *                          damage multiplier changes from 0.75 to 1 when she has Whore of Babylon
 *                          active.
 */
function getCharacterDamageMultiplier(character, hasWhoreOfBabylon = false) {
    if (character === isaac_typescript_definitions_1.PlayerType.EVE && hasWhoreOfBabylon) {
        return 1;
    }
    return characterDamageMultipliers_1.CHARACTER_DAMAGE_MULTIPLIERS[character];
}
exports.getCharacterDamageMultiplier = getCharacterDamageMultiplier;
/**
 * - Most characters have a 56 frame death animation (i.e. the "Death" animation).
 * - The Lost and Tainted Lost have a 38 frame death animation (i.e. the "LostDeath" animation).
 * - Tainted Forgotten have a 20 frame death animation (i.e. the "ForgottenDeath" animation).
 */
function getCharacterDeathAnimationName(character) {
    if (lostStyleCharactersSet_1.LOST_STYLE_CHARACTERS_SET.has(character)) {
        return "LostDeath";
    }
    if (character === isaac_typescript_definitions_1.PlayerType.FORGOTTEN_B) {
        return "ForgottenDeath";
    }
    return "Death";
}
exports.getCharacterDeathAnimationName = getCharacterDeathAnimationName;
/**
 * Returns the maximum heart containers that the provided character can have. Normally, this is 12,
 * but with Keeper it is 3, and with Tainted Keeper it is 2. This does not account for Birthright or
 * Mother's Kiss; use the `getPlayerMaxHeartContainers` helper function for that.
 */
function getCharacterMaxHeartContainers(character) {
    // 14
    if (character === isaac_typescript_definitions_1.PlayerType.KEEPER) {
        return 3;
    }
    // 16
    if (character === isaac_typescript_definitions_1.PlayerType.FORGOTTEN) {
        return 6;
    }
    // 17
    if (character === isaac_typescript_definitions_1.PlayerType.SOUL) {
        return 6;
    }
    // 33
    if (character === isaac_typescript_definitions_1.PlayerType.KEEPER_B) {
        return 2;
    }
    return 12;
}
exports.getCharacterMaxHeartContainers = getCharacterMaxHeartContainers;
/** Helper function to get the name of a character. Returns "Unknown" for modded characters. */
function getCharacterName(character) {
    if (isModdedCharacter(character)) {
        return "Unknown";
    }
    return characterNames_1.CHARACTER_NAMES[character];
}
exports.getCharacterName = getCharacterName;
/**
 * Helper function to get the path to the sprite for a particular character.
 *
 * For example, the file path for `PlayerType.ISAAC` is
 * "characters/costumes/character_001_isaac.png".
 */
function getCharacterSpritePNGFilePath(character) {
    const fileName = characterSpritePNGFileNames_1.CHARACTER_SPRITE_PNG_FILE_NAMES[character];
    return `${PNG_PATH_PREFIX}/${fileName}`;
}
exports.getCharacterSpritePNGFilePath = getCharacterSpritePNGFilePath;
/**
 * Helper function to get the collectibles that are granted to a particular character at the
 * beginning of a run.
 *
 * Note that this will return an empty array for Eden and Tainted Eden.
 */
function getCharacterStartingCollectibleTypes(character) {
    return characterStartingCollectibleTypes_1.CHARACTER_STARTING_COLLECTIBLE_TYPES[character];
}
exports.getCharacterStartingCollectibleTypes = getCharacterStartingCollectibleTypes;
/**
 * Helper function to get the trinket that is granted to a particular character at the beginning of
 * a run. Returns undefined if the character does not start with a trinket.
 *
 * Note that this will return undefined for Eden and Tainted Eden.
 */
function getCharacterStartingTrinketType(character) {
    return characterStartingTrinketTypes_1.CHARACTER_STARTING_TRINKET_TYPE[character];
}
exports.getCharacterStartingTrinketType = getCharacterStartingTrinketType;
/**
 * Helper function to get the "main" version of the character. In other words, this is the character
 * that selectable from the main menu (and has achievements related to completing the various bosses
 * and so on).
 *
 * For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
 * (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
 *
 * For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
 */
function getMainCharacter(character) {
    if (isMainCharacter(character) || isModdedCharacter(character)) {
        return character;
    }
    switch (character) {
        // -1
        case isaac_typescript_definitions_1.PlayerType.POSSESSOR: {
            return isaac_typescript_definitions_1.PlayerType.POSSESSOR;
        }
        // 11
        case isaac_typescript_definitions_1.PlayerType.LAZARUS_2: {
            return isaac_typescript_definitions_1.PlayerType.LAZARUS;
        }
        // 12
        case isaac_typescript_definitions_1.PlayerType.DARK_JUDAS: {
            return isaac_typescript_definitions_1.PlayerType.JUDAS;
        }
        // 17
        case isaac_typescript_definitions_1.PlayerType.SOUL: {
            return isaac_typescript_definitions_1.PlayerType.FORGOTTEN;
        }
        // 20
        case isaac_typescript_definitions_1.PlayerType.ESAU: {
            return isaac_typescript_definitions_1.PlayerType.JACOB;
        }
        // 38
        case isaac_typescript_definitions_1.PlayerType.LAZARUS_2_B: {
            return isaac_typescript_definitions_1.PlayerType.LAZARUS_2;
        }
        // 39
        case isaac_typescript_definitions_1.PlayerType.JACOB_2_B: {
            return isaac_typescript_definitions_1.PlayerType.JACOB_B;
        }
        // 40
        case isaac_typescript_definitions_1.PlayerType.SOUL_B: {
            return isaac_typescript_definitions_1.PlayerType.FORGOTTEN_B;
        }
    }
}
exports.getMainCharacter = getMainCharacter;
function isFlyingCharacter(character) {
    return FLYING_CHARACTERS_SET.has(character);
}
exports.isFlyingCharacter = isFlyingCharacter;
/**
 * Helper function to check if the provided character is one of the characters that are selectable
 * from the main menu (and have achievements related to completing the various bosses and so on).
 */
function isMainCharacter(character) {
    return MAIN_CHARACTERS_SET.has(character);
}
exports.isMainCharacter = isMainCharacter;
function isModdedCharacter(character) {
    return !isVanillaCharacter(character);
}
exports.isModdedCharacter = isModdedCharacter;
function isVanillaCharacter(character) {
    return character <= constantsFirstLast_1.LAST_VANILLA_CHARACTER;
}
exports.isVanillaCharacter = isVanillaCharacter;
