"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.emptyRoomGridEntities = exports.emptyRoom = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const ReadonlySet_1 = require("../types/ReadonlySet");
const entities_1 = require("./entities");
const gridEntities_1 = require("./gridEntities");
const roomShapeWalls_1 = require("./roomShapeWalls");
const rooms_1 = require("./rooms");
const EMPTY_ROOM_BLACKLIST_ENTITY_SET = new ReadonlySet_1.ReadonlySet([
    isaac_typescript_definitions_1.EntityType.PLAYER,
    isaac_typescript_definitions_1.EntityType.TEAR,
    isaac_typescript_definitions_1.EntityType.FAMILIAR,
    isaac_typescript_definitions_1.EntityType.LASER,
    isaac_typescript_definitions_1.EntityType.KNIFE,
    isaac_typescript_definitions_1.EntityType.PROJECTILE,
    isaac_typescript_definitions_1.EntityType.DARK_ESAU, // 866
]);
/**
 * Helper function to remove all naturally spawning entities and grid entities from a room. Notably,
 * this will not remove players (1), tears (2), familiars (3), lasers (7), knives (8), projectiles
 * (9), blacklisted NPCs such as Dark Esau, charmed NPCs, friendly NPCs, persistent NPCs, most
 * effects (1000), doors, and walls.
 */
function emptyRoom() {
    emptyRoomEntities();
    emptyRoomGridEntities();
}
exports.emptyRoom = emptyRoom;
/**
 * We remove entities in the `POST_NEW_ROOM` callback instead of in the `PRE_ROOM_ENTITY_SPAWN`
 * callback so that they will not re-appear when we re-enter the room.
 */
function emptyRoomEntities() {
    const room = cachedClasses_1.game.GetRoom();
    for (const entity of (0, entities_1.getEntities)()) {
        if (EMPTY_ROOM_BLACKLIST_ENTITY_SET.has(entity.Type)) {
            continue;
        }
        if (entity.HasEntityFlags(isaac_typescript_definitions_1.EntityFlag.CHARM) ||
            entity.HasEntityFlags(isaac_typescript_definitions_1.EntityFlag.FRIENDLY) ||
            entity.HasEntityFlags(isaac_typescript_definitions_1.EntityFlag.PERSISTENT)) {
            continue;
        }
        entity.ClearEntityFlags(isaac_typescript_definitions_1.EntityFlag.APPEAR);
        entity.Remove();
        // When fire places are removed, they will leave behind a "path" that will prevent future grid
        // entities from being spawned on the same tile. Thus, reset the path for this tile if this is a
        // fire place.
        if (entity.Type === isaac_typescript_definitions_1.EntityType.FIREPLACE) {
            const gridIndex = room.GetGridIndex(entity.Position);
            room.SetGridPath(gridIndex, 0);
        }
    }
}
/** Helper function to remove all grid entities from a room except for doors and walls. */
function emptyRoomGridEntities() {
    let removedOneOrMoreGridEntities = false;
    for (const gridEntity of (0, gridEntities_1.getGridEntities)()) {
        const gridEntityType = gridEntity.GetType();
        const gridIndex = gridEntity.GetGridIndex();
        // We cannot simply check if the grid entity type is equal to a wall because other mods use
        // walls as a base for custom grid entities.
        if (gridEntityType === isaac_typescript_definitions_1.GridEntityType.WALL &&
            (0, roomShapeWalls_1.isVanillaWallGridIndex)(gridIndex)) {
            continue;
        }
        if (gridEntityType === isaac_typescript_definitions_1.GridEntityType.DOOR) {
            continue;
        }
        (0, gridEntities_1.removeGridEntity)(gridEntity, false);
        removedOneOrMoreGridEntities = true;
    }
    if (removedOneOrMoreGridEntities) {
        (0, rooms_1.roomUpdateSafe)();
    }
}
exports.emptyRoomGridEntities = emptyRoomGridEntities;
