isaacscript-common 3.16.1 → 4.0.1-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/cachedClasses.ts +39 -0
  2. package/callbacks/customRevive.lua +2 -1
  3. package/callbacks/customRevive.ts +215 -0
  4. package/callbacks/itemPickup.ts +101 -0
  5. package/callbacks/postAmbush.ts +73 -0
  6. package/callbacks/postBombExploded.ts +26 -0
  7. package/callbacks/postBombInitLate.ts +36 -0
  8. package/callbacks/postBoneSwing.ts +64 -0
  9. package/callbacks/postCollectibleInitFirst.ts +40 -0
  10. package/callbacks/postCursedTeleport.ts +183 -0
  11. package/callbacks/postCustomDoorEnter.lua +0 -7
  12. package/callbacks/postCustomDoorEnter.ts +292 -0
  13. package/callbacks/postDiceRoomActivated.ts +60 -0
  14. package/callbacks/postDoorRender.ts +26 -0
  15. package/callbacks/postDoorUpdate.ts +26 -0
  16. package/callbacks/postEffectInitLate.ts +36 -0
  17. package/callbacks/postEffectStateChanged.ts +43 -0
  18. package/callbacks/postEsauJr.ts +107 -0
  19. package/callbacks/postFamiliarInitLate.ts +36 -0
  20. package/callbacks/postFamiliarStateChanged.ts +43 -0
  21. package/callbacks/postFlip.ts +88 -0
  22. package/callbacks/postGreedModeWave.ts +41 -0
  23. package/callbacks/postGridEntity.ts +164 -0
  24. package/callbacks/postGridEntityCollision.ts +69 -0
  25. package/callbacks/postGridEntityRender.ts +26 -0
  26. package/callbacks/postHolyMantleRemoved.ts +55 -0
  27. package/callbacks/postItemDischarged.ts +149 -0
  28. package/callbacks/postKnifeInitLate.ts +36 -0
  29. package/callbacks/postLaserInitLate.ts +36 -0
  30. package/callbacks/postNPCInitLate.ts +36 -0
  31. package/callbacks/postNPCStateChanged.ts +42 -0
  32. package/callbacks/postNewRoomEarly.ts +90 -0
  33. package/callbacks/postPickupCollect.ts +48 -0
  34. package/callbacks/postPickupInitFirst.ts +70 -0
  35. package/callbacks/postPickupInitLate.ts +36 -0
  36. package/callbacks/postPickupStateChanged.ts +43 -0
  37. package/callbacks/postPitRender.ts +26 -0
  38. package/callbacks/postPitUpdate.ts +26 -0
  39. package/callbacks/postPlayerChangeHealth.ts +62 -0
  40. package/callbacks/postPlayerChangeType.ts +56 -0
  41. package/callbacks/postPlayerCollectible.ts +113 -0
  42. package/callbacks/postPlayerFatalDamage.ts +141 -0
  43. package/callbacks/postPlayerInitLate.ts +37 -0
  44. package/callbacks/postPlayerReordered.ts +142 -0
  45. package/callbacks/postPoopRender.ts +26 -0
  46. package/callbacks/postPoopUpdate.ts +26 -0
  47. package/callbacks/postPressurePlateRender.ts +26 -0
  48. package/callbacks/postPressurePlateUpdate.ts +26 -0
  49. package/callbacks/postProjectileInitLate.ts +36 -0
  50. package/callbacks/postPurchase.ts +64 -0
  51. package/callbacks/postRockRender.ts +26 -0
  52. package/callbacks/postRockUpdate.ts +26 -0
  53. package/callbacks/postRoomClearChanged.ts +57 -0
  54. package/callbacks/postSacrifice.ts +62 -0
  55. package/callbacks/postSlotDestroyed.ts +92 -0
  56. package/callbacks/postSlotInitUpdate.ts +68 -0
  57. package/callbacks/postSlotRender.ts +69 -0
  58. package/callbacks/postSpikesRender.ts +26 -0
  59. package/callbacks/postSpikesUpdate.ts +26 -0
  60. package/callbacks/postTNTRender.ts +26 -0
  61. package/callbacks/postTNTUpdate.ts +26 -0
  62. package/callbacks/postTearInitLate.ts +36 -0
  63. package/callbacks/postTearInitVeryLate.ts +41 -0
  64. package/callbacks/postTransformation.ts +59 -0
  65. package/callbacks/postTrinketBreak.ts +110 -0
  66. package/callbacks/preBerserkDeath.ts +49 -0
  67. package/callbacks/preNewLevel.ts +55 -0
  68. package/callbacks/reorderedCallbacks.ts +166 -0
  69. package/callbacks/subscriptions/postAmbushFinished.ts +32 -0
  70. package/callbacks/subscriptions/postAmbushStarted.ts +32 -0
  71. package/callbacks/subscriptions/postBombInitLate.ts +32 -0
  72. package/callbacks/subscriptions/postBoneExploded.ts +32 -0
  73. package/callbacks/subscriptions/postBoneSwing.ts +24 -0
  74. package/callbacks/subscriptions/postCollectibleInitFirst.ts +37 -0
  75. package/callbacks/subscriptions/postCursedTeleport.ts +24 -0
  76. package/callbacks/subscriptions/postCustomDoorEnter.ts +45 -0
  77. package/callbacks/subscriptions/postCustomRevive.ts +36 -0
  78. package/callbacks/subscriptions/postDiceRoomActivated.ts +38 -0
  79. package/callbacks/subscriptions/postDoorRender.ts +35 -0
  80. package/callbacks/subscriptions/postDoorUpdate.ts +35 -0
  81. package/callbacks/subscriptions/postEffectInitLate.ts +32 -0
  82. package/callbacks/subscriptions/postEffectStateChanged.ts +40 -0
  83. package/callbacks/subscriptions/postEsauJr.ts +24 -0
  84. package/callbacks/subscriptions/postFamiliarInitLate.ts +32 -0
  85. package/callbacks/subscriptions/postFamiliarStateChanged.ts +40 -0
  86. package/callbacks/subscriptions/postFirstEsauJr.ts +24 -0
  87. package/callbacks/subscriptions/postFirstFlip.ts +24 -0
  88. package/callbacks/subscriptions/postFlip.ts +22 -0
  89. package/callbacks/subscriptions/postGameStartedReordered.ts +24 -0
  90. package/callbacks/subscriptions/postGreedModeWave.ts +24 -0
  91. package/callbacks/subscriptions/postGridEntityBroken.ts +51 -0
  92. package/callbacks/subscriptions/postGridEntityCollision.ts +54 -0
  93. package/callbacks/subscriptions/postGridEntityInit.ts +51 -0
  94. package/callbacks/subscriptions/postGridEntityRemove.ts +52 -0
  95. package/callbacks/subscriptions/postGridEntityRender.ts +51 -0
  96. package/callbacks/subscriptions/postGridEntityStateChanged.ts +55 -0
  97. package/callbacks/subscriptions/postGridEntityUpdate.ts +51 -0
  98. package/callbacks/subscriptions/postHolyMantleRemoved.ts +48 -0
  99. package/callbacks/subscriptions/postItemDischarged.ts +43 -0
  100. package/callbacks/subscriptions/postItemPickup.ts +64 -0
  101. package/callbacks/subscriptions/postKnifeInitLate.ts +32 -0
  102. package/callbacks/subscriptions/postLaserInitLate.ts +32 -0
  103. package/callbacks/subscriptions/postNPCInitLate.ts +32 -0
  104. package/callbacks/subscriptions/postNPCStateChanged.ts +42 -0
  105. package/callbacks/subscriptions/postNewLevelReordered.ts +22 -0
  106. package/callbacks/subscriptions/postNewRoomEarly.ts +22 -0
  107. package/callbacks/subscriptions/postNewRoomReordered.ts +22 -0
  108. package/callbacks/subscriptions/postPEffectUpdateReordered.ts +40 -0
  109. package/callbacks/subscriptions/postPickupCollect.ts +35 -0
  110. package/callbacks/subscriptions/postPickupInitFirst.ts +32 -0
  111. package/callbacks/subscriptions/postPickupInitLate.ts +32 -0
  112. package/callbacks/subscriptions/postPickupStateChanged.ts +40 -0
  113. package/callbacks/subscriptions/postPitRender.ts +35 -0
  114. package/callbacks/subscriptions/postPitUpdate.ts +35 -0
  115. package/callbacks/subscriptions/postPlayerChangeHealth.ts +49 -0
  116. package/callbacks/subscriptions/postPlayerChangeType.ts +40 -0
  117. package/callbacks/subscriptions/postPlayerCollectibleAdded.d.ts +2 -3
  118. package/callbacks/subscriptions/postPlayerCollectibleAdded.lua +2 -7
  119. package/callbacks/subscriptions/postPlayerCollectibleAdded.ts +38 -0
  120. package/callbacks/subscriptions/postPlayerCollectibleRemoved.d.ts +2 -3
  121. package/callbacks/subscriptions/postPlayerCollectibleRemoved.lua +2 -7
  122. package/callbacks/subscriptions/postPlayerCollectibleRemoved.ts +38 -0
  123. package/callbacks/subscriptions/postPlayerFatalDamage.d.ts +1 -1
  124. package/callbacks/subscriptions/postPlayerFatalDamage.ts +68 -0
  125. package/callbacks/subscriptions/postPlayerInitLate.ts +40 -0
  126. package/callbacks/subscriptions/postPlayerInitReordered.ts +40 -0
  127. package/callbacks/subscriptions/postPlayerRenderReordered.ts +40 -0
  128. package/callbacks/subscriptions/postPlayerUpdateReordered.ts +40 -0
  129. package/callbacks/subscriptions/postPoopRender.ts +35 -0
  130. package/callbacks/subscriptions/postPoopUpdate.ts +35 -0
  131. package/callbacks/subscriptions/postPressurePlateRender.ts +37 -0
  132. package/callbacks/subscriptions/postPressurePlateUpdate.ts +37 -0
  133. package/callbacks/subscriptions/postProjectileInitLate.ts +35 -0
  134. package/callbacks/subscriptions/postPurchase.ts +31 -0
  135. package/callbacks/subscriptions/postRockRender.ts +35 -0
  136. package/callbacks/subscriptions/postRockUpdate.ts +35 -0
  137. package/callbacks/subscriptions/postRoomClearChanged.ts +30 -0
  138. package/callbacks/subscriptions/postSacrifice.ts +43 -0
  139. package/callbacks/subscriptions/postSlotAnimationChanged.ts +40 -0
  140. package/callbacks/subscriptions/postSlotDestroyed.ts +55 -0
  141. package/callbacks/subscriptions/postSlotInit.ts +32 -0
  142. package/callbacks/subscriptions/postSlotRender.ts +32 -0
  143. package/callbacks/subscriptions/postSlotUpdate.ts +32 -0
  144. package/callbacks/subscriptions/postSpikesRender.ts +35 -0
  145. package/callbacks/subscriptions/postSpikesUpdate.ts +35 -0
  146. package/callbacks/subscriptions/postTNTRender.ts +35 -0
  147. package/callbacks/subscriptions/postTNTUpdate.ts +35 -0
  148. package/callbacks/subscriptions/postTearInitLate.ts +32 -0
  149. package/callbacks/subscriptions/postTearInitVeryLate.ts +32 -0
  150. package/callbacks/subscriptions/postTransformation.ts +40 -0
  151. package/callbacks/subscriptions/postTrinketBreak.ts +38 -0
  152. package/callbacks/subscriptions/preBerserkDeath.d.ts +1 -1
  153. package/callbacks/subscriptions/preBerserkDeath.ts +42 -0
  154. package/callbacks/subscriptions/preCustomRevive.d.ts +1 -1
  155. package/callbacks/subscriptions/preCustomRevive.ts +46 -0
  156. package/callbacks/subscriptions/preItemPickup.ts +64 -0
  157. package/callbacks/subscriptions/preNewLevel.ts +24 -0
  158. package/classes/DefaultMap.ts +174 -0
  159. package/classes/ModUpgraded.d.ts +3 -3
  160. package/classes/ModUpgraded.lua +3 -6
  161. package/classes/ModUpgraded.ts +77 -0
  162. package/constants.ts +162 -0
  163. package/constantsFirstLast.ts +217 -0
  164. package/enums/AmbushType.ts +4 -0
  165. package/enums/HealthType.ts +16 -0
  166. package/enums/ModCallbackCustom.d.ts +20 -18
  167. package/enums/ModCallbackCustom.ts +1278 -0
  168. package/enums/PocketItemType.ts +8 -0
  169. package/enums/SerializationType.ts +5 -0
  170. package/enums/SlotDestructionType.ts +4 -0
  171. package/enums/private/CopyableIsaacAPIClassType.ts +7 -0
  172. package/enums/private/SaveDataKey.ts +14 -0
  173. package/enums/private/SerializationBrand.ts +42 -0
  174. package/features/characterHealthConversion.lua +2 -9
  175. package/features/characterHealthConversion.ts +111 -0
  176. package/features/characterStats.ts +61 -0
  177. package/features/debugDisplay/debugDisplay.ts +221 -0
  178. package/features/debugDisplay/exports.ts +368 -0
  179. package/features/debugDisplay/v.ts +65 -0
  180. package/features/deployJSONRoom.ts +743 -0
  181. package/features/disableInputs.ts +193 -0
  182. package/features/disableSound.ts +77 -0
  183. package/features/extraConsoleCommands/commandsDisplay.ts +290 -0
  184. package/features/extraConsoleCommands/commandsSubroutines.lua +1 -1
  185. package/features/extraConsoleCommands/commandsSubroutines.ts +139 -0
  186. package/features/extraConsoleCommands/init.ts +334 -0
  187. package/features/extraConsoleCommands/listCommands.ts +1299 -0
  188. package/features/extraConsoleCommands/v.ts +14 -0
  189. package/features/fadeInRemover.ts +60 -0
  190. package/features/fastReset.ts +75 -0
  191. package/features/forgottenSwitch.ts +50 -0
  192. package/features/getCollectibleItemPoolType.ts +66 -0
  193. package/features/persistentEntities.ts +183 -0
  194. package/features/playerInventory.ts +133 -0
  195. package/features/ponyDetection.ts +74 -0
  196. package/features/preventCollectibleRotation.ts +115 -0
  197. package/features/runInNFrames.ts +148 -0
  198. package/features/saveDataManager/constants.ts +4 -0
  199. package/features/saveDataManager/exports.ts +229 -0
  200. package/features/saveDataManager/load.ts +99 -0
  201. package/features/saveDataManager/main.ts +195 -0
  202. package/features/saveDataManager/maps.ts +13 -0
  203. package/features/saveDataManager/merge.ts +194 -0
  204. package/features/saveDataManager/save.ts +74 -0
  205. package/features/saveDataManager/serializationBrand.ts +16 -0
  206. package/features/sirenHelpers.ts +129 -0
  207. package/features/taintedLazarusPlayers.ts +113 -0
  208. package/featuresInitialized.ts +20 -0
  209. package/functions/ambush.ts +47 -0
  210. package/functions/array.ts +410 -0
  211. package/functions/benchmark.ts +36 -0
  212. package/functions/bitwise.ts +24 -0
  213. package/functions/bombs.ts +12 -0
  214. package/functions/boss.ts +227 -0
  215. package/functions/cacheFlag.ts +12 -0
  216. package/functions/cards.lua +1 -1
  217. package/functions/cards.ts +271 -0
  218. package/functions/challenges.ts +13 -0
  219. package/functions/character.ts +126 -0
  220. package/functions/charge.ts +237 -0
  221. package/functions/chargeBar.ts +67 -0
  222. package/functions/collectibleCacheFlag.ts +90 -0
  223. package/functions/collectibleSet.ts +56 -0
  224. package/functions/collectibleTag.ts +89 -0
  225. package/functions/collectibles.ts +659 -0
  226. package/functions/color.d.ts +1 -1
  227. package/functions/color.lua +0 -7
  228. package/functions/color.ts +128 -0
  229. package/functions/debug.lua +2 -2
  230. package/functions/debug.ts +68 -0
  231. package/functions/deepCopy.lua +46 -51
  232. package/functions/deepCopy.ts +535 -0
  233. package/functions/deepCopyTests.ts +386 -0
  234. package/functions/direction.ts +49 -0
  235. package/functions/doors.lua +1 -2
  236. package/functions/doors.ts +347 -0
  237. package/functions/easing.ts +182 -0
  238. package/functions/eden.ts +47 -0
  239. package/functions/effects.ts +20 -0
  240. package/functions/entity.ts +439 -0
  241. package/functions/entitySpecific.ts +889 -0
  242. package/functions/entityTypes.ts +6 -0
  243. package/functions/enums.ts +146 -0
  244. package/functions/familiars.ts +106 -0
  245. package/functions/flag.ts +165 -0
  246. package/functions/flying.ts +117 -0
  247. package/functions/globals.d.ts +3 -3
  248. package/functions/globals.lua +8 -2
  249. package/functions/globals.ts +242 -0
  250. package/functions/gridEntity.ts +511 -0
  251. package/functions/gridEntitySpecific.ts +112 -0
  252. package/functions/input.ts +139 -0
  253. package/functions/isaacAPIClass.ts +67 -0
  254. package/functions/jsonHelpers.ts +45 -0
  255. package/functions/jsonRoom.ts +100 -0
  256. package/functions/kColor.d.ts +1 -1
  257. package/functions/kColor.lua +0 -7
  258. package/functions/kColor.ts +129 -0
  259. package/functions/language.ts +13 -0
  260. package/functions/level.ts +31 -0
  261. package/functions/log.ts +720 -0
  262. package/functions/map.ts +56 -0
  263. package/functions/math.ts +149 -0
  264. package/functions/mergeTests.ts +288 -0
  265. package/functions/npc.ts +148 -0
  266. package/functions/pickupVariants.ts +60 -0
  267. package/functions/pickups.ts +499 -0
  268. package/functions/pills.lua +1 -1
  269. package/functions/pills.ts +205 -0
  270. package/functions/player.lua +0 -6
  271. package/functions/player.ts +1060 -0
  272. package/functions/playerDataStructures.ts +150 -0
  273. package/functions/playerHealth.d.ts +2 -0
  274. package/functions/playerHealth.lua +73 -39
  275. package/functions/playerHealth.ts +382 -0
  276. package/functions/playerIndex.ts +195 -0
  277. package/functions/pocketItems.ts +149 -0
  278. package/functions/positionVelocity.ts +188 -0
  279. package/functions/random.ts +77 -0
  280. package/functions/revive.ts +201 -0
  281. package/functions/rng.d.ts +1 -1
  282. package/functions/rng.lua +0 -7
  283. package/functions/rng.ts +172 -0
  284. package/functions/roomData.ts +199 -0
  285. package/functions/roomGrid.ts +109 -0
  286. package/functions/roomShape.ts +80 -0
  287. package/functions/rooms.lua +1 -3
  288. package/functions/rooms.ts +648 -0
  289. package/functions/run.ts +36 -0
  290. package/functions/saveFile.ts +128 -0
  291. package/functions/seeds.ts +19 -0
  292. package/functions/serialization.lua +0 -3
  293. package/functions/serialization.ts +91 -0
  294. package/functions/set.ts +95 -0
  295. package/functions/sound.ts +9 -0
  296. package/functions/spawnCollectible.ts +104 -0
  297. package/functions/sprite.ts +107 -0
  298. package/functions/stage.ts +125 -0
  299. package/functions/string.ts +47 -0
  300. package/functions/table.ts +189 -0
  301. package/functions/tears.ts +32 -0
  302. package/functions/transformations.lua +1 -3
  303. package/functions/transformations.ts +131 -0
  304. package/functions/trinketCacheFlag.ts +60 -0
  305. package/functions/trinketGive.ts +157 -0
  306. package/functions/trinkets.ts +215 -0
  307. package/functions/tstlClass.ts +157 -0
  308. package/functions/types.ts +36 -0
  309. package/functions/ui.ts +138 -0
  310. package/functions/utils.d.ts +0 -37
  311. package/functions/utils.lua +0 -35
  312. package/functions/utils.ts +189 -0
  313. package/functions/vector.d.ts +1 -1
  314. package/functions/vector.lua +0 -7
  315. package/functions/vector.ts +126 -0
  316. package/index.ts +172 -0
  317. package/initCustomCallbacks.ts +132 -0
  318. package/initFeatures.ts +39 -0
  319. package/interfaces/AddCallbackParameterCustom.ts +188 -0
  320. package/interfaces/ChargeBarSprites.ts +12 -0
  321. package/interfaces/JSONDoor.d.ts +4 -4
  322. package/interfaces/JSONDoor.ts +13 -0
  323. package/interfaces/JSONEntity.d.ts +5 -5
  324. package/interfaces/JSONEntity.ts +16 -0
  325. package/interfaces/JSONRoom.d.ts +9 -9
  326. package/interfaces/JSONRoom.ts +36 -0
  327. package/interfaces/JSONRooms.ts +12 -0
  328. package/interfaces/JSONSpawn.d.ts +3 -3
  329. package/interfaces/JSONSpawn.ts +14 -0
  330. package/interfaces/PlayerHealth.ts +16 -0
  331. package/interfaces/PocketItemDescription.ts +9 -0
  332. package/interfaces/SaveData.ts +29 -0
  333. package/interfaces/TrinketSituation.ts +9 -0
  334. package/interfaces/private/TSTLClassMetatable.ts +8 -0
  335. package/maps/PHDPillConversions.ts +21 -0
  336. package/maps/cardMap.ts +209 -0
  337. package/maps/characterMap.ts +87 -0
  338. package/maps/collectibleDescriptionMap.ts +732 -0
  339. package/maps/collectibleNameMap.ts +731 -0
  340. package/maps/defaultPlayerStatMap.ts +17 -0
  341. package/maps/falsePHDPillConversions.ts +35 -0
  342. package/maps/gridEntityTypeToBrokenStateMap.ts +50 -0
  343. package/maps/gridEntityXMLMap.ts +176 -0
  344. package/maps/pillEffectMap.ts +88 -0
  345. package/maps/roomShapeToTopLeftWallGridIndexMap.ts +18 -0
  346. package/maps/roomTypeMap.ts +40 -0
  347. package/maps/trinketDescriptionMap.ts +200 -0
  348. package/maps/trinketNameMap.ts +198 -0
  349. package/objects/LRoomShapeToRectangles.ts +44 -0
  350. package/objects/callbackRegisterFunctions.ts +187 -0
  351. package/objects/cardDescriptions.ts +105 -0
  352. package/objects/cardNames.ts +105 -0
  353. package/objects/cardTypes.ts +104 -0
  354. package/objects/challengeNames.ts +52 -0
  355. package/objects/characterNames.ts +48 -0
  356. package/objects/coinSubTypeToValue.ts +14 -0
  357. package/objects/colors.ts +16 -0
  358. package/objects/directionNames.ts +11 -0
  359. package/objects/directionToDegrees.ts +11 -0
  360. package/objects/directionToVector.ts +12 -0
  361. package/objects/doorSlotFlagToDoorSlot.ts +16 -0
  362. package/objects/doorSlotToDirection.ts +14 -0
  363. package/objects/isaacAPIClassTypeToBrand.ts +11 -0
  364. package/objects/isaacAPIClassTypeToCopyFunction.ts +18 -0
  365. package/objects/languageNames.ts +13 -0
  366. package/objects/oppositeDoorSlots.ts +15 -0
  367. package/objects/pillEffectClasses.ts +63 -0
  368. package/objects/pillEffectNames.ts +57 -0
  369. package/objects/pillEffectTypes.ts +62 -0
  370. package/objects/roomShapeBounds.ts +71 -0
  371. package/objects/roomShapeLayoutSizes.ts +45 -0
  372. package/objects/roomShapeToBottomRightPosition.ts +25 -0
  373. package/objects/roomShapeToDoorSlots.ts +83 -0
  374. package/objects/roomShapeToDoorSlotsToGridIndexDelta.ts +127 -0
  375. package/objects/roomShapeToGridWidth.ts +21 -0
  376. package/objects/roomShapeToTopLeftPosition.ts +26 -0
  377. package/objects/roomShapeVolumes.ts +38 -0
  378. package/objects/roomTypeNames.ts +36 -0
  379. package/objects/serializedIsaacAPIClassTypeToIdentityFunction.ts +14 -0
  380. package/objects/stageTypeToLetter.ts +15 -0
  381. package/objects/transformationNames.d.ts +0 -1
  382. package/objects/transformationNames.lua +0 -1
  383. package/objects/transformationNames.ts +18 -0
  384. package/package.json +2 -2
  385. package/patchErrorFunctions.ts +92 -0
  386. package/sets/LRoomShapesSet.ts +8 -0
  387. package/sets/bossSets.ts +470 -0
  388. package/sets/charactersThatStartWithAnActiveItemSet.ts +16 -0
  389. package/sets/charactersWithBlackHeartFromEternalHeartSet.ts +7 -0
  390. package/sets/charactersWithFreeDevilDealsSet.ts +4 -0
  391. package/sets/charactersWithNoRedHeartsSet.ts +17 -0
  392. package/sets/charactersWithNoSoulHeartsSet.ts +14 -0
  393. package/sets/chestPickupVariantsSet.ts +16 -0
  394. package/sets/familiarsThatShootPlayerTearsSet.ts +13 -0
  395. package/sets/lostStyleCharactersSet.ts +13 -0
  396. package/sets/mineShaftRoomSubTypesSet.ts +10 -0
  397. package/sets/redHeartSubTypesSet.ts +7 -0
  398. package/sets/sinEntityTypesSet.ts +11 -0
  399. package/sets/singleUseActiveCollectibleTypesSet.ts +13 -0
  400. package/sets/storyBossesSet.ts +17 -0
  401. package/types/AnyEntity.ts +12 -0
  402. package/types/AwaitingTextInput.d.ts +2 -0
  403. package/types/CollectibleIndex.d.ts +1 -1
  404. package/types/CollectibleIndex.ts +16 -0
  405. package/types/PickingUpItem.d.ts +3 -3
  406. package/types/PickingUpItem.ts +89 -0
  407. package/types/PlayerIndex.d.ts +1 -1
  408. package/types/PlayerIndex.ts +13 -0
  409. package/types/private/IsaacAPIClass.d.ts +1 -1
  410. package/types/private/IsaacAPIClass.ts +3 -0
  411. package/types/private/SerializedIsaacAPIClass.d.ts +1 -1
  412. package/types/private/SerializedIsaacAPIClass.ts +3 -0
  413. package/types/private/TSTLClass.d.ts +1 -1
  414. package/types/private/TSTLClass.ts +3 -0
  415. package/upgradeMod.d.ts +2 -2
  416. package/upgradeMod.lua +2 -2
  417. package/upgradeMod.ts +55 -0
