isaacscript-common 2.3.2 → 3.0.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 (269) hide show
  1. package/cachedClasses.lua +24 -0
  2. package/callbacks/customRevive.lua +2 -0
  3. package/callbacks/itemPickup.lua +2 -0
  4. package/callbacks/postBombInitLate.lua +2 -0
  5. package/callbacks/postBoneSwing.lua +2 -0
  6. package/callbacks/postCollectibleInitFirst.lua +2 -0
  7. package/callbacks/postCursedTeleport.lua +2 -0
  8. package/callbacks/postCustomDoorEnter.lua +44 -0
  9. package/callbacks/postDoorRender.lua +2 -0
  10. package/callbacks/postDoorUpdate.lua +2 -0
  11. package/callbacks/postEffectInitLate.lua +2 -0
  12. package/callbacks/postEffectStateChanged.lua +2 -0
  13. package/callbacks/postEsauJr.lua +2 -0
  14. package/callbacks/postFamiliarInitLate.lua +2 -0
  15. package/callbacks/postFamiliarStateChanged.lua +2 -0
  16. package/callbacks/postFlip.lua +2 -0
  17. package/callbacks/postGreedModeWave.lua +2 -0
  18. package/callbacks/postGridEntity.lua +2 -0
  19. package/callbacks/postGridEntityCollision.lua +2 -0
  20. package/callbacks/postGridEntityRender.lua +2 -0
  21. package/callbacks/postHolyMantleRemoved.lua +2 -0
  22. package/callbacks/postKnifeInitLate.lua +2 -0
  23. package/callbacks/postLaserInitLate.lua +2 -0
  24. package/callbacks/postNPCInitLate.lua +2 -0
  25. package/callbacks/postNPCStateChanged.lua +2 -0
  26. package/callbacks/postNewRoomEarly.lua +2 -0
  27. package/callbacks/postPickupCollect.lua +2 -0
  28. package/callbacks/postPickupInitLate.lua +2 -0
  29. package/callbacks/postPickupStateChanged.lua +2 -0
  30. package/callbacks/postPitRender.lua +2 -0
  31. package/callbacks/postPitUpdate.lua +2 -0
  32. package/callbacks/postPlayerChangeHealth.lua +2 -0
  33. package/callbacks/postPlayerChangeType.lua +2 -0
  34. package/callbacks/postPlayerFatalDamage.lua +2 -0
  35. package/callbacks/postPlayerInitLate.lua +2 -0
  36. package/callbacks/postPlayerReordered.lua +2 -0
  37. package/callbacks/postPoopRender.lua +2 -0
  38. package/callbacks/postPoopUpdate.lua +2 -0
  39. package/callbacks/postPressurePlateRender.lua +2 -0
  40. package/callbacks/postPressurePlateUpdate.lua +2 -0
  41. package/callbacks/postProjectileInitLate.lua +2 -0
  42. package/callbacks/postPurchase.lua +2 -0
  43. package/callbacks/postRockRender.lua +2 -0
  44. package/callbacks/postRockUpdate.lua +2 -0
  45. package/callbacks/postRoomClearChanged.lua +2 -0
  46. package/callbacks/postSacrifice.lua +2 -0
  47. package/callbacks/postSlotInitUpdate.lua +2 -0
  48. package/callbacks/postSlotRender.lua +2 -0
  49. package/callbacks/postSpikesRender.lua +2 -0
  50. package/callbacks/postSpikesUpdate.lua +2 -0
  51. package/callbacks/postTNTRender.lua +2 -0
  52. package/callbacks/postTNTUpdate.lua +2 -0
  53. package/callbacks/postTearInitLate.lua +2 -0
  54. package/callbacks/postTearInitVeryLate.lua +2 -0
  55. package/callbacks/postTransformation.lua +2 -0
  56. package/callbacks/postTrinketBreak.lua +2 -0
  57. package/callbacks/preBerserkDeath.lua +2 -0
  58. package/callbacks/preNewLevel.lua +2 -0
  59. package/callbacks/reorderedCallbacks.lua +16 -0
  60. package/callbacks/subscriptions/postBombInitLate.lua +6 -0
  61. package/callbacks/subscriptions/postBoneSwing.lua +6 -0
  62. package/callbacks/subscriptions/postCollectibleInitFirst.lua +6 -0
  63. package/callbacks/subscriptions/postCursedTeleport.lua +6 -0
  64. package/callbacks/subscriptions/postCustomDoorEnter.lua +6 -0
  65. package/callbacks/subscriptions/postCustomRevive.lua +6 -0
  66. package/callbacks/subscriptions/postDoorRender.lua +6 -0
  67. package/callbacks/subscriptions/postDoorUpdate.lua +6 -0
  68. package/callbacks/subscriptions/postEffectInitLate.lua +6 -0
  69. package/callbacks/subscriptions/postEffectStateChanged.lua +6 -0
  70. package/callbacks/subscriptions/postEsauJr.lua +6 -0
  71. package/callbacks/subscriptions/postFamiliarInitLate.lua +6 -0
  72. package/callbacks/subscriptions/postFamiliarStateChanged.lua +6 -0
  73. package/callbacks/subscriptions/postFirstEsauJr.lua +6 -0
  74. package/callbacks/subscriptions/postFirstFlip.lua +6 -0
  75. package/callbacks/subscriptions/postFlip.lua +6 -0
  76. package/callbacks/subscriptions/postGameStartedReordered.lua +6 -0
  77. package/callbacks/subscriptions/postGreedModeWave.lua +6 -0
  78. package/callbacks/subscriptions/postGridEntityBroken.lua +6 -0
  79. package/callbacks/subscriptions/postGridEntityCollision.lua +6 -0
  80. package/callbacks/subscriptions/postGridEntityInit.lua +6 -0
  81. package/callbacks/subscriptions/postGridEntityRemove.lua +6 -0
  82. package/callbacks/subscriptions/postGridEntityRender.lua +6 -0
  83. package/callbacks/subscriptions/postGridEntityStateChanged.lua +6 -0
  84. package/callbacks/subscriptions/postGridEntityUpdate.lua +6 -0
  85. package/callbacks/subscriptions/postHolyMantleRemoved.lua +6 -0
  86. package/callbacks/subscriptions/postItemDischarged.lua +6 -0
  87. package/callbacks/subscriptions/postItemPickup.lua +6 -0
  88. package/callbacks/subscriptions/postKnifeInitLate.lua +6 -0
  89. package/callbacks/subscriptions/postLaserInitLate.lua +6 -0
  90. package/callbacks/subscriptions/postNPCInitLate.lua +6 -0
  91. package/callbacks/subscriptions/postNPCStateChanged.lua +6 -0
  92. package/callbacks/subscriptions/postNewLevelReordered.lua +6 -0
  93. package/callbacks/subscriptions/postNewRoomEarly.lua +6 -0
  94. package/callbacks/subscriptions/postNewRoomReordered.lua +6 -0
  95. package/callbacks/subscriptions/postPEffectUpdateReordered.lua +6 -0
  96. package/callbacks/subscriptions/postPickupCollect.lua +6 -0
  97. package/callbacks/subscriptions/postPickupInitLate.lua +6 -0
  98. package/callbacks/subscriptions/postPickupStateChanged.lua +6 -0
  99. package/callbacks/subscriptions/postPitRender.lua +6 -0
  100. package/callbacks/subscriptions/postPitUpdate.lua +6 -0
  101. package/callbacks/subscriptions/postPlayerChangeHealth.lua +6 -0
  102. package/callbacks/subscriptions/postPlayerChangeType.lua +6 -0
  103. package/callbacks/subscriptions/postPlayerFatalDamage.lua +6 -0
  104. package/callbacks/subscriptions/postPlayerInitLate.lua +6 -0
  105. package/callbacks/subscriptions/postPlayerInitReordered.lua +6 -0
  106. package/callbacks/subscriptions/postPlayerRenderReordered.lua +6 -0
  107. package/callbacks/subscriptions/postPlayerUpdateReordered.lua +6 -0
  108. package/callbacks/subscriptions/postPoopRender.lua +6 -0
  109. package/callbacks/subscriptions/postPoopUpdate.lua +6 -0
  110. package/callbacks/subscriptions/postPressurePlateRender.lua +6 -0
  111. package/callbacks/subscriptions/postPressurePlateUpdate.lua +6 -0
  112. package/callbacks/subscriptions/postProjectileInitLate.lua +6 -0
  113. package/callbacks/subscriptions/postPurchase.lua +6 -0
  114. package/callbacks/subscriptions/postRockRender.lua +6 -0
  115. package/callbacks/subscriptions/postRockUpdate.lua +6 -0
  116. package/callbacks/subscriptions/postRoomClearChanged.lua +6 -0
  117. package/callbacks/subscriptions/postSacrifice.lua +6 -0
  118. package/callbacks/subscriptions/postSlotAnimationChanged.lua +6 -0
  119. package/callbacks/subscriptions/postSlotDestroyed.lua +6 -0
  120. package/callbacks/subscriptions/postSlotInit.lua +6 -0
  121. package/callbacks/subscriptions/postSlotRender.lua +6 -0
  122. package/callbacks/subscriptions/postSlotUpdate.lua +6 -0
  123. package/callbacks/subscriptions/postSpikesRender.lua +6 -0
  124. package/callbacks/subscriptions/postSpikesUpdate.lua +6 -0
  125. package/callbacks/subscriptions/postTNTRender.lua +6 -0
  126. package/callbacks/subscriptions/postTNTUpdate.lua +6 -0
  127. package/callbacks/subscriptions/postTearInitLate.lua +6 -0
  128. package/callbacks/subscriptions/postTearInitVeryLate.lua +6 -0
  129. package/callbacks/subscriptions/postTransformation.lua +6 -0
  130. package/callbacks/subscriptions/postTrinketBreak.lua +6 -0
  131. package/callbacks/subscriptions/preBerserkDeath.lua +6 -0
  132. package/callbacks/subscriptions/preCustomRevive.lua +6 -0
  133. package/callbacks/subscriptions/preItemPickup.lua +6 -0
  134. package/callbacks/subscriptions/preNewLevel.lua +6 -0
  135. package/classes/DefaultMap.d.ts +70 -39
  136. package/classes/DefaultMap.lua +94 -43
  137. package/classes/ModUpgraded.d.ts +3 -3
  138. package/classes/ModUpgraded.lua +5 -0
  139. package/constants.lua +41 -0
  140. package/constantsFirstLast.lua +63 -0
  141. package/enums/HealthType.lua +3 -0
  142. package/enums/ModCallbackCustom.d.ts +1 -1
  143. package/enums/ModCallbackCustom.lua +6 -0
  144. package/enums/private/CopyableIsaacAPIClassType.lua +1 -0
  145. package/enums/private/SerializationBrand.lua +5 -0
  146. package/features/characterHealthConversion.lua +6 -0
  147. package/features/characterStats.lua +17 -0
  148. package/features/debugDisplay/exports.lua +90 -0
  149. package/features/deployJSONRoom.lua +56 -0
  150. package/features/disableInputs.lua +45 -0
  151. package/features/disableSound.lua +14 -0
  152. package/features/extraConsoleCommands/commandsDisplay.lua +90 -0
  153. package/features/extraConsoleCommands/init.lua +16 -0
  154. package/features/extraConsoleCommands/listCommands.lua +172 -0
  155. package/features/fadeInRemover.lua +10 -0
  156. package/features/fastReset.lua +10 -0
  157. package/features/forgottenSwitch.lua +4 -0
  158. package/features/getCollectibleItemPoolType.lua +5 -0
  159. package/features/playerInventory.lua +18 -0
  160. package/features/ponyDetection.lua +4 -0
  161. package/features/preventCollectibleRotation.lua +9 -0
  162. package/features/runInNFrames.lua +50 -0
  163. package/features/saveDataManager/constants.lua +1 -0
  164. package/features/saveDataManager/exports.lua +115 -0
  165. package/features/saveDataManager/main.lua +6 -0
  166. package/features/saveDataManager/maps.lua +3 -0
  167. package/features/saveDataManager/merge.lua +20 -0
  168. package/features/sirenHelpers.lua +13 -0
  169. package/features/taintedLazarusPlayers.lua +11 -0
  170. package/featuresInitialized.lua +6 -0
  171. package/functions/array.lua +85 -0
  172. package/functions/benchmark.lua +6 -0
  173. package/functions/boss.lua +35 -0
  174. package/functions/cacheFlag.lua +4 -0
  175. package/functions/cards.lua +60 -0
  176. package/functions/challenges.lua +1 -0
  177. package/functions/character.lua +23 -0
  178. package/functions/charge.lua +39 -0
  179. package/functions/chargeBar.lua +4 -0
  180. package/functions/collectibleCacheFlag.lua +15 -0
  181. package/functions/collectibleSet.lua +3 -0
  182. package/functions/collectibleTag.lua +9 -0
  183. package/functions/collectibles.lua +131 -0
  184. package/functions/color.lua +18 -0
  185. package/functions/debug.lua +18 -0
  186. package/functions/deepCopy.lua +25 -0
  187. package/functions/doors.lua +53 -0
  188. package/functions/entity.lua +88 -0
  189. package/functions/entitySpecific.lua +182 -0
  190. package/functions/entityTypes.d.ts +1 -1
  191. package/functions/entityTypes.lua +1 -0
  192. package/functions/enums.lua +62 -0
  193. package/functions/familiars.lua +52 -0
  194. package/functions/flag.lua +77 -0
  195. package/functions/flying.lua +10 -0
  196. package/functions/globals.lua +6 -0
  197. package/functions/gridEntity.lua +105 -0
  198. package/functions/gridEntitySpecific.lua +8 -0
  199. package/functions/input.lua +11 -0
  200. package/functions/isaacAPIClass.lua +12 -0
  201. package/functions/jsonHelpers.lua +11 -0
  202. package/functions/jsonRoom.lua +5 -0
  203. package/functions/kColor.lua +9 -0
  204. package/functions/language.lua +5 -0
  205. package/functions/log.lua +28 -0
  206. package/functions/map.lua +18 -0
  207. package/functions/math.lua +26 -0
  208. package/functions/npc.lua +24 -0
  209. package/functions/pickupVariants.d.ts +11 -11
  210. package/functions/pickupVariants.lua +11 -0
  211. package/functions/pickups.lua +67 -0
  212. package/functions/pills.lua +45 -0
  213. package/functions/player.lua +166 -0
  214. package/functions/playerDataStructures.lua +65 -0
  215. package/functions/playerHealth.lua +10 -0
  216. package/functions/playerIndex.lua +47 -0
  217. package/functions/pocketItems.lua +18 -0
  218. package/functions/positionVelocity.lua +46 -0
  219. package/functions/random.lua +32 -0
  220. package/functions/revive.lua +15 -0
  221. package/functions/rng.lua +19 -0
  222. package/functions/roomData.lua +68 -0
  223. package/functions/roomGrid.lua +21 -0
  224. package/functions/roomShape.lua +22 -0
  225. package/functions/rooms.lua +100 -0
  226. package/functions/run.lua +5 -0
  227. package/functions/seeds.lua +4 -0
  228. package/functions/serialization.lua +4 -0
  229. package/functions/set.lua +22 -0
  230. package/functions/spawnCollectible.lua +24 -0
  231. package/functions/sprite.lua +25 -0
  232. package/functions/stage.lua +16 -0
  233. package/functions/string.lua +6 -0
  234. package/functions/table.lua +19 -0
  235. package/functions/tears.lua +12 -0
  236. package/functions/transformations.lua +18 -0
  237. package/functions/trinketCacheFlag.lua +3 -0
  238. package/functions/trinketGive.lua +24 -0
  239. package/functions/trinkets.lua +52 -0
  240. package/functions/tstlClass.lua +9 -0
  241. package/functions/ui.lua +16 -0
  242. package/functions/utils.d.ts +1 -0
  243. package/functions/utils.lua +88 -0
  244. package/functions/vector.lua +9 -0
  245. package/lualib_bundle.lua +21 -34
  246. package/maps/cardMap.lua +1 -0
  247. package/maps/characterMap.lua +1 -0
  248. package/maps/defaultPlayerStatMap.lua +1 -0
  249. package/maps/gridEntityXMLMap.lua +2 -0
  250. package/maps/pillEffectMap.lua +1 -0
  251. package/maps/roomShapeToTopLeftWallGridIndexMap.lua +2 -0
  252. package/maps/roomTypeMap.lua +1 -0
  253. package/objects/LRoomShapeToRectangles.lua +2 -0
  254. package/objects/colors.lua +4 -0
  255. package/objects/roomShapeBounds.lua +2 -0
  256. package/objects/roomShapeLayoutSizes.lua +4 -0
  257. package/objects/roomShapeToBottomRightPosition.lua +2 -0
  258. package/objects/roomShapeToDoorSlotsToGridIndexDelta.lua +2 -0
  259. package/objects/roomShapeToTopLeftPosition.lua +2 -0
  260. package/objects/roomShapeVolumes.lua +3 -0
  261. package/package.json +2 -2
  262. package/patchErrorFunctions.lua +8 -0
  263. package/sets/bossSets.lua +23 -0
  264. package/sets/charactersWithNoRedHeartsSet.lua +2 -0
  265. package/sets/charactersWithNoSoulHeartsSet.lua +2 -0
  266. package/sets/lostStyleCharactersSet.lua +2 -0
  267. package/types/PickingUpItem.lua +7 -0
  268. package/upgradeMod.d.ts +4 -4
  269. package/upgradeMod.lua +18 -0
