local ____lualib = require("lualib_bundle")
local Map = ____lualib.Map
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local getCollectibleTypeFromArg
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local CollectibleSpriteLayer = ____isaac_2Dtypescript_2Ddefinitions.CollectibleSpriteLayer
local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
local ItemConfigChargeType = ____isaac_2Dtypescript_2Ddefinitions.ItemConfigChargeType
local ItemConfigTagZero = ____isaac_2Dtypescript_2Ddefinitions.ItemConfigTagZero
local ItemType = ____isaac_2Dtypescript_2Ddefinitions.ItemType
local PickupPrice = ____isaac_2Dtypescript_2Ddefinitions.PickupPrice
local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
local RenderMode = ____isaac_2Dtypescript_2Ddefinitions.RenderMode
local ____cachedClasses = require("core.cachedClasses")
local game = ____cachedClasses.game
local itemConfig = ____cachedClasses.itemConfig
local ____constants = require("core.constants")
local BLIND_ITEM_PNG_PATH = ____constants.BLIND_ITEM_PNG_PATH
local DEFAULT_ITEM_POOL_TYPE = ____constants.DEFAULT_ITEM_POOL_TYPE
local QUALITIES = ____constants.QUALITIES
local ____constantsFirstLast = require("core.constantsFirstLast")
local LAST_VANILLA_COLLECTIBLE_TYPE = ____constantsFirstLast.LAST_VANILLA_COLLECTIBLE_TYPE
local ____constantsVanilla = require("core.constantsVanilla")
local VANILLA_COLLECTIBLE_TYPES = ____constantsVanilla.VANILLA_COLLECTIBLE_TYPES
local ____collectibleDescriptions = require("objects.collectibleDescriptions")
local COLLECTIBLE_DESCRIPTIONS = ____collectibleDescriptions.COLLECTIBLE_DESCRIPTIONS
local DEFAULT_COLLECTIBLE_DESCRIPTION = ____collectibleDescriptions.DEFAULT_COLLECTIBLE_DESCRIPTION
local ____collectibleNames = require("objects.collectibleNames")
local COLLECTIBLE_NAMES = ____collectibleNames.COLLECTIBLE_NAMES
local DEFAULT_COLLECTIBLE_NAME = ____collectibleNames.DEFAULT_COLLECTIBLE_NAME
local ____singleUseActiveCollectibleTypesSet = require("sets.singleUseActiveCollectibleTypesSet")
local SINGLE_USE_ACTIVE_COLLECTIBLE_TYPES_SET = ____singleUseActiveCollectibleTypesSet.SINGLE_USE_ACTIVE_COLLECTIBLE_TYPES_SET
local ____entities = require("functions.entities")
local getEntityID = ____entities.getEntityID
local ____flag = require("functions.flag")
local hasFlag = ____flag.hasFlag
local ____pickupVariants = require("functions.pickupVariants")
local isCollectible = ____pickupVariants.isCollectible
local ____sprites = require("functions.sprites")
local clearSprite = ____sprites.clearSprite
local spriteEquals = ____sprites.spriteEquals
local ____types = require("functions.types")
local asCollectibleType = ____types.asCollectibleType
local isInteger = ____types.isInteger
local ____utils = require("functions.utils")
local assertDefined = ____utils.assertDefined
function ____exports.clearCollectibleSprite(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"clearCollectibleSprite\" function was given a non-collectible: " .. entityID)
    end
    ____exports.setCollectibleSprite(nil, collectible, nil)
end
--- Helper function to get a collectible's quality, which ranges from 0 to 4 (inclusive). For
-- example, Mom's Knife has a quality of 4. Returns 0 if the provided collectible type was not
-- valid.
function ____exports.getCollectibleQuality(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleQuality")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return 0
    end
    return itemConfigItem.Quality
end
function ____exports.isVanillaCollectibleType(self, collectibleType)
    return collectibleType <= LAST_VANILLA_COLLECTIBLE_TYPE
end
--- Helper function to remove the collectible from a collectible pedestal and make it appear as if a
-- player has already taken the item. This is accomplished by changing the sub-type to
-- `CollectibleType.NULL` and then setting the sprite to an empty/missing PNG file.
-- 
-- For more information, see the documentation for the "clearSprite" helper function.
function ____exports.setCollectibleEmpty(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectibleEmpty\" function was given a non-collectible: " .. entityID)
    end
    collectible.SubType = CollectibleType.NULL
    ____exports.clearCollectibleSprite(nil, collectible)
end
--- Helper function to change the sprite of a collectible pedestal entity.
-- 
-- For more information about removing the collectible sprite, see the documentation for the
-- "clearSprite" helper function.
-- 
-- @param collectible The collectible whose sprite you want to modify.
-- @param pngPath Equal to either the spritesheet path to load (e.g.
-- "gfx/items/collectibles/collectibles_001_thesadonion.png") or undefined. If
-- undefined, the sprite will be removed, making it appear like the collectible has
-- already been taken by the player.
function ____exports.setCollectibleSprite(self, collectible, pngPath)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectibleSprite\" function was given a non-collectible: " .. entityID)
    end
    local sprite = collectible:GetSprite()
    if pngPath == nil then
        clearSprite(nil, sprite, CollectibleSpriteLayer.HEAD, CollectibleSpriteLayer.ITEM_SHADOW)
    else
        sprite:ReplaceSpritesheet(CollectibleSpriteLayer.HEAD, pngPath)
        sprite:LoadGraphics()
    end
