isaacscript-common 7.1.0 → 7.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 (255) hide show
  1. package/dist/callbacks/itemPickup.d.ts.map +1 -1
  2. package/dist/callbacks/itemPickup.lua +3 -1
  3. package/dist/callbacks/postCustomDoorEnter.d.ts.map +1 -1
  4. package/dist/callbacks/postCustomDoorEnter.lua +14 -11
  5. package/dist/callbacks/postDiceRoomActivated.d.ts.map +1 -1
  6. package/dist/callbacks/postDiceRoomActivated.lua +5 -4
  7. package/dist/callbacks/postItemDischarged.lua +2 -1
  8. package/dist/callbacks/postPlayerChangeStat.d.ts.map +1 -1
  9. package/dist/callbacks/postPlayerChangeStat.lua +44 -15
  10. package/dist/callbacks/postSlotDestroyed.lua +3 -3
  11. package/dist/classes/DefaultMap.d.ts +5 -5
  12. package/dist/classes/DefaultMap.d.ts.map +1 -1
  13. package/dist/core/constants.d.ts +2 -2
  14. package/dist/core/constants.d.ts.map +1 -1
  15. package/dist/core/constants.lua +3 -1
  16. package/dist/core/constantsFirstLast.d.ts +2 -0
  17. package/dist/core/constantsFirstLast.d.ts.map +1 -1
  18. package/dist/core/constantsFirstLast.lua +36 -9
  19. package/dist/enums/AmbushType.d.ts +1 -0
  20. package/dist/enums/AmbushType.d.ts.map +1 -1
  21. package/dist/enums/AmbushType.lua +1 -0
  22. package/dist/enums/CornerType.d.ts +1 -0
  23. package/dist/enums/CornerType.d.ts.map +1 -1
  24. package/dist/enums/CornerType.lua +1 -0
  25. package/dist/enums/PocketItemType.d.ts +1 -0
  26. package/dist/enums/PocketItemType.d.ts.map +1 -1
  27. package/dist/enums/PocketItemType.lua +1 -0
  28. package/dist/enums/RockAltType.d.ts +1 -0
  29. package/dist/enums/RockAltType.d.ts.map +1 -1
  30. package/dist/enums/RockAltType.lua +1 -0
  31. package/dist/enums/SaveDataKey.d.ts +11 -0
  32. package/dist/enums/SaveDataKey.d.ts.map +1 -0
  33. package/dist/enums/{private/SaveDataKey.lua → SaveDataKey.lua} +2 -0
  34. package/dist/enums/SerializationType.d.ts +1 -0
  35. package/dist/enums/SerializationType.d.ts.map +1 -1
  36. package/dist/enums/SerializationType.lua +1 -0
  37. package/dist/enums/SlotDestructionType.d.ts +1 -0
  38. package/dist/enums/SlotDestructionType.d.ts.map +1 -1
  39. package/dist/enums/SlotDestructionType.lua +1 -0
  40. package/dist/enums/StatType.d.ts +1 -3
  41. package/dist/enums/StatType.d.ts.map +1 -1
  42. package/dist/enums/StatType.lua +0 -2
  43. package/dist/enums/index.d.ts +1 -0
  44. package/dist/enums/index.d.ts.map +1 -1
  45. package/dist/enums/index.lua +8 -0
  46. package/dist/features/customGridEntity.d.ts.map +1 -1
  47. package/dist/features/customGridEntity.lua +3 -1
  48. package/dist/features/customStage/backdrop.d.ts +1 -1
  49. package/dist/features/customStage/backdrop.d.ts.map +1 -1
  50. package/dist/features/customStage/backdrop.lua +5 -3
  51. package/dist/features/customStage/customStageGridEntities.d.ts.map +1 -1
  52. package/dist/features/customStage/customStageGridEntities.lua +3 -1
  53. package/dist/features/customStage/exports.d.ts.map +1 -1
  54. package/dist/features/customStage/exports.lua +3 -1
  55. package/dist/features/customStage/init.lua +2 -2
  56. package/dist/features/customStage/shadows.d.ts.map +1 -1
  57. package/dist/features/customStage/shadows.lua +2 -1
  58. package/dist/features/deployJSONRoom.lua +13 -10
  59. package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
  60. package/dist/features/extraConsoleCommands/listCommands.lua +8 -2
  61. package/dist/features/saveDataManager/exports.d.ts +2 -1
  62. package/dist/features/saveDataManager/exports.d.ts.map +1 -1
  63. package/dist/features/saveDataManager/main.d.ts +1 -1
  64. package/dist/features/saveDataManager/main.d.ts.map +1 -1
  65. package/dist/features/saveDataManager/main.lua +1 -1
  66. package/dist/functions/bitSet128.d.ts.map +1 -1
  67. package/dist/functions/bosses.d.ts.map +1 -1
  68. package/dist/functions/bosses.lua +3 -1
  69. package/dist/functions/cacheFlag.d.ts +23 -1
  70. package/dist/functions/cacheFlag.d.ts.map +1 -1
  71. package/dist/functions/cacheFlag.lua +78 -0
  72. package/dist/functions/collectibles.d.ts.map +1 -1
  73. package/dist/functions/deepCopy.lua +2 -1
  74. package/dist/functions/doors.d.ts.map +1 -1
  75. package/dist/functions/doors.lua +3 -1
  76. package/dist/functions/entities.lua +2 -1
  77. package/dist/functions/flying.lua +2 -2
  78. package/dist/functions/gridEntities.lua +2 -1
  79. package/dist/functions/gridEntitiesSpecific.d.ts.map +1 -1
  80. package/dist/functions/gridEntitiesSpecific.lua +5 -3
  81. package/dist/functions/index.d.ts +0 -1
  82. package/dist/functions/index.d.ts.map +1 -1
  83. package/dist/functions/index.lua +0 -8
  84. package/dist/functions/input.d.ts +5 -2
  85. package/dist/functions/input.d.ts.map +1 -1
  86. package/dist/functions/input.lua +11 -3
  87. package/dist/functions/kColor.d.ts.map +1 -1
  88. package/dist/functions/levelGrid.d.ts.map +1 -1
  89. package/dist/functions/levelGrid.lua +3 -1
  90. package/dist/functions/nextStage.d.ts.map +1 -1
  91. package/dist/functions/nextStage.lua +7 -5
  92. package/dist/functions/npcs.d.ts.map +1 -1
  93. package/dist/functions/npcs.lua +4 -2
  94. package/dist/functions/pills.d.ts.map +1 -1
  95. package/dist/functions/pills.lua +9 -3
  96. package/dist/functions/playerIndex.d.ts.map +1 -1
  97. package/dist/functions/playerIndex.lua +2 -1
  98. package/dist/functions/playerStats.d.ts.map +1 -1
  99. package/dist/functions/playerStats.lua +1 -2
  100. package/dist/functions/players.d.ts +1 -1
  101. package/dist/functions/players.d.ts.map +1 -1
  102. package/dist/functions/players.lua +13 -15
  103. package/dist/functions/pocketItems.d.ts.map +1 -1
  104. package/dist/functions/pocketItems.lua +3 -1
  105. package/dist/functions/rng.d.ts.map +1 -1
  106. package/dist/functions/rng.lua +3 -0
  107. package/dist/functions/rockAlt.d.ts.map +1 -1
  108. package/dist/functions/rockAlt.lua +11 -20
  109. package/dist/functions/rooms.d.ts +4 -4
  110. package/dist/functions/rooms.d.ts.map +1 -1
  111. package/dist/functions/rooms.lua +18 -16
  112. package/dist/functions/spawnCollectible.d.ts.map +1 -1
  113. package/dist/functions/stage.d.ts.map +1 -1
  114. package/dist/functions/stage.lua +8 -2
  115. package/dist/functions/trinkets.d.ts.map +1 -1
  116. package/dist/functions/trinkets.lua +4 -2
  117. package/dist/functions/types.d.ts +64 -0
  118. package/dist/functions/types.d.ts.map +1 -1
  119. package/dist/functions/types.lua +63 -0
  120. package/dist/functions/vector.d.ts.map +1 -1
  121. package/dist/interfaces/ChargeBarSprites.d.ts +1 -1
  122. package/dist/interfaces/Corner.d.ts +5 -0
  123. package/dist/interfaces/Corner.d.ts.map +1 -1
  124. package/dist/interfaces/CustomStageLua.d.ts +57 -0
  125. package/dist/interfaces/CustomStageLua.d.ts.map +1 -1
  126. package/dist/interfaces/GridEntityCustomData.d.ts +6 -0
  127. package/dist/interfaces/GridEntityCustomData.d.ts.map +1 -1
  128. package/dist/interfaces/JSONRoomsFile.d.ts +7 -3
  129. package/dist/interfaces/JSONRoomsFile.d.ts.map +1 -1
  130. package/dist/interfaces/PlayerHealth.d.ts +1 -1
  131. package/dist/interfaces/PlayerHealth.d.ts.map +1 -1
  132. package/dist/interfaces/PocketItemDescription.d.ts +1 -1
  133. package/dist/interfaces/PocketItemDescription.d.ts.map +1 -1
  134. package/dist/interfaces/RoomDescription.d.ts +1 -1
  135. package/dist/interfaces/RoomDescription.d.ts.map +1 -1
  136. package/dist/interfaces/StatTypeType.d.ts +4 -1
  137. package/dist/interfaces/StatTypeType.d.ts.map +1 -1
  138. package/dist/interfaces/TrinketSituation.d.ts +1 -1
  139. package/dist/interfaces/TrinketSituation.d.ts.map +1 -1
  140. package/dist/maps/keyboardToString.d.ts +4 -0
  141. package/dist/maps/keyboardToString.d.ts.map +1 -0
  142. package/dist/maps/keyboardToString.lua +73 -0
  143. package/dist/types/AnyEntity.d.ts +5 -0
  144. package/dist/types/AnyEntity.d.ts.map +1 -1
  145. package/dist/types/AnyGridEntity.d.ts +5 -0
  146. package/dist/types/AnyGridEntity.d.ts.map +1 -1
  147. package/dist/types/CollectibleIndex.d.ts +4 -3
  148. package/dist/types/CollectibleIndex.d.ts.map +1 -1
  149. package/dist/types/Immutable.d.ts +3 -1
  150. package/dist/types/Immutable.d.ts.map +1 -1
  151. package/dist/types/PickupIndex.d.ts +4 -2
  152. package/dist/types/PickupIndex.d.ts.map +1 -1
  153. package/dist/types/PlayerIndex.d.ts +3 -2
  154. package/dist/types/PlayerIndex.d.ts.map +1 -1
  155. package/dist/types/SerializedIsaacAPIClass.d.ts +6 -0
  156. package/dist/types/SerializedIsaacAPIClass.d.ts.map +1 -1
  157. package/dist/types/TSTLClass.d.ts +5 -0
  158. package/dist/types/TSTLClass.d.ts.map +1 -1
  159. package/dist/types/TrapdoorDestination.d.ts +3 -0
  160. package/dist/types/TrapdoorDestination.d.ts.map +1 -1
  161. package/package.json +2 -2
  162. package/src/callbacks/itemPickup.ts +5 -2
  163. package/src/callbacks/postCustomDoorEnter.ts +18 -11
  164. package/src/callbacks/postDiceRoomActivated.ts +7 -12
  165. package/src/callbacks/postItemDischarged.ts +3 -1
  166. package/src/callbacks/postPlayerChangeStat.ts +45 -3
  167. package/src/callbacks/postSlotDestroyed.ts +3 -2
  168. package/src/callbacks/reorderedCallbacks.ts +2 -2
  169. package/src/classes/DefaultMap.ts +8 -8
  170. package/src/core/constants.ts +3 -3
  171. package/src/core/constantsFirstLast.ts +29 -14
  172. package/src/enums/AmbushType.ts +1 -0
  173. package/src/enums/CornerType.ts +1 -0
  174. package/src/enums/PocketItemType.ts +1 -0
  175. package/src/enums/RockAltType.ts +1 -0
  176. package/src/enums/SaveDataKey.ts +10 -0
  177. package/src/enums/SerializationType.ts +1 -0
  178. package/src/enums/SlotDestructionType.ts +1 -0
  179. package/src/enums/StatType.ts +7 -7
  180. package/src/enums/index.ts +1 -0
  181. package/src/enums/indexTypeDoc.ts +1 -0
  182. package/src/features/customGridEntity.ts +2 -1
  183. package/src/features/customStage/backdrop.ts +5 -3
  184. package/src/features/customStage/customStageGridEntities.ts +2 -1
  185. package/src/features/customStage/exports.ts +5 -4
  186. package/src/features/customStage/init.ts +2 -2
  187. package/src/features/customStage/shadows.ts +2 -1
  188. package/src/features/deployJSONRoom.ts +14 -19
  189. package/src/features/extraConsoleCommands/listCommands.ts +3 -2
  190. package/src/features/fastReset.ts +1 -1
  191. package/src/features/indexTypeDoc.ts +2 -1
  192. package/src/features/saveDataManager/exports.ts +4 -4
  193. package/src/features/saveDataManager/main.ts +1 -1
  194. package/src/features/saveDataManager/save.ts +1 -1
  195. package/src/functions/bitSet128.ts +1 -5
  196. package/src/functions/bosses.ts +2 -1
  197. package/src/functions/cacheFlag.ts +90 -1
  198. package/src/functions/cards.ts +3 -3
  199. package/src/functions/collectibles.ts +2 -8
  200. package/src/functions/color.ts +1 -1
  201. package/src/functions/deepCopy.ts +2 -2
  202. package/src/functions/dimensions.ts +1 -1
  203. package/src/functions/doors.ts +2 -2
  204. package/src/functions/entities.ts +2 -2
  205. package/src/functions/flying.ts +1 -1
  206. package/src/functions/gridEntities.ts +2 -2
  207. package/src/functions/gridEntitiesSpecific.ts +4 -3
  208. package/src/functions/index.ts +0 -1
  209. package/src/functions/indexTypeDoc.ts +0 -1
  210. package/src/functions/input.ts +17 -4
  211. package/src/functions/jsonHelpers.ts +1 -1
  212. package/src/functions/kColor.ts +1 -5
  213. package/src/functions/levelGrid.ts +3 -2
  214. package/src/functions/nextStage.ts +6 -5
  215. package/src/functions/npcs.ts +3 -2
  216. package/src/functions/pills.ts +11 -9
  217. package/src/functions/playerIndex.ts +3 -1
  218. package/src/functions/playerStats.ts +0 -1
  219. package/src/functions/players.ts +5 -6
  220. package/src/functions/pocketItems.ts +4 -4
  221. package/src/functions/rng.ts +8 -5
  222. package/src/functions/rockAlt.ts +28 -13
  223. package/src/functions/rooms.ts +27 -26
  224. package/src/functions/spawnCollectible.ts +1 -2
  225. package/src/functions/stage.ts +3 -2
  226. package/src/functions/trinkets.ts +6 -5
  227. package/src/functions/types.ts +100 -0
  228. package/src/functions/vector.ts +1 -5
  229. package/src/interfaces/ChargeBarSprites.ts +1 -1
  230. package/src/interfaces/Corner.ts +5 -0
  231. package/src/interfaces/CustomStageLua.ts +66 -0
  232. package/src/interfaces/GridEntityCustomData.ts +6 -0
  233. package/src/interfaces/JSONRoomsFile.ts +7 -3
  234. package/src/interfaces/PlayerHealth.ts +1 -1
  235. package/src/interfaces/PocketItemDescription.ts +1 -1
  236. package/src/interfaces/RoomDescription.ts +1 -1
  237. package/src/interfaces/StatTypeType.ts +4 -1
  238. package/src/interfaces/TrinketSituation.ts +1 -1
  239. package/src/maps/keyboardToString.ts +77 -0
  240. package/src/types/AnyEntity.ts +5 -0
  241. package/src/types/AnyGridEntity.ts +5 -0
  242. package/src/types/CollectibleIndex.ts +4 -3
  243. package/src/types/Immutable.ts +3 -1
  244. package/src/types/PickupIndex.ts +4 -2
  245. package/src/types/PlayerIndex.ts +3 -2
  246. package/src/types/SerializedIsaacAPIClass.ts +6 -0
  247. package/src/types/TSTLClass.ts +5 -0
  248. package/src/types/TrapdoorDestination.ts +3 -0
  249. package/dist/enums/private/SaveDataKey.d.ts +0 -7
  250. package/dist/enums/private/SaveDataKey.d.ts.map +0 -1
  251. package/dist/functions/collectibleCacheFlag.d.ts +0 -24
  252. package/dist/functions/collectibleCacheFlag.d.ts.map +0 -1
  253. package/dist/functions/collectibleCacheFlag.lua +0 -80
  254. package/src/enums/private/SaveDataKey.ts +0 -6
  255. package/src/functions/collectibleCacheFlag.ts +0 -90
