isaacscript-common 6.6.1-dev.1 → 6.6.1-dev.2

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