isaacscript-common 31.7.2 → 31.8.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.
Files changed (111) hide show
  1. package/dist/index.rollup.d.ts +215 -153
  2. package/dist/isaacscript-common.lua +144 -14
  3. package/dist/lualib_bundle.lua +99 -3
  4. package/dist/src/classes/ModFeature.d.ts +2 -2
  5. package/dist/src/classes/callbacks/PostPlayerFatalDamage.d.ts +1 -1
  6. package/dist/src/classes/callbacks/PostPlayerFatalDamage.d.ts.map +1 -1
  7. package/dist/src/classes/callbacks/PostUsePillFilter.d.ts +2 -2
  8. package/dist/src/classes/callbacks/PostUsePillFilter.lua +2 -2
  9. package/dist/src/classes/features/callbackLogic/CustomGridEntities.d.ts +1 -1
  10. package/dist/src/classes/features/other/CustomItemPools.d.ts +1 -1
  11. package/dist/src/classes/features/other/CustomTrapdoors.d.ts +2 -2
  12. package/dist/src/classes/features/other/DebugDisplay.d.ts +18 -18
  13. package/dist/src/classes/features/other/ModdedElementSets.d.ts +2 -2
  14. package/dist/src/classes/features/other/RunInNFrames.d.ts +14 -14
  15. package/dist/src/classes/features/other/SaveDataManager.d.ts +2 -2
  16. package/dist/src/classes/features/other/SpawnRockAltRewards.d.ts +1 -1
  17. package/dist/src/classes/features/other/StageHistory.d.ts +2 -2
  18. package/dist/src/classes/features/other/extraConsoleCommands/commands.d.ts +1 -1
  19. package/dist/src/classes/features/other/extraConsoleCommands/commands.d.ts.map +1 -1
  20. package/dist/src/classes/features/other/extraConsoleCommands/commands.lua +1 -1
  21. package/dist/src/functions/array.d.ts +4 -4
  22. package/dist/src/functions/array.lua +4 -4
  23. package/dist/src/functions/cards.d.ts +1 -1
  24. package/dist/src/functions/cards.d.ts.map +1 -1
  25. package/dist/src/functions/cards.lua +1 -1
  26. package/dist/src/functions/charge.d.ts +1 -1
  27. package/dist/src/functions/charge.lua +1 -1
  28. package/dist/src/functions/collectibles.d.ts +3 -3
  29. package/dist/src/functions/collectibles.lua +3 -3
  30. package/dist/src/functions/debugFunctions.d.ts +2 -2
  31. package/dist/src/functions/debugFunctions.lua +2 -2
  32. package/dist/src/functions/deepCopy.d.ts +2 -2
  33. package/dist/src/functions/deepCopy.lua +2 -2
  34. package/dist/src/functions/globals.d.ts +1 -1
  35. package/dist/src/functions/globals.lua +1 -1
  36. package/dist/src/functions/gridEntities.d.ts +6 -6
  37. package/dist/src/functions/gridEntities.lua +6 -6
  38. package/dist/src/functions/gridEntitiesSpecific.d.ts +22 -22
  39. package/dist/src/functions/gridEntitiesSpecific.lua +22 -22
  40. package/dist/src/functions/input.d.ts +4 -4
  41. package/dist/src/functions/input.lua +4 -4
  42. package/dist/src/functions/logEntities.d.ts +1 -1
  43. package/dist/src/functions/logEntities.lua +1 -1
  44. package/dist/src/functions/minimap.d.ts +17 -20
  45. package/dist/src/functions/minimap.d.ts.map +1 -1
  46. package/dist/src/functions/minimap.lua +17 -20
  47. package/dist/src/functions/nextStage.d.ts +2 -2
  48. package/dist/src/functions/nextStage.lua +2 -2
  49. package/dist/src/functions/pills.d.ts +2 -2
  50. package/dist/src/functions/pills.lua +2 -2
  51. package/dist/src/functions/playerHealth.d.ts +4 -4
  52. package/dist/src/functions/playerHealth.lua +4 -4
  53. package/dist/src/functions/playerIndex.d.ts +2 -3
  54. package/dist/src/functions/playerIndex.d.ts.map +1 -1
  55. package/dist/src/functions/playerIndex.lua +2 -3
  56. package/dist/src/functions/players.d.ts +5 -5
  57. package/dist/src/functions/players.lua +5 -5
  58. package/dist/src/functions/pocketItems.d.ts +5 -5
  59. package/dist/src/functions/pocketItems.lua +5 -5
  60. package/dist/src/functions/revive.d.ts +3 -3
  61. package/dist/src/functions/revive.lua +3 -3
  62. package/dist/src/functions/rooms.d.ts +7 -7
  63. package/dist/src/functions/rooms.lua +7 -7
  64. package/dist/src/functions/run.d.ts +1 -1
  65. package/dist/src/functions/run.lua +1 -1
  66. package/dist/src/functions/set.d.ts +1 -1
  67. package/dist/src/functions/set.lua +1 -1
  68. package/dist/src/functions/stage.d.ts +64 -7
  69. package/dist/src/functions/stage.d.ts.map +1 -1
  70. package/dist/src/functions/stage.lua +80 -16
  71. package/dist/src/functions/trinkets.d.ts +1 -1
  72. package/dist/src/functions/trinkets.lua +1 -1
  73. package/package.json +2 -2
  74. package/src/classes/ModFeature.ts +2 -2
  75. package/src/classes/callbacks/PostPlayerFatalDamage.ts +1 -1
  76. package/src/classes/callbacks/PostUsePillFilter.ts +2 -2
  77. package/src/classes/features/callbackLogic/CustomGridEntities.ts +1 -1
  78. package/src/classes/features/other/CustomItemPools.ts +1 -1
  79. package/src/classes/features/other/CustomTrapdoors.ts +2 -2
  80. package/src/classes/features/other/DebugDisplay.ts +18 -18
  81. package/src/classes/features/other/DisableInputs.ts +2 -2
  82. package/src/classes/features/other/ModdedElementSets.ts +2 -2
  83. package/src/classes/features/other/RunInNFrames.ts +15 -15
  84. package/src/classes/features/other/SaveDataManager.ts +2 -2
  85. package/src/classes/features/other/SpawnRockAltRewards.ts +1 -1
  86. package/src/classes/features/other/StageHistory.ts +2 -2
  87. package/src/classes/features/other/extraConsoleCommands/commands.ts +1 -1
  88. package/src/functions/array.ts +4 -4
  89. package/src/functions/cards.ts +1 -1
  90. package/src/functions/charge.ts +1 -1
  91. package/src/functions/collectibles.ts +3 -3
  92. package/src/functions/debugFunctions.ts +2 -2
  93. package/src/functions/deepCopy.ts +3 -3
  94. package/src/functions/globals.ts +1 -1
  95. package/src/functions/gridEntities.ts +6 -6
  96. package/src/functions/gridEntitiesSpecific.ts +22 -22
  97. package/src/functions/input.ts +4 -4
  98. package/src/functions/logEntities.ts +1 -1
  99. package/src/functions/minimap.ts +17 -20
  100. package/src/functions/nextStage.ts +2 -2
  101. package/src/functions/pills.ts +2 -2
  102. package/src/functions/playerHealth.ts +4 -4
  103. package/src/functions/playerIndex.ts +2 -3
  104. package/src/functions/players.ts +5 -5
  105. package/src/functions/pocketItems.ts +5 -5
  106. package/src/functions/revive.ts +3 -3
  107. package/src/functions/rooms.ts +7 -7
  108. package/src/functions/run.ts +1 -1
  109. package/src/functions/set.ts +1 -1
  110. package/src/functions/stage.ts +139 -33
  111. package/src/functions/trinkets.ts +1 -1
