isaacscript-common 7.0.0 → 7.1.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 (144) hide show
  1. package/dist/callbacks/postPlayerChangeHealth.lua +8 -1
  2. package/dist/callbacks/postPlayerChangeStat.d.ts +3 -0
  3. package/dist/callbacks/postPlayerChangeStat.d.ts.map +1 -0
  4. package/dist/callbacks/postPlayerChangeStat.lua +59 -0
  5. package/dist/callbacks/subscriptions/postPlayerChangeHealth.d.ts +2 -2
  6. package/dist/callbacks/subscriptions/postPlayerChangeHealth.d.ts.map +1 -1
  7. package/dist/callbacks/subscriptions/postPlayerChangeHealth.lua +9 -2
  8. package/dist/callbacks/subscriptions/postPlayerChangeStat.d.ts +12 -0
  9. package/dist/callbacks/subscriptions/postPlayerChangeStat.d.ts.map +1 -0
  10. package/dist/callbacks/subscriptions/postPlayerChangeStat.lua +35 -0
  11. package/dist/core/constants.d.ts +1 -1
  12. package/dist/core/constants.d.ts.map +1 -1
  13. package/dist/core/constants.lua +1 -1
  14. package/dist/enums/ModCallbackCustom.d.ts +70 -39
  15. package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
  16. package/dist/enums/ModCallbackCustom.lua +37 -35
  17. package/dist/enums/StatType.d.ts +30 -0
  18. package/dist/enums/StatType.d.ts.map +1 -0
  19. package/dist/enums/StatType.lua +30 -0
  20. package/dist/enums/index.d.ts +1 -0
  21. package/dist/enums/index.d.ts.map +1 -1
  22. package/dist/enums/index.lua +8 -0
  23. package/dist/enums/private/CopyableIsaacAPIClassType.d.ts +5 -1
  24. package/dist/enums/private/CopyableIsaacAPIClassType.d.ts.map +1 -1
  25. package/dist/enums/private/CopyableIsaacAPIClassType.lua +3 -1
  26. package/dist/enums/private/SerializationBrand.d.ts +1 -0
  27. package/dist/enums/private/SerializationBrand.d.ts.map +1 -1
  28. package/dist/enums/private/SerializationBrand.lua +1 -0
  29. package/dist/features/customStage/versusScreen.lua +2 -2
  30. package/dist/features/saveDataManager/merge.d.ts +1 -0
  31. package/dist/features/saveDataManager/merge.d.ts.map +1 -1
  32. package/dist/features/saveDataManager/merge.lua +1 -0
  33. package/dist/functions/bitSet128.d.ts +25 -0
  34. package/dist/functions/bitSet128.d.ts.map +1 -0
  35. package/dist/functions/bitSet128.lua +71 -0
  36. package/dist/functions/collectibles.d.ts +2 -2
  37. package/dist/functions/collectibles.lua +2 -2
  38. package/dist/functions/color.d.ts +1 -1
  39. package/dist/functions/color.d.ts.map +1 -1
  40. package/dist/functions/color.lua +2 -2
  41. package/dist/functions/deepCopy.d.ts +1 -0
  42. package/dist/functions/deepCopy.d.ts.map +1 -1
  43. package/dist/functions/deepCopy.lua +1 -0
  44. package/dist/functions/familiars.d.ts +4 -4
  45. package/dist/functions/familiars.lua +4 -4
  46. package/dist/functions/flag.d.ts +1 -1
  47. package/dist/functions/flag.lua +1 -1
  48. package/dist/functions/index.d.ts +2 -0
  49. package/dist/functions/index.d.ts.map +1 -1
  50. package/dist/functions/index.lua +16 -0
  51. package/dist/functions/jsonRoom.lua +4 -4
  52. package/dist/functions/kColor.d.ts +1 -1
  53. package/dist/functions/kColor.d.ts.map +1 -1
  54. package/dist/functions/kColor.lua +2 -2
  55. package/dist/functions/log.lua +1 -1
  56. package/dist/functions/npcs.d.ts +2 -2
  57. package/dist/functions/npcs.lua +2 -2
  58. package/dist/functions/playerIndex.d.ts +1 -1
  59. package/dist/functions/playerIndex.lua +1 -1
  60. package/dist/functions/playerStats.d.ts +6 -0
  61. package/dist/functions/playerStats.d.ts.map +1 -0
  62. package/dist/functions/playerStats.lua +22 -0
  63. package/dist/functions/players.d.ts +1 -1
  64. package/dist/functions/players.lua +1 -1
  65. package/dist/functions/rng.d.ts +1 -1
  66. package/dist/functions/rng.d.ts.map +1 -1
  67. package/dist/functions/rng.lua +2 -2
  68. package/dist/functions/roomTransition.d.ts +1 -1
  69. package/dist/functions/roomTransition.lua +1 -1
  70. package/dist/functions/rooms.d.ts +1 -1
  71. package/dist/functions/rooms.lua +1 -1
  72. package/dist/functions/sprites.d.ts +3 -3
  73. package/dist/functions/sprites.lua +3 -3
  74. package/dist/functions/tears.d.ts +5 -4
  75. package/dist/functions/tears.d.ts.map +1 -1
  76. package/dist/functions/tears.lua +5 -4
  77. package/dist/functions/utils.d.ts +4 -1
  78. package/dist/functions/utils.d.ts.map +1 -1
  79. package/dist/functions/utils.lua +4 -1
  80. package/dist/functions/vector.d.ts +1 -1
  81. package/dist/functions/vector.d.ts.map +1 -1
  82. package/dist/functions/vector.lua +2 -2
  83. package/dist/initCustomCallbacks.d.ts.map +1 -1
  84. package/dist/initCustomCallbacks.lua +3 -0
  85. package/dist/interfaces/SaveData.d.ts +2 -5
  86. package/dist/interfaces/SaveData.d.ts.map +1 -1
  87. package/dist/interfaces/StatTypeType.d.ts +18 -0
  88. package/dist/interfaces/StatTypeType.d.ts.map +1 -0
  89. package/dist/interfaces/StatTypeType.lua +4 -0
  90. package/dist/interfaces/index.d.ts +1 -0
  91. package/dist/interfaces/index.d.ts.map +1 -1
  92. package/dist/interfaces/private/AddCallbackParameterCustom.d.ts +2 -0
  93. package/dist/interfaces/private/AddCallbackParameterCustom.d.ts.map +1 -1
  94. package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
  95. package/dist/objects/callbackRegisterFunctions.lua +3 -0
  96. package/dist/objects/isaacAPIClassTypeToBrand.d.ts.map +1 -1
  97. package/dist/objects/isaacAPIClassTypeToBrand.lua +7 -1
  98. package/dist/objects/isaacAPIClassTypeToFunctions.d.ts.map +1 -1
  99. package/dist/objects/isaacAPIClassTypeToFunctions.lua +12 -1
  100. package/package.json +2 -2
  101. package/src/callbacks/postPlayerChangeHealth.ts +7 -1
  102. package/src/callbacks/postPlayerChangeStat.ts +68 -0
  103. package/src/callbacks/subscriptions/postPlayerChangeHealth.ts +5 -1
  104. package/src/callbacks/subscriptions/postPlayerChangeStat.ts +55 -0
  105. package/src/core/constants.ts +1 -1
  106. package/src/enums/ModCallbackCustom.ts +36 -4
  107. package/src/enums/StatType.ts +47 -0
  108. package/src/enums/index.ts +1 -0
  109. package/src/enums/indexTypeDoc.ts +1 -0
  110. package/src/enums/private/CopyableIsaacAPIClassType.ts +5 -1
  111. package/src/enums/private/SerializationBrand.ts +1 -0
  112. package/src/features/customStage/versusScreen.ts +2 -2
  113. package/src/features/saveDataManager/merge.ts +1 -0
  114. package/src/functions/bitSet128.ts +96 -0
  115. package/src/functions/collectibles.ts +2 -2
  116. package/src/functions/color.ts +3 -2
  117. package/src/functions/deepCopy.ts +1 -0
  118. package/src/functions/familiars.ts +4 -4
  119. package/src/functions/flag.ts +1 -1
  120. package/src/functions/index.ts +2 -0
  121. package/src/functions/indexTypeDoc.ts +2 -0
  122. package/src/functions/jsonRoom.ts +4 -4
  123. package/src/functions/kColor.ts +2 -2
  124. package/src/functions/log.ts +1 -1
  125. package/src/functions/npcs.ts +2 -2
  126. package/src/functions/playerIndex.ts +1 -1
  127. package/src/functions/playerStats.ts +26 -0
  128. package/src/functions/players.ts +1 -1
  129. package/src/functions/rng.ts +2 -2
  130. package/src/functions/roomTransition.ts +1 -1
  131. package/src/functions/rooms.ts +1 -1
  132. package/src/functions/sprites.ts +3 -3
  133. package/src/functions/tears.ts +5 -4
  134. package/src/functions/utils.ts +5 -1
  135. package/src/functions/vector.ts +2 -2
  136. package/src/initCustomCallbacks.ts +2 -0
  137. package/src/interfaces/SaveData.ts +1 -5
  138. package/src/interfaces/StatTypeType.ts +18 -0
  139. package/src/interfaces/index.ts +1 -0
  140. package/src/interfaces/indexTypeDoc.ts +1 -0
  141. package/src/interfaces/private/AddCallbackParameterCustom.ts +2 -0
  142. package/src/objects/callbackRegisterFunctions.ts +2 -0
  143. package/src/objects/isaacAPIClassTypeToBrand.ts +1 -0
  144. package/src/objects/isaacAPIClassTypeToFunctions.ts +12 -0
