local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__ClassExtends = ____lualib.__TS__ClassExtends
local ____exports = {}
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
local FamiliarVariant = ____isaac_2Dtypescript_2Ddefinitions.FamiliarVariant
local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
local SoundEffect = ____isaac_2Dtypescript_2Ddefinitions.SoundEffect
local ____cachedClasses = require("core.cachedClasses")
local sfxManager = ____cachedClasses.sfxManager
local ____ISCFeature = require("enums.ISCFeature")
local ISCFeature = ____ISCFeature.ISCFeature
local ____ModCallbackCustom = require("enums.ModCallbackCustom")
local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
local ____external = require("functions.external")
local rebirthItemTrackerRemoveCollectible = ____external.rebirthItemTrackerRemoveCollectible
local ____log = require("functions.log")
local log = ____log.log
local logError = ____log.logError
local ____playerIndex = require("functions.playerIndex")
local getPlayerFromIndex = ____playerIndex.getPlayerFromIndex
local getPlayerIndex = ____playerIndex.getPlayerIndex
local ____players = require("functions.players")
local isCharacter = ____players.isCharacter
local ____Feature = require("classes.private.Feature")
local Feature = ____Feature.Feature
local DEBUG = false
local CustomReviveState = {}
CustomReviveState.DISABLED = 0
CustomReviveState[CustomReviveState.DISABLED] = "DISABLED"
CustomReviveState.WAITING_FOR_ROOM_TRANSITION = 1
CustomReviveState[CustomReviveState.WAITING_FOR_ROOM_TRANSITION] = "WAITING_FOR_ROOM_TRANSITION"
CustomReviveState.WAITING_FOR_ITEM_ANIMATION = 2
CustomReviveState[CustomReviveState.WAITING_FOR_ITEM_ANIMATION] = "WAITING_FOR_ITEM_ANIMATION"
local v = {run = {state = CustomReviveState.DISABLED, revivalType = nil, dyingPlayerIndex = nil}}
____exports.CustomRevive = __TS__Class()
local CustomRevive = ____exports.CustomRevive
CustomRevive.name = "CustomRevive"
__TS__ClassExtends(CustomRevive, Feature)
function CustomRevive.prototype.____constructor(self, preCustomRevive, postCustomRevive, runInNFrames)
    Feature.prototype.____constructor(self)
    self.v = v
    self.postRender = function()
        if v.run.state ~= CustomReviveState.WAITING_FOR_ITEM_ANIMATION then
            return
        end
        sfxManager:Stop(SoundEffect.ONE_UP)
    end
    self.postFamiliarInitOneUp = function(____, familiar)
        if v.run.state ~= CustomReviveState.WAITING_FOR_ROOM_TRANSITION then
            return
        end
        familiar:Remove()
    end
    self.postNewRoomReordered = function()
        if v.run.state ~= CustomReviveState.WAITING_FOR_ROOM_TRANSITION then
            return
        end
        v.run.state = CustomReviveState.WAITING_FOR_ITEM_ANIMATION
        self:logStateChanged()
    end
    self.postPEffectUpdateReordered = function(____, player)
        self:checkWaitingForItemAnimation(player)
    end
    self.postPlayerFatalDamage = function(____, player)
        self:playerIsAboutToDie(player)
        return nil
    end
    self.preBerserkDeath = function(____, player)
        self:playerIsAboutToDie(player)
    end
    self.featuresUsed = {ISCFeature.RUN_IN_N_FRAMES}
    self.callbacksUsed = {{ModCallback.POST_RENDER, self.postRender}, {ModCallback.POST_FAMILIAR_INIT, self.postFamiliarInitOneUp, {FamiliarVariant.ONE_UP}}}
    self.customCallbacksUsed = {{ModCallbackCustom.POST_NEW_ROOM_REORDERED, self.postNewRoomReordered}, {ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED, self.postPEffectUpdateReordered}, {ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE, self.postPlayerFatalDamage}, {ModCallbackCustom.PRE_BERSERK_DEATH, self.preBerserkDeath}}
    self.preCustomRevive = preCustomRevive
    self.postCustomRevive = postCustomRevive
    self.runInNFrames = runInNFrames
end
function CustomRevive.prototype.checkWaitingForItemAnimation(self, player)
    if v.run.state ~= CustomReviveState.WAITING_FOR_ITEM_ANIMATION then
        return
    end
    if v.run.dyingPlayerIndex == nil then
        return
    end
    local playerIndex = getPlayerIndex(nil, player)
    if playerIndex ~= v.run.dyingPlayerIndex then
        return
    end
    local playerToCheckHoldingItem = player
    if isCharacter(nil, player, PlayerType.SOUL_B) then
        local forgottenBody = player:GetOtherTwin()
        if forgottenBody ~= nil then
            playerToCheckHoldingItem = forgottenBody
        end
    end
    if not playerToCheckHoldingItem:IsHoldingItem() then
        return
    end
    if v.run.revivalType ~= nil then
        self.postCustomRevive:fire(playerToCheckHoldingItem, v.run.revivalType)
    end
    v.run.state = CustomReviveState.DISABLED
    v.run.revivalType = nil
    v.run.dyingPlayerIndex = nil
    self:logStateChanged()
end
function CustomRevive.prototype.playerIsAboutToDie(self, player)
    local revivalType = self.preCustomRevive:fire(player)
    if revivalType == nil then
        return
    end
    v.run.state = CustomReviveState.WAITING_FOR_ROOM_TRANSITION
    v.run.revivalType = revivalType
    v.run.dyingPlayerIndex = getPlayerIndex(nil, player)
    self:logStateChanged()
    player:AddCollectible(CollectibleType.ONE_UP, 0, false)
    rebirthItemTrackerRemoveCollectible(nil, CollectibleType.ONE_UP)
    local playerIndex = getPlayerIndex(nil, player)
    self.runInNFrames:runNextGameFrame(function()
        local futurePlayer = getPlayerFromIndex(nil, playerIndex)
        if futurePlayer == nil then
            return
        end
        if futurePlayer:IsDead() then
            return
        end
        logError("The player is still alive after initializing a custom revive. Explicitly killing the player.")
        futurePlayer:Kill()
    end)
end
function CustomRevive.prototype.logStateChanged(self)
    if DEBUG then
        log(((("Custom revive state changed: " .. CustomReviveState[v.run.state]) .. " (") .. tostring(v.run.state)) .. ")")
    end
end
return ____exports
