isaacscript-common 14.1.2 → 14.2.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 (494) hide show
  1. package/dist/index.d.ts +954 -158
  2. package/dist/isaacscript-common.lua +4099 -1066
  3. package/dist/src/callbacks.d.ts +102 -20
  4. package/dist/src/callbacks.d.ts.map +1 -1
  5. package/dist/src/callbacks.lua +124 -1
  6. package/dist/src/classes/ModFeature.d.ts +16 -4
  7. package/dist/src/classes/ModFeature.d.ts.map +1 -1
  8. package/dist/src/classes/ModFeature.lua +67 -4
  9. package/dist/src/classes/ModUpgraded.d.ts +10 -10
  10. package/dist/src/classes/ModUpgraded.d.ts.map +1 -1
  11. package/dist/src/classes/ModUpgraded.lua +35 -16
  12. package/dist/src/classes/callbacks/PostCustomRevive.d.ts +5 -2
  13. package/dist/src/classes/callbacks/PostCustomRevive.d.ts.map +1 -1
  14. package/dist/src/classes/callbacks/PostCustomRevive.lua +12 -4
  15. package/dist/src/classes/callbacks/PostGridEntityBroken.lua +1 -1
  16. package/dist/src/classes/callbacks/PostGridEntityCollision.lua +1 -1
  17. package/dist/src/classes/callbacks/PostGridEntityCustomBroken.lua +1 -1
  18. package/dist/src/classes/callbacks/PostGridEntityCustomCollision.lua +1 -1
  19. package/dist/src/classes/callbacks/PostGridEntityCustomInit.lua +1 -1
  20. package/dist/src/classes/callbacks/PostGridEntityCustomRemove.lua +1 -1
  21. package/dist/src/classes/callbacks/PostGridEntityCustomRender.d.ts +6 -0
  22. package/dist/src/classes/callbacks/PostGridEntityCustomRender.d.ts.map +1 -0
  23. package/dist/src/classes/callbacks/PostGridEntityCustomRender.lua +17 -0
  24. package/dist/src/classes/callbacks/PostGridEntityCustomStateChanged.lua +1 -1
  25. package/dist/src/classes/callbacks/PostGridEntityCustomUpdate.lua +1 -1
  26. package/dist/src/classes/callbacks/PostGridEntityInit.lua +1 -1
  27. package/dist/src/classes/callbacks/PostGridEntityRemove.lua +1 -1
  28. package/dist/src/classes/callbacks/PostGridEntityRender.d.ts +6 -0
  29. package/dist/src/classes/callbacks/PostGridEntityRender.d.ts.map +1 -0
  30. package/dist/src/classes/callbacks/PostGridEntityRender.lua +17 -0
  31. package/dist/src/classes/callbacks/PostGridEntityStateChanged.lua +1 -1
  32. package/dist/src/classes/callbacks/PostGridEntityUpdate.lua +1 -1
  33. package/dist/src/classes/callbacks/PostHolyMantleRemoved.d.ts +1 -1
  34. package/dist/src/classes/callbacks/PostHolyMantleRemoved.d.ts.map +1 -1
  35. package/dist/src/classes/callbacks/PostHolyMantleRemoved.lua +3 -4
  36. package/dist/src/classes/callbacks/PostItemDischarge.d.ts +43 -0
  37. package/dist/src/classes/callbacks/PostItemDischarge.d.ts.map +1 -0
  38. package/dist/src/classes/callbacks/PostItemDischarge.lua +113 -0
  39. package/dist/src/classes/callbacks/PostItemPickup.d.ts +6 -0
  40. package/dist/src/classes/callbacks/PostItemPickup.d.ts.map +1 -0
  41. package/dist/src/classes/callbacks/PostItemPickup.lua +17 -0
  42. package/dist/src/classes/callbacks/PostLaserInitLate.d.ts +12 -0
  43. package/dist/src/classes/callbacks/PostLaserInitLate.d.ts.map +1 -0
  44. package/dist/src/classes/callbacks/PostLaserInitLate.lua +27 -0
  45. package/dist/src/classes/callbacks/PostNPCInitLate.d.ts +12 -0
  46. package/dist/src/classes/callbacks/PostNPCInitLate.d.ts.map +1 -0
  47. package/dist/src/classes/callbacks/PostNPCInitLate.lua +27 -0
  48. package/dist/src/classes/callbacks/PostNPCStateChanged.d.ts +14 -0
  49. package/dist/src/classes/callbacks/PostNPCStateChanged.d.ts.map +1 -0
  50. package/dist/src/classes/callbacks/PostNPCStateChanged.lua +33 -0
  51. package/dist/src/classes/callbacks/PostPickupCollect.d.ts +12 -0
  52. package/dist/src/classes/callbacks/PostPickupCollect.d.ts.map +1 -0
  53. package/dist/src/classes/callbacks/PostPickupCollect.lua +35 -0
  54. package/dist/src/classes/callbacks/PostPickupInitFirst.d.ts +12 -0
  55. package/dist/src/classes/callbacks/PostPickupInitFirst.d.ts.map +1 -0
  56. package/dist/src/classes/callbacks/PostPickupInitFirst.lua +32 -0
  57. package/dist/src/classes/callbacks/PostPickupInitLate.d.ts +12 -0
  58. package/dist/src/classes/callbacks/PostPickupInitLate.d.ts.map +1 -0
  59. package/dist/src/classes/callbacks/PostPickupInitLate.lua +27 -0
  60. package/dist/src/classes/callbacks/PostPickupStateChanged.d.ts +13 -0
  61. package/dist/src/classes/callbacks/PostPickupStateChanged.d.ts.map +1 -0
  62. package/dist/src/classes/callbacks/PostPickupStateChanged.lua +33 -0
  63. package/dist/src/classes/callbacks/PostPitUpdate.d.ts +7 -0
  64. package/dist/src/classes/callbacks/PostPitUpdate.d.ts.map +1 -0
  65. package/dist/src/classes/callbacks/PostPitUpdate.lua +24 -0
  66. package/dist/src/classes/callbacks/PostPlayerChangeHealth.d.ts +15 -0
  67. package/dist/src/classes/callbacks/PostPlayerChangeHealth.d.ts.map +1 -0
  68. package/dist/src/classes/callbacks/PostPlayerChangeHealth.lua +52 -0
  69. package/dist/src/classes/callbacks/PostPlayerChangeStat.d.ts +16 -0
  70. package/dist/src/classes/callbacks/PostPlayerChangeStat.d.ts.map +1 -0
  71. package/dist/src/classes/callbacks/PostPlayerChangeStat.lua +94 -0
  72. package/dist/src/classes/callbacks/PostPlayerChangeType.d.ts +15 -0
  73. package/dist/src/classes/callbacks/PostPlayerChangeType.d.ts.map +1 -0
  74. package/dist/src/classes/callbacks/PostPlayerChangeType.lua +37 -0
  75. package/dist/src/classes/callbacks/PostPlayerCollectibleAdded.d.ts +6 -0
  76. package/dist/src/classes/callbacks/PostPlayerCollectibleAdded.d.ts.map +1 -0
  77. package/dist/src/classes/callbacks/PostPlayerCollectibleAdded.lua +17 -0
  78. package/dist/src/classes/callbacks/PostPlayerCollectibleRemoved.d.ts +6 -0
  79. package/dist/src/classes/callbacks/PostPlayerCollectibleRemoved.d.ts.map +1 -0
  80. package/dist/src/classes/callbacks/PostPlayerCollectibleRemoved.lua +17 -0
  81. package/dist/src/classes/callbacks/PostPlayerInitFirst.d.ts +8 -0
  82. package/dist/src/classes/callbacks/PostPlayerInitFirst.d.ts.map +1 -0
  83. package/dist/src/classes/callbacks/PostPlayerInitFirst.lua +39 -0
  84. package/dist/src/classes/callbacks/PostPlayerInitLate.d.ts +13 -0
  85. package/dist/src/classes/callbacks/PostPlayerInitLate.d.ts.map +1 -0
  86. package/dist/src/classes/callbacks/PostPlayerInitLate.lua +29 -0
  87. package/dist/src/classes/callbacks/PostPoopRender.d.ts +7 -0
  88. package/dist/src/classes/callbacks/PostPoopRender.d.ts.map +1 -0
  89. package/dist/src/classes/callbacks/PostPoopRender.lua +24 -0
  90. package/dist/src/classes/callbacks/PostPoopUpdate.d.ts +7 -0
  91. package/dist/src/classes/callbacks/PostPoopUpdate.d.ts.map +1 -0
  92. package/dist/src/classes/callbacks/PostPoopUpdate.lua +24 -0
  93. package/dist/src/classes/callbacks/PostPressurePlateRender.d.ts +7 -0
  94. package/dist/src/classes/callbacks/PostPressurePlateRender.d.ts.map +1 -0
  95. package/dist/src/classes/callbacks/PostPressurePlateRender.lua +24 -0
  96. package/dist/src/classes/callbacks/PostPressurePlateUpdate.d.ts +7 -0
  97. package/dist/src/classes/callbacks/PostPressurePlateUpdate.d.ts.map +1 -0
  98. package/dist/src/classes/callbacks/PostPressurePlateUpdate.lua +24 -0
  99. package/dist/src/classes/callbacks/PostProjectileInitLate.d.ts +12 -0
  100. package/dist/src/classes/callbacks/PostProjectileInitLate.d.ts.map +1 -0
  101. package/dist/src/classes/callbacks/PostProjectileInitLate.lua +27 -0
  102. package/dist/src/classes/callbacks/PostPurchase.d.ts +18 -0
  103. package/dist/src/classes/callbacks/PostPurchase.d.ts.map +1 -0
  104. package/dist/src/classes/callbacks/PostPurchase.lua +56 -0
  105. package/dist/src/classes/callbacks/PostRockRender.d.ts +7 -0
  106. package/dist/src/classes/callbacks/PostRockRender.d.ts.map +1 -0
  107. package/dist/src/classes/callbacks/PostRockRender.lua +24 -0
  108. package/dist/src/classes/callbacks/PostRockUpdate.d.ts +7 -0
  109. package/dist/src/classes/callbacks/PostRockUpdate.d.ts.map +1 -0
  110. package/dist/src/classes/callbacks/PostRockUpdate.lua +24 -0
  111. package/dist/src/classes/callbacks/PostSacrifice.d.ts +15 -0
  112. package/dist/src/classes/callbacks/PostSacrifice.d.ts.map +1 -0
  113. package/dist/src/classes/callbacks/PostSacrifice.lua +52 -0
  114. package/dist/src/classes/callbacks/PostSlotAnimationChanged.d.ts +6 -0
  115. package/dist/src/classes/callbacks/PostSlotAnimationChanged.d.ts.map +1 -0
  116. package/dist/src/classes/callbacks/PostSlotAnimationChanged.lua +17 -0
  117. package/dist/src/classes/callbacks/PostSlotCollision.d.ts +7 -0
  118. package/dist/src/classes/callbacks/PostSlotCollision.d.ts.map +1 -0
  119. package/dist/src/classes/callbacks/PostSlotCollision.lua +25 -0
  120. package/dist/src/classes/callbacks/PostSlotDestroyed.d.ts +14 -0
  121. package/dist/src/classes/callbacks/PostSlotDestroyed.d.ts.map +1 -0
  122. package/dist/src/classes/callbacks/PostSlotDestroyed.lua +65 -0
  123. package/dist/src/classes/callbacks/PostSlotInit.d.ts +6 -0
  124. package/dist/src/classes/callbacks/PostSlotInit.d.ts.map +1 -0
  125. package/dist/src/classes/callbacks/PostSlotInit.lua +17 -0
  126. package/dist/src/classes/callbacks/PostSlotRender.d.ts +6 -0
  127. package/dist/src/classes/callbacks/PostSlotRender.d.ts.map +1 -0
  128. package/dist/src/classes/callbacks/PostSlotRender.lua +17 -0
  129. package/dist/src/classes/callbacks/PostSlotUpdate.d.ts +6 -0
  130. package/dist/src/classes/callbacks/PostSlotUpdate.d.ts.map +1 -0
  131. package/dist/src/classes/callbacks/PostSlotUpdate.lua +17 -0
  132. package/dist/src/classes/callbacks/PostSpikesUpdate.d.ts +7 -0
  133. package/dist/src/classes/callbacks/PostSpikesUpdate.d.ts.map +1 -0
  134. package/dist/src/classes/callbacks/PostSpikesUpdate.lua +24 -0
  135. package/dist/src/classes/callbacks/PostTNTRender.d.ts +7 -0
  136. package/dist/src/classes/callbacks/PostTNTRender.d.ts.map +1 -0
  137. package/dist/src/classes/callbacks/PostTNTRender.lua +24 -0
  138. package/dist/src/classes/callbacks/PostTNTUpdate.d.ts +7 -0
  139. package/dist/src/classes/callbacks/PostTNTUpdate.d.ts.map +1 -0
  140. package/dist/src/classes/callbacks/PostTNTUpdate.lua +24 -0
  141. package/dist/src/classes/callbacks/PostTearInitLate.d.ts +12 -0
  142. package/dist/src/classes/callbacks/PostTearInitLate.d.ts.map +1 -0
  143. package/dist/src/classes/callbacks/PostTearInitLate.lua +27 -0
  144. package/dist/src/classes/callbacks/PostTearInitVeryLate.d.ts +12 -0
  145. package/dist/src/classes/callbacks/PostTearInitVeryLate.d.ts.map +1 -0
  146. package/dist/src/classes/callbacks/PostTearInitVeryLate.lua +30 -0
  147. package/dist/src/classes/callbacks/PostTransformation.d.ts +18 -0
  148. package/dist/src/classes/callbacks/PostTransformation.d.ts.map +1 -0
  149. package/dist/src/classes/callbacks/PostTransformation.lua +53 -0
  150. package/dist/src/classes/callbacks/PreBerserkDeath.d.ts +1 -1
  151. package/dist/src/classes/callbacks/PreBerserkDeath.d.ts.map +1 -1
  152. package/dist/src/classes/callbacks/PreBerserkDeath.lua +3 -4
  153. package/dist/src/classes/callbacks/PreItemPickup.d.ts +6 -0
  154. package/dist/src/classes/callbacks/PreItemPickup.d.ts.map +1 -0
  155. package/dist/src/classes/callbacks/PreItemPickup.lua +17 -0
  156. package/dist/src/classes/callbacks/validation/CustomCallbackCollectibleType.d.ts +10 -0
  157. package/dist/src/classes/callbacks/validation/CustomCallbackCollectibleType.d.ts.map +1 -0
  158. package/dist/src/classes/callbacks/validation/CustomCallbackCollectibleType.lua +19 -0
  159. package/dist/src/classes/callbacks/validation/CustomCallbackItemPickup.d.ts +11 -0
  160. package/dist/src/classes/callbacks/validation/CustomCallbackItemPickup.d.ts.map +1 -0
  161. package/dist/src/classes/callbacks/validation/CustomCallbackItemPickup.lua +22 -0
  162. package/dist/src/classes/callbacks/validation/CustomCallbackLaser.d.ts +10 -0
  163. package/dist/src/classes/callbacks/validation/CustomCallbackLaser.d.ts.map +1 -0
  164. package/dist/src/classes/callbacks/validation/CustomCallbackLaser.lua +19 -0
  165. package/dist/src/classes/callbacks/validation/{CustomCallbackRevive.d.ts → CustomCallbackNPC.d.ts} +4 -4
  166. package/dist/src/classes/callbacks/validation/CustomCallbackNPC.d.ts.map +1 -0
  167. package/dist/src/classes/callbacks/validation/CustomCallbackNPC.lua +22 -0
  168. package/dist/src/classes/callbacks/validation/CustomCallbackPickup.d.ts +12 -0
  169. package/dist/src/classes/callbacks/validation/CustomCallbackPickup.d.ts.map +1 -0
  170. package/dist/src/classes/callbacks/validation/CustomCallbackPickup.lua +22 -0
  171. package/dist/src/classes/callbacks/validation/CustomCallbackPlayer.d.ts +5 -2
  172. package/dist/src/classes/callbacks/validation/CustomCallbackPlayer.d.ts.map +1 -1
  173. package/dist/src/classes/callbacks/validation/CustomCallbackPoop.d.ts +10 -0
  174. package/dist/src/classes/callbacks/validation/CustomCallbackPoop.d.ts.map +1 -0
  175. package/dist/src/classes/callbacks/validation/CustomCallbackPoop.lua +20 -0
  176. package/dist/src/classes/callbacks/validation/CustomCallbackPressurePlate.d.ts +10 -0
  177. package/dist/src/classes/callbacks/validation/CustomCallbackPressurePlate.d.ts.map +1 -0
  178. package/dist/src/classes/callbacks/validation/CustomCallbackPressurePlate.lua +20 -0
  179. package/dist/src/classes/callbacks/validation/CustomCallbackProjectile.d.ts +10 -0
  180. package/dist/src/classes/callbacks/validation/CustomCallbackProjectile.d.ts.map +1 -0
  181. package/dist/src/classes/callbacks/validation/CustomCallbackProjectile.lua +19 -0
  182. package/dist/src/classes/callbacks/validation/CustomCallbackRock.d.ts +10 -0
  183. package/dist/src/classes/callbacks/validation/CustomCallbackRock.d.ts.map +1 -0
  184. package/dist/src/classes/callbacks/validation/CustomCallbackRock.lua +20 -0
  185. package/dist/src/classes/callbacks/validation/CustomCallbackSlot.d.ts +12 -0
  186. package/dist/src/classes/callbacks/validation/CustomCallbackSlot.d.ts.map +1 -0
  187. package/dist/src/classes/callbacks/validation/CustomCallbackSlot.lua +19 -0
  188. package/dist/src/classes/callbacks/validation/CustomCallbackSpikes.lua +4 -4
  189. package/dist/src/classes/callbacks/validation/CustomCallbackTNT.d.ts +10 -0
  190. package/dist/src/classes/callbacks/validation/CustomCallbackTNT.d.ts.map +1 -0
  191. package/dist/src/classes/callbacks/validation/CustomCallbackTNT.lua +20 -0
  192. package/dist/src/classes/callbacks/validation/CustomCallbackTear.d.ts +10 -0
  193. package/dist/src/classes/callbacks/validation/CustomCallbackTear.d.ts.map +1 -0
  194. package/dist/src/classes/callbacks/validation/CustomCallbackTear.lua +19 -0
  195. package/dist/src/classes/features/callbackLogic/CustomGridEntities.d.ts +1 -1
  196. package/dist/src/classes/features/callbackLogic/CustomGridEntities.d.ts.map +1 -1
  197. package/dist/src/classes/features/callbackLogic/CustomGridEntities.lua +27 -30
  198. package/dist/src/classes/features/callbackLogic/CustomRevive.d.ts +2 -2
  199. package/dist/src/classes/features/callbackLogic/CustomRevive.d.ts.map +1 -1
  200. package/dist/src/classes/features/callbackLogic/CustomRevive.lua +6 -6
  201. package/dist/src/classes/features/callbackLogic/EsauJrDetection.d.ts.map +1 -1
  202. package/dist/src/classes/features/callbackLogic/GameReorderedCallbacks.d.ts.map +1 -1
  203. package/dist/src/classes/features/callbackLogic/GameReorderedCallbacks.lua +3 -18
  204. package/dist/src/classes/features/callbackLogic/GridEntityCollisionDetection.d.ts.map +1 -1
  205. package/dist/src/classes/features/callbackLogic/GridEntityRenderDetection.d.ts +12 -0
  206. package/dist/src/classes/features/callbackLogic/GridEntityRenderDetection.d.ts.map +1 -0
  207. package/dist/src/classes/features/callbackLogic/GridEntityRenderDetection.lua +33 -0
  208. package/dist/src/classes/features/callbackLogic/{GridEntityDetection.d.ts → GridEntityUpdateDetection.d.ts} +3 -3
  209. package/dist/src/classes/features/callbackLogic/GridEntityUpdateDetection.d.ts.map +1 -0
  210. package/dist/src/classes/features/callbackLogic/{GridEntityDetection.lua → GridEntityUpdateDetection.lua} +11 -14
  211. package/dist/src/classes/features/callbackLogic/ItemPickupDetection.d.ts +20 -0
  212. package/dist/src/classes/features/callbackLogic/ItemPickupDetection.d.ts.map +1 -0
  213. package/dist/src/classes/features/callbackLogic/ItemPickupDetection.lua +60 -0
  214. package/dist/src/classes/features/callbackLogic/PlayerCollectibleDetection.d.ts +47 -0
  215. package/dist/src/classes/features/callbackLogic/PlayerCollectibleDetection.d.ts.map +1 -0
  216. package/dist/src/classes/features/callbackLogic/PlayerCollectibleDetection.lua +154 -0
  217. package/dist/src/classes/features/callbackLogic/SlotRenderDetection.d.ts +18 -0
  218. package/dist/src/classes/features/callbackLogic/SlotRenderDetection.d.ts.map +1 -0
  219. package/dist/src/classes/features/callbackLogic/SlotRenderDetection.lua +51 -0
  220. package/dist/src/classes/features/callbackLogic/SlotUpdateDetection.d.ts +17 -0
  221. package/dist/src/classes/features/callbackLogic/SlotUpdateDetection.d.ts.map +1 -0
  222. package/dist/src/classes/features/callbackLogic/SlotUpdateDetection.lua +45 -0
  223. package/dist/src/classes/features/other/RunInNFrames.d.ts.map +1 -1
  224. package/dist/src/classes/features/other/RunInNFrames.lua +9 -0
  225. package/dist/src/classes/features/other/SaveDataManager.d.ts +215 -0
  226. package/dist/src/classes/features/other/SaveDataManager.d.ts.map +1 -0
  227. package/dist/src/classes/features/other/SaveDataManager.lua +190 -0
  228. package/dist/src/classes/features/other/saveDataManager/glowingHourGlass.d.ts +6 -0
  229. package/dist/src/classes/features/other/saveDataManager/glowingHourGlass.d.ts.map +1 -0
  230. package/dist/src/classes/features/other/saveDataManager/glowingHourGlass.lua +98 -0
  231. package/dist/src/classes/features/other/saveDataManager/loadFromDisk.d.ts +6 -0
  232. package/dist/src/classes/features/other/saveDataManager/loadFromDisk.d.ts.map +1 -0
  233. package/dist/src/classes/features/other/saveDataManager/loadFromDisk.lua +81 -0
  234. package/dist/src/classes/features/other/saveDataManager/restoreDefaults.d.ts +7 -0
  235. package/dist/src/classes/features/other/saveDataManager/restoreDefaults.d.ts.map +1 -0
  236. package/dist/src/classes/features/other/saveDataManager/restoreDefaults.lua +69 -0
  237. package/dist/src/classes/features/other/saveDataManager/saveToDisk.d.ts +5 -0
  238. package/dist/src/classes/features/other/saveDataManager/saveToDisk.d.ts.map +1 -0
  239. package/dist/src/classes/features/other/saveDataManager/saveToDisk.lua +46 -0
  240. package/dist/src/classes/private/CustomCallback.d.ts +2 -3
  241. package/dist/src/classes/private/CustomCallback.d.ts.map +1 -1
  242. package/dist/src/classes/private/CustomCallback.lua +2 -5
  243. package/dist/src/classes/private/Feature.d.ts +1 -0
  244. package/dist/src/classes/private/Feature.d.ts.map +1 -1
  245. package/dist/src/classes/private/Feature.lua +1 -0
  246. package/dist/src/core/upgradeMod.d.ts +2 -5
  247. package/dist/src/core/upgradeMod.d.ts.map +1 -1
  248. package/dist/src/decorators.d.ts +1 -1
  249. package/dist/src/decorators.d.ts.map +1 -1
  250. package/dist/src/decorators.lua +6 -8
  251. package/dist/src/enums/ISCFeature.d.ts +15 -9
  252. package/dist/src/enums/ISCFeature.d.ts.map +1 -1
  253. package/dist/src/enums/ISCFeature.lua +30 -9
  254. package/dist/src/enums/ModCallbackCustom.d.ts +34 -20
  255. package/dist/src/enums/ModCallbackCustom.d.ts.map +1 -1
  256. package/dist/src/enums/ModCallbackCustom2.d.ts +61 -20
  257. package/dist/src/enums/ModCallbackCustom2.d.ts.map +1 -1
  258. package/dist/src/enums/ModCallbackCustom2.lua +102 -20
  259. package/dist/src/enums/{private/SerializationBrand.d.ts → SerializationBrand.d.ts} +6 -1
  260. package/dist/src/enums/SerializationBrand.d.ts.map +1 -0
  261. package/dist/src/enums/{private/SerializationBrand.lua → SerializationBrand.lua} +1 -0
  262. package/dist/src/features/customItemPool.d.ts +52 -0
  263. package/dist/src/features/customItemPool.d.ts.map +1 -0
  264. package/dist/src/features/customItemPool.lua +111 -0
  265. package/dist/src/features/deployJSONRoom.d.ts +6 -4
  266. package/dist/src/features/deployJSONRoom.d.ts.map +1 -1
  267. package/dist/src/features/deployJSONRoom.lua +6 -4
  268. package/dist/src/features/fadeInRemover.d.ts.map +1 -1
  269. package/dist/src/features/fadeInRemover.lua +4 -16
  270. package/dist/src/features/saveDataManager/exports.d.ts +14 -4
  271. package/dist/src/features/saveDataManager/exports.d.ts.map +1 -1
  272. package/dist/src/features/saveDataManager/exports.lua +38 -0
  273. package/dist/src/features/saveDataManager/load.d.ts +2 -1
  274. package/dist/src/features/saveDataManager/load.d.ts.map +1 -1
  275. package/dist/src/features/saveDataManager/load.lua +10 -4
  276. package/dist/src/features/saveDataManager/main.d.ts.map +1 -1
  277. package/dist/src/features/saveDataManager/main.lua +12 -5
  278. package/dist/src/features/saveDataManager/maps.d.ts +14 -0
  279. package/dist/src/features/saveDataManager/maps.d.ts.map +1 -1
  280. package/dist/src/features/saveDataManager/maps.lua +7 -0
  281. package/dist/src/features.d.ts +31 -12
  282. package/dist/src/features.d.ts.map +1 -1
  283. package/dist/src/features.lua +24 -6
  284. package/dist/src/functions/array.d.ts.map +1 -1
  285. package/dist/src/functions/array.lua +4 -5
  286. package/dist/src/functions/bitSet128.d.ts +2 -2
  287. package/dist/src/functions/bitSet128.lua +3 -3
  288. package/dist/src/functions/color.d.ts +2 -2
  289. package/dist/src/functions/color.lua +3 -3
  290. package/dist/src/functions/decorators.d.ts +28 -6
  291. package/dist/src/functions/decorators.d.ts.map +1 -1
  292. package/dist/src/functions/decorators.lua +24 -5
  293. package/dist/src/functions/deepCopy.d.ts +11 -4
  294. package/dist/src/functions/deepCopy.d.ts.map +1 -1
  295. package/dist/src/functions/deepCopy.lua +84 -32
  296. package/dist/src/functions/deepCopyTests.lua +1 -1
  297. package/dist/src/functions/initArray.d.ts +4 -4
  298. package/dist/src/functions/initArray.d.ts.map +1 -1
  299. package/dist/src/functions/initArray.lua +6 -12
  300. package/dist/src/functions/jsonRoom.d.ts +11 -0
  301. package/dist/src/functions/jsonRoom.d.ts.map +1 -1
  302. package/dist/src/functions/jsonRoom.lua +11 -0
  303. package/dist/src/functions/kColor.d.ts +2 -2
  304. package/dist/src/functions/kColor.lua +3 -3
  305. package/dist/src/functions/logMisc.d.ts +9 -2
  306. package/dist/src/functions/logMisc.d.ts.map +1 -1
  307. package/dist/src/functions/logMisc.lua +32 -2
  308. package/dist/src/functions/merge.d.ts +40 -0
  309. package/dist/src/functions/merge.d.ts.map +1 -0
  310. package/dist/src/{features/saveDataManager → functions}/merge.lua +84 -37
  311. package/dist/src/functions/mergeTests.d.ts +1 -2
  312. package/dist/src/functions/mergeTests.d.ts.map +1 -1
  313. package/dist/src/functions/mergeTests.lua +3 -4
  314. package/dist/src/functions/rng.d.ts +2 -2
  315. package/dist/src/functions/rng.lua +3 -3
  316. package/dist/src/functions/serialization.d.ts.map +1 -1
  317. package/dist/src/functions/serialization.lua +22 -0
  318. package/dist/src/functions/tstlClass.d.ts +0 -10
  319. package/dist/src/functions/tstlClass.d.ts.map +1 -1
  320. package/dist/src/functions/tstlClass.lua +2 -42
  321. package/dist/src/functions/vector.d.ts +2 -2
  322. package/dist/src/functions/vector.lua +3 -3
  323. package/dist/src/functions/weighted.d.ts +12 -1
  324. package/dist/src/functions/weighted.d.ts.map +1 -1
  325. package/dist/src/functions/weighted.lua +27 -10
  326. package/dist/src/index.d.ts +5 -0
  327. package/dist/src/index.d.ts.map +1 -1
  328. package/dist/src/index.lua +24 -0
  329. package/dist/src/interfaces/SaveData.d.ts +3 -7
  330. package/dist/src/interfaces/SaveData.d.ts.map +1 -1
  331. package/dist/src/interfaces/SaveData.lua +0 -11
  332. package/dist/src/interfaces/private/AddCallbackParametersCustom2.d.ts +195 -2
  333. package/dist/src/interfaces/private/AddCallbackParametersCustom2.d.ts.map +1 -1
  334. package/dist/src/objects/isaacAPIClassTypeToBrand.d.ts +1 -1
  335. package/dist/src/objects/isaacAPIClassTypeToBrand.d.ts.map +1 -1
  336. package/dist/src/objects/isaacAPIClassTypeToBrand.lua +1 -1
  337. package/dist/src/types/AnyClass.d.ts +2 -0
  338. package/dist/src/types/AnyClass.d.ts.map +1 -0
  339. package/dist/src/types/AnyClass.lua +2 -0
  340. package/dist/src/types/AnyFunction.d.ts +6 -0
  341. package/dist/src/types/AnyFunction.d.ts.map +1 -0
  342. package/dist/src/types/AnyFunction.lua +2 -0
  343. package/dist/src/types/FunctionTuple.d.ts +2 -4
  344. package/dist/src/types/FunctionTuple.d.ts.map +1 -1
  345. package/dist/src/types/HasFunction.d.ts +5 -0
  346. package/dist/src/types/HasFunction.d.ts.map +1 -0
  347. package/dist/src/types/HasFunction.lua +2 -0
  348. package/package.json +1 -1
  349. package/src/callbacks.ts +88 -5
  350. package/src/classes/ModFeature.ts +96 -6
  351. package/src/classes/ModUpgraded.ts +57 -32
  352. package/src/classes/callbacks/PostCustomRevive.ts +22 -2
  353. package/src/classes/callbacks/PostGridEntityBroken.ts +1 -1
  354. package/src/classes/callbacks/PostGridEntityCollision.ts +1 -1
  355. package/src/classes/callbacks/PostGridEntityCustomBroken.ts +1 -1
  356. package/src/classes/callbacks/PostGridEntityCustomCollision.ts +1 -1
  357. package/src/classes/callbacks/PostGridEntityCustomInit.ts +1 -1
  358. package/src/classes/callbacks/PostGridEntityCustomRemove.ts +1 -1
  359. package/src/classes/callbacks/PostGridEntityCustomRender.ts +11 -0
  360. package/src/classes/callbacks/PostGridEntityCustomStateChanged.ts +1 -1
  361. package/src/classes/callbacks/PostGridEntityCustomUpdate.ts +1 -1
  362. package/src/classes/callbacks/PostGridEntityInit.ts +1 -1
  363. package/src/classes/callbacks/PostGridEntityRemove.ts +1 -1
  364. package/src/classes/callbacks/PostGridEntityRender.ts +11 -0
  365. package/src/classes/callbacks/PostGridEntityStateChanged.ts +1 -1
  366. package/src/classes/callbacks/PostGridEntityUpdate.ts +1 -1
  367. package/src/classes/callbacks/PostHolyMantleRemoved.ts +5 -8
  368. package/src/classes/callbacks/PostItemDischarge.ts +181 -0
  369. package/src/classes/callbacks/PostItemPickup.ts +11 -0
  370. package/src/classes/callbacks/PostLaserInitLate.ts +28 -0
  371. package/src/classes/callbacks/PostNPCInitLate.ts +28 -0
  372. package/src/classes/callbacks/PostNPCStateChanged.ts +37 -0
  373. package/src/classes/callbacks/PostPickupCollect.ts +37 -0
  374. package/src/classes/callbacks/PostPickupInitFirst.ts +34 -0
  375. package/src/classes/callbacks/PostPickupInitLate.ts +28 -0
  376. package/src/classes/callbacks/PostPickupStateChanged.ts +35 -0
  377. package/src/classes/callbacks/PostPitUpdate.ts +21 -0
  378. package/src/classes/callbacks/PostPlayerChangeHealth.ts +57 -0
  379. package/src/classes/callbacks/PostPlayerChangeStat.ts +102 -0
  380. package/src/classes/callbacks/PostPlayerChangeType.ts +44 -0
  381. package/src/classes/callbacks/PostPlayerCollectibleAdded.ts +11 -0
  382. package/src/classes/callbacks/PostPlayerCollectibleRemoved.ts +11 -0
  383. package/src/classes/callbacks/PostPlayerInitFirst.ts +44 -0
  384. package/src/classes/callbacks/PostPlayerInitLate.ts +32 -0
  385. package/src/classes/callbacks/PostPoopRender.ts +21 -0
  386. package/src/classes/callbacks/PostPoopUpdate.ts +21 -0
  387. package/src/classes/callbacks/PostPressurePlateRender.ts +21 -0
  388. package/src/classes/callbacks/PostPressurePlateUpdate.ts +21 -0
  389. package/src/classes/callbacks/PostProjectileInitLate.ts +28 -0
  390. package/src/classes/callbacks/PostPurchase.ts +87 -0
  391. package/src/classes/callbacks/PostRockRender.ts +21 -0
  392. package/src/classes/callbacks/PostRockUpdate.ts +21 -0
  393. package/src/classes/callbacks/PostSacrifice.ts +89 -0
  394. package/src/classes/callbacks/PostSlotAnimationChanged.ts +11 -0
  395. package/src/classes/callbacks/PostSlotCollision.ts +26 -0
  396. package/src/classes/callbacks/PostSlotDestroyed.ts +79 -0
  397. package/src/classes/callbacks/PostSlotInit.ts +11 -0
  398. package/src/classes/callbacks/PostSlotRender.ts +11 -0
  399. package/src/classes/callbacks/PostSlotUpdate.ts +11 -0
  400. package/src/classes/callbacks/PostSpikesUpdate.ts +21 -0
  401. package/src/classes/callbacks/PostTNTRender.ts +21 -0
  402. package/src/classes/callbacks/PostTNTUpdate.ts +21 -0
  403. package/src/classes/callbacks/PostTearInitLate.ts +28 -0
  404. package/src/classes/callbacks/PostTearInitVeryLate.ts +33 -0
  405. package/src/classes/callbacks/PostTransformation.ts +71 -0
  406. package/src/classes/callbacks/PreBerserkDeath.ts +5 -8
  407. package/src/classes/callbacks/PreItemPickup.ts +11 -0
  408. package/src/classes/callbacks/validation/CustomCallbackCollectibleType.ts +32 -0
  409. package/src/classes/callbacks/validation/CustomCallbackItemPickup.ts +48 -0
  410. package/src/classes/callbacks/validation/CustomCallbackLaser.ts +27 -0
  411. package/src/classes/callbacks/validation/CustomCallbackNPC.ts +34 -0
  412. package/src/classes/callbacks/validation/CustomCallbackPickup.ts +41 -0
  413. package/src/classes/callbacks/validation/CustomCallbackPlayer.ts +25 -2
  414. package/src/classes/callbacks/validation/CustomCallbackPoop.ts +28 -0
  415. package/src/classes/callbacks/validation/CustomCallbackPressurePlate.ts +31 -0
  416. package/src/classes/callbacks/validation/CustomCallbackProjectile.ts +28 -0
  417. package/src/classes/callbacks/validation/CustomCallbackRock.ts +30 -0
  418. package/src/classes/callbacks/validation/CustomCallbackSlot.ts +37 -0
  419. package/src/classes/callbacks/validation/CustomCallbackSpikes.ts +4 -4
  420. package/src/classes/callbacks/validation/CustomCallbackTNT.ts +28 -0
  421. package/src/classes/callbacks/validation/CustomCallbackTear.ts +27 -0
  422. package/src/classes/features/callbackLogic/CustomGridEntities.ts +32 -36
  423. package/src/classes/features/callbackLogic/CustomRevive.ts +14 -21
  424. package/src/classes/features/callbackLogic/EsauJrDetection.ts +0 -4
  425. package/src/classes/features/callbackLogic/GameReorderedCallbacks.ts +7 -9
  426. package/src/classes/features/callbackLogic/GridEntityCollisionDetection.ts +0 -4
  427. package/src/classes/features/callbackLogic/GridEntityRenderDetection.ts +42 -0
  428. package/src/classes/features/callbackLogic/{GridEntityDetection.ts → GridEntityUpdateDetection.ts} +4 -20
  429. package/src/classes/features/callbackLogic/ItemPickupDetection.ts +91 -0
  430. package/src/classes/features/callbackLogic/PlayerCollectibleDetection.ts +245 -0
  431. package/src/classes/features/callbackLogic/SlotRenderDetection.ts +64 -0
  432. package/src/classes/features/callbackLogic/SlotUpdateDetection.ts +57 -0
  433. package/src/classes/features/other/RunInNFrames.ts +7 -0
  434. package/src/classes/features/other/SaveDataManager.ts +492 -0
  435. package/src/classes/features/other/saveDataManager/glowingHourGlass.ts +138 -0
  436. package/src/classes/features/other/saveDataManager/loadFromDisk.ts +99 -0
  437. package/src/classes/features/other/saveDataManager/restoreDefaults.ts +116 -0
  438. package/src/classes/features/other/saveDataManager/saveToDisk.ts +70 -0
  439. package/src/classes/private/CustomCallback.ts +2 -6
  440. package/src/classes/private/Feature.ts +1 -0
  441. package/src/core/upgradeMod.ts +6 -13
  442. package/src/decorators.ts +17 -16
  443. package/src/enums/ISCFeature.ts +44 -39
  444. package/src/enums/ModCallbackCustom.ts +34 -20
  445. package/src/enums/ModCallbackCustom2.ts +53 -5
  446. package/src/enums/{private/SerializationBrand.ts → SerializationBrand.ts} +8 -2
  447. package/src/features/customItemPool.ts +133 -0
  448. package/src/features/deployJSONRoom.ts +6 -4
  449. package/src/features/fadeInRemover.ts +4 -22
  450. package/src/features/saveDataManager/exports.ts +62 -3
  451. package/src/features/saveDataManager/load.ts +4 -1
  452. package/src/features/saveDataManager/main.ts +5 -3
  453. package/src/features/saveDataManager/maps.ts +16 -0
  454. package/src/features.ts +39 -4
  455. package/src/functions/array.ts +8 -9
  456. package/src/functions/bitSet128.ts +3 -3
  457. package/src/functions/color.ts +3 -3
  458. package/src/functions/decorators.ts +83 -12
  459. package/src/functions/deepCopy.ts +83 -17
  460. package/src/functions/deepCopyTests.ts +1 -1
  461. package/src/functions/initArray.ts +6 -11
  462. package/src/functions/jsonRoom.ts +11 -0
  463. package/src/functions/kColor.ts +3 -3
  464. package/src/functions/logMisc.ts +28 -2
  465. package/src/{features/saveDataManager → functions}/merge.ts +79 -45
  466. package/src/functions/mergeTests.ts +2 -3
  467. package/src/functions/rng.ts +3 -3
  468. package/src/functions/serialization.ts +25 -1
  469. package/src/functions/table.ts +1 -1
  470. package/src/functions/tstlClass.ts +3 -57
  471. package/src/functions/vector.ts +3 -3
  472. package/src/functions/weighted.ts +28 -11
  473. package/src/index.ts +5 -0
  474. package/src/interfaces/SaveData.ts +3 -34
  475. package/src/interfaces/private/AddCallbackParametersCustom2.ts +298 -7
  476. package/src/objects/isaacAPIClassTypeToBrand.ts +1 -1
  477. package/src/types/AnyClass.ts +1 -0
  478. package/src/types/AnyFunction.ts +5 -0
  479. package/src/types/FunctionTuple.ts +3 -4
  480. package/src/types/HasFunction.ts +7 -0
  481. package/dist/src/classes/callbacks/validation/CustomCallbackRevive.d.ts.map +0 -1
  482. package/dist/src/classes/callbacks/validation/CustomCallbackRevive.lua +0 -19
  483. package/dist/src/classes/features/callbackLogic/GridEntityDetection.d.ts.map +0 -1
  484. package/dist/src/enums/private/SerializationBrand.d.ts.map +0 -1
  485. package/dist/src/features/saveDataManager/merge.d.ts +0 -26
  486. package/dist/src/features/saveDataManager/merge.d.ts.map +0 -1
  487. package/dist/src/features/saveDataManager/serializationBrands.d.ts +0 -2
  488. package/dist/src/features/saveDataManager/serializationBrands.d.ts.map +0 -1
  489. package/dist/src/features/saveDataManager/serializationBrands.lua +0 -19
  490. package/dist/src/indexLua.d.ts +0 -199
  491. package/dist/src/indexLua.d.ts.map +0 -1
  492. package/dist/src/indexLua.lua +0 -1354
  493. package/src/classes/callbacks/validation/CustomCallbackRevive.ts +0 -27
  494. package/src/features/saveDataManager/serializationBrands.ts +0 -16
