isaacscript-common 80.2.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 (62) 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/stage.lua +2 -6
  37. package/dist/functions/trinkets.lua +2 -2
  38. package/dist/functions/types.d.ts +29 -0
  39. package/dist/functions/types.d.ts.map +1 -1
  40. package/dist/index.rollup.d.ts +56 -26
  41. package/dist/isaacscript-common.lua +96 -147
  42. package/package.json +2 -2
  43. package/src/classes/callbacks/PostItemDischarge.ts +1 -2
  44. package/src/classes/features/other/CustomPickups.ts +1 -2
  45. package/src/classes/features/other/CustomStages.ts +1 -4
  46. package/src/classes/features/other/DeployJSONRoom.ts +5 -9
  47. package/src/classes/features/other/ModdedElementDetection.ts +61 -77
  48. package/src/classes/features/other/StageHistory.ts +1 -2
  49. package/src/classes/features/other/extraConsoleCommands/commands.ts +2 -6
  50. package/src/core/constantsFirstLast.ts +29 -6
  51. package/src/functions/bosses.ts +1 -2
  52. package/src/functions/doors.ts +5 -6
  53. package/src/functions/gridEntities.ts +2 -2
  54. package/src/functions/gridEntitiesSpecific.ts +5 -6
  55. package/src/functions/nextStage.ts +4 -5
  56. package/src/functions/npcs.ts +3 -4
  57. package/src/functions/pills.ts +4 -6
  58. package/src/functions/pocketItems.ts +1 -2
  59. package/src/functions/rooms.ts +15 -17
  60. package/src/functions/stage.ts +3 -3
  61. package/src/functions/trinkets.ts +2 -2
  62. package/src/functions/types.ts +30 -0
@@ -13,7 +13,6 @@ import {
13
13
  calculateStageTypeRepentance,
14
14
  onRepentanceStage,
15
15
  } from "./stage";
16
- import { asNumber } from "./types";
17
16
 
18
17
  /**
19
18
  * Helper function to get the stage that a trapdoor or heaven door would take the player to, based
@@ -35,7 +34,7 @@ export function getNextStage(): LevelStage {
35
34
 
36
35
  // First, handle the special case of being on the backwards path.
37
36
  if (backwardsPath) {
38
- const nextStage = asNumber(stage) - 1;
37
+ const nextStage = stage - 1;
39
38
  return nextStage === 0 ? LevelStage.HOME : nextStage;
40
39
  }
41
40
 
@@ -55,7 +54,7 @@ export function getNextStage(): LevelStage {
55
54
  case GridRoom.SECRET_EXIT: {
56
55
  if (repentanceStage) {
57
56
  // e.g. From Downpour 2 to Mines 1, etc.
58
- return asNumber(stage) + 1;
57
+ return stage + 1;
59
58
  }
60
59
 
61
60
  if (
@@ -114,7 +113,7 @@ export function getNextStage(): LevelStage {
114
113
  }
115
114
 
116
115
  // By default, go to the next floor.
117
- return asNumber(stage) + 1;
116
+ return stage + 1;
118
117
  }
119
118
 
120
119
  /**
@@ -146,7 +145,7 @@ export function getNextStageType(upwards = false): StageType {
146
145
  }
147
146
 
148
147
  // Second, handle the special case of being in a specific off-grid room.
149
- if (roomGridIndex === asNumber(GridRoom.SECRET_EXIT)) {
148
+ if (roomGridIndex === GridRoom.SECRET_EXIT) {
150
149
  return calculateStageTypeRepentance(nextStage);
151
150
  }
152
151
 
@@ -19,7 +19,6 @@ import {
19
19
  import { EGGY_STATE_FRAME_OF_FINAL_SPIDER } from "../core/constants";
20
20
  import { ReadonlySet } from "../types/ReadonlySet";
21
21
  import { getNPCs } from "./entitiesSpecific";
22
- import { asNumber } from "./types";
23
22
 
24
23
  /**
25
24
  * Used to filter out certain NPCs when determining of an NPC is "alive" and/or should keep the
@@ -133,7 +132,7 @@ export function isDaddyLongLegsChildStompEntity(npc: EntityNPC): boolean {
133
132
  export function isDyingDump(npc: EntityNPC): boolean {
134
133
  return (
135
134
  npc.Type === EntityType.DUMP &&
136
- npc.Variant === asNumber(DumpVariant.DUMP) &&
135
+ npc.Variant === DumpVariant.DUMP &&
137
136
  npc.State === NPCState.SPECIAL
138
137
  );
139
138
  }
@@ -146,7 +145,7 @@ export function isDyingDump(npc: EntityNPC): boolean {
146
145
  export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
147
146
  return (
148
147
  npc.Type === EntityType.HOPPER &&
149
- npc.Variant === asNumber(HopperVariant.EGGY) &&
148
+ npc.Variant === HopperVariant.EGGY &&
150
149
  npc.State === NPCState.SUICIDE &&
151
150
  npc.StateFrame >= EGGY_STATE_FRAME_OF_FINAL_SPIDER
152
151
  );
@@ -161,7 +160,7 @@ export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
161
160
  export function isRaglingDeathPatch(npc: EntityNPC): boolean {
162
161
  return (
163
162
  npc.Type === EntityType.RAGLING &&
164
- npc.Variant === asNumber(RaglingVariant.RAG_MANS_RAGLING) &&
163
+ npc.Variant === RaglingVariant.RAG_MANS_RAGLING &&
165
164
  // They go to `STATE_SPECIAL` when they are patches on the ground.
166
165
  npc.State === NPCState.SPECIAL
167
166
  );
@@ -64,7 +64,7 @@ export function getFalsePHDPillEffect(pillEffect: PillEffect): PillEffect {
64
64
  * corresponds to the horse pill color for blue/blue.
65
65
  */
