isaacscript-common 6.19.0 → 6.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.lua +4 -0
- package/dist/features/customStage/exports.d.ts +6 -1
- package/dist/features/customStage/exports.d.ts.map +1 -1
- package/dist/features/customStage/exports.lua +14 -11
- package/dist/features/customTrapdoor/blackSprite.d.ts.map +1 -1
- package/dist/features/customTrapdoor/blackSprite.lua +1 -0
- package/dist/features/customTrapdoor/init.d.ts.map +1 -1
- package/dist/features/customTrapdoor/init.lua +10 -2
- package/dist/features/extraConsoleCommands/commandsSubroutines.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/commandsSubroutines.lua +2 -1
- package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/listCommands.lua +2 -1
- package/dist/functions/curses.d.ts +3 -0
- package/dist/functions/curses.d.ts.map +1 -0
- package/dist/functions/curses.lua +11 -0
- package/dist/functions/dimensions.d.ts +12 -0
- package/dist/functions/dimensions.d.ts.map +1 -0
- package/dist/functions/dimensions.lua +35 -0
- package/dist/functions/level.d.ts.map +1 -1
- package/dist/functions/level.lua +8 -7
- package/dist/functions/levelGrid.d.ts +155 -0
- package/dist/functions/levelGrid.d.ts.map +1 -0
- package/dist/functions/levelGrid.lua +349 -0
- package/dist/functions/roomData.d.ts +6 -1
- package/dist/functions/roomData.d.ts.map +1 -1
- package/dist/functions/roomData.lua +6 -0
- package/dist/functions/roomGrid.d.ts +8 -0
- package/dist/functions/roomGrid.d.ts.map +1 -1
- package/dist/functions/rooms.d.ts +67 -68
- package/dist/functions/rooms.d.ts.map +1 -1
- package/dist/functions/rooms.lua +176 -203
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +24 -0
- package/package.json +2 -2
- package/src/constants.ts +8 -0
- package/src/features/customStage/exports.ts +25 -14
- package/src/features/customTrapdoor/blackSprite.ts +1 -0
- package/src/features/customTrapdoor/init.ts +7 -3
- package/src/features/extraConsoleCommands/commandsSubroutines.ts +2 -1
- package/src/features/extraConsoleCommands/listCommands.ts +2 -1
- package/src/functions/curses.ts +9 -0
- package/src/functions/dimensions.ts +41 -0
- package/src/functions/level.ts +7 -10
- package/src/functions/levelGrid.ts +468 -0
- package/src/functions/roomData.ts +13 -1
- package/src/functions/roomGrid.ts +9 -0
- package/src/functions/rooms.ts +161 -219
- package/src/index.ts +3 -0
package/src/functions/rooms.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AngelRoomSubType,
|
|
3
|
+
BackdropType,
|
|
3
4
|
BossID,
|
|
4
5
|
Dimension,
|
|
5
6
|
Direction,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
GridRoom,
|
|
9
10
|
HomeRoomSubType,
|
|
10
11
|
ItemPoolType,
|
|
12
|
+
LevelCurse,
|
|
11
13
|
MinibossID,
|
|
12
14
|
RoomDescriptorFlag,
|
|
13
15
|
RoomShape,
|
|
@@ -17,14 +19,11 @@ import {
|
|
|
17
19
|
StageID,
|
|
18
20
|
} from "isaac-typescript-definitions";
|
|
19
21
|
import { game, sfxManager } from "../cachedClasses";
|
|
20
|
-
import {
|
|
21
|
-
LEVEL_GRID_ROW_WIDTH,
|
|
22
|
-
MAX_LEVEL_GRID_INDEX,
|
|
23
|
-
NUM_DIMENSIONS,
|
|
24
|
-
} from "../constants";
|
|
25
|
-
import { ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA } from "../objects/roomShapeToDoorSlotsToGridIndexDelta";
|
|
22
|
+
import { MAX_LEVEL_GRID_INDEX, NUM_DIMENSIONS } from "../constants";
|
|
26
23
|
import { ROOM_TYPE_NAMES } from "../objects/roomTypeNames";
|
|
27
24
|
import { MINE_SHAFT_ROOM_SUB_TYPE_SET } from "../sets/mineShaftRoomSubTypesSet";
|
|
25
|
+
import { hasCurse } from "./curses";
|
|
26
|
+
import { inDimension } from "./dimensions";
|
|
28
27
|
import {
|
|
29
28
|
closeAllDoors,
|
|
30
29
|
getDoors,
|
|
@@ -40,17 +39,15 @@ import {
|
|
|
40
39
|
setEntityVelocities,
|
|
41
40
|
} from "./positionVelocity";
|
|
42
41
|
import {
|
|
43
|
-
getRoomAllowedDoors,
|
|
44
42
|
getRoomData,
|
|
45
43
|
getRoomDescriptor,
|
|
46
44
|
getRoomDescriptorReadOnly,
|
|
47
45
|
getRoomGridIndex,
|
|
48
46
|
getRoomName,
|
|
49
|
-
getRoomShape,
|
|
50
47
|
getRoomStageID,
|
|
51
48
|
getRoomSubType,
|
|
52
49
|
} from "./roomData";
|
|
53
|
-
import {
|
|
50
|
+
import { getGotoCommand } from "./stage";
|
|
54
51
|
import { erange, irange } from "./utils";
|
|
55
52
|
|
|
56
53
|
/**
|
|
@@ -76,72 +73,85 @@ export function changeRoom(roomGridIndex: int): void {
|
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
/**
|
|
79
|
-
* Helper function to get
|
|
76
|
+
* Helper function to get the number of rooms that are currently on the floor layout. This does not
|
|
77
|
+
* include off-grid rooms, like the Devil Room.
|
|
80
78
|
*/
|
|
81
|
-
export function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/** Helper function to get the grid index for every room on the entire floor. */
|
|
86
|
-
export function getAllRoomGridIndexes(): int[] {
|
|
87
|
-
const rooms = getRooms();
|
|
88
|
-
return rooms.map((roomDescriptor) => roomDescriptor.SafeGridIndex);
|
|
79
|
+
export function getNumRooms(): int {
|
|
80
|
+
const rooms = getRoomsInGrid();
|
|
81
|
+
return rooms.length;
|
|
89
82
|
}
|
|
90
83
|
|
|
91
84
|
/**
|
|
92
|
-
* Helper function to get
|
|
93
|
-
*
|
|
85
|
+
* Helper function to get a read-only copy of the room descriptor for every room on the level. This
|
|
86
|
+
* includes off-grid rooms, such as the Devil Room, and extra-dimensional rooms, if they are
|
|
87
|
+
* generated and exist.
|
|
88
|
+
*
|
|
89
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
90
|
+
*
|
|
91
|
+
* Under the hood, this is performed by iterating over the `RoomList` from the `Level.GetRooms`
|
|
92
|
+
* method. This is the best way to see if off-grid rooms have been initialized, since it is possible
|
|
93
|
+
* for mods to insert room data at non-official negative room grid indexes.
|
|
94
94
|
*/
|
|
95
|
-
export function
|
|
95
|
+
export function getReadOnlyRooms(): Array<Readonly<RoomDescriptor>> {
|
|
96
96
|
const level = game.GetLevel();
|
|
97
|
-
const
|
|
98
|
-
const roomDescription = level.GetRoomByIdx(roomGridIndex, Dimension.CURRENT);
|
|
99
|
-
const currentRoomHash = GetPtrHash(roomDescription);
|
|
97
|
+
const roomList = level.GetRooms();
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
const dimensionRoomDescription = level.GetRoomByIdx(
|
|
103
|
-
roomGridIndex,
|
|
104
|
-
dimension,
|
|
105
|
-
);
|
|
106
|
-
const dimensionRoomHash = GetPtrHash(dimensionRoomDescription);
|
|
99
|
+
const readOnlyRoomDescriptors: Array<Readonly<RoomDescriptor>> = [];
|
|
107
100
|
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
for (let i = 0; i < roomList.Size; i++) {
|
|
102
|
+
const readOnlyRoomDescriptor = roomList.Get(i);
|
|
103
|
+
if (
|
|
104
|
+
readOnlyRoomDescriptor !== undefined &&
|
|
105
|
+
readOnlyRoomDescriptor.Data !== undefined
|
|
106
|
+
) {
|
|
107
|
+
readOnlyRoomDescriptors.push(readOnlyRoomDescriptor);
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Helper function to get the number of rooms that are currently on the floor layout. This does not
|
|
118
|
-
* include off-grid rooms, like the Devil Room.
|
|
119
|
-
*/
|
|
120
|
-
export function getNumRooms(): int {
|
|
121
|
-
const rooms = getRooms();
|
|
122
|
-
return rooms.length;
|
|
111
|
+
return readOnlyRoomDescriptors;
|
|
123
112
|
}
|
|
124
113
|
|
|
125
114
|
/**
|
|
126
|
-
* Helper function to get
|
|
127
|
-
* specified room
|
|
115
|
+
* Helper function to get the room data for a specific room type and variant combination. This is
|
|
116
|
+
* accomplished by using the "goto" console command to load the specified room into the
|
|
117
|
+
* `GridRoom.DEBUG` slot.
|
|
128
118
|
*
|
|
129
|
-
*
|
|
119
|
+
* Returns undefined if the provided room type and variant combination were not found. (A warning
|
|
120
|
+
* message will also appear on the console, since the "goto" command will fail.)
|
|
130
121
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
122
|
+
* Note that the side effect of using the "goto" console command is that it will trigger a room
|
|
123
|
+
* transition after a short delay. By default, this function cancels the incoming room transition by
|
|
124
|
+
* using the `Game.StartRoomTransition` method to travel to the same room.
|
|
125
|
+
*
|
|
126
|
+
* @param roomType The type of room to retrieve.
|
|
127
|
+
* @param roomVariant The room variant to retrieve. (The room variant is the "ID" of the room in
|
|
128
|
+
* Basement Renovator.)
|
|
129
|
+
* @param cancelRoomTransition Optional. Whether to cancel the room transition by using the
|
|
130
|
+
* `Game.StartRoomTransition` method to travel to the same room. Default
|
|
131
|
+
* is true. Set this to false if you are getting the data for many rooms
|
|
132
|
+
* at the same time, and then use the `teleport` helper function when
|
|
133
|
+
* you are finished.
|
|
133
134
|
*/
|
|
134
|
-
export function
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
export function getRoomDataForTypeVariant(
|
|
136
|
+
roomType: RoomType,
|
|
137
|
+
roomVariant: int,
|
|
138
|
+
cancelRoomTransition = true,
|
|
139
|
+
): Readonly<RoomConfig> | undefined {
|
|
140
|
+
const command = getGotoCommand(roomType, roomVariant);
|
|
141
|
+
Isaac.ExecuteCommand(command);
|
|
142
|
+
const newRoomData = getRoomData(GridRoom.DEBUG);
|
|
143
|
+
|
|
144
|
+
if (cancelRoomTransition) {
|
|
145
|
+
const roomGridIndex = getRoomGridIndex();
|
|
146
|
+
teleport(
|
|
147
|
+
roomGridIndex,
|
|
148
|
+
Direction.NO_DIRECTION,
|
|
149
|
+
RoomTransitionAnim.FADE,
|
|
150
|
+
true,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
143
153
|
|
|
144
|
-
return
|
|
154
|
+
return newRoomData;
|
|
145
155
|
}
|
|
146
156
|
|
|
147
157
|
/**
|
|
@@ -157,40 +167,6 @@ export function getRoomItemPoolType(): ItemPoolType {
|
|
|
157
167
|
return itemPool.GetPoolForRoom(roomType, roomSeed);
|
|
158
168
|
}
|
|
159
169
|
|
|
160
|
-
/**
|
|
161
|
-
* Helper function to get the grid indexes of all the rooms connected to the given room index.
|
|
162
|
-
*
|
|
163
|
-
* @param roomGridIndex Optional. Default is the current room index.
|
|
164
|
-
*/
|
|
165
|
-
export function getRoomNeighbors(roomGridIndex?: int): int[] {
|
|
166
|
-
const roomDescriptor = getRoomDescriptor(roomGridIndex);
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
roomDescriptor.SafeGridIndex < 0 ||
|
|
170
|
-
roomDescriptor.SafeGridIndex > MAX_LEVEL_GRID_INDEX
|
|
171
|
-
) {
|
|
172
|
-
return [];
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const roomData = roomDescriptor.Data;
|
|
176
|
-
if (roomData === undefined) {
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const roomShape = roomData.Shape;
|
|
181
|
-
const gridIndexDeltas = getRoomShapeNeighborGridIndexDeltas(roomShape);
|
|
182
|
-
const gridIndexes = gridIndexDeltas.map(
|
|
183
|
-
(gridIndexDelta) => roomDescriptor.SafeGridIndex + gridIndexDelta,
|
|
184
|
-
);
|
|
185
|
-
return gridIndexes.filter((gridIndex) => roomExists(gridIndex));
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export function getRoomShapeNeighborGridIndexDeltas(
|
|
189
|
-
roomShape: RoomShape,
|
|
190
|
-
): int[] {
|
|
191
|
-
return [...ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA[roomShape].values()];
|
|
192
|
-
}
|
|
193
|
-
|
|
194
170
|
/**
|
|
195
171
|
* Helper function to get the proper name of a room type.
|
|
196
172
|
*
|
|
@@ -201,77 +177,106 @@ export function getRoomTypeName(roomType: RoomType): string {
|
|
|
201
177
|
}
|
|
202
178
|
|
|
203
179
|
/**
|
|
204
|
-
* Helper function to get the room descriptor for every room on the level
|
|
205
|
-
*
|
|
206
|
-
*
|
|
180
|
+
* Helper function to get the room descriptor for every room on the level. This includes off-grid
|
|
181
|
+
* rooms, such as the Devil Room.
|
|
182
|
+
*
|
|
183
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
184
|
+
*
|
|
185
|
+
* - If you want just the rooms inside of the grid, use the `getRoomsInGrid` helper function.
|
|
186
|
+
* - If you want just the rooms outside of the grid, use the `getRoomsOutsideGrid` helper function.
|
|
207
187
|
*
|
|
208
188
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
209
|
-
* extra-dimensional rooms are automatically generated
|
|
210
|
-
*
|
|
189
|
+
* extra-dimensional rooms are automatically generated. Default is
|
|
190
|
+
* false.
|
|
211
191
|
*/
|
|
212
192
|
export function getRooms(
|
|
213
193
|
includeExtraDimensionalRooms = false,
|
|
214
194
|
): RoomDescriptor[] {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const roomDescriptor = roomList.Get(i);
|
|
222
|
-
if (roomDescriptor !== undefined && roomDescriptor.Data !== undefined) {
|
|
223
|
-
roomsMap.set(roomDescriptor.ListIndex, roomDescriptor);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
} else {
|
|
227
|
-
for (const roomGridIndex of irange(MAX_LEVEL_GRID_INDEX)) {
|
|
228
|
-
const roomDescriptor = level.GetRoomByIdx(roomGridIndex);
|
|
229
|
-
if (roomDescriptor.Data !== undefined) {
|
|
230
|
-
roomsMap.set(roomDescriptor.ListIndex, roomDescriptor);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return [...roomsMap.values()];
|
|
195
|
+
// The obvious way to get all of the rooms would be to iterate over the `RoomList` from the
|
|
196
|
+
// `Level.GetRooms` method. However, this results in read-only data, and we want to return a
|
|
197
|
+
// writable object. Instead, we let the heavy lifting be handled by other functions.
|
|
198
|
+
const roomsInGrid = getRoomsInGrid(includeExtraDimensionalRooms);
|
|
199
|
+
const roomsOutsideGrid = getRoomsOutsideGrid();
|
|
200
|
+
return [...roomsInGrid, ...roomsOutsideGrid];
|
|
236
201
|
}
|
|
237
202
|
|
|
238
203
|
/**
|
|
239
|
-
* Helper function to get the room descriptor for every room on the level
|
|
240
|
-
*
|
|
241
|
-
*
|
|
204
|
+
* Helper function to get the room descriptor for every room on the level that is on the grid. (For
|
|
205
|
+
* example, Devil Rooms are excluded.)
|
|
206
|
+
*
|
|
207
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
242
208
|
*
|
|
243
209
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
244
|
-
* extra-dimensional rooms are automatically be generated
|
|
245
|
-
*
|
|
210
|
+
* extra-dimensional rooms are automatically be generated. Default
|
|
211
|
+
* is false.
|
|
246
212
|
*/
|
|
247
213
|
export function getRoomsInGrid(
|
|
248
214
|
includeExtraDimensionalRooms = false,
|
|
249
215
|
): RoomDescriptor[] {
|
|
250
|
-
const
|
|
251
|
-
|
|
216
|
+
const level = game.GetLevel();
|
|
217
|
+
|
|
218
|
+
const dimensions = includeExtraDimensionalRooms
|
|
219
|
+
? (erange(NUM_DIMENSIONS) as Dimension[])
|
|
220
|
+
: [Dimension.CURRENT];
|
|
221
|
+
|
|
222
|
+
/** We use a map instead of an array because room shapes occupy more than one room grid index. */
|
|
223
|
+
const roomDescriptorMap = new Map<PtrHash, RoomDescriptor>();
|
|
224
|
+
|
|
225
|
+
for (const dimension of dimensions) {
|
|
226
|
+
for (const roomGridIndex of irange(MAX_LEVEL_GRID_INDEX)) {
|
|
227
|
+
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
228
|
+
if (roomDescriptor.Data !== undefined) {
|
|
229
|
+
const ptrHash = GetPtrHash(roomDescriptor);
|
|
230
|
+
roomDescriptorMap.set(ptrHash, roomDescriptor);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return [...roomDescriptorMap.values()];
|
|
252
236
|
}
|
|
253
237
|
|
|
254
238
|
/**
|
|
255
239
|
* Helper function to get the room descriptor for every room on the level in a specific dimension.
|
|
256
|
-
*
|
|
257
|
-
* non-existent and are not added to the list.
|
|
240
|
+
* This will not include any off-grid rooms, such as the Devil Room.
|
|
258
241
|
*
|
|
259
|
-
*
|
|
242
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
260
243
|
*/
|
|
261
244
|
export function getRoomsOfDimension(dimension: Dimension): RoomDescriptor[] {
|
|
262
245
|
const level = game.GetLevel();
|
|
263
246
|
|
|
264
|
-
|
|
247
|
+
/** We use a map instead of an array because room shapes occupy more than one room grid index. */
|
|
248
|
+
const roomsMap = new Map<PtrHash, RoomDescriptor>();
|
|
249
|
+
|
|
265
250
|
for (const roomGridIndex of irange(MAX_LEVEL_GRID_INDEX)) {
|
|
266
251
|
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
267
252
|
if (roomDescriptor.Data !== undefined) {
|
|
268
|
-
|
|
253
|
+
const ptrHash = GetPtrHash(roomDescriptor);
|
|
254
|
+
roomsMap.set(ptrHash, roomDescriptor);
|
|
269
255
|
}
|
|
270
256
|
}
|
|
271
257
|
|
|
272
258
|
return [...roomsMap.values()];
|
|
273
259
|
}
|
|
274
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Helper function to get the room descriptor for every room on the level that is outside of the
|
|
263
|
+
* grid (like a Devil Room).
|
|
264
|
+
*
|
|
265
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
266
|
+
*/
|
|
267
|
+
export function getRoomsOutsideGrid(): RoomDescriptor[] {
|
|
268
|
+
// We filter an array of all rooms instead of iterating over the `GridRoom` enum because it is
|
|
269
|
+
// possible for mods to insert data at arbitrary negative room grid indexes.
|
|
270
|
+
const readOnlyRooms = getReadOnlyRooms();
|
|
271
|
+
const readOnlyRoomsOffGrid = readOnlyRooms.filter(
|
|
272
|
+
(readOnlyRoomDescriptor) => readOnlyRoomDescriptor.SafeGridIndex < 0,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
return readOnlyRoomsOffGrid.map((readOnlyRoomDescriptor) =>
|
|
276
|
+
getRoomDescriptor(readOnlyRoomDescriptor.SafeGridIndex),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
275
280
|
/**
|
|
276
281
|
* Helper function to determine if the current room shape is equal to `RoomShape.1x2` or
|
|
277
282
|
* `RoomShape.2x1`.
|
|
@@ -361,10 +366,6 @@ export function inDevilsCrownTreasureRoom(): boolean {
|
|
|
361
366
|
return hasFlag(roomDescriptor.Flags, RoomDescriptorFlag.DEVIL_TREASURE);
|
|
362
367
|
}
|
|
363
368
|
|
|
364
|
-
export function inDimension(dimension: Dimension): boolean {
|
|
365
|
-
return dimension === getDimension();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
369
|
export function inDoubleTrouble(): boolean {
|
|
369
370
|
const room = game.GetRoom();
|
|
370
371
|
const roomType = room.GetType();
|
|
@@ -462,7 +463,7 @@ export function inStartingRoom(): boolean {
|
|
|
462
463
|
/**
|
|
463
464
|
* Helper function to loop through every room on the floor and see if it has been cleared.
|
|
464
465
|
*
|
|
465
|
-
* This function will only check rooms
|
|
466
|
+
* This function will only check rooms inside the gird and inside the current dimension.
|
|
466
467
|
*
|
|
467
468
|
* @param onlyCheckRoomTypes Optional. A whitelist of room types. If specified, room types not in
|
|
468
469
|
* the array will be ignored. If not specified, then all rooms will be
|
|
@@ -471,7 +472,7 @@ export function inStartingRoom(): boolean {
|
|
|
471
472
|
export function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolean {
|
|
472
473
|
const roomTypeWhitelist =
|
|
473
474
|
onlyCheckRoomTypes === undefined ? null : new Set(onlyCheckRoomTypes);
|
|
474
|
-
const rooms =
|
|
475
|
+
const rooms = getRoomsInGrid();
|
|
475
476
|
const matchingRooms =
|
|
476
477
|
roomTypeWhitelist === null
|
|
477
478
|
? rooms
|
|
@@ -484,87 +485,6 @@ export function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolean {
|
|
|
484
485
|
return matchingRooms.every((roomDescriptor) => roomDescriptor.Clear);
|
|
485
486
|
}
|
|
486
487
|
|
|
487
|
-
export function isDoorSlotValidAtGridIndex(
|
|
488
|
-
doorSlot: DoorSlot,
|
|
489
|
-
roomGridIndex: int,
|
|
490
|
-
): boolean {
|
|
491
|
-
const allowedDoors = getRoomAllowedDoors(roomGridIndex);
|
|
492
|
-
return allowedDoors.has(doorSlot);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
export function isDoorSlotValidAtGridIndexForRedRoom(
|
|
496
|
-
doorSlot: DoorSlot,
|
|
497
|
-
roomGridIndex: int,
|
|
498
|
-
): boolean {
|
|
499
|
-
const doorSlotValidAtGridIndex = isDoorSlotValidAtGridIndex(
|
|
500
|
-
doorSlot,
|
|
501
|
-
roomGridIndex,
|
|
502
|
-
);
|
|
503
|
-
if (!doorSlotValidAtGridIndex) {
|
|
504
|
-
return false;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
const roomShape = getRoomShape(roomGridIndex);
|
|
508
|
-
if (roomShape === undefined) {
|
|
509
|
-
return false;
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
const delta = getGridIndexDelta(roomShape, doorSlot);
|
|
513
|
-
if (delta === undefined) {
|
|
514
|
-
return false;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
const redRoomGridIndex = roomGridIndex + delta;
|
|
518
|
-
return (
|
|
519
|
-
!roomExists(redRoomGridIndex) &&
|
|
520
|
-
redRoomGridIndex >= 0 &&
|
|
521
|
-
redRoomGridIndex <= MAX_LEVEL_GRID_INDEX
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
/**
|
|
526
|
-
* Helper function to detect if the provided room was created by the Red Key item. Under the hood,
|
|
527
|
-
* this checks for the `RoomDescriptorFlag.FLAG_RED_ROOM` flag.
|
|
528
|
-
*
|
|
529
|
-
* @param roomGridIndex Optional. Default is the current room index.
|
|
530
|
-
*/
|
|
531
|
-
export function isRedKeyRoom(roomGridIndex?: int): boolean {
|
|
532
|
-
const roomDescriptor = getRoomDescriptor(roomGridIndex);
|
|
533
|
-
return hasFlag(roomDescriptor.Flags, RoomDescriptorFlag.RED_ROOM);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Helper function to determine if the provided room is part of the floor layout. For example, Devil
|
|
538
|
-
* Rooms and the Mega Satan room are not considered to be inside the map.
|
|
539
|
-
*
|
|
540
|
-
* @param roomGridIndex Optional. Default is the current room index.
|
|
541
|
-
*/
|
|
542
|
-
export function isRoomInsideMap(roomGridIndex?: int): boolean {
|
|
543
|
-
if (roomGridIndex === undefined) {
|
|
544
|
-
roomGridIndex = getRoomGridIndex();
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
return roomGridIndex >= 0;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/** Helper function to check if a room exists at the given room grid index. */
|
|
551
|
-
export function roomExists(roomGridIndex: int): boolean {
|
|
552
|
-
const roomData = getRoomData(roomGridIndex);
|
|
553
|
-
return roomData !== undefined;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Helper function to get the coordinates of a given grid index. The floor is represented by a 13x13
|
|
558
|
-
* grid. For example, since the starting room is in the center, the starting room grid index of 84
|
|
559
|
-
* be equal to coordinates of (?, ?).
|
|
560
|
-
*/
|
|
561
|
-
export function roomGridIndexToXY(roomGridIndex: int): [x: int, y: int] {
|
|
562
|
-
const x = roomGridIndex % LEVEL_GRID_ROW_WIDTH;
|
|
563
|
-
const y = Math.floor(roomGridIndex / LEVEL_GRID_ROW_WIDTH);
|
|
564
|
-
|
|
565
|
-
return [x, y];
|
|
566
|
-
}
|
|
567
|
-
|
|
568
488
|
/**
|
|
569
489
|
* If the `Room.Update` method is called in a `POST_NEW_ROOM` callback, then some entities will
|
|
570
490
|
* slide around (such as the player). Since those entity velocities are already at zero, setting
|
|
@@ -584,6 +504,11 @@ export function roomUpdateSafe(): void {
|
|
|
584
504
|
setEntityVelocities(entityVelocities, entities);
|
|
585
505
|
}
|
|
586
506
|
|
|
507
|
+
/** Helper function to set the backdrop of the current room. */
|
|
508
|
+
export function setBackdrop(backdropType: BackdropType): void {
|
|
509
|
+
game.ShowHallucination(0, backdropType);
|
|
510
|
+
}
|
|
511
|
+
|
|
587
512
|
/**
|
|
588
513
|
* Helper function to convert an uncleared room to a cleared room in the `POST_NEW_ROOM` callback.
|
|
589
514
|
* This is useful because if enemies are removed in this callback, a room drop will be awarded and
|
|
@@ -635,21 +560,34 @@ export function setRoomUncleared(): void {
|
|
|
635
560
|
/**
|
|
636
561
|
* Helper function to change the current room. It can be used for both teleportation and "normal"
|
|
637
562
|
* room transitions, depending on what is passed for the `direction` and `roomTransitionAnim`
|
|
638
|
-
* arguments.
|
|
639
|
-
*
|
|
640
|
-
*
|
|
563
|
+
* arguments.
|
|
564
|
+
*
|
|
565
|
+
* Use this function instead of invoking the `Game.StartRoomTransition` method directly so that:
|
|
566
|
+
* - you do not forget to set `Level.LeaveDoor` property
|
|
567
|
+
* - to prevent crashing on invalid room grid indexes
|
|
568
|
+
* - to automatically handle Curse of the Maze
|
|
641
569
|
*
|
|
642
570
|
* @param roomGridIndex The room grid index of the destination room.
|
|
643
571
|
* @param direction Optional. Default is `Direction.NO_DIRECTION`.
|
|
644
572
|
* @param roomTransitionAnim Optional. Default is `RoomTransitionAnim.TELEPORT`.
|
|
573
|
+
* @param force Optional. Whether to temporarily disable Curse of the Maze. Default is false. If set
|
|
574
|
+
* to false, then this function may not go to the provided room grid index.
|
|
645
575
|
*/
|
|
646
576
|
export function teleport(
|
|
647
577
|
roomGridIndex: int,
|
|
648
578
|
direction = Direction.NO_DIRECTION,
|
|
649
579
|
roomTransitionAnim = RoomTransitionAnim.TELEPORT,
|
|
580
|
+
force = false,
|
|
650
581
|
): void {
|
|
651
582
|
const level = game.GetLevel();
|
|
652
583
|
|
|
584
|
+
// Before starting a room transition, we must ensure that Curse of the Maze is not in effect, or
|
|
585
|
+
// else the room transition might send us to the wrong room.
|
|
586
|
+
const shouldTempDisableCurse = force && hasCurse(LevelCurse.MAZE);
|
|
587
|
+
if (shouldTempDisableCurse) {
|
|
588
|
+
level.RemoveCurses(LevelCurse.MAZE);
|
|
589
|
+
}
|
|
590
|
+
|
|
653
591
|
const roomData = getRoomData(roomGridIndex);
|
|
654
592
|
if (roomData === undefined) {
|
|
655
593
|
error(
|
|
@@ -662,4 +600,8 @@ export function teleport(
|
|
|
662
600
|
level.LeaveDoor = DoorSlot.NO_DOOR_SLOT;
|
|
663
601
|
|
|
664
602
|
game.StartRoomTransition(roomGridIndex, direction, roomTransitionAnim);
|
|
603
|
+
|
|
604
|
+
if (shouldTempDisableCurse) {
|
|
605
|
+
level.AddCurse(LevelCurse.MAZE, false);
|
|
606
|
+
}
|
|
665
607
|
}
|
package/src/index.ts
CHANGED
|
@@ -97,9 +97,11 @@ export * from "./functions/collectibles";
|
|
|
97
97
|
export * from "./functions/collectibleSet";
|
|
98
98
|
export * from "./functions/collectibleTag";
|
|
99
99
|
export * from "./functions/color";
|
|
100
|
+
export * from "./functions/curses";
|
|
100
101
|
export * from "./functions/debug";
|
|
101
102
|
export * from "./functions/deepCopy";
|
|
102
103
|
export * from "./functions/deepCopyTests";
|
|
104
|
+
export * from "./functions/dimensions";
|
|
103
105
|
export * from "./functions/direction";
|
|
104
106
|
export * from "./functions/doors";
|
|
105
107
|
export * from "./functions/easing";
|
|
@@ -123,6 +125,7 @@ export * from "./functions/jsonRoom";
|
|
|
123
125
|
export * from "./functions/kColor";
|
|
124
126
|
export * from "./functions/language";
|
|
125
127
|
export * from "./functions/level";
|
|
128
|
+
export * from "./functions/levelGrid";
|
|
126
129
|
export * from "./functions/log";
|
|
127
130
|
export * from "./functions/map";
|
|
128
131
|
export * from "./functions/math";
|