isaacscript-common 30.12.11 → 31.0.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.rollup.d.ts +141 -20
- package/dist/isaacscript-common.lua +139 -101
- package/dist/src/classes/features/other/customStages/backdrop.lua +3 -3
- package/dist/src/functions/levelGrid.d.ts +22 -13
- package/dist/src/functions/levelGrid.d.ts.map +1 -1
- package/dist/src/functions/levelGrid.lua +46 -23
- package/dist/src/functions/logMisc.d.ts.map +1 -1
- package/dist/src/functions/logMisc.lua +3 -7
- package/dist/src/functions/roomData.d.ts +1 -5
- package/dist/src/functions/roomData.d.ts.map +1 -1
- package/dist/src/functions/roomGrid.lua +6 -6
- package/dist/src/functions/roomShape.d.ts +1 -1
- package/dist/src/functions/roomShape.d.ts.map +1 -1
- package/dist/src/functions/roomShape.lua +1 -1
- package/dist/src/functions/roomShapeWalls.lua +2 -2
- package/dist/src/functions/rooms.d.ts +98 -1
- package/dist/src/functions/rooms.d.ts.map +1 -1
- package/dist/src/functions/rooms.lua +145 -68
- package/package.json +1 -1
- package/src/classes/features/other/customStages/backdrop.ts +3 -3
- package/src/functions/levelGrid.ts +51 -24
- package/src/functions/logMisc.ts +5 -9
- package/src/functions/roomData.ts +4 -0
- package/src/functions/roomGrid.ts +2 -2
- package/src/functions/roomShape.ts +1 -1
- package/src/functions/roomShapeWalls.ts +2 -2
- package/src/functions/rooms.ts +237 -118
package/src/functions/rooms.ts
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
DungeonSubType,
|
|
13
13
|
GridRoom,
|
|
14
14
|
HomeRoomSubType,
|
|
15
|
-
LevelStage,
|
|
16
15
|
RoomDescriptorFlag,
|
|
17
16
|
RoomShape,
|
|
18
17
|
RoomType,
|
|
@@ -44,10 +43,8 @@ import {
|
|
|
44
43
|
getRoomDescriptor,
|
|
45
44
|
getRoomDescriptorReadOnly,
|
|
46
45
|
getRoomGridIndex,
|
|
47
|
-
getRoomName,
|
|
48
|
-
getRoomStageID,
|
|
49
|
-
getRoomSubType,
|
|
50
46
|
} from "./roomData";
|
|
47
|
+
import { isLRoomShape } from "./roomShape";
|
|
51
48
|
import { reloadRoom } from "./roomTransition";
|
|
52
49
|
import { getGotoCommand } from "./stage";
|
|
53
50
|
import { asNumber } from "./types";
|
|
@@ -293,32 +290,18 @@ export function getRoomsOutsideGrid(): RoomDescriptor[] {
|
|
|
293
290
|
* `RoomShape.2x1`.
|
|
294
291
|
*/
|
|
295
292
|
export function in2x1Room(): boolean {
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return roomShape === RoomShape.SHAPE_1x2 || roomShape === RoomShape.SHAPE_2x1;
|
|
293
|
+
const roomData = getRoomData();
|
|
294
|
+
return is2x1Room(roomData);
|
|
300
295
|
}
|
|
301
296
|
|
|
302
297
|
export function inAngelShop(): boolean {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
const roomSubType = getRoomSubType();
|
|
306
|
-
|
|
307
|
-
return (
|
|
308
|
-
roomType === RoomType.ANGEL &&
|
|
309
|
-
roomSubType === asNumber(AngelRoomSubType.SHOP)
|
|
310
|
-
);
|
|
298
|
+
const roomData = getRoomData();
|
|
299
|
+
return isAngelShop(roomData);
|
|
311
300
|
}
|
|
312
301
|
|
|
313
302
|
export function inBeastRoom(): boolean {
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
const roomSubType = getRoomSubType();
|
|
317
|
-
|
|
318
|
-
return (
|
|
319
|
-
roomType === RoomType.DUNGEON &&
|
|
320
|
-
roomSubType === asNumber(DungeonSubType.BEAST_ROOM)
|
|
321
|
-
);
|
|
303
|
+
const roomData = getRoomData();
|
|
304
|
+
return isBeastRoom(roomData);
|
|
322
305
|
}
|
|
323
306
|
|
|
324
307
|
/**
|
|
@@ -326,46 +309,26 @@ export function inBeastRoom(): boolean {
|
|
|
326
309
|
* work for bosses that have dedicated boss rooms in the "00.special rooms.stb" file.
|
|
327
310
|
*/
|
|
328
311
|
export function inBossRoomOf(bossID: BossID): boolean {
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
const roomStageID = getRoomStageID();
|
|
332
|
-
const roomSubType = getRoomSubType();
|
|
333
|
-
|
|
334
|
-
return (
|
|
335
|
-
roomType === RoomType.BOSS &&
|
|
336
|
-
roomStageID === StageID.SPECIAL_ROOMS &&
|
|
337
|
-
roomSubType === asNumber(bossID)
|
|
338
|
-
);
|
|
312
|
+
const roomData = getRoomData();
|
|
313
|
+
return isBossRoomOf(roomData, bossID);
|
|
339
314
|
}
|
|
340
315
|
|
|
341
316
|
/**
|
|
342
317
|
* Helper function for determining whether the current room is a crawl space. Use this function over
|
|
343
318
|
* comparing to `RoomType.DUNGEON` or `GridRoom.DUNGEON_IDX` since there is a special case of the
|
|
344
|
-
* player being in a boss fight that
|
|
319
|
+
* player being in a boss fight that takes place in a dungeon.
|
|
345
320
|
*/
|
|
346
321
|
export function inCrawlSpace(): boolean {
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
const roomSubType = getRoomSubType();
|
|
350
|
-
|
|
351
|
-
return (
|
|
352
|
-
roomType === RoomType.DUNGEON &&
|
|
353
|
-
roomSubType === asNumber(DungeonSubType.NORMAL)
|
|
354
|
-
);
|
|
322
|
+
const roomData = getRoomData();
|
|
323
|
+
return isCrawlSpace(roomData);
|
|
355
324
|
}
|
|
356
325
|
|
|
357
326
|
/**
|
|
358
327
|
* Helper function to detect if the current room is one of the rooms in the Death Certificate area.
|
|
359
328
|
*/
|
|
360
329
|
export function inDeathCertificateArea(): boolean {
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return (
|
|
365
|
-
roomStageID === StageID.HOME &&
|
|
366
|
-
(roomSubType === asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ENTRANCE) ||
|
|
367
|
-
roomSubType === asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ITEMS))
|
|
368
|
-
);
|
|
330
|
+
const roomData = getRoomData();
|
|
331
|
+
return isDeathCertificateArea(roomData);
|
|
369
332
|
}
|
|
370
333
|
|
|
371
334
|
/**
|
|
@@ -376,7 +339,7 @@ export function inDeathCertificateArea(): boolean {
|
|
|
376
339
|
*/
|
|
377
340
|
export function inDevilsCrownTreasureRoom(): boolean {
|
|
378
341
|
const roomDescriptor = getRoomDescriptorReadOnly();
|
|
379
|
-
return
|
|
342
|
+
return isDevilsCrownTreasureRoom(roomDescriptor);
|
|
380
343
|
}
|
|
381
344
|
|
|
382
345
|
/**
|
|
@@ -385,19 +348,20 @@ export function inDevilsCrownTreasureRoom(): boolean {
|
|
|
385
348
|
* This is performed by checking for the string "Double Trouble" inside of the room name. The
|
|
386
349
|
* vanilla game uses this convention for every Double Trouble Boss Room. Note that this method might
|
|
387
350
|
* fail for mods that add extra Double Trouble rooms but do not follow the convention.
|
|
351
|
+
*
|
|
352
|
+
* Internally, the game is coded to detect Double Trouble Boss Rooms by checking for the variant
|
|
353
|
+
* range of 3700 through 3850. We intentionally do not use this method since it may not work as well
|
|
354
|
+
* with modded rooms.
|
|
388
355
|
*/
|
|
389
356
|
export function inDoubleTrouble(): boolean {
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
const roomName = getRoomName();
|
|
393
|
-
|
|
394
|
-
return roomType === RoomType.BOSS && roomName.includes("Double Trouble");
|
|
357
|
+
const roomData = getRoomData();
|
|
358
|
+
return isDoubleTrouble(roomData);
|
|
395
359
|
}
|
|
396
360
|
|
|
361
|
+
/** Helper function to determine if the current room index is equal to `GridRoom.GENESIS`. */
|
|
397
362
|
export function inGenesisRoom(): boolean {
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
return roomGridIndex === asNumber(GridRoom.GENESIS);
|
|
363
|
+
const roomDescriptor = getRoomDescriptorReadOnly();
|
|
364
|
+
return isGenesisRoom(roomDescriptor);
|
|
401
365
|
}
|
|
402
366
|
|
|
403
367
|
/**
|
|
@@ -407,35 +371,20 @@ export function inGenesisRoom(): boolean {
|
|
|
407
371
|
* Home closets have a unique shape that is different from any other room in the game.
|
|
408
372
|
*/
|
|
409
373
|
export function inHomeCloset(): boolean {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
const roomSubType = getRoomSubType();
|
|
413
|
-
|
|
414
|
-
return (
|
|
415
|
-
stage === LevelStage.HOME &&
|
|
416
|
-
(roomSubType === asNumber(HomeRoomSubType.CLOSET_LEFT) ||
|
|
417
|
-
roomSubType === asNumber(HomeRoomSubType.CLOSET_RIGHT))
|
|
418
|
-
);
|
|
374
|
+
const roomData = getRoomData();
|
|
375
|
+
return isHomeCloset(roomData);
|
|
419
376
|
}
|
|
420
377
|
|
|
421
378
|
/** Helper function to determine if the current room shape is one of the four L room shapes. */
|
|
422
379
|
export function inLRoom(): boolean {
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
return (
|
|
427
|
-
roomShape === RoomShape.LTL ||
|
|
428
|
-
roomShape === RoomShape.LTR ||
|
|
429
|
-
roomShape === RoomShape.LBL ||
|
|
430
|
-
roomShape === RoomShape.LBR
|
|
431
|
-
);
|
|
380
|
+
const roomData = getRoomData();
|
|
381
|
+
return isLRoom(roomData);
|
|
432
382
|
}
|
|
433
383
|
|
|
434
384
|
/** Helper function to determine if the current room index is equal to `GridRoom.MEGA_SATAN`. */
|
|
435
385
|
export function inMegaSatanRoom(): boolean {
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
return roomGridIndex === asNumber(GridRoom.MEGA_SATAN);
|
|
386
|
+
const roomDescriptor = getRoomDescriptorReadOnly();
|
|
387
|
+
return isMegaSatanRoom(roomDescriptor);
|
|
439
388
|
}
|
|
440
389
|
|
|
441
390
|
/**
|
|
@@ -443,14 +392,8 @@ export function inMegaSatanRoom(): boolean {
|
|
|
443
392
|
* the Mines/Ashpit.
|
|
444
393
|
*/
|
|
445
394
|
export function inMineShaft(): boolean {
|
|
446
|
-
const
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
return (
|
|
450
|
-
(roomStageID === StageID.MINES || roomStageID === StageID.ASHPIT) &&
|
|
451
|
-
// eslint-disable-next-line isaacscript/strict-enums
|
|
452
|
-
MINE_SHAFT_ROOM_SUB_TYPE_SET.has(roomSubType)
|
|
453
|
-
);
|
|
395
|
+
const roomData = getRoomData();
|
|
396
|
+
return isMineShaft(roomData);
|
|
454
397
|
}
|
|
455
398
|
|
|
456
399
|
/**
|
|
@@ -458,16 +401,8 @@ export function inMineShaft(): boolean {
|
|
|
458
401
|
* will only work for mini-bosses that have dedicated boss rooms in the "00.special rooms.stb" file.
|
|
459
402
|
*/
|
|
460
403
|
export function inMinibossRoomOf(minibossID: MinibossID): boolean {
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
const roomStageID = getRoomStageID();
|
|
464
|
-
const roomSubType = getRoomSubType();
|
|
465
|
-
|
|
466
|
-
return (
|
|
467
|
-
roomType === RoomType.MINI_BOSS &&
|
|
468
|
-
roomStageID === StageID.SPECIAL_ROOMS &&
|
|
469
|
-
roomSubType === asNumber(minibossID)
|
|
470
|
-
);
|
|
404
|
+
const roomData = getRoomData();
|
|
405
|
+
return isMinibossRoomOf(roomData, minibossID);
|
|
471
406
|
}
|
|
472
407
|
|
|
473
408
|
/**
|
|
@@ -475,16 +410,8 @@ export function inMinibossRoomOf(minibossID: MinibossID): boolean {
|
|
|
475
410
|
* rooms are marked with a specific sub-type.)
|
|
476
411
|
*/
|
|
477
412
|
export function inMirrorRoom(): boolean {
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
const roomStageID = getRoomStageID();
|
|
481
|
-
const roomSubType = getRoomSubType();
|
|
482
|
-
|
|
483
|
-
return (
|
|
484
|
-
roomType === RoomType.DEFAULT &&
|
|
485
|
-
(roomStageID === StageID.DOWNPOUR || roomStageID === StageID.DROSS) &&
|
|
486
|
-
roomSubType === asNumber(DownpourRoomSubType.MIRROR)
|
|
487
|
-
);
|
|
413
|
+
const roomData = getRoomData();
|
|
414
|
+
return isMirrorRoom(roomData);
|
|
488
415
|
}
|
|
489
416
|
|
|
490
417
|
/**
|
|
@@ -493,9 +420,8 @@ export function inMirrorRoom(): boolean {
|
|
|
493
420
|
* This function is variadic, which means you can pass as many room types as you want to match for.
|
|
494
421
|
*/
|
|
495
422
|
export function inRoomType(...roomTypes: RoomType[]): boolean {
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
return roomTypes.includes(thisRoomType);
|
|
423
|
+
const roomData = getRoomData();
|
|
424
|
+
return isRoomType(roomData, ...roomTypes);
|
|
499
425
|
}
|
|
500
426
|
|
|
501
427
|
/**
|
|
@@ -503,9 +429,8 @@ export function inRoomType(...roomTypes: RoomType[]): boolean {
|
|
|
503
429
|
* floor.
|
|
504
430
|
*/
|
|
505
431
|
export function inSecretExit(): boolean {
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
return roomGridIndex === asNumber(GridRoom.SECRET_EXIT);
|
|
432
|
+
const roomDescriptor = getRoomDescriptorReadOnly();
|
|
433
|
+
return isSecretExit(roomDescriptor);
|
|
509
434
|
}
|
|
510
435
|
|
|
511
436
|
/**
|
|
@@ -517,9 +442,8 @@ export function inSecretExit(): boolean {
|
|
|
517
442
|
* the only way to detect them is by using the grid index.
|
|
518
443
|
*/
|
|
519
444
|
export function inSecretShop(): boolean {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
return roomGridIndex === asNumber(GridRoom.SECRET_SHOP);
|
|
445
|
+
const roomDescriptor = getRoomDescriptorReadOnly();
|
|
446
|
+
return isSecretShop(roomDescriptor);
|
|
523
447
|
}
|
|
524
448
|
|
|
525
449
|
/**
|
|
@@ -535,6 +459,16 @@ export function inStartingRoom(): boolean {
|
|
|
535
459
|
return roomGridIndex === startingRoomGridIndex && inDimension(Dimension.MAIN);
|
|
536
460
|
}
|
|
537
461
|
|
|
462
|
+
/**
|
|
463
|
+
* Helper function to determine if the provided room is equal to `RoomShape.1x2` or `RoomShape.2x1`.
|
|
464
|
+
*/
|
|
465
|
+
export function is2x1Room(roomData: RoomConfig): boolean {
|
|
466
|
+
return (
|
|
467
|
+
roomData.Shape === RoomShape.SHAPE_1x2 ||
|
|
468
|
+
roomData.Shape === RoomShape.SHAPE_2x1
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
538
472
|
/**
|
|
539
473
|
* Helper function to loop through every room on the floor and see if it has been cleared.
|
|
540
474
|
*
|
|
@@ -588,6 +522,179 @@ export function isAllRoomsClear(
|
|
|
588
522
|
return matchingRooms.every((roomDescriptor) => roomDescriptor.Clear);
|
|
589
523
|
}
|
|
590
524
|
|
|
525
|
+
export function isAngelShop(roomData: RoomConfig): boolean {
|
|
526
|
+
return (
|
|
527
|
+
roomData.Type === RoomType.ANGEL &&
|
|
528
|
+
roomData.Subtype === asNumber(AngelRoomSubType.SHOP)
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export function isBeastRoom(roomData: RoomConfig): boolean {
|
|
533
|
+
return (
|
|
534
|
+
roomData.Type === RoomType.DUNGEON &&
|
|
535
|
+
roomData.Subtype === asNumber(DungeonSubType.BEAST_ROOM)
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Helper function to check if the provided room is a boss room for a particular boss. This will
|
|
541
|
+
* only work for bosses that have dedicated boss rooms in the "00.special rooms.stb" file.
|
|
542
|
+
*/
|
|
543
|
+
export function isBossRoomOf(roomData: RoomConfig, bossID: BossID): boolean {
|
|
544
|
+
return (
|
|
545
|
+
roomData.Type === RoomType.BOSS &&
|
|
546
|
+
roomData.StageID === StageID.SPECIAL_ROOMS &&
|
|
547
|
+
roomData.Subtype === asNumber(bossID)
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Helper function for determining whether the provided room is a crawl space. Use this function
|
|
553
|
+
* over comparing to `RoomType.DUNGEON` or `GridRoom.DUNGEON_IDX` since there is a special case of
|
|
554
|
+
* the player being in a boss fight that takes place in a dungeon.
|
|
555
|
+
*/
|
|
556
|
+
export function isCrawlSpace(roomData: RoomConfig): boolean {
|
|
557
|
+
return (
|
|
558
|
+
roomData.Type === RoomType.DUNGEON &&
|
|
559
|
+
roomData.Subtype === asNumber(DungeonSubType.NORMAL)
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Helper function to detect if the provided room is one of the rooms in the Death Certificate area.
|
|
565
|
+
*/
|
|
566
|
+
export function isDeathCertificateArea(roomData: RoomConfig): boolean {
|
|
567
|
+
return (
|
|
568
|
+
roomData.StageID === StageID.HOME &&
|
|
569
|
+
(roomData.Subtype ===
|
|
570
|
+
asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ENTRANCE) ||
|
|
571
|
+
roomData.Subtype === asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ITEMS))
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Helper function to detect if the provided room is a Treasure Room created when entering with a
|
|
577
|
+
* Devil's Crown trinket.
|
|
578
|
+
*
|
|
579
|
+
* Under the hood, this checks for `RoomDescriptorFlag.DEVIL_TREASURE`.
|
|
580
|
+
*/
|
|
581
|
+
export function isDevilsCrownTreasureRoom(
|
|
582
|
+
roomDescriptor: RoomDescriptor,
|
|
583
|
+
): boolean {
|
|
584
|
+
return hasFlag(roomDescriptor.Flags, RoomDescriptorFlag.DEVIL_TREASURE);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Helper function to detect if the provided room is a Double Trouble Boss Room.
|
|
589
|
+
*
|
|
590
|
+
* This is performed by checking for the string "Double Trouble" inside of the room name. The
|
|
591
|
+
* vanilla game uses this convention for every Double Trouble Boss Room. Note that this method might
|
|
592
|
+
* fail for mods that add extra Double Trouble rooms but do not follow the convention.
|
|
593
|
+
*
|
|
594
|
+
* Internally, the game is coded to detect Double Trouble Boss Rooms by checking for the variant
|
|
595
|
+
* range of 3700 through 3850. We intentionally do not use this method since it may not work as well
|
|
596
|
+
* with modded rooms.
|
|
597
|
+
*/
|
|
598
|
+
export function isDoubleTrouble(roomData: RoomConfig): boolean {
|
|
599
|
+
return (
|
|
600
|
+
roomData.Type === RoomType.BOSS && roomData.Name.includes("Double Trouble")
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Helper function to determine if the index of the provided room is equal to `GridRoom.GENESIS`.
|
|
606
|
+
*/
|
|
607
|
+
export function isGenesisRoom(roomDescriptor: RoomDescriptor): boolean {
|
|
608
|
+
return roomDescriptor.GridIndex === asNumber(GridRoom.GENESIS);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Helper function to check if the provided room is either the left Home closet (behind the red
|
|
613
|
+
* door) or the right Home closet (with one random pickup).
|
|
614
|
+
*
|
|
615
|
+
* Home closets have a unique shape that is different from any other room in the game.
|
|
616
|
+
*/
|
|
617
|
+
export function isHomeCloset(roomData: RoomConfig): boolean {
|
|
618
|
+
return (
|
|
619
|
+
roomData.StageID === StageID.HOME &&
|
|
620
|
+
(roomData.Subtype === asNumber(HomeRoomSubType.CLOSET_LEFT) ||
|
|
621
|
+
roomData.Subtype === asNumber(HomeRoomSubType.CLOSET_RIGHT))
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/** Helper function to determine if the provided room is one of the four L room shapes. */
|
|
626
|
+
export function isLRoom(roomData: RoomConfig): boolean {
|
|
627
|
+
return isLRoomShape(roomData.Shape);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Helper function to determine if the index of the provided room is equal to `GridRoom.MEGA_SATAN`.
|
|
632
|
+
*/
|
|
633
|
+
export function isMegaSatanRoom(roomDescriptor: RoomDescriptor): boolean {
|
|
634
|
+
return roomDescriptor.GridIndex === asNumber(GridRoom.MEGA_SATAN);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Helper function to determine if the provided room is part of the Repentance "escape sequence" in
|
|
639
|
+
* the Mines/Ashpit.
|
|
640
|
+
*/
|
|
641
|
+
export function isMineShaft(roomData: RoomConfig): boolean {
|
|
642
|
+
return (
|
|
643
|
+
(roomData.StageID === StageID.MINES ||
|
|
644
|
+
roomData.StageID === StageID.ASHPIT) &&
|
|
645
|
+
// eslint-disable-next-line isaacscript/strict-enums
|
|
646
|
+
MINE_SHAFT_ROOM_SUB_TYPE_SET.has(roomData.Subtype)
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Helper function to check if the provided room is a miniboss room for a particular miniboss. This
|
|
652
|
+
* will only work for mini-bosses that have dedicated boss rooms in the "00.special rooms.stb" file.
|
|
653
|
+
*/
|
|
654
|
+
export function isMinibossRoomOf(
|
|
655
|
+
roomData: RoomConfig,
|
|
656
|
+
minibossID: MinibossID,
|
|
657
|
+
): boolean {
|
|
658
|
+
return (
|
|
659
|
+
roomData.Type === RoomType.MINI_BOSS &&
|
|
660
|
+
roomData.StageID === StageID.SPECIAL_ROOMS &&
|
|
661
|
+
roomData.Subtype === asNumber(minibossID)
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Helper function to check if the provided room is a "mirror room" in Downpour or Dross. (These
|
|
667
|
+
* rooms are marked with a specific sub-type.)
|
|
668
|
+
*/
|
|
669
|
+
export function isMirrorRoom(roomData: RoomConfig): boolean {
|
|
670
|
+
return (
|
|
671
|
+
roomData.Type === RoomType.DEFAULT &&
|
|
672
|
+
(roomData.StageID === StageID.DOWNPOUR ||
|
|
673
|
+
roomData.StageID === StageID.DROSS) &&
|
|
674
|
+
roomData.Subtype === asNumber(DownpourRoomSubType.MIRROR)
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Helper function to check if the provided room matches one of the given room types.
|
|
680
|
+
*
|
|
681
|
+
* This function is variadic, which means you can pass as many room types as you want to match for.
|
|
682
|
+
*/
|
|
683
|
+
export function isRoomType(
|
|
684
|
+
roomData: RoomConfig,
|
|
685
|
+
...roomTypes: RoomType[]
|
|
686
|
+
): boolean {
|
|
687
|
+
return roomTypes.includes(roomData.Type);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Helper function for checking if the provided room is a secret exit that leads to a Repentance
|
|
692
|
+
* floor.
|
|
693
|
+
*/
|
|
694
|
+
export function isSecretExit(roomDescriptor: RoomDescriptor): boolean {
|
|
695
|
+
return roomDescriptor.GridIndex === asNumber(GridRoom.SECRET_EXIT);
|
|
696
|
+
}
|
|
697
|
+
|
|
591
698
|
/**
|
|
592
699
|
* Helper function to detect if a room type is a Secret Room, a Super Secret Room, or an Ultra
|
|
593
700
|
* Secret Room.
|
|
@@ -596,6 +703,18 @@ export function isSecretRoomType(roomType: RoomType): boolean {
|
|
|
596
703
|
return SECRET_ROOM_TYPES.has(roomType);
|
|
597
704
|
}
|
|
598
705
|
|
|
706
|
+
/**
|
|
707
|
+
* Helper function for checking if the provided room is a secret shop (from the Member Card
|
|
708
|
+
* collectible).
|
|
709
|
+
*
|
|
710
|
+
* Secret shops are simply copies of normal shops, but with the backdrop of a secret room. In other
|
|
711
|
+
* words, they will have the same room type, room variant, and room sub-type of a normal shop. Thus,
|
|
712
|
+
* the only way to detect them is by using the grid index.
|
|
713
|
+
*/
|
|
714
|
+
export function isSecretShop(roomDescriptor: RoomDescriptor): boolean {
|
|
715
|
+
return roomDescriptor.GridIndex === asNumber(GridRoom.SECRET_SHOP);
|
|
716
|
+
}
|
|
717
|
+
|
|
599
718
|
/**
|
|
600
719
|
* If the `Room.Update` method is called in a `POST_NEW_ROOM` callback, then some entities will
|
|
601
720
|
* slide around (such as the player). Since those entity velocities are already at zero, setting
|