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
@@ -10,6 +10,11 @@ local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
10
10
  local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
11
11
  local ____cachedClasses = require("cachedClasses")
12
12
  local game = ____cachedClasses.game
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.
13
18
  function ____exports.getAllPlayers(self)
14
19
  local numPlayers = game:GetNumPlayers()
15
20
  local players = {}
@@ -23,6 +28,33 @@ function ____exports.getAllPlayers(self)
23
28
  end
24
29
  return players
25
30
  end
31
+ --- Mods often have to track variables relating to the player. In naive mods, information will only
32
+ -- be stored about the first player. However, in order to be robust, mods must handle up to 4
33
+ -- players playing at the same time. This means that information must be stored on a map data
34
+ -- structure. Finding a good index for these types of map data structures is difficult:
35
+ --
36
+ -- - We cannot use the index from `Isaac.GetPlayer(i)` since this fails in the case where there are
37
+ -- two players and the first player leaves the run.
38
+ -- - We cannot use `EntityPlayer.ControllerIndex` as an index because it fails in the case of Jacob
39
+ -- & Esau or Tainted Forgotten. It also fails in the case of a player changing their controls
40
+ -- mid-run.
41
+ -- - We cannot use `EntityPlayer.GetData().index` because it does not persist across saving and
42
+ -- continuing.
43
+ -- - We cannot use `GetPtrHash()` as an index because it does not persist across exiting and
44
+ -- relaunching the game.
45
+ -- - We cannot use `EntityPlayer.InitSeed` because it is not consistent with additional players
46
+ -- beyond the first.
47
+ --
48
+ -- Instead, we use the `EntityPlayer.GetCollectibleRNG` method with an arbitrary value of Sad Onion
49
+ -- (1). This works even if the player does not have any Sad Onions.
50
+ --
51
+ -- Since the RNG value is the same for both Tainted Lazarus and Dead Tainted Lazarus, we revert to
52
+ -- using the RNG of The Inner Eye (2) for Dead Tainted Lazarus.
53
+ --
54
+ -- Note that by default, this returns the same index for both The Forgotten and The Soul. (Even
55
+ -- though they are technically different characters, they share the same inventory and InitSeed.) If
56
+ -- this is not desired, pass true for the `differentiateForgottenAndSoul` argument, and the RNG of
57
+ -- Spoon Bender (3) will be used for The Soul.
26
58
  function ____exports.getPlayerIndex(self, player, differentiateForgottenAndSoul)
27
59
  if differentiateForgottenAndSoul == nil then
28
60
  differentiateForgottenAndSoul = false
@@ -63,6 +95,14 @@ function getPlayerIndexCollectibleType(self, player, differentiateForgottenAndSo
63
95
  end
64
96
  until true
65
97
  end
98
+ --- This function always excludes players with a non-undefined parent, since they are not real
99
+ -- players (e.g. the Strawman Keeper).
100
+ --
101
+ -- If this is not desired, use the `getAllPlayers` helper function instead.
102
+ --
103
+ -- @param performCharacterExclusions Whether or not to exclude characters that are not directly
104
+ -- controlled by the player (i.e. Esau & Tainted Soul). Default is
105
+ -- false.
66
106
  function ____exports.getPlayers(self, performCharacterExclusions)
67
107
  if performCharacterExclusions == nil then
68
108
  performCharacterExclusions = false
@@ -81,6 +121,9 @@ function ____exports.getPlayers(self, performCharacterExclusions)
81
121
  )
82
122
  return performCharacterExclusions and nonChildPlayersFiltered or nonChildPlayers
83
123
  end
124
+ --- Helper function to get a parent `EntityPlayer` object for a given `EntitySubPlayer` object. This
125
+ -- is useful because calling the `EntityPlayer.GetSubPlayer` method on a sub-player object will
126
+ -- return undefined.
84
127
  function ____exports.getSubPlayerParent(self, subPlayer)
85
128
  local subPlayerPtrHash = GetPtrHash(subPlayer)
86
129
  local players = ____exports.getPlayers(nil)
@@ -96,6 +139,8 @@ function ____exports.getSubPlayerParent(self, subPlayer)
96
139
  end
97
140
  )
98
141
  end
142
+ --- Some players are "child" players, meaning that they have a non-undefined Parent property. (For
143
+ -- example, the Strawman Keeper.)
99
144
  function ____exports.isChildPlayer(self, player)
100
145
  return player.Parent ~= nil
101
146
  end
@@ -108,6 +153,8 @@ function ____exports.getPlayerFromIndex(self, playerIndex)
108
153
  function(____, player) return ____exports.getPlayerIndex(nil, player) == playerIndex end
109
154
  )
110
155
  end
