"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomPickups = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const decorators_1 = require("../../../decorators");
const LadderSubTypeCustom_1 = require("../../../enums/LadderSubTypeCustom");
const entities_1 = require("../../../functions/entities");
const entitiesSpecific_1 = require("../../../functions/entitiesSpecific");
const Feature_1 = require("../../private/Feature");
/**
 * Normally, we would make a custom entity to represent a fading-away pickup, but we don't want to
 * interfere with the "entities2.xml" file in end-user mods. Thus, we must select a vanilla effect
 * to masquerade as a backdrop effect.
 *
 * We arbitrarily choose a ladder for this purpose because it will not automatically despawn after
 * time passes, like most other effects.
 */
const PICKUP_EFFECT_VARIANT = isaac_typescript_definitions_1.EffectVariant.LADDER;
const PICKUP_EFFECT_SUB_TYPE = LadderSubTypeCustom_1.LadderSubTypeCustom.CUSTOM_PICKUP;
class CustomPickups extends Feature_1.Feature {
    /** Indexed by entity ID. */
    customPickupFunctionsMap = new Map();
    /** @internal */
    constructor() {
        super();
        this.callbacksUsed = [
            // 38
            [isaac_typescript_definitions_1.ModCallback.PRE_PICKUP_COLLISION, this.prePickupCollision],
            // 56
            [
                isaac_typescript_definitions_1.ModCallback.POST_EFFECT_RENDER,
                this.postEffectRenderPickupEffect,
                [PICKUP_EFFECT_VARIANT],
            ],
        ];
    }
    // ModCallback.PRE_PICKUP_COLLISION (38)
    prePickupCollision = (pickup, collider) => {
        const entityID = (0, entities_1.getEntityID)(pickup);
        const customPickupFunctions = this.customPickupFunctionsMap.get(entityID);
        if (customPickupFunctions === undefined) {
            return undefined;
        }
        const player = collider.ToPlayer();
        if (player === undefined) {
            return undefined;
        }
        const shouldPickup = customPickupFunctions.collisionFunc(player);
        if (!shouldPickup) {
            return undefined;
        }
        pickup.Remove();
        const pickupSprite = pickup.GetSprite();
        const fileName = pickupSprite.GetFilename();
        const effect = (0, entitiesSpecific_1.spawnEffect)(PICKUP_EFFECT_VARIANT, PICKUP_EFFECT_SUB_TYPE, pickup.Position);
        const effectSprite = effect.GetSprite();
        effectSprite.Load(fileName, true);
        effectSprite.Play("Collect", true);
        customPickupFunctions.collectFunc(player);
        return undefined;
    };
    // ModCallback.POST_EFFECT_RENDER (56)
    // PICKUP_EFFECT_VARIANT
    postEffectRenderPickupEffect = (effect) => {
        if (effect.SubType !== PICKUP_EFFECT_SUB_TYPE) {
            return;
        }
        const sprite = effect.GetSprite();
        if (sprite.IsFinished("Collect")) {
            effect.Remove();
        }
    };
    /**
     * Helper function to register a custom pickup with the IsaacScript standard library. Use this
     * feature for custom pickups that are intended to be picked up by the player, like bombs and
     * keys.
     *
     * When IsaacScript detects that a player should be collecting the custom pickup, then the pickup
     * will be immediately removed, and an effect showing the pickup's respective `Collect` animation
     * will be spawned. (This emulates how a normal vanilla pickup would work.) After that, the
     * provided `collectFunc` will be fired. In this function, you will probably want to play a sound
     * corresponding to what kind of pickup it is (e.g. `SoundEffect.KEY_PICKUP_GAUNTLET`), as well as
     * do things like adding something to the player's inventory.
     *
     * Note that when you specify your custom pickup in the "entities2.xml" file, it should have a
     * type of "5" and be associated with an anm2 file that has a "Collect" animation.
     *
     * In order to use this function, you must upgrade your mod with `ISCFeature.CUSTOM_PICKUPS`.
     *
     * @param pickupVariantCustom The variant for the corresponding custom pickup.
     * @param subType The sub-type for the corresponding custom pickup.
     * @param collectFunc The function to run when the player collects this pickup.
     * @param collisionFunc Optional. The function to run when a player collides with the pickup.
     *                      Default is a function that always returns true, meaning that the player
     *                      will always immediately collect the pickup when they collide with it.
     *                      Specify this function if your pickup should only be able to be collected
     *                      under certain conditions.
     * @public
     */
    registerCustomPickup(pickupVariantCustom, subType, collectFunc, collisionFunc = () => true) {
        const entityID = (0, entities_1.getEntityIDFromConstituents)(isaac_typescript_definitions_1.EntityType.PICKUP, pickupVariantCustom, subType);
        const customPickupFunctions = {
            collectFunc,
            collisionFunc,
        };
        this.customPickupFunctionsMap.set(entityID, customPickupFunctions);
    }
}
exports.CustomPickups = CustomPickups;
__decorate([
    decorators_1.Exported
], CustomPickups.prototype, "registerCustomPickup", null);
