isaacscript-common 6.10.2 → 6.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/callbacks/postFlip.lua +2 -2
  2. package/dist/callbacks/postPlayerFatalDamage.lua +1 -1
  3. package/dist/callbacks/postPlayerInitFirst.d.ts +2 -0
  4. package/dist/callbacks/postPlayerInitFirst.d.ts.map +1 -0
  5. package/dist/callbacks/postPlayerInitFirst.lua +42 -0
  6. package/dist/callbacks/postPlayerInitLate.lua +5 -5
  7. package/dist/callbacks/postPlayerReorderedCallbacks.d.ts +2 -0
  8. package/dist/callbacks/postPlayerReorderedCallbacks.d.ts.map +1 -0
  9. package/dist/callbacks/{postPlayerReordered.lua → postPlayerReorderedCallbacks.lua} +11 -37
  10. package/dist/callbacks/subscriptions/postFirstFlip.d.ts +1 -1
  11. package/dist/callbacks/subscriptions/postFirstFlip.d.ts.map +1 -1
  12. package/dist/callbacks/subscriptions/postFirstFlip.lua +2 -2
  13. package/dist/callbacks/subscriptions/postFlip.d.ts +1 -1
  14. package/dist/callbacks/subscriptions/postFlip.d.ts.map +1 -1
  15. package/dist/callbacks/subscriptions/postFlip.lua +2 -2
  16. package/dist/callbacks/subscriptions/{postPlayerInitReordered.d.ts → postPlayerInitFirst.d.ts} +2 -2
  17. package/dist/callbacks/subscriptions/postPlayerInitFirst.d.ts.map +1 -0
  18. package/dist/callbacks/subscriptions/{postPlayerInitReordered.lua → postPlayerInitFirst.lua} +3 -3
  19. package/dist/enums/ModCallbackCustom.d.ts +19 -17
  20. package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
  21. package/dist/enums/ModCallbackCustom.lua +3 -3
  22. package/dist/enums/private/StageTravelState.d.ts +9 -0
  23. package/dist/enums/private/StageTravelState.d.ts.map +1 -0
  24. package/dist/enums/private/StageTravelState.lua +15 -0
  25. package/dist/enums/private/TrapdoorAnimation.d.ts +6 -0
  26. package/dist/enums/private/TrapdoorAnimation.d.ts.map +1 -0
  27. package/dist/enums/private/TrapdoorAnimation.lua +6 -0
  28. package/dist/features/customGridEntity.d.ts +8 -5
  29. package/dist/features/customGridEntity.d.ts.map +1 -1
  30. package/dist/features/customGridEntity.lua +66 -17
  31. package/dist/features/customStage/exports.d.ts.map +1 -1
  32. package/dist/features/customStage/exports.lua +0 -13
  33. package/dist/features/customStage/init.d.ts.map +1 -1
  34. package/dist/features/customStage/init.lua +24 -2
  35. package/dist/features/customStage/streakText.d.ts +6 -0
  36. package/dist/features/customStage/streakText.d.ts.map +1 -1
  37. package/dist/features/customStage/streakText.lua +16 -12
  38. package/dist/features/customStage/versusScreen.d.ts +6 -0
  39. package/dist/features/customStage/versusScreen.d.ts.map +1 -1
  40. package/dist/features/customStage/versusScreen.lua +10 -5
  41. package/dist/features/customTrapdoor/blackSprite.d.ts +2 -0
  42. package/dist/features/customTrapdoor/blackSprite.d.ts.map +1 -0
  43. package/dist/features/customTrapdoor/blackSprite.lua +19 -0
  44. package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts +15 -0
  45. package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts.map +1 -0
  46. package/dist/features/customTrapdoor/customTrapdoorConstants.lua +16 -0
  47. package/dist/features/customTrapdoor/exports.d.ts +29 -0
  48. package/dist/features/customTrapdoor/exports.d.ts.map +1 -0
  49. package/dist/features/customTrapdoor/exports.lua +93 -0
  50. package/dist/features/customTrapdoor/init.d.ts +3 -0
  51. package/dist/features/customTrapdoor/init.d.ts.map +1 -0
  52. package/dist/features/customTrapdoor/init.lua +173 -0
  53. package/dist/features/customTrapdoor/openClose.d.ts +5 -0
  54. package/dist/features/customTrapdoor/openClose.d.ts.map +1 -0
  55. package/dist/features/customTrapdoor/openClose.lua +60 -0
  56. package/dist/features/customTrapdoor/touched.d.ts +4 -0
  57. package/dist/features/customTrapdoor/touched.d.ts.map +1 -0
  58. package/dist/features/customTrapdoor/touched.lua +141 -0
  59. package/dist/features/customTrapdoor/v.d.ts +18 -0
  60. package/dist/features/customTrapdoor/v.d.ts.map +1 -0
  61. package/dist/features/customTrapdoor/v.lua +17 -0
  62. package/dist/features/deployJSONRoom.d.ts.map +1 -1
  63. package/dist/features/deployJSONRoom.lua +1 -1
  64. package/dist/features/extraConsoleCommands/init.d.ts.map +1 -1
  65. package/dist/features/extraConsoleCommands/init.lua +3 -1
  66. package/dist/features/extraConsoleCommands/listCommands.lua +2 -2
  67. package/dist/features/taintedLazarusPlayers.d.ts.map +1 -1
  68. package/dist/features/taintedLazarusPlayers.lua +13 -21
  69. package/dist/functions/{character.d.ts → characters.d.ts} +3 -1
  70. package/dist/functions/characters.d.ts.map +1 -0
  71. package/dist/functions/{character.lua → characters.lua} +12 -0
  72. package/dist/functions/deepCopyTests.lua +35 -45
  73. package/dist/functions/jsonHelpers.d.ts +6 -0
  74. package/dist/functions/jsonHelpers.d.ts.map +1 -1
  75. package/dist/functions/jsonHelpers.lua +9 -3
  76. package/dist/functions/log.lua +3 -3
  77. package/dist/functions/playerIndex.d.ts +11 -2
  78. package/dist/functions/playerIndex.d.ts.map +1 -1
  79. package/dist/functions/playerIndex.lua +20 -8
  80. package/dist/functions/players.lua +4 -4
  81. package/dist/functions/revive.lua +2 -2
  82. package/dist/functions/table.d.ts +1 -1
  83. package/dist/functions/table.d.ts.map +1 -1
  84. package/dist/index.d.ts +3 -2
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.lua +10 -2
  87. package/dist/initCustomCallbacks.d.ts.map +1 -1
  88. package/dist/initCustomCallbacks.lua +5 -2
  89. package/dist/initFeatures.d.ts +1 -2
  90. package/dist/initFeatures.d.ts.map +1 -1
  91. package/dist/initFeatures.lua +10 -2
  92. package/dist/interfaces/AddCallbackParameterCustom.d.ts +2 -2
  93. package/dist/interfaces/AddCallbackParameterCustom.d.ts.map +1 -1
  94. package/dist/interfaces/CustomGridEntityData.d.ts +6 -2
  95. package/dist/interfaces/CustomGridEntityData.d.ts.map +1 -1
  96. package/dist/interfaces/private/CustomTrapdoorDescription.d.ts +7 -0
  97. package/dist/interfaces/private/CustomTrapdoorDescription.d.ts.map +1 -0
  98. package/dist/interfaces/private/CustomTrapdoorDescription.lua +2 -0
  99. package/dist/lib/jsonLua.lua +390 -0
  100. package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
  101. package/dist/objects/callbackRegisterFunctions.lua +3 -3
  102. package/dist/objects/characterDamageMultipliers.d.ts +6 -0
  103. package/dist/objects/characterDamageMultipliers.d.ts.map +1 -0
  104. package/dist/objects/characterDamageMultipliers.lua +49 -0
  105. package/dist/upgradeMod.d.ts.map +1 -1
  106. package/dist/upgradeMod.lua +2 -4
  107. package/package.json +2 -2
  108. package/src/callbacks/customRevive.ts +3 -3
  109. package/src/callbacks/itemPickup.ts +3 -3
  110. package/src/callbacks/postAmbush.ts +3 -3
  111. package/src/callbacks/postEsauJr.ts +3 -3
  112. package/src/callbacks/postFlip.ts +6 -5
  113. package/src/callbacks/postGridEntity.ts +5 -5
  114. package/src/callbacks/postPlayerCollectible.ts +2 -2
  115. package/src/callbacks/postPlayerFatalDamage.ts +5 -0
  116. package/src/callbacks/postPlayerInitFirst.ts +57 -0
  117. package/src/callbacks/postPlayerInitLate.ts +9 -5
  118. package/src/callbacks/{postPlayerReordered.ts → postPlayerReorderedCallbacks.ts} +9 -29
  119. package/src/callbacks/postSlotInitUpdate.ts +5 -2
  120. package/src/callbacks/postSlotRender.ts +2 -2
  121. package/src/callbacks/reorderedCallbacks.ts +1 -1
  122. package/src/callbacks/subscriptions/postFirstFlip.ts +6 -3
  123. package/src/callbacks/subscriptions/postFlip.ts +6 -3
  124. package/src/callbacks/subscriptions/{postPlayerInitReordered.ts → postPlayerInitFirst.ts} +6 -6
  125. package/src/enums/ModCallbackCustom.ts +19 -17
  126. package/src/enums/private/StageTravelState.ts +8 -0
  127. package/src/enums/private/TrapdoorAnimation.ts +5 -0
  128. package/src/features/customGridEntity.ts +93 -12
  129. package/src/features/customStage/exports.ts +3 -22
  130. package/src/features/customStage/init.ts +30 -1
  131. package/src/features/customStage/streakText.ts +13 -5
  132. package/src/features/customStage/versusScreen.ts +20 -12
  133. package/src/features/customTrapdoor/blackSprite.ts +16 -0
  134. package/src/features/customTrapdoor/customTrapdoorConstants.ts +23 -0
  135. package/src/features/customTrapdoor/exports.ts +99 -0
  136. package/src/features/customTrapdoor/init.ts +215 -0
  137. package/src/features/customTrapdoor/openClose.ts +103 -0
  138. package/src/features/customTrapdoor/touched.ts +175 -0
  139. package/src/features/customTrapdoor/v.ts +26 -0
  140. package/src/features/deployJSONRoom.ts +6 -1
  141. package/src/features/extraConsoleCommands/init.ts +5 -2
  142. package/src/features/extraConsoleCommands/listCommands.ts +1 -1
  143. package/src/features/saveDataManager/main.ts +1 -1
  144. package/src/features/taintedLazarusPlayers.ts +32 -31
  145. package/src/functions/{character.ts → characters.ts} +13 -0
  146. package/src/functions/deepCopy.ts +2 -2
  147. package/src/functions/deepCopyTests.ts +44 -48
  148. package/src/functions/entities.ts +1 -1
  149. package/src/functions/jsonHelpers.ts +9 -3
  150. package/src/functions/playerIndex.ts +18 -2
  151. package/src/functions/players.ts +1 -1
  152. package/src/functions/revive.ts +1 -1
  153. package/src/functions/rng.ts +1 -1
  154. package/src/functions/table.ts +2 -2
  155. package/src/index.ts +6 -2
  156. package/src/initCustomCallbacks.ts +3 -1
  157. package/src/initFeatures.ts +9 -2
  158. package/src/interfaces/AddCallbackParameterCustom.ts +2 -2
  159. package/src/interfaces/CustomGridEntityData.ts +7 -2
  160. package/src/interfaces/private/CustomTrapdoorDescription.ts +7 -0
  161. package/src/lib/jsonLua.d.ts +10 -0
  162. package/src/lib/jsonLua.lua +390 -0
  163. package/src/objects/callbackRegisterFunctions.ts +2 -3
  164. package/src/objects/characterDamageMultipliers.ts +49 -0
  165. package/src/upgradeMod.ts +2 -3
  166. package/dist/callbacks/postPlayerReordered.d.ts +0 -2
  167. package/dist/callbacks/postPlayerReordered.d.ts.map +0 -1
  168. package/dist/callbacks/subscriptions/postPlayerInitReordered.d.ts.map +0 -1
  169. package/dist/functions/character.d.ts.map +0 -1
