"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PostPlayerFatalDamage = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../../core/cachedClasses");
const ModCallbackCustom_1 = require("../../enums/ModCallbackCustom");
const flag_1 = require("../../functions/flag");
const playerDataStructures_1 = require("../../functions/playerDataStructures");
const playerIndex_1 = require("../../functions/playerIndex");
const revive_1 = require("../../functions/revive");
const rooms_1 = require("../../functions/rooms");
const shouldFire_1 = require("../../shouldFire");
const CustomCallback_1 = require("../private/CustomCallback");
const v = {
    run: {
        /** Needed to detect if Glass Cannon will kill the player. */
        playersLastDamageGameFrame: new Map(),
    },
};
class PostPlayerFatalDamage extends CustomCallback_1.CustomCallback {
    v = v;
    constructor() {
        super();
        this.callbacksUsed = [
            // 23
            [isaac_typescript_definitions_1.ModCallback.PRE_USE_ITEM, this.preUseItemBible, [isaac_typescript_definitions_1.CollectibleType.BIBLE]],
        ];
        this.customCallbacksUsed = [
            [ModCallbackCustom_1.ModCallbackCustom.ENTITY_TAKE_DMG_PLAYER, this.entityTakeDmgPlayer],
        ];
    }
    shouldFire = shouldFire_1.shouldFirePlayer;
    /**
     * Using The Bible on Satan is one of the few ways to die without taking damage, so we need to
     * handle this case.
     */
    // ModCallback.PRE_USE_ITEM (23)
    // CollectibleType.BIBLE (33)
    preUseItemBible = (_collectibleType, _rng, player, _useFlags, _activeSlot, _customVarData) => {
        if (!(0, rooms_1.inBossRoomOf)(isaac_typescript_definitions_1.BossID.SATAN)) {
            return undefined;
        }
        if ((0, revive_1.willPlayerRevive)(player)) {
            return undefined;
        }
        const shouldSustainDeath = this.fire(player, 0, isaac_typescript_definitions_1.DamageFlagZero, EntityRef(player), 0);
        if (shouldSustainDeath !== undefined) {
            // End-users will return false to stop the damage from being fatal. We have to return true to
            // prevent the Bible from firing.
            return !shouldSustainDeath;
        }
        return undefined;
    };
    // ModCallbackCustom.ENTITY_TAKE_DMG_PLAYER
    entityTakeDmgPlayer = (player, amount, damageFlags, source, countdownFrames) => {
        // This callback should not trigger for the Strawman Keeper and other players that are "child"
        // players.
        if ((0, playerIndex_1.isChildPlayer)(player)) {
            return undefined;
        }
        const gameFrameCount = cachedClasses_1.game.GetFrameCount();
        const lastDamageGameFrame = (0, playerDataStructures_1.mapGetPlayer)(v.run.playersLastDamageGameFrame, player);
        (0, playerDataStructures_1.mapSetPlayer)(v.run.playersLastDamageGameFrame, player, gameFrameCount);
        // If the damage has the damage flag of `DamageFlag.NO_KILL` (1 << 0), this will not be fatal
        // damage. (This is present on things like the Bad Trip pill.)
        if ((0, flag_1.hasFlag)(damageFlags, isaac_typescript_definitions_1.DamageFlag.NO_KILL)) {
            return undefined;
        }
        // If the player has a revival item such as Dead Cat, this will not be fatal damage.
        if ((0, revive_1.willPlayerRevive)(player)) {
            return undefined;
        }
        if (!(0, revive_1.isDamageToPlayerFatal)(player, amount, source, lastDamageGameFrame)) {
            return undefined;
        }
        const shouldSustainDeath = this.fire(player, amount, damageFlags, source, countdownFrames);
        if (shouldSustainDeath !== undefined) {
            return shouldSustainDeath;
        }
        return undefined;
    };
}
exports.PostPlayerFatalDamage = PostPlayerFatalDamage;
