isaacscript-common 21.5.2 → 21.6.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 (87) hide show
  1. package/dist/index.rollup.d.ts +14 -2
  2. package/dist/isaacscript-common.lua +118 -4
  3. package/dist/src/callbacks.d.ts +1 -1
  4. package/dist/src/callbacks.d.ts.map +1 -1
  5. package/dist/src/classes/callbacks/InputActionFilter.d.ts.map +1 -1
  6. package/dist/src/classes/callbacks/InputActionPlayer.d.ts.map +1 -1
  7. package/dist/src/classes/callbacks/PostCollectibleEmpty.d.ts.map +1 -1
  8. package/dist/src/classes/callbacks/PostCustomRevive.d.ts.map +1 -1
  9. package/dist/src/classes/callbacks/PostDiceRoomActivated.d.ts.map +1 -1
  10. package/dist/src/classes/callbacks/PostGridEntityCollision.d.ts.map +1 -1
  11. package/dist/src/classes/callbacks/PostGridEntityCustomCollision.d.ts.map +1 -1
  12. package/dist/src/classes/callbacks/PostGridEntityCustomRemove.d.ts.map +1 -1
  13. package/dist/src/classes/callbacks/PostGridEntityRemove.d.ts.map +1 -1
  14. package/dist/src/classes/callbacks/PostItemDischarge.d.ts.map +1 -1
  15. package/dist/src/classes/callbacks/PostKeyboardChanged.d.ts.map +1 -1
  16. package/dist/src/classes/callbacks/PostPurchase.d.ts.map +1 -1
  17. package/dist/src/classes/callbacks/PostRoomClearChanged.d.ts.map +1 -1
  18. package/dist/src/classes/callbacks/PostTransformation.d.ts.map +1 -1
  19. package/dist/src/classes/callbacks/PreEntitySpawnFilter.d.ts.map +1 -1
  20. package/dist/src/classes/callbacks/PreRoomEntitySpawnFilter.d.ts.map +1 -1
  21. package/dist/src/classes/features/other/CustomItemPools.d.ts.map +1 -1
  22. package/dist/src/classes/features/other/CustomItemPools.lua +3 -0
  23. package/dist/src/classes/features/other/RunInNFrames.d.ts.map +1 -1
  24. package/dist/src/classes/features/other/RunNextRoom.d.ts.map +1 -1
  25. package/dist/src/classes/features/other/TaintedLazarusPlayers.d.ts.map +1 -1
  26. package/dist/src/classes/features/other/customStages/backdrop.d.ts.map +1 -1
  27. package/dist/src/classes/private/CustomCallback.d.ts.map +1 -1
  28. package/dist/src/functions/modFeatures.d.ts +1 -1
  29. package/dist/src/functions/modFeatures.d.ts.map +1 -1
  30. package/dist/src/functions/stage.d.ts +12 -1
  31. package/dist/src/functions/stage.d.ts.map +1 -1
  32. package/dist/src/functions/stage.lua +21 -0
  33. package/dist/src/functions/weighted.d.ts.map +1 -1
  34. package/dist/src/functions/weighted.lua +3 -0
  35. package/dist/src/interfaces/CustomStageTSConfig.d.ts.map +1 -1
  36. package/dist/src/objects/LRoomShapeToRectangles.d.ts +1 -3
  37. package/dist/src/objects/LRoomShapeToRectangles.d.ts.map +1 -1
  38. package/dist/src/objects/englishLevelNames.d.ts +103 -3
  39. package/dist/src/objects/englishLevelNames.d.ts.map +1 -1
  40. package/dist/src/objects/isaacAPIClassTypeToFunctions.d.ts +40 -6
  41. package/dist/src/objects/isaacAPIClassTypeToFunctions.d.ts.map +1 -1
  42. package/dist/src/objects/roomShapeToDoorSlotsToGridIndexDelta.d.ts +1 -3
  43. package/dist/src/objects/roomShapeToDoorSlotsToGridIndexDelta.d.ts.map +1 -1
  44. package/dist/src/objects/stageToMusic.lua +2 -2
  45. package/dist/src/objects/stageToStageID.d.ts +108 -0
  46. package/dist/src/objects/stageToStageID.d.ts.map +1 -0
  47. package/dist/src/objects/stageToStageID.lua +93 -0
  48. package/dist/src/types/private/CallbackTuple.d.ts +8 -8
  49. package/dist/src/types/private/CallbackTuple.d.ts.map +1 -1
  50. package/dist/src/types/private/ModUpgradedWithFeatures.d.ts +1 -1
  51. package/dist/src/types/private/ModUpgradedWithFeatures.d.ts.map +1 -1
  52. package/package.json +2 -2
  53. package/src/callbacks.ts +2 -2
  54. package/src/classes/callbacks/InputActionFilter.ts +0 -1
  55. package/src/classes/callbacks/InputActionPlayer.ts +0 -1
  56. package/src/classes/callbacks/PostCollectibleEmpty.ts +0 -1
  57. package/src/classes/callbacks/PostCustomRevive.ts +0 -1
  58. package/src/classes/callbacks/PostDiceRoomActivated.ts +0 -1
  59. package/src/classes/callbacks/PostGridEntityCollision.ts +0 -1
  60. package/src/classes/callbacks/PostGridEntityCustomCollision.ts +0 -1
  61. package/src/classes/callbacks/PostGridEntityCustomRemove.ts +0 -1
  62. package/src/classes/callbacks/PostGridEntityRemove.ts +0 -1
  63. package/src/classes/callbacks/PostItemDischarge.ts +0 -1
  64. package/src/classes/callbacks/PostKeyboardChanged.ts +0 -1
  65. package/src/classes/callbacks/PostPurchase.ts +0 -1
  66. package/src/classes/callbacks/PostRoomClearChanged.ts +0 -1
  67. package/src/classes/callbacks/PostTransformation.ts +0 -1
  68. package/src/classes/callbacks/PreEntitySpawnFilter.ts +0 -1
  69. package/src/classes/callbacks/PreRoomEntitySpawnFilter.ts +0 -1
  70. package/src/classes/features/other/CustomItemPools.ts +6 -2
  71. package/src/classes/features/other/RunInNFrames.ts +0 -1
  72. package/src/classes/features/other/RunNextRoom.ts +0 -1
  73. package/src/classes/features/other/TaintedLazarusPlayers.ts +0 -1
  74. package/src/classes/features/other/customStages/backdrop.ts +10 -10
  75. package/src/classes/private/CustomCallback.ts +0 -1
  76. package/src/functions/modFeatures.ts +2 -2
  77. package/src/functions/stage.ts +27 -1
  78. package/src/functions/weighted.ts +8 -2
  79. package/src/interfaces/CustomStageTSConfig.ts +0 -2
  80. package/src/objects/LRoomShapeToRectangles.ts +6 -5
  81. package/src/objects/englishLevelNames.ts +2 -7
  82. package/src/objects/isaacAPIClassTypeToFunctions.ts +8 -6
  83. package/src/objects/roomShapeToDoorSlotsToGridIndexDelta.ts +6 -6
  84. package/src/objects/stageToMusic.ts +68 -68
  85. package/src/objects/stageToStageID.ts +98 -0
  86. package/src/types/private/CallbackTuple.ts +8 -8
  87. package/src/types/private/ModUpgradedWithFeatures.ts +1 -1