156
+ --- Helper function to return the index of this player with respect to the output of the
157
+ -- `Isaac.GetPlayer` method.
111
158
  function ____exports.getPlayerIndexVanilla(self, playerToFind)
112
159
  local numPlayers = game:GetNumPlayers()
113
160
  local playerToFindHash = GetPtrHash(playerToFind)
@@ -15,6 +15,14 @@ local ____enums = require("functions.enums")
15
15
  local getEnumValues = ____enums.getEnumValues
16
16
  local ____player = require("functions.player")
17
17
  local isCharacter = ____player.isCharacter
18
+ --- Use this helper function as a workaround for the `EntityPlayer.GetPocketItem` method not working
19
+ -- correctly.
20
+ --
21
+ -- Note that due to API limitations, there is no way to determine the location of a Dice Bag trinket
22
+ -- dice. Furthermore, when the player has a Dice Bag trinket dice and a pocket active at the same
23
+ -- time, there is no way to determine the location of the pocket active item. If this function
24
+ -- cannot determine the identity of a particular slot, it will mark the type of the slot as
25
+ -- `PocketItemType.UNDETERMINABLE`.
18
26
  function ____exports.getPocketItems(self, player)
19
27
  local pocketItem = player:GetActiveItem(ActiveSlot.POCKET)
20
28
  local hasPocketItem = pocketItem ~= CollectibleType.NULL
@@ -49,6 +57,8 @@ function ____exports.getPocketItems(self, player)
49
57
  end
50
58
  return pocketItems
51
59
  end
60
+ --- Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
61
+ -- in, if any. Returns undefined if the player does not have a pocket active item.
52
62
  function ____exports.getActivePocketItemSlot(self, player)
53
63
  local pocketItems = ____exports.getPocketItems(nil, player)
54
64
  for ____, pocketItem in ipairs(pocketItems) do
@@ -65,6 +75,12 @@ function ____exports.getFirstCardOrPill(self, player)
65
75
  function(____, pocketItem) return pocketItem.type == PocketItemType.CARD or pocketItem.type == PocketItemType.PILL end
66
76
  )
67
77
  end
78
+ --- Returns whether or not the player can hold an additional pocket item, beyond what they are
79
+ -- currently carrying. This takes into account items that modify the max number of pocket items,
80
+ -- like Starter Deck.
81
+ --
82
+ -- If the player is the Tainted Soul, this always returns false, since that character cannot pick up
83
+ -- items. (Only Tainted Forgotten can pick up items.)
68
84
  function ____exports.hasOpenPocketItemSlot(self, player)
69
85
  if isCharacter(nil, player, PlayerType.THE_SOUL_B) then
70
86
  return false
@@ -75,6 +91,8 @@ function ____exports.hasOpenPocketItemSlot(self, player)
75
91
  function(____, pocketItem) return pocketItem.type == PocketItemType.EMPTY end
76
92
  )
77
93
  end
94
+ --- Helper function to determine whether or not the player's "active" pocket item slot is set to
95
+ -- their pocket active item.
78
96
  function ____exports.isFirstSlotPocketActiveItem(self, player)
79
97
  local pocketItems = ____exports.getPocketItems(nil, player)
80
98
  local firstPocketItem = pocketItems[1]
@@ -25,6 +25,7 @@ function ____exports.anyEntityCloserThan(self, entities, position, distance)
25
25
  function(____, entity) return position:Distance(entity.Position) <= distance end
26
26
  )
27
27
  end
28
+ --- Iterates over all players and checks if any player is close enough to the specified position.
28
29
  function ____exports.anyPlayerCloserThan(self, position, distance)
29
30
  local players = getPlayers(nil)
30
31
  return __TS__ArraySome(
@@ -32,6 +33,15 @@ function ____exports.anyPlayerCloserThan(self, position, distance)
32
33
  function(____, player) return player.Position:Distance(position) <= distance end
33
34
  )
34
35
  end
36
+ --- Helper function to get a room position that is not overlapping with a grid entity, a heaven door,
37
+ -- or a player. The `Room.FindFreePickupSpawnPosition` method will return locations that overlap
38
+ -- with heaven doors and partially overlap with players, if the thing being spawned is bigger than a
39
+ -- tile (like a Blood Donation Machine). Use this function instead if you want to account for those
40
+ -- specific situations.
41
+ --
42
+ -- @param startingPosition The position to start searching from. If this position is not overlapping
43
+ -- with anything, then it will be returned.
44
+ -- @param avoidActiveEntities Optional. Default is false.
35
45
  function ____exports.findFreePosition(self, startingPosition, avoidActiveEntities)
36
46
  if avoidActiveEntities == nil then
37
47
  avoidActiveEntities = false