@@ -103,6 +103,8 @@ local ____postPitUpdate = require("callbacks.subscriptions.postPitUpdate")
103
103
  local postPitUpdateRegister = ____postPitUpdate.postPitUpdateRegister
104
104
  local ____postPlayerChangeHealth = require("callbacks.subscriptions.postPlayerChangeHealth")
105
105
  local postPlayerChangeHealthRegister = ____postPlayerChangeHealth.postPlayerChangeHealthRegister
106
+ local ____postPlayerChangeStat = require("callbacks.subscriptions.postPlayerChangeStat")
107
+ local postPlayerChangeStatRegister = ____postPlayerChangeStat.postPlayerChangeStatRegister
106
108
  local ____postPlayerChangeType = require("callbacks.subscriptions.postPlayerChangeType")
107
109
  local postPlayerChangeTypeRegister = ____postPlayerChangeType.postPlayerChangeTypeRegister
108
110
  local ____postPlayerCollectibleAdded = require("callbacks.subscriptions.postPlayerCollectibleAdded")
@@ -228,6 +230,7 @@ ____exports.CALLBACK_REGISTER_FUNCTIONS = {
228
230
  [ModCallbackCustom.POST_PIT_RENDER] = postPitRenderRegister,
229
231
  [ModCallbackCustom.POST_PIT_UPDATE] = postPitUpdateRegister,
230
232
  [ModCallbackCustom.POST_PLAYER_CHANGE_HEALTH] = postPlayerChangeHealthRegister,
233
+ [ModCallbackCustom.POST_PLAYER_CHANGE_STAT] = postPlayerChangeStatRegister,
231
234
  [ModCallbackCustom.POST_PLAYER_CHANGE_TYPE] = postPlayerChangeTypeRegister,
232
235
  [ModCallbackCustom.POST_PLAYER_COLLECTIBLE_ADDED] = postPlayerCollectibleAddedRegister,
233
236
  [ModCallbackCustom.POST_PLAYER_COLLECTIBLE_REMOVED] = postPlayerCollectibleRemovedRegister,
@@ -1 +1 @@
1
- {"version":3,"file":"isaacAPIClassTypeToBrand.d.ts","sourceRoot":"","sources":["../../src/objects/isaacAPIClassTypeToBrand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,eAAO,MAAM,6BAA6B,EAAE;IAC1C,QAAQ,EAAE,GAAG,IAAI,yBAAyB,GAAG,kBAAkB;CAMvD,CAAC"}
1
+ {"version":3,"file":"isaacAPIClassTypeToBrand.d.ts","sourceRoot":"","sources":["../../src/objects/isaacAPIClassTypeToBrand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,eAAO,MAAM,6BAA6B,EAAE;IAC1C,QAAQ,EAAE,GAAG,IAAI,yBAAyB,GAAG,kBAAkB;CAOvD,CAAC"}
@@ -3,5 +3,11 @@ local ____CopyableIsaacAPIClassType = require("enums.private.CopyableIsaacAPICla
3
3
  local CopyableIsaacAPIClassType = ____CopyableIsaacAPIClassType.CopyableIsaacAPIClassType
4
4
  local ____SerializationBrand = require("enums.private.SerializationBrand")
5
5
  local SerializationBrand = ____SerializationBrand.SerializationBrand
6
- ____exports.ISAAC_API_CLASS_TYPE_TO_BRAND = {[CopyableIsaacAPIClassType.COLOR] = SerializationBrand.COLOR, [CopyableIsaacAPIClassType.K_COLOR] = SerializationBrand.K_COLOR, [CopyableIsaacAPIClassType.RNG] = SerializationBrand.RNG, [CopyableIsaacAPIClassType.VECTOR] = SerializationBrand.VECTOR}
6
+ ____exports.ISAAC_API_CLASS_TYPE_TO_BRAND = {
7
+ [CopyableIsaacAPIClassType.BIT_SET_128] = SerializationBrand.BIT_SET_128,
8
+ [CopyableIsaacAPIClassType.COLOR] = SerializationBrand.COLOR,
9
+ [CopyableIsaacAPIClassType.K_COLOR] = SerializationBrand.K_COLOR,
10
+ [CopyableIsaacAPIClassType.RNG] = SerializationBrand.RNG,
11
+ [CopyableIsaacAPIClassType.VECTOR] = SerializationBrand.VECTOR
12
+ }
7
13
  return ____exports
@@ -1 +1 @@
1
- {"version":3,"file":"isaacAPIClassTypeToFunctions.d.ts","sourceRoot":"","sources":["../../src/objects/isaacAPIClassTypeToFunctions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AA0BvF,UAAU,0BAA0B;IAClC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC;IACrD,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,eAAO,MAAM,iCAAiC,EAAE;IAC9C,QAAQ,EAAE,GAAG,IAAI,yBAAyB,GAAG,0BAA0B;CA0B/D,CAAC"}
1
+ {"version":3,"file":"isaacAPIClassTypeToFunctions.d.ts","sourceRoot":"","sources":["../../src/objects/isaacAPIClassTypeToFunctions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAgCvF,UAAU,0BAA0B;IAClC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC;IACrD,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,eAAO,MAAM,iCAAiC,EAAE;IAC9C,QAAQ,EAAE,GAAG,IAAI,yBAAyB,GAAG,0BAA0B;CAgC/D,CAAC"}
@@ -1,6 +1,11 @@
1
1
  local ____exports = {}
2
2
  local ____CopyableIsaacAPIClassType = require("enums.private.CopyableIsaacAPIClassType")
3
3
  local CopyableIsaacAPIClassType = ____CopyableIsaacAPIClassType.CopyableIsaacAPIClassType
4
+ local ____bitSet128 = require("functions.bitSet128")
5
+ local copyBitSet128 = ____bitSet128.copyBitSet128
6
+ local deserializeBitSet128 = ____bitSet128.deserializeBitSet128
7
+ local isSerializedBitSet128 = ____bitSet128.isSerializedBitSet128
8
+ local serializeBitSet128 = ____bitSet128.serializeBitSet128
4
9
  local ____color = require("functions.color")
5
10
  local copyColor = ____color.copyColor
6
11
  local deserializeColor = ____color.deserializeColor
@@ -21,5 +26,11 @@ local copyVector = ____vector.copyVector
21
26
  local deserializeVector = ____vector.deserializeVector
22
27
  local isSerializedVector = ____vector.isSerializedVector
23
28
  local serializeVector = ____vector.serializeVector
24
- ____exports.ISAAC_API_CLASS_TYPE_TO_FUNCTIONS = {[CopyableIsaacAPIClassType.COLOR] = {isSerialized = isSerializedColor, copy = copyColor, serialize = serializeColor, deserialize = deserializeColor}, [CopyableIsaacAPIClassType.K_COLOR] = {isSerialized = isSerializedKColor, copy = copyKColor, serialize = serializeKColor, deserialize = deserializeKColor}, [CopyableIsaacAPIClassType.RNG] = {isSerialized = isSerializedRNG, copy = copyRNG, serialize = serializeRNG, deserialize = deserializeRNG}, [CopyableIsaacAPIClassType.VECTOR] = {isSerialized = isSerializedVector, copy = copyVector, serialize = serializeVector, deserialize = deserializeVector}}
29
+ ____exports.ISAAC_API_CLASS_TYPE_TO_FUNCTIONS = {
30
+ [CopyableIsaacAPIClassType.BIT_SET_128] = {isSerialized = isSerializedBitSet128, copy = copyBitSet128, serialize = serializeBitSet128, deserialize = deserializeBitSet128},
31
+ [CopyableIsaacAPIClassType.COLOR] = {isSerialized = isSerializedColor, copy = copyColor, serialize = serializeColor, deserialize = deserializeColor},
32
+ [CopyableIsaacAPIClassType.K_COLOR] = {isSerialized = isSerializedKColor, copy = copyKColor, serialize = serializeKColor, deserialize = deserializeKColor},
33
+ [CopyableIsaacAPIClassType.RNG] = {isSerialized = isSerializedRNG, copy = copyRNG, serialize = serializeRNG, deserialize = deserializeRNG},
34
+ [CopyableIsaacAPIClassType.VECTOR] = {isSerialized = isSerializedVector, copy = copyVector, serialize = serializeVector, deserialize = deserializeVector}
35
+ }
25
36
  return ____exports
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "7.0.0",
3
+ "version": "7.1.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -22,6 +22,6 @@
22
22
  "main": "dist/index",
23
23
  "types": "dist/index.d.ts",
24
24
  "dependencies": {
25
- "isaac-typescript-definitions": "^3.2.1"
25
+ "isaac-typescript-definitions": "^3.2.3"
26
26
  }
27
27
  }
@@ -55,7 +55,13 @@ function postPEffectUpdateReordered(player: EntityPlayer) {
55
55
  storedHealthValue !== currentHealthValue
56
56
  ) {
57
57
  const difference = currentHealthValue - storedHealthValue;
58
- postPlayerChangeHealthFire(player, healthType, difference);
58
+ postPlayerChangeHealthFire(
59
+ player,
60
+ healthType,
61
+ difference,
62
+ storedHealthValue,
63
+ currentHealthValue,
64
+ );
59
65
  }
60
66
  }
61
67
  }
@@ -0,0 +1,68 @@
1
+ import { TearFlag } from "isaac-typescript-definitions";
2
+ import { DefaultMap } from "../classes/DefaultMap";
3
+ import { ModUpgraded } from "../classes/ModUpgraded";
4
+ import { StatType } from "../enums";
5
+ import { ModCallbackCustom } from "../enums/ModCallbackCustom";
6
+ import { saveDataManager } from "../features/saveDataManager/exports";
7
+ import { getPlayerStat, isNumber } from "../functions";
8
+ import { getEnumValues } from "../functions/enums";
9
+ import { getPlayerIndex } from "../functions/playerIndex";
10
+ import { PlayerIndex } from "../types/PlayerIndex";
11
+ import {
12
+ postPlayerChangeStatFire,
13
+ postPlayerChangeStatHasSubscriptions,
14
+ } from "./subscriptions/postPlayerChangeStat";
15
+
16
+ const v = {
17
+ run: {
18
+ playersStatMap: new DefaultMap<
19
+ PlayerIndex,
20
+ Map<StatType, number | boolean | BitFlags<TearFlag> | Color | Vector>
21
+ >(() => new Map()),
22
+ },
23
+ };
24
+
25
+ export function postPlayerChangeStatInit(mod: ModUpgraded): void {
26
+ saveDataManager("postPlayerChangeStat", v, hasSubscriptions);
27
+
28
+ mod.AddCallbackCustom(
29
+ ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED,
30
+ postPEffectUpdateReordered,
31
+ );
32
+ }
33
+
34
+ function hasSubscriptions() {
35
+ return postPlayerChangeStatHasSubscriptions();
36
+ }
37
+
38
+ // ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED
39
+ function postPEffectUpdateReordered(player: EntityPlayer) {
40
+ if (!hasSubscriptions()) {
41
+ return;
42
+ }
43
+
44
+ // We call the "getPlayerIndex" function with the "differentiateForgottenAndSoul" argument. If we
45
+ // don't differentiate between The Forgotten and The Soul, the callback will fire every time the
46
+ // player switches between the two.
47
+ const playerIndex = getPlayerIndex(player, true);
48
+ const playerStatMap = v.run.playersStatMap.getAndSetDefault(playerIndex);
49
+
50
+ for (const statType of getEnumValues(StatType)) {
51
+ const storedStatValue = playerStatMap.get(statType);
52
+ const currentStatValue = getPlayerStat(player, statType);
53
+ playerStatMap.set(statType, currentStatValue);
54
+
55
+ if (storedStatValue !== undefined && storedStatValue !== currentStatValue) {
56
+ const isNumberStat =
57
+ isNumber(storedStatValue) && isNumber(currentStatValue);
58
+ const difference = isNumberStat ? currentStatValue - storedStatValue : 0;
59
+ postPlayerChangeStatFire(
60
+ player,
61
+ statType,
62
+ difference,
63
+ storedStatValue,
64
+ currentStatValue,
65
+ );
66
+ }
67
+ }
68
+ }
@@ -6,6 +6,8 @@ export type PostPlayerChangeHealthRegisterParameters = [
6
6
  player: EntityPlayer,
7
7
  healthType: HealthType,
8
8
  difference: int,
9
+ oldValue: int,
10
+ newValue: int,
9
11
  ) => void,
10
12
  playerVariant?: PlayerVariant,
11
13
  character?: PlayerType,
@@ -27,6 +29,8 @@ export function postPlayerChangeHealthFire(
27
29
  player: EntityPlayer,
28
30
  healthType: HealthType,
29
31
  difference: int,
32
+ oldValue: int,
33
+ newValue: int,
30
34
  ): void {
31
35
  const character = player.GetPlayerType();
32
36
 
@@ -41,6 +45,6 @@ export function postPlayerChangeHealthFire(
41
45
  continue;
42
46
  }
43
47
 
44
- callback(player, healthType, difference);
48
+ callback(player, healthType, difference, oldValue, newValue);
45
49
  }
46
50
  }
@@ -0,0 +1,55 @@
1
+ import {
2
+ PlayerType,
3
+ PlayerVariant,
4
+ TearFlag,
5
+ } from "isaac-typescript-definitions";
6
+ import { StatType } from "../../enums/StatType";
7
+ import { StatTypeType } from "../../interfaces/StatTypeType";
8
+
9
+ export type PostPlayerChangeStatRegisterParameters = [
10
+ callback: (
11
+ player: EntityPlayer,
12
+ statType: StatType,
13
+ difference: int,
14
+ oldValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
15
+ newValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
16
+ ) => void,
17
+ playerVariant?: PlayerVariant,
18
+ character?: PlayerType,
19
+ ];
20
+
21
+ const subscriptions: PostPlayerChangeStatRegisterParameters[] = [];
22
+
23
+ export function postPlayerChangeStatHasSubscriptions(): boolean {
24
+ return subscriptions.length > 0;
25
+ }
26
+
27
+ export function postPlayerChangeStatRegister(
28
+ ...args: PostPlayerChangeStatRegisterParameters
29
+ ): void {
30
+ subscriptions.push(args);
31
+ }
32
+
33
+ export function postPlayerChangeStatFire<T extends StatType>(
34
+ player: EntityPlayer,
35
+ statType: T,
36
+ difference: int,
37
+ oldValue: StatTypeType[T],
38
+ newValue: StatTypeType[T],
39
+ ): void {
40
+ const character = player.GetPlayerType();
41
+
42
+ for (const [callback, playerVariant, callbackCharacter] of subscriptions) {
43
+ // Handle the optional 2nd callback argument.
44
+ if (playerVariant !== undefined && playerVariant !== player.Variant) {
45
+ continue;
46
+ }
47
+
48
+ // Handle the optional 3rd callback argument.
49
+ if (callbackCharacter !== undefined && callbackCharacter !== character) {
50
+ continue;
51
+ }
52
+
53
+ callback(player, statType, difference, oldValue, newValue);
54
+ }
55
+ }
@@ -36,7 +36,7 @@ export const BLIND_ITEM_PNG_PATH = "gfx/items/collectibles/questionmark.png";
36
36
  /** Bombs explode when their frame count is equal to this value. */
37
37
  export const BOMB_EXPLODE_FRAME = 45;
38
38
 
39
- /** This is the initial value of the `EntityPickup.Wait` property after a collectible is spawned. */
39
+ /** This is the initial value of the `EntityPickup.Wait` field after a collectible is spawned. */
40
40
  export const COLLECTIBLE_INITIAL_WAIT = 20;
41
41
 
42
42
  export const DEFAULT_ITEM_POOL_TYPE = ItemPoolType.TREASURE;
@@ -798,8 +798,8 @@ export enum ModCallbackCustom {
798
798
  POST_PIT_UPDATE,
799
799
 
800
800
  /**
801
- * Fires from the `POST_PEFFECT_UPDATE` callback when a player entity gains or loses any health
802
- * (i.e. hearts). For more information, see the `PlayerHealth` enum.
801
+ * Fires from the `POST_PEFFECT_UPDATE` callback when a player's health (i.e. hearts) is different
802
+ * than what it was on the previous frame. For more information, see the `PlayerHealth` enum.
803
803
  *
804
804
  * - When registering the callback, takes an optional second argument that will make the callback
805
805
  * only fire if the player matches the `PlayerVariant` provided.
@@ -811,15 +811,47 @@ export enum ModCallbackCustom {
811
811
  * player: EntityPlayer,
812
812
  * healthType: HealthType,
813
813
  * difference: int,
814
+ * oldValue: int,
815
+ * newValue: int,
814
816
  * ): void {}
815
817
  * ```
816
818
  */
817
819
  POST_PLAYER_CHANGE_HEALTH,
818
820
 
821
+ /**
822
+ * Fires from the `POST_PEFFECT_UPDATE` callback when one of the player's stats change from what
823
+ * they were on the previous frame.
824
+ *
825
+ * The type of `oldValue` and `newValue` will depend on what kind of stat it is. For example,
826
+ * `StatType.FLYING` will be a boolean. (You can use the "Types" helper functions to narrow the
827
+ * type.)
828
+ *
829
+ * For `StatType.TEAR_FLAG`, `StatType.TEAR_COLOR`, `StatType.FLYING`, and `StatType.SIZE`, the
830
+ * `difference` argument will always be a value of 0, since the type of these stats are not
831
+ * numbers. (For these cases, you should examine the `oldValue` and `newValue` arguments
832
+ * accordingly.)
833
+ *
834
+ * - When registering the callback, takes an optional second argument that will make the callback
835
+ * only fire if the player matches the `PlayerVariant` provided.
836
+ * - When registering the callback, takes an optional third argument that will make the callback
837
+ * only fire if the player matches the `PlayerType` provided.
838
+ *
839
+ * ```ts
840
+ * function postPlayerChangeStat(
841
+ * player: EntityPlayer,
842
+ * statType: StatType,
843
+ * difference: int,
844
+ * oldValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
845
+ * newValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
846
+ * ): void {}
847
+ * ```
848
+ */
849
+ POST_PLAYER_CHANGE_STAT,
850
+
819
851
  /**
820
852
  * Fires from the `POST_PEFFECT_UPDATE` callback when a player entity changes its player type
821
- * (i.e. character). For example, it will fire after using Clicker, after dying with the Judas'
822
- * Shadow collectible, etc.
853
+ * (i.e. character) from what it was on the previous frame. For example, it will fire after using
854
+ * Clicker, after dying with the Judas' Shadow collectible, etc.
823
855
  *
824
856
  * Notably, it does not fire after the player uses the Flip item or the Esau Jr. item, because
825
857
  * those items cause separate player entities to be created. Use the `POST_FLIP` and
@@ -0,0 +1,47 @@
1
+ /** This represents the kinds of stats that a player can have. */
2
+ export enum StatType {
3
+ /** Corresponds to `CacheFlag.DAMAGE` (1 << 0) and `EntityPlayer.Damage`. */
4
+ DAMAGE,
5
+
6
+ /** Corresponds to `CacheFlag.FIRE_DELAY` (1 << 1) and `EntityPlayer.MaxFireDelay`. */
7
+ FIRE_DELAY,
8
+
9
+ /** Corresponds to `CacheFlag.SHOT_SPEED` (1 << 2) and `EntityPlayer.ShotSpeed`. */
10
+ SHOT_SPEED,
11
+
12
+ /** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearHeight`. */
13
+ TEAR_HEIGHT,
14
+
15
+ /** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearRange`. */
16
+ TEAR_RANGE,
17
+
18
+ /** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearFallingAcceleration`. */
19
+ TEAR_FALLING_ACCELERATION,
20
+
21
+ /** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearFallingSpeed`. */
22
+ TEAR_FALLING_SPEED,
23
+
24
+ /** Corresponds to `CacheFlag.SPEED` (1 << 4) and `EntityPlayer.MoveSpeed`. */
25
+ MOVE_SPEED,
26
+
27
+ /** Corresponds to `CacheFlag.TEAR_FLAG` (1 << 5) and `EntityPlayer.TearFlags`. */
28
+ TEAR_FLAG,
29
+
30
+ /** Corresponds to `CacheFlag.TEAR_COLOR` (1 << 6) and `EntityPlayer.TearColor`. */
31
+ TEAR_COLOR,
32
+
33
+ /** Corresponds to `CacheFlag.FLYING` (1 << 7) and `EntityPlayer.CanFly`. */
34
+ FLYING,
35
+
36
+ // `CacheFlag.WEAPON` (1 << 8) does not have a corresponding `EntityPlayer` field.
37
+ // `CacheFlag.FAMILIARS` (1 << 9) does not have a corresponding `EntityPlayer` field.
38
+
39
+ /** Corresponds to `CacheFlag.LUCK` (1 << 10) and `EntityPlayer.Luck`. */
40
+ LUCK,
41
+
42
+ /** Corresponds to `CacheFlag.SIZE` (1 << 11) and `EntityPlayer.SizeMulti`. */
43
+ SIZE,
44
+
45
+ // `CacheFlag.COLOR` (1 << 12) does not have a corresponding `EntityPlayer` field.
46
+ // `CacheFlag.PICKUP_VISION` (1 << 13) does not have a corresponding `EntityPlayer` field.
47
+ }
@@ -6,3 +6,4 @@ export * from "./PocketItemType";
6
6
  export * from "./RockAltType";
7
7
  export * from "./SerializationType";
8
8
  export * from "./SlotDestructionType";
9
+ export * from "./StatType";
@@ -6,3 +6,4 @@ export * as PocketItemType from "./PocketItemType";
6
6
  export * as RockAltType from "./RockAltType";
7
7
  export * as SerializationType from "./SerializationType";
8
8
  export * as SlotDestructionType from "./SlotDestructionType";
9
+ export * as StatType from "./StatType";
@@ -1,5 +1,9 @@
1
- /** This must match the enumeration in the JSDoc comments for `deepCopy` and `merge`. */
1
+ /**
2
+ * - This must match the JSDoc comments for `deepCopy` and `merge`.
3
+ * - This must match the `SerializableIsaacAPIClass` type union.
4
+ */
2
5
  export enum CopyableIsaacAPIClassType {
6
+ BIT_SET_128 = "BitSet128",
3
7
  COLOR = "Color",
4
8
  K_COLOR = "KColor",
5
9
  RNG = "RNG",
@@ -12,6 +12,7 @@ export enum SerializationBrand {
12
12
  SET = "__TSTL_SET",
13
13
 
14
14
  // Specific Isaac API class brands:
15
+ BIT_SET_128 = "__BIT_SET_128",
15
16
  COLOR = "__COLOR",
16
17
  K_COLOR = "__K_COLOR",
17
18
  RNG = "__RNG",
@@ -76,13 +76,13 @@ const versusScreenSprite = Sprite();
76
76
 
77
77
  /**
78
78
  * Unfortunately, we must split the background layer into an entirely different sprite so that we
79
- * can color it with the `Color` property.
79
+ * can color it with the `Color` field.
80
80
  */
81
81
  const versusScreenBackgroundSprite = Sprite();
82
82
 
83
83
  /**
84
84
  * Unfortunately, we must split the dirt layer into an entirely different sprite so that we can
85
- * color it with the `Color` property.
85
+ * color it with the `Color` field.
86
86
  */
87
87
  const versusScreenDirtSpotSprite = Sprite();
88
88
 
@@ -25,6 +25,7 @@ import { isSerializationBrand } from "./serializationBrands";
25
25
  * - TSTL `Set`
26
26
  * - TSTL classes
27
27
  * - `DefaultMap`
28
+ * - Isaac `BitSet128` objects
28
29
  * - Isaac `Color` objects
29
30
  * - Isaac `KColor` objects
30
31
  * - Isaac `RNG` objects
@@ -0,0 +1,96 @@
1
+ import { SerializationBrand } from "../enums/private/SerializationBrand";
2
+ import { isIsaacAPIClassOfType } from "./isaacAPIClass";
3
+ import { copyValuesToTable, getNumbersFromTable, tableHasKeys } from "./table";
4
+ import { isTable } from "./types";
5
+
6
+ export type SerializedBitSet128 = LuaMap<string, unknown> & {
7
+ readonly __serializedBitSet128Brand: symbol;
8
+ };
9
+
10
+ const OBJECT_NAME = "BitSet128";
11
+ const KEYS = ["l", "h"];
12
+
13
+ /** Helper function to copy a `BitSet128` Isaac API class. */
14
+ export function copyBitSet128(bitSet128: BitSet128): BitSet128 {
15
+ if (!isBitSet128(bitSet128)) {
16
+ error(
17
+ `Failed to copy a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
18
+ );
19
+ }
20
+
21
+ const lowBits = bitSet128.l;
22
+ const highBits = bitSet128.h;
23
+
24
+ return BitSet128(lowBits, highBits);
25
+ }
26
+
27
+ /**
28
+ * Helper function to convert a `SerializedBitSet128` object to a normal `BitSet128` object. (This
29
+ * is used by the save data manager when reading data from the "save#.dat" file.)
30
+ */
31
+ export function deserializeBitSet128(
32
+ bitSet128: SerializedBitSet128,
33
+ ): BitSet128 {
34
+ if (!isTable(bitSet128)) {
35
+ error(
36
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object was not a Lua table.`,
37
+ );
38
+ }
39
+
40
+ const [l, h] = getNumbersFromTable(
41
+ bitSet128 as LuaMap<string, unknown>,
42
+ OBJECT_NAME,
43
+ ...KEYS,
44
+ );
45
+
46
+ if (l === undefined) {
47
+ error(
48
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: l`,
49
+ );
50
+ }
51
+ if (h === undefined) {
52
+ error(
53
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: h`,
54
+ );
55
+ }
56
+
57
+ return BitSet128(l, h);
58
+ }
59
+
60
+ /** Helper function to check if something is an instantiated `BitSet128` object. */
61
+ export function isBitSet128(object: unknown): object is BitSet128 {
62
+ return isIsaacAPIClassOfType(object, OBJECT_NAME);
63
+ }
64
+
65
+ /**
66
+ * Used to determine is the given table is a serialized `BitSet128` object created by the save data
67
+ * manager and/or the `deepCopy` function.
68
+ */
69
+ export function isSerializedBitSet128(
70
+ object: unknown,
71
+ ): object is SerializedBitSet128 {
72
+ if (!isTable(object)) {
73
+ return false;
74
+ }
75
+
76
+ return (
77
+ tableHasKeys(object, ...KEYS) && object.has(SerializationBrand.BIT_SET_128)
78
+ );
79
+ }
80
+
81
+ /**
82
+ * Helper function to convert a `BitSet128` object to a `SerializedBitSet128` object. (This is used
83
+ * by the save data manager when writing data from the "save#.dat" file.)
84
+ */
85
+ export function serializeBitSet128(bitSet128: BitSet128): SerializedBitSet128 {
86
+ if (!isBitSet128(bitSet128)) {
87
+ error(
88
+ `Failed to serialize a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
89
+ );
90
+ }
91
+
92
+ const bitSet128Table = new LuaMap<string, unknown>();
93
+ copyValuesToTable(bitSet128, KEYS, bitSet128Table);
94
+ bitSet128Table.set(SerializationBrand.BIT_SET_128, "");
95
+ return bitSet128Table as SerializedBitSet128;
96
+ }
@@ -614,8 +614,8 @@ export function setCollectibleSprite(
614
614
  }
615
615
 
616
616
  /**
617
- * Helper function to change the collectible on a pedestal. Simply updating the `SubType` property
618
- * is not sufficient because the sprite will not change.
617
+ * Helper function to change the collectible on a pedestal. Simply updating the `SubType` field is
618
+ * not sufficient because the sprite will not change.
619
619
  */
620
620
  export function setCollectibleSubType(
621
621
  collectible: EntityPickup,
@@ -9,8 +9,8 @@ export type SerializedColor = LuaMap<string, unknown> & {
9
9
  readonly __serializedColorBrand: symbol;
10
10
  };
11
11
 
12
- const KEYS = ["R", "G", "B", "A", "RO", "GO", "BO"];
13
12
  const OBJECT_NAME = "Color";
13
+ const KEYS = ["R", "G", "B", "A", "RO", "GO", "BO"];
14
14
 
15
15
  export function colorEquals(color1: Color, color2: Color): boolean {
16
16
  return isaacAPIClassEquals(color1, color2, KEYS);
@@ -91,7 +91,7 @@ export function getRandomColor(
91
91
  return Color(r, g, b, alpha);
92
92
  }
93
93
 
94
- /** Helper function to check if something is an instantiated Color object. */
94
+ /** Helper function to check if something is an instantiated `Color` object. */
95
95
  export function isColor(object: unknown): object is Color {
96
96
  return isIsaacAPIClassOfType(object, OBJECT_NAME);
97
97
  }
@@ -107,6 +107,7 @@ export function isSerializedColor(object: unknown): object is SerializedColor {
107
107
 
108
108
  return tableHasKeys(object, ...KEYS) && object.has(SerializationBrand.COLOR);
109
109
  }
110
+
110
111
  /**
111
112
  * Helper function to convert a `Color` object to a `SerializedColor` object. (This is used by the
112
113
  * save data manager when writing data from the "save#.dat" file.)
@@ -42,6 +42,7 @@ const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
42
42
  * - TSTL `Set`
43
43
  * - TSTL classes
44
44
  * - `DefaultMap`
45
+ * - Isaac `BitSet128` objects
45
46
  * - Isaac `Color` objects
46
47
  * - Isaac `KColor` objects
47
48
  * - Isaac `RNG` objects
@@ -11,8 +11,8 @@ import { getFamiliars } from "./entitiesSpecific";
11
11
  * specify an incorrect RNG object. (The vanilla method is bugged in that it does not increment the
12
12
  * RNG object; see the documentation of the method for more details.)
13
13
  *
14
- * This function is meant to be called in the EvaluateCache callback (when the cache flag is equal
15
- * to `CacheFlag.FAMILIARS`).
14
+ * This function is meant to be called in the `EVALUATE_CACHE` callback (when the cache flag is
15
+ * equal to `CacheFlag.FAMILIARS`).
16
16
  *
17
17
  * Note that this function is only meant to be used in special circumstances where the familiar
18
18
  * count is completely custom and does not correspond to the amount of collectibles. For the general
@@ -56,8 +56,8 @@ export function checkFamiliar(
56
56
  * Use this helper function instead of invoking the `EntityPlayer.CheckFamiliar` method directly so
57
57
  * that the target count is handled automatically.
58
58
  *
59
- * This function is meant to be called in the EvaluateCache callback (when the cache flag is equal
60
- * to `CacheFlag.FAMILIARS`).
59
+ * This function is meant to be called in the `EVALUATE_CACHE` callback (when the cache flag is
60
+ * equal to `CacheFlag.FAMILIARS`).
61
61
  *
62
62
  * Use this function when the amount of familiars should be equal to the amount of associated
63
63
  * collectibles that the player has (plus any extras from having used Box of Friends or Monster
@@ -42,7 +42,7 @@ export function addFlag<T extends BitFlag | BitFlag128>(
42
42
  * Helper function for casting a flag enum value to a `BitFlags` object.
43
43
  *
44
44
  * This is useful because the compiler will prevent you from assigning a specific flag to a
45
- * `BitFlags` property. (It does this to ensure type safety, since `BitFlags` can represent a zero
45
+ * `BitFlags` field. (It does this to ensure type safety, since `BitFlags` can represent a zero
46
46
  * value or a composition of N flags.)
47
47
  *
48
48
  * For example:
@@ -3,6 +3,7 @@
3
3
  export * from "./ambush";
4
4
  export * from "./array";
5
5
  export * from "./benchmark";
6
+ export * from "./bitSet128";
6
7
  export * from "./bitwise";
7
8
  export * from "./bombs";
8
9
  export * from "./bosses";
@@ -63,6 +64,7 @@ export * from "./playerDataStructures";
63
64
  export * from "./playerHealth";
64
65
  export * from "./playerIndex";
65
66
  export * from "./players";
67
+ export * from "./playerStats";
66
68
  export * from "./pocketItems";
67
69
  export * from "./positionVelocity";
68
70
  export * from "./pressurePlate";
@@ -3,6 +3,7 @@
3
3
  export * as Ambush from "./ambush";
4
4
  export * as Array from "./array";
5
5
  export * as Benchmark from "./benchmark";
6
+ export * as BitSet128 from "./bitSet128";
6
7
  export * as Bitwise from "./bitwise";
7
8
  export * as Bombs from "./bombs";
8
9
  export * as Bosses from "./bosses";
@@ -63,6 +64,7 @@ export * as PlayerDataStructures from "./playerDataStructures";
63
64
  export * as PlayerHealth from "./playerHealth";
64
65
  export * as PlayerIndex from "./playerIndex";
65
66
  export * as Players from "./players";
67
+ export * as PlayerStats from "./playerStats";
66
68
  export * as PocketItems from "./pocketItems";
67
69
  export * as PositionVelocity from "./positionVelocity";
68
70
  export * as PressurePlate from "./pressurePlate";