isaacscript-common 40.0.0 → 41.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/index.rollup.d.ts +364 -334
  2. package/dist/isaacscript-common.lua +379 -378
  3. package/dist/src/classes/features/other/FlyingDetection.lua +2 -2
  4. package/dist/src/classes/features/other/ItemPoolDetection.lua +2 -2
  5. package/dist/src/classes/features/other/ModdedElementDetection.d.ts +0 -86
  6. package/dist/src/classes/features/other/ModdedElementDetection.d.ts.map +1 -1
  7. package/dist/src/classes/features/other/ModdedElementDetection.lua +1 -57
  8. package/dist/src/classes/features/other/ModdedElementSets.d.ts +250 -210
  9. package/dist/src/classes/features/other/ModdedElementSets.d.ts.map +1 -1
  10. package/dist/src/classes/features/other/ModdedElementSets.lua +285 -284
  11. package/dist/src/core/constants.d.ts +17 -2
  12. package/dist/src/core/constants.d.ts.map +1 -1
  13. package/dist/src/core/constants.lua +8 -1
  14. package/dist/src/core/constantsFirstLast.d.ts +5 -0
  15. package/dist/src/core/constantsFirstLast.d.ts.map +1 -1
  16. package/dist/src/core/constantsVanilla.d.ts +93 -0
  17. package/dist/src/core/constantsVanilla.d.ts.map +1 -0
  18. package/dist/src/core/constantsVanilla.lua +115 -0
  19. package/dist/src/core/upgradeMod.lua +3 -0
  20. package/dist/src/functions/cards.d.ts +0 -7
  21. package/dist/src/functions/cards.d.ts.map +1 -1
  22. package/dist/src/functions/cards.lua +0 -10
  23. package/dist/src/functions/collectibles.d.ts +0 -10
  24. package/dist/src/functions/collectibles.d.ts.map +1 -1
  25. package/dist/src/functions/collectibles.lua +0 -13
  26. package/dist/src/functions/dimensions.d.ts +0 -4
  27. package/dist/src/functions/dimensions.d.ts.map +1 -1
  28. package/dist/src/functions/dimensions.lua +2 -8
  29. package/dist/src/functions/pills.d.ts +0 -2
  30. package/dist/src/functions/pills.d.ts.map +1 -1
  31. package/dist/src/functions/pills.lua +0 -5
  32. package/dist/src/functions/rooms.lua +2 -2
  33. package/dist/src/functions/trinkets.d.ts +0 -9
  34. package/dist/src/functions/trinkets.d.ts.map +1 -1
  35. package/dist/src/functions/trinkets.lua +0 -12
  36. package/dist/src/index.d.ts +1 -0
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.lua +8 -0
  39. package/package.json +1 -1
  40. package/src/classes/features/other/FlyingDetection.ts +2 -2
  41. package/src/classes/features/other/ItemPoolDetection.ts +2 -2
  42. package/src/classes/features/other/ModdedElementDetection.ts +4 -156
  43. package/src/classes/features/other/ModdedElementSets.ts +552 -486
  44. package/src/core/constants.ts +15 -2
  45. package/src/core/constantsFirstLast.ts +5 -1
  46. package/src/core/constantsVanilla.ts +183 -0
  47. package/src/core/upgradeMod.ts +6 -1
  48. package/src/functions/cards.ts +1 -15
  49. package/src/functions/collectibles.ts +1 -18
  50. package/src/functions/dimensions.ts +2 -10
  51. package/src/functions/pills.ts +0 -6
  52. package/src/functions/rooms.ts +3 -3
  53. package/src/functions/trinkets.ts +1 -17
  54. package/src/index.ts +1 -0