@@ -22,7 +22,6 @@ export class PreRoomEntitySpawnFilter extends CustomCallback<T> {
22
22
  ];
23
23
  }
24
24
 
25
- // eslint-disable-next-line class-methods-use-this
26
25
  protected override shouldFire = (
27
26
  fireArgs: FireArgs<T>,
28
27
  optionalArgs: OptionalArgs<T>,
@@ -127,8 +127,12 @@ export class CustomItemPools extends Feature {
127
127
  customItemPool,
128
128
  seedOrRNG,
129
129
  );
130
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
131
- const tuple = customItemPool[randomIndex]!;
130
+ const tuple = customItemPool[randomIndex];
131
+ if (tuple === undefined) {
132
+ error(
133
+ `Failed to get an element from a custom item pool using a random index of: ${randomIndex}`,
134
+ );
135
+ }
132
136
 
133
137
  if (decrease) {
134
138
  arrayRemoveIndexInPlace(customItemPool, randomIndex);
@@ -40,7 +40,6 @@ export class RunInNFrames extends Feature {
40
40
  },
41
41
  };
42
42
 
43
- // eslint-disable-next-line class-methods-use-this
44
43
  public override vConditionalFunc = (): boolean => false;
45
44
 
46
45
  private roomHistory: RoomHistory;
@@ -11,7 +11,6 @@ export class RunNextRoom extends Feature {
11
11
  },
12
12
  };
13
13
 
14
- // eslint-disable-next-line class-methods-use-this
15
14
  public override vConditionalFunc = (): boolean => false;
16
15
 
17
16
  /** @internal */
@@ -31,7 +31,6 @@ export class TaintedLazarusPlayers extends Feature {
31
31
  },
32
32
  };
33
33
 
34
- // eslint-disable-next-line class-methods-use-this
35
34
  public override vConditionalFunc = (): boolean => false;
36
35
 
37
36
  /** @internal */
@@ -36,12 +36,12 @@ enum BackdropKind {
36
36
  }
37
37
 
38
38
  /** This is created by the vanilla Basement files. */
39
- const DEFAULT_BACKDROP: NonNullable<CustomStage["backdropPNGPaths"]> = {
39
+ const DEFAULT_BACKDROP = {
40
40
  nFloors: [`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/backdrop/nfloor.png`],
41
41
  lFloors: [`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/backdrop/lfloor.png`], // cspell:ignore lfloor
42
42
  walls: [`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/backdrop/wall.png`],
43
43
  corners: [`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/backdrop/corner.png`],
44
- } as const;
44
+ } as const satisfies NonNullable<CustomStage["backdropPNGPaths"]>;
45
45
 
