"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setRoomData = exports.getRoomVisitedCount = exports.getRoomVariant = exports.getRoomType = exports.getRoomSubType = exports.getRoomStageID = exports.getRoomShape = exports.getRoomName = exports.getRoomListIndex = exports.getRoomGridIndex = exports.getRoomDescriptorReadOnly = exports.getRoomDescriptor = exports.getRoomData = exports.getRoomAllowedDoors = void 0;
const cachedEnumValues_1 = require("../cachedEnumValues");
const cachedClasses_1 = require("../core/cachedClasses");
const doors_1 = require("./doors");
const flag_1 = require("./flag");
/**
 * Helper function to get the set of allowed door slots for the room at the supplied grid index.
 * This corresponds to the doors that are enabled in the STB/XML file for the room.
 */
function getRoomAllowedDoors(roomGridIndex) {
    const allowedDoors = new Set();
    const roomData = getRoomData(roomGridIndex);
    if (roomData === undefined) {
        return allowedDoors;
    }
    for (const doorSlotFlag of cachedEnumValues_1.DOOR_SLOT_FLAG_VALUES) {
        if ((0, flag_1.hasFlag)(roomData.Doors, doorSlotFlag)) {
            const doorSlot = (0, doors_1.doorSlotFlagToDoorSlot)(doorSlotFlag);
            allowedDoors.add(doorSlot);
        }
    }
    return allowedDoors;
}
exports.getRoomAllowedDoors = getRoomAllowedDoors;
function getRoomData(roomGridIndex) {
    const roomDescriptor = getRoomDescriptor(roomGridIndex);
    return roomDescriptor.Data;
}
exports.getRoomData = getRoomData;
/**
 * Helper function to get the descriptor for a room.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function getRoomDescriptor(roomGridIndex) {
    const level = cachedClasses_1.game.GetLevel();
    if (roomGridIndex === undefined) {
        roomGridIndex = getRoomGridIndex();
    }
    return level.GetRoomByIdx(roomGridIndex);
}
exports.getRoomDescriptor = getRoomDescriptor;
/**
 * Alias for the `Level.GetCurrentRoomDesc` method. Use this to make it more clear what type of
 * `RoomDescriptor` object that you are retrieving.
 */
function getRoomDescriptorReadOnly() {
    const level = cachedClasses_1.game.GetLevel();
    return level.GetCurrentRoomDesc();
}
exports.getRoomDescriptorReadOnly = getRoomDescriptorReadOnly;
/**
 * Helper function to get the grid index of the current room.
 *
 * - If the current room is inside of the grid, this function will return the `SafeGridIndex` from
 *   the room descriptor. (The safe grid index is defined as the top-left 1x1 section that the room
 *   overlaps with, or the top-right 1x1 section of a `RoomType.SHAPE_LTL` room.)
 * - If the current room is outside of the grid, it will return the index from the
 *   `Level.GetCurrentRoomIndex` method, since `SafeGridIndex` is bugged for these cases, as
 *   demonstrated by entering a Genesis room and entering `l
 *   print(Game():GetLevel():GetCurrentRoomDesc().SafeGridIndex)` into the console. (It prints -1
 *   instead of -12.)
 *
 * Use this function instead of the `Level.GetCurrentRoomIndex` method directly because the latter
 * will return the specific 1x1 quadrant that the player entered the room at. For most situations,
 * using the safe grid index is more reliable than this.
 *
 * Data structures that store data per room should use the room's `ListIndex` instead of
 * `SafeGridIndex`, since the former is unique across different dimensions.
 */
function getRoomGridIndex() {
    const level = cachedClasses_1.game.GetLevel();
    const currentRoomIndex = level.GetCurrentRoomIndex();
    if (currentRoomIndex < 0) {
        return currentRoomIndex;
    }
    const roomDescriptor = getRoomDescriptorReadOnly();
    return roomDescriptor.SafeGridIndex;
}
exports.getRoomGridIndex = getRoomGridIndex;
/**
 * Helper function to get the list grid index of the provided room, which is equal to the index in
 * the `RoomList.Get` method. In other words, this is equal to the order that the room was created
 * by the floor generation algorithm.
 *
 * Use this as an index for data structures that store data per room, since it is unique across
 * different dimensions.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function getRoomListIndex(roomGridIndex) {
    const roomDescriptor = getRoomDescriptor(roomGridIndex);
    return roomDescriptor.ListIndex;
}
exports.getRoomListIndex = getRoomListIndex;
function getRoomName(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? undefined : roomData.Name;
}
exports.getRoomName = getRoomName;
function getRoomShape(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? undefined : roomData.Shape;
}
exports.getRoomShape = getRoomShape;
function getRoomStageID(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? undefined : roomData.StageID;
}
exports.getRoomStageID = getRoomStageID;
function getRoomSubType(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? undefined : roomData.Subtype;
}
exports.getRoomSubType = getRoomSubType;
/**
 * Helper function for getting the type of the room with the given grid index.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 * @returns The room data type. Returns -1 if the room data was not found.
 */
function getRoomType(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? undefined : roomData.Type;
}
exports.getRoomType = getRoomType;
function getRoomVariant(roomGridIndex) {
    const roomData = getRoomData(roomGridIndex);
    return roomData === undefined ? -1 : roomData.Variant;
}
exports.getRoomVariant = getRoomVariant;
/**
 * Note that the room visited count will be inaccurate during the period before the `POST_NEW_ROOM`
 * callback has fired (i.e. when entities are initializing and performing their first update). This
 * is because the variable is only incremented immediately before the `POST_NEW_ROOM` callback
 * fires.
 *
 * @param roomGridIndex Optional. Default is the current room index.
 */
function getRoomVisitedCount(roomGridIndex) {
    const roomDescriptor = getRoomDescriptor(roomGridIndex);
    return roomDescriptor.VisitedCount;
}
exports.getRoomVisitedCount = getRoomVisitedCount;
/**
 * Helper function to set the data for a given room. This will change the room type, contents, and
 * so on.
 */
function setRoomData(roomGridIndex, roomData) {
    const roomDescriptor = getRoomDescriptor(roomGridIndex);
    roomDescriptor.Data = roomData;
}
exports.setRoomData = setRoomData;