66
66
  export function getHorsePillColor(pillColor: PillColor): PillColor {
67
- return asNumber(pillColor) + HORSE_PILL_ADJUSTMENT;
67
+ return pillColor + HORSE_PILL_ADJUSTMENT;
68
68
  }
69
69
 
70
70
  /** Helper function to get an array with every non-gold horse pill color. */
@@ -80,11 +80,9 @@ export function getHorsePillColors(): readonly PillColor[] {
80
80
  * If called with a non-horse pill color, this function will return back the same color.
81
81
  */
82
82
  export function getNormalPillColorFromHorse(pillColor: PillColor): PillColor {
83
- const normalPillColor = asPillColor(
84
- asNumber(pillColor) - HORSE_PILL_ADJUSTMENT,
85
- );
86
-
87
- return normalPillColor > PillColor.NULL ? normalPillColor : pillColor;
83
+ return isHorsePill(pillColor)
84
+ ? asPillColor(pillColor - HORSE_PILL_ADJUSTMENT)
85
+ : pillColor;
88
86
  }
89
87
 
90
88
  /** Helper function to get an array with every non-gold and non-horse pill color. */
@@ -10,7 +10,6 @@ import { POCKET_ITEM_SLOT_VALUES } from "../arrays/cachedEnumValues";
10
10
  import { PocketItemType } from "../enums/PocketItemType";
11
11
  import type { PocketItemDescription } from "../interfaces/PocketItemDescription";
12
12
  import { isCharacter } from "./players";
13
- import { asNumber } from "./types";
14
13
 
15
14
  /**
16
15
  * Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
@@ -129,7 +128,7 @@ export function getPocketItems(player: EntityPlayer): PocketItemDescription[] {
129
128
  });
130
129
  }
131
130
 
132
- if (asNumber(slot) + 1 === maxPocketItems) {
131
+ if (slot + 1 === maxPocketItems) {
133
132
  break;
134
133
  }
135
134
  }
@@ -48,7 +48,6 @@ import {
48
48
  import { is2x1RoomShape, isBigRoomShape, isLRoomShape } from "./roomShape";
49
49
  import { reloadRoom } from "./roomTransition";
50
50
  import { getGotoCommand } from "./stage";
51
- import { asNumber } from "./types";
52
51
  import { assertDefined, iRange } from "./utils";
53
52
 
54
53
  const SECRET_ROOM_TYPES = new ReadonlySet([
@@ -599,7 +598,7 @@ export function isAllRoomsClear(
599
598
  export function isAngelShop(roomData: RoomConfig): boolean {
600
599
  return (
601
600
  roomData.Type === RoomType.ANGEL &&
602
- roomData.Subtype === asNumber(AngelRoomSubType.SHOP)
601
+ roomData.Subtype === AngelRoomSubType.SHOP
603
602
  );
604
603
  }
605
604
 
@@ -614,7 +613,7 @@ export function isAngelShop(roomData: RoomConfig): boolean {
614
613
  export function isBeastRoom(roomData: RoomConfig): boolean {
615
614
  return (
616
615
  roomData.Type === RoomType.DUNGEON &&
617
- roomData.Subtype === asNumber(DungeonSubType.BEAST_ROOM)
616
+ roomData.Subtype === DungeonSubType.BEAST_ROOM
618
617
  );
619
618
  }
620
619
 
@@ -634,7 +633,7 @@ export function isBossRoomOf(roomData: RoomConfig, bossID: BossID): boolean {
634
633
  return (
635
634
  roomData.Type === RoomType.BOSS &&
636
635
  roomData.StageID === StageID.SPECIAL_ROOMS &&
637
- roomData.Subtype === asNumber(bossID)
636
+ roomData.Subtype === bossID
638
637
  );
639
638
  }
640
639
 
@@ -646,7 +645,7 @@ export function isBossRoomOf(roomData: RoomConfig, bossID: BossID): boolean {
646
645
  export function isCrawlSpace(roomData: RoomConfig): boolean {
647
646
  return (
648
647
  roomData.Type === RoomType.DUNGEON &&
649
- roomData.Subtype === asNumber(DungeonSubType.NORMAL)
648
+ roomData.Subtype === DungeonSubType.NORMAL
650
649
  );
651
650
  }
652
651
 
@@ -668,9 +667,8 @@ export function isCrawlSpaceWithBlackMarketEntrance(
668
667
  export function isDeathCertificateArea(roomData: RoomConfig): boolean {
669
668
  return (
670
669
  roomData.StageID === StageID.HOME &&
671
- (roomData.Subtype ===
672
- asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ENTRANCE) ||
673
- roomData.Subtype === asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ITEMS))
670
+ (roomData.Subtype === HomeRoomSubType.DEATH_CERTIFICATE_ENTRANCE ||
671
+ roomData.Subtype === HomeRoomSubType.DEATH_CERTIFICATE_ITEMS)
674
672
  );
675
673
  }
676
674
 
@@ -704,7 +702,7 @@ export function isDogmaRoom(roomData: RoomConfig): boolean {
704
702
  roomData.StageID === StageID.HOME &&
705
703
  roomData.Type === RoomType.DEFAULT &&
706
704
  roomData.Variant === 1000 &&
707
- roomData.Subtype === asNumber(HomeRoomSubType.LIVING_ROOM)
705
+ roomData.Subtype === HomeRoomSubType.LIVING_ROOM
708
706
  );
709
707
  }
710
708
 
@@ -729,7 +727,7 @@ export function isDoubleTrouble(roomData: RoomConfig): boolean {
729
727
  * Helper function to determine if the index of the provided room is equal to `GridRoom.GENESIS`.
730
728
  */
731
729
  export function isGenesisRoom(roomGridIndex: int): boolean {
732
- return roomGridIndex === asNumber(GridRoom.GENESIS);
730
+ return roomGridIndex === GridRoom.GENESIS;
733
731
  }
734
732
 
735
733
  /**
@@ -741,8 +739,8 @@ export function isGenesisRoom(roomGridIndex: int): boolean {
741
739
  export function isHomeCloset(roomData: RoomConfig): boolean {
742
740
  return (
743
741
  roomData.StageID === StageID.HOME &&
744
- (roomData.Subtype === asNumber(HomeRoomSubType.CLOSET_LEFT) ||
745
- roomData.Subtype === asNumber(HomeRoomSubType.CLOSET_RIGHT))
742
+ (roomData.Subtype === HomeRoomSubType.CLOSET_LEFT ||
743
+ roomData.Subtype === HomeRoomSubType.CLOSET_RIGHT)
746
744
  );
747
745
  }
748
746
 
@@ -755,7 +753,7 @@ export function isLRoom(roomData: RoomConfig): boolean {
755
753
  * Helper function to determine if the index of the provided room is equal to `GridRoom.MEGA_SATAN`.
756
754
  */
757
755
  export function isMegaSatanRoom(roomGridIndex: int): boolean {
758
- return roomGridIndex === asNumber(GridRoom.MEGA_SATAN);
756
+ return roomGridIndex === GridRoom.MEGA_SATAN;
759
757
  }
760
758
 
761
759
  /**
@@ -782,7 +780,7 @@ export function isMinibossRoomOf(
782
780
  return (
783
781
  roomData.Type === RoomType.MINI_BOSS &&
784
782
  roomData.StageID === StageID.SPECIAL_ROOMS &&
785
- roomData.Subtype === asNumber(minibossID)
783
+ roomData.Subtype === minibossID
786
784
  );
787
785
  }
788
786
 
@@ -795,7 +793,7 @@ export function isMirrorRoom(roomData: RoomConfig): boolean {
795
793
  roomData.Type === RoomType.DEFAULT &&
796
794
  (roomData.StageID === StageID.DOWNPOUR ||
797
795
  roomData.StageID === StageID.DROSS) &&
798
- roomData.Subtype === asNumber(DownpourRoomSubType.MIRROR)
796
+ roomData.Subtype === DownpourRoomSubType.MIRROR
799
797
  );
800
798
  }
801
799
 
@@ -828,7 +826,7 @@ export function isRoomType(
828
826
  * floor.
829
827
  */
830
828
  export function isSecretExit(roomGridIndex: int): boolean {
831
- return roomGridIndex === asNumber(GridRoom.SECRET_EXIT);
829
+ return roomGridIndex === GridRoom.SECRET_EXIT;
832
830
  }
833
831
 
834
832
  /**
@@ -848,7 +846,7 @@ export function isSecretRoomType(roomType: RoomType): boolean {
848
846
  * the only way to detect them is by using the grid index.
849
847
  */
850
848
  export function isSecretShop(roomGridIndex: int): boolean {
851
- return roomGridIndex === asNumber(GridRoom.SECRET_SHOP);
849
+ return roomGridIndex === GridRoom.SECRET_SHOP;
852
850
  }
853
851
 
854
852
  /**
@@ -11,7 +11,7 @@ import { ROOM_TYPE_SPECIAL_GOTO_PREFIXES } from "../objects/roomTypeSpecialGotoP
11
11
  import { STAGE_TO_STAGE_ID } from "../objects/stageToStageID";
12
12
  import { STAGE_TYPE_SUFFIXES } from "../objects/stageTypeSuffixes";
13
13
  import { log } from "./log";
14
- import { asLevelStage, asNumber } from "./types";
14
+ import { asLevelStage } from "./types";
15
15
  import { inRange } from "./utils";
16
16
 
17
17
  /**
@@ -62,7 +62,7 @@ export function calculateStageTypeRepentance(stage: LevelStage): StageType {
62
62
  // This algorithm is from Kilburn. We add one because the alt path is offset by 1 relative to the
63
63
  // normal path.
64
64
  const seeds = game.GetSeeds();
65
- const adjustedStage = asLevelStage(asNumber(stage) + 1);
65
+ const adjustedStage = asLevelStage(stage + 1);
66
66
  const stageSeed = seeds.GetStageSeed(adjustedStage);
67
67
 
68
68
  // Kilburn does not know why he divided the stage seed by 2 first.
@@ -84,7 +84,7 @@ export function getEffectiveStage(): LevelStage {
84
84
  const stage = level.GetStage();
85
85
 
86
86
  if (onRepentanceStage()) {
87
- return asNumber(stage) + 1;
87
+ return stage + 1;
88
88
  }
89
89
 
90
90
  return stage;
@@ -42,7 +42,7 @@ const TRINKET_SPRITE_LAYER = 0;
42
42
  export function getGoldenTrinketType(trinketType: TrinketType): TrinketType {
43
43
  return isGoldenTrinketType(trinketType)
44
44
  ? trinketType
45
- : asNumber(trinketType) + GOLDEN_TRINKET_ADJUSTMENT;
45
+ : trinketType + GOLDEN_TRINKET_ADJUSTMENT;
46
46
  }
47
47
 
48
48
  /**
@@ -88,7 +88,7 @@ export function getMysteriousPaperEffectForFrame(
88
88
  */
89
89
  export function getNormalTrinketType(trinketType: TrinketType): TrinketType {
90
90
  return isGoldenTrinketType(trinketType)
91
- ? asNumber(trinketType) - GOLDEN_TRINKET_ADJUSTMENT
91
+ ? trinketType - GOLDEN_TRINKET_ADJUSTMENT
92
92
  : trinketType;
93
93
  }
94
94
 
@@ -1,3 +1,33 @@
1
+ /**
2
+ * Consider the following code that uses a number enum:
3
+ *
4
+ * ```ts
5
+ * enum MyEnum {
6
+ * Value1,
7
+ * }
8
+ *
9
+ * function asMyEnum(num: number): MyEnum {}
10
+ *
11
+ * declare const something: unknown;
12
+ *
13
+ * const foo = something as MyEnum; // no error
14
+ * const bar: MyEnum = something; // error
15
+ * const baz = asMyEnum(something); // error
16
+ * ```
17
+ *
18
+ * Here, using `as` does not give an error because TypeScript allows you to assert a type to a
19
+ * supertype or a subtype. Thus, using `as` to perform a type assertion is not as safe as using a
20
+ * variable declaration or a helper function. However, if we use a variable declaration, then the
21
+ * `isaacscript/strict-enums` rule is triggered, which requires suppressing the lint rule with a `//
22
+ * eslint-disable-next-line`. Thus, the safest and more concise way to do a type assertion is to use
23
+ * a helper function.
24
+ *
25
+ * This file contains helper functions for various number enums that might require type assertions.
26
+ * It also contains helper functions for run-time type checks.
27
+ *
28
+ * @module
29
+ */
30
+
1
31
  import type {
2
32
  CardType,
3
33
  CollectibleType,