@@ -59,6 +69,13 @@ function ____exports.findFreePosition(self, startingPosition, avoidActiveEntitie
59
69
  end
60
70
  return room:FindFreePickupSpawnPosition(startingPosition)
61
71
  end
72
+ --- Helper function to get a map containing the positions of every entity in the current room.
73
+ --
74
+ -- This is useful for rewinding entity positions at a later time. Also see `setEntityPositions`.
75
+ --
76
+ -- @param entities Optional. If provided, will only get the positions of the provided entities. Use
77
+ -- this with cached entities to avoid invoking the `Isaac.GetRoomEntities` method
78
+ -- multiple times.
62
79
  function ____exports.getEntityPositions(self, entities)
63
80
  if entities == nil then
64
81
  entities = getEntities(nil)
@@ -70,6 +87,13 @@ function ____exports.getEntityPositions(self, entities)
70
87
  end
71
88
  return entityPositions
72
89
  end
90
+ --- Helper function to get a map containing the velocities of every entity in the current room.
91
+ --
92
+ -- This is useful for rewinding entity velocities at a later time. Also see `setEntityVelocities`.
93
+ --
94
+ -- @param entities Optional. If provided, will only get the velocities of the provided entities. Use
95
+ -- this with cached entities to avoid invoking the `Isaac.GetRoomEntities` method
96
+ -- multiple times.
73
97
  function ____exports.getEntityVelocities(self, entities)
74
98
  if entities == nil then
75
99
  entities = getEntities(nil)
@@ -81,6 +105,17 @@ function ____exports.getEntityVelocities(self, entities)
81
105
  end
82
106
  return entityVelocities
83
107
  end
108
+ --- Helper function to set the position of every entity in the room based on a map of positions. If
109
+ -- an entity is found that does not have matching element in the provided map, then that entity will
110
+ -- be skipped.
111
+ --
112
+ -- This function is useful for rewinding entity positions at a later time. Also see
113
+ -- `getEntityPositions`.
114
+ --
115
+ -- @param entityPositions The map providing the positions for every entity.
116
+ -- @param entities Optional. If provided, will only set the positions of the provided entities. Use
117
+ -- this with cached entities to avoid invoking the `Isaac.GetRoomEntities` method
118
+ -- multiple times.
84
119
  function ____exports.setEntityPositions(self, entityPositions, entities)
85
120
  if entities == nil then
86
121
  entities = getEntities(nil)
@@ -93,6 +128,17 @@ function ____exports.setEntityPositions(self, entityPositions, entities)
93
128
  end
94
129
  end
95
130
  end
131
+ --- Helper function to set the velocity of every entity in the room based on a map of velocities. If
132
+ -- an entity is found that does not have matching element in the provided map, then that entity will
133
+ -- be skipped.
134
+ --
135
+ -- This function is useful for rewinding entity velocities at a later time. Also see
136
+ -- `getEntityVelocities`.
137
+ --
138
+ -- @param entityVelocities The map providing the velocities for every entity.
139
+ -- @param entities Optional. If provided, will only set the velocities of the provided entities. Use
140
+ -- this with cached entities to avoid invoking the `Isaac.GetRoomEntities` method
141
+ -- multiple times.
96
142
  function ____exports.setEntityVelocities(self, entityVelocities, entities)
97
143
  if entities == nil then
98
144
  entities = getEntities(nil)
@@ -3,6 +3,11 @@ local ____rng = require("functions.rng")
3
3
  local getRandomSeed = ____rng.getRandomSeed
4
4
  local isRNG = ____rng.isRNG
5
5
  local newRNG = ____rng.newRNG
6
+ --- This returns a random float between 0 and 1. It is inclusive on the low end, but exclusive on the
7
+ -- high end. (This is because the `RNG.RandomFloat` method will never return a value of exactly 1.)
8
+ --
9
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
10
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
6
11
  function ____exports.getRandom(self, seedOrRNG)
7
12
  if seedOrRNG == nil then
8
13
  seedOrRNG = getRandomSeed(nil)
@@ -10,6 +15,18 @@ function ____exports.getRandom(self, seedOrRNG)
10
15
  local rng = isRNG(nil, seedOrRNG) and seedOrRNG or newRNG(nil, seedOrRNG)
11
16
  return rng:RandomFloat()
12
17
  end
18
+ --- This returns a random float between min and max.
19
+ --
20
+ -- For example:
21
+ --
22
+ -- ```ts
23
+ -- const realNumberBetweenOneAndThree = getRandomFloat(1, 3);
24
+ -- ```
25
+ --
26
+ -- @param min The lower bound for the random number (inclusive).
27
+ -- @param max The upper bound for the random number (exclusive).
28
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
29
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
13
30
  function ____exports.getRandomFloat(self, min, max, seedOrRNG)
14
31
  if seedOrRNG == nil then
15
32
  seedOrRNG = getRandomSeed(nil)
@@ -22,6 +39,21 @@ function ____exports.getRandomFloat(self, min, max, seedOrRNG)
22
39
  end
23
40
  return min + ____exports.getRandom(nil, seedOrRNG) * (max - min)
24
41
  end
42
+ --- This returns a random integer between min and max. It is inclusive on both ends.
43
+ --
44
+ -- Note that this function will invoke the `Next` method on the `RNG` object before returning the
45
+ -- random number.
46
+ --
47
+ -- For example:
48
+ --
49
+ -- ```ts
50
+ -- const oneTwoOrThree = getRandomInt(1, 3);
51
+ -- ```
52
+ --
53
+ -- @param min The lower bound for the random number (inclusive).
54
+ -- @param max The upper bound for the random number (inclusive).
55
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
56
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
25
57
  function ____exports.getRandomInt(self, min, max, seedOrRNG)
26
58
  if seedOrRNG == nil then
27
59
  seedOrRNG = getRandomSeed(nil)
@@ -22,6 +22,9 @@ local getLastFrameOfAnimation = ____sprite.getLastFrameOfAnimation
22
22
  local ____trinketGive = require("functions.trinketGive")
23
23
  local giveTrinketsBack = ____trinketGive.giveTrinketsBack
24
24
  local temporarilyRemoveTrinket = ____trinketGive.temporarilyRemoveTrinket
25
+ --- Helper function to determine if the player will be revived by the Heartbreak collectible if they
26
+ -- take fatal damage. This is contingent on the character that they are playing as and the amount of
27
+ -- broken hearts that they already have.
25
28
  function ____exports.willReviveFromHeartbreak(self, player)
26
29
  if not player:HasCollectible(CollectibleType.HEARTBREAK) then
27
30
  return false
@@ -32,6 +35,8 @@ function ____exports.willReviveFromHeartbreak(self, player)
32
35
  local numBrokenHeartsAfterRevival = numBrokenHeartsThatWillBeAdded + brokenHearts
33
36
  return maxHeartContainers > numBrokenHeartsAfterRevival
34
37
  end
38
+ --- Helper function to determine if the Spirit Shackles item is in an enabled state. (It can be
39
+ -- either enabled or disabled.)
35
40
  function ____exports.willReviveFromSpiritShackles(self, player)
36
41
  if not player:HasCollectible(CollectibleType.SPIRIT_SHACKLES) then
37
42
  return false
@@ -41,6 +46,8 @@ function ____exports.willReviveFromSpiritShackles(self, player)
41
46
  local playerInSoulForm = effects:HasNullEffect(NullItemID.SPIRIT_SHACKLES_SOUL)
42
47
  return spiritShacklesEnabled and not playerInSoulForm
43
48
  end
49
+ --- Uses the player's current health and other miscellaneous things to determine if incoming damage
50
+ -- will be fatal.
44
51
  function ____exports.isDamageToPlayerFatal(self, player, damageAmount, damageSource, lastDamageGameFrame)
45
52
  local gameFrameCount = game:GetFrameCount()
46
53
  local character = player:GetPlayerType()
@@ -84,6 +91,12 @@ function ____exports.isDamageToPlayerFatal(self, player, damageAmount, damageSou
84
91
  end
85
92
  return true
86
93
  end
94
+ --- Assuming that we are on the frame of fatal damage, this function returns whether or not
95
+ -- Mysterious Paper would rotate to Missing Poster on the frame that the "Game Over" screen would
96
+ -- appear (which would subsequently save the player from fatal damage).
97
+ --
98
+ -- Mysterious Paper rotates between the 4 items on every frame, in order. The formula for whether
99
+ -- Mysterious Paper be Missing Power is: `gameFrameCount % 4 === 3`
87
100
  function ____exports.willMysteriousPaperRevive(self, player)
88
101
  local gameFrameCount = game:GetFrameCount()
89
102
  local sprite = player:GetSprite()
@@ -93,6 +106,8 @@ function ____exports.willMysteriousPaperRevive(self, player)
93
106
  local frameOfDeath = gameFrameCount + deathAnimationFrames + 1
94
107
  return frameOfDeath % 4 == 3
95
108
  end
109
+ --- The `EntityPlayer.WillPlayerRevive` method does not properly account for Mysterious Paper, so use
110
+ -- this helper function instead for more robust revival detection.
96
111
  function ____exports.willPlayerRevive(self, player)
97
112
  local trinketSituation = temporarilyRemoveTrinket(nil, player, TrinketType.MYSTERIOUS_PAPER)
98
113
  local willRevive = player:WillPlayerRevive() or trinketSituation ~= nil and ____exports.willMysteriousPaperRevive(nil, player)
package/functions/rng.lua CHANGED
@@ -16,14 +16,21 @@ local getNumbersFromTable = ____table.getNumbersFromTable
16
16
  local tableHasKeys = ____table.tableHasKeys
17
17
  local ____utils = require("functions.utils")
18
18
  local ensureAllCases = ____utils.ensureAllCases
19
+ --- Helper function to get a random `Seed` value to be used in spawning entities and so on. Use this
20
+ -- instead of calling the `Random` function directly since that can return a value of 0 and crash
21
+ -- the game.
19
22
  function ____exports.getRandomSeed(self)
20
23
  local randomNumber = Random()
21
24
  local safeRandomNumber = randomNumber == 0 and 1 or randomNumber
22
25
  return safeRandomNumber
23
26
  end
27
+ --- Helper function to check if something is an instantiated RNG object.
24
28
  function ____exports.isRNG(self, object)
25
29
  return isIsaacAPIClassOfType(nil, object, OBJECT_NAME)
26
30
  end
31
+ --- Helper function to initialize an RNG object using Blade's recommended shift index.
32
+ --
33
+ -- @param seed The seed to initialize it with. Default is `getRandomSeed()`.
27
34
  function ____exports.newRNG(self, seed)
28
35
  if seed == nil then
29
36
  seed = ____exports.getRandomSeed(nil)
@@ -32,6 +39,7 @@ function ____exports.newRNG(self, seed)
32
39
  ____exports.setSeed(nil, rng, seed)
33
40
  return rng
34
41
  end
42
+ --- Helper function to set a seed to an RNG object using Blade's recommended shift index.
35
43
  function ____exports.setSeed(self, rng, seed)
36
44
  if seed == 0 then
37
45
  error("You cannot set an RNG object to a seed of 0, or the game will crash.")
@@ -41,6 +49,11 @@ end
41
49
  RECOMMENDED_SHIFT_IDX = 35
42
50
  local KEYS = {"seed"}
43
51
  OBJECT_NAME = "RNG"
52
+ --- Helper function to copy an `RNG` object.
53
+ --
54
+ -- @param rng The RNG object to copy. In the case of deserialization, this will actually be a Lua
55
+ -- table instead of an instantiated RNG class.
56
+ -- @param serializationType Default is `SerializationType.NONE`.
44
57
  function ____exports.copyRNG(self, rng, serializationType)
45
58
  if serializationType == nil then
46
59
  serializationType = SerializationType.NONE
@@ -94,6 +107,8 @@ function ____exports.copyRNG(self, rng, serializationType)
94
107
  end
95
108
  until true
96
109
  end
110
+ --- Used to determine is the given table is a serialized `RNG` object created by the save data
111
+ -- manager and/or the `deepCopy` function.
97
112
  function ____exports.isSerializedRNG(self, object)
98
113
  local objectType = type(object)
99
114
  if objectType ~= "table" then
@@ -109,6 +124,8 @@ end
109
124
  function ____exports.rngEquals(self, rng1, rng2)
110
125
  return isaacAPIClassEquals(nil, rng1, rng2, KEYS)
111
126
  end
127
+ --- Helper function to iterate over the provided object and set the seed for all of the values that
128
+ -- are RNG objects equal to a particular seed.
112
129
  function ____exports.setAllRNGToSeed(self, object, seed)
113
130
  local objectType = type(object)
114
131
  if objectType ~= "table" then
@@ -121,6 +138,8 @@ function ____exports.setAllRNGToSeed(self, object, seed)
121
138
  end
122
139
  end
123
140
  end
141
+ --- Helper function to iterate over the provided object and set the seed for all of the values that
142
+ -- are RNG objects equal to the start seed for the current run.
124
143
  function ____exports.setAllRNGToStartSeed(self, object)
125
144
  local seeds = game:GetSeeds()
126
145
  local startSeed = seeds:GetStartSeed()
@@ -12,14 +12,22 @@ local ____enums = require("functions.enums")
12
12
  local getEnumValues = ____enums.getEnumValues
13
13
  local ____flag = require("functions.flag")
14
14
  local hasFlag = ____flag.hasFlag
15
+ --- Alias for the `Level.GetCurrentRoomDesc` method. Use this to make it more clear what type of
16
+ -- `RoomDescriptor` object that you are retrieving.
15
17
  function ____exports.getCurrentRoomDescriptorReadOnly(self)
16
18
  local level = game:GetLevel()
17
19
  return level:GetCurrentRoomDesc()
18
20
  end
21
+ --- Helper function to get the room data for the provided room.
22
+ --
23
+ -- @param roomGridIndex Optional. Default is the current room index.
19
24
  function ____exports.getRoomData(self, roomGridIndex)
20
25
  local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
21
26
  return roomDescriptor.Data
22
27
  end
28
+ --- Helper function to get the descriptor for a room.
29
+ --
30
+ -- @param roomGridIndex Optional. Default is the current room index.
23
31
  function ____exports.getRoomDescriptor(self, roomGridIndex)
24
32
  local level = game:GetLevel()
25
33
  if roomGridIndex == nil then
@@ -27,6 +35,20 @@ function ____exports.getRoomDescriptor(self, roomGridIndex)
27
35
  end
28
36
  return level:GetRoomByIdx(roomGridIndex)
29
37
  end
38
+ --- Helper function to get the grid index of the current room.
39
+ --
40
+ -- - If the current room is inside of the grid, this function will return the `SafeGridIndex` from
41
+ -- the room descriptor. (The safe grid index is defined as the top-left 1x1 section that the room
42
+ -- overlaps with, or the top-right 1x1 section of a `RoomType.SHAPE_LTL` room.)
43
+ -- - If the current room is outside of the grid, it will return the index from the
44
+ -- `Level.GetCurrentRoomIndex` method (since `SafeGridIndex` is bugged for these cases).
45
+ --
46
+ -- Use this function instead of the `Level.GetCurrentRoomIndex` method directly because the latter
47
+ -- will return the specific 1x1 quadrant that the player entered the room at. For most situations,
48
+ -- using the safe grid index is more reliable than this.
49
+ --
50
+ -- Data structures that store data per room should use the room's `ListIndex` instead of
51
+ -- `SafeGridIndex`, since the former is unique across different dimensions.
30
52
  function ____exports.getRoomGridIndex(self)
31
53
  local level = game:GetLevel()
32
54
  local currentRoomIndex = level:GetCurrentRoomIndex()
@@ -36,6 +58,8 @@ function ____exports.getRoomGridIndex(self)
36
58
  local roomDescriptor = ____exports.getCurrentRoomDescriptorReadOnly(nil)
37
59
  return roomDescriptor.SafeGridIndex
38
60
  end
61
+ --- Helper function to get the set of allowed door slots for the room at the supplied grid index.
62
+ -- This corresponds to the doors that are enabled in the STB/XML file for the room.
39
63
  function ____exports.getRoomAllowedDoors(self, roomGridIndex)
40
64
  local allowedDoors = __TS__New(Set)
41
65
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
@@ -51,14 +75,30 @@ function ____exports.getRoomAllowedDoors(self, roomGridIndex)
51
75
  end
52
76
  return allowedDoors
53
77
  end
78
+ --- Helper function to get the list grid index of the provided room, which is equal to the index in
79
+ -- the `RoomList.Get` method. In other words, this is equal to the order that the room was created
80
+ -- by the floor generation algorithm.
81
+ --
82
+ -- Use this as an index for data structures that store data per room, since it is unique across
83
+ -- different dimensions.
84
+ --
85
+ -- @param roomGridIndex Optional. Default is the current room index.
54
86
  function ____exports.getRoomListIndex(self, roomGridIndex)
55
87
  local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
56
88
  return roomDescriptor.ListIndex
57
89
  end
90
+ --- Helper function to get the name of the room as it appears in the STB/XML data.
91
+ --
92
+ -- @param roomGridIndex Optional. Default is the current room index.
93
+ -- @returns The room name. Returns "Unknown" if the type was not found.
58
94
  function ____exports.getRoomName(self, roomGridIndex)
59
95
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
60
96
  return roomData == nil and "Unknown" or roomData.Name
61
97
  end
98
+ --- Helper function to get the name of the room as it appears in the STB/XML data.
99
+ --
100
+ -- @param roomGridIndex Optional. Default is the current room index.
101
+ -- @returns The room name. Returns "Unknown" if the type was not found.
62
102
  function ____exports.getRoomShape(self, roomGridIndex)
63
103
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
64
104
  local ____temp_0
@@ -69,22 +109,50 @@ function ____exports.getRoomShape(self, roomGridIndex)
69
109
  end
70
110
  return ____temp_0
71
111
  end
112
+ --- Helper function to get the stage ID for a room from the XML/STB data. The room stage ID will
113
+ -- correspond to the first number in the filename of the XML/STB file. For example, a Depths room
114
+ -- would have a stage ID of 7.
115
+ --
116
+ -- @param roomGridIndex Optional. Default is the current room index.
117
+ -- @returns The room stage ID. Returns -1 if the stage ID was not found.
72
118
  function ____exports.getRoomStageID(self, roomGridIndex)
73
119
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
74
120
  return roomData == nil and -1 or roomData.StageID
75
121
  end
122
+ --- Helper function to get the sub-type for a room from the XML/STB data. The room sub-type will
123
+ -- correspond to different things depending on what XML/STB file it draws from. For example, in the
124
+ -- "00.special rooms.stb" file, an Angel Room with a sub-type of 0 will correspond to a normal Angel
125
+ -- Room and a sub-type of 1 will correspond to an Angel Room shop for The Stairway.
126
+ --
127
+ -- @param roomGridIndex Optional. Default is the current room index.
128
+ -- @returns The room sub-type. Returns -1 if the sub-type was not found.
76
129
  function ____exports.getRoomSubType(self, roomGridIndex)
77
130
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
78
131
  return roomData == nil and -1 or roomData.Subtype
79
132
  end
133
+ --- Helper function for getting the type of the room with the given grid index.
134
+ --
135
+ -- @param roomGridIndex Optional. Default is the current room index.
136
+ -- @returns The room data type. Returns -1 if the type was not found.
80
137
  function ____exports.getRoomType(self, roomGridIndex)
81
138
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
82
139
  return roomData == nil and -1 or roomData.Type
83
140
  end
141
+ --- Helper function to get the variant for a room from the XML/STB data. You can think of a room
142
+ -- variant as its identifier. For example, to go to Basement room #123, you would use a console
143
+ -- command of `goto d.123` while on the Basement.
144
+ --
145
+ -- @param roomGridIndex Optional. Default is the current room index.
146
+ -- @returns The room variant. Returns -1 if the variant was not found.
84
147
  function ____exports.getRoomVariant(self, roomGridIndex)
85
148
  local roomData = ____exports.getRoomData(nil, roomGridIndex)
86
149
  return roomData == nil and -1 or roomData.Variant
87
150
  end
151
+ --- Note that the room visited count will be inaccurate during the period before the PostNewRoom
152
+ -- callback has fired (i.e. when entities are initializing and performing their first update). This
153
+ -- is because the variable is only incremented immediately before the PostNewRoom callback fires.
154
+ --
155
+ -- @param roomGridIndex Optional. Default is the current room index.
88
156
  function ____exports.getRoomVisitedCount(self, roomGridIndex)
89
157
  local roomDescriptor = ____exports.getRoomDescriptor(nil, roomGridIndex)
90
158
  return roomDescriptor.VisitedCount
@@ -9,6 +9,9 @@ local getRoomShapeBottomRightPosition = ____roomShape.getRoomShapeBottomRightPos
9
9
  local getRoomShapeTopLeftPosition = ____roomShape.getRoomShapeTopLeftPosition
10
10
  local getRoomShapeWidth = ____roomShape.getRoomShapeWidth
11
11
  local isLRoom = ____roomShape.isLRoom
12
+ --- Helper function to convert a grid position `Vector` to a world position `Vector`.
13
+ --
14
+ -- For example, the coordinates of (0, 0) are equal to `Vector(80, 160)`.
12
15
  function ____exports.gridPositionToWorldPosition(self, gridPosition)
13
16
  local x = (gridPosition.X + 2) * 40
14
17
  local y = (gridPosition.Y + 4) * 40
@@ -27,16 +30,26 @@ function isValidGridPositionLRoom(self, gridPosition, roomShape)
27
30
  local verticalTopLeft, verticalBottomRight, horizontalTopLeft, horizontalBottomRight = table.unpack(rectangles)
28
31
  return inRectangle(nil, gridPosition, verticalTopLeft, verticalBottomRight) or inRectangle(nil, gridPosition, horizontalTopLeft, horizontalBottomRight)
29
32
  end
33
+ --- Helper function to convert grid coordinates to a world position `Vector`.
34
+ --
35
+ -- For example, the coordinates of (0, 0) are equal to `Vector(80, 160)`.
30
36
  function ____exports.gridCoordinatesToWorldPosition(self, x, y)
31
37
  local gridPosition = Vector(x, y)
32
38
  return ____exports.gridPositionToWorldPosition(nil, gridPosition)
33
39
  end
40
+ --- Helper function to convert a grid index to a grid position.
41
+ --
42
+ -- For example, in a 1x1 room, grid index 0 is equal to "Vector(-1, -1) and grid index 16 is equal
43
+ -- to "Vector(0, 0)".
34
44
  function ____exports.gridIndexToGridPosition(self, gridIndex, roomShape)
35
45
  local gridWidth = getRoomShapeWidth(nil, roomShape)
36
46
  local x = gridIndex % gridWidth - 1
37
47
  local y = math.floor(gridIndex / gridWidth) - 1
38
48
  return Vector(x, y)
39
49
  end
50
+ --- Test if a grid position is actually in the given `RoomShape`.
51
+ --
52
+ -- In this context, the grid position of the top-left wall is "Vector(-1, -1)".
40
53
  function ____exports.isValidGridPosition(self, gridPosition, roomShape)
41
54
  local ____isLRoom_result_0
42
55
  if isLRoom(nil, roomShape) then
@@ -46,11 +59,19 @@ function ____exports.isValidGridPosition(self, gridPosition, roomShape)
46
59
  end
47
60
  return ____isLRoom_result_0
48
61
  end
62
+ --- Helper function to convert a world position `Vector` to a grid position `Vector`.
63
+ --
64
+ -- In this context, the grid position of the top-left wall is "Vector(-1, -1)".
49
65
  function ____exports.worldPositionToGridPosition(self, worldPos)
50
66
  local x = math.floor(worldPos.X / 40 - 2 + 0.5)
51
67
  local y = math.floor(worldPos.Y / 40 - 4 + 0.5)
52
68
  return Vector(x, y)
53
69
  end
70
+ --- Helper function to convert a world position `Vector` to a grid position `Vector`.
71
+ --
72
+ -- In this context, the grid position of the top-left wall is "Vector(-1, -1)".
73
+ --
74
+ -- This is similar to the `worldPositionToGridPosition` function, but the values are not rounded.
54
75
  function ____exports.worldPositionToGridPositionFast(self, worldPos)
55
76
  local x = worldPos.X / 40 - 2
56
77
  local y = worldPos.Y / 40 - 4
@@ -17,22 +17,44 @@ local ____roomShapeVolumes = require("objects.roomShapeVolumes")
17
17
  local ROOM_SHAPE_VOLUMES = ____roomShapeVolumes.ROOM_SHAPE_VOLUMES
18
18
  local ____LRoomShapesSet = require("sets.LRoomShapesSet")
19
19
  local L_ROOM_SHAPES_SET = ____LRoomShapesSet.L_ROOM_SHAPES_SET
20
+ --- Helper function to get the grid index delta that a door out of the given room shape would lead
21
+ -- to. For example, if you went through the bottom door in a room of `RoomShape.SHAPE_1x2`, you
22
+ -- would end up in a room with a grid index that is +26 units from the `SafeGridIndex` of where you
23
+ -- started.
20
24
  function ____exports.getGridIndexDelta(self, roomShape, doorSlot)
21
25
  local doorSlotToGridIndexMap = ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA[roomShape]
22
26
  return doorSlotToGridIndexMap:get(doorSlot)
23
27
  end
28
+ --- Helper function to get the grid position of the bottom-right tile of a given room shape.
29
+ --
30
+ -- "Vector(0, 0)" corresponds to the top left tile of a room, not including the walls. (The top-left
31
+ -- wall would be at "Vector(-1, -1)".)
24
32
  function ____exports.getRoomShapeBottomRightPosition(self, roomShape)
25
33
  return ROOM_SHAPE_TO_BOTTOM_RIGHT_POSITION[roomShape]
26
34
  end
35
+ --- Helper function to get the bounds of a room shape, which are a box representing its contents.
36
+ -- This does not include the tiles that the walls are on. L rooms use the same bounds as a 2x2 room.
27
37
  function ____exports.getRoomShapeBounds(self, roomShape)
28
38
  return ROOM_SHAPE_BOUNDS[roomShape]
29
39
  end
40
+ --- Helper function to get the dimensions of a room shape's layout. This is NOT the size of the
41
+ -- room's actual contents! For that, use the `getRoomShapeBounds` function.
42
+ --
43
+ -- For example, a horizontal narrow room has a layout size of equal to that of a 1x1 room.
30
44
  function ____exports.getRoomShapeLayoutSize(self, roomShape)
31
45
  return ROOM_SHAPE_LAYOUT_SIZES[roomShape]
32
46
  end
47
+ --- Helper function to get the grid position of the top-left tile of a given room shape.
48
+ --
49
+ -- "Vector(0, 0)" corresponds to the top left tile of a room, not including the walls. (The top-left
50
+ -- wall would be at "Vector(-1, -1)".)
33
51
  function ____exports.getRoomShapeTopLeftPosition(self, roomShape)
34
52
  return ROOM_SHAPE_TO_TOP_LEFT_POSITION[roomShape]
35
53
  end
54
+ --- Helper function to get the volume of a room shape, which is the amount of tiles that are inside
55
+ -- the room.
56
+ --
57
+ -- (This cannot be directly calculated from the bounds since L rooms are a special case.)
36
58
  function ____exports.getRoomShapeVolume(self, roomShape)
37
59
  return ROOM_SHAPE_VOLUMES[roomShape]
38
60
  end