@@ -26,10 +26,15 @@ function postPickupInitCollectible(self, pickup)
26
26
  end
27
27
  local FEATURE_NAME = "get collectible item pool type"
28
28
  v = {run = {collectibleItemPoolTypeMap = __TS__New(Map)}}
29
+ ---
30
+ -- @internal
29
31
  function ____exports.getCollectibleItemPoolTypeInit(self, mod)
30
32
  saveDataManager(nil, "getCollectibleItemPoolType", v)
31
33
  mod:AddCallback(ModCallback.POST_PICKUP_INIT, postPickupInitCollectible, PickupVariant.COLLECTIBLE)
32
34
  end
35
+ --- Helper function to get the item pool type that a given collectible came from. Since there is no
36
+ -- native method in the API to get this, we listen in the PreGetCollectible callback for item pool
37
+ -- types, and then assume that the next spawned collectible will match.
33
38
  function ____exports.getCollectibleItemPoolType(self, collectible)
34
39
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
35
40
  if not isCollectible(nil, collectible) then
@@ -94,12 +94,24 @@ v = {run = {
94
94
  function() return {} end
95
95
  )
96
96
  }}
97
+ ---
98
+ -- @internal
97
99
  function ____exports.playerInventoryInit(self, mod)
98
100
  saveDataManager(nil, "playerInventory", v)
