isaacscript-common
Version:
Helper functions and features for IsaacScript mods.
187 lines (186 loc) • 9.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVanillaWallGridIndexSetForRoomShape = getVanillaWallGridIndexSetForRoomShape;
exports.isVanillaWallGridIndex = isVanillaWallGridIndex;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedEnumValues_1 = require("../cachedEnumValues");
const cachedClasses_1 = require("../core/cachedClasses");
const CornerType_1 = require("../enums/CornerType");
const ReadonlyMap_1 = require("../types/ReadonlyMap");
const ReadonlySet_1 = require("../types/ReadonlySet");
const gridIndex_1 = require("./gridIndex");
const roomShape_1 = require("./roomShape");
const rooms_1 = require("./rooms");
const utils_1 = require("./utils");
const ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP = new ReadonlyMap_1.ReadonlyMap(cachedEnumValues_1.ROOM_SHAPE_VALUES.map((roomShape) => [
roomShape,
getVanillaWallGridIndexSetForRoomShape(roomShape),
]));
/** The Home closet is is 9x3, which is different from `RoomShape.IH` (which is 13x3). */
const HOME_CLOSET_CORNERS = [
{
type: CornerType_1.CornerType.TOP_LEFT,
gridIndex: 30,
position: Vector(60, 220),
},
{
type: CornerType_1.CornerType.TOP_RIGHT,
gridIndex: 38,
position: Vector(340, 220),
},
{
type: CornerType_1.CornerType.BOTTOM_LEFT,
gridIndex: 90,
position: Vector(60, 340),
},
{
type: CornerType_1.CornerType.BOTTOM_RIGHT,
gridIndex: 98,
position: Vector(340, 340),
},
];
const HOME_CLOSET_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(isaac_typescript_definitions_1.RoomShape.IH, HOME_CLOSET_CORNERS);
/**
* The Mother Boss Room is 15x11, which is different from `RoomShape.SHAPE_1x2` (which is 15x16).
*/
const MOTHER_ROOM_CORNERS = [
{
type: CornerType_1.CornerType.TOP_LEFT,
gridIndex: 0,
position: Vector(60, 140),
},
{
type: CornerType_1.CornerType.TOP_RIGHT,
gridIndex: 14,
position: Vector(580, 140),
},
{
type: CornerType_1.CornerType.BOTTOM_LEFT,
gridIndex: 150,
position: Vector(60, 500),
},
{
type: CornerType_1.CornerType.BOTTOM_RIGHT,
gridIndex: 164,
position: Vector(580, 500),
},
];
const MOTHER_ROOM_CORNERS_SET = getVanillaWallGridIndexSetForRectangleRoomShape(isaac_typescript_definitions_1.RoomShape.SHAPE_1x2, MOTHER_ROOM_CORNERS);
/**
* Helper function to get the set of grid indexes that represent where the walls are supposed to be
* in a given room shape.
*
* This function only works reliably in vanilla rooms because in a modded room, it is possible to
* place walls in a non-standard location.
*/
function getVanillaWallGridIndexSetForRoomShape(roomShape) {
const corners = (0, roomShape_1.getRoomShapeCorners)(roomShape);
const lRoom = (0, roomShape_1.isLRoomShape)(roomShape);
if (lRoom && corners.length !== 6) {
error(`Failed to get the correct amount of corners for: RoomShape.${isaac_typescript_definitions_1.RoomShape[roomShape]} (${roomShape})`);
}
switch (roomShape) {
// 9
case isaac_typescript_definitions_1.RoomShape.LTL: {
const [topMiddle, topRight, middleLeft, middle, bottomLeft, bottomRight] = corners;
return new ReadonlySet_1.ReadonlySet([
// Horizontal
...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, topRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, middle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
// Vertical
...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, bottomLeft.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, middle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
]);
}
// 10
case isaac_typescript_definitions_1.RoomShape.LTR: {
const [topLeft, topMiddle, middle, middleRight, bottomLeft, bottomRight] = corners;
return new ReadonlySet_1.ReadonlySet([
// Horizontal
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topMiddle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, middleRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
// Vertical
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topMiddle.gridIndex, middle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middleRight.gridIndex, bottomRight.gridIndex, roomShape),
]);
}
// 11
case isaac_typescript_definitions_1.RoomShape.LBL: {
const [topLeft, topRight, middleLeft, middle, bottomMiddle, bottomRight] = corners;
return new ReadonlySet_1.ReadonlySet([
// Horizontal
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middleLeft.gridIndex, middle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(bottomMiddle.gridIndex, bottomRight.gridIndex, roomShape),
// Vertical
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, middleLeft.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, bottomMiddle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
]);
}
// 12
case isaac_typescript_definitions_1.RoomShape.LBR: {
const [topLeft, topRight, middle, middleRight, bottomLeft, bottomMiddle] = corners;
return new ReadonlySet_1.ReadonlySet([
// Horizontal
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, middleRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomMiddle.gridIndex, roomShape),
// Vertical
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(middle.gridIndex, bottomMiddle.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, middleRight.gridIndex, roomShape),
]);
}
default: {
return getVanillaWallGridIndexSetForRectangleRoomShape(roomShape, corners);
}
}
}
/**
* Providing the room shape is necessary so that the `getGridIndexesBetween` function can use the
* corresponding grid width.
*/
function getVanillaWallGridIndexSetForRectangleRoomShape(roomShape, corners) {
if (corners.length !== 4) {
error("Failed to get the correct amount of corners for rectangular room shape.");
}
const [topLeft, topRight, bottomLeft, bottomRight] = corners;
return new ReadonlySet_1.ReadonlySet([
// Horizontal
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, topRight.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(bottomLeft.gridIndex, bottomRight.gridIndex, roomShape),
// Vertical
...(0, gridIndex_1.getGridIndexesBetween)(topLeft.gridIndex, bottomLeft.gridIndex, roomShape),
...(0, gridIndex_1.getGridIndexesBetween)(topRight.gridIndex, bottomRight.gridIndex, roomShape),
]);
}
/**
* Helper function to determine if a given grid index should have a wall generated by the vanilla
* game. This is useful as a mechanism to distinguish between real walls and custom walls spawned by
* mods.
*
* This function properly handles the special cases of the Mother boss room and the Home closet
* rooms, which are both non-standard room shapes.
*/
function isVanillaWallGridIndex(gridIndex) {
const room = cachedClasses_1.game.GetRoom();
const roomShape = room.GetRoomShape();
// Handle the special cases of non-standard room shapes.
let wallGridIndexSet;
if ((0, rooms_1.inHomeCloset)()) {
wallGridIndexSet = HOME_CLOSET_CORNERS_SET;
}
else if ((0, rooms_1.inBossRoomOf)(isaac_typescript_definitions_1.BossID.MOTHER)) {
wallGridIndexSet = MOTHER_ROOM_CORNERS_SET;
}
else {
wallGridIndexSet = ROOM_SHAPE_TO_WALL_GRID_INDEX_MAP.get(roomShape);
(0, utils_1.assertDefined)(wallGridIndexSet, `Failed to find the wall grid index set for: RoomShape.${isaac_typescript_definitions_1.RoomShape[roomShape]} (${roomShape})`);
}
return wallGridIndexSet.has(gridIndex);
}