isaacscript-common 80.1.0 → 80.2.1

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 (66) hide show
  1. package/dist/classes/callbacks/PostItemDischarge.d.ts.map +1 -1
  2. package/dist/classes/callbacks/PostItemDischarge.lua +1 -3
  3. package/dist/classes/features/other/CustomPickups.d.ts.map +1 -1
  4. package/dist/classes/features/other/CustomPickups.lua +1 -3
  5. package/dist/classes/features/other/CustomStages.d.ts.map +1 -1
  6. package/dist/classes/features/other/CustomStages.lua +1 -3
  7. package/dist/classes/features/other/DeployJSONRoom.d.ts.map +1 -1
  8. package/dist/classes/features/other/DeployJSONRoom.lua +4 -4
  9. package/dist/classes/features/other/ModdedElementDetection.d.ts +31 -20
  10. package/dist/classes/features/other/ModdedElementDetection.d.ts.map +1 -1
  11. package/dist/classes/features/other/ModdedElementDetection.lua +23 -49
  12. package/dist/classes/features/other/StageHistory.d.ts.map +1 -1
  13. package/dist/classes/features/other/StageHistory.lua +1 -3
  14. package/dist/classes/features/other/extraConsoleCommands/commands.d.ts.map +1 -1
  15. package/dist/classes/features/other/extraConsoleCommands/commands.lua +1 -6
  16. package/dist/core/constantsFirstLast.d.ts +29 -6
  17. package/dist/core/constantsFirstLast.d.ts.map +1 -1
  18. package/dist/core/constantsFirstLast.lua +18 -3
  19. package/dist/functions/bosses.d.ts.map +1 -1
  20. package/dist/functions/bosses.lua +1 -3
  21. package/dist/functions/doors.d.ts.map +1 -1
  22. package/dist/functions/doors.lua +5 -7
  23. package/dist/functions/gridEntities.lua +1 -2
  24. package/dist/functions/gridEntitiesSpecific.d.ts.map +1 -1
  25. package/dist/functions/gridEntitiesSpecific.lua +5 -7
  26. package/dist/functions/nextStage.d.ts.map +1 -1
  27. package/dist/functions/nextStage.lua +4 -6
  28. package/dist/functions/npcs.d.ts.map +1 -1
  29. package/dist/functions/npcs.lua +3 -5
  30. package/dist/functions/pills.d.ts.map +1 -1
  31. package/dist/functions/pills.lua +8 -16
  32. package/dist/functions/pocketItems.d.ts.map +1 -1
  33. package/dist/functions/pocketItems.lua +1 -3
  34. package/dist/functions/rooms.d.ts.map +1 -1
  35. package/dist/functions/rooms.lua +13 -15
  36. package/dist/functions/set.d.ts +37 -1
  37. package/dist/functions/set.d.ts.map +1 -1
  38. package/dist/functions/set.lua +56 -11
  39. package/dist/functions/stage.lua +2 -6
  40. package/dist/functions/trinkets.lua +2 -2
  41. package/dist/functions/types.d.ts +29 -0
  42. package/dist/functions/types.d.ts.map +1 -1
  43. package/dist/index.rollup.d.ts +97 -27
  44. package/dist/isaacscript-common.lua +152 -158
  45. package/package.json +2 -2
  46. package/src/classes/callbacks/PostItemDischarge.ts +1 -2
  47. package/src/classes/features/other/CustomPickups.ts +1 -2
  48. package/src/classes/features/other/CustomStages.ts +1 -4
  49. package/src/classes/features/other/DeployJSONRoom.ts +5 -9
  50. package/src/classes/features/other/ModdedElementDetection.ts +61 -77
  51. package/src/classes/features/other/StageHistory.ts +1 -2
  52. package/src/classes/features/other/extraConsoleCommands/commands.ts +2 -6
  53. package/src/core/constantsFirstLast.ts +29 -6
  54. package/src/functions/bosses.ts +1 -2
  55. package/src/functions/doors.ts +5 -6
  56. package/src/functions/gridEntities.ts +2 -2
  57. package/src/functions/gridEntitiesSpecific.ts +5 -6
  58. package/src/functions/nextStage.ts +4 -5
  59. package/src/functions/npcs.ts +3 -4
  60. package/src/functions/pills.ts +4 -6
  61. package/src/functions/pocketItems.ts +1 -2
  62. package/src/functions/rooms.ts +15 -17
  63. package/src/functions/set.ts +79 -11
  64. package/src/functions/stage.ts +3 -3
  65. package/src/functions/trinkets.ts +2 -2
  66. package/src/functions/types.ts +30 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "80.1.0",
3
+ "version": "80.2.1",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -37,6 +37,6 @@
37
37
  "lint": "tsx --tsconfig ./scripts/tsconfig.json ./scripts/lint.mts"
38
38
  },
39
39
  "dependencies": {
40
- "isaac-typescript-definitions": "^39.0.2"
40
+ "isaac-typescript-definitions": "^39.0.3"
41
41
  }