@@ -1,5 +1,62 @@
1
- import { CacheFlag } from "isaac-typescript-definitions";
1
+ import { CacheFlag, CollectibleType } from "isaac-typescript-definitions";
2
+ import { itemConfig } from "../core/cachedClasses";
2
3
  import { DEFAULT_PLAYER_STAT_MAP } from "../maps/defaultPlayerStatMap";
4
+ import { getCollectibleArray } from "./collectibleSet";
5
+ import { getEnumValues } from "./enums";
6
+ import { hasFlag } from "./flag";
7
+ import { copySet, getSortedSetValues } from "./set";
8
+ import { repeat } from "./utils";
9
+
10
+ const CACHE_FLAG_TO_COLLECTIBLES_MAP = new Map<
11
+ CacheFlag,
12
+ Set<CollectibleType>
13
+ >();
14
+
15
+ function initCacheFlagMap() {
16
+ for (const cacheFlag of getEnumValues(CacheFlag)) {
17
+ const collectiblesSet = new Set<CollectibleType>();
18
+
19
+ for (const collectibleType of getCollectibleArray()) {
20
+ if (collectibleHasCacheFlag(collectibleType, cacheFlag)) {
21
+ collectiblesSet.add(collectibleType);
22
+ }
23
+ }
24
+
25
+ CACHE_FLAG_TO_COLLECTIBLES_MAP.set(cacheFlag, collectiblesSet);
26
+ }
27
+ }
28
+
29
+ export function collectibleHasCacheFlag(
30
+ collectibleType: CollectibleType,
31
+ cacheFlag: CacheFlag,
32
+ ): boolean {
33
+ const itemConfigItem = itemConfig.GetCollectible(collectibleType);
34
+ if (itemConfigItem === undefined) {
35
+ return false;
36
+ }
37
+
38
+ return hasFlag(itemConfigItem.CacheFlags, cacheFlag);
39
+ }
40
+
41
+ /**
42
+ * Returns a set containing every collectible type with the given cache flag, including modded
43
+ * collectibles.
44
+ */
45
+ export function getCollectiblesForCacheFlag(
46
+ cacheFlag: CacheFlag,
47
+ ): Set<CollectibleType> {
48
+ // Lazy initialize the map.
49
+ if (CACHE_FLAG_TO_COLLECTIBLES_MAP.size === 0) {
50
+ initCacheFlagMap();
51
+ }
52
+
53
+ const collectiblesSet = CACHE_FLAG_TO_COLLECTIBLES_MAP.get(cacheFlag);
54
+ if (collectiblesSet === undefined) {
55
+ return new Set();
56
+ }
57
+
58
+ return copySet(collectiblesSet);
59
+ }
3
60
 
