"use strict";
// For machines, destruction is detected in two ways:
Object.defineProperty(exports, "__esModule", { value: true });
exports.SlotDestroyedDetection = void 0;
// 1) The main way is via a change in grid entity class. This happens when the machine is destroyed
//    with a bomb, for example. For this case, the slot will remain until the player leaves the
//    room.
// 2) In the specific case of a machine spawning a collectible, the machine will be immediately
//    removed. Thus, we assume that any despawning slot machine is destroyed in this way.
// For beggars, destruction is detected by monitoring for when a beggar despawns mid-room. Beggars
// that are paying out with a collectible will always be playing the "Teleport" animation.
// Otherwise, the beggar won't be playing any animation in particular.
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const ISCFeature_1 = require("../../../enums/ISCFeature");
const ModCallbackCustom_1 = require("../../../enums/ModCallbackCustom");
const SlotDestructionType_1 = require("../../../enums/SlotDestructionType");
const slots_1 = require("../../../functions/slots");
const Feature_1 = require("../../private/Feature");
const v = {
    room: {
        destroyedSlotSet: new Set(),
    },
};
class SlotDestroyedDetection extends Feature_1.Feature {
    v = v;
    postSlotDestroyed;
    roomHistory;
    constructor(postSlotDestroyed, roomHistory) {
        super();
        this.featuresUsed = [ISCFeature_1.ISCFeature.ROOM_HISTORY];
        this.callbacksUsed = [
            // 67
            [
                isaac_typescript_definitions_1.ModCallback.POST_ENTITY_REMOVE,
                this.postEntityRemoveSlot,
                [isaac_typescript_definitions_1.EntityType.SLOT],
            ],
        ];
        this.customCallbacksUsed = [
            [ModCallbackCustom_1.ModCallbackCustom.POST_SLOT_UPDATE, this.postSlotUpdate],
        ];
        this.postSlotDestroyed = postSlotDestroyed;
        this.roomHistory = roomHistory;
    }
    // ModCallback.POST_ENTITY_REMOVE (67)
    // EntityType.SLOT (6)
    postEntityRemoveSlot = (entity) => {
        const slot = entity;
        // The `POST_ENTITY_REMOVE` callback will fire for slots that are naturally despawning as a
        // player leaves a room. We want to ignore all slots that despawn for this reason.
        if (this.roomHistory.isLeavingRoom()) {
            return;
        }
        if ((0, slots_1.isSlotMachine)(slot)) {
            this.postEntityRemoveSlotMachine(slot);
        }
        else {
            this.postEntityRemoveBeggar(slot);
        }
    };
    postEntityRemoveSlotMachine(slot) {
        this.postSlotDestroyed.fire(slot, SlotDestructionType_1.SlotDestructionType.COLLECTIBLE_PAYOUT);
    }
    postEntityRemoveBeggar(slot) {
        const sprite = slot.GetSprite();
        const animation = sprite.GetAnimation();
        const slotDestructionType = animation === "Teleport"
            ? SlotDestructionType_1.SlotDestructionType.COLLECTIBLE_PAYOUT
            : SlotDestructionType_1.SlotDestructionType.NORMAL;
        this.postSlotDestroyed.fire(slot, slotDestructionType);
    }
    // ModCallbackCustom.POST_SLOT_UPDATE
    postSlotUpdate = (slot) => {
        const ptrHash = GetPtrHash(slot);
        const alreadyDestroyed = v.room.destroyedSlotSet.has(ptrHash);
        if (alreadyDestroyed) {
            return;
        }
        this.checkDestroyedFromCollisionClass(slot);
    };
    /**
     * Slots normally have an entity collision class of `EntityCollisionClass.ALL` (4) and a grid
     * collision class of `EntityGridCollisionClass.NONE` (0). When they are destroyed with a bomb,
     * the entity collision class stays the same, but the grid collision class switches to
     * `EntityGridCollisionClass.GROUND` (5).
     */
    checkDestroyedFromCollisionClass(slot) {
        if (slot.GridCollisionClass === isaac_typescript_definitions_1.EntityGridCollisionClass.GROUND) {
            const ptrHash = GetPtrHash(slot);
            v.room.destroyedSlotSet.add(ptrHash);
            this.postSlotDestroyed.fire(slot, SlotDestructionType_1.SlotDestructionType.NORMAL);
        }
    }
}
exports.SlotDestroyedDetection = SlotDestroyedDetection;