@@ -8,9 +8,9 @@ import { assertDefined } from "./utils";
8
8
 
9
9
  /**
10
10
  * Helper function to add a `DisplayFlag` to a particular room's minimap display flags (e.g. whether
11
- * or not it is visible and so on).
11
+ * it is visible and so on).
12
12
  *
13
- * This function automatically accounts for whether or not MinimapAPI is being used.
13
+ * This function automatically accounts for if MinimapAPI is being used.
14
14
  *
15
15
  * @param roomGridIndex Set to undefined to use the current room index.
16
16
  * @param displayFlag The `DisplayFlag` to set. (See the `DisplayFlag` enum.)
@@ -30,7 +30,7 @@ export function addRoomDisplayFlag(
30
30
  /**
31
31
  * Helper function to set the value of `DisplayFlag` for every room on the floor to 0.
32
32
  *
33
- * This function automatically accounts for whether or not MinimapAPI is being used.
33
+ * This function automatically accounts for if MinimapAPI is being used.
34
34
  *
35
35
  * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
36
36
  * the changes will be immediately visible.
@@ -42,7 +42,7 @@ export function clearFloorDisplayFlags(): void {
42
42
  /**
43
43
  * Helper function to set the value of `DisplayFlag` for a room 0.
44
44
  *
45
- * This function automatically accounts for whether or not MinimapAPI is being used.
45
+ * This function automatically accounts for if MinimapAPI is being used.
46
46
  *
47
47
  * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
48
48
  * the changes will be immediately visible.
@@ -59,10 +59,9 @@ export function clearRoomDisplayFlags(roomGridIndex: int): void {
59
59
  * Helper function to get the minimap `DisplayFlag` value for every room on the floor. Returns a map
60
60
  * that is indexed by the room's safe grid index.
61
61
  *
62
- * This function automatically accounts for whether or not MinimapAPI is being used.
62
+ * This function automatically accounts for if MinimapAPI is being used.
63
63
  *
64
- * @param minimapAPI Optional. Whether or not MinimapAPI should be used, if present. Default is
65
- * true.
64
+ * @param minimapAPI Optional. If MinimapAPI should be used, if present. Default is true.
66
65
  */