4
61
  /**
5
62
  * Returns the starting stat that Isaac (the default character) starts with. For example, if you
@@ -10,3 +67,35 @@ import { DEFAULT_PLAYER_STAT_MAP } from "../maps/defaultPlayerStatMap";
10
67
  export function getDefaultPlayerStat(cacheFlag: CacheFlag): number | undefined {
11
68
  return DEFAULT_PLAYER_STAT_MAP.get(cacheFlag);
12
69
  }
70
+
71
+ /**
72
+ * Returns an array containing every collectible type that the player has that matches the provided
73
+ * CacheFlag.
74
+ *
75
+ * For example, if the cache flag is `CacheFlag.FLYING`, and the player has one Lord of the Pit and
76
+ * two Dead Doves, then this function would return:
77
+ *
78
+ * ```ts
79
+ * [
80
+ * CollectibleType.LORD_OF_THE_PIT,
81
+ * CollectibleType.DEAD_DOVE,
82
+ * CollectibleType.DEAD_DOVE,
83
+ * ]
84
+ * ```
85
+ */
86
+ export function getPlayerCollectiblesForCacheFlag(
87
+ player: EntityPlayer,
88
+ cacheFlag: CacheFlag,
89
+ ): CollectibleType[] {
90
+ const collectiblesForCacheFlag = getCollectiblesForCacheFlag(cacheFlag);
91
+
92
+ const playerCollectibles: CollectibleType[] = [];
93
+ for (const collectibleType of getSortedSetValues(collectiblesForCacheFlag)) {
94
+ const numCollectibles = player.GetCollectibleNum(collectibleType);
95
+ repeat(numCollectibles, () => {
96
+ playerCollectibles.push(collectibleType);
97
+ });
98
+ }
99
+
100
+ return playerCollectibles;
101
+ }
@@ -59,7 +59,7 @@ function initCardObjects() {
59
59
 
60
60
  /** Helper function to get an array with every valid card sub-type. This includes modded cards. */
61
61
  export function getAllCards(): Card[] {
62
- return irange(FIRST_CARD, LAST_CARD) as Card[];
62
+ return irange(FIRST_CARD, LAST_CARD);
63
63
  }
64
64
 
65
65
  /**
@@ -159,7 +159,7 @@ export function getModdedCards(): Card[] {
159
159
  return [];
160
160
  }
161
161
 
162
- return irange(FIRST_MODDED_CARD, LAST_CARD) as Card[];
162
+ return irange(FIRST_MODDED_CARD, LAST_CARD);
163
163
  }
164
164
 
165
165
  /**
@@ -216,7 +216,7 @@ export function getRandomRune(
216
216
 
217
217
  /** Helper function to get an array with every valid vanilla card sub-type. */
218
218
  export function getVanillaCards(): Card[] {
219
- return irange(FIRST_CARD, MAX_VANILLA_CARD) as Card[];
219
+ return irange(FIRST_CARD, MAX_VANILLA_CARD);
220
220
  }
221
221
 
222
222
  /**
@@ -389,10 +389,7 @@ export function getModdedCollectibleTypes(): CollectibleType[] {
389
389
  return [];
390
390
  }
391
391
 
392
- return irange(
393
- FIRST_MODDED_COLLECTIBLE_TYPE,
394
- LAST_COLLECTIBLE_TYPE,
395
- ) as CollectibleType[];
392
+ return irange(FIRST_MODDED_COLLECTIBLE_TYPE, LAST_COLLECTIBLE_TYPE);
396
393
  }
397
394
 
398
395
  /**
@@ -404,10 +401,7 @@ export function getModdedCollectibleTypes(): CollectibleType[] {
404
401
  * should use the `getVanillaCollectibleSet` helper function instead.
405
402
  */
406
403
  export function getVanillaCollectibleTypeRange(): CollectibleType[] {
407
- return irange(
408
- FIRST_COLLECTIBLE_TYPE,
409
- LAST_VANILLA_COLLECTIBLE_TYPE,
410
- ) as CollectibleType[];
404
+ return irange(FIRST_COLLECTIBLE_TYPE, LAST_VANILLA_COLLECTIBLE_TYPE);
411
405
  }
412
406
 
413
407
  /** Returns true if the item type in the item config is equal to `ItemType.ITEM_ACTIVE`. */
@@ -47,7 +47,7 @@ export function deserializeColor(color: SerializedColor): Color {
47
47
  }
48
48
 
49
49
  const [r, g, b, a, ro, go, bo] = getNumbersFromTable(
50
- color as LuaMap<string, unknown>,
50
+ color,
51
51
  OBJECT_NAME,
52
52
  ...KEYS,
53
53
  );
@@ -23,7 +23,7 @@ import {
23
23
  isUserDefinedTSTLClass,
24
24
  newTSTLClass,
25
25
  } from "./tstlClass";
26
- import { isNumber, isPrimitive } from "./types";
26
+ import { asString, isNumber, isPrimitive } from "./types";
27
27
  import { getTraversalDescription, twoDimensionalSort } from "./utils";
28
28
 
29
29
  const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
@@ -575,7 +575,7 @@ function getCopiedEntries(
575
575
  const convertStringKeysToNumbers =
576
576
  serializationType === SerializationType.DESERIALIZE &&
577
577
  entries.some(
578
- ([key]) => key === (SerializationBrand.OBJECT_WITH_NUMBER_KEYS as string),
578
+ ([key]) => key === asString(SerializationBrand.OBJECT_WITH_NUMBER_KEYS),
579
579
  );
580
580
 
581
581
  const hasNumberKeys = entries.some(([key]) => isNumber(key));
@@ -8,7 +8,7 @@ import { erange } from "./utils";
8
8
  * Helper function to get an array with every valid `Dimension` (not including `Dimension.CURRENT`).
9
9
  */
10
10
  export function getAllDimensions(): Dimension[] {
11
- return erange(NUM_DIMENSIONS) as Dimension[];
11
+ return erange(NUM_DIMENSIONS);
12
12
  }
13
13
 
14
14
  /**
@@ -22,6 +22,7 @@ import { arrayToBitFlags } from "./bitwise";
22
22
  import { directionToVector } from "./direction";
23
23
  import { getEnumValues } from "./enums";
24
24
  import { isTSTLSet } from "./tstlClass";
25
+ import { asNumber } from "./types";
25
26
 
26
27
  /**
27
28
  * When players enter a room, they do not appear exactly on the location of the door, because then
@@ -341,8 +342,7 @@ export function isHiddenSecretRoomDoor(door: GridEntityDoor): boolean {
341
342
  * you to the Repentance floor.
342
343
  */
343
344
  export function isRepentanceDoor(door: GridEntityDoor): boolean {
344
- // eslint-disable-next-line isaacscript/strict-enums
345
- return door.TargetRoomIndex === GridRoom.SECRET_EXIT;
345
+ return door.TargetRoomIndex === asNumber(GridRoom.SECRET_EXIT);
346
346
  }
347
347
 
348
348
  /**
@@ -6,7 +6,7 @@ import { AnyEntity } from "../types/AnyEntity";
6
6
  import { getIsaacAPIClassName } from "./isaacAPIClass";
7
7
  import { getRandom } from "./random";
8
8
  import { isRNG, newRNG } from "./rng";
9
- import { isPrimitive } from "./types";
9
+ import { asNumber, isPrimitive } from "./types";
10
10
  import { isVector, vectorToString } from "./vector";
11
11
 
12
12
  /**
@@ -122,7 +122,7 @@ export function getEntities(
122
122
  subType = -1,
123
123
  ignoreFriendly = false,
124
124
  ): Entity[] {
125
- if ((entityType as int) === -1) {
125
+ if (asNumber(entityType) === -1) {
126
126
  return Isaac.GetRoomEntities();
127
127
  }
128
128
 
@@ -5,7 +5,7 @@ import {
5
5
  PlayerType,
6
6
  TrinketType,
7
7
  } from "isaac-typescript-definitions";
8
- import { getCollectiblesForCacheFlag } from "./collectibleCacheFlag";
8
+ import { getCollectiblesForCacheFlag } from "./cacheFlag";
9
9
  import { copySet, deleteSetsFromSet } from "./set";
10
10
 
11
11
  const FLYING_CHARACTERS: ReadonlySet<PlayerType> = new Set([
@@ -19,7 +19,7 @@ import { AnyGridEntity } from "../types/AnyGridEntity";
19
19
  import { isCircleIntersectingRectangle } from "./math";
20
20
  import { roomUpdateSafe } from "./rooms";
21
21
  import { clearSprite } from "./sprites";
22
- import { isNumber } from "./types";
22
+ import { asNumber, isNumber } from "./types";
23
23
  import { erange } from "./utils";
24
24
  import { isVector } from "./vector";
25
25
 
@@ -136,7 +136,7 @@ export function getCollidingEntitiesWithGridEntity(
136
136
  export function getCrawlSpaces(
137
137
  crawlSpaceVariant: CrawlSpaceVariant = -1,
138
138
  ): GridEntity[] {
139
- if ((crawlSpaceVariant as int) === -1) {
139
+ if (asNumber(crawlSpaceVariant) === -1) {
140
140
  return getGridEntities(GridEntityType.CRAWL_SPACE);
141
141
  }
142
142
 
@@ -11,6 +11,7 @@ import {
11
11
  removeGridEntities,
12
12
  spawnGridEntityWithVariant,
13
13
  } from "./gridEntities";
14
+ import { asNumber } from "./types";
14
15
 
15
16
  // The `getDoors` function is not located here because doors are collected via the `Room.GetDoor`
16
17
  // method instead, which is faster.
@@ -29,7 +30,7 @@ export function getPits(pitVariant: PitVariant = -1): GridEntityPit[] {
29
30
  const pit = gridEntity.ToPit();
30
31
  if (pit !== undefined) {
31
32
  const gridEntityVariant = pit.GetVariant();
32
- if ((pitVariant as int) === -1 || pitVariant === gridEntityVariant) {
33
+ if (asNumber(pitVariant) === -1 || pitVariant === gridEntityVariant) {
33
34
  pits.push(pit);
34
35
  }
35
36
  }
@@ -54,7 +55,7 @@ export function getPoops(
54
55
  const poop = gridEntity.ToPoop();
55
56
  if (poop !== undefined) {
56
57
  const gridEntityVariant = poop.GetVariant();
57
- if ((poopVariant as int) === -1 || poopVariant === gridEntityVariant) {
58
+ if (asNumber(poopVariant) === -1 || poopVariant === gridEntityVariant) {
58
59
  poops.push(poop);
59
60
  }
60
61
  }
@@ -80,7 +81,7 @@ export function getPressurePlates(
80
81
  if (pressurePlate !== undefined) {
81
82
  const gridEntityVariant = pressurePlate.GetVariant();
82
83
  if (
83
- (pressurePlateVariant as int) === -1 ||
84
+ asNumber(pressurePlateVariant) === -1 ||
84
85
  pressurePlateVariant === gridEntityVariant
85
86
  ) {
86
87
  pressurePlates.push(pressurePlate);
@@ -13,7 +13,6 @@ export * from "./challenges";
13
13
  export * from "./characters";
14
14
  export * from "./charge";
15
15
  export * from "./chargeBar";
16
- export * from "./collectibleCacheFlag";
17
16
  export * from "./collectibles";
18
17
  export * from "./collectibleSet";
19
18
  export * from "./collectibleTag";
@@ -13,7 +13,6 @@ export * as Challenges from "./challenges";
13
13
  export * as Characters from "./characters";
14
14
  export * as Charge from "./charge";
15
15
  export * as ChargeBar from "./chargeBar";
16
- export * as CollectibleCacheFlag from "./collectibleCacheFlag";
17
16
  export * as Collectibles from "./collectibles";
18
17
  export * as CollectibleSet from "./collectibleSet";
19
18
  export * as CollectibleTag from "./collectibleTag";
@@ -4,6 +4,7 @@ import {
4
4
  ControllerIndex,
5
5
  Keyboard,
6
6
  } from "isaac-typescript-definitions";
7
+ import { KEYBOARD_TO_STRING } from "../maps/keyboardToString";
7
8
  import { getEnumValues } from "./enums";
8
9
  import { copySet } from "./set";
9
10
  import { trimPrefix } from "./string";
@@ -42,10 +43,10 @@ const SHOOTING_ACTIONS_SET: ReadonlySet<ButtonAction> = new Set(
42
43
  );
43
44
 
44
45
  /** Helper function to get the enum name for the specified `Controller` value. */
45
- export function controllerToString(controller: Controller): string {
46
+ export function controllerToString(controller: Controller): string | undefined {
46
47
  const key = Controller[controller];
47
48
  if (key === undefined) {
48
- return "unknown";
49
+ return undefined;
49
50
  }
50
51
 
51
52
  return trimPrefix(key, "BUTTON_");
@@ -133,6 +134,18 @@ export function isShootActionTriggeredOnAnyInput(): boolean {
133
134
  );
134
135
  }
135
136
 
136
- export function keyboardToString(keyboard: Keyboard): string {
137
- return Keyboard[keyboard] ?? "unknown";
137
+ /**
138
+ * Helper function to get the string that would be typed if someone pressed the corresponding key.
139
+ */
140
+ export function keyboardToString(
141
+ keyboard: Keyboard,
142
+ uppercase: boolean,
143
+ ): string | undefined {
144
+ const tuple = KEYBOARD_TO_STRING.get(keyboard);
145
+ if (tuple === undefined) {
146
+ return undefined;
147
+ }
148
+
149
+ const [lowercaseCharacter, uppercaseCharacter] = tuple;
150
+ return uppercase ? uppercaseCharacter : lowercaseCharacter;
138
151
  }
@@ -2,7 +2,7 @@ import * as jsonLua from "../lib/jsonLua";
2
2
  import { logError } from "./log";
3
3
 
4
4
  function tryDecode(this: void, jsonString: string) {
5
- return jsonLua.decode(jsonString) as LuaMap;
5
+ return jsonLua.decode(jsonString) as LuaMap<AnyNotNil, unknown>;
6
6
  }
7
7
 
8
8
  function tryEncode(this: void, luaTable: unknown) {
@@ -34,11 +34,7 @@ export function deserializeKColor(kColor: SerializedKColor): KColor {
34
34
  );
35
35
  }
36
36
 
37
- const [r, g, b, a] = getNumbersFromTable(
38
- kColor as LuaMap<string, unknown>,
39
- OBJECT_NAME,
40
- ...KEYS,
41
- );
37
+ const [r, g, b, a] = getNumbersFromTable(kColor, OBJECT_NAME, ...KEYS);
42
38
 
43
39
  if (r === undefined) {
44
40
  error(
@@ -37,6 +37,7 @@ import {
37
37
  } from "./roomData";
38
38
  import { getRooms, getRoomsInsideGrid } from "./rooms";
39
39
  import { getGridIndexDelta } from "./roomShape";
40
+ import { asNumber } from "./types";
40
41
 
41
42
  const LEFT = -1;
42
43
  const UP = -LEVEL_GRID_ROW_WIDTH;
@@ -177,8 +178,8 @@ export function getNewRoomCandidatesForLevel(): Array<
177
178
  (room) =>
178
179
  room.Data !== undefined &&
179
180
  room.Data.Type === RoomType.DEFAULT &&
180
- room.Data.Subtype !== (DownpourRoomSubType.MIRROR as int) &&
181
- room.Data.Subtype !== (MinesRoomSubType.MINESHAFT_ENTRANCE as int),
181
+ room.Data.Subtype !== asNumber(DownpourRoomSubType.MIRROR) &&
182
+ room.Data.Subtype !== asNumber(MinesRoomSubType.MINESHAFT_ENTRANCE),
182
183
  );
183
184
 
184
185
  const newRoomCandidates: Array<[int, DoorSlot, int]> = [];
@@ -13,6 +13,7 @@ import {
13
13
  calculateStageTypeRepentance,
14
14
  onRepentanceStage,
15
15
  } from "./stage";
16
+ import { asNumber } from "./types";
16
17
 
17
18
  /**
18
19
  * Helper function to get the stage that a trapdoor or heaven door would take the player to, based
@@ -53,7 +54,7 @@ export function getNextStage(): LevelStage {
53
54
  case GridRoom.SECRET_EXIT: {
54
55
  if (repentanceStage) {
55
56
  // e.g. From Downpour 2 to Mines 1, etc.
56
- return (stage as int) + 1;
57
+ return asNumber(stage) + 1;
57
58
  }
58
59
 
59
60
  if (stage === LevelStage.DEPTHS_2) {
@@ -109,7 +110,7 @@ export function getNextStage(): LevelStage {
109
110
  }
110
111
 
111
112
  // By default, go to the next floor.
112
- return (stage as int) + 1;
113
+ return asNumber(stage) + 1;
113
114
  }
114
115
 
115
116
  function getNextStageBackwardsPath(
@@ -118,7 +119,7 @@ function getNextStageBackwardsPath(
118
119
  ): LevelStage {
119
120
  // If we have no stage history to work with, then default to the previous stage.
120
121
  if (!areFeaturesInitialized()) {
121
- return (stage as int) - 1;
122
+ return asNumber(stage) - 1;
122
123
  }
123
124
 
124
125
  const visitedDownpour1 = hasVisitedStage(
@@ -234,7 +235,7 @@ function getNextStageBackwardsPath(
234
235
  return LevelStage.DEPTHS_1;
235
236
  }
236
237
 
237
- return (stage as int) - 1;
238
+ return asNumber(stage) - 1;
238
239
  }
239
240
 
240
241
  /**
@@ -262,7 +263,7 @@ export function getNextStageType(upwards = false): StageType {
262
263
  }
263
264
 
264
265
  // Second, handle the special case of being in a specific off-grid room.
265
- if (roomGridIndex === (GridRoom.SECRET_EXIT as int)) {
266
+ if (roomGridIndex === asNumber(GridRoom.SECRET_EXIT)) {
266
267
  return calculateStageTypeRepentance(nextStage);
267
268
  }
268
269
 
@@ -17,6 +17,7 @@ import {
17
17
  } from "isaac-typescript-definitions";
18
18
  import { EGGY_STATE_FRAME_OF_FINAL_SPIDER } from "../core/constants";
19
19
  import { getNPCs } from "./entitiesSpecific";
20
+ import { asNumber } from "./types";
20
21
 
21
22
  /**
22
23
  * Used to filter out certain NPCs when determining of an NPC is "alive" and/or should keep the
@@ -125,7 +126,7 @@ export function isDaddyLongLegsChildStompEntity(npc: EntityNPC): boolean {
125
126
  export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
126
127
  return (
127
128
  npc.Type === EntityType.HOPPER &&
128
- npc.Variant === (HopperVariant.EGGY as int) &&
129
+ npc.Variant === asNumber(HopperVariant.EGGY) &&
129
130
  npc.State === NpcState.SUICIDE &&
130
131
  npc.StateFrame >= EGGY_STATE_FRAME_OF_FINAL_SPIDER
131
132
  );
@@ -140,7 +141,7 @@ export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
140
141
  export function isRaglingDeathPatch(npc: EntityNPC): boolean {
141
142
  return (
142
143
  npc.Type === EntityType.RAGLING &&
143
- npc.Variant === (RaglingVariant.RAG_MANS_RAGLING as int) &&
144
+ npc.Variant === asNumber(RaglingVariant.RAG_MANS_RAGLING) &&
144
145
  // They go to `STATE_SPECIAL` when they are patches on the ground.
145
146
  npc.State === NpcState.SPECIAL
146
147
  );
@@ -30,6 +30,7 @@ import {
30
30
  PILL_EFFECT_TYPES,
31
31
  } from "../objects/pillEffectTypes";
32
32
  import { getEnumValues } from "./enums";
33
+ import { asNumber, asPillColor } from "./types";
33
34
  import { irange } from "./utils";
34
35
 
35
36
  /**
@@ -55,7 +56,7 @@ export function getAllPillColors(): PillColor[] {
55
56
  * Helper function to get an array with every valid pill effect. This includes modded pill effects.
56
57
  */
57
58
  export function getAllPillEffects(): PillEffect[] {
58
- return irange(FIRST_PILL_EFFECT, LAST_PILL_EFFECT) as PillEffect[];
59
+ return irange(FIRST_PILL_EFFECT, LAST_PILL_EFFECT);
59
60
  }
60
61
 
61
62
  /**
@@ -74,12 +75,12 @@ export function getFalsePHDPillEffect(pillEffect: PillEffect): PillEffect {
74
75
  * corresponds to the horse pill color for blue/blue.
75
76
  */
76
77
  export function getHorsePillColor(pillColor: PillColor): PillColor {
77
- return pillColor + HORSE_PILL_ADJUSTMENT; // eslint-disable-line isaacscript/strict-enums
78
+ return asNumber(pillColor) + HORSE_PILL_ADJUSTMENT;
78
79
  }
79
80
 
80
81
  /** Helper function to get an array with every non-gold horse pill color. */
81
82
  export function getHorsePillColors(): PillColor[] {
82
- return irange(FIRST_HORSE_PILL_COLOR, LAST_HORSE_PILL_COLOR) as PillColor[];
83
+ return irange(FIRST_HORSE_PILL_COLOR, LAST_HORSE_PILL_COLOR);
83
84
  }
84
85
 
85
86
  /**
@@ -92,7 +93,7 @@ export function getModdedPillEffects(): PillEffect[] {
92
93
  return [];
93
94
  }
94
95
 
95
- return irange(FIRST_MODDED_PILL_EFFECT, LAST_PILL_EFFECT) as PillEffect[];
96
+ return irange(FIRST_MODDED_PILL_EFFECT, LAST_PILL_EFFECT);
96
97
  }
97
98
 
98
99
  /**
@@ -103,15 +104,16 @@ export function getModdedPillEffects(): PillEffect[] {
103
104
  * If called with a non-horse pill color, this function will return back the same color.
104
105
  */
105
106
  export function getNormalPillColorFromHorse(pillColor: PillColor): PillColor {
106
- // eslint-disable-next-line isaacscript/strict-enums
107
- const normalPillColor = (pillColor - HORSE_PILL_ADJUSTMENT) as PillColor;
107
+ const normalPillColor = asPillColor(
108
+ asNumber(pillColor) - HORSE_PILL_ADJUSTMENT,
109
+ );
108
110
 
109
111
  return normalPillColor > PillColor.NULL ? normalPillColor : pillColor;
110
112
  }
111
113
 
112
114
  /** Helper function to get an array with every non-gold and non-horse pill color. */
113
115
  export function getNormalPillColors(): PillColor[] {
114
- return irange(FIRST_PILL_COLOR, LAST_NORMAL_PILL_COLOR) as PillColor[];
116
+ return irange(FIRST_PILL_COLOR, LAST_NORMAL_PILL_COLOR);
115
117
  }
116
118
 
117
119
  /**
@@ -197,9 +199,9 @@ export function getPillEffectType(
197
199
 
198
200
  /** Helper function to get an array with every vanilla pill effect. */
199
201
  export function getVanillaPillEffects(): PillEffect[] {
200
- return irange(FIRST_PILL_EFFECT, LAST_VANILLA_PILL_EFFECT) as PillEffect[];
202
+ return irange(FIRST_PILL_EFFECT, LAST_VANILLA_PILL_EFFECT);
201
203
  }
202
204
 
203
205
  export function isHorsePill(pillColor: PillColor): boolean {
204
- return pillColor > (HORSE_PILL_ADJUSTMENT as PillColor);
206
+ return asNumber(pillColor) > HORSE_PILL_ADJUSTMENT;
205
207
  }
@@ -96,9 +96,11 @@ export function getPlayerIndex(
96
96
  let playerToUse = player;
97
97
  const isSubPlayer = player.IsSubPlayer();
98
98
  if (isSubPlayer) {
99
+ const subPlayer = player as EntitySubPlayer;
100
+
99
101
  // The "getSubPlayerParent" function will return undefined in the situation where we are on Dead
100
102
  // Tainted Lazarus in the `POST_PLAYER_INIT` callback.
101
- const playerParent = getSubPlayerParent(player as EntitySubPlayer);
103
+ const playerParent = getSubPlayerParent(subPlayer);
102
104
  if (playerParent !== undefined) {
103
105
  playerToUse = playerParent;
104
106
  }
@@ -21,6 +21,5 @@ export function getPlayerStat<T extends StatType>(
21
21
  [StatType.TEAR_COLOR]: player.TearColor, // 1 << 6
22
22
  [StatType.FLYING]: player.CanFly, // 1 << 7
23
23
  [StatType.LUCK]: player.Luck, // 1 << 10
24
- [StatType.SIZE]: player.SizeMulti, // 1 << 11
25
24
  }[statType];
26
25
  }
@@ -23,6 +23,7 @@ import { getCollectibleArray } from "./collectibleSet";
23
23
  import { getEnumValues } from "./enums";
24
24
  import { getPlayerIndexVanilla, getPlayers } from "./playerIndex";
25
25
  import { addTearsStat } from "./tears";
26
+ import { isNumber } from "./types";
26
27
  import { repeat } from "./utils";
27
28
 
28
29
  const STAT_CACHE_FLAGS_SET: ReadonlySet<CacheFlag> = new Set([
@@ -225,16 +226,14 @@ export function getActiveItemSlot(
225
226
  * Helper function to get how long Azazel's Brimstone laser should be. You can pass either an
226
227
  * `EntityPlayer` object or a tear height stat.
227
228
  *
228
- * The formula for calculating it is: 32 - 2.5 * player.TearHeight
229
+ * The formula for calculating it is: 32 - 2.5 * tearHeight
229
230
  */
230
231
  export function getAzazelBrimstoneDistance(
231
232
  playerOrTearHeight: EntityPlayer | float,
232
233
  ): float {
233
- let tearHeight = tonumber(playerOrTearHeight);
234
- if (tearHeight === undefined) {
235
- const player = playerOrTearHeight as EntityPlayer;
236
- tearHeight = player.TearHeight;
237
- }
234
+ const tearHeight = isNumber(playerOrTearHeight)
235
+ ? playerOrTearHeight
236
+ : playerOrTearHeight.TearHeight;
238
237
 
239
238
  return 32 - 2.5 * tearHeight;
240
239
  }
@@ -10,6 +10,7 @@ import { PocketItemType } from "../enums/PocketItemType";
10
10
  import { PocketItemDescription } from "../interfaces/PocketItemDescription";
11
11
  import { getEnumValues } from "./enums";
12
12
  import { isCharacter } from "./players";
13
+ import { asNumber } from "./types";
13
14
 
14
15
  /**
15
16
  * Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
@@ -63,8 +64,8 @@ export function getPocketItems(player: EntityPlayer): PocketItemDescription[] {
63
64
  let pocketItemIdentified = false;
64
65
  let pocketItem2Identified = false;
65
66
  for (const slot of pocketItemSlots) {
66
- const card = player.GetCard(slot as PocketItemSlot);
67
- const pillColor = player.GetPill(slot as PocketItemSlot);
67
+ const card = player.GetCard(slot);
68
+ const pillColor = player.GetPill(slot);
68
69
 
69
70
  if (card !== Card.NULL) {
70
71
  pocketItems.push({
@@ -106,8 +107,7 @@ export function getPocketItems(player: EntityPlayer): PocketItemDescription[] {
106
107
  });
107
108
  }
108
109
 
109
- // eslint-disable-next-line isaacscript/strict-enums
110
- if (slot + 1 === maxPocketItems) {
110
+ if (asNumber(slot) + 1 === maxPocketItems) {
111
111
  break;
112
112
  }
113
113
  }
@@ -41,11 +41,14 @@ export function deserializeRNG(rng: SerializedRNG): RNG {
41
41
  );
42
42
  }
43
43
 
44
- const [seed] = getNumbersFromTable(
45
- rng as LuaMap<string, unknown>,
46
- OBJECT_NAME,
47
- ...KEYS,
48
- );
44
+ const [seed] = getNumbersFromTable(rng, OBJECT_NAME, ...KEYS);
45
+
46
+ if (seed === undefined) {
47
+ error(
48
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: seed`,
49
+ );
50
+ }
51
+
49
52
  return newRNG(seed as Seed);
50
53
  }
51
54