isaacscript-common 84.2.5 → 84.3.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.
@@ -88,7 +88,7 @@ exports.NUM_NORMAL_PILL_COLORS = exports.LAST_NORMAL_PILL_COLOR - exports.FIRST_
88
88
  // -------
89
89
  /** Equal to `PlayerType.ISAAC` (0). */
90
90
  exports.FIRST_CHARACTER = isaac_typescript_definitions_1.PlayerType.ISAAC;
91
- // It is not possible to determine "LAST_PLAYER_TYPE", since there is no associated config.
91
+ // It is not possible to determine "LAST_CHARACTER", since there is no associated config.
92
92
  /** Calculated from the `PlayerType` enum. */
93
93
  exports.LAST_VANILLA_CHARACTER = (0, enums_1.getHighestEnumValue)(isaac_typescript_definitions_1.PlayerType);
94
94
  // ----------
@@ -1,36 +1,38 @@
1
1
  import type { CollectibleType, TrinketType } from "isaac-typescript-definitions";
2
2
  import { PlayerType } from "isaac-typescript-definitions";
3
+ import { MAIN_CHARACTERS } from "../core/constants";
4
+ type MainCharacter = (typeof MAIN_CHARACTERS)[number];
5
+ /**
6
+ * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
7
+ * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
8
+ * Otherwise, returns false.
9
+ */
10
+ export declare function canCharacterGetBlackHeartFromEternalHeart(character: PlayerType): boolean;
3
11
  /**
4
12
  * Helper function to determine if the given character can have red heart containers. Returns true
5
13
  * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
6
14
  * though coin containers are not technically the same as red heart containers. Returns false for
7
15
  * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
8
16
  */
9
- export declare function characterCanHaveRedHearts(character: PlayerType): boolean;
17
+ export declare function canCharacterHaveRedHearts(character: PlayerType): boolean;
10
18
  /**
11
19
  * Helper function to determine if the given character can have soul hearts. Returns true for
12
20
  * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
13
21
  * false for The Lost and Tainted Lost.
14
22
  */
15
- export declare function characterCanHaveSoulHearts(character: PlayerType): boolean;
23
+ export declare function canCharacterHaveSoulHearts(character: PlayerType): boolean;
16
24
  /**
17
25
  * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
18
26
  * Lost, Tainted Lost, etc.)
19
27
  */
20
- export declare function characterCanTakeFreeDevilDeals(character: PlayerType): boolean;
21
- /**
22
- * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
23
- * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
24
- * Otherwise, returns false.
25
- */
26
- export declare function characterGetsBlackHeartFromEternalHeart(character: PlayerType): boolean;
28
+ export declare function canCharacterTakeFreeDevilDeals(character: PlayerType): boolean;
27
29
  /**
28
30
  * Helper function to determine if the specified character starts with an active item.
29
31
  *
30
32
  * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
31
33
  * is considered to starts with the D6, but this is not the case on a brand new save file).
32
34
  */
33
- export declare function characterStartsWithActiveItem(character: PlayerType): boolean;
35
+ export declare function doesCharacterStartWithActiveItem(character: PlayerType): boolean;
34
36
  /**
35
37
  * Helper function to get the numerical damage multiplier for a character.
36
38
  *
@@ -76,12 +78,24 @@ export declare function getCharacterStartingCollectibleTypes(character: PlayerTy
76
78
  * Note that this will return undefined for Eden and Tainted Eden.
77
79
  */
78
80
  export declare function getCharacterStartingTrinketType(character: PlayerType): TrinketType | undefined;
81
+ /**
82
+ * Helper function to get the "main" version of the character. In other words, this is the character
83
+ * that selectable from the main menu (and has achievements related to completing the various bosses
84
+ * and so on).
85
+ *
86
+ * For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
87
+ * (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
88
+ *
89
+ * For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
90
+ */
91
+ export declare function getMainCharacter(character: PlayerType): PlayerType | undefined;
79
92
  export declare function isFlyingCharacter(character: PlayerType): boolean;
80
93
  /**
81
94
  * Helper function to check if the provided character is one of the characters that are selectable
82
95
  * from the main menu (and have achievements related to completing the various bosses and so on).
83
96
  */
84
- export declare function isMainCharacter(character: PlayerType): boolean;
97
+ export declare function isMainCharacter(character: PlayerType): character is MainCharacter;
85
98
  export declare function isModdedCharacter(character: PlayerType): boolean;
86
99
  export declare function isVanillaCharacter(character: PlayerType): boolean;
100
+ export {};
87
101
  //# sourceMappingURL=characters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"characters.d.ts","sourceRoot":"","sources":["../../src/functions/characters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAqB1D;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAExE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEzE;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,uCAAuC,CACrD,SAAS,EAAE,UAAU,GACpB,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAE5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,UAAU,EACrB,iBAAiB,UAAQ,GACxB,KAAK,CAMP;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAU5E;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,GAAG,CAsBzE;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAG3E;AAED;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,SAAS,EAAE,UAAU,GACpB,SAAS,eAAe,EAAE,CAE5B;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,UAAU,GACpB,WAAW,GAAG,SAAS,CAEzB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEjE"}