42
42
  }
@@ -13,7 +13,6 @@ import {
13
13
  mapGetPlayer,
14
14
  mapSetPlayer,
15
15
  } from "../../functions/playerDataStructures";
16
- import { asNumber } from "../../functions/types";
17
16
  import type { PlayerIndex } from "../../types/PlayerIndex";
18
17
  import { DefaultMap } from "../DefaultMap";
19
18
  import type { FireArgs, OptionalArgs } from "../private/CustomCallback";
@@ -84,7 +83,7 @@ export class PostItemDischarge extends CustomCallback<T> {
84
83
  npc: EntityNPC,
85
84
  collider: Entity,
86
85
  ): boolean | undefined => {
87
- if (npc.Variant === asNumber(SuckerVariant.BULB)) {
86
+ if (npc.Variant === SuckerVariant.BULB) {
88
87
  return this.preNPCCollisionBulb(npc, collider);
89
88
  }
90
89
 
@@ -11,7 +11,6 @@ import {
11
11
  getEntityIDFromConstituents,
12
12
  } from "../../../functions/entities";
13
13
  import { spawnEffect } from "../../../functions/entitiesSpecific";
14
- import { asNumber } from "../../../functions/types";
15
14
  import { Feature } from "../../private/Feature";
16
15
 
17
16
  interface CustomPickupFunctions {
@@ -97,7 +96,7 @@ export class CustomPickups extends Feature {
97
96
  // ModCallback.POST_EFFECT_RENDER (56)
98
97
  // PICKUP_EFFECT_VARIANT
99
98
  private readonly postEffectRenderPickupEffect = (effect: EntityEffect) => {
100
- if (effect.SubType !== asNumber(PICKUP_EFFECT_SUB_TYPE)) {
99
+ if (effect.SubType !== PICKUP_EFFECT_SUB_TYPE) {
101
100
  return;
102
101
  }
103
102
 
@@ -30,7 +30,6 @@ import {
30
30
  } from "../../../functions/rooms";
31
31
  import { getMusicForStage } from "../../../functions/sound";
32
32
  import { setStage } from "../../../functions/stage";
33
- import { asNumber } from "../../../functions/types";
34
33
  import { assertDefined } from "../../../functions/utils";
35
34
  import type {
36
35
  CustomStageLua,
@@ -532,9 +531,7 @@ export class CustomStages extends Feature {
532
531
  ? DEFAULT_BASE_STAGE_TYPE
533
532
  : (customStage.baseStageType as StageType);
534
533
 
535
- // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
536
- const reseed = asNumber(stage) >= baseStage;
537
-
534
+ const reseed = stage >= baseStage;
538
535
  setStage(baseStage, baseStageType, reseed);
539
536
 
540
537
  // As soon as we warp to the base stage, the base stage music will begin to play. Thus, we
@@ -28,7 +28,7 @@ import { isRNG, newRNG } from "../../../functions/rng";
28
28
  import { gridCoordinatesToWorldPosition } from "../../../functions/roomGrid";
29
29
  import { setRoomCleared, setRoomUncleared } from "../../../functions/rooms";
30
30
  import { spawnCollectible } from "../../../functions/spawnCollectible";
31
- import { asCollectibleType, asNumber } from "../../../functions/types";
31
+ import { asCollectibleType } from "../../../functions/types";
32
32
  import { assertDefined } from "../../../functions/utils";
33
33
  import type { JSONRoom } from "../../../interfaces/JSONRoomsFile";
34
34
  import { ReadonlySet } from "../../../types/ReadonlySet";
@@ -162,15 +162,11 @@ export class DeployJSONRoom extends Feature {
162
162
  let entity: Entity;
163
163
  if (
164
164
  entityType === EntityType.PICKUP &&
165
- variant === asNumber(PickupVariant.COLLECTIBLE)
165
+ variant === PickupVariant.COLLECTIBLE
166
166
  ) {
167
+ const collectibleType = asCollectibleType(subType);
167
168
  const options = roomType === RoomType.ANGEL;
168
- entity = spawnCollectible(
169
- asCollectibleType(subType),
170
- position,
171
- seed,
172
- options,
173
- );
169
+ entity = spawnCollectible(collectibleType, position, seed, options);
174
170
  } else {
175
171
  entity = spawnWithSeed(entityType, variant, subType, position, seed);
176
172
  }
@@ -178,7 +174,7 @@ export class DeployJSONRoom extends Feature {
178
174
  // For some reason, Pitfalls do not spawn with the correct collision classes.
179
175
  if (
180
176
  entityType === EntityType.PITFALL &&
181
- variant === asNumber(PitfallVariant.PITFALL)
177
+ variant === PitfallVariant.PITFALL
182
178
  ) {
183
179
  entity.EntityCollisionClass = EntityCollisionClass.ENEMIES;
184
180
  entity.GridCollisionClass = EntityGridCollisionClass.WALLS;
@@ -17,15 +17,23 @@ import {
17
17
  NUM_VANILLA_TRINKET_TYPES,
18
18
  } from "../../../core/constantsFirstLast";
19
19
  import { Exported } from "../../../decorators";
20
- import {
21
- asCardType,
22
- asCollectibleType,
23
- asNumber,
24
- asPillEffect,
25
- asTrinketType,
26
- } from "../../../functions/types";
27
20
  import { Feature } from "../../private/Feature";
28
21
 
22
+ // eslint-disable-next-line isaacscript/strict-enums
23
+ export const FIRST_MODDED_COLLECTIBLE_TYPE: CollectibleType =
24
+ LAST_VANILLA_COLLECTIBLE_TYPE + 1;
25
+
26
+ // eslint-disable-next-line isaacscript/strict-enums
27
+ export const FIRST_MODDED_TRINKET_TYPE: TrinketType =
28
+ LAST_VANILLA_TRINKET_TYPE + 1;
29
+
30
+ // eslint-disable-next-line isaacscript/strict-enums
31
+ export const FIRST_MODDED_CARD_TYPE: CardType = LAST_VANILLA_CARD_TYPE + 1;
32
+
33
+ // eslint-disable-next-line isaacscript/strict-enums
34
+ export const FIRST_MODDED_PILL_EFFECT: PillEffect =
35
+ LAST_VANILLA_PILL_EFFECT + 1;
36
+
29
37
  /**
30
38
  * Mods can add extra things to the game (e.g. collectibles, trinkets, and so on). Since mods load
31
39
  * in alphabetical order, the total number of things can't be properly be known until at least one
@@ -82,16 +90,13 @@ export class ModdedElementDetection extends Feature {
82
90
  public getFirstModdedCollectibleType(): CollectibleType | undefined {
83
91
  this.errorIfNoCallbacksFired("collectible");
84
92
 
85
- const firstModdedCollectibleType = asCollectibleType(
86
- asNumber(LAST_VANILLA_COLLECTIBLE_TYPE) + 1,
87
- );
88
93
  const itemConfigItem = itemConfig.GetCollectible(
89
- firstModdedCollectibleType,
94
+ FIRST_MODDED_COLLECTIBLE_TYPE,
90
95
  );
91
96
 
92
97
  return itemConfigItem === undefined
93
98
  ? undefined
94
- : firstModdedCollectibleType;
99
+ : FIRST_MODDED_COLLECTIBLE_TYPE;
95
100
  }
96
101
 
97
102
  /**
@@ -100,7 +105,7 @@ export class ModdedElementDetection extends Feature {
100
105
  * Equal to `itemConfig.GetCollectibles().Size - 1`. (`Size` includes invalid collectibles, like
101
106
  * 666. We subtract one to account for `CollectibleType.NULL`.)
102
107
  *
103
- * If there are no mods present that add any custom items, this function will return
108
+ * If there are no mods present that add any custom collectibles, this function will return
104
109
  * `CollectibleType.MOMS_RING` (732).
105
110
  *
106
111
  * This function can only be called if at least one callback has been executed. This is because
@@ -120,7 +125,7 @@ export class ModdedElementDetection extends Feature {
120
125
 
121
126
  /**
122
127
  * Returns the total number of collectibles in the item config, including both vanilla and modded
123
- * items. If you just need the number of vanilla collectible types, use the
128
+ * collectibles. If you just need the number of vanilla collectible types, use the
124
129
  * `NUM_VANILLA_COLLECTIBLE_TYPES` constant.
125
130
  *
126
131
  * This function can only be called if at least one callback has been executed. This is because
@@ -135,9 +140,7 @@ export class ModdedElementDetection extends Feature {
135
140
  @Exported
136
141
  public getNumCollectibleTypes(): int {
137
142
  this.errorIfNoCallbacksFired("collectible");
138
-
139
- const numModdedCollectibleTypes = this.getNumModdedCollectibleTypes();
140
- return NUM_VANILLA_COLLECTIBLE_TYPES + numModdedCollectibleTypes;
143
+ return NUM_VANILLA_COLLECTIBLE_TYPES + this.getNumModdedCollectibleTypes();
141
144
  }
142
145
 
143
146
  /**
@@ -155,9 +158,7 @@ export class ModdedElementDetection extends Feature {
155
158
  @Exported
156
159
  public getNumModdedCollectibleTypes(): int {
157
160
  this.errorIfNoCallbacksFired("collectible");
158
-
159
- const lastCollectibleType = this.getLastCollectibleType();
160
- return lastCollectibleType - LAST_VANILLA_COLLECTIBLE_TYPE;
161
+ return this.getLastCollectibleType() - LAST_VANILLA_COLLECTIBLE_TYPE;
161
162
  }
162
163
 
163
164
  // --------
@@ -179,11 +180,8 @@ export class ModdedElementDetection extends Feature {
179
180
  public getFirstModdedTrinketType(): TrinketType | undefined {
180
181
  this.errorIfNoCallbacksFired("trinket");
181
182
 
182
- const firstModdedTrinketType = asTrinketType(
183
- asNumber(LAST_VANILLA_TRINKET_TYPE) + 1,
184
- );
185
- const itemConfigItem = itemConfig.GetTrinket(firstModdedTrinketType);
186
- return itemConfigItem === undefined ? undefined : firstModdedTrinketType;
183
+ const itemConfigItem = itemConfig.GetTrinket(FIRST_MODDED_TRINKET_TYPE);
184
+ return itemConfigItem === undefined ? undefined : FIRST_MODDED_TRINKET_TYPE;
187
185
  }
188
186
 
189
187
  /**
@@ -211,7 +209,7 @@ export class ModdedElementDetection extends Feature {
211
209
 
212
210
  /**
213
211
  * Returns the total number of trinkets in the item config, including both vanilla and modded
214
- * items. If you just need the number of vanilla trinket types, use the
212
+ * trinkets. If you just need the number of vanilla trinket types, use the
215
213
  * `NUM_VANILLA_TRINKET_TYPES` constant.
216
214
  *
217
215
  * This function can only be called if at least one callback has been executed. This is because
@@ -225,9 +223,7 @@ export class ModdedElementDetection extends Feature {
225
223
  @Exported
226
224
  public getNumTrinketTypes(): int {
227
225
  this.errorIfNoCallbacksFired("trinket");
228
-
229
- const numModdedTrinketTypes = this.getNumModdedTrinketTypes();
230
- return NUM_VANILLA_TRINKET_TYPES + numModdedTrinketTypes;
226
+ return NUM_VANILLA_TRINKET_TYPES + this.getNumModdedTrinketTypes();
231
227
  }
232
228
 
233
229
  /**
@@ -244,9 +240,7 @@ export class ModdedElementDetection extends Feature {
244
240
  @Exported
245
241
  public getNumModdedTrinketTypes(): int {
246
242
  this.errorIfNoCallbacksFired("trinket");
247
-
248
- const lastTrinketType = this.getLastTrinketType();
249
- return lastTrinketType - LAST_VANILLA_TRINKET_TYPE;
243
+ return this.getLastTrinketType() - LAST_VANILLA_TRINKET_TYPE;
250
244
  }
251
245
 
252
246
  // -----
@@ -268,22 +262,21 @@ export class ModdedElementDetection extends Feature {
268
262
  public getFirstModdedCardType(): CardType | undefined {
269
263
  this.errorIfNoCallbacksFired("card");
270
264
 
271
- const firstModdedCardType = asCardType(
272
- asNumber(LAST_VANILLA_CARD_TYPE) + 1,
273
- );
274
-
275
- const itemConfigCard = itemConfig.GetCard(firstModdedCardType);
276
- return itemConfigCard === undefined ? undefined : firstModdedCardType;
265
+ const itemConfigCard = itemConfig.GetCard(FIRST_MODDED_CARD_TYPE);
266
+ return itemConfigCard === undefined ? undefined : FIRST_MODDED_CARD_TYPE;
277
267
  }
278
268
 
279
269
  /**
280
270
  * Will change depending on how many modded cards there are.
281
271
  *
282
- * This is equal to the number of cards, since all card sub-types are contiguous (unlike
283
- * collectibles).
272
+ * Equal to `itemConfig.GetCards().Size - 1`. (`Size` includes invalid cards, but since cards are
273
+ * contiguous, there are no invalid cards. We subtract one to account for `CardType.NULL`.)
274
+ *
275
+ * If there are no mods present that add any custom cards, this function will return
276
+ * `CardType.SOUL_OF_JACOB_AND_ESAU` (97).
284
277
  *
285
278
  * This function can only be called if at least one callback has been executed. This is because
286
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
279
+ * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
287
280
  *
288
281
  * In order to use this function, you must upgrade your mod with
289
282
  * `ISCFeature.MODDED_ELEMENT_DETECTION`.
@@ -293,15 +286,12 @@ export class ModdedElementDetection extends Feature {
293
286
  @Exported
294
287
  public getLastCardType(): CardType {
295
288
  this.errorIfNoCallbacksFired("card");
296
-
297
- const numCards = this.getNumCardTypes();
298
- return asCardType(numCards);
289
+ return itemConfig.GetCards().Size - 1;
299
290
  }
300
291
 
301
292
  /**
302
- * Will change depending on how many modded cards there are.
303
- *
304
- * Equal to `itemConfig.GetCards().Size - 1`. (We subtract one to account for `Card.NULL`.)
293
+ * Returns the total number of cards in the item config, including both vanilla and modded cards.
294
+ * If you just need the number of vanilla card types, use the `NUM_VANILLA_CARD_TYPES` constant.
305
295
  *
306
296
  * This function can only be called if at least one callback has been executed. This is because
307
297
  * not all cards will necessarily be present when a mod first loads (due to mod load order).
@@ -314,12 +304,14 @@ export class ModdedElementDetection extends Feature {
314
304
  @Exported
315
305
  public getNumCardTypes(): int {
316
306
  this.errorIfNoCallbacksFired("card");
317
- return itemConfig.GetCards().Size - 1;
307
+ return NUM_VANILLA_CARD_TYPES + this.getNumModdedCardTypes();
318
308
  }
319
309
 
320
310
  /**
311
+ * Like vanilla card types, modded card types are always contiguous.
312
+ *
321
313
  * This function can only be called if at least one callback has been executed. This is because
322
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
314
+ * not all cards will necessarily be present when a mod first loads (due to mod load order).
323
315
  *
324
316
  * In order to use this function, you must upgrade your mod with
325
317
  * `ISCFeature.MODDED_ELEMENT_DETECTION`.
@@ -329,9 +321,7 @@ export class ModdedElementDetection extends Feature {
329
321
  @Exported
330
322
  public getNumModdedCardTypes(): int {
331
323
  this.errorIfNoCallbacksFired("card");
332
-
333
- const numCardTypes = this.getNumCardTypes();
334
- return numCardTypes - NUM_VANILLA_CARD_TYPES;
324
+ return this.getLastCardType() - LAST_VANILLA_CARD_TYPE;
335
325
  }
336
326
 
337
327
  // ------------
@@ -354,23 +344,24 @@ export class ModdedElementDetection extends Feature {
354
344
  public getFirstModdedPillEffect(): PillEffect | undefined {
355
345
  this.errorIfNoCallbacksFired("pill");
356
346
 
357
- const firstModdedPillEffect = asPillEffect(
358
- asNumber(LAST_VANILLA_PILL_EFFECT) + 1,
359
- );
360
347
  const itemConfigPillEffect = itemConfig.GetPillEffect(
361
- firstModdedPillEffect,
348
+ FIRST_MODDED_PILL_EFFECT,
362
349
  );
363
350
 
364
351
  return itemConfigPillEffect === undefined
365
352
  ? undefined
366
- : firstModdedPillEffect;
353
+ : FIRST_MODDED_PILL_EFFECT;
367
354
  }
368
355
 
369
356
  /**
370
357
  * Will change depending on how many modded pill effects there are.
371
358
  *
372
- * This is equal to the number of pill effects, since all pill effects are contiguous (unlike
373
- * collectibles).
359
+ * Equal to `itemConfig.GetPillEffects().Size - 1`. (`Size` includes invalid pill effects, but
360
+ * since pill effects are contiguous, there are no invalid pill effects. We subtract one to
361
+ * account for the enum starting at 0 instead of 1.)
362
+ *
363
+ * If there are no mods present that add any custom pill effects, this function will return
364
+ * `PillEffect.EXPERIMENTAL` (49).
374
365
  *
375
366
  * This function can only be called if at least one callback has been executed. This is because
376
367
  * not all pill effects will necessarily be present when a mod first loads (due to mod load
@@ -384,22 +375,16 @@ export class ModdedElementDetection extends Feature {
384
375
  @Exported
385
376
  public getLastPillEffect(): PillEffect {
386
377
  this.errorIfNoCallbacksFired("pill");
387
-
388
- // We need to subtract one because Bad Gas is ID 0. In other words, in vanilla Repentance, there
389
- // are 50 pill effects that have IDs from 0 to 49, so the highest pill effect is 49.
390
- const numPillEffects = this.getNumPillEffects() - 1;
391
- return asPillEffect(numPillEffects);
378
+ return itemConfig.GetPillEffects().Size - 1;
392
379
  }
393
380
 
394
381
  /**
395
- * Will change depending on how many modded pill effects there are.
396
- *
397
- * Equal to `itemConfig.GetPillEffects().Size`. (We do not have to subtract one, because the first
398
- * pill effect has an ID of 0 and there is no `PillEffect.NULL`.)
382
+ * Returns the total number of pill effects in the item config, including both vanilla and modded
383
+ * pill effects. If you just need the number of vanilla pill effects, use the
384
+ * `NUM_VANILLA_PILL_EFFECTS` constant.
399
385
  *
400
386
  * This function can only be called if at least one callback has been executed. This is because
401
- * not all pill effects will necessarily be present when a mod first loads (due to mod load
402
- * order).
387
+ * not all cards will necessarily be present when a mod first loads (due to mod load order).
403
388
  *
404
389
  * In order to use this function, you must upgrade your mod with
405
390
  * `ISCFeature.MODDED_ELEMENT_DETECTION`.
@@ -409,13 +394,14 @@ export class ModdedElementDetection extends Feature {
409
394
  @Exported
410
395
  public getNumPillEffects(): int {
411
396
  this.errorIfNoCallbacksFired("pill");
412
- return itemConfig.GetPillEffects().Size;
397
+ return NUM_VANILLA_PILL_EFFECTS + this.getNumModdedPillEffects();
413
398
  }
414
399
 
415
400
  /**
401
+ * Like vanilla pill effects, modded pill effects are always contiguous.
402
+ *
416
403
  * This function can only be called if at least one callback has been executed. This is because
417
- * not all pill effects will necessarily be present when a mod first loads (due to mod load
418
- * order).
404
+ * not all cards will necessarily be present when a mod first loads (due to mod load order).
419
405
  *
420
406
  * In order to use this function, you must upgrade your mod with
421
407
  * `ISCFeature.MODDED_ELEMENT_DETECTION`.
@@ -424,9 +410,7 @@ export class ModdedElementDetection extends Feature {
424
410
  */
425
411
  @Exported
426
412
  public getNumModdedPillEffects(): int {
427
- this.errorIfNoCallbacksFired("pill");
428
-
429
- const numPillEffects = this.getNumPillEffects();
430
- return numPillEffects - NUM_VANILLA_PILL_EFFECTS;
413
+ this.errorIfNoCallbacksFired("card");
414
+ return this.getLastPillEffect() - LAST_VANILLA_PILL_EFFECT;
431
415
  }
432
416
  }
@@ -11,7 +11,6 @@ import {
11
11
  calculateStageType,
12
12
  onRepentanceStage,
13
13
  } from "../../../functions/stage";
14
- import { asNumber } from "../../../functions/types";
15
14
  import type { StageHistoryEntry } from "../../../interfaces/StageHistoryEntry";
16
15
  import { Feature } from "../../private/Feature";
17
16
 
@@ -289,7 +288,7 @@ export class StageHistory extends Feature {
289
288
  return LevelStage.DEPTHS_1;
290
289
  }
291
290
 
292
- return asNumber(stage) - 1;
291
+ return stage - 1;
293
292
  }
294
293
 
295
294
  /**
@@ -124,11 +124,7 @@ import { spawnCollectible as spawnCollectibleFunc } from "../../../../functions/
124
124
  import { onStage, setStage } from "../../../../functions/stage";
125
125
  import { getMapPartialMatch } from "../../../../functions/string";
126
126
  import { getGoldenTrinketType } from "../../../../functions/trinkets";
127
- import {
128
- asCardType,
129
- asCollectibleType,
130
- asTrinketType,
131
- } from "../../../../functions/types";
127
+ import { asCollectibleType, asTrinketType } from "../../../../functions/types";
132
128
  import { iRange } from "../../../../functions/utils";
133
129
  import { CARD_NAME_TO_TYPE_MAP } from "../../../../maps/cardNameToTypeMap";
134
130
  import { CHARACTER_NAME_TO_TYPE_MAP } from "../../../../maps/characterNameToTypeMap";
@@ -423,7 +419,7 @@ export function cards(): void {
423
419
  }
424
420
 
425
421
  const worldPosition = gridCoordinatesToWorldPosition(x, y);
426
- spawnCard(asCardType(cardType), worldPosition);
422
+ spawnCard(cardType, worldPosition);
427
423
  cardType++; // eslint-disable-line isaacscript/strict-enums
428
424
  }
429
425
  }
@@ -28,8 +28,8 @@ export const FIRST_COLLECTIBLE_TYPE = CollectibleType.SAD_ONION;
28
28
  /**
29
29
  * Calculated from the `CollectibleType` enum.
30
30
  *
31
- * Note that this cannot be calculated from the length of the enum, because unlike all of the other
32
- * enums, collectible types are not contiguous.
31
+ * Note that this cannot be calculated from the length of the enum, because collectible types are
32
+ * not contiguous.
33
33
  */
34
34
  export const LAST_VANILLA_COLLECTIBLE_TYPE =
35
35
  getHighestEnumValue(CollectibleType);
@@ -44,7 +44,12 @@ export const NUM_VANILLA_COLLECTIBLE_TYPES = getEnumLength(CollectibleType) - 1;
44
44
  /** Equal to `TrinketType.SWALLOWED_PENNY`. */
45
45
  export const FIRST_TRINKET_TYPE = TrinketType.SWALLOWED_PENNY;
46
46
 
47
- /** Calculated from the `TrinketType` enum. */
47
+ /**
48
+ * Calculated from the `TrinketType` enum.
49
+ *
50
+ * Note that this cannot be calculated from the length of the enum, because trinket types are not
51
+ * contiguous.
52
+ */
48
53
  export const LAST_VANILLA_TRINKET_TYPE = getHighestEnumValue(TrinketType);
49
54
 
50
55
  /** Calculated from the `TrinketType` enum. (`TrinketType.NULL` is not included.) */
@@ -57,7 +62,13 @@ export const NUM_VANILLA_TRINKET_TYPES = getEnumLength(TrinketType) - 1;
57
62
  /** Equal to `Card.FOOL`. */
58
63
  export const FIRST_CARD_TYPE = CardType.FOOL;
59
64
 
60
- /** Calculated from the `Card` enum. */
65
+ /**
66
+ * Calculated from the `CardType` enum.
67
+ *
68
+ * Note that this could be calculated from the length of the enum, because card types are
69
+ * contiguous. However, we instead get the highest enum value to be safer and to make the code more
70
+ * consistent with collectibles and trinkets.
71
+ */
61
72
  export const LAST_VANILLA_CARD_TYPE = getHighestEnumValue(CardType);
62
73
 
63
74
  /** Calculated from the `Card` enum. `Card.NULL` is not included. */
@@ -70,7 +81,13 @@ export const NUM_VANILLA_CARD_TYPES = getEnumLength(CardType) - 1;
70
81
  /** Equal to `PillEffect.BAD_GAS`. */
71
82
  export const FIRST_PILL_EFFECT = PillEffect.BAD_GAS;
72
83
 
73
- /** Calculated from the `PillEffect` enum. */
84
+ /**
85
+ * Calculated from the `PillEffect` enum.
86
+ *
87
+ * Note that this could be calculated from the length of the enum, because pill effects are
88
+ * contiguous. However, we instead get the highest enum value to be safer and to make the code more
89
+ * consistent with collectibles and trinkets.
90
+ */
74
91
  export const LAST_VANILLA_PILL_EFFECT = getHighestEnumValue(PillEffect);
75
92
 
76
93
  /**
@@ -119,7 +136,13 @@ export const FIRST_CHARACTER = PlayerType.ISAAC;
119
136
 
120
137
  // It is not possible to determine "LAST_PLAYER_TYPE", since there is no associated config.
121
138
 
122
- /** Calculated from the `PlayerType` enum. */
139
+ /**
140
+ * Calculated from the `PlayerType` enum.
141
+ *
142
+ * Note that this could be calculated from the length of the enum, because characters are
143
+ * contiguous. However, we instead get the highest enum value to be safer and to make the code more
144
+ * consistent with collectibles and trinkets.
145
+ */
123
146
  export const LAST_VANILLA_CHARACTER = getHighestEnumValue(PlayerType);
124
147
 
125
148
  // ----------
@@ -24,7 +24,6 @@ import { getNPCs, spawnNPC } from "./entitiesSpecific";
24
24
  import { getAliveNPCs } from "./npcs";
25
25
  import { isRNG } from "./rng";
26
26
  import { inBeastRoom, inDogmaRoom } from "./rooms";
27
- import { asNumber } from "./types";
28
27
  import { repeat } from "./utils";
29
28
 
30
29
  const BOSSES_THAT_REQUIRE_MULTIPLE_SPAWNS = new ReadonlySet<EntityType>([
@@ -234,7 +233,7 @@ function getNumBossSegments(
234
233
 
235
234
  // 69
236
235
  case EntityType.LOKI: {
237
- return variant === asNumber(LokiVariant.LOKII) ? 2 : 1;
236
+ return variant === LokiVariant.LOKII ? 2 : 1;
238
237
  }
239
238
 
240
239
  // 237
@@ -31,7 +31,6 @@ import { arrayToBitFlags } from "./bitwise";
31
31
  import { directionToVector } from "./direction";
32
32
  import { hasFlag } from "./flag";
33
33
  import { isTSTLSet } from "./tstlClass";
34
- import { asNumber } from "./types";
35
34
 
36
35
  export function closeAllDoors(): void {
37
36
  for (const door of getDoors()) {
@@ -373,7 +372,7 @@ export function isAngelRoomDoor(door: GridEntityDoor): boolean {
373
372
  * Room.)
374
373
  */
375
374
  export function isBlueWombDoor(door: GridEntityDoor): boolean {
376
- return door.TargetRoomIndex === asNumber(GridRoom.BLUE_WOMB);
375
+ return door.TargetRoomIndex === GridRoom.BLUE_WOMB;
377
376
  }
378
377
 
379
378
  /**
@@ -381,7 +380,7 @@ export function isBlueWombDoor(door: GridEntityDoor): boolean {
381
380
  * vanilla, the door will only appear in the Boss Room of the sixth floor.)
382
381
  */
383
382
  export function isBossRushDoor(door: GridEntityDoor): boolean {
384
- return door.TargetRoomIndex === asNumber(GridRoom.BOSS_RUSH);
383
+ return door.TargetRoomIndex === GridRoom.BOSS_RUSH;
385
384
  }
386
385
 
387
386
  export function isDevilRoomDoor(door: GridEntityDoor): boolean {
@@ -489,7 +488,7 @@ export function isHiddenSecretRoomDoor(door: GridEntityDoor): boolean {
489
488
  * (In vanilla, the door will only appear in the starting room of The Chest / Dark Room.)
490
489
  */
491
490
  export function isMegaSatanDoor(door: GridEntityDoor): boolean {
492
- return door.TargetRoomIndex === asNumber(GridRoom.MEGA_SATAN);
491
+ return door.TargetRoomIndex === GridRoom.MEGA_SATAN;
493
492
  }
494
493
 
495
494
  /**
@@ -497,7 +496,7 @@ export function isMegaSatanDoor(door: GridEntityDoor): boolean {
497
496
  * you to the Repentance floor.
498
497
  */
499
498
  export function isRepentanceDoor(door: GridEntityDoor): boolean {
500
- return door.TargetRoomIndex === asNumber(GridRoom.SECRET_EXIT);
499
+ return door.TargetRoomIndex === GridRoom.SECRET_EXIT;
501
500
  }
502
501
 
503
502
  /**
@@ -521,7 +520,7 @@ export function isSecretRoomDoor(door: GridEntityDoor): boolean {
521
520
  * contains the portal to The Void. (In vanilla, the door will only appear in the Hush Boss Room.)
522
521
  */
523
522
  export function isVoidDoor(door: GridEntityDoor): boolean {
524
- return door.TargetRoomIndex === asNumber(GridRoom.VOID);
523
+ return door.TargetRoomIndex === GridRoom.VOID;
525
524
  }
526
525
 
527
526
  /**
@@ -26,7 +26,7 @@ import { removeEntities } from "./entities";
26
26
  import { getEffects } from "./entitiesSpecific";
27
27
  import { isCircleIntersectingRectangle } from "./math";
28
28
  import { roomUpdateSafe } from "./rooms";
29
- import { asNumber, isInteger } from "./types";
29
+ import { isInteger } from "./types";
30
30
  import { assertDefined, eRange, iRange } from "./utils";
31
31
  import { isVector, vectorEquals } from "./vector";
32
32
 
@@ -1032,7 +1032,7 @@ export function removeGridEntity(
1032
1032
  // corresponding effect.
1033
1033
  if (gridEntityType === GridEntityType.STATUE) {
1034
1034
  const effectVariant =
1035
- variant === asNumber(StatueVariant.DEVIL)
1035
+ variant === StatueVariant.DEVIL
1036
1036
  ? EffectVariant.DEVIL
1037
1037
  : EffectVariant.ANGEL;
1038
1038
  const effects = getEffects(effectVariant);
@@ -14,7 +14,6 @@ import {
14
14
  removeGridEntities,
15
15
  spawnGridEntityWithVariant,
16
16
  } from "./gridEntities";
17
- import { asNumber } from "./types";
18
17
  import { assertDefined } from "./utils";
19
18
 
20
19
  /**
@@ -27,7 +26,7 @@ import { assertDefined } from "./utils";
27
26
  export function getCrawlSpaces(
28
27
  crawlSpaceVariant: CrawlSpaceVariant | -1 = -1,
29
28
  ): GridEntity[] {
30
- if (asNumber(crawlSpaceVariant) === -1) {
29
+ if (crawlSpaceVariant === -1) {
31
30
  return getGridEntities(GridEntityType.CRAWL_SPACE);
32
31
  }
33
32
 
@@ -49,7 +48,7 @@ export function getPits(pitVariant: PitVariant | -1 = -1): GridEntityPit[] {
49
48
  const pit = gridEntity.ToPit();
50
49
  if (pit !== undefined) {
51
50
  const thisPitVariant = pit.GetVariant();
52
- if (asNumber(pitVariant) === -1 || pitVariant === thisPitVariant) {
51
+ if (pitVariant === -1 || pitVariant === thisPitVariant) {
53
52
  pits.push(pit);
54
53
  }
55
54
  }
@@ -72,7 +71,7 @@ export function getPoops(
72
71
  const poop = gridEntity.ToPoop();
73
72
  if (poop !== undefined) {
74
73
  const thisPoopVariant = poop.GetVariant();
75
- if (asNumber(poopVariant) === -1 || poopVariant === thisPoopVariant) {
74
+ if (poopVariant === -1 || poopVariant === thisPoopVariant) {
76
75
  poops.push(poop);
77
76
  }
78
77
  }
@@ -96,7 +95,7 @@ export function getPressurePlates(
96
95
  if (pressurePlate !== undefined) {
97
96
  const thisPressurePlateVariant = pressurePlate.GetVariant();
98
97
  if (
99
- asNumber(pressurePlateVariant) === -1 ||
98
+ pressurePlateVariant === -1 ||
100
99
  pressurePlateVariant === thisPressurePlateVariant
101
100
  ) {
102
101
  pressurePlates.push(pressurePlate);
@@ -187,7 +186,7 @@ export function getTeleporters(variant = -1): GridEntity[] {
187
186
  export function getTrapdoors(
188
187
  trapdoorVariant: TrapdoorVariant | -1 = -1,
189
188
  ): GridEntity[] {
190
- if (asNumber(trapdoorVariant) === -1) {
189
+ if (trapdoorVariant === -1) {
191
190
  return getGridEntities(GridEntityType.TRAPDOOR);
192
191
  }
193
192