99
101
  mod:AddCallback(ModCallback.POST_USE_ITEM, useItemD4, CollectibleType.D4)
100
102
  mod:AddCallback(ModCallback.POST_GAME_STARTED, postGameStarted)
101
103
  mod:AddCallbackCustom(ModCallbackCustom.POST_ITEM_PICKUP, postItemPickup)
102
104
  end
105
+ --- Helper function to get all of the collectibles that the player has gotten so far on this run, in
106
+ -- order.
107
+ --
108
+ -- Note that this does not include active collectibles that have since been dropped for other
109
+ -- collectibles.
110
+ --
111
+ -- In the case of inventory initialization or the case where the player rerolls their build in the
112
+ -- middle of the run (e.g. with D4), the order of the inventory will not correspond to the order
113
+ -- that the items were actually given to the player. In this case, the inventory will be in the
114
+ -- order of the lowest `CollectibleType` to the highest.
103
115
  function ____exports.getPlayerInventory(self, player, includeActiveCollectibles)
104
116
  if includeActiveCollectibles == nil then
105
117
  includeActiveCollectibles = true
@@ -116,6 +128,12 @@ function ____exports.getPlayerInventory(self, player, includeActiveCollectibles)
116
128
  function(____, collectibleType) return not isActiveCollectible(nil, collectibleType) end