@@ -0,0 +1,64 @@
1
+ import { ModCallback } from "isaac-typescript-definitions";
2
+ import { getSlots } from "../../../functions/entitiesSpecific";
3
+ import { PostSlotAnimationChanged } from "../../callbacks/PostSlotAnimationChanged";
4
+ import { PostSlotRender } from "../../callbacks/PostSlotRender";
5
+ import { DefaultMap } from "../../DefaultMap";
6
+ import { Feature } from "../../private/Feature";
7
+
8
+ export class SlotRenderDetection extends Feature {
9
+ public override v = {
10
+ room: {
11
+ slotAnimations: new DefaultMap<PtrHash, string, [slot: Entity]>(
12
+ (slot: Entity) => {
13
+ const sprite = slot.GetSprite();
14
+ return sprite.GetAnimation();
15
+ },
16
+ ),
17
+ brokenSlots: new Set<PtrHash>(),
18
+ },
19
+ };
20
+
21
+ private postSlotRender: PostSlotRender;
22
+ private postSlotAnimationChanged: PostSlotAnimationChanged;
23
+
24
+ constructor(
25
+ postSlotRender: PostSlotRender,
26
+ postSlotAnimationChanged: PostSlotAnimationChanged,
27
+ ) {
28
+ super();
29
+
30
+ this.callbacksUsed = [
31
+ [ModCallback.POST_RENDER, [this.postRender]], // 2
32
+ ];
33
+
34
+ this.postSlotRender = postSlotRender;
35
+ this.postSlotAnimationChanged = postSlotAnimationChanged;
36
+ }
37
+
38
+ // ModCallback.POST_RENDER (2)
39
+ private postRender = () => {
40
+ for (const slot of getSlots()) {
41
+ this.postSlotRender.fire(slot);
42
+ this.checkSlotAnimationChanged(slot);
43
+ }
44
+ };
45
+
46
+ private checkSlotAnimationChanged(slot: EntitySlot) {
47
+ const sprite = slot.GetSprite();
48
+ const currentAnimation = sprite.GetAnimation();
49
+ const ptrHash = GetPtrHash(slot);
50
+ const previousAnimation = this.v.room.slotAnimations.getAndSetDefault(
51
+ ptrHash,
52
+ slot,
53
+ );
54
+ this.v.room.slotAnimations.set(ptrHash, currentAnimation);
55
+
56
+ if (currentAnimation !== previousAnimation) {
57
+ this.postSlotAnimationChanged.fire(
58
+ slot,
59
+ previousAnimation,
60
+ currentAnimation,
61
+ );
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,57 @@
1
+ import { ModCallback } from "isaac-typescript-definitions";
2
+ import { ModCallbackCustom2 } from "../../../enums/ModCallbackCustom2";
3
+ import { getSlots } from "../../../functions/entitiesSpecific";
4
+ import { PostSlotInit } from "../../callbacks/PostSlotInit";
5
+ import { PostSlotUpdate } from "../../callbacks/PostSlotUpdate";
6
+ import { Feature } from "../../private/Feature";
7
+
8
+ export class SlotUpdateDetection extends Feature {
9
+ public override v = {
10
+ room: {
11
+ initializedSlots: new Set<PtrHash>(),
12
+ },
13
+ };
14
+
15
+ private postSlotInit: PostSlotInit;
16
+ private postSlotUpdate: PostSlotUpdate;
17
+
18
+ constructor(postSlotInit: PostSlotInit, postSlotUpdate: PostSlotUpdate) {
19
+ super();
20
+
21
+ this.callbacksUsed = [
22
+ [ModCallback.POST_UPDATE, [this.postUpdate]], // 1
23
+ ];
24
+
25
+ this.customCallbacksUsed = [
26
+ // This has to be the reordered callback because we don't want the `POST_SLOT_INIT` callback
27
+ // firing on the first room of a floor before the `POST_NEW_LEVEL` callback.
28
+ [ModCallbackCustom2.POST_NEW_ROOM_REORDERED, [this.postNewRoomReordered]],
29
+ ];
30
+
31
+ this.postSlotInit = postSlotInit;
32
+ this.postSlotUpdate = postSlotUpdate;
33
+ }
34
+
35
+ // ModCallback.POST_UPDATE (1)
36
+ private postUpdate = () => {
37
+ for (const slot of getSlots()) {
38
+ this.checkNewEntity(slot);
39
+ this.postSlotUpdate.fire(slot);
40
+ }
41
+ };
42
+
43
+ // ModCallbackCustom.POST_NEW_ROOM_REORDERED
44
+ private postNewRoomReordered = () => {
45
+ for (const slot of getSlots()) {
46
+ this.checkNewEntity(slot);
47
+ }
48
+ };
49
+
50
+ private checkNewEntity(slot: EntitySlot) {
51
+ const ptrHash = GetPtrHash(slot);
52
+ if (!this.v.room.initializedSlots.has(ptrHash)) {
53
+ this.v.room.initializedSlots.add(ptrHash);
54
+ this.postSlotInit.fire(slot);
55
+ }
56
+ }
57
+ }
@@ -1,5 +1,6 @@
1
1
  import { ModCallback } from "isaac-typescript-definitions";
2
2
  import { game } from "../../../core/cachedClasses";
3
+ import { Exported } from "../../../decorators";
3
4
  import { arrayRemoveInPlace } from "../../../functions/array";
4
5
  import { Feature } from "../../private/Feature";
5
6
 
@@ -79,6 +80,7 @@ export class RunInNFrames extends Feature {
79
80
  * before the deferred function fires would cause a bug in your mod, then you should handle
80
81
  * deferred functions manually using serializable data.
81
82
  */
83
+ @Exported
82
84
  public runInNGameFrames(func: () => void, gameFrames: int): void {
83
85
  const gameFrameCount = game.GetFrameCount();
84
86
  const functionFireFrame = gameFrameCount + gameFrames;
@@ -96,6 +98,7 @@ export class RunInNFrames extends Feature {
96
98
  * before the deferred function fires would cause a bug in your mod, then you should handle
97
99
  * deferred functions manually using serializable data.
98
100
  */
101
+ @Exported
99
102
  public runInNRenderFrames(func: () => void, renderFrames: int): void {
100
103
  const renderFrameCount = Isaac.GetFrameCount();
101
104
  const functionFireFrame = renderFrameCount + renderFrames;
@@ -131,6 +134,7 @@ export class RunInNFrames extends Feature {
131
134
  * before the deferred function fires would cause a bug in your mod, then you should handle
132
135
  * deferred functions manually using serializable data.
133
136
  */
137
+ @Exported
134
138
  public runNextGameFrame(func: () => void): void {
135
139
  this.runInNGameFrames(func, 1);
136
140
  }
@@ -143,6 +147,7 @@ export class RunInNFrames extends Feature {
143
147
  *
144
148
  * Note that this function will not handle saving and quitting.
145
149
  */
150
+ @Exported
146
151
  public runNextRenderFrame(func: () => void): void {
147
152
  this.runInNRenderFrames(func, 1);
148
153
  }
@@ -163,6 +168,7 @@ export class RunInNFrames extends Feature {
163
168
  * @param runImmediately Whether or not to execute the function right now before waiting for the
164
169
  * interval.
165
170
  */
171
+ @Exported
166
172
  public setIntervalGameFrames(
167
173
  func: () => boolean,
168
174
  gameFrames: int,
@@ -194,6 +200,7 @@ export class RunInNFrames extends Feature {
194
200
  * @param runImmediately Whether or not to execute the function right now before waiting for the
195
201
  * interval.
196
202
  */
203
+ @Exported
197
204
  public setIntervalRenderFrames(
198
205
  func: () => boolean,
199
206
  renderFrames: int,
@@ -0,0 +1,492 @@
1
+ import { CollectibleType, ModCallback } from "isaac-typescript-definitions";
2
+ import { game } from "../../../core/cachedClasses";
3
+ import { Exported } from "../../../decorators";
4
+ import { SaveDataKey } from "../../../enums/SaveDataKey";
5
+ import { SerializationType } from "../../../enums/SerializationType";
6
+ import { deepCopy } from "../../../functions/deepCopy";
7
+ import { onFirstFloor } from "../../../functions/stage";
8
+ import { getTSTLClassName } from "../../../functions/tstlClass";
9
+ import { isString, isTable } from "../../../functions/types";
10
+ import { SaveData } from "../../../interfaces/SaveData";
11
+ import { AnyClass } from "../../../types/AnyClass";
12
+ import { Feature } from "../../private/Feature";
13
+ import {
14
+ makeGlowingHourGlassBackup,
15
+ restoreGlowingHourGlassBackup,
16
+ } from "./saveDataManager/glowingHourGlass";
17
+ import { loadFromDisk } from "./saveDataManager/loadFromDisk";
18
+ import {
19
+ restoreDefaultForFeatureKey,
20
+ restoreDefaultsForAllFeaturesAndKeys,
21
+ restoreDefaultsForAllFeaturesKey,
22
+ } from "./saveDataManager/restoreDefaults";
23
+ import { saveToDisk } from "./saveDataManager/saveToDisk";
24
+
25
+ /** "g" stands for "globals". */
26
+ declare let g: LuaMap<string, SaveData>; // eslint-disable-line @typescript-eslint/no-unused-vars
27
+
28
+ const NON_USER_DEFINED_CLASS_NAMES: ReadonlySet<string> = new Set([
29
+ "Map",
30
+ "Set",
31
+ "DefaultMap",
32
+ ]);
33
+
34
+ export class SaveDataManager extends Feature {
35
+ /**
36
+ * We store a local reference to the mod object so that we can access the corresponding methods
37
+ * that read and write to the "save#.dat" file.
38
+ */
39
+ private mod: Mod;
40
+
41
+ /**
42
+ * The save data map is indexed by subscriber name. We use Lua tables instead of TypeScriptToLua
43
+ * Maps for the master map so that we can access the variables via the in-game console when
44
+ * debugging. (TSTL Maps don't expose the map keys as normal keys.)
45
+ */
46
+ private saveDataMap = new LuaMap<string, SaveData>();
47
+
48
+ /**
49
+ * When mod feature data is initialized, we copy the initial values into a separate map so that we
50
+ * can restore them later on.
51
+ */
52
+ private saveDataDefaultsMap = new LuaMap<string, SaveData>();
53
+
54
+ /**
55
+ * Each mod feature can optionally provide a function that can control whether or not the save
56
+ * data is written to disk.
57
+ */
58
+ private saveDataConditionalFuncMap = new LuaMap<string, () => boolean>();
59
+
60
+ /**
61
+ * We backup some save data keys on every new room for the purposes of restoring it when Glowing
62
+ * Hour Glass is used.
63
+ *
64
+ * Note that the save data is backed up in serialized form so that we can use the `merge` function
65
+ * to restore it.
66
+ */
67
+ private saveDataGlowingHourGlassMap = new LuaMap<string, SaveData>();
68
+
69
+ /**
70
+ * End-users can register their classes with the save data manager for proper serialization when
71
+ * contained in nested maps, sets, and arrays.
72
+ */
73
+ private classConstructors = new LuaMap<string, AnyClass>();
74
+
75
+ // Other variables
76
+ private loadedDataOnThisRun = false;
77
+ private restoreGlowingHourGlassDataOnNextRoom = false;
78
+
79
+ constructor(mod: Mod) {
80
+ super();
81
+
82
+ this.callbacksUsed = [
83
+ [
84
+ ModCallback.POST_USE_ITEM,
85
+ [this.postUseItemGlowingHourGlass, CollectibleType.GLOWING_HOUR_GLASS],
86
+ ], // 3
87
+ [ModCallback.POST_PLAYER_INIT, [this.postPlayerInit]], // 9
88
+ [ModCallback.PRE_GAME_EXIT, [this.preGameExit]], // 17
89
+ [ModCallback.POST_NEW_LEVEL, [this.postNewLevel]], // 18
90
+ ];
91
+
92
+ this.mod = mod;
93
+ }
94
+
95
+ // ModCallback.POST_USE_ITEM (3)
96
+ // CollectibleType.GLOWING_HOUR_GLASS (422)
97
+ private postUseItemGlowingHourGlass = (): boolean | undefined => {
98
+ this.restoreGlowingHourGlassDataOnNextRoom = true;
99
+ return undefined;
100
+ };
101
+
102
+ // ModCallback.POST_PLAYER_INIT (9)
103
+
104
+ private postPlayerInit = (): void => {
105
+ // We want to only load data once per run to handle the case of a player using Genesis, a second
106
+ // player joining the run, and so on.
107
+ if (this.loadedDataOnThisRun) {
108
+ return;
109
+ }
110
+ this.loadedDataOnThisRun = true;
111
+
112
+ // Handle the race-condition of using the Glowing Hour Glass and then resetting the run.
113
+ this.restoreGlowingHourGlassDataOnNextRoom = false;
114
+
115
+ // We want to unconditionally load save data on every new run since there might be persistent
116
+ // data that is not tied to an individual run.
117
+ loadFromDisk(this.mod, this.saveDataMap, this.classConstructors);
118
+
119
+ const gameFrameCount = game.GetFrameCount();
120
+ const isContinued = gameFrameCount !== 0;
121
+ if (!isContinued) {
122
+ restoreDefaultsForAllFeaturesAndKeys(
123
+ this.saveDataMap,
124
+ this.saveDataDefaultsMap,
125
+ );
126
+ }
127
+
128
+ // On continued runs, the `POST_NEW_LEVEL` callback will not fire, so we do not have to worry
129
+ // about saved data based on level getting overwritten.
130
+ };
131
+
132
+ // ModCallback.PRE_GAME_EXIT (17)
133
+ private preGameExit = (): void => {
134
+ // We unconditionally save variables to disk (because regardless of a save & quit or a death,
135
+ // persistent variables should be recorded).
136
+ saveToDisk(this.mod, this.saveDataMap, this.saveDataConditionalFuncMap);
137
+
138
+ restoreDefaultsForAllFeaturesAndKeys(
139
+ this.saveDataMap,
140
+ this.saveDataDefaultsMap,
141
+ );
142
+ this.loadedDataOnThisRun = false;
143
+ };
144
+
145
+ // ModCallback.POST_NEW_LEVEL (18)
146
+ private postNewLevel = (): void => {
147
+ restoreDefaultsForAllFeaturesKey(
148
+ this.saveDataMap,
149
+ this.saveDataDefaultsMap,
150
+ SaveDataKey.LEVEL,
151
+ );
152
+
153
+ // We save data to disk at the beginning of every floor (for the 2nd floor and beyond) to
154
+ // emulate what the game does internally. (This mitigates data loss in the event of a crash).
155
+ if (!onFirstFloor()) {
156
+ saveToDisk(this.mod, this.saveDataMap, this.saveDataConditionalFuncMap);
157
+ }
158
+ };
159
+
160
+ // ModCallbackCustom.POST_NEW_ROOM_EARLY
161
+ private postNewRoomEarly = (): void => {
162
+ restoreDefaultsForAllFeaturesKey(
163
+ this.saveDataMap,
164
+ this.saveDataDefaultsMap,
165
+ SaveDataKey.ROOM,
166
+ );
167
+
168
+ // Handle the Glowing Hour Glass.
169
+ if (this.restoreGlowingHourGlassDataOnNextRoom) {
170
+ this.restoreGlowingHourGlassDataOnNextRoom = false;
171
+ restoreGlowingHourGlassBackup(
172
+ this.saveDataMap,
173
+ this.saveDataConditionalFuncMap,
174
+ this.saveDataGlowingHourGlassMap,
175
+ this.classConstructors,
176
+ );
177
+ } else {
178
+ makeGlowingHourGlassBackup(
179
+ this.saveDataMap,
180
+ this.saveDataConditionalFuncMap,
181
+ this.saveDataGlowingHourGlassMap,
182
+ );
183
+ }
184
+ };
185
+
186
+ // --------------
187
+ // Public methods
188
+ // --------------
189
+
190
+ /**
191
+ * This is the entry point to the save data manager, a system which provides two major features:
192
+ *
193
+ * 1. automatic resetting of variables on a new run, on a new level, or on a new room (as desired)
194
+ * 2. automatic saving and loading of all tracked data to the "save#.dat" file
195
+ *
196
+ * You feed this function with an object containing your variables, and then it will automatically
197
+ * manage them for you. (See below for an example.)
198
+ *
199
+ * The save data manager is meant to be called once for each feature of your mod. In other words,
200
+ * you should not put all of the data for your mod on the same object. Instead, scope your
201
+ * variables locally to a single file that contains a mod feature, and then call this function to
202
+ * register them. For example:
203
+ *
204
+ * ```ts
205
+ * // In file: feature1.ts
206
+ * import { saveDataManager } from "isaacscript-common";
207
+ *
208
+ * // Declare local variables for this file or feature.
209
+ * const v = {
210
+ * // These variables are never reset; manage them yourself at will.
211
+ * persistent: {
212
+ * foo1: 0,
213
+ * },
214
+ *
215
+ * // These variables are reset at the beginning of every run.
216
+ * run: {
217
+ * foo2: 0,
218
+ * },
219
+ *
220
+ * // These variables are reset at the beginning of every level.
221
+ * level: {
222
+ * foo3: 0,
223
+ * },
224
+ *
225
+ * // These variables are reset at the beginning of every room.
226
+ * room: {
227
+ * foo4: 0,
228
+ * },
229
+ * };
230
+ * // Every child object is optional; only create the ones that you need.
231
+ *
232
+ * // Register the variables with the save data manager. (We need to provide a string key that
233
+ * // matches the name of this file.)
234
+ * function feature1Init() {
235
+ * saveDataManager("feature1", v);
236
+ * }
237
+ *
238
+ * // Elsewhere in the file, use your variables.
239
+ * function feature1Function() {
240
+ * if (v.run.foo1 > 0) {
241
+ * // Insert code here.
242
+ * }
243
+ * }
244
+ * ```
245
+ *
246
+ * - Save data is loaded from disk in the `POST_PLAYER_INIT` callback (i.e. the first callback
247
+ * that can possibly run).
248
+ * - Save data is recorded to disk in the `PRE_GAME_EXIT` callback.
249
+ *
250
+ * You can use many different variable types on your variable object, but not everything is
251
+ * supported. For the specific things that are supported, see the documentation for the `deepCopy`
252
+ * helper function.
253
+ *
254
+ * Note that before using the save data manager, you must call the `upgradeMod` function. (Upgrade
255
+ * your mod before registering any of your own callbacks so that the save data manager will run
256
+ * before any of your code does.)
257
+ *
258
+ * If you want the save data manager to load data before the `POST_PLAYER_INIT` callback (i.e. in
259
+ * the main menu), then you should explicitly call the `saveDataManagerLoad` function. (The save
260
+ * data manager cannot do this on its own because it cannot know when your mod features are
261
+ * finished initializing.)
262
+ *
263
+ * Some features may have variables that need to be automatically reset per run/level, but not
264
+ * saved to disk on game exit. (For example, if they contain functions or other non-serializable
265
+ * data.) For these cases, set the second argument to `false`.
266
+ *
267
+ * Note that when the player uses Glowing Hour Glass, the save data manager will automatically
268
+ * restore any variables on a "run" or "level" object with a backup that was created when the room
269
+ * was entered. Thus, you should not have to explicitly program support for Glowing Hour Glass
270
+ * into your mod features that use the save data manager. If this is undesired for your specific
271
+ * use-case, then add a key of `__ignoreGlowingHourGlass: true` to your "run" or "level" object.
272
+ *
273
+ * @param key The name of the file or feature that is submitting data to be managed by the save
274
+ * data manager. The save data manager will throw an error if the key is already
275
+ * registered.
276
+ * @param v An object that corresponds to the `SaveData` interface. The object is conventionally
277
+ * called "v" for brevity. ("v" is short for "local variables").
278
+ * @param conditionalFunc Optional. A function to run to check if this save data should be written
279
+ * to disk. Default is `() => true`, meaning that this save data will
280
+ * always be written to disk. Use a conditional function for the situations
281
+ * when the local variables are for a feature that the end-user can
282
+ * disable. (If the feature is disabled, then there would be no point in
283
+ * writing any of the variables to the "save#.dat" file.) You can also
284
+ * specify `false` to this argument in order to completely disable saving
285
+ * data. (Specifying `false` will allow you to use non-serializable objects
286
+ * in your save data, such as `EntityPtr`.
287
+ */
288
+ public saveDataManager<Persistent, Run, Level>(
289
+ key: string, // This is the overload for the standard case with serializable data.
290
+ v: SaveData<Persistent, Run, Level>,
291
+ conditionalFunc?: () => boolean,
292
+ ): void;
293
+ public saveDataManager(
294
+ key: string, // This is the overload for the case when saving data is disabled.
295
+ v: SaveData,
296
+ conditionalFunc: false,
297
+ ): void;
298
+ @Exported
299
+ public saveDataManager<Persistent, Run, Level>(
300
+ key: string,
301
+ v: SaveData<Persistent, Run, Level>,
302
+ conditionalFunc?: (() => boolean) | false,
303
+ ): void {
304
+ if (!isString(key)) {
305
+ error(
306
+ `The save data manager requires that keys are strings. You tried to use a key of type: ${typeof key}`,
307
+ );
308
+ }
309
+
310
+ if (this.saveDataMap.has(key)) {
311
+ error(
312
+ `The save data manager is already managing save data for a key of: ${key}`,
313
+ );
314
+ }
315
+
316
+ // First, recursively look through the new save data for any classes, so we can register them
317
+ // with the save data manager.
318
+ this.storeClassConstructorsFromObject(v as LuaMap);
319
+
320
+ // Add the new save data to the map.
321
+ this.saveDataMap.set(key, v);
322
+
323
+ // Convert the boolean to a function, if necessary. (Having the argument be a boolean is
324
+ // necessary in order for the overloads to work properly.)
325
+ if (conditionalFunc === false) {
326
+ conditionalFunc = () => false;
327
+ }
328
+
329
+ // If the only key in the save data is "room", then we don't have to worry about saving this
330
+ // data to disk (because the room would be reloaded upon resuming a continued run).
331
+ const saveDataKeys = Object.keys(v);
332
+ if (saveDataKeys.length === 1 && saveDataKeys[0] === "room") {
333
+ conditionalFunc = () => false;
334
+ }
335
+
336
+ // Make a copy of the initial save data so that we can use it to restore the default values
337
+ // later on.
338
+ const saveDataCopy = deepCopy(v, SerializationType.NONE, key);
339
+ this.saveDataDefaultsMap.set(key, saveDataCopy);
340
+
341
+ // Store the conditional function for later, if present.
342
+ if (conditionalFunc !== undefined) {
343
+ this.saveDataConditionalFuncMap.set(key, conditionalFunc);
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Recursively traverses an object, collecting all of the class constructors that it encounters.
349
+ */
350
+ private storeClassConstructorsFromObject(luaMap: LuaMap<AnyNotNil, unknown>) {
351
+ const tstlClassName = getTSTLClassName(luaMap);
352
+ if (
353
+ tstlClassName !== undefined &&
354
+ !NON_USER_DEFINED_CLASS_NAMES.has(tstlClassName)
355
+ ) {
356
+ this.classConstructors.set(tstlClassName, luaMap as unknown as AnyClass);
357
+ }
358
+
359
+ for (const [_key, value] of luaMap) {
360
+ if (isTable(value)) {
361
+ this.storeClassConstructorsFromObject(value);
362
+ }
363
+ }
364
+ }
365
+
366
+ /**
367
+ * The save data manager will automatically load variables from disk at the appropriate times
368
+ * (i.e. when a new run is started). Use this function to explicitly force the save data manager
369
+ * to load all of its variables from disk immediately.
370
+ *
371
+ * Obviously, doing this will overwrite the current data, so using this function can potentially
372
+ * result in lost state.
373
+ */
374
+ @Exported
375
+ public saveDataManagerLoad(): void {
376
+ loadFromDisk(this.mod, this.saveDataMap, this.classConstructors);
377
+ }
378
+
379
+ /**
380
+ * The save data manager will automatically save variables to disk at the appropriate times (i.e.
381
+ * when the run is exited). Use this function to explicitly force the save data manager to write
382
+ * all of its variables to disk immediately.
383
+ */
384
+ @Exported
385
+ public saveDataManagerSave(): void {
386
+ saveToDisk(this.mod, this.saveDataMap, this.saveDataConditionalFuncMap);
387
+ }
388
+
389
+ /**
390
+ * Sets the global variable of "g" equal to all of the save data variables for this mod.
391
+ *
392
+ * This can make debugging easier, as you can access the variables from the game's debug console.
393
+ * e.g. `l print(g.feature1.run.foo)`
394
+ */
395
+ @Exported
396
+ public saveDataManagerSetGlobal(): void {
397
+ g = this.saveDataMap;
398
+ }
399
+
400
+ /**
401
+ * By default, the save data manager will not be able to serialize/deserialize classes that are
402
+ * nested inside of maps, sets, and arrays, because it does not have access to the corresponding
403
+ * class constructor. If you want to use nested classes in this way, then use this function to
404
+ * register the class constructor with the save data manager. Once registered, the save data
405
+ * manager will automatically run the constructor when deserializing (in addition to copying over
406
+ * the data fields).
407
+ *
408
+ * This function is variadic, which means you can pass as many classes as you want to register.
409
+ */
410
+ @Exported
411
+ public saveDataManagerRegisterClass(...tstlClasses: AnyClass[]): void {
412
+ for (const tstlClass of tstlClasses) {
413
+ const { name } = tstlClass;
414
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
415
+ if (name === undefined) {
416
+ error(
417
+ "Failed to register a class with the save data manager due to not being able to derive the name of the class.",
418
+ );
419
+ }
420
+
421
+ this.classConstructors.set(name, tstlClass);
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Removes a previously registered key from the save data manager. This is the opposite of the
427
+ * "saveDataManager" method.
428
+ */
429
+ @Exported
430
+ public saveDataManagerRemove(key: string): void {
431
+ if (!isString(key)) {
432
+ error(
433
+ `The save data manager requires that keys are strings. You tried to use a key of type: ${typeof key}`,
434
+ );
435
+ }
436
+
437
+ if (!this.saveDataMap.has(key)) {
438
+ error(
439
+ `The save data manager is not managing save data for a key of: ${key}`,
440
+ );
441
+ }
442
+
443
+ // Delete the save data from the map.
444
+ this.saveDataMap.delete(key);
445
+ this.saveDataDefaultsMap.delete(key);
446
+ this.saveDataConditionalFuncMap.delete(key);
447
+ this.saveDataGlowingHourGlassMap.delete(key);
448
+ }
449
+
450
+ /**
451
+ * The save data manager will automatically reset variables at the appropriate times, like when a
452
+ * player enters a new room. Use this function to explicitly force the save data manager to reset
453
+ * a specific variable group.
454
+ *
455
+ * For example:
456
+ *
457
+ * ```ts
458
+ * const v = {
459
+ * room: {
460
+ * foo: 123,
461
+ * },
462
+ * };
463
+ *
464
+ * mod.saveDataManager("file1", v);
465
+ *
466
+ * // Then, later on, to explicit reset all of the "room" variables:
467
+ * mod.saveDataManagerReset("file1", "room");
468
+ * ```
469
+ */
470
+ @Exported
471
+ public saveDataManagerReset(key: string, childObjectKey: SaveDataKey): void {
472
+ if (!isString(key)) {
473
+ error(
474
+ `The save data manager requires that keys are strings. You tried to use a key of type: ${typeof key}`,
475
+ );
476
+ }
477
+
478
+ const saveData = this.saveDataMap.get(key);
479
+ if (saveData === undefined) {
480
+ error(
481
+ `The save data manager is not managing save data for a key of: ${key}`,
482
+ );
483
+ }
484
+
485
+ restoreDefaultForFeatureKey(
486
+ this.saveDataDefaultsMap,
487
+ key,
488
+ saveData,
489
+ childObjectKey,
490
+ );
491
+ }
492
+ }