isaacscript-common 4.0.0 → 4.0.1-dev.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 (387) hide show
  1. package/cachedClasses.ts +39 -0
  2. package/callbacks/customRevive.lua +2 -1
  3. package/callbacks/customRevive.ts +215 -0
  4. package/callbacks/itemPickup.ts +101 -0
  5. package/callbacks/postAmbush.ts +73 -0
  6. package/callbacks/postBombExploded.ts +26 -0
  7. package/callbacks/postBombInitLate.ts +36 -0
  8. package/callbacks/postBoneSwing.ts +64 -0
  9. package/callbacks/postCollectibleInitFirst.ts +40 -0
  10. package/callbacks/postCursedTeleport.ts +183 -0
  11. package/callbacks/postCustomDoorEnter.lua +0 -7
  12. package/callbacks/postCustomDoorEnter.ts +292 -0
  13. package/callbacks/postDiceRoomActivated.ts +60 -0
  14. package/callbacks/postDoorRender.ts +26 -0
  15. package/callbacks/postDoorUpdate.ts +26 -0
  16. package/callbacks/postEffectInitLate.ts +36 -0
  17. package/callbacks/postEffectStateChanged.ts +43 -0
  18. package/callbacks/postEsauJr.ts +107 -0
  19. package/callbacks/postFamiliarInitLate.ts +36 -0
  20. package/callbacks/postFamiliarStateChanged.ts +43 -0
  21. package/callbacks/postFlip.ts +88 -0
  22. package/callbacks/postGreedModeWave.ts +41 -0
  23. package/callbacks/postGridEntity.ts +164 -0
  24. package/callbacks/postGridEntityCollision.ts +69 -0
  25. package/callbacks/postGridEntityRender.ts +26 -0
  26. package/callbacks/postHolyMantleRemoved.ts +55 -0
  27. package/callbacks/postItemDischarged.ts +149 -0
  28. package/callbacks/postKnifeInitLate.ts +36 -0
  29. package/callbacks/postLaserInitLate.ts +36 -0
  30. package/callbacks/postNPCInitLate.ts +36 -0
  31. package/callbacks/postNPCStateChanged.ts +42 -0
  32. package/callbacks/postNewRoomEarly.ts +90 -0
  33. package/callbacks/postPickupCollect.ts +48 -0
  34. package/callbacks/postPickupInitFirst.ts +70 -0
  35. package/callbacks/postPickupInitLate.ts +36 -0
  36. package/callbacks/postPickupStateChanged.ts +43 -0
  37. package/callbacks/postPitRender.ts +26 -0
  38. package/callbacks/postPitUpdate.ts +26 -0
  39. package/callbacks/postPlayerChangeHealth.ts +62 -0
  40. package/callbacks/postPlayerChangeType.ts +56 -0
  41. package/callbacks/postPlayerCollectible.ts +113 -0
  42. package/callbacks/postPlayerFatalDamage.ts +141 -0
  43. package/callbacks/postPlayerInitLate.ts +37 -0
  44. package/callbacks/postPlayerReordered.ts +142 -0
  45. package/callbacks/postPoopRender.ts +26 -0
  46. package/callbacks/postPoopUpdate.ts +26 -0
  47. package/callbacks/postPressurePlateRender.ts +26 -0
  48. package/callbacks/postPressurePlateUpdate.ts +26 -0
  49. package/callbacks/postProjectileInitLate.ts +36 -0
  50. package/callbacks/postPurchase.ts +64 -0
  51. package/callbacks/postRockRender.ts +26 -0
  52. package/callbacks/postRockUpdate.ts +26 -0
  53. package/callbacks/postRoomClearChanged.ts +57 -0
  54. package/callbacks/postSacrifice.ts +62 -0
  55. package/callbacks/postSlotDestroyed.ts +92 -0
  56. package/callbacks/postSlotInitUpdate.ts +68 -0
  57. package/callbacks/postSlotRender.ts +69 -0
  58. package/callbacks/postSpikesRender.ts +26 -0
  59. package/callbacks/postSpikesUpdate.ts +26 -0
  60. package/callbacks/postTNTRender.ts +26 -0
  61. package/callbacks/postTNTUpdate.ts +26 -0
  62. package/callbacks/postTearInitLate.ts +36 -0
  63. package/callbacks/postTearInitVeryLate.ts +41 -0
  64. package/callbacks/postTransformation.ts +59 -0
  65. package/callbacks/postTrinketBreak.ts +110 -0
  66. package/callbacks/preBerserkDeath.ts +49 -0
  67. package/callbacks/preNewLevel.ts +55 -0
  68. package/callbacks/reorderedCallbacks.ts +166 -0
  69. package/callbacks/subscriptions/postAmbushFinished.ts +32 -0
  70. package/callbacks/subscriptions/postAmbushStarted.ts +32 -0
  71. package/callbacks/subscriptions/postBombInitLate.ts +32 -0
  72. package/callbacks/subscriptions/postBoneExploded.ts +32 -0
  73. package/callbacks/subscriptions/postBoneSwing.ts +24 -0
  74. package/callbacks/subscriptions/postCollectibleInitFirst.ts +37 -0
  75. package/callbacks/subscriptions/postCursedTeleport.ts +24 -0
  76. package/callbacks/subscriptions/postCustomDoorEnter.ts +45 -0
  77. package/callbacks/subscriptions/postCustomRevive.ts +36 -0
  78. package/callbacks/subscriptions/postDiceRoomActivated.ts +38 -0
  79. package/callbacks/subscriptions/postDoorRender.ts +35 -0
  80. package/callbacks/subscriptions/postDoorUpdate.ts +35 -0
  81. package/callbacks/subscriptions/postEffectInitLate.ts +32 -0
  82. package/callbacks/subscriptions/postEffectStateChanged.ts +40 -0
  83. package/callbacks/subscriptions/postEsauJr.ts +24 -0
  84. package/callbacks/subscriptions/postFamiliarInitLate.ts +32 -0
  85. package/callbacks/subscriptions/postFamiliarStateChanged.ts +40 -0
  86. package/callbacks/subscriptions/postFirstEsauJr.ts +24 -0
  87. package/callbacks/subscriptions/postFirstFlip.ts +24 -0
  88. package/callbacks/subscriptions/postFlip.ts +22 -0
  89. package/callbacks/subscriptions/postGameStartedReordered.ts +24 -0
  90. package/callbacks/subscriptions/postGreedModeWave.ts +24 -0
  91. package/callbacks/subscriptions/postGridEntityBroken.ts +51 -0
  92. package/callbacks/subscriptions/postGridEntityCollision.ts +54 -0
  93. package/callbacks/subscriptions/postGridEntityInit.ts +51 -0
  94. package/callbacks/subscriptions/postGridEntityRemove.ts +52 -0
  95. package/callbacks/subscriptions/postGridEntityRender.ts +51 -0
  96. package/callbacks/subscriptions/postGridEntityStateChanged.ts +55 -0
  97. package/callbacks/subscriptions/postGridEntityUpdate.ts +51 -0
  98. package/callbacks/subscriptions/postHolyMantleRemoved.ts +48 -0
  99. package/callbacks/subscriptions/postItemDischarged.ts +43 -0
  100. package/callbacks/subscriptions/postItemPickup.ts +64 -0
  101. package/callbacks/subscriptions/postKnifeInitLate.ts +32 -0
  102. package/callbacks/subscriptions/postLaserInitLate.ts +32 -0
  103. package/callbacks/subscriptions/postNPCInitLate.ts +32 -0
  104. package/callbacks/subscriptions/postNPCStateChanged.ts +42 -0
  105. package/callbacks/subscriptions/postNewLevelReordered.ts +22 -0
  106. package/callbacks/subscriptions/postNewRoomEarly.ts +22 -0
  107. package/callbacks/subscriptions/postNewRoomReordered.ts +22 -0
  108. package/callbacks/subscriptions/postPEffectUpdateReordered.ts +40 -0
  109. package/callbacks/subscriptions/postPickupCollect.ts +35 -0
  110. package/callbacks/subscriptions/postPickupInitFirst.ts +32 -0
  111. package/callbacks/subscriptions/postPickupInitLate.ts +32 -0
  112. package/callbacks/subscriptions/postPickupStateChanged.ts +40 -0
  113. package/callbacks/subscriptions/postPitRender.ts +35 -0
  114. package/callbacks/subscriptions/postPitUpdate.ts +35 -0
  115. package/callbacks/subscriptions/postPlayerChangeHealth.ts +49 -0
  116. package/callbacks/subscriptions/postPlayerChangeType.ts +40 -0
  117. package/callbacks/subscriptions/postPlayerCollectibleAdded.ts +38 -0
  118. package/callbacks/subscriptions/postPlayerCollectibleRemoved.ts +38 -0
  119. package/callbacks/subscriptions/postPlayerFatalDamage.d.ts +1 -1
  120. package/callbacks/subscriptions/postPlayerFatalDamage.ts +68 -0
  121. package/callbacks/subscriptions/postPlayerInitLate.ts +40 -0
  122. package/callbacks/subscriptions/postPlayerInitReordered.ts +40 -0
  123. package/callbacks/subscriptions/postPlayerRenderReordered.ts +40 -0
  124. package/callbacks/subscriptions/postPlayerUpdateReordered.ts +40 -0
  125. package/callbacks/subscriptions/postPoopRender.ts +35 -0
  126. package/callbacks/subscriptions/postPoopUpdate.ts +35 -0
  127. package/callbacks/subscriptions/postPressurePlateRender.ts +37 -0
  128. package/callbacks/subscriptions/postPressurePlateUpdate.ts +37 -0
  129. package/callbacks/subscriptions/postProjectileInitLate.ts +35 -0
  130. package/callbacks/subscriptions/postPurchase.ts +31 -0
  131. package/callbacks/subscriptions/postRockRender.ts +35 -0
  132. package/callbacks/subscriptions/postRockUpdate.ts +35 -0
  133. package/callbacks/subscriptions/postRoomClearChanged.ts +30 -0
  134. package/callbacks/subscriptions/postSacrifice.ts +43 -0
  135. package/callbacks/subscriptions/postSlotAnimationChanged.ts +40 -0
  136. package/callbacks/subscriptions/postSlotDestroyed.ts +55 -0
  137. package/callbacks/subscriptions/postSlotInit.ts +32 -0
  138. package/callbacks/subscriptions/postSlotRender.ts +32 -0
  139. package/callbacks/subscriptions/postSlotUpdate.ts +32 -0
  140. package/callbacks/subscriptions/postSpikesRender.ts +35 -0
  141. package/callbacks/subscriptions/postSpikesUpdate.ts +35 -0
  142. package/callbacks/subscriptions/postTNTRender.ts +35 -0
  143. package/callbacks/subscriptions/postTNTUpdate.ts +35 -0
  144. package/callbacks/subscriptions/postTearInitLate.ts +32 -0
  145. package/callbacks/subscriptions/postTearInitVeryLate.ts +32 -0
  146. package/callbacks/subscriptions/postTransformation.ts +40 -0
  147. package/callbacks/subscriptions/postTrinketBreak.ts +38 -0
  148. package/callbacks/subscriptions/preBerserkDeath.ts +42 -0
  149. package/callbacks/subscriptions/preCustomRevive.d.ts +1 -1
  150. package/callbacks/subscriptions/preCustomRevive.ts +46 -0
  151. package/callbacks/subscriptions/preItemPickup.ts +64 -0
  152. package/callbacks/subscriptions/preNewLevel.ts +24 -0
  153. package/classes/DefaultMap.ts +174 -0
  154. package/classes/ModUpgraded.ts +77 -0
  155. package/constants.ts +162 -0
  156. package/constantsFirstLast.ts +217 -0
  157. package/enums/AmbushType.ts +4 -0
  158. package/enums/HealthType.ts +16 -0
  159. package/enums/ModCallbackCustom.d.ts +2 -2
  160. package/enums/ModCallbackCustom.ts +1278 -0
  161. package/enums/PocketItemType.ts +8 -0
  162. package/enums/SerializationType.ts +5 -0
  163. package/enums/SlotDestructionType.ts +4 -0
  164. package/enums/private/CopyableIsaacAPIClassType.ts +7 -0
  165. package/enums/private/SaveDataKey.ts +14 -0
  166. package/enums/private/SerializationBrand.ts +42 -0
  167. package/features/characterHealthConversion.lua +2 -9
  168. package/features/characterHealthConversion.ts +111 -0
  169. package/features/characterStats.ts +61 -0
  170. package/features/debugDisplay/debugDisplay.ts +221 -0
  171. package/features/debugDisplay/exports.ts +368 -0
  172. package/features/debugDisplay/v.ts +65 -0
  173. package/features/deployJSONRoom.ts +743 -0
  174. package/features/disableInputs.ts +193 -0
  175. package/features/disableSound.ts +77 -0
  176. package/features/extraConsoleCommands/commandsDisplay.ts +290 -0
  177. package/features/extraConsoleCommands/commandsSubroutines.ts +139 -0
  178. package/features/extraConsoleCommands/init.ts +334 -0
  179. package/features/extraConsoleCommands/listCommands.ts +1299 -0
  180. package/features/extraConsoleCommands/v.ts +14 -0
  181. package/features/fadeInRemover.ts +60 -0
  182. package/features/fastReset.ts +75 -0
  183. package/features/forgottenSwitch.ts +50 -0
  184. package/features/getCollectibleItemPoolType.ts +66 -0
  185. package/features/persistentEntities.ts +183 -0
  186. package/features/playerInventory.ts +133 -0
  187. package/features/ponyDetection.ts +74 -0
  188. package/features/preventCollectibleRotation.ts +115 -0
  189. package/features/runInNFrames.ts +148 -0
  190. package/features/saveDataManager/constants.ts +4 -0
  191. package/features/saveDataManager/exports.ts +229 -0
  192. package/features/saveDataManager/load.ts +99 -0
  193. package/features/saveDataManager/main.ts +195 -0
  194. package/features/saveDataManager/maps.ts +13 -0
  195. package/features/saveDataManager/merge.ts +194 -0
  196. package/features/saveDataManager/save.ts +74 -0
  197. package/features/saveDataManager/serializationBrand.ts +16 -0
  198. package/features/sirenHelpers.ts +129 -0
  199. package/features/taintedLazarusPlayers.ts +113 -0
  200. package/featuresInitialized.ts +20 -0
  201. package/functions/ambush.ts +47 -0
  202. package/functions/array.ts +410 -0
  203. package/functions/benchmark.ts +36 -0
  204. package/functions/bitwise.ts +24 -0
  205. package/functions/bombs.ts +12 -0
  206. package/functions/boss.ts +227 -0
  207. package/functions/cacheFlag.ts +12 -0
  208. package/functions/cards.ts +271 -0
  209. package/functions/challenges.ts +13 -0
  210. package/functions/character.ts +126 -0
  211. package/functions/charge.ts +237 -0
  212. package/functions/chargeBar.ts +67 -0
  213. package/functions/collectibleCacheFlag.ts +90 -0
  214. package/functions/collectibleSet.ts +56 -0
  215. package/functions/collectibleTag.ts +89 -0
  216. package/functions/collectibles.ts +659 -0
  217. package/functions/color.lua +0 -7
  218. package/functions/color.ts +128 -0
  219. package/functions/debug.ts +68 -0
  220. package/functions/deepCopy.lua +46 -51
  221. package/functions/deepCopy.ts +535 -0
  222. package/functions/deepCopyTests.ts +386 -0
  223. package/functions/direction.ts +49 -0
  224. package/functions/doors.ts +347 -0
  225. package/functions/easing.ts +182 -0
  226. package/functions/eden.ts +47 -0
  227. package/functions/effects.ts +20 -0
  228. package/functions/entity.ts +439 -0
  229. package/functions/entitySpecific.ts +889 -0
  230. package/functions/entityTypes.ts +6 -0
  231. package/functions/enums.ts +146 -0
  232. package/functions/familiars.ts +106 -0
  233. package/functions/flag.ts +165 -0
  234. package/functions/flying.ts +117 -0
  235. package/functions/globals.ts +242 -0
  236. package/functions/gridEntity.ts +511 -0
  237. package/functions/gridEntitySpecific.ts +112 -0
  238. package/functions/input.ts +139 -0
  239. package/functions/isaacAPIClass.ts +67 -0
  240. package/functions/jsonHelpers.ts +45 -0
  241. package/functions/jsonRoom.ts +100 -0
  242. package/functions/kColor.lua +0 -7
  243. package/functions/kColor.ts +129 -0
  244. package/functions/language.ts +13 -0
  245. package/functions/level.ts +31 -0
  246. package/functions/log.ts +720 -0
  247. package/functions/map.ts +56 -0
  248. package/functions/math.ts +149 -0
  249. package/functions/mergeTests.ts +288 -0
  250. package/functions/npc.ts +148 -0
  251. package/functions/pickupVariants.ts +60 -0
  252. package/functions/pickups.ts +499 -0
  253. package/functions/pills.ts +205 -0
  254. package/functions/player.lua +0 -6
  255. package/functions/player.ts +1060 -0
  256. package/functions/playerDataStructures.ts +150 -0
  257. package/functions/playerHealth.lua +28 -39
  258. package/functions/playerHealth.ts +382 -0
  259. package/functions/playerIndex.ts +195 -0
  260. package/functions/pocketItems.ts +149 -0
  261. package/functions/positionVelocity.ts +188 -0
  262. package/functions/random.ts +77 -0
  263. package/functions/revive.ts +201 -0
  264. package/functions/rng.lua +0 -7
  265. package/functions/rng.ts +172 -0
  266. package/functions/roomData.ts +199 -0
  267. package/functions/roomGrid.ts +109 -0
  268. package/functions/roomShape.ts +80 -0
  269. package/functions/rooms.ts +648 -0
  270. package/functions/run.ts +36 -0
  271. package/functions/saveFile.ts +128 -0
  272. package/functions/seeds.ts +19 -0
  273. package/functions/serialization.ts +91 -0
  274. package/functions/set.ts +95 -0
  275. package/functions/sound.ts +9 -0
  276. package/functions/spawnCollectible.ts +104 -0
  277. package/functions/sprite.ts +107 -0
  278. package/functions/stage.ts +125 -0
  279. package/functions/string.ts +47 -0
  280. package/functions/table.ts +189 -0
  281. package/functions/tears.ts +32 -0
  282. package/functions/transformations.ts +131 -0
  283. package/functions/trinketCacheFlag.ts +60 -0
  284. package/functions/trinketGive.ts +157 -0
  285. package/functions/trinkets.ts +215 -0
  286. package/functions/tstlClass.ts +157 -0
  287. package/functions/types.ts +36 -0
  288. package/functions/ui.ts +138 -0
  289. package/functions/utils.d.ts +0 -37
  290. package/functions/utils.lua +0 -35
  291. package/functions/utils.ts +189 -0
  292. package/functions/vector.lua +0 -7
  293. package/functions/vector.ts +126 -0
  294. package/index.ts +172 -0
  295. package/initCustomCallbacks.ts +132 -0
  296. package/initFeatures.ts +39 -0
  297. package/interfaces/AddCallbackParameterCustom.ts +188 -0
  298. package/interfaces/ChargeBarSprites.ts +12 -0
  299. package/interfaces/JSONDoor.d.ts +3 -3
  300. package/interfaces/JSONDoor.ts +13 -0
  301. package/interfaces/JSONEntity.d.ts +4 -4
  302. package/interfaces/JSONEntity.ts +16 -0
  303. package/interfaces/JSONRoom.d.ts +8 -8
  304. package/interfaces/JSONRoom.ts +36 -0
  305. package/interfaces/JSONRooms.ts +12 -0
  306. package/interfaces/JSONSpawn.d.ts +2 -2
  307. package/interfaces/JSONSpawn.ts +14 -0
  308. package/interfaces/PlayerHealth.ts +16 -0
  309. package/interfaces/PocketItemDescription.ts +9 -0
  310. package/interfaces/SaveData.ts +29 -0
  311. package/interfaces/TrinketSituation.ts +9 -0
  312. package/interfaces/private/TSTLClassMetatable.ts +8 -0
  313. package/maps/PHDPillConversions.ts +21 -0
  314. package/maps/cardMap.ts +209 -0
  315. package/maps/characterMap.ts +87 -0
  316. package/maps/collectibleDescriptionMap.ts +732 -0
  317. package/maps/collectibleNameMap.ts +731 -0
  318. package/maps/defaultPlayerStatMap.ts +17 -0
  319. package/maps/falsePHDPillConversions.ts +35 -0
  320. package/maps/gridEntityTypeToBrokenStateMap.ts +50 -0
  321. package/maps/gridEntityXMLMap.ts +176 -0
  322. package/maps/pillEffectMap.ts +88 -0
  323. package/maps/roomShapeToTopLeftWallGridIndexMap.ts +18 -0
  324. package/maps/roomTypeMap.ts +40 -0
  325. package/maps/trinketDescriptionMap.ts +200 -0
  326. package/maps/trinketNameMap.ts +198 -0
  327. package/objects/LRoomShapeToRectangles.ts +44 -0
  328. package/objects/callbackRegisterFunctions.ts +187 -0
  329. package/objects/cardDescriptions.ts +105 -0
  330. package/objects/cardNames.ts +105 -0
  331. package/objects/cardTypes.ts +104 -0
  332. package/objects/challengeNames.ts +52 -0
  333. package/objects/characterNames.ts +48 -0
  334. package/objects/coinSubTypeToValue.ts +14 -0
  335. package/objects/colors.ts +16 -0
  336. package/objects/directionNames.ts +11 -0
  337. package/objects/directionToDegrees.ts +11 -0
  338. package/objects/directionToVector.ts +12 -0
  339. package/objects/doorSlotFlagToDoorSlot.ts +16 -0
  340. package/objects/doorSlotToDirection.ts +14 -0
  341. package/objects/isaacAPIClassTypeToBrand.ts +11 -0
  342. package/objects/isaacAPIClassTypeToCopyFunction.ts +18 -0
  343. package/objects/languageNames.ts +13 -0
  344. package/objects/oppositeDoorSlots.ts +15 -0
  345. package/objects/pillEffectClasses.ts +63 -0
  346. package/objects/pillEffectNames.ts +57 -0
  347. package/objects/pillEffectTypes.ts +62 -0
  348. package/objects/roomShapeBounds.ts +71 -0
  349. package/objects/roomShapeLayoutSizes.ts +45 -0
  350. package/objects/roomShapeToBottomRightPosition.ts +25 -0
  351. package/objects/roomShapeToDoorSlots.ts +83 -0
  352. package/objects/roomShapeToDoorSlotsToGridIndexDelta.ts +127 -0
  353. package/objects/roomShapeToGridWidth.ts +21 -0
  354. package/objects/roomShapeToTopLeftPosition.ts +26 -0
  355. package/objects/roomShapeVolumes.ts +38 -0
  356. package/objects/roomTypeNames.ts +36 -0
  357. package/objects/serializedIsaacAPIClassTypeToIdentityFunction.ts +14 -0
  358. package/objects/stageTypeToLetter.ts +15 -0
  359. package/objects/transformationNames.d.ts +0 -1
  360. package/objects/transformationNames.lua +0 -1
  361. package/objects/transformationNames.ts +18 -0
  362. package/package.json +1 -1
  363. package/patchErrorFunctions.ts +92 -0
  364. package/sets/LRoomShapesSet.ts +8 -0
  365. package/sets/bossSets.ts +470 -0
  366. package/sets/charactersThatStartWithAnActiveItemSet.ts +16 -0
  367. package/sets/charactersWithBlackHeartFromEternalHeartSet.ts +7 -0
  368. package/sets/charactersWithFreeDevilDealsSet.ts +4 -0
  369. package/sets/charactersWithNoRedHeartsSet.ts +17 -0
  370. package/sets/charactersWithNoSoulHeartsSet.ts +14 -0
  371. package/sets/chestPickupVariantsSet.ts +16 -0
  372. package/sets/familiarsThatShootPlayerTearsSet.ts +13 -0
  373. package/sets/lostStyleCharactersSet.ts +13 -0
  374. package/sets/mineShaftRoomSubTypesSet.ts +10 -0
  375. package/sets/redHeartSubTypesSet.ts +7 -0
  376. package/sets/sinEntityTypesSet.ts +11 -0
  377. package/sets/singleUseActiveCollectibleTypesSet.ts +13 -0
  378. package/sets/storyBossesSet.ts +17 -0
  379. package/types/AnyEntity.ts +12 -0
  380. package/types/AwaitingTextInput.d.ts +2 -0
  381. package/types/CollectibleIndex.ts +16 -0
  382. package/types/PickingUpItem.ts +89 -0
  383. package/types/PlayerIndex.ts +13 -0
  384. package/types/private/IsaacAPIClass.ts +3 -0
  385. package/types/private/SerializedIsaacAPIClass.ts +3 -0
  386. package/types/private/TSTLClass.ts +3 -0
  387. package/upgradeMod.ts +55 -0