@@ -0,0 +1,382 @@
1
+ import {
2
+ ActiveSlot,
3
+ CollectibleType,
4
+ HeartSubType,
5
+ PlayerType,
6
+ } from "isaac-typescript-definitions";
7
+ import { MAX_PLAYER_HEART_CONTAINERS } from "../constants";
8
+ import { HealthType } from "../enums/HealthType";
9
+ import { PlayerHealth } from "../interfaces/PlayerHealth";
10
+ import { getTotalCharge } from "./charge";
11
+ import { getEnumValues } from "./enums";
12
+ import {
13
+ getPlayerBlackHearts,
14
+ getPlayerHearts,
15
+ getPlayerSoulHearts,
16
+ isCharacter,
17
+ setActiveItem,
18
+ } from "./player";
19
+ import { repeat } from "./utils";
20
+
21
+ export function addPlayerHealthType(
22
+ player: EntityPlayer,
23
+ healthType: HealthType,
24
+ numHearts: int,
25
+ ): void {
26
+ switch (healthType) {
27
+ case HealthType.RED: {
28
+ player.AddHearts(numHearts);
29
+ break;
30
+ }
31
+
32
+ case HealthType.SOUL: {
33
+ player.AddSoulHearts(numHearts);
34
+ break;
35
+ }
36
+
37
+ case HealthType.ETERNAL: {
38
+ player.AddEternalHearts(numHearts);
39
+ break;
40
+ }
41
+
42
+ case HealthType.BLACK: {
43
+ player.AddBlackHearts(numHearts);
44
+ break;
45
+ }
46
+
47
+ case HealthType.GOLDEN: {
48
+ player.AddGoldenHearts(numHearts);
49
+ break;
50
+ }
51
+
52
+ case HealthType.BONE: {
53
+ player.AddBoneHearts(numHearts);
54
+ break;
55
+ }
56
+
57
+ case HealthType.ROTTEN: {
58
+ player.AddRottenHearts(numHearts);
59
+ break;
60
+ }
61
+
62
+ case HealthType.BROKEN: {
63
+ player.AddBrokenHearts(numHearts);
64
+ break;
65
+ }
66
+
67
+ case HealthType.MAX_HEARTS: {
68
+ player.AddMaxHearts(numHearts, false);
69
+ break;
70
+ }
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Helper function to get an object representing the player's health. You can use this in
76
+ * combination with the `setPlayerHealth` function to restore the player's health back to a certain
77
+ * configuration at a later time.
78
+ *
79
+ * This is based on the `REVEL.StoreHealth` function in the Revelations mod.
80
+ */
81
+ export function getPlayerHealth(player: EntityPlayer): PlayerHealth {
82
+ const character = player.GetPlayerType();
83
+ const soulHeartTypes: HeartSubType[] = [];
84
+ let maxHearts = player.GetMaxHearts();
85
+ let hearts = getPlayerHearts(player); // We use the helper function to remove rotten hearts
86
+ let soulHearts = player.GetSoulHearts();
87
+ let boneHearts = player.GetBoneHearts();
88
+ const goldenHearts = player.GetGoldenHearts();
89
+ const eternalHearts = player.GetEternalHearts();
90
+ const rottenHearts = player.GetRottenHearts();
91
+ const brokenHearts = player.GetBrokenHearts();
92
+ const subPlayer = player.GetSubPlayer();
93
+ const soulCharges = player.GetEffectiveSoulCharge();
94
+ const bloodCharges = player.GetEffectiveBloodCharge();
95
+
96
+ // The Forgotten and The Soul has special health, so we need to account for this.
97
+ if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
98
+ // The Forgotten does not have red heart containers.
99
+ maxHearts = boneHearts * 2;
100
+ boneHearts = 0;
101
+
102
+ // The Forgotten will always have 0 soul hearts; we need to get the soul heart amount from the
103
+ // sub player.
104
+ soulHearts = subPlayer.GetSoulHearts();
105
+ } else if (character === PlayerType.THE_SOUL && subPlayer !== undefined) {
106
+ // The Soul will always have 0 bone hearts; we need to get the bone heart amount from the sub
107
+ // player. We need to store it as "maxHearts" instead of "boneHearts".
108
+ maxHearts = subPlayer.GetBoneHearts() * 2;
109
+ hearts = subPlayer.GetHearts();
110
+ }
111
+
112
+ // This is the number of individual hearts shown in the HUD, minus heart containers.
113
+ const extraHearts = math.ceil(soulHearts / 2) + boneHearts;
114
+
115
+ // Since bone hearts can be inserted anywhere between soul hearts, we need a separate counter to
116
+ // track which soul heart we're currently at.
117
+ let currentSoulHeart = 0;
118
+
119
+ for (let i = 0; i < extraHearts; i++) {
120
+ let isBoneHeart = player.IsBoneHeart(i);
121
+ if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
122
+ isBoneHeart = subPlayer.IsBoneHeart(i);
123
+ }
124
+ if (isBoneHeart) {
125
+ soulHeartTypes.push(HeartSubType.BONE);
126
+ } else {
127
+ // We need to add 1 here because only the second half of a black heart is considered black.
128
+ let isBlackHeart = player.IsBlackHeart(currentSoulHeart + 1);
129
+ if (character === PlayerType.THE_FORGOTTEN && subPlayer !== undefined) {
130
+ isBlackHeart = subPlayer.IsBlackHeart(currentSoulHeart + 1);
131
+ }
132
+ if (isBlackHeart) {
133
+ soulHeartTypes.push(HeartSubType.BLACK);
134
+ } else {
135
+ soulHeartTypes.push(HeartSubType.SOUL);
136
+ }
137
+
138
+ // Move to the next heart.
139
+ currentSoulHeart += 2;
140
+ }
141
+ }
142
+
143
+ return {
144
+ maxHearts,
145
+ hearts,
146
+ eternalHearts,
147
+ soulHearts,
148
+ boneHearts,
149
+ goldenHearts,
150
+ rottenHearts,
151
+ brokenHearts,
152
+ soulCharges,
153
+ bloodCharges,
154
+ soulHeartTypes,
155
+ };
156
+ }
157
+
158
+ export function getPlayerHealthType(
159
+ player: EntityPlayer,
160
+ healthType: HealthType,
161
+ ): int {
162
+ switch (healthType) {
163
+ // 5.10.1
164
+ case HealthType.RED: {
165
+ // We use the standard library helper function since the `EntityPlayer.GetHearts` method
166
+ // returns a value that includes rotten hearts.
167
+ return getPlayerHearts(player);
168
+ }
169
+
170
+ // 5.10.3
171
+ case HealthType.SOUL: {
172
+ // We use the standard library helper function since the `EntityPlayer.GetSoulHearts` method
173
+ // returns a value that includes black hearts.
174
+ return getPlayerSoulHearts(player);
175
+ }
176
+
177
+ // 5.10.4
178
+ case HealthType.ETERNAL: {
179
+ return player.GetEternalHearts();
180
+ }
181
+
182
+ // 5.10.6
183
+ case HealthType.BLACK: {
184
+ // We use the standard library helper function since the `EntityPlayer.GetBlackHearts` method
185
+ // returns a bit mask.
186
+ return getPlayerBlackHearts(player);
187
+ }
188
+
189
+ // 5.10.7
190
+ case HealthType.GOLDEN: {
191
+ return player.GetGoldenHearts();
192
+ }
193
+
194
+ // 5.10.11
195
+ case HealthType.BONE: {
196
+ return player.GetBoneHearts();
197
+ }
198
+
199
+ // 5.10.12
200
+ case HealthType.ROTTEN: {
201
+ return player.GetRottenHearts();
202
+ }
203
+
204
+ case HealthType.BROKEN: {
205
+ return player.GetBrokenHearts();
206
+ }
207
+
208
+ case HealthType.MAX_HEARTS: {
209
+ return player.GetMaxHearts();
210
+ }
211
+ }
212
+ }
213
+
214
+ /** Returns a `PlayerHealth` object with all 0s. */
215
+ export function newPlayerHealth(): PlayerHealth {
216
+ return {
217
+ maxHearts: 0,
218
+ hearts: 0,
219
+ eternalHearts: 0,
220
+ soulHearts: 0,
221
+ boneHearts: 0,
222
+ goldenHearts: 0,
223
+ rottenHearts: 0,
224
+ brokenHearts: 0,
225
+ soulCharges: 0,
226
+ bloodCharges: 0,
227
+ soulHeartTypes: [],
228
+ };
229
+ }
230
+
231
+ export function playerConvertBlackHeartsToSoulHearts(
232
+ player: EntityPlayer,
233
+ ): void {
234
+ const playerHealth = getPlayerHealth(player);
235
+ removeAllPlayerHealth(player);
236
+ playerHealth.soulHeartTypes = playerHealth.soulHeartTypes.map(
237
+ (soulHeartType) =>
238
+ soulHeartType === HeartSubType.BLACK ? HeartSubType.SOUL : soulHeartType,
239
+ );
240
+ setPlayerHealth(player, playerHealth);
241
+ }
242
+
243
+ export function playerConvertSoulHeartsToBlackHearts(
244
+ player: EntityPlayer,
245
+ ): void {
246
+ const playerHealth = getPlayerHealth(player);
247
+ removeAllPlayerHealth(player);
248
+ playerHealth.soulHeartTypes = playerHealth.soulHeartTypes.map(
249
+ (soulHeartType) =>
250
+ soulHeartType === HeartSubType.SOUL ? HeartSubType.BLACK : soulHeartType,
251
+ );
252
+ setPlayerHealth(player, playerHealth);
253
+ }
254
+
255
+ export function removeAllPlayerHealth(player: EntityPlayer): void {
256
+ const goldenHearts = player.GetGoldenHearts();
257
+ const eternalHearts = player.GetEternalHearts();
258
+ const boneHearts = player.GetBoneHearts();
259
+ const brokenHearts = player.GetBrokenHearts();
260
+
261
+ // To avoid bugs, we have to remove the exact amount of certain types of hearts. We remove Golden
262
+ // Hearts first so that they don't break.
263
+ player.AddGoldenHearts(goldenHearts * -1);
264
+ player.AddEternalHearts(eternalHearts * -1);
265
+ player.AddBoneHearts(boneHearts * -1);
266
+ player.AddBrokenHearts(brokenHearts * -1);
267
+ player.AddMaxHearts(MAX_PLAYER_HEART_CONTAINERS * -2, true);
268
+ player.AddSoulHearts(MAX_PLAYER_HEART_CONTAINERS * -2);
269
+
270
+ // If we are The Soul, the `EntityPlayer.AddBoneHearts` method will not remove Forgotten's bone
271
+ // hearts, so we need to explicitly handle this.
272
+ if (isCharacter(player, PlayerType.THE_SOUL)) {
273
+ const forgotten = player.GetSubPlayer();
274
+ if (forgotten !== undefined) {
275
+ const forgottenBoneHearts = forgotten.GetBoneHearts();
276
+ forgotten.AddBoneHearts(forgottenBoneHearts * -1);
277
+ }
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Helper function to set a player's health to a specific state. You can use this in combination
283
+ * with the `getPlayerHealth` function to restore the player's health back to a certain
284
+ * configuration at a later time.
285
+ *
286
+ * Based on the `REVEL.LoadHealth` function in the Revelations mod.
287
+ */
288
+ export function setPlayerHealth(
289
+ player: EntityPlayer,
290
+ playerHealth: PlayerHealth,
291
+ ): void {
292
+ const character = player.GetPlayerType();
293
+ const subPlayer = player.GetSubPlayer();
294
+
295
+ removeAllPlayerHealth(player);
296
+
297
+ // Before we add any health, we have to take away Alabaster Box, if present.
298
+ const alabasterBoxes: Array<[slot: ActiveSlot, totalCharge: int]> = [];
299
+ if (player.HasCollectible(CollectibleType.ALABASTER_BOX)) {
300
+ for (const activeSlot of getEnumValues(ActiveSlot)) {
301
+ const activeItem = player.GetActiveItem();
302
+ if (activeItem === CollectibleType.ALABASTER_BOX) {
303
+ const totalCharge = getTotalCharge(player, activeSlot);
304
+ setActiveItem(player, CollectibleType.NULL, activeSlot);
305
+ alabasterBoxes.push([activeSlot, totalCharge]);
306
+ }
307
+ }
308
+ }
309
+
310
+ // Add the red heart containers.
311
+ if (character === PlayerType.THE_SOUL && subPlayer !== undefined) {
312
+ // Adding health to The Soul is a special case.
313
+ subPlayer.AddMaxHearts(playerHealth.maxHearts, false);
314
+ } else {
315
+ player.AddMaxHearts(playerHealth.maxHearts, false);
316
+ }
317
+
318
+ // Add the eternal hearts.
319
+ player.AddEternalHearts(playerHealth.eternalHearts);
320
+
321
+ // Add the soul / black / bone hearts.
322
+ let soulHeartsRemaining = playerHealth.soulHearts;
323
+ playerHealth.soulHeartTypes.forEach((heartType, i) => {
324
+ const isHalf =
325
+ playerHealth.soulHearts + playerHealth.boneHearts * 2 < (i + 1) * 2;
326
+ let addAmount = 2;
327
+ if (isHalf || heartType === HeartSubType.BONE || soulHeartsRemaining < 2) {
328
+ // Fix the bug where a half soul heart to the left of a bone heart will be treated as a full
329
+ // soul heart.
330
+ addAmount = 1;
331
+ }
332
+
333
+ if (heartType === HeartSubType.SOUL) {
334
+ player.AddSoulHearts(addAmount);
335
+ soulHeartsRemaining -= addAmount;
336
+ } else if (heartType === HeartSubType.BLACK) {
337
+ player.AddBlackHearts(addAmount);
338
+ soulHeartsRemaining -= addAmount;
339
+ } else if (heartType === HeartSubType.BONE) {
340
+ player.AddBoneHearts(addAmount);
341
+ }
342
+ });
343
+
344
+ /**
345
+ * Fill in the red heart containers.
346
+ *
347
+ * (Rotten Hearts must be filled in first in order for this to work properly, since they conflict
348
+ * with half red hearts.)
349
+ *
350
+ * The `EntityPlayer.AddRottenHearts` method is not like actually picking up a rotten heart, since
351
+ * it will only grant one rotten heart to Tainted Magdalene (whereas picking up a rotten heart
352
+ * would grant two).
353
+ */
354
+ player.AddRottenHearts(playerHealth.rottenHearts);
355
+ repeat(playerHealth.hearts, () => {
356
+ player.AddHearts(1);
357
+
358
+ // Adding 1 heart to Tainted Magdalene will actually add two hearts.
359
+ if (character === PlayerType.MAGDALENE_B) {
360
+ player.AddHearts(-1);
361
+ }
362
+ });
363
+ player.AddGoldenHearts(playerHealth.goldenHearts);
364
+ player.AddBrokenHearts(playerHealth.brokenHearts);
365
+
366
+ // Set the Bethany / Tainted Bethany charges.
367
+ if (character === PlayerType.BETHANY) {
368
+ player.SetSoulCharge(playerHealth.soulCharges);
369
+ } else if (character === PlayerType.BETHANY_B) {
370
+ player.SetBloodCharge(playerHealth.bloodCharges);
371
+ }
372
+
373
+ // Re-add the Alabaster Box, if present.
374
+ for (const [activeSlot, totalCharge] of alabasterBoxes) {
375
+ setActiveItem(
376
+ player,
377
+ CollectibleType.ALABASTER_BOX,
378
+ activeSlot,
379
+ totalCharge,
380
+ );
381
+ }
382
+ }
@@ -0,0 +1,195 @@
1
+ import { CollectibleType, PlayerType } from "isaac-typescript-definitions";
2
+ import { game } from "../cachedClasses";
3
+ import { PlayerIndex } from "../types/PlayerIndex";
4
+
5
+ const DEFAULT_COLLECTIBLE_TYPE = CollectibleType.SAD_ONION;
6
+
7
+ const EXCLUDED_CHARACTERS: ReadonlySet<PlayerType> = new Set([
8
+ PlayerType.ESAU, // 20
9
+ PlayerType.THE_SOUL_B, // 40
10
+ ]);
11
+
12
+ /**
13
+ * Helper function to get every player with no restrictions, by using `Game.GetNumPlayers` and
14
+ * `Isaac.GetPlayer`.
15
+ *
16
+ * This function is almost never what you want to use. For most purposes, use the `getPlayers`
17
+ * helper function instead to get a filtered list of players.
18
+ */
19
+ export function getAllPlayers(): EntityPlayer[] {
20
+ const numPlayers = game.GetNumPlayers();
21
+
22
+ const players: EntityPlayer[] = [];
23
+ for (let i = 0; i < numPlayers; i++) {
24
+ const player = Isaac.GetPlayer(i);
25
+ players.push(player);
26
+ }
27
+
28
+ return players;
29
+ }
30
+
31
+ export function getPlayerFromIndex(
32
+ playerIndex: PlayerIndex,
33
+ ): EntityPlayer | undefined {
34
+ const players = getPlayers();
35
+ return players.find((player) => getPlayerIndex(player) === playerIndex);
36
+ }
37
+
38
+ /**
39
+ * Mods often have to track variables relating to the player. In naive mods, information will only
40
+ * be stored about the first player. However, in order to be robust, mods must handle up to 4
41
+ * players playing at the same time. This means that information must be stored on a map data
42
+ * structure. Finding a good index for these types of map data structures is difficult:
43
+ *
44
+ * - We cannot use the index from `Isaac.GetPlayer(i)` since this fails in the case where there are
45
+ * two players and the first player leaves the run.
46
+ * - We cannot use `EntityPlayer.ControllerIndex` as an index because it fails in the case of Jacob
47
+ * & Esau or Tainted Forgotten. It also fails in the case of a player changing their controls
48
+ * mid-run.
49
+ * - We cannot use `EntityPlayer.GetData().index` because it does not persist across saving and
50
+ * continuing.
51
+ * - We cannot use `GetPtrHash()` as an index because it does not persist across exiting and
52
+ * relaunching the game.
53
+ * - We cannot use `EntityPlayer.InitSeed` because it is not consistent with additional players
54
+ * beyond the first.
55
+ *
56
+ * Instead, we use the `EntityPlayer.GetCollectibleRNG` method with an arbitrary value of Sad Onion
57
+ * (1). This works even if the player does not have any Sad Onions.
58
+ *
59
+ * Since the RNG value is the same for both Tainted Lazarus and Dead Tainted Lazarus, we revert to
60
+ * using the RNG of The Inner Eye (2) for Dead Tainted Lazarus.
61
+ *
62
+ * Note that by default, this returns the same index for both The Forgotten and The Soul. (Even
63
+ * though they are technically different characters, they share the same inventory and InitSeed.) If
64
+ * this is not desired, pass true for the `differentiateForgottenAndSoul` argument, and the RNG of
65
+ * Spoon Bender (3) will be used for The Soul.
66
+ */
67
+ export function getPlayerIndex(
68
+ player: EntityPlayer,
69
+ differentiateForgottenAndSoul = false,
70
+ ): PlayerIndex {
71
+ // Sub-players use separate RNG values for some reason, so we need to always use the main player:
72
+ // https://github.com/Meowlala/RepentanceAPIIssueTracker/issues/443
73
+
74
+ // We can safely ignore the player's character because regardless of whether the main player ends
75
+ // up being The Forgotten or The Soul, the collectible RNG values will be the same. The
76
+ // `EntityPlayer.IsSubPlayer` method can return true for Dead Tainted Lazarus during the
77
+ // PostPlayerInit callback, but since we fall back to the player in the case of
78
+ // "getSubPlayerParent" returning undefined, we do not need to explicitly check for this case.
79
+ let playerToUse = player;
80
+ const isSubPlayer = player.IsSubPlayer();
81
+ if (isSubPlayer) {
82
+ // The "getSubPlayerParent" function will return undefined in the situation where we are on Dead
83
+ // Tainted Lazarus in the PostPlayerInit callback.
84
+ const playerParent = getSubPlayerParent(player as EntitySubPlayer);
85
+ if (playerParent !== undefined) {
86
+ playerToUse = playerParent;
87
+ }
88
+ }
89
+
90
+ const collectibleType = getPlayerIndexCollectibleType(
91
+ player,
92
+ differentiateForgottenAndSoul,
93
+ );
94
+ const collectibleRNG = playerToUse.GetCollectibleRNG(collectibleType);
95
+ const seed = collectibleRNG.GetSeed();
96
+
97
+ return seed as unknown as PlayerIndex;
98
+ }
99
+
100
+ function getPlayerIndexCollectibleType(
101
+ player: EntityPlayer,
102
+ differentiateForgottenAndSoul: boolean,
103
+ ) {
104
+ const character = player.GetPlayerType();
105
+
106
+ switch (character) {
107
+ // 17
108
+ case PlayerType.THE_SOUL: {
109
+ return differentiateForgottenAndSoul
110
+ ? CollectibleType.SPOON_BENDER
111
+ : DEFAULT_COLLECTIBLE_TYPE;
112
+ }
113
+
114
+ // 38
115
+ case PlayerType.LAZARUS_2_B: {
116
+ return CollectibleType.INNER_EYE;
117
+ }
118
+
119
+ default: {
120
+ return DEFAULT_COLLECTIBLE_TYPE;
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Helper function to return the index of this player with respect to the output of the
127
+ * `Isaac.GetPlayer` method.
128
+ */
129
+ export function getPlayerIndexVanilla(
130
+ playerToFind: EntityPlayer,
131
+ ): int | undefined {
132
+ const numPlayers = game.GetNumPlayers();
133
+ const playerToFindHash = GetPtrHash(playerToFind);
134
+
135
+ for (let i = 0; i < numPlayers; i++) {
136
+ const player = Isaac.GetPlayer(i);
137
+ const playerHash = GetPtrHash(player);
138
+ if (playerHash === playerToFindHash) {
139
+ return i;
140
+ }
141
+ }
142
+
143
+ return undefined;
144
+ }
145
+
146
+ /**
147
+ * This function always excludes players with a non-undefined parent, since they are not real
148
+ * players (e.g. the Strawman Keeper).
149
+ *
150
+ * If this is not desired, use the `getAllPlayers` helper function instead.
151
+ *
152
+ * @param performCharacterExclusions Whether or not to exclude characters that are not directly
153
+ * controlled by the player (i.e. Esau & Tainted Soul). Default is
154
+ * false.
155
+ */
156
+ export function getPlayers(performCharacterExclusions = false): EntityPlayer[] {
157
+ const players = getAllPlayers();
158
+ const nonChildPlayers = players.filter((player) => !isChildPlayer(player));
159
+ const nonChildPlayersFiltered = nonChildPlayers.filter((player) => {
160
+ const character = player.GetPlayerType();
161
+ return !EXCLUDED_CHARACTERS.has(character);
162
+ });
163
+
164
+ return performCharacterExclusions ? nonChildPlayersFiltered : nonChildPlayers;
165
+ }
166
+
167
+ /**
168
+ * Helper function to get a parent `EntityPlayer` object for a given `EntitySubPlayer` object. This
169
+ * is useful because calling the `EntityPlayer.GetSubPlayer` method on a sub-player object will
170
+ * return undefined.
171
+ */
172
+ export function getSubPlayerParent(
173
+ subPlayer: EntitySubPlayer,
174
+ ): EntityPlayer | undefined {
175
+ const subPlayerPtrHash = GetPtrHash(subPlayer);
176
+ const players = getPlayers();
177
+
178
+ return players.find((player) => {
179
+ const thisPlayerSubPlayer = player.GetSubPlayer();
180
+ if (thisPlayerSubPlayer === undefined) {
181
+ return false;
182
+ }
183
+
184
+ const thisPlayerSubPlayerPtrHash = GetPtrHash(thisPlayerSubPlayer);
185
+ return thisPlayerSubPlayerPtrHash === subPlayerPtrHash;
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Some players are "child" players, meaning that they have a non-undefined Parent property. (For
191
+ * example, the Strawman Keeper.)
192
+ */
193
+ export function isChildPlayer(player: EntityPlayer): boolean {
194
+ return player.Parent !== undefined;
195
+ }