46
46
  const ROOM_SHAPE_WALL_ANM2_LAYERS = {
47
47
  [RoomShape.SHAPE_1x1]: 44, // 1
@@ -58,16 +58,18 @@ const ROOM_SHAPE_WALL_ANM2_LAYERS = {
58
58
  [RoomShape.LBR]: 63, // 12
59
59
  } as const satisfies Record<RoomShape, int>;
60
60
 
61
- const ROOM_SHAPE_WALL_EXTRA_ANM2_LAYERS: {
62
- readonly [Key in RoomShape]?: int;
63
- } = {
61
+ // We don't use `as const` since we need the object to be indexable by all `RoomShape`.
62
+ // eslint-disable-next-line isaacscript/require-capital-const-assertions
63
+ const ROOM_SHAPE_WALL_EXTRA_ANM2_LAYERS: Readonly<
64
+ Partial<Record<RoomShape, int>>
65
+ > = {
64
66
  [RoomShape.SHAPE_2x1]: 7, // 6
65
67
  [RoomShape.SHAPE_2x2]: 21, // 8
66
68
  [RoomShape.LTL]: 19, // 9
67
69
  [RoomShape.LTR]: 19, // 10
68
70
  [RoomShape.LBL]: 19, // 11
69
71
  [RoomShape.LBR]: 19, // 12
70
- } as const;
72
+ };
71
73
 
72
74
  const WALL_OFFSET = Vector(-80, -80);
73
75
 
@@ -177,8 +179,7 @@ function spawnWallEntity(
177
179
  wallEffect.SpriteOffset = modifiedOffset;
178
180
 
179
181
  sprite.LoadGraphics();
180
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
181
- const roomShapeName = RoomShape[roomShape]!;
182
+ const roomShapeName = RoomShape[roomShape];
182
183
  const animation = trimPrefix(roomShapeName, "SHAPE_");
183
184
  const modifiedAnimation = isExtraWall ? `${animation}X` : animation;
184
185
  sprite.Play(modifiedAnimation, true);
@@ -252,8 +253,7 @@ function spawnFloorEntity(customStage: CustomStage, rng: RNG) {
252
253
  floorEffect.SpriteOffset = modifiedOffset;
253
254
 
254
255
  sprite.LoadGraphics();
255
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
256
- const roomShapeName = RoomShape[roomShape]!;
256
+ const roomShapeName = RoomShape[roomShape];
257
257
  const animation = trimPrefix(roomShapeName, "SHAPE_");
258
258
  sprite.Play(animation, true);
259
259
  }
@@ -81,7 +81,6 @@ export abstract class CustomCallback<
81
81
  * This method needs to be overwritten for any callback that has optional filtration arguments.
82
82
  * See "shouldFire.ts" for methods tailored to specific kinds of callbacks.
83
83
  */
84
- // eslint-disable-next-line class-methods-use-this
85
84
  protected shouldFire: (
86
85
  fireArgs: FireArgs<T>,
87
86
  optionalArgs: OptionalArgs<T>,
@@ -25,7 +25,7 @@ import { ModUpgraded } from "../classes/ModUpgraded";
25
25
  export function initModFeatures<T extends ReadonlyArray<typeof ModFeature>>(
26
26
  mod: ModUpgraded,
27
27
  modFeatures: T,
28
- ): { [Key in keyof T]: InstanceType<T[Key]> } {
28
+ ): { [K in keyof T]: InstanceType<T[K]> } {
29
29
  const instantiatedModFeatures: ModFeature[] = [];
30
30
 
31
31
  for (const modFeature of modFeatures) {
@@ -36,5 +36,5 @@ export function initModFeatures<T extends ReadonlyArray<typeof ModFeature>>(
36
36
  instantiatedModFeatures.push(instantiatedModFeature);
37
37
  }
38
38
 
39
- return instantiatedModFeatures as { [Key in keyof T]: InstanceType<T[Key]> };
39
+ return instantiatedModFeatures as { [K in keyof T]: InstanceType<T[K]> };
40
40
  }
@@ -2,11 +2,13 @@ import {
2
2
  GameStateFlag,
3
3
  LevelStage,
4
4
  RoomType,
5
+ StageID,
5
6
  StageType,
6
7
  } from "isaac-typescript-definitions";
7
8
  import { game } from "../core/cachedClasses";
8
9
  import { ENGLISH_LEVEL_NAMES } from "../objects/englishLevelNames";
9
10
  import { ROOM_TYPE_GOTO_PREFIXES } from "../objects/roomTypeGotoPrefixes";
11
+ import { STAGE_TO_STAGE_ID } from "../objects/stageToStageID";
10
12
  import { STAGE_TYPE_SUFFIXES } from "../objects/stageTypeSuffixes";
11
13
  import { STAGE_TYPE_TO_LETTER } from "../objects/stageTypeToLetter";
12
14
  import { asLevelStage, asNumber } from "./types";
@@ -88,7 +90,6 @@ export function getEffectiveStage(): LevelStage {
88
90
  return stage;
89
91
  }
90
92
 
91
- // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
92
93
  /**
93
94
  * Helper function to get the English name of the level. For example, "Caves 1".
94
95
  *
@@ -134,6 +135,31 @@ export function getStage(): LevelStage {
134
135
  return level.GetStage();
135
136
  }
136
137
 
138
+ /**
139
+ * Helper function to get the stage ID that corresponds to a particular floor. It does this by
140
+ * manually converting `LevelStage` and `StageType` into `StageID`. This is useful because
141
+ * `getRoomStageID` will not correctly return the `StageID` if the player is in a special room.
142
+ *
143
+ * @param stage Optional. If not specified, the stage corresponding to the current floor will be
144
+ * used.
145
+ * @param stageType Optional. If not specified, the stage type corresponding to the current floor
146
+ * will be used.
147
+ */
148
+ export function getStageID(stage?: LevelStage, stageType?: StageType): StageID {
149
+ const level = game.GetLevel();
150
+
151
+ if (stage === undefined) {
152
+ stage = level.GetStage();
153
+ }
154
+
155
+ if (stageType === undefined) {
156
+ stageType = level.GetStageType();
157
+ }
158
+
159
+ const stageTypeToStageID = STAGE_TO_STAGE_ID[stage];
160
+ return stageTypeToStageID[stageType];
161
+ }
162
+
137
163
  /** Alias for the `Level.GetStageType` method. */
138
164
  export function getStageType(): StageType {
139
165
  const level = game.GetLevel();
@@ -13,8 +13,14 @@ export function getRandomFromWeightedArray<T>(
13
13
  seedOrRNG: Seed | RNG = getRandomSeed(),
14
14
  ): T {
15
15
  const randomIndex = getRandomIndexFromWeightedArray(weightedArray, seedOrRNG);
16
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
17
- const randomElement = weightedArray[randomIndex]!;
16
+
17
+ const randomElement = weightedArray[randomIndex];
18
+ if (randomElement === undefined) {
19
+ error(
20
+ `Failed to get an element from a weighted array using a random index of: ${randomIndex}`,
21
+ );
22
+ }
23
+
18
24
  return randomElement[0];
19
25
  }
20
26
 
@@ -548,7 +548,6 @@ export interface CustomStageBossPoolEntry {
548
548
 
549
549
  /** Optional. A collection of sprites used for the boss on the "versus" screen. */
550
550
  versusScreen?: {
551
- // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
552
551
  /**
553
552
  * Mandatory. The full path to the spritesheet that contains the graphics of the name of the
554
553
  * boss that will be displayed on the top of the boss "versus" screen.
@@ -557,7 +556,6 @@ export interface CustomStageBossPoolEntry {
557
556
  */
558
557
  namePNGPath: string;
559
558
 
560
- // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
561
559
  /**
562
560
  * Mandatory. The full path to the spritesheet that contains the portrait of the boss that will
563
561
  * be displayed on the right side of the boss "versus" screen.
@@ -15,10 +15,11 @@ const TWO_BY_TWO_BOTTOM_RIGHT = newReadonlyVector(25, 13);
15
15
  * "Vector(0, 0)" corresponds to the top left tile of a room, not including the walls. (The top-left
16
16
  * wall would be at "Vector(-1, -1)".)
17
17
  */
18
- // We need to specify the type so that the object will be indexable by room shapes.
19
- export const L_ROOM_SHAPE_TO_RECTANGLES: {
20
- readonly [Key in RoomShape]?: LRoomRectangles;
21
- } = {
18
+ // We don't use `as const` since we need the object to be indexable by all `RoomShape`.
19
+ // eslint-disable-next-line isaacscript/require-capital-const-assertions
20
+ export const L_ROOM_SHAPE_TO_RECTANGLES: Readonly<
21
+ Partial<Record<RoomShape, LRoomRectangles>>
22
+ > = {
22
23
  // 9
23
24
  [RoomShape.LTL]: {
24
25
  verticalTopLeft: newReadonlyVector(13, 0),
@@ -50,4 +51,4 @@ export const L_ROOM_SHAPE_TO_RECTANGLES: {
50
51
  horizontalTopLeft: VectorZero,
51
52
  horizontalBottomRight: newReadonlyVector(12, 13),
52
53
  },
53
- } as const;
54
+ };
@@ -1,6 +1,5 @@
1
1
  import { LevelStage, StageType } from "isaac-typescript-definitions";
2
2
 
3
- // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
4
3
  /**
5
4
  * A mapping of stage and stage types to the corresponding English level name.
6
5
  *
@@ -9,11 +8,7 @@ import { LevelStage, StageType } from "isaac-typescript-definitions";
9
8
  *
10
9
  * Note that this contains "Blue Womb" instead of "???" for stage 9.
11
10
  */
12
- export const ENGLISH_LEVEL_NAMES: {
13
- readonly [levelStage in LevelStage]: {
14
- readonly [stageType in StageType]: string;
15
- };
16
- } = {
11
+ export const ENGLISH_LEVEL_NAMES = {
17
12
  [LevelStage.BASEMENT_1]: {
18
13
  [StageType.ORIGINAL]: "Basement 1",
19
14
  [StageType.WRATH_OF_THE_LAMB]: "Cellar 1",
@@ -118,4 +113,4 @@ export const ENGLISH_LEVEL_NAMES: {
118
113
  [StageType.REPENTANCE]: "Home",
119
114
  [StageType.REPENTANCE_B]: "Home",
120
115
  },
121
- } as const;
116
+ } as const satisfies Record<LevelStage, Record<StageType, string>>;
@@ -80,12 +80,14 @@ export interface IsaacAPIClassTypeFunctions<T, SerializedT> {
80
80
  deserialize: (object: SerializedT) => T;
81
81
  }
82
82
 
83
- export const ISAAC_API_CLASS_TYPE_TO_FUNCTIONS: {
84
- readonly [Key in CopyableIsaacAPIClassType]: IsaacAPIClassTypeFunctions<
85
- IsaacAPIClassTypeToType[Key],
86
- IsaacAPIClassTypeToSerializedType[Key]
83
+ type IsaacAPIClassTypeToFunctions = {
84
+ readonly [K in CopyableIsaacAPIClassType]: IsaacAPIClassTypeFunctions<
85
+ IsaacAPIClassTypeToType[K],
86
+ IsaacAPIClassTypeToSerializedType[K]
87
87
  >;
88
- } = {
88
+ };
89
+
90
+ export const ISAAC_API_CLASS_TYPE_TO_FUNCTIONS = {
89
91
  [CopyableIsaacAPIClassType.BIT_SET_128]: {
90
92
  is: isBitSet128,
91
93
  isSerialized: isSerializedBitSet128,
@@ -121,4 +123,4 @@ export const ISAAC_API_CLASS_TYPE_TO_FUNCTIONS: {
121
123
  serialize: serializeVector,
122
124
  deserialize: deserializeVector,
123
125
  },
124
- } as const;
126
+ } as const satisfies IsaacAPIClassTypeToFunctions;
@@ -11,11 +11,11 @@ const DOWN = LEVEL_GRID_ROW_WIDTH;
11
11
  * Deltas are considered to be from the safe grid index of the room (i.e. the top left corner, or
12
12
  * top right corner in the case of `RoomShape.LTL`).
13
13
  */
14
- // We need the maps to be widened for all `DoorSlot`, so we specify the type instead of using the
15
- // `satisfies` operator.
16
- export const ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA: {
17
- readonly [Key in RoomShape]: ReadonlyMap<DoorSlot, int>;
18
- } = {
14
+ // We don't use `as const` since we need the map to be indexable by all `DoorSlot`.
15
+ // eslint-disable-next-line isaacscript/require-capital-const-assertions
16
+ export const ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA: Readonly<
17
+ Record<RoomShape, ReadonlyMap<DoorSlot, int>>
18
+ > = {
19
19
  // 1
20
20
  [RoomShape.SHAPE_1x1]: new ReadonlyMap([
21
21
  [DoorSlot.LEFT_0, LEFT], // 0
@@ -127,4 +127,4 @@ export const ROOM_SHAPE_TO_DOOR_SLOTS_TO_GRID_INDEX_DELTA: {
127
127
  [DoorSlot.RIGHT_1, DOWN + RIGHT], // 6
128
128
  [DoorSlot.DOWN_1, RIGHT + DOWN], // 7
129
129
  ]),
130
- } as const;
130
+ };
@@ -1,98 +1,98 @@
1
1
  import { LevelStage, Music, StageType } from "isaac-typescript-definitions";
2
2
 
3
3
  const BASEMENT_TO_MUSIC = {
4
- [StageType.ORIGINAL]: Music.BASEMENT,
5
- [StageType.WRATH_OF_THE_LAMB]: Music.CELLAR,
6
- [StageType.AFTERBIRTH]: Music.BURNING_BASEMENT,
7
- [StageType.GREED_MODE]: Music.BASEMENT,
8
- [StageType.REPENTANCE]: Music.DOWNPOUR,
9
- [StageType.REPENTANCE_B]: Music.DROSS,
4
+ [StageType.ORIGINAL]: Music.BASEMENT, // 0
5
+ [StageType.WRATH_OF_THE_LAMB]: Music.CELLAR, // 1
6
+ [StageType.AFTERBIRTH]: Music.BURNING_BASEMENT, // 2
7
+ [StageType.GREED_MODE]: Music.BASEMENT, // 3
8
+ [StageType.REPENTANCE]: Music.DOWNPOUR, // 4
9
+ [StageType.REPENTANCE_B]: Music.DROSS, // 5
10
10
  } as const satisfies Record<StageType, Music>;
11
11
 
12
12
  const CAVES_TO_MUSIC = {
13
- [StageType.ORIGINAL]: Music.CAVES,
14
- [StageType.WRATH_OF_THE_LAMB]: Music.CATACOMBS,
15
- [StageType.AFTERBIRTH]: Music.FLOODED_CAVES,
16
- [StageType.GREED_MODE]: Music.CAVES,
17
- [StageType.REPENTANCE]: Music.MINES,
18
- [StageType.REPENTANCE_B]: Music.ASHPIT,
13
+ [StageType.ORIGINAL]: Music.CAVES, // 0
14
+ [StageType.WRATH_OF_THE_LAMB]: Music.CATACOMBS, // 1
15
+ [StageType.AFTERBIRTH]: Music.FLOODED_CAVES, // 2
16
+ [StageType.GREED_MODE]: Music.CAVES, // 3
17
+ [StageType.REPENTANCE]: Music.MINES, // 4
18
+ [StageType.REPENTANCE_B]: Music.ASHPIT, // 5
19
19
  } as const satisfies Record<StageType, Music>;
20
20
 
21
21
  const DEPTHS_TO_MUSIC = {
22
- [StageType.ORIGINAL]: Music.DEPTHS,
23
- [StageType.WRATH_OF_THE_LAMB]: Music.NECROPOLIS,
24
- [StageType.AFTERBIRTH]: Music.DANK_DEPTHS,
25
- [StageType.GREED_MODE]: Music.DEPTHS,
26
- [StageType.REPENTANCE]: Music.MAUSOLEUM,
27
- [StageType.REPENTANCE_B]: Music.GEHENNA,
22
+ [StageType.ORIGINAL]: Music.DEPTHS, // 0
23
+ [StageType.WRATH_OF_THE_LAMB]: Music.NECROPOLIS, // 1
24
+ [StageType.AFTERBIRTH]: Music.DANK_DEPTHS, // 2
25
+ [StageType.GREED_MODE]: Music.DEPTHS, // 3
26
+ [StageType.REPENTANCE]: Music.MAUSOLEUM, // 4
27
+ [StageType.REPENTANCE_B]: Music.GEHENNA, // 5
28
28
  } as const satisfies Record<StageType, Music>;
29
29
 
30
30
  const WOMB_TO_MUSIC = {
31
- [StageType.ORIGINAL]: Music.WOMB,
32
- [StageType.WRATH_OF_THE_LAMB]: Music.UTERO,
33
- [StageType.AFTERBIRTH]: Music.SCARRED_WOMB,
34
- [StageType.GREED_MODE]: Music.WOMB,
35
- [StageType.REPENTANCE]: Music.CORPSE,
36
- [StageType.REPENTANCE_B]: Music.MORTIS,
31
+ [StageType.ORIGINAL]: Music.WOMB, // 0
32
+ [StageType.WRATH_OF_THE_LAMB]: Music.UTERO, // 1
33
+ [StageType.AFTERBIRTH]: Music.SCARRED_WOMB, // 2
34
+ [StageType.GREED_MODE]: Music.WOMB, // 3
35
+ [StageType.REPENTANCE]: Music.CORPSE, // 4
36
+ [StageType.REPENTANCE_B]: Music.MORTIS, // 5
37
37
  } as const satisfies Record<StageType, Music>;
38
38
 
39
39
  const BLUE_WOMB_TO_MUSIC = {
40
- [StageType.ORIGINAL]: Music.BLUE_WOMB,
41
- [StageType.WRATH_OF_THE_LAMB]: Music.BLUE_WOMB,
42
- [StageType.AFTERBIRTH]: Music.BLUE_WOMB,
43
- [StageType.GREED_MODE]: Music.BLUE_WOMB,
44
- [StageType.REPENTANCE]: Music.BLUE_WOMB,
45
- [StageType.REPENTANCE_B]: Music.BLUE_WOMB,
40
+ [StageType.ORIGINAL]: Music.BLUE_WOMB, // 0
41
+ [StageType.WRATH_OF_THE_LAMB]: Music.BLUE_WOMB, // 1
42
+ [StageType.AFTERBIRTH]: Music.BLUE_WOMB, // 2
43
+ [StageType.GREED_MODE]: Music.BLUE_WOMB, // 3
44
+ [StageType.REPENTANCE]: Music.BLUE_WOMB, // 4
45
+ [StageType.REPENTANCE_B]: Music.BLUE_WOMB, // 5
46
46
  } as const satisfies Record<StageType, Music>;
47
47
 
48
48
  const SHEOL_CATHEDRAL_TO_MUSIC = {
49
- [StageType.ORIGINAL]: Music.SHEOL,
50
- [StageType.WRATH_OF_THE_LAMB]: Music.CATHEDRAL,
51
- [StageType.AFTERBIRTH]: Music.SHEOL,
52
- [StageType.GREED_MODE]: Music.SHEOL,
53
- [StageType.REPENTANCE]: Music.SHEOL,
54
- [StageType.REPENTANCE_B]: Music.SHEOL,
49
+ [StageType.ORIGINAL]: Music.SHEOL, // 0
50
+ [StageType.WRATH_OF_THE_LAMB]: Music.CATHEDRAL, // 1
51
+ [StageType.AFTERBIRTH]: Music.SHEOL, // 2
52
+ [StageType.GREED_MODE]: Music.SHEOL, // 3
53
+ [StageType.REPENTANCE]: Music.SHEOL, // 4
54
+ [StageType.REPENTANCE_B]: Music.SHEOL, // 5
55
55
  } as const satisfies Record<StageType, Music>;
56
56
 
57
57
  const DARK_ROOM_CHEST_TO_MUSIC = {
58
- [StageType.ORIGINAL]: Music.DARK_ROOM,
59
- [StageType.WRATH_OF_THE_LAMB]: Music.CHEST,
60
- [StageType.AFTERBIRTH]: Music.DARK_ROOM,
61
- [StageType.GREED_MODE]: Music.DARK_ROOM,
62
- [StageType.REPENTANCE]: Music.DARK_ROOM,
63
- [StageType.REPENTANCE_B]: Music.DARK_ROOM,
58
+ [StageType.ORIGINAL]: Music.DARK_ROOM, // 0
59
+ [StageType.WRATH_OF_THE_LAMB]: Music.CHEST, // 1
60
+ [StageType.AFTERBIRTH]: Music.DARK_ROOM, // 2
61
+ [StageType.GREED_MODE]: Music.DARK_ROOM, // 3
62
+ [StageType.REPENTANCE]: Music.DARK_ROOM, // 4
63
+ [StageType.REPENTANCE_B]: Music.DARK_ROOM, // 5
64
64
  } as const satisfies Record<StageType, Music>;
65
65
 
66
- const THE_VOID_TO_MUSIC = {
67
- [StageType.ORIGINAL]: Music.VOID,
68
- [StageType.WRATH_OF_THE_LAMB]: Music.VOID,
69
- [StageType.AFTERBIRTH]: Music.VOID,
70
- [StageType.GREED_MODE]: Music.VOID,
71
- [StageType.REPENTANCE]: Music.VOID,
72
- [StageType.REPENTANCE_B]: Music.VOID,
66
+ const VOID_TO_MUSIC = {
67
+ [StageType.ORIGINAL]: Music.VOID, // 0
68
+ [StageType.WRATH_OF_THE_LAMB]: Music.VOID, // 1
69
+ [StageType.AFTERBIRTH]: Music.VOID, // 2
70
+ [StageType.GREED_MODE]: Music.VOID, // 3
71
+ [StageType.REPENTANCE]: Music.VOID, // 4
72
+ [StageType.REPENTANCE_B]: Music.VOID, // 5
73
73
  } as const satisfies Record<StageType, Music>;
74
74
 
75
75
  const HOME_TO_MUSIC = {
76
- [StageType.ORIGINAL]: Music.ISAACS_HOUSE,
77
- [StageType.WRATH_OF_THE_LAMB]: Music.ISAACS_HOUSE,
78
- [StageType.AFTERBIRTH]: Music.ISAACS_HOUSE,
79
- [StageType.GREED_MODE]: Music.ISAACS_HOUSE,
80
- [StageType.REPENTANCE]: Music.ISAACS_HOUSE,
81
- [StageType.REPENTANCE_B]: Music.ISAACS_HOUSE,
76
+ [StageType.ORIGINAL]: Music.ISAACS_HOUSE, // 0
77
+ [StageType.WRATH_OF_THE_LAMB]: Music.ISAACS_HOUSE, // 1
78
+ [StageType.AFTERBIRTH]: Music.ISAACS_HOUSE, // 2
79
+ [StageType.GREED_MODE]: Music.ISAACS_HOUSE, // 3
80
+ [StageType.REPENTANCE]: Music.ISAACS_HOUSE, // 4
81
+ [StageType.REPENTANCE_B]: Music.ISAACS_HOUSE, // 5
82
82
  } as const satisfies Record<StageType, Music>;
83
83
 
84
84
  export const STAGE_TO_MUSIC = {
85
- [LevelStage.BASEMENT_1]: BASEMENT_TO_MUSIC,
86
- [LevelStage.BASEMENT_2]: BASEMENT_TO_MUSIC,
87
- [LevelStage.CAVES_1]: CAVES_TO_MUSIC,
88
- [LevelStage.CAVES_2]: CAVES_TO_MUSIC,
89
- [LevelStage.DEPTHS_1]: DEPTHS_TO_MUSIC,
90
- [LevelStage.DEPTHS_2]: DEPTHS_TO_MUSIC,
91
- [LevelStage.WOMB_1]: WOMB_TO_MUSIC,
92
- [LevelStage.WOMB_2]: WOMB_TO_MUSIC,
93
- [LevelStage.BLUE_WOMB]: BLUE_WOMB_TO_MUSIC,
94
- [LevelStage.SHEOL_CATHEDRAL]: SHEOL_CATHEDRAL_TO_MUSIC,
95
- [LevelStage.DARK_ROOM_CHEST]: DARK_ROOM_CHEST_TO_MUSIC,
96
- [LevelStage.THE_VOID]: THE_VOID_TO_MUSIC,
97
- [LevelStage.HOME]: HOME_TO_MUSIC,
85
+ [LevelStage.BASEMENT_1]: BASEMENT_TO_MUSIC, // 1
86
+ [LevelStage.BASEMENT_2]: BASEMENT_TO_MUSIC, // 2
87
+ [LevelStage.CAVES_1]: CAVES_TO_MUSIC, // 3
88
+ [LevelStage.CAVES_2]: CAVES_TO_MUSIC, // 4
89
+ [LevelStage.DEPTHS_1]: DEPTHS_TO_MUSIC, // 5
90
+ [LevelStage.DEPTHS_2]: DEPTHS_TO_MUSIC, // 6
91
+ [LevelStage.WOMB_1]: WOMB_TO_MUSIC, // 7
92
+ [LevelStage.WOMB_2]: WOMB_TO_MUSIC, // 8
93
+ [LevelStage.BLUE_WOMB]: BLUE_WOMB_TO_MUSIC, // 9
94
+ [LevelStage.SHEOL_CATHEDRAL]: SHEOL_CATHEDRAL_TO_MUSIC, // 10
95
+ [LevelStage.DARK_ROOM_CHEST]: DARK_ROOM_CHEST_TO_MUSIC, // 11
96
+ [LevelStage.THE_VOID]: VOID_TO_MUSIC, // 12
97
+ [LevelStage.HOME]: HOME_TO_MUSIC, // 13
98
98
  } as const satisfies Record<LevelStage, Record<StageType, Music>>;
@@ -0,0 +1,98 @@
1
+ import { LevelStage, StageID, StageType } from "isaac-typescript-definitions";
2
+
3
+ const BASEMENT_TO_STAGE_ID = {
4
+ [StageType.ORIGINAL]: StageID.BASEMENT, // 0
5
+ [StageType.WRATH_OF_THE_LAMB]: StageID.CELLAR, // 1
6
+ [StageType.AFTERBIRTH]: StageID.BURNING_BASEMENT, // 2
7
+ [StageType.GREED_MODE]: StageID.BASEMENT, // 3
8
+ [StageType.REPENTANCE]: StageID.DOWNPOUR, // 4
9
+ [StageType.REPENTANCE_B]: StageID.DROSS, // 5
10
+ } as const satisfies Record<StageType, StageID>;
11
+
12
+ const CAVES_TO_STAGE_ID = {
13
+ [StageType.ORIGINAL]: StageID.CAVES, // 0
14
+ [StageType.WRATH_OF_THE_LAMB]: StageID.CATACOMBS, // 1
15
+ [StageType.AFTERBIRTH]: StageID.FLOODED_CAVES, // 2
16
+ [StageType.GREED_MODE]: StageID.CAVES, // 3
17
+ [StageType.REPENTANCE]: StageID.MINES, // 4
18
+ [StageType.REPENTANCE_B]: StageID.ASHPIT, // 5
19
+ } as const satisfies Record<StageType, StageID>;
20
+
21
+ const DEPTHS_TO_STAGE_ID = {
22
+ [StageType.ORIGINAL]: StageID.DEPTHS, // 0
23
+ [StageType.WRATH_OF_THE_LAMB]: StageID.NECROPOLIS, // 1
24
+ [StageType.AFTERBIRTH]: StageID.DANK_DEPTHS, // 2
25
+ [StageType.GREED_MODE]: StageID.DEPTHS, // 3
26
+ [StageType.REPENTANCE]: StageID.MAUSOLEUM, // 4
27
+ [StageType.REPENTANCE_B]: StageID.GEHENNA, // 5
28
+ } as const satisfies Record<StageType, StageID>;
29
+
30
+ const WOMB_TO_STAGE_ID = {
31
+ [StageType.ORIGINAL]: StageID.WOMB, // 0
32
+ [StageType.WRATH_OF_THE_LAMB]: StageID.UTERO, // 1
33
+ [StageType.AFTERBIRTH]: StageID.SCARRED_WOMB, // 2
34
+ [StageType.GREED_MODE]: StageID.WOMB, // 3
35
+ [StageType.REPENTANCE]: StageID.CORPSE, // 4
36
+ [StageType.REPENTANCE_B]: StageID.MORTIS, // 5
37
+ } as const satisfies Record<StageType, StageID>;
38
+
39
+ const BLUE_WOMB_TO_STAGE_ID = {
40
+ [StageType.ORIGINAL]: StageID.BLUE_WOMB, // 0
41
+ [StageType.WRATH_OF_THE_LAMB]: StageID.BLUE_WOMB, // 1
42
+ [StageType.AFTERBIRTH]: StageID.BLUE_WOMB, // 2
43
+ [StageType.GREED_MODE]: StageID.BLUE_WOMB, // 3
44
+ [StageType.REPENTANCE]: StageID.BLUE_WOMB, // 4
45
+ [StageType.REPENTANCE_B]: StageID.BLUE_WOMB, // 5
46
+ } as const satisfies Record<StageType, StageID>;
47
+
48
+ const SHEOL_CATHEDRAL_TO_STAGE_ID = {
49
+ [StageType.ORIGINAL]: StageID.SHEOL, // 0
50
+ [StageType.WRATH_OF_THE_LAMB]: StageID.CATHEDRAL, // 1
51
+ [StageType.AFTERBIRTH]: StageID.SHEOL, // 2
52
+ [StageType.GREED_MODE]: StageID.SHEOL, // 3
53
+ [StageType.REPENTANCE]: StageID.SHEOL, // 4
54
+ [StageType.REPENTANCE_B]: StageID.SHEOL, // 5
55
+ } as const satisfies Record<StageType, StageID>;
56
+
57
+ const DARK_ROOM_CHEST_TO_STAGE_ID = {
58
+ [StageType.ORIGINAL]: StageID.DARK_ROOM, // 0
59
+ [StageType.WRATH_OF_THE_LAMB]: StageID.CHEST, // 1
60
+ [StageType.AFTERBIRTH]: StageID.DARK_ROOM, // 2
61
+ [StageType.GREED_MODE]: StageID.DARK_ROOM, // 3
62
+ [StageType.REPENTANCE]: StageID.DARK_ROOM, // 4
63
+ [StageType.REPENTANCE_B]: StageID.DARK_ROOM, // 5
64
+ } as const satisfies Record<StageType, StageID>;
65
+
66
+ const VOID_TO_STAGE_ID = {
67
+ [StageType.ORIGINAL]: StageID.VOID, // 0
68
+ [StageType.WRATH_OF_THE_LAMB]: StageID.VOID, // 1
69
+ [StageType.AFTERBIRTH]: StageID.VOID, // 2
70
+ [StageType.GREED_MODE]: StageID.VOID, // 3
71
+ [StageType.REPENTANCE]: StageID.VOID, // 4
72
+ [StageType.REPENTANCE_B]: StageID.VOID, // 5
73
+ } as const satisfies Record<StageType, StageID>;
74
+
75
+ const HOME_TO_STAGE_ID = {
76
+ [StageType.ORIGINAL]: StageID.HOME, // 0
77
+ [StageType.WRATH_OF_THE_LAMB]: StageID.HOME, // 1
78
+ [StageType.AFTERBIRTH]: StageID.HOME, // 2
79
+ [StageType.GREED_MODE]: StageID.HOME, // 3
80
+ [StageType.REPENTANCE]: StageID.HOME, // 4
81
+ [StageType.REPENTANCE_B]: StageID.HOME, // 5
82
+ } as const satisfies Record<StageType, StageID>;
83
+
84
+ export const STAGE_TO_STAGE_ID = {
85
+ [LevelStage.BASEMENT_1]: BASEMENT_TO_STAGE_ID, // 1
86
+ [LevelStage.BASEMENT_2]: BASEMENT_TO_STAGE_ID, // 2
87
+ [LevelStage.CAVES_1]: CAVES_TO_STAGE_ID, // 3
88
+ [LevelStage.CAVES_2]: CAVES_TO_STAGE_ID, // 4
89
+ [LevelStage.DEPTHS_1]: DEPTHS_TO_STAGE_ID, // 5
90
+ [LevelStage.DEPTHS_2]: DEPTHS_TO_STAGE_ID, // 6
91
+ [LevelStage.WOMB_1]: WOMB_TO_STAGE_ID, // 7
92
+ [LevelStage.WOMB_2]: WOMB_TO_STAGE_ID, // 8
93
+ [LevelStage.BLUE_WOMB]: BLUE_WOMB_TO_STAGE_ID, // 9
94
+ [LevelStage.SHEOL_CATHEDRAL]: SHEOL_CATHEDRAL_TO_STAGE_ID, // 10
95
+ [LevelStage.DARK_ROOM_CHEST]: DARK_ROOM_CHEST_TO_STAGE_ID, // 11
96
+ [LevelStage.THE_VOID]: VOID_TO_STAGE_ID, // 12
97
+ [LevelStage.HOME]: HOME_TO_STAGE_ID, // 13
98
+ } as const satisfies Record<LevelStage, unknown>;
@@ -9,10 +9,10 @@ import { AllButFirst } from "../AllButFirst";
9
9
  * added/removed.
10
10
  */
11
11
  export type CallbackTuple = {
12
- [Key in ModCallback]: [
13
- modCallback: Key,
14
- callbackFunc: AddCallbackParameters[Key][0],
15
- optionalArgs?: AllButFirst<AddCallbackParameters[Key]>,
12
+ [K in ModCallback]: [
13
+ modCallback: K,
14
+ callbackFunc: AddCallbackParameters[K][0],
15
+ optionalArgs?: AllButFirst<AddCallbackParameters[K]>,
16
16
  ];
17
17
  }[ModCallback];
18
18
 
@@ -22,9 +22,9 @@ export type CallbackTuple = {
22
22
  * get added/removed.
23
23
  */
24
24
  export type CustomCallbackTuple = {
25
- [Key in ModCallbackCustom]: [
26
- modCallback: Key,
27
- callbackFunc: AddCallbackParametersCustom[Key][0],
28
- optionalArgs?: AllButFirst<AddCallbackParametersCustom[Key]>,
25
+ [K in ModCallbackCustom]: [
26
+ modCallback: K,
27
+ callbackFunc: AddCallbackParametersCustom[K][0],
28
+ optionalArgs?: AllButFirst<AddCallbackParametersCustom[K]>,
29
29
  ];
30
30
  }[ModCallbackCustom];
@@ -37,5 +37,5 @@ type ISCFeaturesToKeys<T extends readonly ISCFeature[]> = Omit<
37
37
  * same private fields will cause a `never` type.
38
38
  */
39
39
  type ISCFeatureTupleToClassTuple<T extends ISCFeature[]> = {
40
- [Key in keyof T]: PublicInterface<ISCFeatureToClass[T[Key]]>;
40
+ [K in keyof T]: PublicInterface<ISCFeatureToClass[T[K]]>;
41
41
  };