end
--- Helper function to change the collectible on a pedestal. Simply updating the `SubType` field is
-- not sufficient because the sprite will not change.
function ____exports.setCollectibleSubType(self, collectible, newCollectibleType)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectibleSubType\" function was given a non-collectible: " .. entityID)
    end
    if newCollectibleType == CollectibleType.NULL then
        ____exports.setCollectibleEmpty(nil, collectible)
        return
    end
    collectible:Morph(
        EntityType.PICKUP,
        PickupVariant.COLLECTIBLE,
        newCollectibleType,
        true,
        true,
        true
    )
end
function getCollectibleTypeFromArg(self, collectibleOrCollectibleType, functionName)
    if isInteger(nil, collectibleOrCollectibleType) then
        return collectibleOrCollectibleType
    end
    local collectible = collectibleOrCollectibleType
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error((("The \"" .. functionName) .. "\" function was given a non-collectible: ") .. entityID)
    end
    return collectible.SubType
end
local COLLECTIBLE_ANM2_PATH = "gfx/005.100_collectible.anm2"
local DEFAULT_COLLECTIBLE_PRICE = 15
--- Glitched items start at id 4294967295 (the final 32-bit integer) and increment backwards.
local GLITCHED_ITEM_THRESHOLD = 4000000000
local QUALITY_TO_VANILLA_COLLECTIBLE_TYPES_MAP = (function()
    local qualityToCollectibleTypesMap = __TS__New(Map)
    for ____, quality in ipairs(QUALITIES) do
        local collectibleTypes = {}
        for ____, collectibleType in ipairs(VANILLA_COLLECTIBLE_TYPES) do
            local collectibleTypeQuality = ____exports.getCollectibleQuality(nil, collectibleType)
            if collectibleTypeQuality == quality then
                collectibleTypes[#collectibleTypes + 1] = collectibleType
            end
        end
        qualityToCollectibleTypesMap:set(quality, collectibleTypes)
    end
    return qualityToCollectibleTypesMap
end)(nil)
--- The `isBlindCollectible` function needs a reference sprite to work properly.
local questionMarkSprite = (function()
    local sprite = Sprite()
    sprite:Load("gfx/005.100_collectible.anm2", false)
    sprite:ReplaceSpritesheet(1, "gfx/items/collectibles/questionmark.png")
    sprite:LoadGraphics()
    return sprite
end)(nil)
--- Helper function to check in the item config if a given collectible has a given cache flag.
function ____exports.collectibleHasCacheFlag(self, collectibleOrCollectibleType, cacheFlag)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "collectibleHasCacheFlag")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return false
    end
    return hasFlag(nil, itemConfigItem.CacheFlags, cacheFlag)
end
--- Helper function to check if two collectible sprites have the same sprite sheet loaded.
function ____exports.collectibleSpriteEquals(self, sprite1, sprite2)
    local xStart = -1
    local xFinish = 1
    local xIncrement = 1
    local yStart = -40
    local yFinish = 10
    local yIncrement = 3
    return spriteEquals(
        nil,
        sprite1,
        sprite2,
        CollectibleSpriteLayer.HEAD,
        xStart,
        xFinish,
        xIncrement,
        yStart,
        yFinish,
        yIncrement
    )