117
129
  )
118
130
  end
131
+ --- Helper function to add a collectible to a player. Use this instead of the
132
+ -- `EntityPlayer.AddCollectible` method if you want the collectible that is added to be
133
+ -- automatically tracked by the player inventory tracker feature.
134
+ --
135
+ -- You only need to use this function if you are using the inventory feature from the standard
136
+ -- library.
119
137
  function ____exports.addCollectible(self, player, collectibleType, charge, firstTimePickingUp, activeSlot, varData)
120
138
  player:AddCollectible(
121
139
  collectibleType,
@@ -38,10 +38,14 @@ end
38
38
  local FEATURE_NAME = "pony activation detector"
39
39
  FLAGS_WHEN_PONY_IS_ACTIVE = {EntityFlag.NO_KNOCKBACK, EntityFlag.NO_PHYSICS_KNOCKBACK, EntityFlag.NO_DAMAGE_BLINK}
40
40
  v = {run = {playersIsPonyActive = __TS__New(Set)}}
41
+ ---
42
+ -- @internal
41
43
  function ____exports.ponyDetectionInit(self, mod)
42
44
  saveDataManager(nil, "ponyDetection", v)
43
45
  mod:AddCallbackCustom(ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED, postPEffectUpdateReordered)
44
46
  end
47
+ --- Helper function to see if the player is under the effects of A Pony or White Pony charge.
48
+ -- Detecting this is difficult, as the temporary effect will disappear upon entering a new room.
45
49
  function ____exports.isPonyActive(self, player)
46
50
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
47
51
  return setHasPlayer(nil, v.run.playersIsPonyActive, player)
@@ -40,11 +40,20 @@ function getMapIndex(self, collectible)
40
40
  end
41
41
  local FEATURE_NAME = "prevent collectible rotation"
42
42
  v = {room = {trackedCollectibles = __TS__New(Map)}}
43
+ ---
44
+ -- @internal
43
45
  function ____exports.preventCollectibleRotationInit(self, mod)
44
46
  saveDataManager(nil, "preventCollectibleRotation", v)
45
47
  mod:AddCallback(ModCallback.POST_USE_CARD, useCardSoulOfIsaac, Card.SOUL_ISAAC)
46
48
  mod:AddCallback(ModCallback.POST_PICKUP_UPDATE, postPickupUpdateCollectible, PickupVariant.COLLECTIBLE)
47
49
  end
50
+ --- Helper function to prevent a collectible from being affected by Tainted Isaac's rotation
51
+ -- mechanic. (This mechanic also happens from Glitched Crown and Binge Eater.) This is useful
52
+ -- because quest items that are manually spawned by mods will be automatically be affected by this
53
+ -- mechanic.
54
+ --
55
+ -- It is required to pass the intended collectible type to this function since it is possible for
56
+ -- collectibles to rotate on the first frame that they are spawned.
48
57
  function ____exports.preventCollectibleRotation(self, collectible, collectibleType)
49
58
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
50
59
  if not isCollectible(nil, collectible) then
@@ -41,6 +41,8 @@ function checkExecuteQueuedFunctions(self, frameCount, functionTuples)
41
41
  end
42
42
  local FEATURE_NAME = "run in N frames"
43
43
  v = {run = {queuedGameFunctionTuples = {}, queuedRenderFunctionTuples = {}}}
44
+ ---
45
+ -- @internal
44
46
  function ____exports.runInNFramesInit(self, mod)
45
47
  saveDataManager(
46
48
  nil,
@@ -51,6 +53,14 @@ function ____exports.runInNFramesInit(self, mod)
51
53
  mod:AddCallback(ModCallback.POST_UPDATE, postUpdate)
52
54
  mod:AddCallback(ModCallback.POST_RENDER, postRender)
53
55
  end
56
+ --- Supply a function to run N game frames from now in the PostUpdate callback.
57
+ --
58
+ -- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
59
+ -- way.
60
+ --
61
+ -- Note that this function will not handle saving and quitting. If a player saving and quitting
62
+ -- before the deferred function fires would cause a bug in your mod, then you should handle deferred
63
+ -- functions manually using serializable data.
54
64
  function ____exports.runInNGameFrames(self, func, gameFrames)
55
65
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
56
66
  local gameFrameCount = game:GetFrameCount()
@@ -59,6 +69,14 @@ function ____exports.runInNGameFrames(self, func, gameFrames)
59
69
  local ____v_run_queuedGameFunctionTuples_0 = v.run.queuedGameFunctionTuples
60
70
  ____v_run_queuedGameFunctionTuples_0[#____v_run_queuedGameFunctionTuples_0 + 1] = tuple
61
71
  end
72
+ --- Supply a function to run N render frames from now in the PostRender callback.
73
+ --
74
+ -- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
75
+ -- way.
76
+ --
77
+ -- Note that this function will not handle saving and quitting. If a player saving and quitting
78
+ -- before the deferred function fires would cause a bug in your mod, then you should handle deferred
79
+ -- functions manually using serializable data.
62
80
  function ____exports.runInNRenderFrames(self, func, renderFrames)
63
81
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
64
82
  local renderFrameCount = Isaac.GetFrameCount()
@@ -67,10 +85,42 @@ function ____exports.runInNRenderFrames(self, func, renderFrames)
67
85
  local ____v_run_queuedRenderFunctionTuples_1 = v.run.queuedRenderFunctionTuples
68
86
  ____v_run_queuedRenderFunctionTuples_1[#____v_run_queuedRenderFunctionTuples_1 + 1] = tuple
69
87
  end
88
+ --- Supply a function to run on the next PostUpdate callback.
89
+ --
90
+ -- For example:
91
+ --
92
+ -- ```ts
93
+ -- const NUM_EXPLODER_EXPLOSIONS = 5;
94
+ --
95
+ -- function useItemExploder(player: EntityPlayer) {
96
+ -- playSound("exploderBegin");
97
+ -- explode(player, NUM_EXPLODER_EXPLOSIONS);
98
+ -- }
99
+ --
100
+ -- function explode(player: EntityPlayer, numFramesLeft: int) {
101
+ -- Isaac.Explode(player, undefined, 1);
102
+ -- numFramesLeft -= 1;
103
+ -- if (numFramesLeft === 0) {
104
+ -- runNextFrame(() => {
105
+ -- explode(player, numFramesLeft);
106
+ -- });
107
+ -- }
108
+ -- }
109
+ -- ```
110
+ --
111
+ -- Note that this function will not handle saving and quitting. If a player saving and quitting
112
+ -- before the deferred function fires would cause a bug in your mod, then you should handle deferred
113
+ -- functions manually using serializable data.
70
114
  function ____exports.runNextGameFrame(self, func)
71
115
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
72
116
  ____exports.runInNGameFrames(nil, func, 1)
73
117
  end
118
+ --- Supply a function to run on the next PostRender callback.
119
+ --
120
+ -- For a usage example, see the documentation for the `runNextGameFrame`, which is used in a similar
121
+ -- way.
122
+ --
123
+ -- Note that this function will not handle saving and quitting.
74
124
  function ____exports.runNextRenderFrame(self, func)
75
125
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
76
126
  ____exports.runInNRenderFrames(nil, func, 1)
@@ -1,4 +1,5 @@
1
1
  local ____exports = {}
2
+ --- Set this to true to enable more verbosity in the save data manger.
2
3
  ____exports.SAVE_DATA_MANAGER_DEBUG = false
3
4
  ____exports.SAVE_DATA_MANAGER_FEATURE_NAME = "save data manager"
4
5
  return ____exports
@@ -18,6 +18,89 @@ local ____maps = require("features.saveDataManager.maps")
18
18
  local saveDataConditionalFuncMap = ____maps.saveDataConditionalFuncMap
19
19
  local saveDataDefaultsMap = ____maps.saveDataDefaultsMap
20
20
  local saveDataMap = ____maps.saveDataMap
21
+ --- This is the entry point to the save data manager, a system which provides two major features:
22
+ --
23
+ -- 1. automatic resetting of variables on a new run, on a new level, or on a new room (as desired)
24
+ -- 2. automatic saving and loading of all tracked data to the "save#.dat" file
25
+ --
26
+ -- You feed this function with an anonymous object containing your variables, and then it will
27
+ -- automatically manage them for you. (See below for an example.)
28
+ --
29
+ -- The save data manager is meant to be called once for each feature of your mod. In other words,
30
+ -- you should not put all of the data for your mod on the same object. Instead, scope your variables
31
+ -- locally to a single file that contains a mod feature, and then call this function to register
32
+ -- them. For example:
33
+ --
34
+ -- ```ts
35
+ -- // in file: feature1.ts
36
+ -- import { saveDataManager } from "isaacscript-common";
37
+ --
38
+ -- // Declare local variables for this file or feature.
39
+ -- const v = {
40
+ -- // These variables are never reset; manage them yourself at will.
41
+ -- persistent: {
42
+ -- foo1: 0,
43
+ -- },
44
+ --
45
+ -- // These variables are reset at the beginning of every run.
46
+ -- run: {
47
+ -- foo2: 0,
48
+ -- },
49
+ --
50
+ -- // These variables are reset at the beginning of every level.
51
+ -- level: {
52
+ -- foo3: 0,
53
+ -- },
54
+ --
55
+ -- // These variables are reset at the beginning of every room.
56
+ -- room: {
57
+ -- foo4: 0,
58
+ -- },
59
+ -- };
60
+ -- // Every child object is optional; only create the ones that you need.
61
+ --
62
+ -- // Register the variables with the save data manager. (We need to provide a string key that
63
+ -- // matches the name of this file.)
64
+ -- function feature1Init() {
65
+ -- saveDataManager("feature1", v);
66
+ -- }
67
+ --
68
+ -- // Elsewhere in the file, use your variables.
69
+ -- function feature1Function() {
70
+ -- if (v.run.foo1 > 0) {
71
+ -- // Insert code here.
72
+ -- }
73
+ -- }
74
+ -- ```
75
+ --
76
+ -- - Save data is loaded from disk in the `POST_PLAYER_INIT` callback (i.e. the first callback that
77
+ -- can possibly run).
78
+ -- - Save data is recorded to disk in the `PRE_GAME_EXIT` callback.
79
+ --
80
+ -- Note that before using the save data manager, you must call the `upgradeMod` function. (Upgrade
81
+ -- your mod before registering any of your own callbacks so that the save data manager will run
82
+ -- before any of your code does.)
83
+ --
84
+ -- If you want the save data manager to load data before the `POST_PLAYER_INIT` callback (i.e. in
85
+ -- the main menu), then you should explicitly call the `saveDataManagerLoad` function. (The save
86
+ -- data manager cannot do this on its own because it cannot know when your mod features are finished
87
+ -- initializing.)
88
+ --
89
+ -- Finally, some features may have variables that need to be automatically reset per run/level, but
90
+ -- not saved to disk on game exit. (For example, if they contain functions or other non-serializable
91
+ -- data.) For these cases, set the second argument to `() => false`.
92
+ --
93
+ -- @param key The name of the file or feature that is submitting data to be managed by the save data
94
+ -- manager. The save data manager will throw an error if the key is already registered.
95
+ -- @param v An object that corresponds to the `SaveData` interface. The object is conventionally
96
+ -- called "v" for brevity. ("v" is short for "local variables").
97
+ -- @param conditionalFunc An optional function to run upon saving this key to disk. For example,
98
+ -- this allows features to only save data to disk if the feature is enabled.
99
+ -- Specify a value of `() => false` to completely disable saving this feature
100
+ -- to disk. Disabling saving to disk is useful if you are using data that is
101
+ -- not serializable. Alternatively, it could be useful if you want to use the
102
+ -- save data manager to automatically reset variables on run/level/room, but
103
+ -- not clutter the the "save#.dat" file with unnecessary keys.
21
104
  function ____exports.saveDataManager(self, key, v, conditionalFunc)
22
105
  errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
23
106
  local keyType = type(key)
@@ -39,18 +122,50 @@ function ____exports.saveDataManager(self, key, v, conditionalFunc)
39
122
  saveDataConditionalFuncMap:set(key, conditionalFunc)
40
123
  end
41
124
  end
125
+ --- The save data manager will automatically load variables from disk at the appropriate times (i.e.
126
+ -- when a new run is started). Use this function to explicitly force the save data manager to load
127
+ -- all of its variables from disk immediately.
128
+ --
129
+ -- Obviously, doing this will overwrite the current data, so using this function can potentially
130
+ -- result in lost state.
42
131
  function ____exports.saveDataManagerLoad(self)
43
132
  errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
44
133
  forceSaveDataManagerLoad(nil)
45
134
  end
135
+ --- The save data manager will automatically save variables to disk at the appropriate times (i.e.
136
+ -- when the run is exited). Use this function to explicitly force the save data manager to write all
137
+ -- of its variables to disk immediately.
46
138
  function ____exports.saveDataManagerSave(self)
47
139
  errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
48
140
  forceSaveDataManagerSave(nil)
49
141
  end
142
+ --- - Sets the global variable of "g" equal to all of the save data variables for this mod.
143
+ -- - Sets the global variable of "gd" equal to all of the save data default variables for this mod.
144
+ --
145
+ -- This can make debugging easier, as you can access the variables from the game's debug console.
146
+ -- e.g. `l print(g.feature1.foo)`
50
147
  function ____exports.saveDataManagerSetGlobal(self)
51
148
  g = saveDataMap
52
149
  gd = saveDataDefaultsMap
53
150
  end
151
+ --- The save data manager will automatically reset variables at the appropriate times (i.e. when a
152
+ -- player enters a new room). Use this function to explicitly force the save data manager to reset a
153
+ -- specific variable group.
154
+ --
155
+ -- For example:
156
+ --
157
+ -- ```ts
158
+ -- const v = {
159
+ -- room: {
160
+ -- foo: 123,
161
+ -- },
162
+ -- };
163
+ --
164
+ -- saveDataManager("file1", v);
165
+ --
166
+ -- // Then, later on, to explicit reset all of the "room" variables:
167
+ -- saveDataManagerReset("file1", "room");
168
+ -- ```
54
169
  function ____exports.saveDataManagerReset(self, key, childObjectKey)
55
170
  errorIfFeaturesNotInitialized(nil, SAVE_DATA_MANAGER_FEATURE_NAME)
56
171
  local keyType = type(key)
@@ -97,6 +97,8 @@ function clearAndCopyAllElements(self, oldTable, newTable)
97
97
  end
98
98
  mod = nil
99
99
  loadedDataOnThisRun = false
100
+ ---
101
+ -- @internal
100
102
  function ____exports.saveDataManagerInit(self, incomingMod)
101
103
  mod = incomingMod
102
104
  mod:AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit)
@@ -104,12 +106,16 @@ function ____exports.saveDataManagerInit(self, incomingMod)
104
106
  mod:AddCallback(ModCallback.POST_NEW_LEVEL, postNewLevel)
105
107
  mod:AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_EARLY, postNewRoomEarly)
106
108
  end
109
+ ---
110
+ -- @internal
107
111
  function ____exports.forceSaveDataManagerSave(self)
108
112
  if mod == nil then
109
113
  return
110
114
  end
111
115
  saveToDisk(nil, mod, saveDataMap, saveDataConditionalFuncMap)
112
116
  end
117
+ ---
118
+ -- @internal
113
119
  function ____exports.forceSaveDataManagerLoad(self)
114
120
  if mod == nil then
115
121
  return
@@ -2,6 +2,9 @@ local ____lualib = require("lualib_bundle")
2
2
  local Map = ____lualib.Map
3
3
  local __TS__New = ____lualib.__TS__New
4
4
  local ____exports = {}
5
+ --- The save data map is indexed by subscriber name. We use Lua tables instead of TypeScriptToLua
6
+ -- Maps for the master map so that we can access the variables via the in-game console when
7
+ -- debugging. (TSTL Maps don't expose the map keys as normal keys.)
5
8
  ____exports.saveDataMap = {}
6
9
  ____exports.saveDataDefaultsMap = {}
7
10
  ____exports.saveDataConditionalFuncMap = __TS__New(Map)
@@ -25,6 +25,26 @@ local ____constants = require("features.saveDataManager.constants")
25
25
  local SAVE_DATA_MANAGER_DEBUG = ____constants.SAVE_DATA_MANAGER_DEBUG
26
26
  local ____serializationBrand = require("features.saveDataManager.serializationBrand")
27
27
  local isSerializationBrand = ____serializationBrand.isSerializationBrand
28
+ --- `merge` takes the values from a new table and recursively merges them into an old object (while
29
+ -- performing appropriate deserialization).
30
+ --
31
+ -- It supports the following object types:
32
+ --
33
+ -- - `LuaTable` / basic TSTL objects
34
+ -- - TSTL `Map`
35
+ -- - TSTL `Set`
36
+ -- - TSTL classes
37
+ -- - `DefaultMap`
38
+ -- - Isaac `Color` objects
39
+ -- - Isaac `KColor` objects
40
+ -- - Isaac `RNG` objects
41
+ -- - Isaac `Vector` objects
42
+ --
43
+ -- Since it is common for a variable to have a type of `something | null`, we must iterate over the
44
+ -- new object and copy over all of the values. (A value of null transpiles to nil, which means the
45
+ -- table key does not exist.) The consequence of this is that it can copy over old variables that
46
+ -- are no longer used in the code, or copy over old variables of a different type, which can cause
47
+ -- run-time errors. In such cases, users will have to manually delete their save data.
28
48
  function ____exports.merge(self, oldObject, newTable, traversalDescription)
29
49
  if SAVE_DATA_MANAGER_DEBUG then
30
50
  log("merge is traversing: " .. traversalDescription)
@@ -50,10 +50,18 @@ function getSirenHelper(self, familiar)
50
50
  end
51
51
  local FEATURE_NAME = "siren helpers"
52
52
  v = {run = {familiarBlacklist = {}}}
53
+ ---
54
+ -- @internal
53
55
  function ____exports.sirenHelpersInit(self, mod)
54
56
  saveDataManager(nil, "sirenHelpers", v)
55
57
  mod:AddCallback(ModCallback.POST_NPC_INIT, postNPCInitSirenHelper, EntityType.SIREN_HELPER)
56
58
  end
59
+ --- Blacklists a familiar from being stolen by The Siren boss. This should be called once at the
60
+ -- beginning of every run.
61
+ --
62
+ -- @param familiarVariant The familiar variant to blacklist.
63
+ -- @param familiarSubType The sub-type to blacklist. Optional. The default is to blacklist all
64
+ -- sub-types of the given variant.
57
65
  function ____exports.setFamiliarNoSirenSteal(self, familiarVariant, familiarSubType)
58
66
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
59
67
  if blacklistEntryExists(nil, familiarVariant, familiarSubType) then
@@ -62,6 +70,11 @@ function ____exports.setFamiliarNoSirenSteal(self, familiarVariant, familiarSubT
62
70
  local ____v_run_familiarBlacklist_0 = v.run.familiarBlacklist
63
71
  ____v_run_familiarBlacklist_0[#____v_run_familiarBlacklist_0 + 1] = {familiarVariant, familiarSubType}
64
72
  end
73
+ --- Helper function to check if the Siren boss has stolen a familiar. Some familiars may need to
74
+ -- behave differently when under The Siren's control (e.g. if they auto-target enemies).
75
+ --
76
+ -- @param familiar The familiar to be checked.
77
+ -- @returns Returns whether the familiar has been stolen by The Siren.
65
78
  function ____exports.hasSirenStolenFamiliar(self, familiar)
66
79
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
67
80
  return getSirenHelper(nil, familiar) ~= nil
@@ -49,6 +49,8 @@ v = {run = {
49
49
  queuedDeadTaintedLazarus = {},
50
50
  subPlayerMap = __TS__New(Map)
51
51
  }}
52
+ ---
53
+ -- @internal
52
54
  function ____exports.taintedLazarusPlayersInit(self, mod)
53
55
  saveDataManager(
54
56
  nil,
@@ -58,6 +60,15 @@ function ____exports.taintedLazarusPlayersInit(self, mod)
58
60
  )
59
61
  mod:AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit)
60
62
  end
63
+ --- Helper function to get the other version of Tainted Lazarus.
64
+ --
65
+ -- - On Tainted Lazarus, returns the player object for Dead Tainted Lazarus.
66
+ -- - On Dead Tainted Lazarus, returns the player object for Tainted Lazarus.
67
+ -- - Returns undefined if player object retrieval failed for any reason.
68
+ --
69
+ -- If you call the `EntityPlayer.Exists` method on the returned object, it will return false.
70
+ -- However, you can still call the other methods like you normally would (e.g.
71
+ -- `EntityPlayer.AddCollectible`).
61
72
  function ____exports.getTaintedLazarusSubPlayer(self, player)
62
73
  errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
63
74
  local ptrHash = GetPtrHash(player)
@@ -1,13 +1,19 @@
1
1
  local ____exports = {}
2
2
  local featuresInitialized = false
3
+ ---
4
+ -- @internal
3
5
  function ____exports.areFeaturesInitialized(self)
4
6
  return featuresInitialized
5
7
  end
8
+ ---
9
+ -- @internal
6
10
  function ____exports.errorIfFeaturesNotInitialized(self, featureName)
7
11
  if not ____exports.areFeaturesInitialized(nil) then
8
12
  error(("The " .. featureName) .. " is not initialized. You must first upgrade your mod object by calling the \"upgradeMod\" function.")
9
13
  end
10
14
  end
15
+ ---
16
+ -- @internal
11
17
  function ____exports.setFeaturesInitialized(self)
12
18
  featuresInitialized = true
13
19
  end
@@ -20,6 +20,11 @@ local newRNG = ____rng.newRNG
20
20
  local ____utils = require("functions.utils")
21
21
  local erange = ____utils.erange
22
22
  local ____repeat = ____utils["repeat"]
23
+ --- Helper function to get a random index from the provided array.
24
+ --
25
+ -- @param array The array to get the index from.
26
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
27
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
23
28
  function ____exports.getRandomArrayIndex(self, array, seedOrRNG)
24
29
  if seedOrRNG == nil then
25
30
  seedOrRNG = getRandomSeed(nil)
@@ -29,6 +34,13 @@ function ____exports.getRandomArrayIndex(self, array, seedOrRNG)
29
34
  end
30
35
  return getRandomInt(nil, 0, #array - 1, seedOrRNG)
31
36
  end
37
+ --- Shuffles the provided array in-place using the Fisher-Yates algorithm.
38
+ --
39
+ -- From: https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
40
+ --
41
+ -- @param array The array to shuffle.
42
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
43
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
32
44
  function ____exports.shuffleArrayInPlace(self, array, seedOrRNG)
33
45
  if seedOrRNG == nil then
34
46
  seedOrRNG = getRandomSeed(nil)
@@ -44,6 +56,8 @@ function ____exports.shuffleArrayInPlace(self, array, seedOrRNG)
44
56
  array[randomIndex + 1] = ____temp_0[2]
45
57
  end
46
58
  end
59
+ --- Helper function for determining if two arrays contain the exact same elements. Note that this
60
+ -- only performs a shallow comparison.
47
61
  function ____exports.arrayEquals(self, array1, array2)
48
62
  if #array1 ~= #array2 then
49
63
  return false
@@ -56,6 +70,11 @@ function ____exports.arrayEquals(self, array1, array2)
56
70
  end
57
71
  )
58
72
  end
73
+ --- Shallow copies and removes the specified element(s) from the array. Returns the copied array. If
74
+ -- the specified element(s) are not found in the array, it will simply return a shallow copy of the
75
+ -- array.
76
+ --
77
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
59
78
  function ____exports.arrayRemove(self, originalArray, ...)
60
79
  local elementsToRemove = {...}
61
80
  local elementsToRemoveSet = __TS__New(Set, elementsToRemove)
@@ -67,6 +86,10 @@ function ____exports.arrayRemove(self, originalArray, ...)
67
86
  end
68
87
  return array
69
88
  end
89
+ --- Removes the specified element(s) from the array. If the specified element(s) are not found in the
90
+ -- array, this function will do nothing. Returns whether or not one or more elements were removed.
91
+ --
92
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
70
93
  function ____exports.arrayRemoveInPlace(self, array, ...)
71
94
  local elementsToRemove = {...}
72
95
  local removedOneOrMoreElements = false
@@ -79,6 +102,11 @@ function ____exports.arrayRemoveInPlace(self, array, ...)
79
102
  end
80
103
  return removedOneOrMoreElements
81
104
  end
105
+ --- Shallow copies and removes the elements at the specified indexes from the array. Returns the
106
+ -- copied array. If the specified indexes are not found in the array, it will simply return a
107
+ -- shallow copy of the array.
108
+ --
109
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
82
110
  function ____exports.arrayRemoveIndex(self, originalArray, ...)
83
111
  local indexesToRemove = {...}
84
112
  local indexesToRemoveSet = __TS__New(Set, indexesToRemove)
@@ -93,6 +121,11 @@ function ____exports.arrayRemoveIndex(self, originalArray, ...)
93
121
  )
94
122
  return array
95
123
  end
124
+ --- Removes the elements at the specified indexes from the array. If the specified indexes are not
125
+ -- found in the array, this function will do nothing. Returns whether or not one or more elements
126
+ -- were removed.
127
+ --
128
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
96
129
  function ____exports.arrayRemoveIndexInPlace(self, array, ...)
97
130
  local indexesToRemove = {...}
98
131
  local legalIndexes = __TS__ArrayFilter(
@@ -123,6 +156,11 @@ function ____exports.arrayToString(self, array)
123
156
  local commaSeparatedStrings = table.concat(strings, ", ")
124
157
  return ("[" .. commaSeparatedStrings) .. "]"
125
158
  end
159
+ --- Helper function to combine two or more arrays. Returns a new array that is the composition of all
160
+ -- of the specified arrays.
161
+ --
162
+ -- This function is variadic, meaning that you can specify N arguments to combine N arrays. Note
163
+ -- that this will only perform a shallow copy of the array elements.
126
164
  function ____exports.combineArrays(self, ...)
127
165
  local arrays = {...}
128
166
  local elements = {}
@@ -133,6 +171,11 @@ function ____exports.combineArrays(self, ...)
133
171
  end
134
172
  return elements
135
173
  end
174
+ --- Helper function to perform a shallow copy.
175
+ --
176
+ -- @param oldArray The array to copy.
177
+ -- @param numElements Optional. If specified, will only copy the first N elements. By default, the
178
+ -- entire array will be copied.
136
179
  function ____exports.copyArray(self, oldArray, numElements)
137
180
  if numElements == nil then
138
181
  numElements = #oldArray
@@ -153,12 +196,24 @@ end
153
196
  function ____exports.emptyArray(self, array)
154
197
  __TS__ArraySplice(array, 0, #array)
155
198
  end
199
+ --- Helper function to get an array containing the indexes of an array.
200
+ --
201
+ -- For example, an array of `["Apple", "Banana"]` would return an array of `[0, 1]`.
156
202
  function ____exports.getArrayIndexes(self, array)
157
203
  return erange(nil, #array)
158
204
  end
205
+ --- Helper function to return the last element of an array.
206
+ --
207
+ -- If the array is empty, this will return undefined.
159
208
  function ____exports.getLastElement(self, array)
160
209
  return array[#array]
161
210
  end
211
+ --- Helper function to get a random element from the provided array.
212
+ --
213
+ -- @param array The array to get an element from.
214
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
215
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
216
+ -- @param exceptions Optional. An array of elements to skip over if selected.
162
217
  function ____exports.getRandomArrayElement(self, array, seedOrRNG, exceptions)
163
218
  if seedOrRNG == nil then
164
219
  seedOrRNG = getRandomSeed(nil)
@@ -181,6 +236,13 @@ function ____exports.getRandomArrayElement(self, array, seedOrRNG, exceptions)
181
236
  end
182
237
  return randomElement
183
238
  end
239
+ --- Helper function to get a random element from the provided array. Once the random element is
240
+ -- decided, it is then removed from the array (in-place).
241
+ --
242
+ -- @param array The array to get an element from.
243
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
244
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
245
+ -- @param exceptions Optional. An array of elements to skip over if selected.
184
246
  function ____exports.getRandomArrayElementAndRemove(self, array, seedOrRNG, exceptions)
185
247
  if seedOrRNG == nil then
186
248
  seedOrRNG = getRandomSeed(nil)
@@ -192,6 +254,13 @@ function ____exports.getRandomArrayElementAndRemove(self, array, seedOrRNG, exce
192
254
  ____exports.arrayRemoveInPlace(nil, array, randomArrayElement)
193
255
  return randomArrayElement
194
256
  end
257
+ --- Initializes an array with all elements containing the specified default value.
258
+ --
259
+ -- For example:
260
+ --
261
+ -- ```ts
262
+ -- const playerTransformations = initArray(false, PlayerForm.NUM_PLAYER_FORMS - 1);
263
+ -- ```
195
264
  function ____exports.initArray(self, defaultValue, size)
196
265
  local array = {}
197
266
  ____repeat(
@@ -203,6 +272,11 @@ function ____exports.initArray(self, defaultValue, size)
203
272
  )
204
273
  return array
205
274
  end
275
+ --- Since Lua uses tables for every non-primitive data structure, it is non-trivial to determine if a
276
+ -- particular table is being used as an array. `isArray` returns true if:
277
+ --
278
+ -- - the table contains all numerical indexes that are contiguous, starting at 1
279
+ -- - the table has no keys (i.e. an "empty" table)
206
280
  function ____exports.isArray(self, object)
207
281
  if type(object) ~= "table" then
208
282
  return false
@@ -234,6 +308,9 @@ function ____exports.isArray(self, object)
234
308
  end
235
309
  return true
236
310
  end
311
+ --- Helper function to see if every element in the array is N + 1.
312
+ --
313
+ -- For example, `[2, 3, 4]` would return true, and `[2, 3, 5]` would return false.
237
314
  function ____exports.isArrayContiguous(self, array)
238
315
  local lastValue
239
316
  for ____, element in ipairs(array) do
@@ -246,12 +323,20 @@ function ____exports.isArrayContiguous(self, array)
246
323
  end
247
324
  return true
248
325
  end
326
+ --- Checks if an array is in the provided 2-dimensional array.
249
327
  function ____exports.isArrayInArray(self, arrayToMatch, parentArray)
250
328
  return __TS__ArraySome(
251
329
  parentArray,
252
330
  function(____, element) return ____exports.arrayEquals(nil, element, arrayToMatch) end
253
331
  )
254
332
  end
333
+ --- Shallow copies and shuffles the array using the Fisher-Yates algorithm. Returns the copied array.
334
+ --
335
+ -- From: https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
336
+ --
337
+ -- @param originalArray The array to shuffle.
338
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
339
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
255
340
  function ____exports.shuffleArray(self, originalArray, seedOrRNG)
256
341
  if seedOrRNG == nil then
257
342
  seedOrRNG = getRandomSeed(nil)
@@ -3,6 +3,12 @@ local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
3
3
  local ____exports = {}
4
4
  local ____log = require("functions.log")
5
5
  local log = ____log.log
6
+ --- Helper function to benchmark the performance of a function.
7
+ --
8
+ -- This function is variadic, which means that you can supply as many as you want to benchmark.
9
+ --
10
+ -- @returns An array containing the average time in milliseconds for each function. (This will also
11
+ -- be printed to the log.)
6
12
  function ____exports.benchmark(self, numTrials, ...)
7
13
  local functions = {...}
8
14
  log(((("Benchmarking " .. tostring(#functions)) .. " function(s) with ") .. tostring(numTrials)) .. " trials.")