local ____lualib = require("lualib_bundle")
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local MAIN_CHARACTERS_SET
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
local ____constants = require("core.constants")
local FLYING_CHARACTERS = ____constants.FLYING_CHARACTERS
local MAIN_CHARACTERS = ____constants.MAIN_CHARACTERS
local ____constantsFirstLast = require("core.constantsFirstLast")
local LAST_VANILLA_CHARACTER = ____constantsFirstLast.LAST_VANILLA_CHARACTER
local ____characterDamageMultipliers = require("objects.characterDamageMultipliers")
local CHARACTER_DAMAGE_MULTIPLIERS = ____characterDamageMultipliers.CHARACTER_DAMAGE_MULTIPLIERS
local ____characterNames = require("objects.characterNames")
local CHARACTER_NAMES = ____characterNames.CHARACTER_NAMES
local ____characterSpritePNGFileNames = require("objects.characterSpritePNGFileNames")
local CHARACTER_SPRITE_PNG_FILE_NAMES = ____characterSpritePNGFileNames.CHARACTER_SPRITE_PNG_FILE_NAMES
local ____characterStartingCollectibleTypes = require("objects.characterStartingCollectibleTypes")
local CHARACTER_STARTING_COLLECTIBLE_TYPES = ____characterStartingCollectibleTypes.CHARACTER_STARTING_COLLECTIBLE_TYPES
local ____characterStartingTrinketTypes = require("objects.characterStartingTrinketTypes")
local CHARACTER_STARTING_TRINKET_TYPE = ____characterStartingTrinketTypes.CHARACTER_STARTING_TRINKET_TYPE
local ____charactersThatStartWithAnActiveItemSet = require("sets.charactersThatStartWithAnActiveItemSet")
local CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET = ____charactersThatStartWithAnActiveItemSet.CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET
local ____charactersWithBlackHeartFromEternalHeartSet = require("sets.charactersWithBlackHeartFromEternalHeartSet")
local CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET = ____charactersWithBlackHeartFromEternalHeartSet.CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET
local ____charactersWithFreeDevilDealsSet = require("sets.charactersWithFreeDevilDealsSet")
local CHARACTERS_WITH_FREE_DEVIL_DEALS_SET = ____charactersWithFreeDevilDealsSet.CHARACTERS_WITH_FREE_DEVIL_DEALS_SET
local ____charactersWithNoRedHeartsSet = require("sets.charactersWithNoRedHeartsSet")
local CHARACTERS_WITH_NO_RED_HEARTS_SET = ____charactersWithNoRedHeartsSet.CHARACTERS_WITH_NO_RED_HEARTS_SET
local ____charactersWithNoSoulHeartsSet = require("sets.charactersWithNoSoulHeartsSet")
local CHARACTERS_WITH_NO_SOUL_HEARTS_SET = ____charactersWithNoSoulHeartsSet.CHARACTERS_WITH_NO_SOUL_HEARTS_SET
local ____lostStyleCharactersSet = require("sets.lostStyleCharactersSet")
local LOST_STYLE_CHARACTERS_SET = ____lostStyleCharactersSet.LOST_STYLE_CHARACTERS_SET
local ____ReadonlySet = require("types.ReadonlySet")
local ReadonlySet = ____ReadonlySet.ReadonlySet
--- 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 ____exports.isMainCharacter(self, character)
    return MAIN_CHARACTERS_SET:has(character)
end
function ____exports.isModdedCharacter(self, character)
    return not ____exports.isVanillaCharacter(nil, character)
end
function ____exports.isVanillaCharacter(self, character)
    return character <= LAST_VANILLA_CHARACTER
end
local FLYING_CHARACTERS_SET = __TS__New(ReadonlySet, FLYING_CHARACTERS)
MAIN_CHARACTERS_SET = __TS__New(ReadonlySet, MAIN_CHARACTERS)
local 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 ____exports.canCharacterHaveRedHearts(self, character)
    return not CHARACTERS_WITH_NO_RED_HEARTS_SET:has(character)
end
--- 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 ____exports.canCharacterHaveSoulHearts(self, character)
    return not CHARACTERS_WITH_NO_SOUL_HEARTS_SET:has(character)
end
--- Helper function for determining whether the given character can take free Devil Deals. (e.g. The
-- Lost, Tainted Lost, etc.)
function ____exports.canCharacterTakeFreeDevilDeals(self, character)
    return CHARACTERS_WITH_FREE_DEVIL_DEALS_SET:has(character)
end
--- 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 ____exports.doesCharacterGetBlackHeartFromEternalHeart(self, character)
    return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET:has(character)
end
--- 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 ____exports.doesCharacterStartWithActiveItem(self, character)
    return CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET:has(character)
end
--- 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 ____exports.getCharacterDamageMultiplier(self, character, hasWhoreOfBabylon)
    if hasWhoreOfBabylon == nil then
        hasWhoreOfBabylon = false
    end
    if character == PlayerType.EVE and hasWhoreOfBabylon then
        return 1
    end
    return CHARACTER_DAMAGE_MULTIPLIERS[character]
end
--- - 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 ____exports.getCharacterDeathAnimationName(self, character)
    if LOST_STYLE_CHARACTERS_SET:has(character) then
        return "LostDeath"
    end
    if character == PlayerType.FORGOTTEN_B then
        return "ForgottenDeath"
    end
    return "Death"
end
--- 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 ____exports.getCharacterMaxHeartContainers(self, character)
    if character == PlayerType.KEEPER then
        return 3
    end
    if character == PlayerType.FORGOTTEN then
        return 6
    end
    if character == PlayerType.SOUL then
        return 6
    end
    if character == PlayerType.KEEPER_B then
        return 2
    end
    return 12
end
--- Helper function to get the name of a character. Returns "Unknown" for modded characters.
function ____exports.getCharacterName(self, character)
    if ____exports.isModdedCharacter(nil, character) then
        return "Unknown"
    end
    return CHARACTER_NAMES[character]
end
--- 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 ____exports.getCharacterSpritePNGFilePath(self, character)
    local fileName = CHARACTER_SPRITE_PNG_FILE_NAMES[character]
    return (PNG_PATH_PREFIX .. "/") .. fileName
end
--- 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 ____exports.getCharacterStartingCollectibleTypes(self, character)
    return CHARACTER_STARTING_COLLECTIBLE_TYPES[character]
end
--- 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 ____exports.getCharacterStartingTrinketType(self, character)
    return CHARACTER_STARTING_TRINKET_TYPE[character]
end
--- 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 ____exports.getMainCharacter(self, character)
    if ____exports.isMainCharacter(nil, character) or ____exports.isModdedCharacter(nil, character) then
        return character
    end
    repeat
        local ____switch24 = character
        local ____cond24 = ____switch24 == PlayerType.POSSESSOR
        if ____cond24 then
            do
                return PlayerType.POSSESSOR
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2
        if ____cond24 then
            do
                return PlayerType.LAZARUS
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.DARK_JUDAS
        if ____cond24 then
            do
                return PlayerType.JUDAS
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL
        if ____cond24 then
            do
                return PlayerType.FORGOTTEN
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.ESAU
        if ____cond24 then
            do
                return PlayerType.JACOB
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2_B
        if ____cond24 then
            do
                return PlayerType.LAZARUS_2
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.JACOB_2_B
        if ____cond24 then
            do
                return PlayerType.JACOB_B
            end
        end
        ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL_B
        if ____cond24 then
            do
                return PlayerType.FORGOTTEN_B
            end
        end
    until true
end
function ____exports.isFlyingCharacter(self, character)
    return FLYING_CHARACTERS_SET:has(character)
end
return ____exports