end
--- Helper function to get the charge type that a collectible has. Returns
-- `ItemConfigChargeType.NORMAL` if the provided collectible type was not valid.
function ____exports.getCollectibleChargeType(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleChargeType")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return ItemConfigChargeType.NORMAL
    end
    return itemConfigItem.ChargeType
end
--- Helper function to get the in-game description for a collectible. Returns "Unknown" if the
-- provided collectible type was not valid.
-- 
-- This function works for both vanilla and modded collectibles.
function ____exports.getCollectibleDescription(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleDescription")
    local collectibleDescription = COLLECTIBLE_DESCRIPTIONS[collectibleType]
    if collectibleDescription ~= nil then
        return collectibleDescription
    end
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem ~= nil then
        return itemConfigItem.Description
    end
    return DEFAULT_COLLECTIBLE_DESCRIPTION
end
--- Helper function to get the coin cost that a collectible item would be if it were being offered in
-- a Devil Room deal. Returns 0 if passed `CollectibleType.NULL`.
function ____exports.getCollectibleDevilCoinPrice(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleDescription")
    if collectibleType == CollectibleType.NULL then
        return 0
    end
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return DEFAULT_COLLECTIBLE_PRICE
    end
    return itemConfigItem.DevilPrice * DEFAULT_COLLECTIBLE_PRICE
end
--- Helper function to get the heart cost that a collectible item would be if it were being offered
-- in a Devil Room deal. Returns 0 if passed `CollectibleType.NULL`.
function ____exports.getCollectibleDevilHeartPrice(self, collectibleOrCollectibleType, player)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleDevilHeartPrice")
    local maxHearts = player:GetMaxHearts()
    if collectibleType == CollectibleType.NULL then
        return 0
    end
    if maxHearts == 0 then
        return PickupPrice.THREE_SOUL_HEARTS
    end
    local defaultCollectiblePrice = PickupPrice.ONE_HEART
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return defaultCollectiblePrice
    end
    local twoHeartPrice = maxHearts == 2 and PickupPrice.ONE_HEART_AND_TWO_SOUL_HEARTS or PickupPrice.TWO_HEARTS
    return itemConfigItem.DevilPrice == 2 and twoHeartPrice or PickupPrice.ONE_HEART
end
--- Helper function to get the path to a collectible PNG file. Returns the path to the question mark
-- sprite (i.e. from Curse of the Blind) if the provided collectible type was not valid.
-- 
-- If you intentionally want the path to the question mark sprite, pass -1 as the collectible type.
-- 
-- Note that this does not return the file name, but the full path to the collectible's PNG file.
-- The function is named "GfxFilename" to correspond to the associated `ItemConfigItem.GfxFileName`
-- field.
function ____exports.getCollectibleGfxFilename(self, collectibleOrCollectibleType)
    if collectibleOrCollectibleType == -1 then
        return BLIND_ITEM_PNG_PATH
    end
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleGfxFilename")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return BLIND_ITEM_PNG_PATH
    end
    return itemConfigItem.GfxFileName
end
--- Helper function to get the initial amount of charges that a collectible has. In most cases, when
-- picking up an active collectible for the first time, it will be fully charged, which corresponds
-- to an `InitCharge` value of -1. However, in some cases, this may be different. For example,
-- Eden's Soul starts without any charges, so it has an `InitCharge` value of 0.
-- 
-- This function returns 0 if the provided collectible type was not valid. This function returns -1
-- if the provided collectible type was not an active collectible.
function ____exports.getCollectibleInitCharge(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleInitCharge")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return 0
    end
    return itemConfigItem.InitCharge
end
--- Helper function to get the `ItemType` of a collectible. Returns `ItemType.ITEM_NULL` if the
-- provided collectible type was not valid.
function ____exports.getCollectibleItemType(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleItemType")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return ItemType.NULL
    end
    return itemConfigItem.Type
end
--- Helper function to get the maximum amount of charges that a collectible has. Returns 0 if the
-- provided collectible type was not valid.
function ____exports.getCollectibleMaxCharges(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleMaxCharges")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem == nil then
        return 0
    end
    return itemConfigItem.MaxCharges
end
--- Helper function to get the name of a collectible. Returns "Unknown" if the provided collectible
-- type is not valid.
-- 
-- This function works for both vanilla and modded collectibles.
-- 
-- For example, `getCollectibleName(CollectibleType.SAD_ONION)` would return "Sad Onion".
function ____exports.getCollectibleName(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleName")
    local collectibleName = COLLECTIBLE_NAMES[collectibleType]
    if collectibleName ~= nil then
        return collectibleName
    end
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    if itemConfigItem ~= nil then
        return itemConfigItem.Name
    end
    return DEFAULT_COLLECTIBLE_NAME
end
--- Helper function to get the "pedestal type" of a collectible. For example, it might be sitting on
-- top of a broken Blood Donation Machine, or it might be sitting on top of an opened Spiked Chest.
function ____exports.getCollectiblePedestalType(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"getCollectiblePedestalType\" function was given a non-collectible: " .. entityID)
    end
    local sprite = collectible:GetSprite()
    return sprite:GetOverlayFrame()
end
--- Helper function to get the tags of a collectible (which is the composition of zero or more
-- `ItemConfigTag`). Returns 0 if the provided collectible type is not valid.
-- 
-- For example:
-- 
-- ```ts
-- const collectibleType = CollectibleType.SAD_ONION;
-- const itemConfigTags = getCollectibleTags(collectibleType); // itemConfigTags is "18350080"
-- ```
function ____exports.getCollectibleTags(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "getCollectibleTags")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    return itemConfigItem == nil and ItemConfigTagZero or itemConfigItem.Tags
end
--- Returns an array containing every vanilla collectible type with the given quality.
-- 
-- Note that this function will only return vanilla collectible types. To handle modded collectible
-- types, use the `getCollectibleTypesOfQuality` helper function instead.
function ____exports.getVanillaCollectibleTypesOfQuality(self, quality)
    local collectibleTypes = QUALITY_TO_VANILLA_COLLECTIBLE_TYPES_MAP:get(quality)
    assertDefined(
        nil,
        collectibleTypes,
        "Failed to find the vanilla collectible types corresponding to quality: " .. tostring(quality)
    )
    return collectibleTypes
end
--- Returns true if the item type in the item config is equal to `ItemType.ACTIVE`.
function ____exports.isActiveCollectible(self, collectibleType)
    local itemType = ____exports.getCollectibleItemType(nil, collectibleType)
    return itemType == ItemType.ACTIVE
end
--- Returns true if the collectible has a red question mark sprite.
-- 
-- Note that this function will not work properly in a render callback with the `RenderMode` set to
-- `RenderMode.WATER_REFLECT`. If this is detected, this function will throw a run-time error.
function ____exports.isBlindCollectible(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"isBlindCollectible\" function was given a non-collectible: " .. entityID)
    end
    local room = game:GetRoom()
    local renderMode = room:GetRenderMode()
    if renderMode == RenderMode.WATER_REFLECT then
        error("The \"isBlindCollectible\" function will not work properly in a render callback with the render mode equal to \"RenderMode.WATER_REFLECT\". Make sure that you properly account for this case if you are calling this function in a render callback.")
    end
    local sprite = collectible:GetSprite()
    local animation = sprite:GetAnimation()
    local frame = sprite:GetFrame()
    questionMarkSprite:SetFrame(animation, frame)
    return ____exports.collectibleSpriteEquals(nil, sprite, questionMarkSprite)
end
--- Returns true if the item type in the item config is equal to `ItemType.FAMILIAR`.
function ____exports.isFamiliarCollectible(self, collectibleType)
    local itemType = ____exports.getCollectibleItemType(nil, collectibleType)
    return itemType == ItemType.FAMILIAR
end
--- Returns whether the given collectible is a "glitched" item. All items are replaced by glitched
-- items once a player has TMTRAINER. However, glitched items can also "naturally" appear in secret
-- rooms and I AM ERROR rooms if the "Corrupted Data" achievement is unlocked.
-- 
-- Under the hood, this checks if the sub-type of the collectible is greater than 4,000,000,000.
function ____exports.isGlitchedCollectible(self, collectible)
    return collectible.Variant == PickupVariant.COLLECTIBLE and collectible.SubType > GLITCHED_ITEM_THRESHOLD
end
--- Returns true if the collectible has the "Hidden" attribute in the item config.
-- 
-- Hidden collectibles will not show up in any pools and Eden will not start with them.
function ____exports.isHiddenCollectible(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "isHiddenCollectible")
    local itemConfigItem = itemConfig:GetCollectible(collectibleType)
    return itemConfigItem ~= nil and itemConfigItem.Hidden
end
function ____exports.isModdedCollectibleType(self, collectibleType)
    return not ____exports.isVanillaCollectibleType(nil, collectibleType)
end
--- Returns true if the item type in the item config is equal to `ItemType.ITEM_PASSIVE` or
-- `ItemType.ITEM_FAMILIAR`.
function ____exports.isPassiveOrFamiliarCollectible(self, collectibleOrCollectibleType)
    local collectibleType = getCollectibleTypeFromArg(nil, collectibleOrCollectibleType, "isPassiveCollectible")
    local itemType = ____exports.getCollectibleItemType(nil, collectibleType)
    return itemType == ItemType.PASSIVE or itemType == ItemType.FAMILIAR
end
--- Helper function to check if a collectible type is a particular quality.
function ____exports.isQuality(self, collectibleOrCollectibleType, quality)
    local actualQuality = ____exports.getCollectibleQuality(nil, collectibleOrCollectibleType)
    return quality == actualQuality
end
--- Helper function to determine if a particular collectible will disappear from the player's
-- inventory upon use. Note that this will not work will modded collectibles, as there is no way to
-- dynamically know if a modded collectible will disappear.
function ____exports.isSingleUseCollectible(self, collectibleType)
    return SINGLE_USE_ACTIVE_COLLECTIBLE_TYPES_SET:has(collectibleType)
end
function ____exports.isValidCollectibleType(self, collectibleType)
    local potentialCollectibleType = asCollectibleType(nil, collectibleType)
    local itemConfigItem = itemConfig:GetCollectible(potentialCollectibleType)
    return itemConfigItem ~= nil
end
--- Helper function to generate a new sprite based on a collectible. If the provided collectible type
-- is invalid, a sprite with a Curse of the Blind question mark will be returned.
-- 
-- If you intentionally want a question mark sprite, pass -1 as the collectible type.
function ____exports.newCollectibleSprite(self, collectibleType)
    local sprite = Sprite()
    sprite:Load(COLLECTIBLE_ANM2_PATH, false)
    clearSprite(nil, sprite)
    local gfxFileName = ____exports.getCollectibleGfxFilename(nil, collectibleType)
    sprite:ReplaceSpritesheet(CollectibleSpriteLayer.HEAD, gfxFileName)
    sprite:LoadGraphics()
    local defaultAnimation = sprite:GetDefaultAnimation()
    sprite:Play(defaultAnimation, true)
    return sprite
end
--- Helper function to remove the rotation behavior from a collectible. This will happen by default
-- when collectibles are spawned when playing as Tainted Isaac or when having Binge Eater.
-- 
-- Under the hood, this is accomplished by morphing the collectible with the `ignoreModifiers`
-- argument set to true.
function ____exports.preventCollectibleRotation(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"preventCollectibleRotation\" function was given a non-collectible: " .. entityID)
    end
    collectible:Morph(
        collectible.Type,
        collectible.Variant,
        collectible.SubType,
        true,
        true,
        true
    )
end
--- Helper function to remove all pickup delay on a collectible. By default, collectibles have a 20
-- frame delay before they can be picked up by a player.
function ____exports.removeCollectiblePickupDelay(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"removeCollectiblePickupDelay\" function was given a non-collectible: " .. entityID)
    end
    collectible.Wait = 0
end
--- Helper function to set a collectible sprite to a question mark (i.e. how collectibles look when
-- the player has Curse of the Blind).
function ____exports.setCollectibleBlind(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectibleBlind\" function was given a non-collectible: " .. entityID)
    end
    ____exports.setCollectibleSprite(nil, collectible, BLIND_ITEM_PNG_PATH)
end
--- Helper function to change a collectible into a "glitched" item (like the ones that appear when
-- the player has TMTRAINER).
function ____exports.setCollectibleGlitched(self, collectible)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectibleGlitched\" function was given a non-collectible: " .. entityID)
    end
    local player = Isaac.GetPlayer()
    local hasTMTRAINER = player:HasCollectible(CollectibleType.TMTRAINER)
    if not hasTMTRAINER then
        player:AddCollectible(CollectibleType.TMTRAINER, 0, false)
    end
    local itemPool = game:GetItemPool()
    local collectibleType = itemPool:GetCollectible(DEFAULT_ITEM_POOL_TYPE)
    ____exports.setCollectibleSubType(nil, collectible, collectibleType)
    if not hasTMTRAINER then
        player:RemoveCollectible(CollectibleType.TMTRAINER)
    end
end
--- Helper function to set the "pedestal type" of a collectible. For example, it might be sitting on
-- top of a broken Blood Donation Machine and you want to change it to be sitting on top of an
-- opened Spiked Chest.
function ____exports.setCollectiblePedestalType(self, collectible, collectiblePedestalType)
    if not isCollectible(nil, collectible) then
        local entityID = getEntityID(nil, collectible)
        error("The \"setCollectiblePedestalType\" function was given a non-collectible: " .. entityID)
    end
    local sprite = collectible:GetSprite()
    local overlayAnimation = sprite:GetOverlayAnimation()
    sprite:SetOverlayFrame(overlayAnimation, collectiblePedestalType)
end
--- Helper function to put a message in the log.txt file to let the Rebirth Item Tracker know that
-- the build has been rerolled.
function ____exports.setCollectiblesRerolledForItemTracker(self)
    Isaac.DebugString("Added 3 Collectibles")
end
return ____exports