@@ -1,3 +1,4 @@
1
+ import type { PillEffect } from "isaac-typescript-definitions";
1
2
  import {
2
3
  CacheFlag,
3
4
  CardType,
@@ -14,16 +15,18 @@ import {
14
15
  } from "../../../arrays/cachedEnumValues";
15
16
  import { itemConfig } from "../../../core/cachedClasses";
16
17
  import { FIRST_GLITCHED_COLLECTIBLE_TYPE } from "../../../core/constants";
18
+ import {
19
+ VANILLA_CARD_TYPES,
20
+ VANILLA_COLLECTIBLE_TYPES,
21
+ VANILLA_PILL_EFFECTS,
22
+ VANILLA_TRINKET_TYPES,
23
+ } from "../../../core/constantsVanilla";
17
24
  import { Exported } from "../../../decorators";
18
25
  import { ISCFeature } from "../../../enums/ISCFeature";
19
- import {
20
- getItemConfigCardType,
21
- getVanillaCardTypes,
22
- } from "../../../functions/cards";
26
+ import { getItemConfigCardType } from "../../../functions/cards";
23
27
  import { collectibleHasTag } from "../../../functions/collectibleTag";
24
28
  import {
25
29
  collectibleHasCacheFlag,
26
- getVanillaCollectibleTypeRange,
27
30
  isActiveCollectible,
28
31
  isHiddenCollectible,
29
32
  isPassiveCollectible,
@@ -36,11 +39,14 @@ import {
36
39
  getRandomSetElement,
37
40
  getSortedSetValues,
38
41
  } from "../../../functions/set";
42
+ import { trinketHasCacheFlag } from "../../../functions/trinkets";
39
43
  import {
40
- getVanillaTrinketTypeRange,
41
- trinketHasCacheFlag,
42
- } from "../../../functions/trinkets";
43
- import { assertDefined, repeat } from "../../../functions/utils";
44
+ asCardType,
45
+ asCollectibleType,
46
+ asPillEffect,
47
+ asTrinketType,
48
+ } from "../../../functions/types";
49
+ import { assertDefined, iRange, repeat } from "../../../functions/utils";
44
50
  import { ITEM_CONFIG_CARD_TYPES_FOR_CARDS_SET } from "../../../sets/itemConfigCardTypesForCardsSet";
45
51
  import { ReadonlyMap } from "../../../types/ReadonlyMap";
46
52
  import { ReadonlySet } from "../../../types/ReadonlySet";
@@ -71,40 +77,40 @@ const TRANSFORMATION_TO_TAG_MAP = new ReadonlyMap<PlayerForm, ItemConfigTag>([
71
77
  // PlayerForm.STOMPY (13) is based on size.
72
78
  ]);
73
79
 
80
+ /**
81
+ * A feature that lazy-inits and caches various arrays and sets that include both vanilla and modded
82
+ * elements. This is useful for performance purposes (so that we do not have to reconstruct the
83
+ * arrays/sets multiple times).
84
+ *
85
+ * The modded arrays/sets are created using the functions from
86
+ * `ISCFeature.MODDED_ELEMENT_DETECTION`.
87
+ */
74
88
  export class ModdedElementSets extends Feature {
75
89
  private arraysInitialized = false;
76
90
 
77
91
  private readonly allCollectibleTypesArray: CollectibleType[] = [];
78
92
  private readonly allCollectibleTypesSet = new Set<CollectibleType>();
79
93
 
80
- private readonly vanillaCollectibleTypesArray: CollectibleType[] = [];
81
- private readonly vanillaCollectibleTypesSet = new Set<CollectibleType>();
82
-
83
94
  private readonly moddedCollectibleTypesArray: CollectibleType[] = [];
84
95
  private readonly moddedCollectibleTypesSet = new Set<CollectibleType>();
85
96
 
86
97
  private readonly allTrinketTypesArray: TrinketType[] = [];
87
98
  private readonly allTrinketTypesSet = new Set<TrinketType>();
88
99
 
89
- private readonly vanillaTrinketTypesArray: TrinketType[] = [];
90
- private readonly vanillaTrinketTypesSet = new Set<TrinketType>();
91
-
92
100
  private readonly moddedTrinketTypesArray: TrinketType[] = [];
93
101
  private readonly moddedTrinketTypesSet = new Set<TrinketType>();
94
102
 
95
103
  private readonly allCardTypesArray: CardType[] = [];
96
104
  private readonly allCardTypesSet = new Set<CardType>();
97
105
 
98
- private readonly vanillaCardTypesArray: CardType[] = [];
99
- private readonly vanillaCardTypesSet = new Set<CardType>();
100
-
101
106
  private readonly moddedCardTypesArray: CardType[] = [];
102
107
  private readonly moddedCardTypesSet = new Set<CardType>();
103
108
 
104
- private readonly tagToCollectibleTypesMap = new Map<
105
- ItemConfigTag,
106
- Set<CollectibleType>
107
- >();
109
+ private readonly allPillEffectsArray: PillEffect[] = [];
110
+ private readonly allPillEffectsSet = new Set<PillEffect>();
111
+
112
+ private readonly moddedPillEffectsArray: PillEffect[] = [];
113
+ private readonly moddedPillEffectsSet = new Set<PillEffect>();
108
114
 
109
115
  private readonly cacheFlagToCollectibleTypesMap = new Map<
110
116
  CacheFlag,
@@ -121,6 +127,12 @@ export class ModdedElementSets extends Feature {
121
127
  new Set<CollectibleType>();
122
128
 
123
129
  private flyingTrinketTypesSet = new Set<TrinketType>();
130
+
131
+ private readonly tagToCollectibleTypesMap = new Map<
132
+ ItemConfigTag,
133
+ Set<CollectibleType>
134
+ >();
135
+
124
136
  private readonly edenActiveCollectibleTypesSet = new Set<CollectibleType>();
125
137
  private readonly edenPassiveCollectibleTypesSet = new Set<CollectibleType>();
126
138
 
@@ -130,7 +142,7 @@ export class ModdedElementSets extends Feature {
130
142
  >();
131
143
 
132
144
  /**
133
- * The set of cards that are not:
145
+ * The set of card types that are not:
134
146
  *
135
147
  * - ItemConfigCardType.RUNE
136
148
  * - ItemConfigCardType.SPECIAL_OBJECT
@@ -154,12 +166,10 @@ export class ModdedElementSets extends Feature {
154
166
  }
155
167
  this.arraysInitialized = true;
156
168
 
157
- this.lazyInitVanillaCollectibleTypes();
158
169
  this.lazyInitModdedCollectibleTypes();
159
- this.lazyInitVanillaTrinketTypes();
160
170
  this.lazyInitModdedTrinketTypes();
161
- this.lazyInitVanillaCardTypes();
162
171
  this.lazyInitModdedCardTypes();
172
+ this.lazyInitModdedPillEffects();
163
173
  this.lazyInitTagToCollectibleTypesMap();
164
174
  this.lazyInitCacheFlagToCollectibleTypesMap();
165
175
  this.lazyInitCacheFlagToTrinketTypesMap();
@@ -169,33 +179,28 @@ export class ModdedElementSets extends Feature {
169
179
  this.lazyInitCardTypes();
170
180
  }
171
181
 
172
- private lazyInitVanillaCollectibleTypes() {
173
- if (this.vanillaCollectibleTypesArray.length > 0) {
174
- return;
175
- }
176
-
177
- const vanillaCollectibleTypeRange = getVanillaCollectibleTypeRange();
178
- for (const collectibleType of vanillaCollectibleTypeRange) {
179
- // Vanilla collectible types are not contiguous, so we must check every value. (There are
180
- // several gaps, e.g. 666.)
181
- const itemConfigItem = itemConfig.GetCollectible(collectibleType);
182
- if (itemConfigItem !== undefined) {
183
- this.vanillaCollectibleTypesArray.push(collectibleType);
184
- this.vanillaCollectibleTypesSet.add(collectibleType);
185
- }
186
- }
187
- }
188
-
189
182
  private lazyInitModdedCollectibleTypes() {
190
- for (const collectibleType of this.vanillaCollectibleTypesArray) {
183
+ for (const collectibleType of VANILLA_COLLECTIBLE_TYPES) {
191
184
  this.allCollectibleTypesArray.push(collectibleType);
192
185
  this.allCollectibleTypesSet.add(collectibleType);
193
186
  }
194
187
 
195
- const moddedCollectibleTypes =
196
- this.moddedElementDetection.getModdedCollectibleTypes();
197
- for (const collectibleType of moddedCollectibleTypes) {
188
+ const firstModdedCollectibleType =
189
+ this.moddedElementDetection.getFirstModdedCollectibleType();
190
+ if (firstModdedCollectibleType === undefined) {
191
+ return;
192
+ }
193
+
194
+ const lastCollectibleType =
195
+ this.moddedElementDetection.getLastCollectibleType();
196
+ const moddedCollectibleTypes = iRange(
197
+ firstModdedCollectibleType,
198
+ lastCollectibleType,
199
+ );
200
+
201
+ for (const collectibleTypeInt of moddedCollectibleTypes) {
198
202
  // Modded collectible types are contiguous, but we check every value just in case.
203
+ const collectibleType = asCollectibleType(collectibleTypeInt);
199
204
  const itemConfigItem = itemConfig.GetCollectible(collectibleType);
200
205
  if (itemConfigItem !== undefined) {
201
206
  this.moddedCollectibleTypesArray.push(collectibleType);
@@ -207,33 +212,24 @@ export class ModdedElementSets extends Feature {
207
212
  }
208
213
  }
209
214
 
210
- private lazyInitVanillaTrinketTypes() {
211
- if (this.vanillaTrinketTypesArray.length > 0) {
212
- return;
213
- }
214
-
215
- const vanillaTrinketTypeRange = getVanillaTrinketTypeRange();
216
- for (const trinketType of vanillaTrinketTypeRange) {
217
- // Vanilla trinket types are not contiguous, so we must check every value. (The only gap is 47
218
- // for `POLAROID_OBSOLETE`.)
219
- const itemConfigItem = itemConfig.GetTrinket(trinketType);
220
- if (itemConfigItem !== undefined) {
221
- this.vanillaTrinketTypesArray.push(trinketType);
222
- this.vanillaTrinketTypesSet.add(trinketType);
223
- }
224
- }
225
- }
226
-
227
215
  private lazyInitModdedTrinketTypes() {
228
- for (const trinketType of this.vanillaTrinketTypesArray) {
216
+ for (const trinketType of VANILLA_TRINKET_TYPES) {
229
217
  this.allTrinketTypesArray.push(trinketType);
230
218
  this.allTrinketTypesSet.add(trinketType);
231
219
  }
232
220
 
233
- const moddedTrinketTypes =
234
- this.moddedElementDetection.getModdedTrinketTypes();
235
- for (const trinketType of moddedTrinketTypes) {
221
+ const firstModdedTrinketType =
222
+ this.moddedElementDetection.getFirstModdedTrinketType();
223
+ if (firstModdedTrinketType === undefined) {
224
+ return;
225
+ }
226
+
227
+ const lastTrinketType = this.moddedElementDetection.getLastTrinketType();
228
+ const moddedTrinketTypes = iRange(firstModdedTrinketType, lastTrinketType);
229
+
230
+ for (const trinketTypeInt of moddedTrinketTypes) {
236
231
  // Modded trinket types are contiguous, but we check every value just in case.
232
+ const trinketType = asTrinketType(trinketTypeInt);
237
233
  const itemConfigItem = itemConfig.GetTrinket(trinketType);
238
234
  if (itemConfigItem !== undefined) {
239
235
  this.moddedTrinketTypesArray.push(trinketType);
@@ -245,33 +241,24 @@ export class ModdedElementSets extends Feature {
245
241
  }
246
242
  }
247
243
 
248
- private lazyInitVanillaCardTypes() {
249
- if (this.vanillaCardTypesArray.length > 0) {
250
- return;
251
- }
252
-
253
- const vanillaCardTypes = getVanillaCardTypes();
254
- for (const cardType of vanillaCardTypes) {
255
- // Vanilla card types are contiguous, but we check every value just to be safe (and so that
256
- // the code is similar to the collectible and trinket functions above).
257
- const itemConfigCard = itemConfig.GetCard(cardType);
258
- if (itemConfigCard !== undefined) {
259
- this.vanillaCardTypesArray.push(cardType);
260
- this.vanillaCardTypesSet.add(cardType);
261
- }
262
- }
263
- }
264
-
265
244
  private lazyInitModdedCardTypes() {
266
- for (const cardType of this.vanillaCardTypesArray) {
245
+ for (const cardType of VANILLA_CARD_TYPES) {
267
246
  this.allCardTypesArray.push(cardType);
268
247
  this.allCardTypesSet.add(cardType);
269
248
  }
270
249
 
271
- const moddedCardTypes = this.moddedElementDetection.getModdedCardTypes();
272
- for (const cardType of moddedCardTypes) {
273
- // Modded card types are contiguous, but we check every value just to be safe (and so that the
274
- // code is similar to the collectible and trinket functions above).
250
+ const firstModdedCardType =
251
+ this.moddedElementDetection.getFirstModdedCardType();
252
+ if (firstModdedCardType === undefined) {
253
+ return;
254
+ }
255
+
256
+ const lastCardType = this.moddedElementDetection.getLastCardType();
257
+ const moddedCardTypes = iRange(firstModdedCardType, lastCardType);
258
+
259
+ for (const cardTypeInt of moddedCardTypes) {
260
+ // Modded card types are contiguous, but we check every value just in case.
261
+ const cardType = asCardType(cardTypeInt);
275
262
  const itemConfigCard = itemConfig.GetCard(cardType);
276
263
  if (itemConfigCard !== undefined) {
277
264
  this.moddedCardTypesArray.push(cardType);
@@ -283,6 +270,35 @@ export class ModdedElementSets extends Feature {
283
270
  }
284
271
  }
285
272
 
273
+ private lazyInitModdedPillEffects() {
274
+ for (const pillEffect of VANILLA_PILL_EFFECTS) {
275
+ this.allPillEffectsArray.push(pillEffect);
276
+ this.allPillEffectsSet.add(pillEffect);
277
+ }
278
+
279
+ const firstModdedPillEffect =
280
+ this.moddedElementDetection.getFirstModdedPillEffect();
281
+ if (firstModdedPillEffect === undefined) {
282
+ return;
283
+ }
284
+
285
+ const lastPillEffect = this.moddedElementDetection.getLastPillEffect();
286
+ const moddedPillEffects = iRange(firstModdedPillEffect, lastPillEffect);
287
+
288
+ for (const pillEffectInt of moddedPillEffects) {
289
+ // Modded pill effects are contiguous, but we check every value just in case.
290
+ const pillEffect = asPillEffect(pillEffectInt);
291
+ const itemConfigPillEffect = itemConfig.GetPillEffect(pillEffect);
292
+ if (itemConfigPillEffect !== undefined) {
293
+ this.moddedPillEffectsArray.push(pillEffect);
294
+ this.moddedPillEffectsSet.add(pillEffect);
295
+
296
+ this.allPillEffectsArray.push(pillEffect);
297
+ this.allPillEffectsSet.add(pillEffect);
298
+ }
299
+ }
300
+ }
301
+
286
302
  private lazyInitTagToCollectibleTypesMap() {
287
303
  // The tag to collectible types map should be valid for every tag, so we initialize it with
288
304
  // empty sets.
@@ -290,7 +306,7 @@ export class ModdedElementSets extends Feature {
290
306
  this.tagToCollectibleTypesMap.set(itemConfigTag, new Set());
291
307
  }
292
308
 
293
- for (const collectibleType of this.getCollectibleArray()) {
309
+ for (const collectibleType of this.getCollectibleTypes()) {
294
310
  for (const itemConfigTag of ITEM_CONFIG_TAG_VALUES) {
295
311
  if (!collectibleHasTag(collectibleType, itemConfigTag)) {
296
312
  continue;
@@ -313,7 +329,7 @@ export class ModdedElementSets extends Feature {
313
329
  for (const cacheFlag of CACHE_FLAG_VALUES) {
314
330
  const collectiblesSet = new Set<CollectibleType>();
315
331
 
316
- for (const collectibleType of this.getCollectibleArray()) {
332
+ for (const collectibleType of this.getCollectibleTypes()) {
317
333
  if (collectibleHasCacheFlag(collectibleType, cacheFlag)) {
318
334
  collectiblesSet.add(collectibleType);
319
335
  }
@@ -327,7 +343,7 @@ export class ModdedElementSets extends Feature {
327
343
  for (const cacheFlag of CACHE_FLAG_VALUES) {
328
344
  const trinketsSet = new Set<TrinketType>();
329
345
 
330
- for (const trinketType of this.getTrinketArray()) {
346
+ for (const trinketType of this.getTrinketTypes()) {
331
347
  if (trinketHasCacheFlag(trinketType, cacheFlag)) {
332
348
  trinketsSet.add(trinketType);
333
349
  }
@@ -341,13 +357,13 @@ export class ModdedElementSets extends Feature {
341
357
  // Instead of manually compiling a list of collectibles that grant flying, we can instead
342
358
  // dynamically look for collectibles that have `CacheFlag.FLYING`.
343
359
  this.flyingCollectibleTypesSet = copySet(
344
- this.getCollectiblesWithCacheFlag(CacheFlag.FLYING),
360
+ this.getCollectibleTypesWithCacheFlag(CacheFlag.FLYING),
345
361
  );
346
362
 
347
363
  // None of the collectibles with a cache of "all" grant flying (including all of the 3 Dollar
348
364
  // Bill collectibles and all of the Birthright effects), so we can safely remove them from the
349
365
  // list.
350
- const collectiblesWithAllCacheFlag = this.getCollectiblesWithCacheFlag(
366
+ const collectiblesWithAllCacheFlag = this.getCollectibleTypesWithCacheFlag(
351
367
  CacheFlag.ALL,
352
368
  );
353
369
  deleteSetsFromSet(
@@ -372,20 +388,20 @@ export class ModdedElementSets extends Feature {
372
388
  // Instead of manually compiling a list of trinkets that grant flying, we can instead
373
389
  // dynamically look for collectibles that have `CacheFlag.FLYING`.
374
390
  this.flyingTrinketTypesSet = copySet(
375
- this.getTrinketsWithCacheFlag(CacheFlag.FLYING),
391
+ this.getTrinketsTypesWithCacheFlag(CacheFlag.FLYING),
376
392
  );
377
393
 
378
- // None of the collectibles with a cache of "all" grant flying except for Azazel's Stump, so we
379
- // can safely remove them from the list.
394
+ // None of the trinkets with `CacheFlag.ALL` grant flying except for Azazel's Stump, so we can
395
+ // safely remove them from the list.
380
396
  const trinketsWithAllCacheFlag = copySet(
381
- this.getTrinketsWithCacheFlag(CacheFlag.ALL),
397
+ this.getTrinketsTypesWithCacheFlag(CacheFlag.ALL),
382
398
  );
383
399
  trinketsWithAllCacheFlag.delete(TrinketType.AZAZELS_STUMP);
384
400
  deleteSetsFromSet(this.flyingTrinketTypesSet, trinketsWithAllCacheFlag);
385
401
  }
386
402
 
387
403
  private lazyInitEdenCollectibleTypesSet() {
388
- for (const collectibleType of this.getCollectibleArray()) {
404
+ for (const collectibleType of this.getCollectibleTypes()) {
389
405
  if (
390
406
  isHiddenCollectible(collectibleType) ||
391
407
  collectibleHasTag(collectibleType, ItemConfigTag.NO_EDEN)
@@ -413,7 +429,7 @@ export class ModdedElementSets extends Feature {
413
429
  );
414
430
  }
415
431
 
416
- for (const cardType of this.getCardArray()) {
432
+ for (const cardType of this.getCardTypes()) {
417
433
  const itemConfigCardType = getItemConfigCardType(cardType);
418
434
  if (itemConfigCardType !== undefined) {
419
435
  const cardTypeSet =
@@ -432,292 +448,262 @@ export class ModdedElementSets extends Feature {
432
448
  }
433
449
  }
434
450
 
435
- // --------------
436
- // Public Methods
437
- // --------------
438
-
439
- /**
440
- * Returns an array containing every valid card type in the game, including modded cards.
441
- *
442
- * Use this if you need to iterate over the cards in order. If you need to do O(1) lookups, then
443
- * use the `getCardSet` helper function instead.
444
- *
445
- * This function can only be called if at least one callback has been executed. This is because
446
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
447
- *
448
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
449
- */
450
- @Exported
451
- public getCardArray(): readonly CardType[] {
452
- this.lazyInit();
453
- return this.allCardTypesArray;
454
- }
451
+ // ------------
452
+ // Collectibles
453
+ // ------------
455
454
 
456
455
  /**
457
- * Returns a set containing every valid card type in the game, including modded cards.
456
+ * Returns an array containing every valid collectible type in the game, including modded
457
+ * collectibles.
458
458
  *
459
- * Use this if you need to do O(1) lookups. If you need to iterate over the cards in order, then
460
- * use the `getCardArray` helper function instead.
459
+ * Use this if you need to iterate over the collectibles in order. If you need to do O(1) lookups,
460
+ * then use the `getCollectibleTypesSet` helper function instead.
461
461
  *
462
462
  * This function can only be called if at least one callback has been executed. This is because
463
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
463
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
464
+ * order).
464
465
  *
465
466
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
466
467
  */
467
468
  @Exported
468
- public getCardSet(): ReadonlySet<CardType> {
469
+ public getCollectibleTypes(): readonly CollectibleType[] {
469
470
  this.lazyInit();
470
- return this.allCardTypesSet;
471
+ return this.allCollectibleTypesArray;
471
472
  }
472
473
 
473
474
  /**
474
- * Helper function to get a set of card types matching the `ItemConfigCardType`.
475
+ * Returns a set containing every valid collectible type in the game, including modded
476
+ * collectibles.
475
477
  *
476
- * This function is variadic, meaning that you can you can specify N card types to get a set
477
- * containing cards that match any of the specified types.
478
+ * Use this if you need to do O(1) lookups. If you need to iterate over the collectibles in order,
479
+ * then use the `getCollectibleTypes` helper function instead.
478
480
  *
479
481
  * This function can only be called if at least one callback has been executed. This is because
480
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
482
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
483
+ * order).
481
484
  *
482
485
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
483
486
  */
484
487
  @Exported
485
- public getCardTypesOfType(
486
- ...itemConfigCardTypes: ItemConfigCardType[]
487
- ): Set<CardType> {
488
+ public getCollectibleTypeSet(): ReadonlySet<CollectibleType> {
488
489
  this.lazyInit();
489
-
490
- const matchingCardTypes = new Set<CardType>();
491
- for (const itemConfigCardType of itemConfigCardTypes) {
492
- const cardTypeSet =
493
- this.itemConfigCardTypeToCardTypeMap.get(itemConfigCardType);
494
- assertDefined(
495
- cardTypeSet,
496
- `Failed to get the card type set for item config type: ${itemConfigCardType}`,
497
- );
498
-
499
- for (const cardType of cardTypeSet) {
500
- matchingCardTypes.add(cardType);
501
- }
502
- }
503
-
504
- return matchingCardTypes;
490
+ return this.allCollectibleTypesSet;
505
491
  }
506
492
 
507
493
  /**
508
- * Returns an array containing every valid collectible type in the game, including modded
509
- * collectibles.
494
+ * Returns an array containing every modded collectible type in the game.
510
495
  *
511
496
  * Use this if you need to iterate over the collectibles in order. If you need to do O(1) lookups,
512
- * then use the `getCollectibleSet` helper function instead.
497
+ * then use the `getModdedCollectibleTypesSet` helper function instead.
513
498
  *
514
499
  * This function can only be called if at least one callback has been executed. This is because
515
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
500
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
516
501
  * order).
517
502
  *
518
503
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
519
504
  */
520
505
  @Exported
521
- public getCollectibleArray(): readonly CollectibleType[] {
506
+ public getModdedCollectibleTypes(): readonly CollectibleType[] {
522
507
  this.lazyInit();
523
- return this.allCollectibleTypesArray;
508
+ return this.moddedCollectibleTypesArray;
524
509
  }
525
510
 
526
511
  /**
527
- * Returns a set containing every valid collectible type in the game, including modded
528
- * collectibles.
512
+ * Returns a set containing every modded collectible type in the game.
529
513
  *
530
514
  * Use this if you need to do O(1) lookups. If you need to iterate over the collectibles in order,
531
- * then use the `getCollectibleArray` helper function instead.
515
+ * then use the `getModdedCollectibleTypes` helper function instead.
532
516
  *
533
517
  * This function can only be called if at least one callback has been executed. This is because
534
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
518
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
535
519
  * order).
536
520
  *
537
521
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
538
522
  */
539
523
  @Exported
540
- public getCollectibleSet(): ReadonlySet<CollectibleType> {
524
+ public getModdedCollectibleTypesSet(): ReadonlySet<CollectibleType> {
541
525
  this.lazyInit();
542
- return this.allCollectibleTypesSet;
526
+ return this.moddedCollectibleTypesSet;
543
527
  }
544
528
 
545
529
  /**
546
- * Helper function to get all of the collectible types in the game that count towards a particular
547
- * transformation.
530
+ * Iterates over every collectible in the game and returns a map containing the number of each
531
+ * item that the player has.
548
532
  *
549
- * For example, to get all of the collectible types that count towards Guppy:
550
- *
551
- * ```ts
552
- * const guppyCollectibleTypes = getCollectiblesForTransformation(PlayerForm.GUPPY);
553
- * ```
533
+ * Note that this will filter out non-real collectibles like Lilith's Incubus.
554
534
  *
555
535
  * This function can only be called if at least one callback has been executed. This is because
556
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
536
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
557
537
  * order).
558
538
  *
559
539
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
560
540
  */
561
541
  @Exported
562
- public getCollectiblesForTransformation(
563
- playerForm: PlayerForm,
564
- ): ReadonlySet<CollectibleType> {
565
- const itemConfigTag = TRANSFORMATION_TO_TAG_MAP.get(playerForm);
566
- assertDefined(
567
- itemConfigTag,
568
- `Failed to get the collectible types for the transformation of ${playerForm} because that transformation is not based on collectibles.`,
569
- );
542
+ public getPlayerCollectibleMap(
543
+ player: EntityPlayer,
544
+ ): Map<CollectibleType, int> {
545
+ const collectibleArray = this.getCollectibleTypes();
546
+
547
+ const collectibleMap = new Map<CollectibleType, int>();
548
+ for (const collectibleType of collectibleArray) {
549
+ // We specify "true" as the second argument to filter out things like Lilith's Incubus.
550
+ const numCollectibles = player.GetCollectibleNum(collectibleType, true);
551
+ if (numCollectibles > 0) {
552
+ collectibleMap.set(collectibleType, numCollectibles);
553
+ }
554
+ }
555
+
556
+ // If the player has TMTRAINER, they might also have glitched items.
557
+ if (player.HasCollectible(CollectibleType.TMTRAINER)) {
558
+ let collectibleType = FIRST_GLITCHED_COLLECTIBLE_TYPE;
559
+ let itemConfigItem: Readonly<ItemConfigItem> | undefined;
560
+ do {
561
+ itemConfigItem = itemConfig.GetCollectible(collectibleType);
570
562
 
571
- return this.getCollectiblesWithTag(itemConfigTag);
563
+ if (itemConfigItem !== undefined) {
564
+ // The `EntityPlayer.GetCollectibleNum` method is bugged with TMTrainer items and will
565
+ // always return 0. To work around this, we simply assume that if the player has the
566
+ // collectible, then they have one copy of the item.
567
+ const hasCollectibles = player.HasCollectible(collectibleType, true);
568
+ if (hasCollectibles) {
569
+ collectibleMap.set(collectibleType, 1);
570
+ }
571
+ }
572
+
573
+ collectibleType--; // eslint-disable-line isaacscript/strict-enums
574
+ } while (itemConfigItem !== undefined);
575
+ }
576
+
577
+ return collectibleMap;
572
578
  }
573
579
 
580
+ // --------
581
+ // Trinkets
582
+ // --------
583
+
574
584
  /**
575
- * Returns a set containing every collectible type with the given cache flag, including modded
576
- * collectibles.
585
+ * Returns an array containing every modded trinket type in the game.
577
586
  *
578
- * This function can only be called if at least one callback has been executed. This is because
579
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
580
- * order).
587
+ * Use this if you need to iterate over the trinkets in order. If you need to do O(1) lookups,
588
+ * then use the `getModdedTrinketTypesSet` helper function instead.
581
589
  *
582
590
  * This function can only be called if at least one callback has been executed. This is because
583
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
591
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
584
592
  * order).
585
593
  *
586
594
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
587
595
  */
588
596
  @Exported
589
- public getCollectiblesWithCacheFlag(
590
- cacheFlag: CacheFlag,
591
- ): ReadonlySet<CollectibleType> {
597
+ public getTrinketTypes(): readonly TrinketType[] {
592
598
  this.lazyInit();
593
-
594
- const collectiblesSet = this.cacheFlagToCollectibleTypesMap.get(cacheFlag);
595
- if (collectiblesSet === undefined) {
596
- return new ReadonlySet();
597
- }
598
-
599
- return collectiblesSet;
599
+ return this.allTrinketTypesArray;
600
600
  }
601
601
 
602
602
  /**
603
- * Returns a set containing every collectible type with the given tag.
604
- *
605
- * For example, to get all of the collectible types that count as offensive for the purposes of
606
- * Tainted Lost:
603
+ * Returns a set containing every modded trinket type in the game.
607
604
  *
608
- * ```ts
609
- * const offensiveCollectibleTypes = getCollectibleTypesWithTag(ItemConfigTag.OFFENSIVE);
610
- * ```
605
+ * Use this if you need to do O(1) lookups. If you need to iterate over the trinkets in order,
606
+ * then use the `getModdedTrinketTypes` helper function instead.
611
607
  *
612
608
  * This function can only be called if at least one callback has been executed. This is because
613
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
609
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
614
610
  * order).
615
611
  *
616
612
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
617
613
  */
618
614
  @Exported
619
- public getCollectiblesWithTag(
620
- itemConfigTag: ItemConfigTag,
621
- ): ReadonlySet<CollectibleType> {
615
+ public getTrinketTypesSet(): ReadonlySet<TrinketType> {
622
616
  this.lazyInit();
623
-
624
- const collectibleTypes = this.tagToCollectibleTypesMap.get(itemConfigTag);
625
- assertDefined(
626
- collectibleTypes,
627
- `The item config tag of ${itemConfigTag} is not a valid value of the "ItemConfigTag" enum.`,
628
- );
629
-
630
- return collectibleTypes;
617
+ return this.allTrinketTypesSet;
631
618
  }
632
619
 
633
620
  /**
634
- * Returns a set containing every valid passive item that can be randomly granted to Eden as a
635
- * starting item.
621
+ * Returns an array containing every modded trinket type in the game.
622
+ *
623
+ * Use this if you need to iterate over the trinkets in order. If you need to do O(1) lookups,
624
+ * then use the `getModdedTrinketTypesSet` helper function instead.
636
625
  *
637
626
  * This function can only be called if at least one callback has been executed. This is because
638
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
627
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
639
628
  * order).
640
629
  *
641
630
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
642
631
  */
643
632
  @Exported
644
- public getEdenActiveCollectibles(): ReadonlySet<CollectibleType> {
633
+ public getModdedTrinketTypes(): readonly TrinketType[] {
645
634
  this.lazyInit();
646
- return this.edenActiveCollectibleTypesSet;
635
+ return this.moddedTrinketTypesArray;
647
636
  }
648
637
 
649
638
  /**
650
- * Returns a set containing every valid passive item that can be randomly granted to Eden as a
651
- * starting item.
639
+ * Returns a set containing every modded trinket type in the game.
640
+ *
641
+ * Use this if you need to do O(1) lookups. If you need to iterate over the trinkets in order,
642
+ * then use the `getModdedTrinketTypes` helper function instead.
652
643
  *
653
644
  * This function can only be called if at least one callback has been executed. This is because
654
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
645
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
655
646
  * order).
656
647
  *
657
648
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
658
649
  */
659
650
  @Exported
660
- public getEdenPassiveCollectibles(): ReadonlySet<CollectibleType> {
651
+ public getModdedTrinketTypesSet(): ReadonlySet<TrinketType> {
661
652
  this.lazyInit();
662
- return this.edenPassiveCollectibleTypesSet;
653
+ return this.moddedTrinketTypesSet;
663
654
  }
664
655
 
656
+ // -----
657
+ // Cards
658
+ // -----
659
+
665
660
  /**
666
- * Returns a set of all of the collectibles that grant flight. This is derived from collectibles
667
- * that have `CacheFlag.FLYING` set in the "items.xml" file.
661
+ * Returns an array containing every valid card type in the game, including modded cards.
668
662
  *
669
- * Collectibles that only grant flight conditionally are manually pruned. Collectibles such as
670
- * Empty Vessel should be checked for via the `hasFlyingTemporaryEffect` function.
663
+ * Use this if you need to iterate over the cards in order. If you need to do O(1) lookups, then
664
+ * use the `getCardTypesSet` helper function instead.
671
665
  *
672
666
  * This function can only be called if at least one callback has been executed. This is because
673
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
674
- * order).
667
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
675
668
  *
676
669
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
677
- *
678
- * @param includeConditionalItems Whether collectibles that only grant flight conditionally should
679
- * be included in the set (like Empty Vessel).
680
670
  */
681
671
  @Exported
682
- public getFlyingCollectibles(
683
- includeConditionalItems: boolean,
684
- ): ReadonlySet<CollectibleType> {
672
+ public getCardTypes(): readonly CardType[] {
685
673
  this.lazyInit();
686
-
687
- return includeConditionalItems
688
- ? this.flyingCollectibleTypesSet
689
- : this.permanentFlyingCollectibleTypesSet;
674
+ return this.allCardTypesArray;
690
675
  }
691
676
 
692
677
  /**
693
- * Returns a set of all of the trinkets that grant flight. (All trinkets that grant flight do so
694
- * conditionally, like Bat Wing and Azazel's Stump.)
678
+ * Returns a set containing every valid card type in the game, including modded cards.
679
+ *
680
+ * Use this if you need to do O(1) lookups. If you need to iterate over the cards in order, then
681
+ * use the `getCardTypes` helper function instead.
695
682
  *
696
683
  * This function can only be called if at least one callback has been executed. This is because
697
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
684
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
698
685
  *
699
686
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
700
687
  */
701
688
  @Exported
702
- public getFlyingTrinkets(): ReadonlySet<TrinketType> {
689
+ public getCardTypesSet(): ReadonlySet<CardType> {
703
690
  this.lazyInit();
704
-
705
- return this.flyingTrinketTypesSet;
691
+ return this.allCardTypesSet;
706
692
  }
707
693
 
708
694
  /**
709
695
  * Returns an array containing every modded card type in the game.
710
696
  *
711
697
  * Use this if you need to iterate over the cards in order. If you need to do O(1) lookups, then
712
- * use the `getModdedCardSet` helper function instead.
698
+ * use the `getModdedCardTypesSet` helper function instead.
713
699
  *
714
700
  * This function can only be called if at least one callback has been executed. This is because
715
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
701
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
716
702
  *
717
703
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
718
704
  */
719
705
  @Exported
720
- public getModdedCardArray(): readonly CardType[] {
706
+ public getModdedCardTypes(): readonly CardType[] {
721
707
  this.lazyInit();
722
708
  return this.moddedCardTypesArray;
723
709
  }
@@ -726,134 +712,145 @@ export class ModdedElementSets extends Feature {
726
712
  * Returns a set containing every modded card type in the game.
727
713
  *
728
714
  * Use this if you need to do O(1) lookups. If you need to iterate over the cards in order, then
729
- * use the `getModdedCardArray` helper function instead.
715
+ * use the `getModdedCardTypes` helper function instead.
730
716
  *
731
717
  * This function can only be called if at least one callback has been executed. This is because
732
- * not all cards will necessarily be present when a mod first loads (due to mod load order).
718
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
733
719
  *
734
720
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
735
721
  */
736
722
  @Exported
737
- public getModdedCardSet(): ReadonlySet<CardType> {
723
+ public getModdedCardTypesSet(): ReadonlySet<CardType> {
738
724
  this.lazyInit();
739
725
  return this.moddedCardTypesSet;
740
726
  }
741
727
 
728
+ // ------------
729
+ // Pill Effects
730
+ // ------------
731
+
742
732
  /**
743
- * Returns an array containing every modded collectible type in the game.
733
+ * Returns an array containing every valid pill effect in the game, including modded pill effects.
744
734
  *
745
- * Use this if you need to iterate over the collectibles in order. If you need to do O(1) lookups,
746
- * then use the `getModdedCollectibleSet` helper function instead.
735
+ * Use this if you need to iterate over the pill effects in order. If you need to do O(1) lookups,
736
+ * then use the `getPillEffectSet` helper function instead.
747
737
  *
748
738
  * This function can only be called if at least one callback has been executed. This is because
749
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
739
+ * not all pill effects will necessarily be present when a mod first loads (due to mod load
750
740
  * order).
751
741
  *
752
742
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
753
743
  */
754
744
  @Exported
755
- public getModdedCollectibleArray(): readonly CollectibleType[] {
745
+ public getPillEffects(): readonly PillEffect[] {
756
746
  this.lazyInit();
757
- return this.moddedCollectibleTypesArray;
747
+ return this.allPillEffectsArray;
758
748
  }
759
749
 
760
750
  /**
761
- * Returns a set containing every modded collectible type in the game.
751
+ * Returns a set containing every valid pill effect in the game, including modded pill effects.
762
752
  *
763
- * Use this if you need to do O(1) lookups. If you need to iterate over the collectibles in order,
764
- * then use the `getModdedCollectibleArray` helper function instead.
753
+ * Use this if you need to do O(1) lookups. If you need to iterate over the pill effects in order,
754
+ * then use the `getPillEffects` helper function instead.
765
755
  *
766
756
  * This function can only be called if at least one callback has been executed. This is because
767
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
757
+ * not all pill effects will necessarily be present when a mod first loads (due to mod load
768
758
  * order).
769
759
  *
770
760
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
771
761
  */
772
762
  @Exported
773
- public getModdedCollectibleSet(): ReadonlySet<CollectibleType> {
763
+ public getPillEffectsSet(): ReadonlySet<PillEffect> {
774
764
  this.lazyInit();
775
- return this.moddedCollectibleTypesSet;
765
+ return this.allPillEffectsSet;
776
766
  }
777
767
 
778
768
  /**
779
- * Returns an array containing every modded trinket type in the game.
769
+ * Returns an array containing every modded pill effect in the game.
780
770
  *
781
- * Use this if you need to iterate over the trinkets in order. If you need to do O(1) lookups,
782
- * then use the `getModdedTrinketSet` helper function instead.
771
+ * Use this if you need to iterate over the pill effects in order. If you need to do O(1) lookups,
772
+ * then use the `getModdedPillEffectsSet` helper function instead.
783
773
  *
784
774
  * This function can only be called if at least one callback has been executed. This is because
785
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
775
+ * not all pill effects will necessarily be present when a mod first loads (due to mod load
776
+ * order).
786
777
  *
787
778
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
788
779
  */
789
780
  @Exported
790
- public getModdedTrinketArray(): readonly TrinketType[] {
781
+ public getModdedPillEffects(): readonly PillEffect[] {
791
782
  this.lazyInit();
792
- return this.moddedTrinketTypesArray;
783
+ return this.moddedPillEffectsArray;
793
784
  }
794
785
 
795
786
  /**
796
- * Returns a set containing every modded trinket type in the game.
787
+ * Returns a set containing every modded pill effect in the game.
797
788
  *
798
- * Use this if you need to do O(1) lookups. If you need to iterate over the trinkets in order,
799
- * then use the `getModdedTrinketArray` helper function instead.
789
+ * Use this if you need to do O(1) lookups. If you need to iterate over the pill effects in order,
790
+ * then use the `getModdedPillEffects` helper function instead.
800
791
  *
801
792
  * This function can only be called if at least one callback has been executed. This is because
802
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
793
+ * not all pill effects will necessarily be present when a mod first loads (due to mod load
794
+ * order).
803
795
  *
804
796
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
805
797
  */
806
798
  @Exported
807
- public getModdedTrinketSet(): ReadonlySet<TrinketType> {
799
+ public getModdedPillEffectsSet(): ReadonlySet<PillEffect> {
808
800
  this.lazyInit();
809
- return this.moddedTrinketTypesSet;
801
+ return this.moddedPillEffectsSet;
810
802
  }
811
803
 
804
+ // -----------
805
+ // Cache Flags
806
+ // -----------
807
+
812
808
  /**
813
- * Iterates over every item in the game and returns a map containing the number of each item that
814
- * the player has.
809
+ * Returns a set containing every collectible type with the given cache flag, including modded
810
+ * collectibles.
815
811
  *
816
- * Note that this will filter out non-real collectibles like Lilith's Incubus.
812
+ * This function can only be called if at least one callback has been executed. This is because
813
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
814
+ * order).
817
815
  *
818
816
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
819
817
  */
820
818
  @Exported
821
- public getPlayerCollectibleMap(
822
- player: EntityPlayer,
823
- ): Map<CollectibleType, int> {
824
- const collectibleArray = this.getCollectibleArray();
819
+ public getCollectibleTypesWithCacheFlag(
820
+ cacheFlag: CacheFlag,
821
+ ): ReadonlySet<CollectibleType> {
822
+ this.lazyInit();
825
823
 
826
- const collectibleMap = new Map<CollectibleType, int>();
827
- for (const collectibleType of collectibleArray) {
828
- // We specify "true" as the second argument to filter out things like Lilith's Incubus.
829
- const numCollectibles = player.GetCollectibleNum(collectibleType, true);
830
- if (numCollectibles > 0) {
831
- collectibleMap.set(collectibleType, numCollectibles);
832
- }
824
+ const collectiblesSet = this.cacheFlagToCollectibleTypesMap.get(cacheFlag);
825
+ if (collectiblesSet === undefined) {
826
+ return new ReadonlySet();
833
827
  }
834
828
 
835
- // If the player has TMTRAINER, they might also have glitched items.
836
- if (player.HasCollectible(CollectibleType.TMTRAINER)) {
837
- let collectibleType = FIRST_GLITCHED_COLLECTIBLE_TYPE;
838
- let itemConfigItem: Readonly<ItemConfigItem> | undefined;
839
- do {
840
- itemConfigItem = itemConfig.GetCollectible(collectibleType);
829
+ return collectiblesSet;
830
+ }
841
831
 
842
- if (itemConfigItem !== undefined) {
843
- // The `EntityPlayer.GetCollectibleNum` method is bugged with TMTrainer items and will
844
- // always return 0. To work around this, we simply assume that if the player has the
845
- // collectible, then they have one copy of the item.
846
- const hasCollectibles = player.HasCollectible(collectibleType, true);
847
- if (hasCollectibles) {
848
- collectibleMap.set(collectibleType, 1);
849
- }
850
- }
832
+ /**
833
+ * Returns a set containing every trinket type with the given cache flag, including modded
834
+ * trinkets.
835
+ *
836
+ * This function can only be called if at least one callback has been executed. This is because
837
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
838
+ * order).
839
+ *
840
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
841
+ */
842
+ @Exported
843
+ public getTrinketsTypesWithCacheFlag(
844
+ cacheFlag: CacheFlag,
845
+ ): ReadonlySet<TrinketType> {
846
+ this.lazyInit();
851
847
 
852
- collectibleType--; // eslint-disable-line isaacscript/strict-enums
853
- } while (itemConfigItem !== undefined);
848
+ const trinketsSet = this.cacheFlagToTrinketTypesMap.get(cacheFlag);
849
+ if (trinketsSet === undefined) {
850
+ return new ReadonlySet();
854
851
  }
855
852
 
856
- return collectibleMap;
853
+ return trinketsSet;
857
854
  }
858
855
 
859
856
  /**
@@ -875,7 +872,7 @@ export class ModdedElementSets extends Feature {
875
872
  * Lilith's Incubus.
876
873
  *
877
874
  * This function can only be called if at least one callback has been executed. This is because
878
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
875
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
879
876
  * order).
880
877
  *
881
878
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
@@ -886,7 +883,7 @@ export class ModdedElementSets extends Feature {
886
883
  cacheFlag: CacheFlag,
887
884
  ): CollectibleType[] {
888
885
  const collectiblesWithCacheFlag =
889
- this.getCollectiblesWithCacheFlag(cacheFlag);
886
+ this.getCollectibleTypesWithCacheFlag(cacheFlag);
890
887
 
891
888
  const playerCollectibles: CollectibleType[] = [];
892
889
  for (const collectibleType of getSortedSetValues(
@@ -902,9 +899,129 @@ export class ModdedElementSets extends Feature {
902
899
  return playerCollectibles;
903
900
  }
904
901
 
902
+ /**
903
+ * Returns a map containing every trinket type that the player has that matches the provided
904
+ * `CacheFlag`. The values of the map correspond to the multiplier for that trinket.
905
+ *
906
+ * This function can only be called if at least one callback has been executed. This is because
907
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
908
+ * order).
909
+ *
910
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
911
+ */
912
+ @Exported
913
+ public getPlayerTrinketsWithCacheFlag(
914
+ player: EntityPlayer,
915
+ cacheFlag: CacheFlag,
916
+ ): Map<TrinketType, int> {
917
+ const trinketTypesWithCacheFlag =
918
+ this.getTrinketsTypesWithCacheFlag(cacheFlag);
919
+
920
+ const playerTrinkets = new Map<TrinketType, int>();
921
+ for (const trinketType of trinketTypesWithCacheFlag) {
922
+ const trinketMultiplier = player.GetTrinketMultiplier(trinketType);
923
+ if (trinketMultiplier > 0) {
924
+ playerTrinkets.set(trinketType, trinketMultiplier);
925
+ }
926
+ }
927
+
928
+ return playerTrinkets;
929
+ }
930
+
931
+ /**
932
+ * Returns a set of all of the collectibles that grant flight. This is derived from collectibles
933
+ * that have `CacheFlag.FLYING` set in the "items.xml" file.
934
+ *
935
+ * Vanilla collectibles that only grant flight conditionally are manually pruned. Collectibles
936
+ * such as Empty Vessel should be checked for via the `hasFlyingTemporaryEffect` function.
937
+ *
938
+ * Under the hood, this is determined by looking at the collectibles that have `CacheFlag.FLYING`
939
+ * and excluding the ones that have `CacheFlag.ALL`. (None of the collectibles with
940
+ * `CacheFlag.ALL` grant flying, including all of the 3 Dollar Bill collectibles and all of the
941
+ * Birthright effects.)
942
+ *
943
+ * This function can only be called if at least one callback has been executed. This is because
944
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
945
+ * order).
946
+ *
947
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
948
+ *
949
+ * @param includeConditionalItems Whether collectibles that only grant flight conditionally should
950
+ * be included in the set (like Empty Vessel).
951
+ */
952
+ @Exported
953
+ public getFlyingCollectibleTypes(
954
+ includeConditionalItems: boolean,
955
+ ): ReadonlySet<CollectibleType> {
956
+ this.lazyInit();
957
+
958
+ return includeConditionalItems
959
+ ? this.flyingCollectibleTypesSet
960
+ : this.permanentFlyingCollectibleTypesSet;
961
+ }
962
+
963
+ /**
964
+ * Returns a set of all of the trinkets that grant flight. (All vanilla trinkets that grant flight
965
+ * do so conditionally, like Bat Wing and Azazel's Stump.)
966
+ *
967
+ * Under the hood, this is determined by looking at the trinkets that have `CacheFlag.FLYING` and
968
+ * excluding the ones that have `CacheFlag.ALL`. (None of the trinket with `CacheFlag.ALL` grant
969
+ * flying except for Azazel's Stump.)
970
+ *
971
+ * This function can only be called if at least one callback has been executed. This is because
972
+ * not all trinket types will necessarily be present when a mod first loads (due to mod load
973
+ * order).
974
+ *
975
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
976
+ */
977
+ @Exported
978
+ public getFlyingTrinketTypes(): ReadonlySet<TrinketType> {
979
+ this.lazyInit();
980
+ return this.flyingTrinketTypesSet;
981
+ }
982
+
983
+ // ----------------
984
+ // Collectible Tags
985
+ // ----------------
986
+
987
+ /**
988
+ * Returns a set containing every collectible type with the given tag.
989
+ *
990
+ * For example, to get all of the collectible types that count as offensive for the purposes of
991
+ * Tainted Lost:
992
+ *
993
+ * ```ts
994
+ * const offensiveCollectibleTypes = getCollectibleTypesWithTag(ItemConfigTag.OFFENSIVE);
995
+ * ```
996
+ *
997
+ * This function can only be called if at least one callback has been executed. This is because
998
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
999
+ * order).
1000
+ *
1001
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1002
+ */
1003
+ @Exported
1004
+ public getCollectibleTypesWithTag(
1005
+ itemConfigTag: ItemConfigTag,
1006
+ ): ReadonlySet<CollectibleType> {
1007
+ this.lazyInit();
1008
+
1009
+ const collectibleTypes = this.tagToCollectibleTypesMap.get(itemConfigTag);
1010
+ assertDefined(
1011
+ collectibleTypes,
1012
+ `The item config tag of ${itemConfigTag} is not a valid value of the "ItemConfigTag" enum.`,
1013
+ );
1014
+
1015
+ return collectibleTypes;
1016
+ }
1017
+
905
1018
  /**
906
1019
  * Returns the number of items that a player has towards a particular transformation.
907
1020
  *
1021
+ * This function can only be called if at least one callback has been executed. This is because
1022
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1023
+ * order).
1024
+ *
908
1025
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
909
1026
  */
910
1027
  @Exported
@@ -912,10 +1029,11 @@ export class ModdedElementSets extends Feature {
912
1029
  player: EntityPlayer,
913
1030
  itemConfigTag: ItemConfigTag,
914
1031
  ): CollectibleType[] {
915
- const collectiblesWithTag = this.getCollectiblesWithTag(itemConfigTag);
1032
+ const collectibleTypesWithTag =
1033
+ this.getCollectibleTypesWithTag(itemConfigTag);
916
1034
 
917
1035
  const playerCollectibles: CollectibleType[] = [];
918
- for (const collectibleType of getSortedSetValues(collectiblesWithTag)) {
1036
+ for (const collectibleType of getSortedSetValues(collectibleTypesWithTag)) {
919
1037
  // We specify "true" as the second argument to filter out things like Lilith's Incubus.
920
1038
  const numCollectibles = player.GetCollectibleNum(collectibleType, true);
921
1039
  repeat(numCollectibles, () => {
@@ -926,9 +1044,42 @@ export class ModdedElementSets extends Feature {
926
1044
  return playerCollectibles;
927
1045
  }
928
1046
 
1047
+ /**
1048
+ * Helper function to get all of the collectible types in the game that count towards a particular
1049
+ * transformation.
1050
+ *
1051
+ * For example, to get all of the collectible types that count towards Guppy:
1052
+ *
1053
+ * ```ts
1054
+ * const guppyCollectibleTypes = getCollectiblesForTransformation(PlayerForm.GUPPY);
1055
+ * ```
1056
+ *
1057
+ * This function can only be called if at least one callback has been executed. This is because
1058
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1059
+ * order).
1060
+ *
1061
+ * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1062
+ */
1063
+ @Exported
1064
+ public getCollectibleTypesForTransformation(
1065
+ playerForm: PlayerForm,
1066
+ ): ReadonlySet<CollectibleType> {
1067
+ const itemConfigTag = TRANSFORMATION_TO_TAG_MAP.get(playerForm);
1068
+ assertDefined(
1069
+ itemConfigTag,
1070
+ `Failed to get the collectible types for the transformation of ${playerForm} because that transformation is not based on collectibles.`,
1071
+ );
1072
+
1073
+ return this.getCollectibleTypesWithTag(itemConfigTag);
1074
+ }
1075
+
929
1076
  /**
930
1077
  * Returns the number of items that a player has towards a particular transformation.
931
1078
  *
1079
+ * This function can only be called if at least one callback has been executed. This is because
1080
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1081
+ * order).
1082
+ *
932
1083
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
933
1084
  */
934
1085
  @Exported
@@ -937,7 +1088,7 @@ export class ModdedElementSets extends Feature {
937
1088
  playerForm: PlayerForm,
938
1089
  ): CollectibleType[] {
939
1090
  const collectibleForTransformation =
940
- this.getCollectiblesForTransformation(playerForm);
1091
+ this.getCollectibleTypesForTransformation(playerForm);
941
1092
 
942
1093
  const playerCollectibles: CollectibleType[] = [];
943
1094
  for (const collectibleType of getSortedSetValues(
@@ -954,100 +1105,46 @@ export class ModdedElementSets extends Feature {
954
1105
  }
955
1106
 
956
1107
  /**
957
- * Returns a map containing every trinket type that the player has that matches the provided
958
- * `CacheFlag`. The values of the map correspond to the multiplier for that trinket.
959
- *
960
- * This function can only be called if at least one callback has been executed. This is because
961
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
1108
+ * Returns a set containing every valid passive item that can be randomly granted to Eden as a
1109
+ * starting item.
962
1110
  *
963
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
964
- */
965
- @Exported
966
- public getPlayerTrinketsWithCacheFlag(
967
- player: EntityPlayer,
968
- cacheFlag: CacheFlag,
969
- ): Map<TrinketType, int> {
970
- const trinketsWithCacheFlag = this.getTrinketsWithCacheFlag(cacheFlag);
971
-
972
- const playerTrinkets = new Map<TrinketType, int>();
973
- for (const trinketType of trinketsWithCacheFlag) {
974
- const trinketMultiplier = player.GetTrinketMultiplier(trinketType);
975
- if (trinketMultiplier > 0) {
976
- playerTrinkets.set(trinketType, trinketMultiplier);
977
- }
978
- }
979
-
980
- return playerTrinkets;
981
- }
982
-
983
- /**
984
- * Has an equal chance of returning any card (e.g. Fool, Reverse Fool, Wild Card, etc.).
1111
+ * Under the hood, this is determined by looking at the "noeden" tag in "items_metadata.xml".
985
1112
  *
986
- * This will not return:
987
- * - any runes
988
- * - any objects like Dice Shard
1113
+ * This function can only be called if at least one callback has been executed. This is because
1114
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1115
+ * order).
989
1116
  *
990
1117
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
991
- *
992
- * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
993
- * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
994
- * @param exceptions Optional. An array of cards to not select.
995
1118
  */
996
1119
  @Exported
997
- public getRandomCard(
998
- seedOrRNG: Seed | RNG = getRandomSeed(),
999
- exceptions: CardType[] = [],
1000
- ): CardType {
1120
+ public getEdenActiveCollectibleTypes(): ReadonlySet<CollectibleType> {
1001
1121
  this.lazyInit();
1002
- return getRandomSetElement(this.cardSet, seedOrRNG, exceptions);
1122
+ return this.edenActiveCollectibleTypesSet;
1003
1123
  }
1004
1124
 
1005
1125
  /**
1006
- * Helper function to get a random card type that matches the provided `ItemConfigCardType`.
1126
+ * Returns a set containing every valid passive item that can be randomly granted to Eden as a
1127
+ * starting item.
1007
1128
  *
1008
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1129
+ * Under the hood, this is determined by looking at the "noeden" tag in "items_metadata.xml".
1009
1130
  *
1010
- * @param itemConfigCardType The item config card type that represents the pool of cards to select
1011
- * from.
1012
- * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
1013
- * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
1014
- * @param exceptions Optional. An array of cards to not select.
1015
- */
1016
- @Exported
1017
- public getRandomCardTypeOfType(
1018
- itemConfigCardType: ItemConfigCardType,
1019
- seedOrRNG: Seed | RNG = getRandomSeed(),
1020
- exceptions: CardType[] = [],
1021
- ): CardType {
1022
- const cardTypeSet = this.getCardTypesOfType(itemConfigCardType);
1023
- return getRandomSetElement(cardTypeSet, seedOrRNG, exceptions);
1024
- }
1025
-
1026
- /**
1027
- * Has an equal chance of returning any rune (e.g. Rune of Hagalaz, Blank Rune, Black Rune, Soul
1028
- * of Isaac, etc.). This will never return a Rune Shard.
1131
+ * This function can only be called if at least one callback has been executed. This is because
1132
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1133
+ * order).
1029
1134
  *
1030
1135
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1031
- *
1032
- * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
1033
- * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
1034
- * @param exceptions Optional. An array of runes to not select.
1035
1136
  */
1036
1137
  @Exported
1037
- public getRandomRune(
1038
- seedOrRNG: Seed | RNG = getRandomSeed(),
1039
- exceptions: CardType[] = [],
1040
- ): CardType {
1041
- const runesSet = this.getCardTypesOfType(ItemConfigCardType.RUNE);
1042
- runesSet.delete(CardType.RUNE_SHARD);
1043
- return getRandomSetElement(runesSet, seedOrRNG, exceptions);
1138
+ public getEdenPassiveCollectibleTypes(): ReadonlySet<CollectibleType> {
1139
+ this.lazyInit();
1140
+ return this.edenPassiveCollectibleTypesSet;
1044
1141
  }
1045
1142
 
1046
1143
  /**
1047
1144
  * Returns a random active collectible type that that is a valid starting item for Eden.
1048
1145
  *
1049
1146
  * This function can only be called if at least one callback has been executed. This is because
1050
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
1147
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1051
1148
  * order).
1052
1149
  *
1053
1150
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
@@ -1057,7 +1154,7 @@ export class ModdedElementSets extends Feature {
1057
1154
  * @param exceptions Optional. An array of runes to not select.
1058
1155
  */
1059
1156
  @Exported
1060
- public getRandomEdenActiveCollectible(
1157
+ public getRandomEdenActiveCollectibleType(
1061
1158
  seedOrRNG: Seed | RNG = getRandomSeed(),
1062
1159
  exceptions: CollectibleType[] | readonly CollectibleType[] = [],
1063
1160
  ): CollectibleType {
@@ -1073,7 +1170,7 @@ export class ModdedElementSets extends Feature {
1073
1170
  * Returns a random passive collectible type that that is a valid starting item for Eden.
1074
1171
  *
1075
1172
  * This function can only be called if at least one callback has been executed. This is because
1076
- * not all collectibles will necessarily be present when a mod first loads (due to mod load
1173
+ * not all collectible types will necessarily be present when a mod first loads (due to mod load
1077
1174
  * order).
1078
1175
  *
1079
1176
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
@@ -1083,7 +1180,7 @@ export class ModdedElementSets extends Feature {
1083
1180
  * @param exceptions Optional. An array of runes to not select.
1084
1181
  */
1085
1182
  @Exported
1086
- public getRandomEdenPassiveCollectible(
1183
+ public getRandomEdenPassiveCollectibleType(
1087
1184
  seedOrRNG: Seed | RNG = getRandomSeed(),
1088
1185
  exceptions: CollectibleType[] | readonly CollectibleType[] = [],
1089
1186
  ): CollectibleType {
@@ -1095,144 +1192,113 @@ export class ModdedElementSets extends Feature {
1095
1192
  );
1096
1193
  }
1097
1194
 
1098
- /**
1099
- * Returns an array containing every modded trinket type in the game.
1100
- *
1101
- * Use this if you need to iterate over the trinkets in order. If you need to do O(1) lookups,
1102
- * then use the `getModdedTrinketSet` helper function instead.
1103
- *
1104
- * This function can only be called if at least one callback has been executed. This is because
1105
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
1106
- *
1107
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1108
- */
1109
- @Exported
1110
- public getTrinketArray(): readonly TrinketType[] {
1111
- this.lazyInit();
1112
- return this.allTrinketTypesArray;
1113
- }
1195
+ // ----------------------
1196
+ // Item Config Card Types
1197
+ // ----------------------
1114
1198
 
1115
1199
  /**
1116
- * Returns a set containing every modded trinket type in the game.
1200
+ * Helper function to get a set of card types matching the `ItemConfigCardType`.
1117
1201
  *
1118
- * Use this if you need to do O(1) lookups. If you need to iterate over the trinkets in order,
1119
- * then use the `getModdedTrinketArray` helper function instead.
1202
+ * This function is variadic, meaning that you can you can specify N card types to get a set
1203
+ * containing cards that match any of the specified types.
1120
1204
  *
1121
1205
  * This function can only be called if at least one callback has been executed. This is because
1122
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
1206
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
1123
1207
  *
1124
1208
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1125
1209
  */
1126
1210
  @Exported
1127
- public getTrinketSet(): ReadonlySet<TrinketType> {
1211
+ public getCardTypesOfType(
1212
+ ...itemConfigCardTypes: ItemConfigCardType[]
1213
+ ): Set<CardType> {
1128
1214
  this.lazyInit();
1129
- return this.allTrinketTypesSet;
1130
- }
1131
1215
 
1132
- /**
1133
- * Returns a set containing every trinket type with the given cache flag, including modded
1134
- * trinkets.
1135
- *
1136
- * This function can only be called if at least one callback has been executed. This is because
1137
- * not all trinkets will necessarily be present when a mod first loads (due to mod load order).
1138
- *
1139
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1140
- */
1141
- @Exported
1142
- public getTrinketsWithCacheFlag(
1143
- cacheFlag: CacheFlag,
1144
- ): ReadonlySet<TrinketType> {
1145
- this.lazyInit();
1216
+ const matchingCardTypes = new Set<CardType>();
1217
+ for (const itemConfigCardType of itemConfigCardTypes) {
1218
+ const cardTypeSet =
1219
+ this.itemConfigCardTypeToCardTypeMap.get(itemConfigCardType);
1220
+ assertDefined(
1221
+ cardTypeSet,
1222
+ `Failed to get the card type set for item config type: ${itemConfigCardType}`,
1223
+ );
1146
1224
 
1147
- const trinketsSet = this.cacheFlagToTrinketTypesMap.get(cacheFlag);
1148
- if (trinketsSet === undefined) {
1149
- return new ReadonlySet();
1225
+ for (const cardType of cardTypeSet) {
1226
+ matchingCardTypes.add(cardType);
1227
+ }
1150
1228
  }
1151
1229
 
1152
- return trinketsSet;
1230
+ return matchingCardTypes;
1153
1231
  }
1154
1232
 
1155
1233
  /**
1156
- * Returns an array containing every valid vanilla card type in the game.
1234
+ * Helper function to get a random card type that matches the provided `ItemConfigCardType`.
1157
1235
  *
1158
- * Use this if you need to iterate over the cards in order. If you need to do O(1) lookups, then
1159
- * use the `getVanillaCardSet` helper function instead.
1236
+ * This function can only be called if at least one callback has been executed. This is because
1237
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
1160
1238
  *
1161
1239
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1162
- */
1163
- @Exported
1164
- public getVanillaCardArray(): readonly CardType[] {
1165
- this.lazyInitVanillaCardTypes();
1166
- return this.vanillaCardTypesArray;
1167
- }
1168
-
1169
- /**
1170
- * Returns a set containing every valid vanilla card type in the game.
1171
- *
1172
- * Use this if you need to do O(1) lookups. If you need to iterate over the cards in order, then
1173
- * use the `getVanillaCardArray` helper function instead.
1174
1240
  *
1175
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1241
+ * @param itemConfigCardType The item config card type that represents the pool of cards to select
1242
+ * from.
1243
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
1244
+ * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
1245
+ * @param exceptions Optional. An array of cards to not select.
1176
1246
  */
1177
1247
  @Exported
1178
- public getVanillaCardSet(): ReadonlySet<CardType> {
1179
- this.lazyInitVanillaCardTypes();
1180
- return this.vanillaCardTypesSet;
1248
+ public getRandomCardTypeOfType(
1249
+ itemConfigCardType: ItemConfigCardType,
1250
+ seedOrRNG: Seed | RNG = getRandomSeed(),
1251
+ exceptions: CardType[] = [],
1252
+ ): CardType {
1253
+ const cardTypeSet = this.getCardTypesOfType(itemConfigCardType);
1254
+ return getRandomSetElement(cardTypeSet, seedOrRNG, exceptions);
1181
1255
  }
1182
1256
 
1183
1257
  /**
1184
- * Returns an array containing every valid vanilla collectible type in the game.
1185
- *
1186
- * Use this if you need to iterate over the collectibles in order. If you need to do O(1) lookups,
1187
- * then use the `getVanillaCollectibleSet` helper function instead.
1258
+ * Has an equal chance of returning any card (e.g. Fool, Reverse Fool, Wild Card, etc.).
1188
1259
  *
1189
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1190
- */
1191
- @Exported
1192
- public getVanillaCollectibleArray(): readonly CollectibleType[] {
1193
- this.lazyInitVanillaCollectibleTypes();
1194
- return this.vanillaCollectibleTypesArray;
1195
- }
1196
-
1197
- /**
1198
- * Returns a set containing every valid vanilla collectible type in the game.
1260
+ * This will not return:
1261
+ * - any runes
1262
+ * - any objects like Dice Shard
1199
1263
  *
1200
- * Use this if you need to do O(1) lookups. If you need to iterate over the collectibles in order,
1201
- * then use the `getVanillaCollectibleArray` helper function instead.
1264
+ * This function can only be called if at least one callback has been executed. This is because
1265
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
1202
1266
  *
1203
1267
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1204
- */
1205
- @Exported
1206
- public getVanillaCollectibleSet(): ReadonlySet<CollectibleType> {
1207
- this.lazyInitVanillaCollectibleTypes();
1208
- return this.vanillaCollectibleTypesSet;
1209
- }
1210
-
1211
- /**
1212
- * Returns an array containing every valid vanilla trinket type in the game.
1213
1268
  *
1214
- * Use this if you need to iterate over the trinkets in order. If you need to do O(1) lookups,
1215
- * then use the `getVanillaTrinketSet` helper function instead.
1216
- *
1217
- * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1269
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
1270
+ * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
1271
+ * @param exceptions Optional. An array of cards to not select.
1218
1272
  */
1219
1273
  @Exported
1220
- public getVanillaTrinketArray(): readonly TrinketType[] {
1221
- this.lazyInitVanillaTrinketTypes();
1222
- return this.vanillaTrinketTypesArray;
1274
+ public getRandomCard(
1275
+ seedOrRNG: Seed | RNG = getRandomSeed(),
1276
+ exceptions: CardType[] = [],
1277
+ ): CardType {
1278
+ this.lazyInit();
1279
+ return getRandomSetElement(this.cardSet, seedOrRNG, exceptions);
1223
1280
  }
1224
1281
 
1225
1282
  /**
1226
- * Returns a set containing every valid vanilla trinket type in the game.
1283
+ * Has an equal chance of returning any rune (e.g. Rune of Hagalaz, Blank Rune, Black Rune, Soul
1284
+ * of Isaac, etc.). This will never return a Rune Shard.
1227
1285
  *
1228
- * Use this if you need to do O(1) lookups. If you need to iterate over the trinkets in order,
1229
- * then use the `getVanillaTrinketArray` helper function instead.
1286
+ * This function can only be called if at least one callback has been executed. This is because
1287
+ * not all card types will necessarily be present when a mod first loads (due to mod load order).
1230
1288
  *
1231
1289
  * In order to use this function, you must upgrade your mod with `ISCFeature.MODDED_ELEMENT_SETS`.
1290
+ *
1291
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
1292
+ * the `RNG.Next` method will be called. Default is `getRandomSeed()`.
1293
+ * @param exceptions Optional. An array of runes to not select.
1232
1294
  */
1233
1295
  @Exported
1234
- public getVanillaTrinketSet(): ReadonlySet<TrinketType> {
1235
- this.lazyInitVanillaTrinketTypes();
1236
- return this.vanillaTrinketTypesSet;
1296
+ public getRandomRune(
1297
+ seedOrRNG: Seed | RNG = getRandomSeed(),
1298
+ exceptions: CardType[] = [],
1299
+ ): CardType {
1300
+ const runesSet = this.getCardTypesOfType(ItemConfigCardType.RUNE);
1301
+ runesSet.delete(CardType.RUNE_SHARD);
1302
+ return getRandomSetElement(runesSet, seedOrRNG, exceptions);
1237
1303
  }
1238
1304
  }