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,532 @@
1
+ // Basement Renovator can create custom rooms that are saved to XML files. These XML files can be
2
+ // converted to JSON so that they can be imported by TypeScript code. Then, existing rooms can be
3
+ // manually replaced with a custom room by manually removing everything in the room and rebuilding
4
+ // it from scratch based on the JSON data.
5
+ import { CollectibleType, EffectVariant, EntityCollisionClass, EntityFlag, EntityGridCollisionClass, EntityType, GridEntityType, ModCallback, PickupVariant, PitfallVariant, RoomType, } from "isaac-typescript-definitions";
6
+ import { game } from "../cachedClasses";
7
+ import { DefaultMap } from "../classes/DefaultMap";
8
+ import { ModCallbackCustom } from "../enums/ModCallbackCustom";
9
+ import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
10
+ import { emptyArray } from "../functions/array";
11
+ import { getEntityIDFromConstituents, removeAllMatchingEntities, spawn, spawnWithSeed, } from "../functions/entity";
12
+ import { getNPCs, removeAllBombs, removeAllPickups, } from "../functions/entitySpecific";
13
+ import { convertXMLGridEntityType, getAllGridIndexes, getGridEntities, getGridEntityIDFromConstituents, removeAllGridExcept, removeGrid, setGridEntityInvisible, spawnGridWithVariant, } from "../functions/gridEntity";
14
+ import { getRandomJSONRoom } from "../functions/jsonRoom";
15
+ import { log } from "../functions/log";
16
+ import { getRandomSeed, isRNG, newRNG } from "../functions/rng";
17
+ import { getRoomListIndex } from "../functions/roomData";
18
+ import { gridCoordinatesToWorldPosition } from "../functions/roomGrid";
19
+ import { setRoomCleared, setRoomUncleared } from "../functions/rooms";
20
+ import { spawnCollectible } from "../functions/spawnCollectible";
21
+ import { runNextGameFrame } from "./runInNFrames";
22
+ import { saveDataManager } from "./saveDataManager/exports";
23
+ const FEATURE_NAME = "deployJSONRoom";
24
+ const NPC_TYPES_TO_NOT_REMOVE = new Set([
25
+ EntityType.DARK_ESAU,
26
+ ]);
27
+ const PERSISTENT_ENTITY_TYPES = new Set([
28
+ EntityType.WALL_HUGGER,
29
+ ]);
30
+ const v = {
31
+ level: {
32
+ deployedRoomListIndexes: new Set(),
33
+ /** Indexed by room list index. */
34
+ roomToPersistentEntitiesMap: new DefaultMap(() => []),
35
+ /** Indexed by room list index. */
36
+ roomToDecorationGridIndexesMap: new DefaultMap(() => []),
37
+ },
38
+ room: {
39
+ manuallyUsingShovel: false,
40
+ },
41
+ };
42
+ /** @internal */
43
+ export function deployJSONRoomInit(mod) {
44
+ saveDataManager(FEATURE_NAME, v);
45
+ mod.AddCallback(ModCallback.PRE_USE_ITEM, preUseItemWeNeedToGoDeeper, CollectibleType.WE_NEED_TO_GO_DEEPER); // 23
46
+ mod.AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_REORDERED, postNewRoomReordered);
47
+ }
48
+ // ModCallback.PRE_USE_ITEM (23)
49
+ // CollectibleType.WE_NEED_TO_GO_DEEPER (84)
50
+ function preUseItemWeNeedToGoDeeper(_collectibleType, _rng, player) {
51
+ if (v.room.manuallyUsingShovel) {
52
+ return undefined;
53
+ }
54
+ const roomListIndex = getRoomListIndex();
55
+ if (!v.level.deployedRoomListIndexes.has(roomListIndex)) {
56
+ return undefined;
57
+ }
58
+ // If the player uses the shovel in a JSON room, then it will always reveal a crawl space. This is
59
+ // because the room is filled with invisible decorations to prevent any grid entities from
60
+ // respawning. In order to restore the normal shovel functionality, we cancel the shovel use,
61
+ // remove all the decorations, wait a frame, manually use the shovel again, and then respawn the
62
+ // decorations. (We can't do it all on this frame because updating the room causes two invocations
63
+ // of the shovel to happen.)
64
+ const decorations = getGridEntities(GridEntityType.DECORATION);
65
+ for (const decoration of decorations) {
66
+ removeGrid(decoration, false);
67
+ }
68
+ const playerPtr = EntityPtr(player);
69
+ runNextGameFrame(() => {
70
+ const futureEntity = playerPtr.Ref;
71
+ if (futureEntity === undefined) {
72
+ return;
73
+ }
74
+ const futurePlayer = futureEntity.ToPlayer();
75
+ if (futurePlayer === undefined) {
76
+ return;
77
+ }
78
+ v.room.manuallyUsingShovel = true;
79
+ futurePlayer.UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER);
80
+ v.room.manuallyUsingShovel = false;
81
+ const decorationGridIndexes = v.level.roomToDecorationGridIndexesMap.getAndSetDefault(roomListIndex);
82
+ emptyArray(decorationGridIndexes);
83
+ fillRoomWithDecorations();
84
+ });
85
+ // Cancel the effect.
86
+ return true;
87
+ }
88
+ // ModCallbackCustom.POST_NEW_ROOM_REORDERED
89
+ function postNewRoomReordered() {
90
+ const roomListIndex = getRoomListIndex();
91
+ if (!v.level.deployedRoomListIndexes.has(roomListIndex)) {
92
+ return;
93
+ }
94
+ setDecorationsInvisible();
95
+ respawnPersistentEntities();
96
+ }
97
+ /**
98
+ * Every time we re-enter a deployed room, the sprites for all of the decorations will come back, so
99
+ * we have to remove them again.
100
+ */
101
+ function setDecorationsInvisible() {
102
+ const room = game.GetRoom();
103
+ const roomListIndex = getRoomListIndex();
104
+ const decorationGridIndexes = v.level.roomToDecorationGridIndexesMap.getAndSetDefault(roomListIndex);
105
+ for (const gridIndex of decorationGridIndexes) {
106
+ const gridEntity = room.GetGridEntity(gridIndex);
107
+ if (gridEntity !== undefined) {
108
+ // Other grid entities may have spawned, like trapdoors or crawl spaces. Thus, only make
109
+ // decorations invisible.
110
+ const gridEntityType = gridEntity.GetType();
111
+ if (gridEntityType === GridEntityType.DECORATION) {
112
+ setGridEntityInvisible(gridEntity);
113
+ }
114
+ }
115
+ }
116
+ }
117
+ /** Some entities must be manually respawned every time the player re-enters the room. */
118
+ function respawnPersistentEntities() {
119
+ const room = game.GetRoom();
120
+ const roomListIndex = getRoomListIndex();
121
+ const persistentEntities = v.level.roomToPersistentEntitiesMap.getAndSetDefault(roomListIndex);
122
+ for (const persistentEntity of persistentEntities) {
123
+ const position = room.GetGridPosition(persistentEntity.gridIndex);
124
+ spawn(persistentEntity.entityType, persistentEntity.variant, persistentEntity.subType, position);
125
+ }
126
+ }
127
+ /**
128
+ * Helper function to deconstruct a vanilla room and set up a custom room in its place.
129
+ * Specifically, this will clear the current room of all entities and grid entities, and then spawn
130
+ * all of the entries and grid entities in the provided JSON room.
131
+ *
132
+ * This function is meant to be used in the PostNewRoom callback.
133
+ *
134
+ * For example:
135
+ *
136
+ * ```ts
137
+ *
138
+ * import customRooms from "./customRooms";
139
+ *
140
+ * const firstJSONRoom = customRooms.rooms.room[0];
141
+ * deployJSONRoom(firstJSONRoom);
142
+ * ```
143
+ *
144
+ * @param jsonRoom The JSON room to deploy. *
145
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
146
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
147
+ * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
148
+ * what the function is doing. Default is false.
149
+ */
150
+ export function deployJSONRoom(jsonRoom, seedOrRNG = getRandomSeed(), verbose = false) {
151
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
152
+ const rng = isRNG(seedOrRNG) ? seedOrRNG : newRNG(seedOrRNG);
153
+ if (verbose) {
154
+ log("Starting to empty the room of entities and grid entities.");
155
+ }
156
+ emptyRoom(false);
157
+ if (verbose) {
158
+ log("Finished emptying the room of entities and grid entities.");
159
+ }
160
+ if (verbose) {
161
+ log("Starting to spawn all of the new entities and grid entities.");
162
+ }
163
+ spawnAllEntities(jsonRoom, rng, verbose);
164
+ if (verbose) {
165
+ log("Finished spawning all of the new entities and grid entities.");
166
+ }
167
+ fixPitGraphics();
168
+ fillRoomWithDecorations();
169
+ }
170
+ /**
171
+ * Helper function to deconstruct a vanilla room and set up a custom room in its place.
172
+ * Specifically, this will clear the current room of all entities and grid entities, and then spawn
173
+ * all of the entries and grid entities in one of the provided JSON rooms.
174
+ *
175
+ * This function is meant to be used in the PostNewRoom callback.
176
+ *
177
+ * Note that this function does not simply choose a random element in the provided array; it will
178
+ * properly account for each room weight using the algorithm from:
179
+ * https://stackoverflow.com/questions/1761626/weighted-random-numbers
180
+ *
181
+ * For example:
182
+ *
183
+ * ```ts
184
+ * import customRooms from "./customRooms";
185
+ *
186
+ * const jsonRooms = customRooms.rooms.room;
187
+ * deployRandomJSONRoom(jsonRooms);
188
+ * ```
189
+ *
190
+ * @param jsonRooms An array of JSON rooms to randomly select from. In practice, this will be
191
+ * something like.
192
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
193
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
194
+ * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
195
+ * what the function is doing. Default is false.
196
+ */
197
+ export function deployRandomJSONRoom(jsonRooms, seedOrRNG = getRandomSeed(), verbose = false) {
198
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
199
+ const rng = isRNG(seedOrRNG) ? seedOrRNG : newRNG(seedOrRNG);
200
+ const randomJSONRoom = getRandomJSONRoom(jsonRooms, rng, verbose);
201
+ if (verbose) {
202
+ log(`Randomly chose JSON room ${randomJSONRoom.$.type}.${randomJSONRoom.$.variant}.${randomJSONRoom.$.subtype} with name: ${randomJSONRoom.$.name}`);
203
+ }
204
+ return deployJSONRoom(randomJSONRoom, rng, verbose);
205
+ }
206
+ /**
207
+ * Helper function to remove all naturally spawning entities and grid entities from a room. Notably,
208
+ * this will not remove players (1), tears (2), familiars (3), lasers (7), knives (8), projectiles
209
+ * (9), blacklisted NPCs such as Dark Esau, charmed NPCs, friendly NPCs, persistent NPCs, most
210
+ * effects (1000), doors, and walls.
211
+ *
212
+ * @param fillWithDecorations Optional. Set to true to fill every grid tile with an invisible
213
+ * decoration, which prevents vanilla entities in the room from
214
+ * respawning the next time that the player enters. Default is false.
215
+ */
216
+ export function emptyRoom(fillWithDecorations) {
217
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
218
+ const roomListIndex = getRoomListIndex();
219
+ v.level.deployedRoomListIndexes.add(roomListIndex);
220
+ removeAllBombs(); // 4
221
+ removeAllPickups(); // 5
222
+ removeAllMatchingEntities(EntityType.SLOT); // 6
223
+ removeSpecificNPCs();
224
+ removeAllMatchingEntities(EntityType.EFFECT, EffectVariant.DEVIL);
225
+ removeAllMatchingEntities(EntityType.EFFECT, EffectVariant.ANGEL);
226
+ removeAllGridExcept(GridEntityType.WALL, // 15
227
+ GridEntityType.DOOR);
228
+ setRoomCleared();
229
+ if (fillWithDecorations) {
230
+ fillRoomWithDecorations();
231
+ }
232
+ }
233
+ /**
234
+ * We remove entities in the PostNewRoom callback instead of in the PreRoomEntitySpawn callback so
235
+ * that they will not re-appear when we re-enter the room.
236
+ */
237
+ function removeSpecificNPCs() {
238
+ const room = game.GetRoom();
239
+ for (const npc of getNPCs()) {
240
+ if (NPC_TYPES_TO_NOT_REMOVE.has(npc.Type)) {
241
+ continue;
242
+ }
243
+ if (npc.HasEntityFlags(EntityFlag.CHARM) ||
244
+ npc.HasEntityFlags(EntityFlag.FRIENDLY) ||
245
+ npc.HasEntityFlags(EntityFlag.PERSISTENT)) {
246
+ continue;
247
+ }
248
+ npc.ClearEntityFlags(EntityFlag.APPEAR);
249
+ npc.Remove();
250
+ // When fire places are removed, they will leave behind a "path" that will prevent future grid
251
+ // entities from being spawned on the same tile. Thus, reset the path for this tile if this is a
252
+ // fire place.
253
+ if (npc.Type === EntityType.FIREPLACE) {
254
+ const gridIndex = room.GetGridIndex(npc.Position);
255
+ room.SetGridPath(gridIndex, 0);
256
+ }
257
+ }
258
+ }
259
+ /**
260
+ * We removed most normal entities, which should prevent them from respawning when the player
261
+ * re-enters the room. However, this is not the case for grid entities; even if they are removed,
262
+ * they will come back when the player re-enters the room.
263
+ *
264
+ * In order to prevent this from happening, we can spawn a grid entity on every tile that does not
265
+ * already have a grid entity. The natural grid entity to choose for this purpose is a decoration,
266
+ * since it is non-interacting.
267
+ *
268
+ * Another option besides decorations would be to use a pressure plates with a state of 1, which is
269
+ * a state that is normally unused by the game and makes it invisible & persistent. However, pickups
270
+ * will not be able to spawn on pressure plates, which lead to various bugs (e.g. pickups spawning
271
+ * on top of pits). Thus, we use a decoration and remove its sprite to make it invisible.
272
+ *
273
+ * Yet another option is to replace the room data with that of an empty room. However, the room data
274
+ * must exactly match the room type, the room shape, and the doors, so this is not possible to do in
275
+ * a robust way without adding empty rooms to the mod's `content` folder to draw the data from.
276
+ */
277
+ function fillRoomWithDecorations() {
278
+ const room = game.GetRoom();
279
+ const roomListIndex = getRoomListIndex();
280
+ const decorationGridIndexes = v.level.roomToDecorationGridIndexesMap.getAndSetDefault(roomListIndex);
281
+ for (const gridIndex of getAllGridIndexes()) {
282
+ const existingGridEntity = room.GetGridEntity(gridIndex);
283
+ if (existingGridEntity !== undefined) {
284
+ continue;
285
+ }
286
+ const position = room.GetGridPosition(gridIndex);
287
+ const decoration = Isaac.GridSpawn(GridEntityType.DECORATION, 0, position);
288
+ if (decoration !== undefined) {
289
+ setGridEntityInvisible(decoration);
290
+ }
291
+ decorationGridIndexes.push(gridIndex);
292
+ }
293
+ }
294
+ function spawnAllEntities(jsonRoom, rng, verbose = false) {
295
+ let shouldUnclearRoom = false;
296
+ for (const jsonSpawn of jsonRoom.spawn) {
297
+ const xString = jsonSpawn.$.x;
298
+ const x = tonumber(xString);
299
+ if (x === undefined) {
300
+ error(`Failed to convert the following x coordinate to a number (for a spawn): ${xString}`);
301
+ }
302
+ const yString = jsonSpawn.$.y;
303
+ const y = tonumber(yString);
304
+ if (y === undefined) {
305
+ error(`Failed to convert the following y coordinate to a number (for a spawn): ${yString}`);
306
+ }
307
+ if (jsonSpawn.entity.length > 1) {
308
+ error("Stacked entities are not implemented for JSON rooms.");
309
+ }
310
+ const firstXMLEntity = jsonSpawn.entity[0];
311
+ if (firstXMLEntity === undefined) {
312
+ error('Failed to get the first JSON entity from an "entity" array.');
313
+ }
314
+ const entityTypeString = firstXMLEntity.$.type;
315
+ const entityType = tonumber(entityTypeString);
316
+ if (entityType === undefined) {
317
+ error(`Failed to convert the entity type to a number: ${entityTypeString}`);
318
+ }
319
+ const variantString = firstXMLEntity.$.variant;
320
+ const variant = tonumber(variantString);
321
+ if (variant === undefined) {
322
+ error(`Failed to convert the entity variant to a number: ${variant}`);
323
+ }
324
+ const subTypeString = firstXMLEntity.$.subtype;
325
+ const subType = tonumber(subTypeString);
326
+ if (subType === undefined) {
327
+ error(`Failed to convert the entity sub-type to a number: ${subType}`);
328
+ }
329
+ // Note that XML entity type 1000 is a rock, not an effect.
330
+ if (entityType >= 1000) {
331
+ if (verbose) {
332
+ const gridEntityID = getGridEntityIDFromConstituents(entityType, variant);
333
+ log(`Spawning grid entity ${gridEntityID} at: (${x}, ${y})`);
334
+ }
335
+ spawnGridEntityForJSONRoom(entityType, variant, x, y);
336
+ }
337
+ else {
338
+ if (verbose) {
339
+ const entityID = getEntityIDFromConstituents(entityType, variant, subType);
340
+ log(`Spawning normal entity ${entityID} at: (${x}, ${y})`);
341
+ }
342
+ const entity = spawnNormalEntityForJSONRoom(entityType, variant, subType, x, y, rng);
343
+ const npc = entity.ToNPC();
344
+ if (npc !== undefined && npc.CanShutDoors) {
345
+ shouldUnclearRoom = true;
346
+ }
347
+ }
348
+ }
349
+ // After emptying the room, we manually cleared the room. However, if the room layout contains an
350
+ // battle NPC, then we need to reset the clear state and close the doors again.
351
+ if (shouldUnclearRoom) {
352
+ if (verbose) {
353
+ log("Setting the room to be uncleared since there were one or more battle NPCs spawned.");
354
+ }
355
+ setRoomUncleared();
356
+ }
357
+ else if (verbose) {
358
+ log("Leaving the room cleared since there were no battle NPCs spawned.");
359
+ }
360
+ }
361
+ function spawnGridEntityForJSONRoom(gridEntityXMLType, gridEntityXMLVariant, x, y) {
362
+ const room = game.GetRoom();
363
+ const gridEntityTuple = convertXMLGridEntityType(gridEntityXMLType, gridEntityXMLVariant);
364
+ if (gridEntityTuple === undefined) {
365
+ return undefined;
366
+ }
367
+ const [gridEntityType, variant] = gridEntityTuple;
368
+ const position = gridCoordinatesToWorldPosition(x, y);
369
+ const gridIndex = room.GetGridIndex(position);
370
+ const gridEntity = spawnGridWithVariant(gridEntityType, variant, gridIndex);
371
+ if (gridEntity === undefined) {
372
+ return gridEntity;
373
+ }
374
+ // Prevent poops from playing an appear animation, since that is not supposed to normally happen
375
+ // when entering a new room.
376
+ if (gridEntityType === GridEntityType.POOP) {
377
+ const sprite = gridEntity.GetSprite();
378
+ sprite.Play("State1", true);
379
+ sprite.SetLastFrame();
380
+ }
381
+ return gridEntity;
382
+ }
383
+ function spawnNormalEntityForJSONRoom(entityType, variant, subType, x, y, rng) {
384
+ const room = game.GetRoom();
385
+ const roomType = room.GetType();
386
+ const position = gridCoordinatesToWorldPosition(x, y);
387
+ const seed = rng.Next();
388
+ let entity;
389
+ if (entityType === EntityType.PICKUP &&
390
+ variant === PickupVariant.COLLECTIBLE) {
391
+ const options = roomType === RoomType.ANGEL;
392
+ entity = spawnCollectible(subType, position, seed, options);
393
+ }
394
+ else {
395
+ entity = spawnWithSeed(entityType, variant, subType, position, seed);
396
+ }
397
+ // For some reason, Pitfalls do not spawn with the correct collision classes.
398
+ if (entityType === EntityType.PITFALL &&
399
+ variant === PitfallVariant.PITFALL) {
400
+ entity.EntityCollisionClass = EntityCollisionClass.ENEMIES;
401
+ entity.GridCollisionClass = EntityGridCollisionClass.WALLS;
402
+ }
403
+ storePersistentEntity(entity);
404
+ return entity;
405
+ }
406
+ /**
407
+ * Some entities must be manually respawned every time the player re-enters the room. If we just
408
+ * spawned one such entity, then record it for later.
409
+ */
410
+ function storePersistentEntity(entity) {
411
+ if (!PERSISTENT_ENTITY_TYPES.has(entity.Type)) {
412
+ return;
413
+ }
414
+ const room = game.GetRoom();
415
+ const gridIndex = room.GetGridIndex(entity.Position);
416
+ const roomListIndex = getRoomListIndex();
417
+ const persistentEntity = {
418
+ gridIndex,
419
+ entityType: entity.Type,
420
+ variant: entity.Variant,
421
+ subType: entity.SubType,
422
+ };
423
+ const persistentEntities = v.level.roomToPersistentEntitiesMap.getAndSetDefault(roomListIndex);
424
+ persistentEntities.push(persistentEntity);
425
+ }
426
+ /**
427
+ * By default, when spawning multiple pits next to each other, the graphics will not "meld"
428
+ * together. Thus, now that all of the entities in the room are spawned, we must iterate over the
429
+ * pits in the room and manually fix their sprites, if necessary.
430
+ */
431
+ function fixPitGraphics() {
432
+ const room = game.GetRoom();
433
+ const gridWidth = room.GetGridWidth();
434
+ const pitMap = getPitMap();
435
+ for (const [gridIndex, gridEntity] of pitMap.entries()) {
436
+ const gridIndexLeft = gridIndex - 1;
437
+ const L = pitMap.has(gridIndexLeft);
438
+ const gridIndexRight = gridIndex + 1;
439
+ const R = pitMap.has(gridIndexRight);
440
+ const gridIndexUp = gridIndex - gridWidth;
441
+ const U = pitMap.has(gridIndexUp);
442
+ const gridIndexDown = gridIndex + gridWidth;
443
+ const D = pitMap.has(gridIndexDown);
444
+ const gridIndexUpLeft = gridIndex - gridWidth - 1;
445
+ const UL = pitMap.has(gridIndexUpLeft);
446
+ const gridIndexUpRight = gridIndex - gridWidth + 1;
447
+ const UR = pitMap.has(gridIndexUpRight);
448
+ const gridIndexDownLeft = gridIndex + gridWidth - 1;
449
+ const DL = pitMap.has(gridIndexDownLeft);
450
+ const gridIndexDownRight = gridIndex + gridWidth + 1;
451
+ const DR = pitMap.has(gridIndexDownRight);
452
+ const pitFrame = getPitFrame(L, R, U, D, UL, UR, DL, DR);
453
+ const sprite = gridEntity.GetSprite();
454
+ sprite.SetFrame(pitFrame);
455
+ }
456
+ }
457
+ function getPitMap() {
458
+ const pitMap = new Map();
459
+ for (const gridEntity of getGridEntities(GridEntityType.PIT)) {
460
+ const gridIndex = gridEntity.GetGridIndex();
461
+ pitMap.set(gridIndex, gridEntity);
462
+ }
463
+ return pitMap;
464
+ }
465
+ /** The logic in this function is copied from Basement Renovator. */
466
+ function getPitFrame(L, R, U, D, UL, UR, DL, DR) {
467
+ let F = 0;
468
+ // First, check for bitwise frames. (It works for all combinations of just left/up/right/down.)
469
+ if (L) {
470
+ F |= 1;
471
+ }
472
+ if (U) {
473
+ F |= 2;
474
+ }
475
+ if (R) {
476
+ F |= 4;
477
+ }
478
+ if (D) {
479
+ F |= 8;
480
+ }
481
+ // Then, check for other combinations.
482
+ if (U && L && !UL && !R && !D) {
483
+ F = 17;
484
+ }
485
+ if (U && R && !UR && !L && !D) {
486
+ F = 18;
487
+ }
488
+ if (L && D && !DL && !U && !R) {
489
+ F = 19;
490
+ }
491
+ if (R && D && !DR && !L && !U) {
492
+ F = 20;
493
+ }
494
+ if (L && U && R && D && !UL) {
495
+ F = 21;
496
+ }
497
+ if (L && U && R && D && !UR) {
498
+ F = 22;
499
+ }
500
+ if (U && R && D && !L && !UR) {
501
+ F = 25;
502
+ }
503
+ if (L && U && D && !R && !UL) {
504
+ F = 26;
505
+ }
506
+ if (L && U && R && D && !DL && !DR) {
507
+ F = 24;
508
+ }
509
+ if (L && U && R && D && !UR && !UL) {
510
+ F = 23;
511
+ }
512
+ if (L && U && R && UL && !UR && !D) {
513
+ F = 27;
514
+ }
515
+ if (L && U && R && UR && !UL && !D) {
516
+ F = 28;
517
+ }
518
+ if (L && U && R && !D && !UR && !UL) {
519
+ F = 29;
520
+ }
521
+ if (L && R && D && DL && !U && !DR) {
522
+ F = 30;
523
+ }
524
+ if (L && R && D && DR && !U && !DL) {
525
+ F = 31;
526
+ }
527
+ if (L && R && D && !U && !DL && !DR) {
528
+ F = 32;
529
+ }
530
+ return F;
531
+ }
532
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95SlNPTlJvb20uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9pc2FhY3NjcmlwdC1jb21tb24vc3JjL2ZlYXR1cmVzL2RlcGxveUpTT05Sb29tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlHQUFpRztBQUNqRyxpR0FBaUc7QUFDakcsa0dBQWtHO0FBQ2xHLDBDQUEwQztBQUUxQyxPQUFPLEVBQ0wsZUFBZSxFQUNmLGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsVUFBVSxFQUNWLHdCQUF3QixFQUN4QixVQUFVLEVBQ1YsY0FBYyxFQUVkLFdBQVcsRUFDWCxhQUFhLEVBQ2IsY0FBYyxFQUNkLFFBQVEsR0FDVCxNQUFNLDhCQUE4QixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDL0QsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IseUJBQXlCLEVBQ3pCLEtBQUssRUFDTCxhQUFhLEdBQ2QsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsT0FBTyxFQUNQLGNBQWMsRUFDZCxnQkFBZ0IsR0FDakIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsK0JBQStCLEVBQy9CLG1CQUFtQixFQUNuQixVQUFVLEVBQ1Ysc0JBQXNCLEVBQ3RCLG9CQUFvQixHQUNyQixNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixD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QyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7UUFDN0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQzdCLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRTtRQUM3QixDQUFDLEdBQUcsRUFBRSxDQUFDO0tBQ1I7SUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7UUFDN0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDM0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDM0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUM1QixDQUFDLEdBQUcsRUFBRSxDQUFDO0tBQ1I7SUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQzVCLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUVELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2xDLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2xDLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQ2xDLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQ2xDLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDUjtJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDbkMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDbEMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDbEMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNuQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0tBQ1I7SUFFRCxPQUFPLENBQUMsQ0FBQztBQUNYLENBQUMifQ==
@@ -0,0 +1,63 @@
1
+ import { ModCallback } from "isaac-typescript-definitions";
2
+ import { musicManager } from "../cachedClasses";
3
+ import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
4
+ import { stopAllSoundEffects } from "../functions/sound";
5
+ import { saveDataManager } from "./saveDataManager/exports";
6
+ const FEATURE_NAME = "disableAllSound";
7
+ let musicWasEnabled = false;
8
+ const v = {
9
+ run: {
10
+ disableSoundSet: new Set(),
11
+ },
12
+ };
13
+ /** @internal */
14
+ export function disableAllSoundInit(mod) {
15
+ saveDataManager(FEATURE_NAME, v);
16
+ mod.AddCallback(ModCallback.POST_RENDER, postRender);
17
+ }
18
+ // ModCallback.POST_RENDER (2)
19
+ function postRender() {
20
+ if (v.run.disableSoundSet.size === 0) {
21
+ return;
22
+ }
23
+ stopAllSoundEffects();
24
+ }
25
+ /**
26
+ * Helper function to stop muting all sound effects and music.
27
+ *
28
+ * Use this function to set things back to normal after having used `disableAllSounds`.
29
+ *
30
+ * @param key The name of the mod feature that is requesting the enable/disable. This is needed so
31
+ * that multiple mod features can work in tandem.
32
+ */
33
+ export function enableAllSound(key) {
34
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
35
+ if (!v.run.disableSoundSet.has(key)) {
36
+ return;
37
+ }
38
+ v.run.disableSoundSet.delete(key);
39
+ if (v.run.disableSoundSet.size === 0 && musicWasEnabled) {
40
+ musicManager.Enable();
41
+ }
42
+ // Stop all sound effects that were initialized prior to enabling sounds (in case there was a
43
+ // sound played played previously on this render frame).
44
+ stopAllSoundEffects();
45
+ }
46
+ /**
47
+ * Helper function to disable all sound effects and music (by constantly musting them).
48
+ *
49
+ * Use the `enableAllSounds` helper function to set things back to normal.
50
+ *
51
+ * @param key The name of the mod feature that is requesting the enable/disable. This is needed so
52
+ * that multiple mod features can work in tandem.
53
+ */
54
+ export function disableAllSound(key) {
55
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
56
+ if (v.run.disableSoundSet.size === 0) {
57
+ musicWasEnabled = musicManager.IsEnabled();
58
+ }
59
+ v.run.disableSoundSet.add(key);
60
+ // Stop all sound effects that were initialized prior to disabling sounds.
61
+ stopAllSoundEffects();
62
+ }
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzYWJsZUFsbFNvdW5kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvaXNhYWNzY3JpcHQtY29tbW9uL3NyYy9mZWF0dXJlcy9kaXNhYmxlQWxsU291bmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFNUQsTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUM7QUFFdkMsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDO0FBRTVCLE1BQU0sQ0FBQyxHQUFHO0lBQ1IsR0FBRyxFQUFFO1FBQ0gsZUFBZSxFQUFFLElBQUksR0FBRyxFQUFVO0tBQ25DO0NBQ0YsQ0FBQztBQUVGLGdCQUFnQjtBQUNoQixNQUFNLFVBQVUsbUJBQW1CLENBQUMsR0FBUTtJQUMxQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWpDLEdBQUcsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN2RCxDQUFDO0FBRUQsOEJBQThCO0FBQzlCLFNBQVMsVUFBVTtJQUNqQixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUU7UUFDcEMsT0FBTztLQUNSO0lBRUQsbUJBQW1CLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBVztJQUN4Qyw2QkFBNkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU1QyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ25DLE9BQU87S0FDUjtJQUNELENBQUMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVsQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksZUFBZSxFQUFFO1FBQ3ZELFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztLQUN2QjtJQUVELDZGQUE2RjtJQUM3Rix3REFBd0Q7SUFDeEQsbUJBQW1CLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsR0FBVztJQUN6Qyw2QkFBNkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU1QyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUU7UUFDcEMsZUFBZSxHQUFHLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQztLQUM1QztJQUVELENBQUMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUvQiwwRUFBMEU7SUFDMUUsbUJBQW1CLEVBQUUsQ0FBQztBQUN4QixDQUFDIn0=