@@ -0,0 +1,128 @@
1
+ import {
2
+ CollectibleType,
3
+ ItemPoolType,
4
+ PlayerType,
5
+ TrinketType,
6
+ } from "isaac-typescript-definitions";
7
+ import { game } from "../cachedClasses";
8
+ import { PlayerIndex } from "../types/PlayerIndex";
9
+ import { getCollectibleSet } from "./collectibleSet";
10
+ import { anyPlayerHasCollectible, getPlayersOfType } from "./player";
11
+ import { mapGetPlayer, mapSetPlayer } from "./playerDataStructures";
12
+ import { getPlayers } from "./playerIndex";
13
+ import { repeat } from "./utils";
14
+
15
+ const COLLECTIBLES_THAT_AFFECT_ITEM_POOLS: readonly CollectibleType[] = [
16
+ CollectibleType.CHAOS, // 402
17
+ CollectibleType.SACRED_ORB, // 691
18
+ CollectibleType.TMTRAINER, // 721
19
+ ];
20
+
21
+ const TRINKETS_THAT_AFFECT_ITEM_POOLS: readonly TrinketType[] = [
22
+ TrinketType.NO,
23
+ ];
24
+
25
+ /**
26
+ * Helper function to see if the given collectible is unlocked on the player's save file. This
27
+ * requires providing the corresponding item pool that the collectible is located in.
28
+ *
29
+ * - If any player currently has the item, then it is assumed to be unlocked. (This is because Eden
30
+ * may have randomly started with the provided collectible, and it will be subsequently removed
31
+ * from all pools.)
32
+ * - If the collectible is located in more than one item pool, then any item pool can be provided.
33
+ * - If the collectible is not located in any item pools, then this function will always return
34
+ * false.
35
+ * - If any player is Tainted Lost, they will be temporarily changed to Isaac and then temporarily
36
+ * changed back (because Tainted Lost is not able to retrieve some collectibles from item pools).
37
+ */
38
+ export function isCollectibleUnlocked(
39
+ collectibleTypeToCheckFor: CollectibleType,
40
+ itemPoolToCheckFor: ItemPoolType,
41
+ ): boolean {
42
+ // If Eden is holding this collectible, then it is obviously unlocked (and it will also be removed
43
+ // from pools, so the below check won't work).
44
+ if (anyPlayerHasCollectible(collectibleTypeToCheckFor)) {
45
+ return true;
46
+ }
47
+
48
+ // On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
49
+ // temporarily change the character to Isaac.
50
+ const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
51
+ for (const player of taintedLosts) {
52
+ player.ChangePlayerType(PlayerType.ISAAC);
53
+ }
54
+
55
+ // Before checking the item pools, remove any collectibles or trinkets that affect retrieved
56
+ // collectible types.
57
+ const removedItemsMap = new Map<PlayerIndex, CollectibleType[]>();
58
+ const removedTrinketsMap = new Map<PlayerIndex, TrinketType[]>();
59
+ for (const player of getPlayers()) {
60
+ const removedItems: CollectibleType[] = [];
61
+ for (const itemToRemove of COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) {
62
+ if (player.HasCollectible(itemToRemove)) {
63
+ const numCollectibles = player.GetCollectibleNum(itemToRemove);
64
+ repeat(numCollectibles, () => {
65
+ player.RemoveCollectible(itemToRemove);
66
+ removedItems.push(itemToRemove);
67
+ });
68
+ }
69
+ }
70
+
71
+ mapSetPlayer(removedItemsMap, player, removedItems);
72
+
73
+ const removedTrinkets: TrinketType[] = [];
74
+ for (const trinketToRemove of TRINKETS_THAT_AFFECT_ITEM_POOLS) {
75
+ if (player.HasTrinket(trinketToRemove)) {
76
+ const numTrinkets = player.GetTrinketMultiplier(trinketToRemove);
77
+ repeat(numTrinkets, () => {
78
+ player.TryRemoveTrinket(trinketToRemove);
79
+ removedTrinkets.push(trinketToRemove);
80
+ });
81
+ }
82
+ }
83
+
84
+ mapSetPlayer(removedTrinketsMap, player, removedTrinkets);
85
+ }
86
+
87
+ // Blacklist every collectible in the game except for the provided collectible.
88
+ const itemPool = game.GetItemPool();
89
+ const collectibleSet = getCollectibleSet();
90
+ for (const collectibleType of collectibleSet.values()) {
91
+ if (collectibleType !== collectibleTypeToCheckFor) {
92
+ itemPool.AddRoomBlacklist(collectibleType);
93
+ }
94
+ }
95
+
96
+ // Get a collectible from the pool and see if it is the intended collectible. (We can use any
97
+ // arbitrary value as the seed since it should not influence the result.)
98
+ const retrievedCollectibleType = itemPool.GetCollectible(
99
+ itemPoolToCheckFor,
100
+ false,
101
+ 1 as Seed,
102
+ );
103
+
104
+ const collectibleUnlocked =
105
+ retrievedCollectibleType === collectibleTypeToCheckFor;
106
+
107
+ // Reset the blacklist
108
+ itemPool.ResetRoomBlacklist();
109
+
110
+ // Give back items/trinkets, if necessary.
111
+ for (const player of getPlayers()) {
112
+ const removedItems = mapGetPlayer(removedItemsMap, player);
113
+ if (removedItems !== undefined) {
114
+ for (const collectibleType of removedItems) {
115
+ player.AddCollectible(collectibleType, 0, false); // Prevent Chaos from spawning pickups
116
+ }
117
+ }
118
+
119
+ const removedTrinkets = mapGetPlayer(removedTrinketsMap, player);
120
+ if (removedTrinkets !== undefined) {
121
+ for (const trinketType of removedTrinkets) {
122
+ player.AddTrinket(trinketType, false);
123
+ }
124
+ }
125
+ }
126
+
127
+ return collectibleUnlocked;
128
+ }
@@ -0,0 +1,19 @@
1
+ import { game } from "../cachedClasses";
2
+ import { newRNG } from "./rng";
3
+
4
+ /** Alias for the `Seeds.GetStartSeedString` method. */
5
+ export function getStartSeedString(): string {
6
+ const seeds = game.GetSeeds();
7
+ return seeds.GetStartSeedString();
8
+ }
9
+
10
+ /**
11
+ * Helper function to get the next seed value.
12
+ *
13
+ * This function is useful when you are working with seed values directly over RNG objects.
14
+ */
15
+ export function nextSeed(seed: Seed): Seed {
16
+ const rng = newRNG(seed);
17
+ rng.Next();
18
+ return rng.GetSeed();
19
+ }
@@ -0,0 +1,91 @@
1
+ import { CopyableIsaacAPIClassType } from "../enums/private/CopyableIsaacAPIClassType";
2
+ import { SerializationType } from "../enums/SerializationType";
3
+ import { ISAAC_API_CLASS_TYPE_TO_BRAND } from "../objects/isaacAPIClassTypeToBrand";
4
+ import { ISAAC_API_CLASS_TYPE_TO_COPY_FUNCTION } from "../objects/isaacAPIClassTypeToCopyFunction";
5
+ import { SERIALIZED_ISAAC_API_CLASS_TYPE_TO_IDENTITY_FUNCTION } from "../objects/serializedIsaacAPIClassTypeToIdentityFunction";
6
+ import { SerializedIsaacAPIClass } from "../types/private/SerializedIsaacAPIClass";
7
+ import { getIsaacAPIClassName } from "./isaacAPIClass";
8
+ import { isTable, isUserdata } from "./types";
9
+
10
+ export function copyIsaacAPIClass(
11
+ isaacAPIClass: unknown,
12
+ serializationType: SerializationType,
13
+ ): unknown {
14
+ if (!isUserdata(isaacAPIClass)) {
15
+ error(
16
+ `Failed to copy an Isaac API class since the provided object was of type: ${typeof isaacAPIClass}`,
17
+ );
18
+ }
19
+
20
+ const isaacAPIClassType = getIsaacAPIClassName(isaacAPIClass);
21
+ if (isaacAPIClassType === undefined) {
22
+ error(
23
+ "Failed to copy an Isaac API class since it does not have a class type.",
24
+ );
25
+ }
26
+
27
+ const copyableIsaacAPIClassType =
28
+ isaacAPIClassType as CopyableIsaacAPIClassType;
29
+ const copyFunction =
30
+ ISAAC_API_CLASS_TYPE_TO_COPY_FUNCTION[copyableIsaacAPIClassType];
31
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
32
+ if (copyFunction === undefined) {
33
+ error(
34
+ `Failed to copy Isaac API class "${copyableIsaacAPIClassType}" since there is not a defined copy function for this class type.`,
35
+ );
36
+ }
37
+
38
+ return copyFunction(isaacAPIClass, serializationType);
39
+ }
40
+
41
+ /**
42
+ * Deserialization is a special case, so we make a dedicated function for this.
43
+ *
44
+ * There is no need for a corresponding "serializeIsaacAPIClass" function because the
45
+ * "copyIsaacAPIClass" function can handle all serialization types.
46
+ */
47
+ export function deserializeIsaacAPIClass(
48
+ serializedIsaacAPIClass: SerializedIsaacAPIClass,
49
+ ): unknown {
50
+ if (!isTable(serializedIsaacAPIClass)) {
51
+ error(
52
+ `Failed to deserialize an Isaac API class since the provided object was of type: ${typeof serializedIsaacAPIClass}`,
53
+ );
54
+ }
55
+
56
+ const copyableIsaacAPIClassType = getSerializedTableType(
57
+ serializedIsaacAPIClass,
58
+ );
59
+ if (copyableIsaacAPIClassType === undefined) {
60
+ error(
61
+ "Failed to deserialize an API class since a valid class type brand was not found.",
62
+ );
63
+ }
64
+
65
+ const copyFunction =
66
+ ISAAC_API_CLASS_TYPE_TO_COPY_FUNCTION[copyableIsaacAPIClassType];
67
+ return copyFunction(serializedIsaacAPIClass, SerializationType.DESERIALIZE);
68
+ }
69
+
70
+ function getSerializedTableType(
71
+ serializedIsaacAPIClass: SerializedIsaacAPIClass,
72
+ ): CopyableIsaacAPIClassType | undefined {
73
+ for (const [copyableIsaacAPIClassType, serializationBrand] of Object.entries(
74
+ ISAAC_API_CLASS_TYPE_TO_BRAND,
75
+ )) {
76
+ if (serializedIsaacAPIClass.has(serializationBrand)) {
77
+ return copyableIsaacAPIClassType as CopyableIsaacAPIClassType;
78
+ }
79
+ }
80
+
81
+ return undefined;
82
+ }
83
+
84
+ export function isSerializedIsaacAPIClass(
85
+ object: unknown,
86
+ ): object is SerializedIsaacAPIClass {
87
+ const identityFunctions = Object.values(
88
+ SERIALIZED_ISAAC_API_CLASS_TYPE_TO_IDENTITY_FUNCTION,
89
+ );
90
+ return identityFunctions.some((identityFunction) => identityFunction(object));
91
+ }
@@ -0,0 +1,95 @@
1
+ import { getRandomArrayElement } from "./array";
2
+ import { getRandomSeed } from "./rng";
3
+
4
+ /**
5
+ * Helper function to add all of the values in one set to another set. The first set passed will be
6
+ * modified in place.
7
+ *
8
+ * This function is variadic, meaning that you can specify N sets to add to the first set.
9
+ */
10
+ export function addSetsToSet<T>(
11
+ mainSet: Set<T>,
12
+ ...setsToAdd: Array<Set<T> | ReadonlySet<T>>
13
+ ): void {
14
+ for (const set of setsToAdd) {
15
+ for (const value of set.values()) {
16
+ mainSet.add(value);
17
+ }
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Helper function to create a new set that is the composition of two or more sets.
23
+ *
24
+ * This function is variadic, meaning that you can specify N sets.
25
+ */
26
+ export function combineSets<T>(
27
+ ...sets: Array<Set<T> | ReadonlySet<T>>
28
+ ): Set<T> {
29
+ const newSet = new Set<T>();
30
+ for (const set of sets) {
31
+ for (const value of set.values()) {
32
+ newSet.add(value);
33
+ }
34
+ }
35
+
36
+ return newSet;
37
+ }
38
+
39
+ /** Helper function to copy a set. (You can also use a Set constructor to accomplish this task.) */
40
+ export function copySet<T>(oldSet: Set<T> | ReadonlySet<T>): Set<T> {
41
+ const newSet = new Set<T>();
42
+ for (const value of oldSet.values()) {
43
+ newSet.add(value);
44
+ }
45
+
46
+ return newSet;
47
+ }
48
+
49
+ /**
50
+ * Helper function to delete all of the values in one set from another set. The first set passed
51
+ * will be modified in place.
52
+ *
53
+ * This function is variadic, meaning that you can specify N sets to remove from the first set.
54
+ */
55
+ export function deleteSetsFromSet<T>(
56
+ mainSet: Set<T>,
57
+ ...setsToRemove: Array<Set<T> | ReadonlySet<T>>
58
+ ): void {
59
+ for (const set of setsToRemove) {
60
+ for (const value of set.values()) {
61
+ mainSet.delete(value);
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Helper function to get a random element from the provided set.
68
+ *
69
+ * @param set The set to get an element from.
70
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
71
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
72
+ * @param exceptions Optional. An array of elements to skip over if selected.
73
+ */
74
+ export function getRandomSetElement<T>(
75
+ set: Set<T> | ReadonlySet<T>,
76
+ seedOrRNG: Seed | RNG = getRandomSeed(),
77
+ exceptions: T[] | readonly T[] = [],
78
+ ): T {
79
+ const array = getSortedSetValues(set);
80
+ return getRandomArrayElement(array, seedOrRNG, exceptions);
81
+ }
82
+
83
+ /**
84
+ * Helper function to get a sorted array based on the contents of a set.
85
+ *
86
+ * Normally, set values are returned in a random order, so use this function when the ordering of
87
+ * the contents is important.
88
+ */
89
+ export function getSortedSetValues<T>(set: Set<T> | ReadonlySet<T>): T[] {
90
+ const values = set.values();
91
+ const array = [...values];
92
+ array.sort();
93
+
94
+ return array;
95
+ }
@@ -0,0 +1,9 @@
1
+ import { SoundEffect } from "isaac-typescript-definitions";
2
+ import { sfxManager } from "../cachedClasses";
3
+ import { getEnumValues } from "./enums";
4
+
5
+ export function stopAllSoundEffects(): void {
6
+ for (const soundEffect of getEnumValues(SoundEffect)) {
7
+ sfxManager.Stop(soundEffect);
8
+ }
9
+ }
@@ -0,0 +1,104 @@
1
+ import {
2
+ CollectibleType,
3
+ PickupPrice,
4
+ PickupVariant,
5
+ PlayerType,
6
+ } from "isaac-typescript-definitions";
7
+ import { VectorZero } from "../constants";
8
+ import { preventCollectibleRotation } from "../features/preventCollectibleRotation";
9
+ import { areFeaturesInitialized } from "../featuresInitialized";
10
+ import { setCollectibleEmpty } from "./collectibles";
11
+ import { isQuestCollectible } from "./collectibleTag";
12
+ import { spawnPickupWithSeed } from "./entitySpecific";
13
+ import { anyPlayerIs } from "./player";
14
+ import { getRandomSeed, isRNG } from "./rng";
15
+
16
+ /**
17
+ * Helper function to spawn a collectible. Use this instead of the `Game.Spawn` method because it
18
+ * handles the cases of Tainted Keeper collectibles costing coins and preventing quest items from
19
+ * being rotated by Tainted Isaac's rotation mechanic. (Rotation prevention will only occur in
20
+ * upgraded mods.)
21
+ *
22
+ * @param collectibleType The collectible type to spawn.
23
+ * @param position The position to spawn the collectible at.
24
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
25
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
26
+ * @param options Optional. Set to true to make the collectible a "There's Options" style
27
+ * collectible. Default is false.
28
+ * @param forceFreeItem Optional. Set to true to disable the logic that gives the item a price for
29
+ * Tainted Keeper. Default is false.
30
+ * @param spawner Optional.
31
+ */
32
+ export function spawnCollectible(
33
+ collectibleType: CollectibleType,
34
+ position: Vector,
35
+ seedOrRNG: Seed | RNG = getRandomSeed(),
36
+ options = false,
37
+ forceFreeItem = false,
38
+ spawner?: Entity,
39
+ ): EntityPickupCollectible {
40
+ const seed = isRNG(seedOrRNG) ? seedOrRNG.Next() : seedOrRNG;
41
+ const collectible = spawnPickupWithSeed(
42
+ PickupVariant.COLLECTIBLE,
43
+ collectibleType,
44
+ position,
45
+ seed,
46
+ VectorZero,
47
+ spawner,
48
+ ) as EntityPickupCollectible;
49
+
50
+ if (options) {
51
+ collectible.OptionsPickupIndex = 1;
52
+ }
53
+
54
+ if (
55
+ anyPlayerIs(PlayerType.KEEPER_B) &&
56
+ !isQuestCollectible(collectibleType) &&
57
+ !forceFreeItem
58
+ ) {
59
+ // When playing Tainted Keeper, collectibles are supposed to have a price, and manually spawned
60
+ // items will not have a price, so we have to set it manually.
61
+
62
+ // Setting the shop item ID in this way prevents the bug where the item will sometimes change to
63
+ // 99 cents.
64
+ collectible.ShopItemId = -1;
65
+
66
+ // We can set the price to any arbitrary value; it will auto-update to the true price on the
67
+ // next frame.
68
+ collectible.Price = 15 as PickupPrice;
69
+ }
70
+
71
+ if (isQuestCollectible(collectibleType) && areFeaturesInitialized()) {
72
+ preventCollectibleRotation(collectible, collectibleType);
73
+ }
74
+
75
+ return collectible;
76
+ }
77
+
78
+ /**
79
+ * Helper function to spawn an empty collectible. Doing this is tricky since spawning a collectible
80
+ * with `CollectibleType.NULL` will result in spawning a collectible with a random type from the
81
+ * current room's item pool.
82
+ *
83
+ * Instead, this function arbitrarily spawns a collectible with `CollectibleType.SAD_ONION`, and
84
+ * then converts it to an empty pedestal afterward.
85
+ *
86
+ * @param position The position to spawn the empty collectible at.
87
+ * @param seedOrRNG The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
88
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
89
+ */
90
+ export function spawnEmptyCollectible(
91
+ position: Vector,
92
+ seedOrRNG: Seed | RNG = getRandomSeed(),
93
+ ): EntityPickup {
94
+ const collectible = spawnCollectible(
95
+ CollectibleType.SAD_ONION,
96
+ position,
97
+ seedOrRNG,
98
+ false,
99
+ true,
100
+ );
101
+ setCollectibleEmpty(collectible);
102
+
103
+ return collectible;
104
+ }
@@ -0,0 +1,107 @@
1
+ import { EMPTY_PNG_PATH, VectorZero } from "../constants";
2
+ import { kColorEquals } from "./kColor";
3
+ import { erange } from "./utils";
4
+
5
+ /**
6
+ * Helper function to clear a specific layer from a sprite.
7
+ *
8
+ * This function is variadic, so pass as many layer IDs as you want to clear. If no specific layers
9
+ * are passed, it will clear every layer.
10
+ *
11
+ * Since there is no official API method to "clear" a sprite, we can work around it by setting the
12
+ * spritesheet to a non-existent or completely transparent file. If the path to the spritesheet does
13
+ * not exist, then this function might cause spurious errors to appear in the "log.txt file". To
14
+ * silence these errors, create a transparent 1 pixel PNG file in your mod's resources folder at the
15
+ * path corresponding to the "EMPTY_PNG_PATH" constant.
16
+ */
17
+ export function clearSprite(sprite: Sprite, ...layerIDs: int[]): void {
18
+ if (layerIDs.length === 0) {
19
+ const numLayers = sprite.GetLayerCount();
20
+ layerIDs = erange(numLayers);
21
+ }
22
+
23
+ for (const layerID of layerIDs) {
24
+ sprite.ReplaceSpritesheet(layerID, EMPTY_PNG_PATH);
25
+ }
26
+
27
+ sprite.LoadGraphics();
28
+ }
29
+
30
+ /**
31
+ * Helper function that returns the number of the final frame in a particular animation for a
32
+ * sprite. By default, it will use the currently playing animation, but you can also specify a
33
+ * specific animation to check.
34
+ *
35
+ * Note that this function is bugged with the Stop Watch or the Broken Watch, since using the
36
+ * `Sprite.SetFrame` method will reset the internal accumulator used to slow down the playback speed
37
+ * of the animation. (The `PlaybackSpeed` property of the sprite is not used.) Thus, it is only safe
38
+ * to use this function on animations that are not slowed down by Stop Watch or Broken Watch, such
39
+ * as player animations.
40
+ */
41
+ export function getLastFrameOfAnimation(
42
+ sprite: Sprite,
43
+ animation?: string,
44
+ ): int {
45
+ // Record the current sprite status.
46
+ const currentAnimation = sprite.GetAnimation();
47
+ const currentFrame = sprite.GetFrame();
48
+
49
+ // Get the final frame.
50
+ if (animation !== undefined && animation !== currentAnimation) {
51
+ sprite.SetAnimation(animation);
52
+ }
53
+ sprite.SetLastFrame();
54
+ const finalFrame = sprite.GetFrame();
55
+
56
+ // Set the sprite back to the way it was.
57
+ if (animation !== undefined && animation !== currentAnimation) {
58
+ sprite.Play(currentAnimation, true);
59
+ }
60
+ sprite.SetFrame(currentFrame);
61
+
62
+ return finalFrame;
63
+ }
64
+
65
+ /**
66
+ * Helper function to check if two sprite layers have the same sprite sheet by using the
67
+ * `Sprite.GetTexel` method.
68
+ *
69
+ * Since checking every single texel in the entire sprite is very expensive, this function requires
70
+ * that you provide a range of specific texels to check.
71
+ */
72
+ export function spriteEquals(
73
+ sprite1: Sprite,
74
+ sprite2: Sprite,
75
+ layerID: int,
76
+ xStart: int,
77
+ xFinish: int,
78
+ xIncrement: int,
79
+ yStart: int,
80
+ yFinish: int,
81
+ yIncrement: int,
82
+ ): boolean {
83
+ // Iterate over N texels, checking for equality at each step. The center of the sprite is equal to
84
+ // the "pivot" point in the anm2 file.
85
+ for (let x = xStart; x <= xFinish; x += xIncrement) {
86
+ for (let y = yStart; y <= yFinish; y += yIncrement) {
87
+ const position = Vector(x, y);
88
+ if (!texelEquals(sprite1, sprite2, position, layerID)) {
89
+ return false;
90
+ }
91
+ }
92
+ }
93
+
94
+ return true;
95
+ }
96
+
97
+ /** Helper function to check if two texels on a sprite are equivalent to each other. */
98
+ export function texelEquals(
99
+ sprite1: Sprite,
100
+ sprite2: Sprite,
101
+ position: Vector,
102
+ layerID: int,
103
+ ): boolean {
104
+ const kColor1 = sprite1.GetTexel(position, VectorZero, 1, layerID);
105
+ const kColor2 = sprite2.GetTexel(position, VectorZero, 1, layerID);
106
+ return kColorEquals(kColor1, kColor2);
107
+ }
@@ -0,0 +1,125 @@
1
+ import { LevelStage, StageType } from "isaac-typescript-definitions";
2
+ import { game } from "../cachedClasses";
3
+ import { STAGE_TYPE_TO_LETTER } from "../objects/stageTypeToLetter";
4
+
5
+ /**
6
+ * Helper function to account for Repentance floors being offset by 1. For example, Downpour 2 is
7
+ * the third level of the run, but the game considers it to have a stage of 2. This function will
8
+ * consider Downpour 2 to have a stage of 3.
9
+ */
10
+ export function getEffectiveStage(): int {
11
+ const level = game.GetLevel();
12
+ const stage = level.GetStage();
13
+
14
+ if (onRepentanceStage()) {
15
+ return stage + 1; // eslint-disable-line isaacscript/strict-enums
16
+ }
17
+
18
+ return stage;
19
+ }
20
+
21
+ /** Alias for the `Level.GetStage` method. */
22
+ export function getStage(): LevelStage {
23
+ const level = game.GetLevel();
24
+
25
+ return level.GetStage();
26
+ }
27
+
28
+ /** Alias for the `Level.GetStageType` method. */
29
+ export function getStageType(): StageType {
30
+ const level = game.GetLevel();
31
+
32
+ return level.GetStageType();
33
+ }
34
+
35
+ /** Helper function to directly warp to a specific stage using the "stage" console command. */
36
+ export function goToStage(stage: LevelStage, stageType: StageType): void {
37
+ const stageTypeLetterSuffix = stageTypeToLetter(stageType);
38
+ const command = `stage ${stage}${stageTypeLetterSuffix}`;
39
+ Isaac.ExecuteCommand(command);
40
+ }
41
+
42
+ export function isRepentanceStage(stageType: StageType): boolean {
43
+ return (
44
+ stageType === StageType.REPENTANCE || stageType === StageType.REPENTANCE_B
45
+ );
46
+ }
47
+
48
+ export function onCathedral(): boolean {
49
+ const level = game.GetLevel();
50
+ const stage = level.GetStage();
51
+ const stageType = level.GetStageType();
52
+
53
+ return (
54
+ stage === LevelStage.SHEOL_CATHEDRAL &&
55
+ stageType === StageType.WRATH_OF_THE_LAMB
56
+ );
57
+ }
58
+
59
+ export function onChest(): boolean {
60
+ const level = game.GetLevel();
61
+ const stage = level.GetStage();
62
+ const stageType = level.GetStageType();
63
+
64
+ return (
65
+ stage === LevelStage.DARK_ROOM_CHEST &&
66
+ stageType === StageType.WRATH_OF_THE_LAMB
67
+ );
68
+ }
69
+
70
+ export function onDarkRoom(): boolean {
71
+ const level = game.GetLevel();
72
+ const stage = level.GetStage();
73
+ const stageType = level.GetStageType();
74
+
75
+ return (
76
+ stage === LevelStage.DARK_ROOM_CHEST && stageType === StageType.ORIGINAL
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Returns whether or not the player is on the "final floor" of the particular run. The final floor
82
+ * is defined as one that prevents the player from entering the I AM ERROR room on.
83
+ *
84
+ * For example, when using Undefined on The Chest, it has a 50% chance of teleporting the player to
85
+ * the Secret Room and a 50% chance of teleporting the player to the Super Secret Room, because the
86
+ * I AM ERROR room is never entered into the list of possibilities.
87
+ */
88
+ export function onFinalFloor(): boolean {
89
+ const level = game.GetLevel();
90
+ const stage = level.GetStage();
91
+
92
+ return (
93
+ stage === LevelStage.DARK_ROOM_CHEST ||
94
+ stage === LevelStage.THE_VOID ||
95
+ stage === LevelStage.HOME ||
96
+ (stage === LevelStage.WOMB_2 && onRepentanceStage()) // Corpse 2
97
+ );
98
+ }
99
+
100
+ export function onRepentanceStage(): boolean {
101
+ const level = game.GetLevel();
102
+ const stageType = level.GetStageType();
103
+
104
+ return isRepentanceStage(stageType);
105
+ }
106
+
107
+ export function onSheol(): boolean {
108
+ const level = game.GetLevel();
109
+ const stage = level.GetStage();
110
+ const stageType = level.GetStageType();
111
+
112
+ return (
113
+ stage === LevelStage.SHEOL_CATHEDRAL && stageType === StageType.ORIGINAL
114
+ );
115
+ }
116
+
117
+ /**
118
+ * Helper function to convert a numerical `StageType` into the letter suffix supplied to the "stage"
119
+ * console command. For example, `StageType.REPENTANCE` is the stage type for Downpour, and the
120
+ * console command to go to Downpour is "stage 1c", so this function converts `StageType.REPENTANCE`
121
+ * to "c".
122
+ */
123
+ export function stageTypeToLetter(stageType: StageType): string {
124
+ return STAGE_TYPE_TO_LETTER[stageType];
125
+ }