@@ -28,6 +28,22 @@ export function getAllPlayers(): EntityPlayer[] {
28
28
  return players;
29
29
  }
30
30
 
31
+ /**
32
+ * Helper function to get all of the other players in the room besides the one provided. (This
33
+ * includes "child" players.)
34
+ */
35
+ export function getOtherPlayers(player: EntityPlayer): EntityPlayer[] {
36
+ const playerPtrHash = GetPtrHash(player);
37
+ const players = getAllPlayers();
38
+ return players.filter(
39
+ (otherPlayer) => GetPtrHash(otherPlayer) !== playerPtrHash,
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Helper function to get the corresponding `EntityPlayer` object that corresponds to a
45
+ * `PlayerIndex`.
46
+ */
31
47
  export function getPlayerFromIndex(
32
48
  playerIndex: PlayerIndex,
33
49
  ): EntityPlayer | undefined {
@@ -194,8 +210,8 @@ export function getSubPlayerParent(
194
210
  }
195
211
 
196
212
  /**
197
- * Some players are "child" players, meaning that they have a non-undefined Parent property. (For
198
- * example, the Strawman Keeper.)
213
+ * Helper function to detect if a particular player is a "child" player, meaning that they have a
214
+ * non-undefined `EntityPlayer.Parent` property. (For example, the Strawman Keeper.)
199
215
  */
200
216
  export function isChildPlayer(player: EntityPlayer): boolean {
201
217
  return player.Parent !== undefined;
@@ -17,7 +17,7 @@ import {
17
17
  getCharacterMaxHeartContainers,
18
18
  getCharacterName,
19
19
  isVanillaCharacter,
20
- } from "./character";
20
+ } from "./characters";
21
21
  import { getCollectibleMaxCharges } from "./collectibles";
22
22
  import { getCollectibleArray } from "./collectibleSet";
23
23
  import { getEnumValues } from "./enums";
@@ -10,7 +10,7 @@ import {
10
10
  MAX_TAINTED_SAMSON_BERSERK_CHARGE,
11
11
  TAINTED_SAMSON_BERSERK_CHARGE_FROM_TAKING_DAMAGE,
12
12
  } from "../constants";
13
- import { getCharacterDeathAnimationName } from "./character";
13
+ import { getCharacterDeathAnimationName } from "./characters";
14
14
  import {
15
15
  getPlayerMaxHeartContainers,
16
16
  getPlayerNumHitsRemaining,
@@ -142,7 +142,7 @@ export function setAllRNGToSeed(object: unknown, seed: Seed): void {
142
142
  }
143
143
 
144
144
  let setAtLeastOneSeed = false;
145
- for (const [_key, value] of pairs(object)) {
145
+ for (const [_key, value] of object) {
146
146
  if (isRNG(value)) {
147
147
  setSeed(value, seed);
148
148
  setAtLeastOneSeed = true;
@@ -4,8 +4,8 @@ import { isBoolean, isNumber, isString } from "./types";
4
4
  * In a `Map`, you can use the `clear` method to delete every element. However, in a `LuaMap`, the
5
5
  * `clear` method does not exist. Use this helper function as a drop-in replacement for this.
6
6
  */
7
- export function clearTable(luaMap: LuaMap): void {
8
- for (const [key] of pairs(luaMap)) {
7
+ export function clearTable(luaMap: LuaMap<AnyNotNil, unknown>): void {
8
+ for (const [key] of luaMap) {
9
9
  luaMap.delete(key);
10
10
  }
11
11
  }
package/src/index.ts CHANGED
@@ -22,8 +22,12 @@ export {
22
22
  } from "./features/characterHealthConversion";
23
23
  export { registerCharacterStats } from "./features/characterStats";
24
24
  export { getCollectibleItemPoolType } from "./features/collectibleItemPoolType";
25
- export { removeCustomGrid, spawnCustomGrid } from "./features/customGridEntity";
25
+ export {
26
+ removeCustomGrid,
27
+ spawnCustomGridEntity as spawnCustomGrid,
28
+ } from "./features/customGridEntity";
26
29
  export * from "./features/customStage/exports";
30
+ export * from "./features/customTrapdoor/exports";
27
31
  export * from "./features/debugDisplay/exports";
28
32
  export {
29
33
  deployJSONRoom,
@@ -82,7 +86,7 @@ export * from "./functions/bosses";
82
86
  export * from "./functions/cacheFlag";
83
87
  export * from "./functions/cards";
84
88
  export * from "./functions/challenges";
85
- export * from "./functions/character";
89
+ export * from "./functions/characters";
86
90
  export * from "./functions/charge";
87
91
  export * from "./functions/chargeBar";
88
92
  export * from "./functions/collectibleCacheFlag";
@@ -37,8 +37,9 @@ import { postPlayerChangeHealthInit } from "./callbacks/postPlayerChangeHealth";
37
37
  import { postPlayerChangeTypeInit } from "./callbacks/postPlayerChangeType";
38
38
  import { postPlayerCollectibleCallbacksInit } from "./callbacks/postPlayerCollectible";
39
39
  import { postPlayerFatalDamageInit } from "./callbacks/postPlayerFatalDamage";
40
+ import { postPlayerInitFirstInit } from "./callbacks/postPlayerInitFirst";
40
41
  import { postPlayerInitLateInit } from "./callbacks/postPlayerInitLate";
41
- import { postPlayerReorderedCallbacksInit } from "./callbacks/postPlayerReordered";
42
+ import { postPlayerReorderedCallbacksInit } from "./callbacks/postPlayerReorderedCallbacks";
42
43
  import { postPoopRenderInit } from "./callbacks/postPoopRender";
43
44
  import { postPoopUpdateInit } from "./callbacks/postPoopUpdate";
44
45
  import { postPressurePlateRenderInit } from "./callbacks/postPressurePlateRender";
@@ -105,6 +106,7 @@ export function initCustomCallbacks(mod: ModUpgraded): void {
105
106
  postPlayerChangeTypeInit(mod);
106
107
  postPlayerCollectibleCallbacksInit(mod);
107
108
  postPlayerFatalDamageInit(mod);
109
+ postPlayerInitFirstInit(mod);
108
110
  postPlayerInitLateInit(mod);
109
111
  postPlayerReorderedCallbacksInit(mod);
110
112
  postPoopRenderInit(mod);
@@ -4,6 +4,7 @@ import { characterStatsInit } from "./features/characterStats";
4
4
  import { collectibleItemPoolTypeInit } from "./features/collectibleItemPoolType";
5
5
  import { customGridEntityInit } from "./features/customGridEntity";
6
6
  import { customStageInit } from "./features/customStage/init";
7
+ import { customTrapdoorInit } from "./features/customTrapdoor/init";
7
8
  import { deployJSONRoomInit } from "./features/deployJSONRoom";
8
9
  import { disableAllSoundInit } from "./features/disableAllSound";
9
10
  import { disableInputsInit } from "./features/disableInputs";
@@ -23,7 +24,12 @@ import { sirenHelpersInit } from "./features/sirenHelpers";
23
24
  import { stageHistoryInit } from "./features/stageHistory";
24
25
  import { taintedLazarusPlayersInit } from "./features/taintedLazarusPlayers";
25
26
 
26
- export function initFeaturesMajor(mod: ModUpgraded): void {
27
+ export function initFeatures(mod: ModUpgraded): void {
28
+ initFeaturesMajor(mod);
29
+ initFeaturesMinor(mod);
30
+ }
31
+
32
+ function initFeaturesMajor(mod: ModUpgraded) {
27
33
  customStageInit(mod);
28
34
  deployJSONRoomInit(mod);
29
35
  runInNFramesInit(mod);
@@ -32,7 +38,8 @@ export function initFeaturesMajor(mod: ModUpgraded): void {
32
38
  customGridEntityInit(mod);
33
39
  }
34
40
 
35
- export function initFeaturesMinor(mod: ModUpgraded): void {
41
+ function initFeaturesMinor(mod: ModUpgraded) {
42
+ customTrapdoorInit(mod);
36
43
  disableAllSoundInit(mod);
37
44
  disableInputsInit(mod);
38
45
  fadeInRemoverInit(mod);
@@ -50,8 +50,8 @@ import { PostPlayerChangeTypeRegisterParameters } from "../callbacks/subscriptio
50
50
  import { PostPlayerCollectibleAddedRegisterParameters } from "../callbacks/subscriptions/postPlayerCollectibleAdded";
51
51
  import { PostPlayerCollectibleRemovedRegisterParameters } from "../callbacks/subscriptions/postPlayerCollectibleRemoved";
52
52
  import { PostPlayerFatalDamageRegisterParameters } from "../callbacks/subscriptions/postPlayerFatalDamage";
53
+ import { PostPlayerInitFirstRegisterParameters } from "../callbacks/subscriptions/postPlayerInitFirst";
53
54
  import { PostPlayerInitLateRegisterParameters } from "../callbacks/subscriptions/postPlayerInitLate";
54
- import { PostPlayerInitReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerInitReordered";
55
55
  import { PostPlayerRenderReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerRenderReordered";
56
56
  import { PostPlayerUpdateReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerUpdateReordered";
57
57
  import { PostPoopRenderRegisterParameters } from "../callbacks/subscriptions/postPoopRender";
@@ -136,8 +136,8 @@ export interface AddCallbackParameterCustom {
136
136
  [ModCallbackCustom.POST_PLAYER_COLLECTIBLE_ADDED]: PostPlayerCollectibleAddedRegisterParameters;
137
137
  [ModCallbackCustom.POST_PLAYER_COLLECTIBLE_REMOVED]: PostPlayerCollectibleRemovedRegisterParameters;
138
138
  [ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE]: PostPlayerFatalDamageRegisterParameters;
139
+ [ModCallbackCustom.POST_PLAYER_INIT_FIRST]: PostPlayerInitFirstRegisterParameters;
139
140
  [ModCallbackCustom.POST_PLAYER_INIT_LATE]: PostPlayerInitLateRegisterParameters;
140
- [ModCallbackCustom.POST_PLAYER_INIT_REORDERED]: PostPlayerInitReorderedRegisterParameters;
141
141
  [ModCallbackCustom.POST_PLAYER_RENDER_REORDERED]: PostPlayerRenderReorderedRegisterParameters;
142
142
  [ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED]: PostPlayerUpdateReorderedRegisterParameters;
143
143
  [ModCallbackCustom.POST_POOP_RENDER]: PostPoopRenderRegisterParameters;
@@ -4,10 +4,15 @@ import {
4
4
  } from "isaac-typescript-definitions";
5
5
 
6
6
  export interface CustomGridEntityData {
7
+ /**
8
+ * This is not a real `GridEntityType`; rather it is an arbitrary integer selected by end-user
9
+ * mods.
10
+ */
7
11
  gridEntityTypeCustom: GridEntityType;
12
+
8
13
  roomListIndex: int;
9
14
  gridIndex: int;
10
- anm2: string;
11
- defaultAnimation: string;
15
+ anm2Path: string;
16
+ defaultAnimation?: string;
12
17
  gridCollisionClass: GridCollisionClass;
13
18
  }
@@ -0,0 +1,7 @@
1
+ import { LevelStage, StageType } from "isaac-typescript-definitions";
2
+
3
+ export interface CustomTrapdoorDescription {
4
+ open: boolean;
5
+ destination: [stage: LevelStage, stageType: StageType] | string;
6
+ firstSpawn: boolean;
7
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This is the custom JSON parser library called "json.lua". It is located at:
3
+ * https://github.com/rxi/json.lua
4
+ *
5
+ * This parser was measured to be 11.8 times faster than the vanilla parser at decoding a sample
6
+ * "save1.dat" file.
7
+ */
8
+
9
+ export function encode(this: void, data: unknown): string;
10
+ export function decode(this: void, data: string): unknown;
@@ -0,0 +1,390 @@
1
+ -- cspell:disable
2
+
3
+ --
4
+ -- json.lua
5
+ --
6
+ -- Copyright (c) 2020 rxi
7
+ --
8
+ -- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ -- this software and associated documentation files (the "Software"), to deal in
10
+ -- the Software without restriction, including without limitation the rights to
11
+ -- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ -- of the Software, and to permit persons to whom the Software is furnished to do
13
+ -- so, subject to the following conditions:
14
+ --
15
+ -- The above copyright notice and this permission notice shall be included in all
16
+ -- copies or substantial portions of the Software.
17
+ --
18
+ -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ -- SOFTWARE.
25
+ --
26
+
27
+ local json = { _version = "0.1.2" }
28
+
29
+ -------------------------------------------------------------------------------
30
+ -- Encode
31
+ -------------------------------------------------------------------------------
32
+
33
+ local encode
34
+
35
+ local escape_char_map = {
36
+ [ "\\" ] = "\\",
37
+ [ "\"" ] = "\"",
38
+ [ "\b" ] = "b",
39
+ [ "\f" ] = "f",
40
+ [ "\n" ] = "n",
41
+ [ "\r" ] = "r",
42
+ [ "\t" ] = "t",
43
+ }
44
+
45
+ local escape_char_map_inv = { [ "/" ] = "/" }
46
+ for k, v in pairs(escape_char_map) do
47
+ escape_char_map_inv[v] = k
48
+ end
49
+
50
+
51
+ local function escape_char(c)
52
+ return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
53
+ end
54
+
55
+
56
+ local function encode_nil(val)
57
+ return "null"
58
+ end
59
+
60
+
61
+ local function encode_table(val, stack)
62
+ local res = {}
63
+ stack = stack or {}
64
+
65
+ -- Circular reference?
66
+ if stack[val] then error("circular reference") end
67
+
68
+ stack[val] = true
69
+
70
+ if rawget(val, 1) ~= nil or next(val) == nil then
71
+ -- Treat as array -- check keys are valid and it is not sparse
72
+ local n = 0
73
+ for k in pairs(val) do
74
+ if type(k) ~= "number" then
75
+ error("invalid table: mixed or invalid key types")
76
+ end
77
+ n = n + 1
78
+ end
79
+ if n ~= #val then
80
+ error("invalid table: sparse array")
81
+ end
82
+ -- Encode
83
+ for i, v in ipairs(val) do
84
+ table.insert(res, encode(v, stack))
85
+ end
86
+ stack[val] = nil
87
+ return "[" .. table.concat(res, ",") .. "]"
88
+
89
+ else
90
+ -- Treat as an object
91
+ for k, v in pairs(val) do
92
+ if type(k) ~= "string" then
93
+ error("invalid table: mixed or invalid key types")
94
+ end
95
+ table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
96
+ end
97
+ stack[val] = nil
98
+ return "{" .. table.concat(res, ",") .. "}"
99
+ end
100
+ end
101
+
102
+
103
+ local function encode_string(val)
104
+ return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
105
+ end
106
+
107
+
108
+ local function encode_number(val)
109
+ -- Check for NaN, -inf and inf
110
+ if val ~= val or val <= -math.huge or val >= math.huge then
111
+ error("unexpected number value '" .. tostring(val) .. "'")
112
+ end
113
+ return string.format("%.14g", val)
114
+ end
115
+
116
+
117
+ local type_func_map = {
118
+ [ "nil" ] = encode_nil,
119
+ [ "table" ] = encode_table,
120
+ [ "string" ] = encode_string,
121
+ [ "number" ] = encode_number,
122
+ [ "boolean" ] = tostring,
123
+ }
124
+
125
+
126
+ encode = function(val, stack)
127
+ local t = type(val)
128
+ local f = type_func_map[t]
129
+ if f then
130
+ return f(val, stack)
131
+ end
132
+ error("unexpected type '" .. t .. "'")
133
+ end
134
+
135
+
136
+ function json.encode(val)
137
+ return ( encode(val) )
138
+ end
139
+
140
+
141
+ -------------------------------------------------------------------------------
142
+ -- Decode
143
+ -------------------------------------------------------------------------------
144
+
145
+ local parse
146
+
147
+ local function create_set(...)
148
+ local res = {}
149
+ for i = 1, select("#", ...) do
150
+ res[ select(i, ...) ] = true
151
+ end
152
+ return res
153
+ end
154
+
155
+ local space_chars = create_set(" ", "\t", "\r", "\n")
156
+ local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
157
+ local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
158
+ local literals = create_set("true", "false", "null")
159
+
160
+ local literal_map = {
161
+ [ "true" ] = true,
162
+ [ "false" ] = false,
163
+ [ "null" ] = nil,
164
+ }
165
+
166
+
167
+ local function next_char(str, idx, set, negate)
168
+ for i = idx, #str do
169
+ if set[str:sub(i, i)] ~= negate then
170
+ return i
171
+ end
172
+ end
173
+ return #str + 1
174
+ end
175
+
176
+
177
+ local function decode_error(str, idx, msg)
178
+ local line_count = 1
179
+ local col_count = 1
180
+ for i = 1, idx - 1 do
181
+ col_count = col_count + 1
182
+ if str:sub(i, i) == "\n" then
183
+ line_count = line_count + 1
184
+ col_count = 1
185
+ end
186
+ end
187
+ error( string.format("%s at line %d col %d", msg, line_count, col_count) )
188
+ end
189
+
190
+
191
+ local function codepoint_to_utf8(n)
192
+ -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
193
+ local f = math.floor
194
+ if n <= 0x7f then
195
+ return string.char(n)
196
+ elseif n <= 0x7ff then
197
+ return string.char(f(n / 64) + 192, n % 64 + 128)
198
+ elseif n <= 0xffff then
199
+ return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
200
+ elseif n <= 0x10ffff then
201
+ return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
202
+ f(n % 4096 / 64) + 128, n % 64 + 128)
203
+ end
204
+ error( string.format("invalid unicode codepoint '%x'", n) )
205
+ end
206
+
207
+
208
+ local function parse_unicode_escape(s)
209
+ local n1 = tonumber( s:sub(1, 4), 16 )
210
+ local n2 = tonumber( s:sub(7, 10), 16 )
211
+ -- Surrogate pair?
212
+ if n2 then
213
+ return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
214
+ else
215
+ return codepoint_to_utf8(n1)
216
+ end
217
+ end
218
+
219
+
220
+ local function parse_string(str, i)
221
+ local res = ""
222
+ local j = i + 1
223
+ local k = j
224
+
225
+ while j <= #str do
226
+ local x = str:byte(j)
227
+
228
+ if x < 32 then
229
+ decode_error(str, j, "control character in string")
230
+
231
+ elseif x == 92 then -- `\`: Escape
232
+ res = res .. str:sub(k, j - 1)
233
+ j = j + 1
234
+ local c = str:sub(j, j)
235
+ if c == "u" then
236
+ local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1)
237
+ or str:match("^%x%x%x%x", j + 1)
238
+ or decode_error(str, j - 1, "invalid unicode escape in string")
239
+ res = res .. parse_unicode_escape(hex)
240
+ j = j + #hex
241
+ else
242
+ if not escape_chars[c] then
243
+ decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string")
244
+ end
245
+ res = res .. escape_char_map_inv[c]
246
+ end
247
+ k = j + 1
248
+
249
+ elseif x == 34 then -- `"`: End of string
250
+ res = res .. str:sub(k, j - 1)
251
+ return res, j + 1
252
+ end
253
+
254
+ j = j + 1
255
+ end
256
+
257
+ decode_error(str, i, "expected closing quote for string")
258
+ end
259
+
260
+
261
+ local function parse_number(str, i)
262
+ local x = next_char(str, i, delim_chars)
263
+ local s = str:sub(i, x - 1)
264
+ local n = tonumber(s)
265
+ if not n then
266
+ decode_error(str, i, "invalid number '" .. s .. "'")
267
+ end
268
+ return n, x
269
+ end
270
+
271
+
272
+ local function parse_literal(str, i)
273
+ local x = next_char(str, i, delim_chars)
274
+ local word = str:sub(i, x - 1)
275
+ if not literals[word] then
276
+ decode_error(str, i, "invalid literal '" .. word .. "'")
277
+ end
278
+ return literal_map[word], x
279
+ end
280
+
281
+
282
+ local function parse_array(str, i)
283
+ local res = {}
284
+ local n = 1
285
+ i = i + 1
286
+ while 1 do
287
+ local x
288
+ i = next_char(str, i, space_chars, true)
289
+ -- Empty / end of array?
290
+ if str:sub(i, i) == "]" then
291
+ i = i + 1
292
+ break
293
+ end
294
+ -- Read token
295
+ x, i = parse(str, i)
296
+ res[n] = x
297
+ n = n + 1
298
+ -- Next token
299
+ i = next_char(str, i, space_chars, true)
300
+ local chr = str:sub(i, i)
301
+ i = i + 1
302
+ if chr == "]" then break end
303
+ if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
304
+ end
305
+ return res, i
306
+ end
307
+
308
+
309
+ local function parse_object(str, i)
310
+ local res = {}
311
+ i = i + 1
312
+ while 1 do
313
+ local key, val
314
+ i = next_char(str, i, space_chars, true)
315
+ -- Empty / end of object?
316
+ if str:sub(i, i) == "}" then
317
+ i = i + 1
318
+ break
319
+ end
320
+ -- Read key
321
+ if str:sub(i, i) ~= '"' then
322
+ decode_error(str, i, "expected string for key")
323
+ end
324
+ key, i = parse(str, i)
325
+ -- Read ':' delimiter
326
+ i = next_char(str, i, space_chars, true)
327
+ if str:sub(i, i) ~= ":" then
328
+ decode_error(str, i, "expected ':' after key")
329
+ end
330
+ i = next_char(str, i + 1, space_chars, true)
331
+ -- Read value
332
+ val, i = parse(str, i)
333
+ -- Set
334
+ res[key] = val
335
+ -- Next token
336
+ i = next_char(str, i, space_chars, true)
337
+ local chr = str:sub(i, i)
338
+ i = i + 1
339
+ if chr == "}" then break end
340
+ if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
341
+ end
342
+ return res, i
343
+ end
344
+
345
+
346
+ local char_func_map = {
347
+ [ '"' ] = parse_string,
348
+ [ "0" ] = parse_number,
349
+ [ "1" ] = parse_number,
350
+ [ "2" ] = parse_number,
351
+ [ "3" ] = parse_number,
352
+ [ "4" ] = parse_number,
353
+ [ "5" ] = parse_number,
354
+ [ "6" ] = parse_number,
355
+ [ "7" ] = parse_number,
356
+ [ "8" ] = parse_number,
357
+ [ "9" ] = parse_number,
358
+ [ "-" ] = parse_number,
359
+ [ "t" ] = parse_literal,
360
+ [ "f" ] = parse_literal,
361
+ [ "n" ] = parse_literal,
362
+ [ "[" ] = parse_array,
363
+ [ "{" ] = parse_object,
364
+ }
365
+
366
+
367
+ parse = function(str, idx)
368
+ local chr = str:sub(idx, idx)
369
+ local f = char_func_map[chr]
370
+ if f then
371
+ return f(str, idx)
372
+ end
373
+ decode_error(str, idx, "unexpected character '" .. chr .. "'")
374
+ end
375
+
376
+
377
+ function json.decode(str)
378
+ if type(str) ~= "string" then
379
+ error("expected argument of type string, got " .. type(str))
380
+ end
381
+ local res, idx = parse(str, next_char(str, 1, space_chars, true))
382
+ idx = next_char(str, idx, space_chars, true)
383
+ if idx <= #str then
384
+ decode_error(str, idx, "trailing garbage")
385
+ end
386
+ return res
387
+ end
388
+
389
+
390
+ return json
@@ -50,8 +50,8 @@ import { postPlayerChangeTypeRegister } from "../callbacks/subscriptions/postPla
50
50
  import { postPlayerCollectibleAddedRegister } from "../callbacks/subscriptions/postPlayerCollectibleAdded";
51
51
  import { postPlayerCollectibleRemovedRegister } from "../callbacks/subscriptions/postPlayerCollectibleRemoved";
52
52
  import { postPlayerFatalDamageRegister } from "../callbacks/subscriptions/postPlayerFatalDamage";
53
+ import { postPlayerInitFirstRegister } from "../callbacks/subscriptions/postPlayerInitFirst";
53
54
  import { postPlayerInitLateRegister } from "../callbacks/subscriptions/postPlayerInitLate";
54
- import { postPlayerInitReorderedRegister } from "../callbacks/subscriptions/postPlayerInitReordered";
55
55
  import { postPlayerRenderReorderedRegister } from "../callbacks/subscriptions/postPlayerRenderReordered";
56
56
  import { postPlayerUpdateReorderedRegister } from "../callbacks/subscriptions/postPlayerUpdateReordered";
57
57
  import { postPoopRenderRegister } from "../callbacks/subscriptions/postPoopRender";
@@ -149,9 +149,8 @@ export const CALLBACK_REGISTER_FUNCTIONS: {
149
149
  [ModCallbackCustom.POST_PLAYER_COLLECTIBLE_REMOVED]:
150
150
  postPlayerCollectibleRemovedRegister,
151
151
  [ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE]: postPlayerFatalDamageRegister,
152
+ [ModCallbackCustom.POST_PLAYER_INIT_FIRST]: postPlayerInitFirstRegister,
152
153
  [ModCallbackCustom.POST_PLAYER_INIT_LATE]: postPlayerInitLateRegister,
153
- [ModCallbackCustom.POST_PLAYER_INIT_REORDERED]:
154
- postPlayerInitReorderedRegister,
155
154
  [ModCallbackCustom.POST_PLAYER_RENDER_REORDERED]:
156
155
  postPlayerRenderReorderedRegister,
157
156
  [ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED]:
@@ -0,0 +1,49 @@
1
+ import { PlayerType } from "isaac-typescript-definitions";
2
+
3
+ /** From: https://bindingofisaacrebirth.fandom.com/wiki/Characters#Regular_Characters */
4
+ export const CHARACTER_DAMAGE_MULTIPLIERS: {
5
+ readonly [key in PlayerType]: float;
6
+ } = {
7
+ [PlayerType.POSSESSOR]: 1.0, // -1
8
+ [PlayerType.ISAAC]: 1.0, // 0
9
+ [PlayerType.MAGDALENE]: 1.0, // 1
10
+ [PlayerType.CAIN]: 1.2, // 2
11
+ [PlayerType.JUDAS]: 1.35, // 3
12
+ [PlayerType.BLUE_BABY]: 1.05, // 4
13
+ [PlayerType.EVE]: 0.75, // 5
14
+ [PlayerType.SAMSON]: 1.0, // 6
15
+ [PlayerType.AZAZEL]: 1.5, // 7
16
+ [PlayerType.LAZARUS]: 1.0, // 8
17
+ [PlayerType.EDEN]: 1.0, // 9
18
+ [PlayerType.THE_LOST]: 1.0, // 10
19
+ [PlayerType.LAZARUS_2]: 1.4, // 11
20
+ [PlayerType.BLACK_JUDAS]: 2.0, // 12
21
+ [PlayerType.LILITH]: 1.0, // 13
22
+ [PlayerType.KEEPER]: 1.2, // 14
23
+ [PlayerType.APOLLYON]: 1.0, // 15
24
+ [PlayerType.THE_FORGOTTEN]: 1.5, // 16
25
+ [PlayerType.THE_SOUL]: 1.0, // 17
26
+ [PlayerType.BETHANY]: 1.0, // 18
27
+ [PlayerType.JACOB]: 1.0, // 19
28
+ [PlayerType.ESAU]: 1.0, // 20
29
+ [PlayerType.ISAAC_B]: 1.0, // 21
30
+ [PlayerType.MAGDALENE_B]: 0.75, // 22
31
+ [PlayerType.CAIN_B]: 1.0, // 23
32
+ [PlayerType.JUDAS_B]: 1.0, // 24
33
+ [PlayerType.BLUE_BABY_B]: 1.0, // 25
34
+ [PlayerType.EVE_B]: 1.2, // 26
35
+ [PlayerType.SAMSON_B]: 1.0, // 27
36
+ [PlayerType.AZAZEL_B]: 1.5, // 28
37
+ [PlayerType.LAZARUS_B]: 1.0, // 29
38
+ [PlayerType.EDEN_B]: 1.0, // 30
39
+ [PlayerType.THE_LOST_B]: 1.3, // 31
40
+ [PlayerType.LILITH_B]: 1.0, // 32
41
+ [PlayerType.KEEPER_B]: 1.0, // 33
42
+ [PlayerType.APOLLYON_B]: 1.0, // 34
43
+ [PlayerType.THE_FORGOTTEN_B]: 1.5, // 35
44
+ [PlayerType.BETHANY_B]: 1.0, // 36
45
+ [PlayerType.JACOB_B]: 1.0, // 37
46
+ [PlayerType.LAZARUS_2_B]: 1.5, // 38
47
+ [PlayerType.JACOB_2_B]: 1.0, // 39
48
+ [PlayerType.THE_SOUL_B]: 1.0, // 40
49
+ } as const;