1
+ {"version":3,"file":"characters.d.ts","sourceRoot":"","sources":["../../src/functions/characters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACZ,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAqB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAevE,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAOtD;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,SAAS,EAAE,UAAU,GACpB,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAExE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEzE;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,UAAU,GACpB,OAAO,CAET;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,UAAU,EACrB,iBAAiB,UAAQ,GACxB,KAAK,CAMP;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAU5E;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,UAAU,GAAG,GAAG,CAsBzE;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAG3E;AAED;;;;;GAKG;AACH,wBAAgB,oCAAoC,CAClD,SAAS,EAAE,UAAU,GACpB,SAAS,eAAe,EAAE,CAE5B;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,UAAU,GACpB,WAAW,GAAG,SAAS,CAEzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,UAAU,GACpB,UAAU,GAAG,SAAS,CA8CxB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,UAAU,GACpB,SAAS,IAAI,aAAa,CAE5B;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAEjE"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isVanillaCharacter = exports.isModdedCharacter = exports.isMainCharacter = exports.isFlyingCharacter = exports.getCharacterStartingTrinketType = exports.getCharacterStartingCollectibleTypes = exports.getCharacterSpritePNGFilePath = exports.getCharacterName = exports.getCharacterMaxHeartContainers = exports.getCharacterDeathAnimationName = exports.getCharacterDamageMultiplier = exports.characterStartsWithActiveItem = exports.characterGetsBlackHeartFromEternalHeart = exports.characterCanTakeFreeDevilDeals = exports.characterCanHaveSoulHearts = exports.characterCanHaveRedHearts = void 0;
3
+ exports.isVanillaCharacter = exports.isModdedCharacter = exports.isMainCharacter = exports.isFlyingCharacter = exports.getMainCharacter = exports.getCharacterStartingTrinketType = exports.getCharacterStartingCollectibleTypes = exports.getCharacterSpritePNGFilePath = exports.getCharacterName = exports.getCharacterMaxHeartContainers = exports.getCharacterDeathAnimationName = exports.getCharacterDamageMultiplier = exports.doesCharacterStartWithActiveItem = exports.canCharacterTakeFreeDevilDeals = exports.canCharacterHaveSoulHearts = exports.canCharacterHaveRedHearts = exports.canCharacterGetBlackHeartFromEternalHeart = void 0;
4
4
  const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
5
5
  const constants_1 = require("../core/constants");
6
6
  const constantsFirstLast_1 = require("../core/constantsFirstLast");
@@ -19,52 +19,52 @@ const ReadonlySet_1 = require("../types/ReadonlySet");
19
19
  const FLYING_CHARACTERS_SET = new ReadonlySet_1.ReadonlySet(constants_1.FLYING_CHARACTERS);
20
20
  const MAIN_CHARACTERS_SET = new ReadonlySet_1.ReadonlySet(constants_1.MAIN_CHARACTERS);
21
21
  const PNG_PATH_PREFIX = "characters/costumes";
22
+ /**
23
+ * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
24
+ * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
25
+ * Otherwise, returns false.
26
+ */
27
+ function canCharacterGetBlackHeartFromEternalHeart(character) {
28
+ return charactersWithBlackHeartFromEternalHeartSet_1.CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET.has(character);
29
+ }
30
+ exports.canCharacterGetBlackHeartFromEternalHeart = canCharacterGetBlackHeartFromEternalHeart;
22
31
  /**
23
32
  * Helper function to determine if the given character can have red heart containers. Returns true
24
33
  * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
25
34
  * though coin containers are not technically the same as red heart containers. Returns false for
26
35
  * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
27
36
  */
28
- function characterCanHaveRedHearts(character) {
37
+ function canCharacterHaveRedHearts(character) {
29
38
  return !charactersWithNoRedHeartsSet_1.CHARACTERS_WITH_NO_RED_HEARTS_SET.has(character);
30
39
  }
31
- exports.characterCanHaveRedHearts = characterCanHaveRedHearts;
40
+ exports.canCharacterHaveRedHearts = canCharacterHaveRedHearts;
32
41
  /**
33
42
  * Helper function to determine if the given character can have soul hearts. Returns true for
34
43
  * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
35
44
  * false for The Lost and Tainted Lost.
36
45
  */
37
- function characterCanHaveSoulHearts(character) {
46
+ function canCharacterHaveSoulHearts(character) {
38
47
  return !charactersWithNoSoulHeartsSet_1.CHARACTERS_WITH_NO_SOUL_HEARTS_SET.has(character);
39
48
  }
40
- exports.characterCanHaveSoulHearts = characterCanHaveSoulHearts;
49
+ exports.canCharacterHaveSoulHearts = canCharacterHaveSoulHearts;
41
50
  /**
42
51
  * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
43
52
  * Lost, Tainted Lost, etc.)
44
53
  */
45
- function characterCanTakeFreeDevilDeals(character) {
54
+ function canCharacterTakeFreeDevilDeals(character) {
46
55
  return charactersWithFreeDevilDealsSet_1.CHARACTERS_WITH_FREE_DEVIL_DEALS_SET.has(character);
47
56
  }
48
- exports.characterCanTakeFreeDevilDeals = characterCanTakeFreeDevilDeals;
49
- /**
50
- * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
51
- * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
52
- * Otherwise, returns false.
53
- */
54
- function characterGetsBlackHeartFromEternalHeart(character) {
55
- return charactersWithBlackHeartFromEternalHeartSet_1.CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET.has(character);
56
- }
57
- exports.characterGetsBlackHeartFromEternalHeart = characterGetsBlackHeartFromEternalHeart;
57
+ exports.canCharacterTakeFreeDevilDeals = canCharacterTakeFreeDevilDeals;
58
58
  /**
59
59
  * Helper function to determine if the specified character starts with an active item.
60
60
  *
61
61
  * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
62
62
  * is considered to starts with the D6, but this is not the case on a brand new save file).
63
63
  */
64
- function characterStartsWithActiveItem(character) {
64
+ function doesCharacterStartWithActiveItem(character) {
65
65
  return charactersThatStartWithAnActiveItemSet_1.CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET.has(character);
66
66
  }
67
- exports.characterStartsWithActiveItem = characterStartsWithActiveItem;
67
+ exports.doesCharacterStartWithActiveItem = doesCharacterStartWithActiveItem;
68
68
  /**
69
69
  * Helper function to get the numerical damage multiplier for a character.
70
70
  *
@@ -160,6 +160,56 @@ function getCharacterStartingTrinketType(character) {
160
160
  return characterStartingTrinketTypes_1.CHARACTER_STARTING_TRINKET_TYPE[character];
161
161
  }
162
162
  exports.getCharacterStartingTrinketType = getCharacterStartingTrinketType;
163
+ /**
164
+ * Helper function to get the "main" version of the character. In other words, this is the character
165
+ * that selectable from the main menu (and has achievements related to completing the various bosses
166
+ * and so on).
167
+ *
168
+ * For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
169
+ * (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
170
+ *
171
+ * For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
172
+ */
173
+ function getMainCharacter(character) {
174
+ if (isMainCharacter(character) || isModdedCharacter(character)) {
175
+ return character;
176
+ }
177
+ switch (character) {
178
+ // -1
179
+ case isaac_typescript_definitions_1.PlayerType.POSSESSOR: {
180
+ return isaac_typescript_definitions_1.PlayerType.POSSESSOR;
181
+ }
182
+ // 11
183
+ case isaac_typescript_definitions_1.PlayerType.LAZARUS_2: {
184
+ return isaac_typescript_definitions_1.PlayerType.LAZARUS;
185
+ }
186
+ // 12
187
+ case isaac_typescript_definitions_1.PlayerType.DARK_JUDAS: {
188
+ return isaac_typescript_definitions_1.PlayerType.JUDAS;
189
+ }
190
+ // 17
191
+ case isaac_typescript_definitions_1.PlayerType.SOUL: {
192
+ return isaac_typescript_definitions_1.PlayerType.FORGOTTEN;
193
+ }
194
+ // 20
195
+ case isaac_typescript_definitions_1.PlayerType.ESAU: {
196
+ return isaac_typescript_definitions_1.PlayerType.JACOB;
197
+ }
198
+ // 38
199
+ case isaac_typescript_definitions_1.PlayerType.LAZARUS_2_B: {
200
+ return isaac_typescript_definitions_1.PlayerType.LAZARUS_2;
201
+ }
202
+ // 39
203
+ case isaac_typescript_definitions_1.PlayerType.JACOB_2_B: {
204
+ return isaac_typescript_definitions_1.PlayerType.JACOB_B;
205
+ }
206
+ // 40
207
+ case isaac_typescript_definitions_1.PlayerType.SOUL_B: {
208
+ return isaac_typescript_definitions_1.PlayerType.FORGOTTEN_B;
209
+ }
210
+ }
211
+ }
212
+ exports.getMainCharacter = getMainCharacter;
163
213
  function isFlyingCharacter(character) {
164
214
  return FLYING_CHARACTERS_SET.has(character);
165
215
  }
@@ -1,6 +1,7 @@
1
1
  local ____lualib = require("lualib_bundle")
2
2
  local __TS__New = ____lualib.__TS__New
3
3
  local ____exports = {}
4
+ local MAIN_CHARACTERS_SET
4
5
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
5
6
  local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
6
7
  local ____constants = require("core.constants")
@@ -32,6 +33,11 @@ local ____lostStyleCharactersSet = require("sets.lostStyleCharactersSet")
32
33
  local LOST_STYLE_CHARACTERS_SET = ____lostStyleCharactersSet.LOST_STYLE_CHARACTERS_SET
33
34
  local ____ReadonlySet = require("types.ReadonlySet")
34
35
  local ReadonlySet = ____ReadonlySet.ReadonlySet
36
+ --- Helper function to check if the provided character is one of the characters that are selectable
37
+ -- from the main menu (and have achievements related to completing the various bosses and so on).
38
+ function ____exports.isMainCharacter(self, character)
39
+ return MAIN_CHARACTERS_SET:has(character)
40
+ end
35
41
  function ____exports.isModdedCharacter(self, character)
36
42
  return not ____exports.isVanillaCharacter(nil, character)
37
43
  end
@@ -39,37 +45,37 @@ function ____exports.isVanillaCharacter(self, character)
39
45
  return character <= LAST_VANILLA_CHARACTER
40
46
  end
41
47
  local FLYING_CHARACTERS_SET = __TS__New(ReadonlySet, FLYING_CHARACTERS)
42
- local MAIN_CHARACTERS_SET = __TS__New(ReadonlySet, MAIN_CHARACTERS)
48
+ MAIN_CHARACTERS_SET = __TS__New(ReadonlySet, MAIN_CHARACTERS)
43
49
  local PNG_PATH_PREFIX = "characters/costumes"
50
+ --- Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
51
+ -- but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
52
+ -- Otherwise, returns false.
53
+ function ____exports.canCharacterGetBlackHeartFromEternalHeart(self, character)
54
+ return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET:has(character)
55
+ end
44
56
  --- Helper function to determine if the given character can have red heart containers. Returns true
45
57
  -- for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
46
58
  -- though coin containers are not technically the same as red heart containers. Returns false for
47
59
  -- characters like Blue Baby. Returns false for The Lost and Tainted Lost.
48
- function ____exports.characterCanHaveRedHearts(self, character)
60
+ function ____exports.canCharacterHaveRedHearts(self, character)
49
61
  return not CHARACTERS_WITH_NO_RED_HEARTS_SET:has(character)
50
62
  end
51
63
  --- Helper function to determine if the given character can have soul hearts. Returns true for
52
64
  -- characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
53
65
  -- false for The Lost and Tainted Lost.
54
- function ____exports.characterCanHaveSoulHearts(self, character)
66
+ function ____exports.canCharacterHaveSoulHearts(self, character)
55
67
  return not CHARACTERS_WITH_NO_SOUL_HEARTS_SET:has(character)
56
68
  end
57
69
  --- Helper function for determining whether the given character can take free Devil Deals. (e.g. The
58
70
  -- Lost, Tainted Lost, etc.)
59
- function ____exports.characterCanTakeFreeDevilDeals(self, character)
71
+ function ____exports.canCharacterTakeFreeDevilDeals(self, character)
60
72
  return CHARACTERS_WITH_FREE_DEVIL_DEALS_SET:has(character)
61
73
  end
62
- --- Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
63
- -- but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
64
- -- Otherwise, returns false.
65
- function ____exports.characterGetsBlackHeartFromEternalHeart(self, character)
66
- return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET:has(character)
67
- end
68
74
  --- Helper function to determine if the specified character starts with an active item.
69
75
  --
70
76
  -- For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
71
77
  -- is considered to starts with the D6, but this is not the case on a brand new save file).
72
- function ____exports.characterStartsWithActiveItem(self, character)
78
+ function ____exports.doesCharacterStartWithActiveItem(self, character)
73
79
  return CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET:has(character)
74
80
  end
75
81
  --- Helper function to get the numerical damage multiplier for a character.
@@ -147,12 +153,71 @@ end
147
153
  function ____exports.getCharacterStartingTrinketType(self, character)
148
154
  return CHARACTER_STARTING_TRINKET_TYPE[character]
149
155
  end
156
+ --- Helper function to get the "main" version of the character. In other words, this is the character
157
+ -- that selectable from the main menu (and has achievements related to completing the various bosses
158
+ -- and so on).
159
+ --
160
+ -- For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
161
+ -- (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
162
+ --
163
+ -- For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
164
+ function ____exports.getMainCharacter(self, character)
165
+ if ____exports.isMainCharacter(nil, character) or ____exports.isModdedCharacter(nil, character) then
166
+ return character
167
+ end
168
+ repeat
169
+ local ____switch24 = character
170
+ local ____cond24 = ____switch24 == PlayerType.POSSESSOR
171
+ if ____cond24 then
172
+ do
173
+ return PlayerType.POSSESSOR
174
+ end
175
+ end
176
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2
177
+ if ____cond24 then
178
+ do
179
+ return PlayerType.LAZARUS
180
+ end
181
+ end
182
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.DARK_JUDAS
183
+ if ____cond24 then
184
+ do
185
+ return PlayerType.JUDAS
186
+ end
187
+ end
188
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL
189
+ if ____cond24 then
190
+ do
191
+ return PlayerType.FORGOTTEN
192
+ end
193
+ end
194
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.ESAU
195
+ if ____cond24 then
196
+ do
197
+ return PlayerType.JACOB
198
+ end
199
+ end
200
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2_B
201
+ if ____cond24 then
202
+ do
203
+ return PlayerType.LAZARUS_2
204
+ end
205
+ end
206
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.JACOB_2_B
207
+ if ____cond24 then
208
+ do
209
+ return PlayerType.JACOB_B
210
+ end
211
+ end
212
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL_B
213
+ if ____cond24 then
214
+ do
215
+ return PlayerType.FORGOTTEN_B
216
+ end
217
+ end
218
+ until true
219
+ end
150
220
  function ____exports.isFlyingCharacter(self, character)
151
221
  return FLYING_CHARACTERS_SET:has(character)
152
222
  end
153
- --- Helper function to check if the provided character is one of the characters that are selectable
154
- -- from the main menu (and have achievements related to completing the various bosses and so on).
155
- function ____exports.isMainCharacter(self, character)
156
- return MAIN_CHARACTERS_SET:has(character)
157
- end
158
223
  return ____exports
@@ -1353,6 +1353,34 @@ export declare function Callback<T extends ModCallback>(modCallback: T, ...optio
1353
1353
  */
1354
1354
  export declare function CallbackCustom<T extends ModCallbackCustom>(modCallbackCustom: T, ...optionalArgs: AllButFirst<AddCallbackParametersCustom[T]>): <Class extends ModFeature, Fn extends AddCallbackParametersCustom[T][0]>(target: Class, propertyKey: string, _descriptor: TypedPropertyDescriptor<Fn>) => void;
1355
1355
 
1356
+ /**
1357
+ * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
1358
+ * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
1359
+ * Otherwise, returns false.
1360
+ */
1361
+ export declare function canCharacterGetBlackHeartFromEternalHeart(character: PlayerType): boolean;
1362
+
1363
+ /**
1364
+ * Helper function to determine if the given character can have red heart containers. Returns true
1365
+ * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
1366
+ * though coin containers are not technically the same as red heart containers. Returns false for
1367
+ * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
1368
+ */
1369
+ export declare function canCharacterHaveRedHearts(character: PlayerType): boolean;
1370
+
1371
+ /**
1372
+ * Helper function to determine if the given character can have soul hearts. Returns true for
1373
+ * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
1374
+ * false for The Lost and Tainted Lost.
1375
+ */
1376
+ export declare function canCharacterHaveSoulHearts(character: PlayerType): boolean;
1377
+
1378
+ /**
1379
+ * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
1380
+ * Lost, Tainted Lost, etc.)
1381
+ */
1382
+ export declare function canCharacterTakeFreeDevilDeals(character: PlayerType): boolean;
1383
+
1356
1384
  /**
1357
1385
  * Helper function to see if the provided player can pick up an eternal heart. (If a player already
1358
1386
  * has an eternal heart and full heart containers, they are not able to pick up any additional
@@ -1388,34 +1416,6 @@ export declare function changeRoom(roomGridIndex: int): void;
1388
1416
  /** Maps character names to the values of the `PlayerType` enum. */
1389
1417
  export declare const CHARACTER_NAME_TO_TYPE_MAP: ReadonlyMap<string, PlayerType>;
1390
1418
 
1391
- /**
1392
- * Helper function to determine if the given character can have red heart containers. Returns true
1393
- * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
1394
- * though coin containers are not technically the same as red heart containers. Returns false for
1395
- * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
1396
- */
1397
- export declare function characterCanHaveRedHearts(character: PlayerType): boolean;
1398
-
1399
- /**
1400
- * Helper function to determine if the given character can have soul hearts. Returns true for
1401
- * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
1402
- * false for The Lost and Tainted Lost.
1403
- */
1404
- export declare function characterCanHaveSoulHearts(character: PlayerType): boolean;
1405
-
1406
- /**
1407
- * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
1408
- * Lost, Tainted Lost, etc.)
1409
- */
1410
- export declare function characterCanTakeFreeDevilDeals(character: PlayerType): boolean;
1411
-
1412
- /**
1413
- * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
1414
- * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
1415
- * Otherwise, returns false.
1416
- */
1417
- export declare function characterGetsBlackHeartFromEternalHeart(character: PlayerType): boolean;
1418
-
1419
1419
  declare class CharacterHealthConversion extends Feature {
1420
1420
  private readonly characterHealthReplacementMap;
1421
1421
  private readonly prePickupCollisionHeart;
@@ -1434,14 +1434,6 @@ declare class CharacterHealthConversion extends Feature {
1434
1434
  registerCharacterHealthConversion(playerType: PlayerType, conversionHeartSubType: ConversionHeartSubType): void;
1435
1435
  }
1436
1436
 
1437
- /**
1438
- * Helper function to determine if the specified character starts with an active item.
1439
- *
1440
- * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
1441
- * is considered to starts with the D6, but this is not the case on a brand new save file).
1442
- */
1443
- export declare function characterStartsWithActiveItem(character: PlayerType): boolean;
1444
-
1445
1437
  /** Easily create custom characters that have base stats different from that of Isaac. */
1446
1438
  declare class CharacterStats extends Feature {
1447
1439
  private readonly charactersStatMap;
@@ -3962,6 +3954,14 @@ export declare const DISTANCE_OF_GRID_TILE = 40;
3962
3954
  */
3963
3955
  export declare function doesAnyEntityExist(entityTypes: readonly EntityType[] | ReadonlySet<EntityType>, ignoreFriendly?: boolean): boolean;
3964
3956
 
3957
+ /**
3958
+ * Helper function to determine if the specified character starts with an active item.
3959
+ *
3960
+ * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
3961
+ * is considered to starts with the D6, but this is not the case on a brand new save file).
3962
+ */
3963
+ export declare function doesCharacterStartWithActiveItem(character: PlayerType): boolean;
3964
+
3965
3965
  /**
3966
3966
  * Helper function to check if one or more of a specific kind of entity is present in the current
3967
3967
  * room. It uses the `countEntities` helper function to determine this.
@@ -6345,6 +6345,18 @@ export declare function getLowestArrayElement(array: readonly number[]): number
6345
6345
  */
6346
6346
  export declare function getLowestEnumValue<T extends TranspiledEnum>(transpiledEnum: T): T[keyof T];
6347
6347
 
6348
+ /**
6349
+ * Helper function to get the "main" version of the character. In other words, this is the character
6350
+ * that selectable from the main menu (and has achievements related to completing the various bosses
6351
+ * and so on).
6352
+ *
6353
+ * For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
6354
+ * (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
6355
+ *
6356
+ * For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
6357
+ */
6358
+ export declare function getMainCharacter(character: PlayerType): PlayerType | undefined;
6359
+
6348
6360
  /**
6349
6361
  * Helper function to get the closest key from a map based on partial search text. (It only searches
6350
6362
  * through the keys, not the values.)
@@ -9766,7 +9778,7 @@ export declare function isLuaDebugEnabled(): boolean;
9766
9778
  * Helper function to check if the provided character is one of the characters that are selectable
9767
9779
  * from the main menu (and have achievements related to completing the various bosses and so on).
9768
9780
  */
9769
- export declare function isMainCharacter(character: PlayerType): boolean;
9781
+ export declare function isMainCharacter(character: PlayerType): character is MainCharacter;
9770
9782
 
9771
9783
  /**
9772
9784
  * Helper function to check if the provided door is the one that leads to the Mega Satan Boss Room.
@@ -10972,6 +10984,8 @@ export declare type LowercaseKeys<T> = StartsWithLowercase<keyof T>;
10972
10984
  */
10973
10985
  export declare const MAIN_CHARACTERS: readonly [PlayerType.ISAAC, PlayerType.MAGDALENE, PlayerType.CAIN, PlayerType.JUDAS, PlayerType.BLUE_BABY, PlayerType.EVE, PlayerType.SAMSON, PlayerType.AZAZEL, PlayerType.LAZARUS, PlayerType.EDEN, PlayerType.LOST, PlayerType.LILITH, PlayerType.KEEPER, PlayerType.APOLLYON, PlayerType.FORGOTTEN, PlayerType.BETHANY, PlayerType.JACOB, PlayerType.ISAAC_B, PlayerType.MAGDALENE_B, PlayerType.CAIN_B, PlayerType.JUDAS_B, PlayerType.BLUE_BABY_B, PlayerType.EVE_B, PlayerType.SAMSON_B, PlayerType.AZAZEL_B, PlayerType.LAZARUS_B, PlayerType.EDEN_B, PlayerType.LOST_B, PlayerType.LILITH_B, PlayerType.KEEPER_B, PlayerType.APOLLYON_B, PlayerType.FORGOTTEN_B, PlayerType.BETHANY_B, PlayerType.JACOB_B];
10974
10986
 
10987
+ declare type MainCharacter = (typeof MAIN_CHARACTERS)[number];
10988
+
10975
10989
  /**
10976
10990
  * Helper function for non-TypeScript users to convert all of the elements in an array to something
10977
10991
  * else.
@@ -1,6 +1,6 @@
1
1
  --[[
2
2
 
3
- isaacscript-common 84.2.4
3
+ isaacscript-common 84.2.5
4
4
 
5
5
  This is the "isaacscript-common" library, which was created with the IsaacScript tool.
6
6
 
@@ -22287,6 +22287,7 @@ return ____exports
22287
22287
  local ____lualib = require("lualib_bundle")
22288
22288
  local __TS__New = ____lualib.__TS__New
22289
22289
  local ____exports = {}
22290
+ local MAIN_CHARACTERS_SET
22290
22291
  local ____isaac_2Dtypescript_2Ddefinitions = require("lua_modules.isaac-typescript-definitions.dist.index")
22291
22292
  local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
22292
22293
  local ____constants = require("core.constants")
@@ -22318,6 +22319,11 @@ local ____lostStyleCharactersSet = require("sets.lostStyleCharactersSet")
22318
22319
  local LOST_STYLE_CHARACTERS_SET = ____lostStyleCharactersSet.LOST_STYLE_CHARACTERS_SET
22319
22320
  local ____ReadonlySet = require("types.ReadonlySet")
22320
22321
  local ReadonlySet = ____ReadonlySet.ReadonlySet
22322
+ --- Helper function to check if the provided character is one of the characters that are selectable
22323
+ -- from the main menu (and have achievements related to completing the various bosses and so on).
22324
+ function ____exports.isMainCharacter(self, character)
22325
+ return MAIN_CHARACTERS_SET:has(character)
22326
+ end
22321
22327
  function ____exports.isModdedCharacter(self, character)
22322
22328
  return not ____exports.isVanillaCharacter(nil, character)
22323
22329
  end
@@ -22325,37 +22331,37 @@ function ____exports.isVanillaCharacter(self, character)
22325
22331
  return character <= LAST_VANILLA_CHARACTER
22326
22332
  end
22327
22333
  local FLYING_CHARACTERS_SET = __TS__New(ReadonlySet, FLYING_CHARACTERS)
22328
- local MAIN_CHARACTERS_SET = __TS__New(ReadonlySet, MAIN_CHARACTERS)
22334
+ MAIN_CHARACTERS_SET = __TS__New(ReadonlySet, MAIN_CHARACTERS)
22329
22335
  local PNG_PATH_PREFIX = "characters/costumes"
22336
+ --- Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
22337
+ -- but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
22338
+ -- Otherwise, returns false.
22339
+ function ____exports.canCharacterGetBlackHeartFromEternalHeart(self, character)
22340
+ return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET:has(character)
22341
+ end
22330
22342
  --- Helper function to determine if the given character can have red heart containers. Returns true
22331
22343
  -- for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
22332
22344
  -- though coin containers are not technically the same as red heart containers. Returns false for
22333
22345
  -- characters like Blue Baby. Returns false for The Lost and Tainted Lost.
22334
- function ____exports.characterCanHaveRedHearts(self, character)
22346
+ function ____exports.canCharacterHaveRedHearts(self, character)
22335
22347
  return not CHARACTERS_WITH_NO_RED_HEARTS_SET:has(character)
22336
22348
  end
22337
22349
  --- Helper function to determine if the given character can have soul hearts. Returns true for
22338
22350
  -- characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
22339
22351
  -- false for The Lost and Tainted Lost.
22340
- function ____exports.characterCanHaveSoulHearts(self, character)
22352
+ function ____exports.canCharacterHaveSoulHearts(self, character)
22341
22353
  return not CHARACTERS_WITH_NO_SOUL_HEARTS_SET:has(character)
22342
22354
  end
22343
22355
  --- Helper function for determining whether the given character can take free Devil Deals. (e.g. The
22344
22356
  -- Lost, Tainted Lost, etc.)
22345
- function ____exports.characterCanTakeFreeDevilDeals(self, character)
22357
+ function ____exports.canCharacterTakeFreeDevilDeals(self, character)
22346
22358
  return CHARACTERS_WITH_FREE_DEVIL_DEALS_SET:has(character)
22347
22359
  end
22348
- --- Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
22349
- -- but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
22350
- -- Otherwise, returns false.
22351
- function ____exports.characterGetsBlackHeartFromEternalHeart(self, character)
22352
- return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET:has(character)
22353
- end
22354
22360
  --- Helper function to determine if the specified character starts with an active item.
22355
22361
  --
22356
22362
  -- For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
22357
22363
  -- is considered to starts with the D6, but this is not the case on a brand new save file).
22358
- function ____exports.characterStartsWithActiveItem(self, character)
22364
+ function ____exports.doesCharacterStartWithActiveItem(self, character)
22359
22365
  return CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET:has(character)
22360
22366
  end
22361
22367
  --- Helper function to get the numerical damage multiplier for a character.
@@ -22433,14 +22439,73 @@ end
22433
22439
  function ____exports.getCharacterStartingTrinketType(self, character)
22434
22440
  return CHARACTER_STARTING_TRINKET_TYPE[character]
22435
22441
  end
22442
+ --- Helper function to get the "main" version of the character. In other words, this is the character
22443
+ -- that selectable from the main menu (and has achievements related to completing the various bosses
22444
+ -- and so on).
22445
+ --
22446
+ -- For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
22447
+ -- (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
22448
+ --
22449
+ -- For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
22450
+ function ____exports.getMainCharacter(self, character)
22451
+ if ____exports.isMainCharacter(nil, character) or ____exports.isModdedCharacter(nil, character) then
22452
+ return character
22453
+ end
22454
+ repeat
22455
+ local ____switch24 = character
22456
+ local ____cond24 = ____switch24 == PlayerType.POSSESSOR
22457
+ if ____cond24 then
22458
+ do
22459
+ return PlayerType.POSSESSOR
22460
+ end
22461
+ end
22462
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2
22463
+ if ____cond24 then
22464
+ do
22465
+ return PlayerType.LAZARUS
22466
+ end
22467
+ end
22468
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.DARK_JUDAS
22469
+ if ____cond24 then
22470
+ do
22471
+ return PlayerType.JUDAS
22472
+ end
22473
+ end
22474
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL
22475
+ if ____cond24 then
22476
+ do
22477
+ return PlayerType.FORGOTTEN
22478
+ end
22479
+ end
22480
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.ESAU
22481
+ if ____cond24 then
22482
+ do
22483
+ return PlayerType.JACOB
22484
+ end
22485
+ end
22486
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.LAZARUS_2_B
22487
+ if ____cond24 then
22488
+ do
22489
+ return PlayerType.LAZARUS_2
22490
+ end
22491
+ end
22492
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.JACOB_2_B
22493
+ if ____cond24 then
22494
+ do
22495
+ return PlayerType.JACOB_B
22496
+ end
22497
+ end
22498
+ ____cond24 = ____cond24 or ____switch24 == PlayerType.SOUL_B
22499
+ if ____cond24 then
22500
+ do
22501
+ return PlayerType.FORGOTTEN_B
22502
+ end
22503
+ end
22504
+ until true
22505
+ end
22436
22506
  function ____exports.isFlyingCharacter(self, character)
22437
22507
  return FLYING_CHARACTERS_SET:has(character)
22438
22508
  end
22439
- --- Helper function to check if the provided character is one of the characters that are selectable
22440
- -- from the main menu (and have achievements related to completing the various bosses and so on).
22441
- function ____exports.isMainCharacter(self, character)
22442
- return MAIN_CHARACTERS_SET:has(character)
22443
- end
22444
22509
  return ____exports
22445
22510
  end,
22446
22511
  ["functions.players"] = function(...)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "84.2.5",
3
+ "version": "84.3.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -121,7 +121,7 @@ export const NUM_NORMAL_PILL_COLORS =
121
121
  /** Equal to `PlayerType.ISAAC` (0). */
122
122
  export const FIRST_CHARACTER = PlayerType.ISAAC;
123
123
 
124
- // It is not possible to determine "LAST_PLAYER_TYPE", since there is no associated config.
124
+ // It is not possible to determine "LAST_CHARACTER", since there is no associated config.
125
125
 
126
126
  /** Calculated from the `PlayerType` enum. */
127
127
  export const LAST_VANILLA_CHARACTER = getHighestEnumValue(PlayerType);
@@ -18,18 +18,31 @@ import { CHARACTERS_WITH_NO_SOUL_HEARTS_SET } from "../sets/charactersWithNoSoul
18
18
  import { LOST_STYLE_CHARACTERS_SET } from "../sets/lostStyleCharactersSet";
19
19
  import { ReadonlySet } from "../types/ReadonlySet";
20
20
 
21
+ type MainCharacter = (typeof MAIN_CHARACTERS)[number];
22
+
21
23
  const FLYING_CHARACTERS_SET = new ReadonlySet<PlayerType>(FLYING_CHARACTERS);
22
24
  const MAIN_CHARACTERS_SET = new ReadonlySet<PlayerType>(MAIN_CHARACTERS);
23
25
 
24
26
  const PNG_PATH_PREFIX = "characters/costumes";
25
27
 
28
+ /**
29
+ * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
30
+ * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
31
+ * Otherwise, returns false.
32
+ */
33
+ export function canCharacterGetBlackHeartFromEternalHeart(
34
+ character: PlayerType,
35
+ ): boolean {
36
+ return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET.has(character);
37
+ }
38
+
26
39
  /**
27
40
  * Helper function to determine if the given character can have red heart containers. Returns true
28
41
  * for characters like Isaac, Magdalene, or Cain. Returns true for Keeper and Tainted Keeper, even
29
42
  * though coin containers are not technically the same as red heart containers. Returns false for
30
43
  * characters like Blue Baby. Returns false for The Lost and Tainted Lost.
31
44
  */
32
- export function characterCanHaveRedHearts(character: PlayerType): boolean {
45
+ export function canCharacterHaveRedHearts(character: PlayerType): boolean {
33
46
  return !CHARACTERS_WITH_NO_RED_HEARTS_SET.has(character);
34
47
  }
35
48
 
@@ -38,7 +51,7 @@ export function characterCanHaveRedHearts(character: PlayerType): boolean {
38
51
  * characters like Isaac, Magdalene, or Cain. Returns false for characters like Bethany. Returns
39
52
  * false for The Lost and Tainted Lost.
40
53
  */
41
- export function characterCanHaveSoulHearts(character: PlayerType): boolean {
54
+ export function canCharacterHaveSoulHearts(character: PlayerType): boolean {
42
55
  return !CHARACTERS_WITH_NO_SOUL_HEARTS_SET.has(character);
43
56
  }
44
57
 
@@ -46,28 +59,19 @@ export function characterCanHaveSoulHearts(character: PlayerType): boolean {
46
59
  * Helper function for determining whether the given character can take free Devil Deals. (e.g. The
47
60
  * Lost, Tainted Lost, etc.)
48
61
  */
49
- export function characterCanTakeFreeDevilDeals(character: PlayerType): boolean {
62
+ export function canCharacterTakeFreeDevilDeals(character: PlayerType): boolean {
50
63
  return CHARACTERS_WITH_FREE_DEVIL_DEALS_SET.has(character);
51
64
  }
52
65
 
53
- /**
54
- * Normally, characters get a red heart container upon reaching a new floor with an eternal heart,
55
- * but some characters grant a black heart instead. Returns true for Dark Judas and Tainted Judas.
56
- * Otherwise, returns false.
57
- */
58
- export function characterGetsBlackHeartFromEternalHeart(
59
- character: PlayerType,
60
- ): boolean {
61
- return CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET.has(character);
62
- }
63
-
64
66
  /**
65
67
  * Helper function to determine if the specified character starts with an active item.
66
68
  *
67
69
  * For the purposes of this function, the save file is considered to be fully unlocked (e.g. Isaac
68
70
  * is considered to starts with the D6, but this is not the case on a brand new save file).
69
71
  */
70
- export function characterStartsWithActiveItem(character: PlayerType): boolean {
72
+ export function doesCharacterStartWithActiveItem(
73
+ character: PlayerType,
74
+ ): boolean {
71
75
  return CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET.has(character);
72
76
  }
73
77
 
@@ -181,6 +185,66 @@ export function getCharacterStartingTrinketType(
181
185
  return CHARACTER_STARTING_TRINKET_TYPE[character];
182
186
  }
183
187
 
188
+ /**
189
+ * Helper function to get the "main" version of the character. In other words, this is the character
190
+ * that selectable from the main menu (and has achievements related to completing the various bosses
191
+ * and so on).
192
+ *
193
+ * For example, the main character for `PlayerType.MAGDALENE` (1) is also `PlayerType.MAGDALENE`
194
+ * (1), but the main character for `PlayerType.LAZARUS_2` (11) would be `PlayerType.LAZARUS` (8).
195
+ *
196
+ * For `PlayerType.POSSESSOR` (-1) and modded characters, the same character will be returned.
197
+ */
198
+ export function getMainCharacter(
199
+ character: PlayerType,
200
+ ): PlayerType | undefined {
201
+ if (isMainCharacter(character) || isModdedCharacter(character)) {
202
+ return character;
203
+ }
204
+
205
+ switch (character) {
206
+ // -1
207
+ case PlayerType.POSSESSOR: {
208
+ return PlayerType.POSSESSOR;
209
+ }
210
+
211
+ // 11
212
+ case PlayerType.LAZARUS_2: {
213
+ return PlayerType.LAZARUS;
214
+ }
215
+
216
+ // 12
217
+ case PlayerType.DARK_JUDAS: {
218
+ return PlayerType.JUDAS;
219
+ }
220
+
221
+ // 17
222
+ case PlayerType.SOUL: {
223
+ return PlayerType.FORGOTTEN;
224
+ }
225
+
226
+ // 20
227
+ case PlayerType.ESAU: {
228
+ return PlayerType.JACOB;
229
+ }
230
+
231
+ // 38
232
+ case PlayerType.LAZARUS_2_B: {
233
+ return PlayerType.LAZARUS_2;
234
+ }
235
+
236
+ // 39
237
+ case PlayerType.JACOB_2_B: {
238
+ return PlayerType.JACOB_B;
239
+ }
240
+
241
+ // 40
242
+ case PlayerType.SOUL_B: {
243
+ return PlayerType.FORGOTTEN_B;
244
+ }
245
+ }
246
+ }
247
+
184
248
  export function isFlyingCharacter(character: PlayerType): boolean {
185
249
  return FLYING_CHARACTERS_SET.has(character);
186
250
  }
@@ -189,7 +253,9 @@ export function isFlyingCharacter(character: PlayerType): boolean {
189
253
  * Helper function to check if the provided character is one of the characters that are selectable
190
254
  * from the main menu (and have achievements related to completing the various bosses and so on).
191
255
  */
192
- export function isMainCharacter(character: PlayerType): boolean {
256
+ export function isMainCharacter(
257
+ character: PlayerType,
258
+ ): character is MainCharacter {
193
259
  return MAIN_CHARACTERS_SET.has(character);
194
260
  }
195
261