67
66
  export function getFloorDisplayFlags(
68
67
  minimapAPI = true,
@@ -79,14 +78,13 @@ export function getFloorDisplayFlags(
79
78
  }
80
79
 
81
80
  /**
82
- * Helper function to get a particular room's minimap display flags (e.g. whether or not it is
83
- * visible and so on).
81
+ * Helper function to get a particular room's minimap display flags (e.g. whether it is visible and
82
+ * so on).
84
83
  *
85
- * This function automatically accounts for whether or not MinimapAPI is being used.
84
+ * This function automatically accounts for if MinimapAPI is being used.
86
85
  *
87
86
  * @param roomGridIndex Optional. Default is the current room index.
88
- * @param minimapAPI Optional. Whether or not MinimapAPI should be used, if present. Default is
89
- * true.
87
+ * @param minimapAPI Optional. If MinimapAPI should be used, if present. Default is true.
90
88
  */
91
89
  export function getRoomDisplayFlags(
92
90
  roomGridIndex?: int,
@@ -117,7 +115,7 @@ export function getRoomDisplayFlags(
117
115
  * This is because if the player enters into the room or walks into an adjacent room, the room will
118
116
  * reappear on the minimap.
119
117
  *
120
- * This function automatically accounts for whether or not MinimapAPI is being used.
118
+ * This function automatically accounts for if MinimapAPI is being used.
121
119
  */
122
120
  export function hideRoomOnMinimap(roomGridIndex: int): void {
123
121
  clearRoomDisplayFlags(roomGridIndex);
@@ -140,8 +138,7 @@ export function hideRoomOnMinimap(roomGridIndex: int): void {
140
138
  * Helper function to check if a given room is visible on the minimap.
141
139
  *
142
140
  * @param roomGridIndex The room to check.
143
- * @param minimapAPI Optional. Whether or not MinimapAPI should be used, if present. Default is
144
- * true.
141
+ * @param minimapAPI Optional. Whether MinimapAPI should be used, if present. Default is true.
145
142
  */
146
143
  export function isRoomVisible(roomGridIndex: int, minimapAPI = true): boolean {
147
144
  const roomDisplayFlags = getRoomDisplayFlags(roomGridIndex, minimapAPI);
@@ -154,7 +151,7 @@ export function isRoomVisible(roomGridIndex: int, minimapAPI = true): boolean {
154
151
  * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
155
152
  * the changes will be immediately visible.
156
153
  *
157
- * This function automatically accounts for whether or not MinimapAPI is being used.
154
+ * This function automatically accounts for if MinimapAPI is being used.
158
155
  */
159
156
  export function setAllDisplayFlags(displayFlags: BitFlags<DisplayFlag>): void {
160
157
  for (const room of getRoomsInsideGrid()) {
@@ -175,7 +172,7 @@ export function setAllDisplayFlags(displayFlags: BitFlags<DisplayFlag>): void {
175
172
  * This function automatically calls the `Level.UpdateVisibility` after setting the flags so that
176
173
  * the changes will be immediately visible.
177
174
  *
178
- * This function automatically accounts for whether or not MinimapAPI is being used.
175
+ * This function automatically accounts for if MinimapAPI is being used.
179
176
  *
180
177
  * @param displayFlagsMap A map of the display flags that is indexed by the room's safe grid index.
181
178
  */
@@ -195,10 +192,10 @@ export function setFloorDisplayFlags(
195
192
  }
196
193
 
197
194
  /**
198
- * Helper function to set a particular room's minimap display flags (e.g. whether or not it is
199
- * visible and so on).
195
+ * Helper function to set a particular room's minimap display flags (e.g. whether it is visible and
196
+ * so on).
200
197
  *
201
- * This function automatically accounts for whether or not MinimapAPI is being used.
198
+ * This function automatically accounts for if MinimapAPI is being used.
202
199
  *
203
200
  * @param roomGridIndex Set to undefined to use the current room index.
204
201
  * @param displayFlags The bit flags value to set. (See the `DisplayFlag` enum.)
@@ -120,8 +120,8 @@ export function getNextStage(): LevelStage {
120
120
  * `getNextStageTypeUsingHistory` helper function instead (from the stage history feature). Handling
121
121
  * this requires stateful tracking as the player progresses through the run.
122
122
  *
123
- * @param upwards Whether or not the player should go up to Cathedral in the case of being on Womb
124
- * 2. Default is false.
123
+ * @param upwards Whether the player should go up to Cathedral in the case of being on Womb 2.
124
+ * Default is false.
125
125
  */
126
126
  export function getNextStageType(upwards = false): StageType {
127
127
  const backwardsPath = game.GetStateFlag(GameStateFlag.BACKWARDS_PATH);
@@ -131,8 +131,8 @@ export function getPillColorFromEffect(pillEffect: PillEffect): PillColor {
131
131
  /**
132
132
  * Helper function to get a pill effect class from a PillEffect enum value. In this context, the
133
133
  * class is equal to the numerical prefix in the "class" tag in the "pocketitems.xml" file. Use the
134
- * `getPillEffectType` helper function to determine whether or not the pill effect is positive,
135
- * negative, or neutral.
134
+ * `getPillEffectType` helper function to determine whether the pill effect is positive, negative,
135
+ * or neutral.
136
136
  *
137
137
  * Due to limitations in the API, this function will not work properly for modded pill effects, and
138
138
  * will always return `DEFAULT_PILL_EFFECT_CLASS` in those cases.
@@ -88,7 +88,7 @@ export function canPickEternalHearts(player: EntityPlayer): boolean {
88
88
  }
89
89
 
90
90
  /**
91
- * Returns whether or not all of the player's soul-heart-type hearts are black hearts.
91
+ * Returns whether all of the player's soul-heart-type hearts are black hearts.
92
92
  *
93
93
  * Note that this function does not consider red heart containers.
94
94
  *
@@ -108,7 +108,7 @@ export function doesPlayerHaveAllBlackHearts(player: EntityPlayer): boolean {
108
108
  }
109
109
 
110
110
  /**
111
- * Returns whether or not all of the player's soul-heart-type hearts are soul hearts.
111
+ * Returns whether all of the player's soul-heart-type hearts are soul hearts.
112
112
  *
113
113
  * Note that this function does not consider red heart containers.
114
114
  *
@@ -439,8 +439,8 @@ export function getPlayerSoulHearts(player: EntityPlayer): int {
439
439
  *
440
440
  * If Tainted Magdalene has Birthright, she will gained an additional non-temporary heart container.
441
441
  *
442
- * This function does not validate whether or not the provided player is Tainted Magdalene; that
443
- * should be accomplished before invoking this function.
442
+ * This function does not validate whether the provided player is Tainted Magdalene; that should be
443
+ * accomplished before invoking this function.
444
444
  */
445
445
  export function getTaintedMagdaleneNonTemporaryMaxHearts(
446
446
  player: EntityPlayer,
@@ -167,9 +167,8 @@ export function getPlayerIndexVanilla(
167
167
  *
168
168
  * If this is not desired, use the `getAllPlayers` helper function instead.
169
169
  *
170
- * @param performCharacterExclusions Whether or not to exclude characters that are not directly
171
- * controlled by the player (i.e. Esau & Tainted Soul). Default is
172
- * false.
170
+ * @param performCharacterExclusions Whether to exclude characters that are not directly controlled
171
+ * by the player (i.e. Esau & Tainted Soul). Default is false.
173
172
  */
174
173
  export function getPlayers(performCharacterExclusions = false): EntityPlayer[] {
175
174
  const players = getAllPlayers();
@@ -149,7 +149,7 @@ export function canPlayerCrushRocks(player: EntityPlayer): boolean {
149
149
  *
150
150
  * If the player does not have an item currently queued, then this function will be a no-op.
151
151
  *
152
- * Returns whether or not an item was actually dequeued.
152
+ * Returns whether an item was actually dequeued.
153
153
  */
154
154
  export function dequeueItem(player: EntityPlayer): boolean {
155
155
  if (player.QueuedItem.Item === undefined) {
@@ -554,8 +554,8 @@ export function hasLostCurse(player: EntityPlayer): boolean {
554
554
  }
555
555
 
556
556
  /**
557
- * Returns whether or not the player can hold an additional active item, beyond what they are
558
- * currently carrying. This takes the Schoolbag into account.
557
+ * Returns whether the player can hold an additional active item, beyond what they are currently
558
+ * carrying. This takes the Schoolbag into account.
559
559
  *
560
560
  * If the player is the Tainted Soul, this always returns false, since that character cannot pick up
561
561
  * items. (Only Tainted Forgotten can pick up items.)
@@ -850,7 +850,7 @@ export function removeTrinketCostume(
850
850
  * @param activeSlot Optional. The slot to set. Default is `ActiveSlot.PRIMARY`.
851
851
  * @param charge Optional. The argument of charges to set. If not specified, the item will be set
852
852
  * with maximum charges.
853
- * @param keepInPools Optional. Whether or not to remove the item from pools. Default is false.
853
+ * @param keepInPools Optional. Whether to remove the item from pools. Default is false.
854
854
  */
855
855
  export function setActiveItem(
856
856
  player: EntityPlayer,
@@ -927,7 +927,7 @@ export function setActiveItem(
927
927
  * The method used in this function was discovered by im_tem.
928
928
  *
929
929
  * @param player The player to apply or remove the blindfold state from.
930
- * @param enabled Whether or not to apply or remove the blindfold.
930
+ * @param enabled Whether to apply or remove the blindfold.
931
931
  * @param modifyCostume Optional. Whether to add or remove the blindfold costume. Default is true.
932
932
  */
933
933
  export function setBlindfold(
@@ -138,9 +138,9 @@ export function getPocketItems(player: EntityPlayer): PocketItemDescription[] {
138
138
  }
139
139
 
140
140
  /**
141
- * Returns whether or not the player can hold an additional pocket item, beyond what they are
142
- * currently carrying. This takes into account items that modify the max number of pocket items,
143
- * like Starter Deck.
141
+ * Returns whether the player can hold an additional pocket item, beyond what they are currently
142
+ * carrying. This takes into account items that modify the max number of pocket items, like Starter
143
+ * Deck.
144
144
  *
145
145
  * If the player is the Tainted Soul, this always returns false, since that character cannot pick up
146
146
  * items. (Only Tainted Forgotten can pick up items.)
@@ -157,8 +157,8 @@ export function hasOpenPocketItemSlot(player: EntityPlayer): boolean {
157
157
  }
158
158
 
159
159
  /**
160
- * Helper function to determine whether or not the player's "active" pocket item slot is set to
161
- * their pocket active item.
160
+ * Helper function to determine whether the player's "active" pocket item slot is set to their
161
+ * pocket active item.
162
162
  */
163
163
  export function isFirstSlotPocketActiveItem(player: EntityPlayer): boolean {
164
164
  const pocketItems = getPocketItems(player);
@@ -117,9 +117,9 @@ export function isDamageToPlayerFatal(
117
117
  }
118
118
 
119
119
  /**
120
- * Assuming that we are on the frame of fatal damage, this function returns whether or not
121
- * Mysterious Paper would rotate to Missing Poster on the frame that the "Game Over" screen would
122
- * appear (which would subsequently save the player from fatal damage).
120
+ * Assuming that we are on the frame of fatal damage, this function returns whether Mysterious Paper
121
+ * would rotate to Missing Poster on the frame that the "Game Over" screen would appear (which would
122
+ * subsequently save the player from fatal damage).
123
123
  *
124
124
  * Mysterious Paper rotates between the 4 items on every frame, in order. The formula for whether
125
125
  * Mysterious Paper be Missing Power is: `gameFrameCount % 4 === 3`
@@ -446,9 +446,9 @@ export function inSecretShop(): boolean {
446
446
  }
447
447
 
448
448
  /**
449
- * Helper function to determine whether or not the current room is the starting room of a floor. It
450
- * only returns true for the starting room of the primary dimension (meaning that being in the
451
- * starting room of the mirror world does not count).
449
+ * Helper function to determine whether the current room is the starting room of a floor. It only
450
+ * returns true for the starting room of the primary dimension (meaning that being in the starting
451
+ * room of the mirror world does not count).
452
452
  */
453
453
  export function inStartingRoom(): boolean {
454
454
  const level = game.GetLevel();
@@ -476,10 +476,10 @@ export function is2x1Room(roomData: RoomConfig): boolean {
476
476
  * @param onlyCheckRoomTypes Optional. A whitelist of room types. If specified, room types not in
477
477
  * the array will be ignored. If not specified, then all rooms will be
478
478
  * checked. Undefined by default.
479
- * @param includeSecretAndSuperSecretRoom Optional. Whether or not to include the Secret Room and
480
- * the Super Secret Room. Default is false.
481
- * @param includeUltraSecretRoom Optional. Whether or not to include the Ultra Secret Room. Default
482
- * is false.
479
+ * @param includeSecretAndSuperSecretRoom Optional. Whether to include the Secret Room and the Super
480
+ * Secret Room. Default is false.
481
+ * @param includeUltraSecretRoom Optional. Whether to include the Ultra Secret Room. Default is
482
+ * false.
483
483
  * @allowEmptyVariadic
484
484
  */
485
485
  export function isAllRoomsClear(
@@ -38,7 +38,7 @@ export function isGreedMode(): boolean {
38
38
  }
39
39
 
40
40
  /**
41
- * Whether or not the player is playing on a set seed (i.e. that they entered in a specific seed by
41
+ * Whether the player is playing on a set seed (i.e. that they entered in a specific seed by
42
42
  * pressing tab on the character selection screen). When the player resets the game on a set seed,
43
43
  * the game will not switch to a different seed.
44
44
  */
@@ -99,7 +99,7 @@ export function getRandomSetElement<T>(
99
99
  * - [1, 2, 3]
100
100
  *
101
101
  * @param set The set to get the combinations of.
102
- * @param includeEmptyArray Whether or not to include an empty array in the combinations.
102
+ * @param includeEmptyArray Whether to include an empty array in the combinations.
103
103
  */
104
104
  export function getSetCombinations<T>(
105
105
  set: Set<T> | ReadonlySet<T>,
@@ -188,6 +188,23 @@ export function goToStage(stage: LevelStage, stageType: StageType): void {
188
188
  Isaac.ExecuteCommand(command);
189
189
  }
190
190
 
191
+ /**
192
+ * Returns whether the provided stage and stage type represent a "final floor". This is defined as a
193
+ * floor that prevents the player from entering the I AM ERROR room on.
194
+ *
195
+ * For example, when using Undefined on The Chest, it has a 50% chance of teleporting the player to
196
+ * the Secret Room and a 50% chance of teleporting the player to the Super Secret Room, because the
197
+ * I AM ERROR room is never entered into the list of possibilities.
198
+ */
199
+ export function isFinalFloor(stage: LevelStage, stageType: StageType): boolean {
200
+ return (
201
+ stage === LevelStage.DARK_ROOM_CHEST ||
202
+ stage === LevelStage.THE_VOID ||
203
+ stage === LevelStage.HOME ||
204
+ (stage === LevelStage.WOMB_2 && isRepentanceStage(stageType)) // Corpse 2
205
+ );
206
+ }
207
+
191
208
  /**
192
209
  * Helper function to check if the provided stage type is equal to `StageType.REPENTANCE` or
193
210
  * `StageType.REPENTANCE_B`.
@@ -198,6 +215,97 @@ export function isRepentanceStage(stageType: StageType): boolean {
198
215
  );
199
216
  }
200
217
 
218
+ /**
219
+ * Helper function to check if the provided effective stage is one that has the possibility to grant
220
+ * a natural Devil Room or Angel Room after killing the boss.
221
+ *
222
+ * Note that in order for this function to work properly, you must provide it with the effective
223
+ * stage (e.g. from the `getEffectiveStage` helper function) and not the absolute stage (e.g. from
224
+ * the `Level.GetStage` method).
225
+ */
226
+ export function isStageWithNaturalDevilRoom(
227
+ effectiveStage: LevelStage,
228
+ ): boolean {
229
+ return (
230
+ inRange(effectiveStage, LevelStage.BASEMENT_2, LevelStage.WOMB_2) &&
231
+ effectiveStage !== LevelStage.BLUE_WOMB
232
+ );
233
+ }
234
+
235
+ /**
236
+ * After defeating the boss on most stages, a random collectible will spawn from the Boss Room pool.
237
+ * However, this does not happen on Depths 2, Womb 2, and beyond.
238
+ */
239
+ export function isStageWithRandomBossCollectible(stage: LevelStage): boolean {
240
+ return stage !== LevelStage.DEPTHS_2 && stage < LevelStage.WOMB_2;
241
+ }
242
+
243
+ /**
244
+ * Helper function to check if the provided stage will spawn a locked door to Downpour/Dross after
245
+ * defeating the boss.
246
+ */
247
+ export function isStageWithSecretExitToDownpour(stage: LevelStage): boolean {
248
+ return stage === LevelStage.BASEMENT_1 || stage === LevelStage.BASEMENT_2;
249
+ }
250
+
251
+ /**
252
+ * Helper function to check if the provided stage and stage type will spawn a spiked door to
253
+ * Mausoleum/Gehenna after defeating the boss.
254
+ */
255
+ export function isStageWithSecretExitToMausoleum(
256
+ stage: LevelStage,
257
+ stageType: StageType,
258
+ ): boolean {
259
+ const repentanceStage = isRepentanceStage(stageType);
260
+
261
+ return (
262
+ (stage === LevelStage.DEPTHS_1 && !repentanceStage) ||
263
+ (stage === LevelStage.CAVES_2 && repentanceStage)
264
+ );
265
+ }
266
+
267
+ /**
268
+ * Helper function to check if the provided stage and stage type will spawn a wooden door to
269
+ * Mines/Ashpit after defeating the boss.
270
+ */
271
+ export function isStageWithSecretExitToMines(
272
+ stage: LevelStage,
273
+ stageType: StageType,
274
+ ): boolean {
275
+ const repentanceStage = isRepentanceStage(stageType);
276
+
277
+ return (
278
+ (stage === LevelStage.CAVES_1 && !repentanceStage) ||
279
+ (stage === LevelStage.BASEMENT_2 && repentanceStage)
280
+ );
281
+ }
282
+
283
+ /**
284
+ * Helper function to check if the current stage is one that would create a trapdoor if We Need to
285
+ * Go Deeper was used.
286
+ */
287
+ export function isStageWithShovelTrapdoors(
288
+ stage: LevelStage,
289
+ stageType: StageType,
290
+ ): boolean {
291
+ const repentanceStage = isRepentanceStage(stageType);
292
+
293
+ return (
294
+ stage < LevelStage.WOMB_2 ||
295
+ (stage === LevelStage.WOMB_2 && !repentanceStage)
296
+ );
297
+ }
298
+
299
+ /**
300
+ * Helper function to check if the provided stage is one with a story boss. Specifically, this is
301
+ * Depths 2 (Mom), Womb 2 (Mom's Heart / It Lives), Blue Womb (Hush), Sheol (Satan), Cathedral
302
+ * (Isaac), Dark Room (Lamb), The Chest (Blue Baby), The Void (Delirium), and Home (Dogma / The
303
+ * Beast).
304
+ */
305
+ export function isStageWithStoryBoss(stage: LevelStage): boolean {
306
+ return stage === LevelStage.DEPTHS_2 || stage >= LevelStage.WOMB_2;
307
+ }
308
+
201
309
  /**
202
310
  * Helper function to check if the player has taken Dad's Note. This sets the game state flag of
203
311
  * `GameStateFlag.BACKWARDS_PATH` and causes floor generation to change.
@@ -250,8 +358,8 @@ export function onEffectiveStage(...effectiveStages: LevelStage[]): boolean {
250
358
  }
251
359
 
252
360
  /**
253
- * Returns whether or not the player is on the "final floor" of the particular run. The final floor
254
- * is defined as one that prevents the player from entering the I AM ERROR room on.
361
+ * Returns whether the player is on the "final floor" of the particular run. The final floor is
362
+ * defined as one that prevents the player from entering the I AM ERROR room on.
255
363
  *
256
364
  * For example, when using Undefined on The Chest, it has a 50% chance of teleporting the player to
257
365
  * the Secret Room and a 50% chance of teleporting the player to the Super Secret Room, because the
@@ -260,17 +368,13 @@ export function onEffectiveStage(...effectiveStages: LevelStage[]): boolean {
260
368
  export function onFinalFloor(): boolean {
261
369
  const level = game.GetLevel();
262
370
  const stage = level.GetStage();
371
+ const stageType = level.GetStageType();
263
372
 
264
- return (
265
- stage === LevelStage.DARK_ROOM_CHEST ||
266
- stage === LevelStage.THE_VOID ||
267
- stage === LevelStage.HOME ||
268
- (stage === LevelStage.WOMB_2 && onRepentanceStage()) // Corpse 2
269
- );
373
+ return isFinalFloor(stage, stageType);
270
374
  }
271
375
 
272
376
  /**
273
- * Returns whether or not the player is on the first floor of the particular run.
377
+ * Returns whether the player is on the first floor of the particular run.
274
378
  *
275
379
  * This is tricky to determine because we have to handle the cases of Downpour/Dross 1 not being the
276
380
  * first floor and The Ascent.
@@ -345,10 +449,7 @@ export function onStageType(...stageTypes: StageType[]): boolean {
345
449
  */
346
450
  export function onStageWithNaturalDevilRoom(): boolean {
347
451
  const effectiveStage = getEffectiveStage();
348
- return (
349
- inRange(effectiveStage, LevelStage.BASEMENT_2, LevelStage.WOMB_2) &&
350
- effectiveStage !== LevelStage.BLUE_WOMB
351
- );
452
+ return isStageWithNaturalDevilRoom(effectiveStage);
352
453
  }
353
454
 
354
455
  /**
@@ -359,7 +460,7 @@ export function onStageWithRandomBossCollectible(): boolean {
359
460
  const level = game.GetLevel();
360
461
  const stage = level.GetStage();
361
462
 
362
- return stage !== LevelStage.DEPTHS_2 && stage < LevelStage.WOMB_2;
463
+ return isStageWithRandomBossCollectible(stage);
363
464
  }
364
465
 
365
466
  /**
@@ -370,7 +471,7 @@ export function onStageWithSecretExitToDownpour(): boolean {
370
471
  const level = game.GetLevel();
371
472
  const stage = level.GetStage();
372
473
 
373
- return stage === LevelStage.BASEMENT_1 || stage === LevelStage.BASEMENT_2;
474
+ return isStageWithSecretExitToDownpour(stage);
374
475
  }
375
476
 
376
477
  /**
@@ -380,12 +481,9 @@ export function onStageWithSecretExitToDownpour(): boolean {
380
481
  export function onStageWithSecretExitToMausoleum(): boolean {
381
482
  const level = game.GetLevel();
382
483
  const stage = level.GetStage();
383
- const repentanceStage = onRepentanceStage();
484
+ const stageType = level.GetStageType();
384
485
 
385
- return (
386
- (stage === LevelStage.DEPTHS_1 && !repentanceStage) ||
387
- (stage === LevelStage.CAVES_2 && repentanceStage)
388
- );
486
+ return isStageWithSecretExitToMausoleum(stage, stageType);
389
487
  }
390
488
 
391
489
  /**
@@ -395,26 +493,34 @@ export function onStageWithSecretExitToMausoleum(): boolean {
395
493
  export function onStageWithSecretExitToMines(): boolean {
396
494
  const level = game.GetLevel();
397
495
  const stage = level.GetStage();
398
- const repentanceStage = onRepentanceStage();
496
+ const stageType = level.GetStageType();
399
497
 
400
- return (
401
- (stage === LevelStage.CAVES_1 && !repentanceStage) ||
402
- (stage === LevelStage.BASEMENT_2 && repentanceStage)
403
- );
498
+ return isStageWithSecretExitToMines(stage, stageType);
404
499
  }
405
500
 
406
501
  /**
407
502
  * Helper function to check if the current stage is one that would create a trapdoor if We Need to
408
503
  * Go Deeper was used.
409
504
  */
410
- export function onStageWithShovelWorking(): boolean {
505
+ export function onStageWithShovelTrapdoors(): boolean {
411
506
  const level = game.GetLevel();
412
507
  const stage = level.GetStage();
508
+ const stageType = level.GetStageType();
413
509
 
414
- return (
415
- stage < LevelStage.WOMB_2 ||
416
- (stage === LevelStage.WOMB_2 && !onRepentanceStage())
417
- );
510
+ return isStageWithShovelTrapdoors(stage, stageType);
511
+ }
512
+
513
+ /**
514
+ * Helper function to check if the current stage is one with a story boss. Specifically, this is
515
+ * Depths 2 (Mom), Womb 2 (Mom's Heart / It Lives), Blue Womb (Hush), Sheol (Satan), Cathedral
516
+ * (Isaac), Dark Room (Lamb), The Chest (Blue Baby), The Void (Delirium), and Home (Dogma / The
517
+ * Beast).
518
+ */
519
+ export function onStageWithStoryBoss(): boolean {
520
+ const level = game.GetLevel();
521
+ const stage = level.GetStage();
522
+
523
+ return isStageWithStoryBoss(stage);
418
524
  }
419
525
 
420
526
  /**
@@ -425,9 +531,9 @@ export function onStageWithShovelWorking(): boolean {
425
531
  *
426
532
  * @param stage The stage number to warp to.
427
533
  * @param stageType The stage type to warp to.
428
- * @param reseed Optional. Whether or not to reseed the floor upon arrival. Default is false. Set
429
- * this to true if you are warping to the same stage but a different stage type (or
430
- * else the floor layout will be identical to the old floor).
534
+ * @param reseed Optional. Whether to reseed the floor upon arrival. Default is false. Set this to
535
+ * true if you are warping to the same stage but a different stage type (or else the
536
+ * floor layout will be identical to the old floor).
431
537
  */
432
538
  export function setStage(
433
539
  stage: LevelStage,
@@ -197,7 +197,7 @@ export function getVanillaTrinketTypeRange(): TrinketType[] {
197
197
  }
198
198
 
199
199
  /**
200
- * Returns whether or not the player can hold an additional trinket, beyond what they are currently
200
+ * Returns whether the player can hold an additional trinket, beyond what they are currently
201
201
  * carrying. This takes into account items that modify the max number of trinkets, like Mom's Purse.
202
202
  *
203
203
  * If the player is the Tainted Soul, this always returns false, since that character cannot pick up