isaacscript-common 13.0.0 → 13.1.0
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/index.d.ts +105 -26
- package/dist/isaacscript-common.lua +615 -168
- package/dist/src/features/customStage/backdrop.lua +4 -4
- package/dist/src/features/customStage/versusScreen.lua +2 -2
- package/dist/src/features/deployJSONRoom.d.ts +0 -11
- package/dist/src/features/deployJSONRoom.d.ts.map +1 -1
- package/dist/src/features/deployJSONRoom.lua +10 -74
- package/dist/src/features/extraConsoleCommands/listCommands.lua +2 -2
- package/dist/src/features/firstLast.lua +8 -8
- package/dist/src/features/setHotkey.d.ts +27 -8
- package/dist/src/features/setHotkey.d.ts.map +1 -1
- package/dist/src/features/setHotkey.lua +41 -30
- package/dist/src/functions/array.lua +2 -2
- package/dist/src/functions/cards.lua +2 -2
- package/dist/src/functions/collectibles.lua +2 -2
- package/dist/src/functions/dimensions.lua +2 -2
- package/dist/src/functions/emptyRoom.d.ts +8 -0
- package/dist/src/functions/emptyRoom.d.ts.map +1 -0
- package/dist/src/functions/emptyRoom.lua +74 -0
- package/dist/src/functions/enums.d.ts.map +1 -1
- package/dist/src/functions/enums.lua +3 -3
- package/dist/src/functions/gridEntities.lua +2 -2
- package/dist/src/functions/gridIndex.d.ts +10 -0
- package/dist/src/functions/gridIndex.d.ts.map +1 -0
- package/dist/src/functions/gridIndex.lua +32 -0
- package/dist/src/functions/log.d.ts.map +1 -1
- package/dist/src/functions/log.lua +9 -8
- package/dist/src/functions/logEntities.d.ts.map +1 -1
- package/dist/src/functions/logEntities.lua +17 -9
- package/dist/src/functions/pills.lua +4 -4
- package/dist/src/functions/roomShape.d.ts +6 -1
- package/dist/src/functions/roomShape.d.ts.map +1 -1
- package/dist/src/functions/roomShape.lua +3 -0
- package/dist/src/functions/roomShapeWalls.d.ts +20 -0
- package/dist/src/functions/roomShapeWalls.d.ts.map +1 -0
- package/dist/src/functions/roomShapeWalls.lua +285 -0
- package/dist/src/functions/rooms.d.ts +7 -0
- package/dist/src/functions/rooms.d.ts.map +1 -1
- package/dist/src/functions/rooms.lua +16 -5
- package/dist/src/functions/set.d.ts +7 -0
- package/dist/src/functions/set.d.ts.map +1 -1
- package/dist/src/functions/set.lua +10 -0
- package/dist/src/functions/sprites.lua +2 -2
- package/dist/src/functions/trinkets.lua +2 -2
- package/dist/src/functions/utils.d.ts +18 -12
- package/dist/src/functions/utils.d.ts.map +1 -1
- package/dist/src/functions/utils.lua +26 -14
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.lua +24 -0
- package/dist/src/interfaces/Corner.d.ts +8 -0
- package/dist/src/interfaces/Corner.d.ts.map +1 -1
- package/dist/src/objects/roomShapeCorners.d.ts +6 -1
- package/dist/src/objects/roomShapeCorners.d.ts.map +1 -1
- package/dist/src/objects/roomShapeCorners.lua +71 -14
- package/package.json +2 -2
- package/src/features/customStage/backdrop.ts +3 -3
- package/src/features/customStage/versusScreen.ts +2 -2
- package/src/features/deployJSONRoom.ts +8 -98
- package/src/features/extraConsoleCommands/listCommands.ts +2 -2
- package/src/features/firstLast.ts +8 -8
- package/src/features/setHotkey.ts +60 -40
- package/src/functions/array.ts +2 -2
- package/src/functions/cards.ts +2 -2
- package/src/functions/collectibles.ts +2 -2
- package/src/functions/dimensions.ts +2 -2
- package/src/functions/emptyRoom.ts +85 -0
- package/src/functions/enums.ts +4 -3
- package/src/functions/gridEntities.ts +2 -2
- package/src/functions/gridIndex.ts +40 -0
- package/src/functions/log.ts +9 -10
- package/src/functions/logEntities.ts +25 -9
- package/src/functions/pills.ts +4 -4
- package/src/functions/roomShape.ts +6 -1
- package/src/functions/roomShapeWalls.ts +359 -0
- package/src/functions/rooms.ts +22 -3
- package/src/functions/set.ts +12 -0
- package/src/functions/sprites.ts +2 -2
- package/src/functions/trinkets.ts +2 -2
- package/src/functions/utils.ts +20 -14
- package/src/index.ts +3 -0
- package/src/interfaces/Corner.ts +9 -0
- package/src/objects/roomShapeCorners.ts +74 -16
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { BossID, RoomShape } from "isaac-typescript-definitions";
|
|
2
|
+
import { game } from "../core/cachedClasses";
|
|
3
|
+
import { CornerType } from "../enums/CornerType";
|
|
4
|
+
import { Corner } from "../interfaces/Corner";
|
|
5
|
+
import { getEnumValues } from "./enums";
|
|
6
|
+
import { getGridIndexesBetween } from "./gridIndex";
|
|
7
|
+
import { inBossRoomOf, inHomeCloset } from "./rooms";
|
|
8
|
+
import { getRoomShapeCorners, isLRoom } from "./roomShape";
|
|
9
|
+
|
|
10
|
+
const ROOM_SHAPE_TO_WALL_GRID_INDEX_SET = getRoomShapeToWallGridIndexSet();
|
|
11
|
+
|
|
12
|
+
function getRoomShapeToWallGridIndexSet(): ReadonlyMap<
|
|
13
|
+
RoomShape,
|
|
14
|
+
ReadonlySet<int>
|
|
15
|
+
> {
|
|
16
|
+
const roomShapeToWallGridIndexSet = new Map<RoomShape, ReadonlySet<int>>();
|
|
17
|
+
|
|
18
|
+
for (const roomShape of getEnumValues(RoomShape)) {
|
|
19
|
+
const gridIndexSet = getVanillaWallGridIndexSetForRoomShape(roomShape);
|
|
20
|
+
roomShapeToWallGridIndexSet.set(roomShape, gridIndexSet);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return roomShapeToWallGridIndexSet;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getVanillaWallGridIndexSetForRoomShape(
|
|
27
|
+
roomShape: RoomShape,
|
|
28
|
+
): ReadonlySet<int> {
|
|
29
|
+
const corners = getRoomShapeCorners(roomShape);
|
|
30
|
+
const lRoom = isLRoom(roomShape);
|
|
31
|
+
|
|
32
|
+
if (lRoom && corners.length !== 6) {
|
|
33
|
+
error(
|
|
34
|
+
`Failed to get the correct amount of corners for: RoomShape.${RoomShape[roomShape]} (${roomShape})`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
switch (roomShape) {
|
|
39
|
+
// 9
|
|
40
|
+
case RoomShape.LTL: {
|
|
41
|
+
const [topMiddle, topRight, middleLeft, middle, bottomLeft, bottomRight] =
|
|
42
|
+
corners as [Corner, Corner, Corner, Corner, Corner, Corner];
|
|
43
|
+
return new Set([
|
|
44
|
+
// Horizontal
|
|
45
|
+
...getGridIndexesBetween(
|
|
46
|
+
topMiddle.gridIndex,
|
|
47
|
+
topRight.gridIndex,
|
|
48
|
+
roomShape,
|
|
49
|
+
),
|
|
50
|
+
...getGridIndexesBetween(
|
|
51
|
+
middleLeft.gridIndex,
|
|
52
|
+
middle.gridIndex,
|
|
53
|
+
roomShape,
|
|
54
|
+
),
|
|
55
|
+
...getGridIndexesBetween(
|
|
56
|
+
bottomLeft.gridIndex,
|
|
57
|
+
bottomRight.gridIndex,
|
|
58
|
+
roomShape,
|
|
59
|
+
),
|
|
60
|
+
|
|
61
|
+
// Vertical
|
|
62
|
+
...getGridIndexesBetween(
|
|
63
|
+
middleLeft.gridIndex,
|
|
64
|
+
bottomLeft.gridIndex,
|
|
65
|
+
roomShape,
|
|
66
|
+
),
|
|
67
|
+
...getGridIndexesBetween(
|
|
68
|
+
topMiddle.gridIndex,
|
|
69
|
+
middle.gridIndex,
|
|
70
|
+
roomShape,
|
|
71
|
+
),
|
|
72
|
+
...getGridIndexesBetween(
|
|
73
|
+
topRight.gridIndex,
|
|
74
|
+
bottomRight.gridIndex,
|
|
75
|
+
roomShape,
|
|
76
|
+
),
|
|
77
|
+
]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 10
|
|
81
|
+
case RoomShape.LTR: {
|
|
82
|
+
const [topLeft, topMiddle, middle, middleRight, bottomLeft, bottomRight] =
|
|
83
|
+
corners as [Corner, Corner, Corner, Corner, Corner, Corner];
|
|
84
|
+
return new Set([
|
|
85
|
+
// Horizontal
|
|
86
|
+
...getGridIndexesBetween(
|
|
87
|
+
topLeft.gridIndex,
|
|
88
|
+
topMiddle.gridIndex,
|
|
89
|
+
roomShape,
|
|
90
|
+
),
|
|
91
|
+
...getGridIndexesBetween(
|
|
92
|
+
middle.gridIndex,
|
|
93
|
+
middleRight.gridIndex,
|
|
94
|
+
roomShape,
|
|
95
|
+
),
|
|
96
|
+
...getGridIndexesBetween(
|
|
97
|
+
bottomLeft.gridIndex,
|
|
98
|
+
bottomRight.gridIndex,
|
|
99
|
+
roomShape,
|
|
100
|
+
),
|
|
101
|
+
|
|
102
|
+
// Vertical
|
|
103
|
+
...getGridIndexesBetween(
|
|
104
|
+
topLeft.gridIndex,
|
|
105
|
+
bottomLeft.gridIndex,
|
|
106
|
+
roomShape,
|
|
107
|
+
),
|
|
108
|
+
...getGridIndexesBetween(
|
|
109
|
+
topMiddle.gridIndex,
|
|
110
|
+
middle.gridIndex,
|
|
111
|
+
roomShape,
|
|
112
|
+
),
|
|
113
|
+
...getGridIndexesBetween(
|
|
114
|
+
middleRight.gridIndex,
|
|
115
|
+
bottomRight.gridIndex,
|
|
116
|
+
roomShape,
|
|
117
|
+
),
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 11
|
|
122
|
+
case RoomShape.LBL: {
|
|
123
|
+
const [topLeft, topRight, middleLeft, middle, bottomMiddle, bottomRight] =
|
|
124
|
+
corners as [Corner, Corner, Corner, Corner, Corner, Corner];
|
|
125
|
+
return new Set([
|
|
126
|
+
// Horizontal
|
|
127
|
+
...getGridIndexesBetween(
|
|
128
|
+
topLeft.gridIndex,
|
|
129
|
+
topRight.gridIndex,
|
|
130
|
+
roomShape,
|
|
131
|
+
),
|
|
132
|
+
...getGridIndexesBetween(
|
|
133
|
+
middleLeft.gridIndex,
|
|
134
|
+
middle.gridIndex,
|
|
135
|
+
roomShape,
|
|
136
|
+
),
|
|
137
|
+
...getGridIndexesBetween(
|
|
138
|
+
bottomMiddle.gridIndex,
|
|
139
|
+
bottomRight.gridIndex,
|
|
140
|
+
roomShape,
|
|
141
|
+
),
|
|
142
|
+
|
|
143
|
+
// Vertical
|
|
144
|
+
...getGridIndexesBetween(
|
|
145
|
+
topLeft.gridIndex,
|
|
146
|
+
middleLeft.gridIndex,
|
|
147
|
+
roomShape,
|
|
148
|
+
),
|
|
149
|
+
...getGridIndexesBetween(
|
|
150
|
+
middle.gridIndex,
|
|
151
|
+
bottomMiddle.gridIndex,
|
|
152
|
+
roomShape,
|
|
153
|
+
),
|
|
154
|
+
...getGridIndexesBetween(
|
|
155
|
+
topRight.gridIndex,
|
|
156
|
+
bottomRight.gridIndex,
|
|
157
|
+
roomShape,
|
|
158
|
+
),
|
|
159
|
+
]);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 12
|
|
163
|
+
case RoomShape.LBR: {
|
|
164
|
+
const [topLeft, topRight, middle, middleRight, bottomLeft, bottomMiddle] =
|
|
165
|
+
corners as [Corner, Corner, Corner, Corner, Corner, Corner];
|
|
166
|
+
return new Set([
|
|
167
|
+
// Horizontal
|
|
168
|
+
...getGridIndexesBetween(
|
|
169
|
+
topLeft.gridIndex,
|
|
170
|
+
topRight.gridIndex,
|
|
171
|
+
roomShape,
|
|
172
|
+
),
|
|
173
|
+
...getGridIndexesBetween(
|
|
174
|
+
middle.gridIndex,
|
|
175
|
+
middleRight.gridIndex,
|
|
176
|
+
roomShape,
|
|
177
|
+
),
|
|
178
|
+
...getGridIndexesBetween(
|
|
179
|
+
bottomLeft.gridIndex,
|
|
180
|
+
bottomMiddle.gridIndex,
|
|
181
|
+
roomShape,
|
|
182
|
+
),
|
|
183
|
+
|
|
184
|
+
// Vertical
|
|
185
|
+
...getGridIndexesBetween(
|
|
186
|
+
topLeft.gridIndex,
|
|
187
|
+
bottomLeft.gridIndex,
|
|
188
|
+
roomShape,
|
|
189
|
+
),
|
|
190
|
+
...getGridIndexesBetween(
|
|
191
|
+
middle.gridIndex,
|
|
192
|
+
bottomMiddle.gridIndex,
|
|
193
|
+
roomShape,
|
|
194
|
+
),
|
|
195
|
+
...getGridIndexesBetween(
|
|
196
|
+
topRight.gridIndex,
|
|
197
|
+
middleRight.gridIndex,
|
|
198
|
+
roomShape,
|
|
199
|
+
),
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
default: {
|
|
204
|
+
return getWallGridIndexSetForRectangleRoomShape(roomShape, corners);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Providing the room shape is necessary so that the `getGridIndexesBetween` function can use the
|
|
211
|
+
* corresponding grid width.
|
|
212
|
+
*/
|
|
213
|
+
function getWallGridIndexSetForRectangleRoomShape(
|
|
214
|
+
roomShape: RoomShape,
|
|
215
|
+
corners: readonly Corner[],
|
|
216
|
+
): ReadonlySet<int> {
|
|
217
|
+
if (corners.length !== 4) {
|
|
218
|
+
error(
|
|
219
|
+
"Failed to get the correct amount of corners for rectangular room shape.",
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const [topLeft, topRight, bottomLeft, bottomRight] = corners as [
|
|
224
|
+
Corner,
|
|
225
|
+
Corner,
|
|
226
|
+
Corner,
|
|
227
|
+
Corner,
|
|
228
|
+
];
|
|
229
|
+
|
|
230
|
+
return new Set([
|
|
231
|
+
// Horizontal
|
|
232
|
+
...getGridIndexesBetween(topLeft.gridIndex, topRight.gridIndex, roomShape),
|
|
233
|
+
...getGridIndexesBetween(
|
|
234
|
+
bottomLeft.gridIndex,
|
|
235
|
+
bottomRight.gridIndex,
|
|
236
|
+
roomShape,
|
|
237
|
+
),
|
|
238
|
+
|
|
239
|
+
// Vertical
|
|
240
|
+
...getGridIndexesBetween(
|
|
241
|
+
topLeft.gridIndex,
|
|
242
|
+
bottomLeft.gridIndex,
|
|
243
|
+
roomShape,
|
|
244
|
+
),
|
|
245
|
+
...getGridIndexesBetween(
|
|
246
|
+
topRight.gridIndex,
|
|
247
|
+
bottomRight.gridIndex,
|
|
248
|
+
roomShape,
|
|
249
|
+
),
|
|
250
|
+
]);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** The Home closet is is 9x3, which is different from `RoomShape.IH` (which is 13x3). */
|
|
254
|
+
const HOME_CLOSET_CORNERS = [
|
|
255
|
+
{
|
|
256
|
+
type: CornerType.TOP_LEFT,
|
|
257
|
+
gridIndex: 30,
|
|
258
|
+
position: Vector(60, 220),
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
type: CornerType.TOP_RIGHT,
|
|
262
|
+
gridIndex: 38,
|
|
263
|
+
position: Vector(340, 220),
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
type: CornerType.BOTTOM_LEFT,
|
|
267
|
+
gridIndex: 90,
|
|
268
|
+
position: Vector(60, 340),
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
type: CornerType.BOTTOM_RIGHT,
|
|
272
|
+
gridIndex: 98,
|
|
273
|
+
position: Vector(340, 340),
|
|
274
|
+
},
|
|
275
|
+
] as const;
|
|
276
|
+
|
|
277
|
+
const HOME_CLOSET_CORNERS_SET = getWallGridIndexSetForRectangleRoomShape(
|
|
278
|
+
RoomShape.IH,
|
|
279
|
+
HOME_CLOSET_CORNERS,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The Mother Boss Room is 15x11, which is different from `RoomShape.SHAPE_1x2` (which is 15x16).
|
|
284
|
+
*/
|
|
285
|
+
const MOTHER_ROOM_CORNERS = [
|
|
286
|
+
{
|
|
287
|
+
type: CornerType.TOP_LEFT,
|
|
288
|
+
gridIndex: 0,
|
|
289
|
+
position: Vector(60, 140),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
type: CornerType.TOP_RIGHT,
|
|
293
|
+
gridIndex: 14,
|
|
294
|
+
position: Vector(580, 140),
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
type: CornerType.BOTTOM_LEFT,
|
|
298
|
+
gridIndex: 150,
|
|
299
|
+
position: Vector(60, 500),
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
type: CornerType.BOTTOM_RIGHT,
|
|
303
|
+
gridIndex: 164,
|
|
304
|
+
position: Vector(580, 500),
|
|
305
|
+
},
|
|
306
|
+
] as const;
|
|
307
|
+
|
|
308
|
+
const MOTHER_ROOM_CORNERS_SET = getWallGridIndexSetForRectangleRoomShape(
|
|
309
|
+
RoomShape.SHAPE_1x2,
|
|
310
|
+
MOTHER_ROOM_CORNERS,
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Helper function to determine if a given wall is a "real" wall generated by the vanilla game. This
|
|
315
|
+
* is useful because mods can use custom spawned walls as a stand-in for custom grid entities.
|
|
316
|
+
*
|
|
317
|
+
* This function checks for identity via a combination of `StageAPI.IsCustomGrid` and the
|
|
318
|
+
* `isVanillaWallGridIndex` function.
|
|
319
|
+
*/
|
|
320
|
+
export function isVanillaWall(gridEntity: GridEntity): boolean {
|
|
321
|
+
const gridIndex = gridEntity.GetGridIndex();
|
|
322
|
+
|
|
323
|
+
if (StageAPI !== undefined && StageAPI.IsCustomGrid(gridIndex)) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return isVanillaWallGridIndex(gridIndex);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Helper function to determine if a given grid index should have a wall generated by the vanilla
|
|
332
|
+
* game. This is useful as a mechanism to distinguish between real walls and custom walls spawned by
|
|
333
|
+
* mods.
|
|
334
|
+
*
|
|
335
|
+
* This function properly handles the special cases of the Mother boss room and the Home closet
|
|
336
|
+
* rooms, which are both non-standard room shapes.
|
|
337
|
+
*/
|
|
338
|
+
export function isVanillaWallGridIndex(gridIndex: int): boolean {
|
|
339
|
+
const room = game.GetRoom();
|
|
340
|
+
const roomShape = room.GetRoomShape();
|
|
341
|
+
|
|
342
|
+
// Handle the special cases of non-standard room shapes.
|
|
343
|
+
let wallGridIndexSet: ReadonlySet<int> | undefined;
|
|
344
|
+
if (inHomeCloset()) {
|
|
345
|
+
wallGridIndexSet = HOME_CLOSET_CORNERS_SET;
|
|
346
|
+
} else if (inBossRoomOf(BossID.MOTHER)) {
|
|
347
|
+
wallGridIndexSet = MOTHER_ROOM_CORNERS_SET;
|
|
348
|
+
} else {
|
|
349
|
+
wallGridIndexSet = ROOM_SHAPE_TO_WALL_GRID_INDEX_SET.get(roomShape);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (wallGridIndexSet === undefined) {
|
|
353
|
+
error(
|
|
354
|
+
`Failed to find the wall grid index set for: RoomShape.${RoomShape[roomShape]} (${roomShape})`,
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return wallGridIndexSet.has(gridIndex);
|
|
359
|
+
}
|
package/src/functions/rooms.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
GridRoom,
|
|
10
10
|
HomeRoomSubType,
|
|
11
11
|
ItemPoolType,
|
|
12
|
+
LevelStage,
|
|
12
13
|
MinibossID,
|
|
13
14
|
RoomDescriptorFlag,
|
|
14
15
|
RoomShape,
|
|
@@ -47,7 +48,7 @@ import {
|
|
|
47
48
|
import { reloadRoom } from "./roomTransition";
|
|
48
49
|
import { getGotoCommand } from "./stage";
|
|
49
50
|
import { asNumber } from "./types";
|
|
50
|
-
import {
|
|
51
|
+
import { iRange } from "./utils";
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
54
|
* Helper function for quickly switching to a new room without playing a particular animation. Use
|
|
@@ -216,7 +217,7 @@ export function getRoomsInsideGrid(
|
|
|
216
217
|
const roomDescriptorMap = new Map<PtrHash, RoomDescriptor>();
|
|
217
218
|
|
|
218
219
|
for (const dimension of dimensions) {
|
|
219
|
-
for (const roomGridIndex of
|
|
220
|
+
for (const roomGridIndex of iRange(MAX_LEVEL_GRID_INDEX)) {
|
|
220
221
|
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
221
222
|
if (roomDescriptor.Data !== undefined) {
|
|
222
223
|
const ptrHash = GetPtrHash(roomDescriptor);
|
|
@@ -240,7 +241,7 @@ export function getRoomsOfDimension(dimension: Dimension): RoomDescriptor[] {
|
|
|
240
241
|
/** We use a map instead of an array because room shapes occupy more than one room grid index. */
|
|
241
242
|
const roomsMap = new Map<PtrHash, RoomDescriptor>();
|
|
242
243
|
|
|
243
|
-
for (const roomGridIndex of
|
|
244
|
+
for (const roomGridIndex of iRange(MAX_LEVEL_GRID_INDEX)) {
|
|
244
245
|
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
245
246
|
if (roomDescriptor.Data !== undefined) {
|
|
246
247
|
const ptrHash = GetPtrHash(roomDescriptor);
|
|
@@ -375,6 +376,24 @@ export function inGenesisRoom(): boolean {
|
|
|
375
376
|
return roomGridIndex === asNumber(GridRoom.GENESIS);
|
|
376
377
|
}
|
|
377
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Helper function to check if the current room is either the left Home closet (behind the red door)
|
|
381
|
+
* or the right Home closet (with one random pickup).
|
|
382
|
+
*
|
|
383
|
+
* Home closets have a unique shape that is different from any other room in the game.
|
|
384
|
+
*/
|
|
385
|
+
export function inHomeCloset(): boolean {
|
|
386
|
+
const level = game.GetLevel();
|
|
387
|
+
const stage = level.GetStage();
|
|
388
|
+
const roomSubType = getRoomSubType();
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
stage === LevelStage.HOME &&
|
|
392
|
+
(roomSubType === asNumber(HomeRoomSubType.CLOSET_LEFT) ||
|
|
393
|
+
roomSubType === asNumber(HomeRoomSubType.CLOSET_RIGHT))
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
|
|
378
397
|
/** Helper function to determine if the current room shape is one of the four L room shapes. */
|
|
379
398
|
export function inLRoom(): boolean {
|
|
380
399
|
const room = game.GetRoom();
|
package/src/functions/set.ts
CHANGED
|
@@ -136,6 +136,18 @@ export function getSortedSetValues<T>(set: Set<T> | ReadonlySet<T>): T[] {
|
|
|
136
136
|
return array;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Helper function to add one or more elements to a set at once without having to repeatedly call
|
|
141
|
+
* the `Set.add` method.
|
|
142
|
+
*
|
|
143
|
+
* This function is variadic, meaning that you can pass as many things as you want to add.
|
|
144
|
+
*/
|
|
145
|
+
export function setAdd<T>(set: Set<T>, ...elements: T[]): void {
|
|
146
|
+
for (const element of elements) {
|
|
147
|
+
set.add(element);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
139
151
|
/** Helper function to sum every value in a set together. */
|
|
140
152
|
export function sumSet(set: Set<number> | ReadonlySet<number>): number {
|
|
141
153
|
const values = [...set.values()];
|
package/src/functions/sprites.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EMPTY_PNG_PATH, VectorZero } from "../core/constants";
|
|
2
2
|
import { kColorEquals } from "./kColor";
|
|
3
|
-
import {
|
|
3
|
+
import { eRange } from "./utils";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Helper function to clear all layers or specific layers from a sprite.
|
|
@@ -17,7 +17,7 @@ import { erange } from "./utils";
|
|
|
17
17
|
export function clearSprite(sprite: Sprite, ...layerIDs: int[]): void {
|
|
18
18
|
if (layerIDs.length === 0) {
|
|
19
19
|
const numLayers = sprite.GetLayerCount();
|
|
20
|
-
layerIDs =
|
|
20
|
+
layerIDs = eRange(numLayers);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
for (const layerID of layerIDs) {
|
|
@@ -22,7 +22,7 @@ import { isTrinket } from "./pickupVariants";
|
|
|
22
22
|
import { isCharacter } from "./players";
|
|
23
23
|
import { clearSprite } from "./sprites";
|
|
24
24
|
import { asNumber } from "./types";
|
|
25
|
-
import {
|
|
25
|
+
import { iRange } from "./utils";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Add this to a `TrinketType` to get the corresponding golden trinket type.
|
|
@@ -145,7 +145,7 @@ export function getTrinketName(trinketType: TrinketType): string {
|
|
|
145
145
|
|
|
146
146
|
/** Helper function to get an array that represents every vanilla trinket type. */
|
|
147
147
|
export function getVanillaTrinketTypes(): TrinketType[] {
|
|
148
|
-
return
|
|
148
|
+
return iRange(FIRST_TRINKET_TYPE, LAST_VANILLA_TRINKET_TYPE);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
package/src/functions/utils.ts
CHANGED
|
@@ -3,22 +3,25 @@ import { game } from "../core/cachedClasses";
|
|
|
3
3
|
import { CONSOLE_COMMANDS_SET } from "../sets/consoleCommandsSet";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Helper function to return an array with the
|
|
7
|
-
*
|
|
6
|
+
* Helper function to return an array of integers with the specified range, inclusive on the lower
|
|
7
|
+
* end and exclusive on the high end. (The "e" stands for exclusive.)
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* - For example, `eRange(1, 3)` will return `[1, 2]`.
|
|
10
|
+
* - For example, `eRange(2)` will return `[0, 1]`.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* @param start The number to start at.
|
|
13
|
+
* @param end Optional. The number to end at. If not specified, then the start will be 0 and the
|
|
14
|
+
* first argument will be the end.
|
|
15
|
+
* @param increment Optional. The increment to use. Default is 1.
|
|
13
16
|
*/
|
|
14
|
-
export function
|
|
17
|
+
export function eRange(start: int, end?: int, increment = 1): int[] {
|
|
15
18
|
if (end === undefined) {
|
|
16
19
|
end = start;
|
|
17
20
|
start = 0;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
const array: int[] = [];
|
|
21
|
-
for (let i = start; i < end; i
|
|
24
|
+
for (let i = start; i < end; i += increment) {
|
|
22
25
|
array.push(i);
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -43,22 +46,25 @@ export function getTraversalDescription(
|
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
/**
|
|
46
|
-
* Helper function to return an array with the
|
|
47
|
-
* stands for inclusive.)
|
|
49
|
+
* Helper function to return an array of integers with the specified range, inclusive on both ends.
|
|
50
|
+
* (The "i" stands for inclusive.)
|
|
48
51
|
*
|
|
49
|
-
*
|
|
52
|
+
* - For example, `iRange(1, 3)` will return `[1, 2, 3]`.
|
|
53
|
+
* - For example, `iRange(2)` will return `[0, 1, 2]`.
|
|
50
54
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
55
|
+
* @param start The number to start at.
|
|
56
|
+
* @param end Optional. The number to end at. If not specified, then the start will be 0 and the
|
|
57
|
+
* first argument will be the end.
|
|
58
|
+
* @param increment Optional. The increment to use. Default is 1.
|
|
53
59
|
*/
|
|
54
|
-
export function
|
|
60
|
+
export function iRange(start: int, end?: int, increment = 1): int[] {
|
|
55
61
|
if (end === undefined) {
|
|
56
62
|
end = start;
|
|
57
63
|
start = 0;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
const array: int[] = [];
|
|
61
|
-
for (let i = start; i <= end; i
|
|
67
|
+
for (let i = start; i <= end; i += increment) {
|
|
62
68
|
array.push(i);
|
|
63
69
|
}
|
|
64
70
|
|
package/src/index.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * from "./functions/doors";
|
|
|
74
74
|
export * from "./functions/easing";
|
|
75
75
|
export * from "./functions/eden";
|
|
76
76
|
export * from "./functions/effects";
|
|
77
|
+
export * from "./functions/emptyRoom";
|
|
77
78
|
export * from "./functions/entities";
|
|
78
79
|
export * from "./functions/entitiesSpecific";
|
|
79
80
|
export * from "./functions/entityTypes";
|
|
@@ -84,6 +85,7 @@ export * from "./functions/flying";
|
|
|
84
85
|
export * from "./functions/globals";
|
|
85
86
|
export * from "./functions/gridEntities";
|
|
86
87
|
export * from "./functions/gridEntitiesSpecific";
|
|
88
|
+
export * from "./functions/gridIndex";
|
|
87
89
|
export * from "./functions/hex";
|
|
88
90
|
export * from "./functions/initArray";
|
|
89
91
|
export * from "./functions/input";
|
|
@@ -126,6 +128,7 @@ export * from "./functions/roomData";
|
|
|
126
128
|
export * from "./functions/roomGrid";
|
|
127
129
|
export * from "./functions/rooms";
|
|
128
130
|
export * from "./functions/roomShape";
|
|
131
|
+
export * from "./functions/roomShapeWalls";
|
|
129
132
|
export * from "./functions/roomTransition";
|
|
130
133
|
export * from "./functions/run";
|
|
131
134
|
export * from "./functions/saveFile";
|
package/src/interfaces/Corner.ts
CHANGED
|
@@ -7,5 +7,14 @@ import { CornerType } from "../enums/CornerType";
|
|
|
7
7
|
*/
|
|
8
8
|
export interface Corner {
|
|
9
9
|
readonly type: CornerType;
|
|
10
|
+
|
|
11
|
+
/** The grid index of the corresponding wall tile. */
|
|
12
|
+
readonly gridIndex: int;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The position is not the same as the center of the corresponding grid index. Rather, it is the
|
|
16
|
+
* exact position of the corner, which will be offset from the grid index position by half of a
|
|
17
|
+
* grid tile.
|
|
18
|
+
*/
|
|
10
19
|
readonly position: Readonly<Vector>;
|
|
11
20
|
}
|