isaacscript-common 7.5.0 → 7.6.1

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 (86) hide show
  1. package/dist/classes/DefaultMap.d.ts +3 -2
  2. package/dist/classes/DefaultMap.d.ts.map +1 -1
  3. package/dist/classes/DefaultMap.lua +2 -1
  4. package/dist/features/customGridEntity.d.ts +6 -3
  5. package/dist/features/customGridEntity.d.ts.map +1 -1
  6. package/dist/features/customGridEntity.lua +20 -11
  7. package/dist/features/customStage/customStageConstants.d.ts +1 -0
  8. package/dist/features/customStage/customStageConstants.d.ts.map +1 -1
  9. package/dist/features/customStage/customStageConstants.lua +1 -0
  10. package/dist/features/customStage/customStageGridEntities.d.ts.map +1 -1
  11. package/dist/features/customStage/customStageGridEntities.lua +9 -5
  12. package/dist/features/customStage/customStageUtils.d.ts +2 -1
  13. package/dist/features/customStage/customStageUtils.d.ts.map +1 -1
  14. package/dist/features/customStage/customStageUtils.lua +40 -1
  15. package/dist/features/customStage/exports.d.ts +1 -25
  16. package/dist/features/customStage/exports.d.ts.map +1 -1
  17. package/dist/features/customStage/exports.lua +28 -29
  18. package/dist/features/customStage/init.d.ts.map +1 -1
  19. package/dist/features/customStage/init.lua +3 -1
  20. package/dist/features/customStage/v.d.ts +0 -2
  21. package/dist/features/customStage/v.d.ts.map +1 -1
  22. package/dist/features/customStage/v.lua +0 -2
  23. package/dist/features/customStage/versusScreen.d.ts.map +1 -1
  24. package/dist/features/customStage/versusScreen.lua +80 -60
  25. package/dist/features/customTrapdoor/exports.d.ts +28 -16
  26. package/dist/features/customTrapdoor/exports.d.ts.map +1 -1
  27. package/dist/features/customTrapdoor/exports.lua +45 -61
  28. package/dist/features/customTrapdoor/init.d.ts.map +1 -1
  29. package/dist/features/customTrapdoor/init.lua +12 -10
  30. package/dist/features/customTrapdoor/spawn.d.ts +6 -0
  31. package/dist/features/customTrapdoor/spawn.d.ts.map +1 -0
  32. package/dist/features/customTrapdoor/spawn.lua +51 -0
  33. package/dist/features/customTrapdoor/v.d.ts +2 -2
  34. package/dist/features/customTrapdoor/v.d.ts.map +1 -1
  35. package/dist/functions/doors.d.ts +6 -5
  36. package/dist/functions/doors.d.ts.map +1 -1
  37. package/dist/functions/doors.lua +25 -12
  38. package/dist/functions/enums.d.ts +3 -3
  39. package/dist/functions/enums.lua +3 -3
  40. package/dist/functions/players.d.ts.map +1 -1
  41. package/dist/functions/players.lua +3 -2
  42. package/dist/index.d.ts +172 -11145
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.lua +4 -4
  45. package/dist/interfaces/{CustomStageLua.d.ts → CustomStageTSConfig.d.ts} +87 -61
  46. package/dist/interfaces/CustomStageTSConfig.d.ts.map +1 -0
  47. package/dist/interfaces/{CustomStageLua.lua → CustomStageTSConfig.lua} +0 -0
  48. package/dist/interfaces/GridEntityCustomData.d.ts +2 -2
  49. package/dist/interfaces/GridEntityCustomData.d.ts.map +1 -1
  50. package/dist/interfaces/JSONRoomsFile.d.ts +6 -5
  51. package/dist/interfaces/JSONRoomsFile.d.ts.map +1 -1
  52. package/dist/interfaces/private/CustomStage.d.ts +1 -1
  53. package/dist/interfaces/private/CustomStage.d.ts.map +1 -1
  54. package/dist/interfaces/private/CustomTrapdoorDescription.d.ts +2 -2
  55. package/dist/interfaces/private/CustomTrapdoorDescription.d.ts.map +1 -1
  56. package/dist/interfaces/private/CustomTrapdoorDestination.d.ts +14 -0
  57. package/dist/interfaces/private/CustomTrapdoorDestination.d.ts.map +1 -0
  58. package/dist/{types/TrapdoorDestination.lua → interfaces/private/CustomTrapdoorDestination.lua} +0 -0
  59. package/package.json +1 -1
  60. package/src/classes/DefaultMap.ts +3 -2
  61. package/src/features/customGridEntity.ts +30 -20
  62. package/src/features/customStage/customStageConstants.ts +2 -0
  63. package/src/features/customStage/customStageGridEntities.ts +20 -16
  64. package/src/features/customStage/customStageUtils.ts +52 -1
  65. package/src/features/customStage/exports.ts +33 -45
  66. package/src/features/customStage/init.ts +3 -2
  67. package/src/features/customStage/v.ts +0 -6
  68. package/src/features/customStage/versusScreen.ts +78 -57
  69. package/src/features/customTrapdoor/exports.ts +60 -66
  70. package/src/features/customTrapdoor/init.ts +12 -11
  71. package/src/features/customTrapdoor/spawn.ts +53 -0
  72. package/src/features/customTrapdoor/v.ts +2 -2
  73. package/src/functions/doors.ts +37 -21
  74. package/src/functions/enums.ts +3 -3
  75. package/src/functions/players.ts +7 -3
  76. package/src/index.ts +3 -4
  77. package/src/interfaces/{CustomStageLua.ts → CustomStageTSConfig.ts} +108 -42
  78. package/src/interfaces/GridEntityCustomData.ts +2 -2
  79. package/src/interfaces/JSONRoomsFile.ts +6 -5
  80. package/src/interfaces/private/CustomStage.ts +4 -1
  81. package/src/interfaces/private/CustomTrapdoorDescription.ts +2 -2
  82. package/src/interfaces/private/CustomTrapdoorDestination.ts +14 -0
  83. package/dist/interfaces/CustomStageLua.d.ts.map +0 -1
  84. package/dist/types/TrapdoorDestination.d.ts +0 -6
  85. package/dist/types/TrapdoorDestination.d.ts.map +0 -1
  86. package/src/types/TrapdoorDestination.ts +0 -8
@@ -4,7 +4,6 @@ import {
4
4
  EntityGridCollisionClass,
5
5
  ModCallback,
6
6
  RoomTransitionAnim,
7
- StageType,
8
7
  } from "isaac-typescript-definitions";
9
8
  import { ModUpgraded } from "../../classes/ModUpgraded";
10
9
  import { game } from "../../core/cachedClasses";
@@ -15,7 +14,6 @@ import { getAllPlayers } from "../../functions/playerIndex";
15
14
  import { getRoomGridIndex, getRoomListIndex } from "../../functions/roomData";
16
15
  import { teleport } from "../../functions/roomTransition";
17
16
  import { setStage } from "../../functions/stage";
18
- import { isString } from "../../functions/types";
19
17
  import { disableCustomStage, setCustomStage } from "../customStage/exports";
20
18
  import { topStreakTextStart } from "../customStage/streakText";
21
19
  import { enableAllInputs } from "../disableInputs";
@@ -119,7 +117,7 @@ function checkPixelationToBlackComplete() {
119
117
  StageTravelState.WAITING_FOR_SECOND_PIXELATION_TO_GET_HALF_WAY;
120
118
  v.run.stateRenderFrame = futureRenderFrameCount;
121
119
 
122
- goToCustomDestination();
120
+ goToCustomTrapdoorDestination();
123
121
 
124
122
  // Start another pixelation effect. This time, we will keep the screen black with the sprite,
125
123
  // and then remove the black sprite once the pixelation effect is halfway complete.
@@ -193,21 +191,24 @@ function checkAllPlayersLayingDownComplete() {
193
191
  enableAllInputs(CUSTOM_TRAPDOOR_FEATURE_NAME);
194
192
  }
195
193
 
196
- function goToCustomDestination() {
194
+ function goToCustomTrapdoorDestination() {
197
195
  if (v.run.destination === null) {
198
196
  return;
199
197
  }
200
198
 
201
- const [arg1, arg2] = v.run.destination;
199
+ const {
200
+ customStageName,
201
+ customStageFloorNum,
202
+ vanillaStage,
203
+ vanillaStageType,
204
+ } = v.run.destination;
202
205
 
203
- if (isString(arg1)) {
204
- // A string represents a custom stage.
205
- const firstFloor = arg2 === 1;
206
+ if (customStageName !== undefined && customStageFloorNum !== undefined) {
207
+ const firstFloor = customStageFloorNum === 1;
206
208
  setCustomStage("Slaughterhouse", firstFloor);
207
- } else {
208
- // A number represents a vanilla `LevelStage`.
209
+ } else if (vanillaStage !== undefined && vanillaStageType !== undefined) {
209
210
  disableCustomStage();
210
- setStage(arg1, arg2 as StageType);
211
+ setStage(vanillaStage, vanillaStageType);
211
212
  }
212
213
  }
213
214
 
@@ -0,0 +1,53 @@
1
+ import { GridCollisionClass } from "isaac-typescript-definitions";
2
+ import { game } from "../../core/cachedClasses";
3
+ import { TrapdoorAnimation } from "../../enums/private/TrapdoorAnimation";
4
+ import { getRoomListIndex } from "../../functions/roomData";
5
+ import { isVector } from "../../functions/vector";
6
+ import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
7
+ import { CustomTrapdoorDestination } from "../../interfaces/private/CustomTrapdoorDestination";
8
+ import { spawnCustomGridEntity } from "../customGridEntity";
9
+ import { GridEntityTypeCustom } from "./customTrapdoorConstants";
10
+ import { shouldTrapdoorSpawnOpen } from "./openClose";
11
+ import v from "./v";
12
+
13
+ export function spawnCustomTrapdoorToDestination(
14
+ gridIndexOrPosition: int | Vector,
15
+ destination: CustomTrapdoorDestination,
16
+ anm2Path: string,
17
+ spawnOpen?: boolean,
18
+ ): GridEntity {
19
+ const room = game.GetRoom();
20
+ const roomFrameCount = room.GetFrameCount();
21
+ const roomListIndex = getRoomListIndex();
22
+ const gridIndex = isVector(gridIndexOrPosition)
23
+ ? room.GetGridIndex(gridIndexOrPosition)
24
+ : gridIndexOrPosition;
25
+
26
+ const gridEntity = spawnCustomGridEntity(
27
+ GridEntityTypeCustom.TRAPDOOR_CUSTOM,
28
+ gridIndexOrPosition,
29
+ GridCollisionClass.NONE,
30
+ anm2Path,
31
+ TrapdoorAnimation.OPENED,
32
+ );
33
+
34
+ const firstSpawn = roomFrameCount !== 0;
35
+ const open =
36
+ spawnOpen === undefined
37
+ ? shouldTrapdoorSpawnOpen(gridEntity, firstSpawn)
38
+ : spawnOpen;
39
+
40
+ const roomTrapdoorMap = v.level.trapdoors.getAndSetDefault(roomListIndex);
41
+ const customTrapdoorDescription: CustomTrapdoorDescription = {
42
+ open,
43
+ destination,
44
+ firstSpawn,
45
+ };
46
+ roomTrapdoorMap.set(gridIndex, customTrapdoorDescription);
47
+
48
+ const sprite = gridEntity.GetSprite();
49
+ const animation = open ? TrapdoorAnimation.OPENED : TrapdoorAnimation.CLOSED;
50
+ sprite.Play(animation, true);
51
+
52
+ return gridEntity;
53
+ }
@@ -1,7 +1,7 @@
1
1
  import { DefaultMap } from "../../classes/DefaultMap";
2
2
  import { StageTravelState } from "../../enums/private/StageTravelState";
3
3
  import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
4
- import { TrapdoorDestination } from "../../types/TrapdoorDestination";
4
+ import { CustomTrapdoorDestination } from "../../interfaces/private/CustomTrapdoorDestination";
5
5
 
6
6
  const v = {
7
7
  run: {
@@ -10,7 +10,7 @@ const v = {
10
10
  /** The render frame that this state was reached. */
11
11
  stateRenderFrame: null as int | null,
12
12
 
13
- destination: null as TrapdoorDestination | null,
13
+ destination: null as CustomTrapdoorDestination | null,
14
14
  },
15
15
 
16
16
  level: {
@@ -21,6 +21,7 @@ import { ROOM_SHAPE_TO_DOOR_SLOTS } from "../objects/roomShapeToDoorSlots";
21
21
  import { arrayToBitFlags } from "./bitwise";
22
22
  import { directionToVector } from "./direction";
23
23
  import { getEnumValues } from "./enums";
24
+ import { hasFlag } from "./flag";
24
25
  import { isTSTLSet } from "./tstlClass";
25
26
  import { asNumber } from "./types";
26
27
 
@@ -53,6 +54,21 @@ export function doorSlotFlagToDoorSlot(doorSlotFlag: DoorSlotFlag): DoorSlot {
53
54
  return doorSlot === undefined ? DEFAULT_DOOR_SLOT : doorSlot;
54
55
  }
55
56
 
57
+ export function doorSlotFlagsToDoorSlots(
58
+ doorSlotFlags: BitFlags<DoorSlotFlag>,
59
+ ): DoorSlot[] {
60
+ const doorSlots: DoorSlot[] = [];
61
+
62
+ for (const doorSlotFlag of getEnumValues(DoorSlotFlag)) {
63
+ if (hasFlag(doorSlotFlags, doorSlotFlag)) {
64
+ const doorSlot = doorSlotFlagToDoorSlot(doorSlotFlag);
65
+ doorSlots.push(doorSlot);
66
+ }
67
+ }
68
+
69
+ return doorSlots;
70
+ }
71
+
56
72
  export function doorSlotToDirection(doorSlot: DoorSlot): Direction {
57
73
  return DOOR_SLOT_TO_DIRECTION[doorSlot];
58
74
  }
@@ -61,6 +77,27 @@ export function doorSlotToDoorSlotFlag(doorSlot: DoorSlot): DoorSlotFlag {
61
77
  return DOOR_SLOT_TO_DOOR_SLOT_FLAG[doorSlot];
62
78
  }
63
79
 
80
+ /**
81
+ * Helper function to convert an array of door slots or a set of door slots to the resulting bit
82
+ * flag number.
83
+ */
84
+ export function doorSlotsToDoorSlotFlags(
85
+ doorSlots:
86
+ | DoorSlot[]
87
+ | readonly DoorSlot[]
88
+ | Set<DoorSlot>
89
+ | ReadonlySet<DoorSlot>,
90
+ ): BitFlags<DoorSlotFlag> {
91
+ const doorSlotArray = isTSTLSet(doorSlots)
92
+ ? [...doorSlots.values()]
93
+ : (doorSlots as DoorSlot[]);
94
+ const doorSlotFlagArray = doorSlotArray.map((doorSlot) =>
95
+ doorSlotToDoorSlotFlag(doorSlot),
96
+ );
97
+
98
+ return arrayToBitFlags(doorSlotFlagArray);
99
+ }
100
+
64
101
  export function getAngelRoomDoor(): GridEntityDoor | undefined {
65
102
  const angelRoomDoors = getDoors(RoomType.ANGEL);
66
103
  return angelRoomDoors.length === 0 ? undefined : angelRoomDoors[0];
@@ -113,27 +150,6 @@ export function getDoorSlotEnterPositionOffset(
113
150
  return oppositeVector.mul(ROOM_ENTRY_OFFSET_FROM_DOOR);
114
151
  }
115
152
 
116
- /**
117
- * Helper function to convert an array of door slots or a set of door slots to the resulting bit
118
- * flag number.
119
- */
120
- export function getDoorSlotFlags(
121
- doorSlots:
122
- | DoorSlot[]
123
- | readonly DoorSlot[]
124
- | Set<DoorSlot>
125
- | ReadonlySet<DoorSlot>,
126
- ): BitFlags<DoorSlotFlag> {
127
- const doorSlotArray = isTSTLSet(doorSlots)
128
- ? [...doorSlots.values()]
129
- : (doorSlots as DoorSlot[]);
130
- const doorSlotFlagArray = doorSlotArray.map((doorSlot) =>
131
- doorSlotToDoorSlotFlag(doorSlot),
132
- );
133
-
134
- return arrayToBitFlags(doorSlotFlagArray);
135
- }
136
-
137
153
  /** Helper function to get the possible door slots that can exist for a given room shape. */
138
154
  export function getDoorSlotsForRoomShape(
139
155
  roomShape: RoomShape,
@@ -18,7 +18,7 @@ import { irange } from "./utils";
18
18
  * Also see the `getEnumKeys` and `getEnumValues` helper functions.
19
19
  *
20
20
  * For a more in depth explanation, see:
21
- * https://isaacscript.github.io/gotchas#iterating-over-enums
21
+ * https://isaacscript.github.io/main/gotchas#iterating-over-enums
22
22
  */
23
23
  export function getEnumEntries<T>(
24
24
  transpiledEnum: T,
@@ -57,7 +57,7 @@ export function getEnumEntries<T>(
57
57
  * Also see the `getEnumEntries` and `getEnumValues` helper functions.
58
58
  *
59
59
  * For a more in depth explanation, see:
60
- * https://isaacscript.github.io/gotchas#iterating-over-enums
60
+ * https://isaacscript.github.io/main/gotchas#iterating-over-enums
61
61
  */
62
62
  export function getEnumKeys<T>(transpiledEnum: T): string[] {
63
63
  const enumEntries = getEnumEntries(transpiledEnum);
@@ -84,7 +84,7 @@ export function getEnumLength<T>(transpiledEnum: T): int {
84
84
  * Also see the `getEnumEntries` and `getEnumKeys` helper functions.
85
85
  *
86
86
  * For a more in depth explanation, see:
87
- * https://isaacscript.github.io/gotchas#iterating-over-enums
87
+ * https://isaacscript.github.io/main/gotchas#iterating-over-enums
88
88
  */
89
89
  export function getEnumValues<T>(transpiledEnum: T): Array<T[keyof T]> {
90
90
  const enumEntries = getEnumEntries(transpiledEnum);
@@ -21,7 +21,11 @@ import {
21
21
  import { getCollectibleMaxCharges } from "./collectibles";
22
22
  import { getCollectibleArray } from "./collectibleSet";
23
23
  import { getEnumValues } from "./enums";
24
- import { getPlayerIndexVanilla, getPlayers } from "./playerIndex";
24
+ import {
25
+ getAllPlayers,
26
+ getPlayerIndexVanilla,
27
+ getPlayers,
28
+ } from "./playerIndex";
25
29
  import { addTearsStat } from "./tears";
26
30
  import { isNumber } from "./types";
27
31
  import { repeat } from "./utils";
@@ -127,12 +131,12 @@ export function addTrinketCostume(
127
131
  export function anyPlayerHasCollectible(
128
132
  collectibleType: CollectibleType,
129
133
  ): boolean {
130
- const players = getPlayers();
134
+ const players = getAllPlayers();
131
135
  return players.some((player) => player.HasCollectible(collectibleType));
132
136
  }
133
137
 
134
138
  export function anyPlayerHasTrinket(trinketType: TrinketType): boolean {
135
- const players = getPlayers();
139
+ const players = getAllPlayers();
136
140
  return players.some((player) => player.HasTrinket(trinketType));
137
141
  }
138
142
 
package/src/index.ts CHANGED
@@ -22,8 +22,8 @@ export { registerCharacterStats } from "./features/characterStats";
22
22
  export { getCollectibleItemPoolType } from "./features/collectibleItemPoolType";
23
23
  export { initCustomDoor, spawnCustomDoor } from "./features/customDoor";
24
24
  export {
25
- removeCustomGridEntity as removeCustomGrid,
26
- spawnCustomGridEntity as spawnCustomGrid,
25
+ removeCustomGridEntity,
26
+ spawnCustomGridEntity,
27
27
  } from "./features/customGridEntity";
28
28
  export * from "./features/customStage/exports";
29
29
  export * from "./features/customTrapdoor/exports";
@@ -181,7 +181,7 @@ export * from "./functions/utils";
181
181
  export * from "./functions/vector";
182
182
  export * from "./interfaces/ChargeBarSprites";
183
183
  export * from "./interfaces/Corner";
184
- export * from "./interfaces/CustomStageLua";
184
+ export * from "./interfaces/CustomStageTSConfig";
185
185
  export * from "./interfaces/GridEntityCustomData";
186
186
  export * from "./interfaces/JSONRoomsFile";
187
187
  export * from "./interfaces/PlayerHealth";
@@ -204,5 +204,4 @@ export * from "./types/PickupIndex";
204
204
  export * from "./types/PlayerIndex";
205
205
  export * from "./types/PossibleStatType";
206
206
  export * from "./types/SerializedIsaacAPIClass";
207
- export * from "./types/TrapdoorDestination";
208
207
  export * from "./types/TSTLClass";
@@ -9,8 +9,11 @@
9
9
  *
10
10
  * The `CustomStageLua` interface extends this, adding room metadata.
11
11
  */
12
+
13
+ import { Immutable } from "../types/Immutable";
14
+
12
15
  // ts-prune-ignore-next
13
- export type CustomStageTSConfig = Readonly<{
16
+ export interface CustomStageTSConfig {
14
17
  /** Mandatory. The name of the custom stage. */
15
18
  name: string;
16
19
 
@@ -29,7 +32,7 @@ export type CustomStageTSConfig = Readonly<{
29
32
  * https://isaacscript.github.io/main/custom-stages
30
33
  *
31
34
  * @minimum 101
32
- * @maximum 109
35
+ * @maximum 999
33
36
  */
34
37
  roomVariantPrefix: number;
35
38
 
@@ -38,8 +41,14 @@ export type CustomStageTSConfig = Readonly<{
38
41
  * number of the stage that will be warped to and used as a basis for the stage by the level
39
42
  * generation algorithm.
40
43
  *
41
- * (It is not possible to use Basement 1 as a base stage due to conflicts with the `Game.SetStage`
42
- * method.)
44
+ * For example, if you wanted to have a custom stage with a small amount of rooms per floor, then
45
+ * you should choose 2 as a base. (This would copy the number of rooms that would appear in
46
+ * Basement 2.) And if you wanted to have a custom stage with the maximum amount of rooms, then
47
+ * you should choose 13 as a base. (This would copy the number of rooms that would appear on The
48
+ * Void.)
49
+ *
50
+ * It is not possible to use Basement 1 as a base stage due to conflicts with the `Game.SetStage`
51
+ * method.
43
52
  *
44
53
  * If not specified, `LevelStage.BASEMENT_2` (2) will be used.
45
54
  *
@@ -65,7 +74,7 @@ export type CustomStageTSConfig = Readonly<{
65
74
  * the graphics for the walls and floor.) If not specified, the graphics for Basement will be
66
75
  * used.
67
76
  */
68
- backdropPNGPaths?: Readonly<{
77
+ backdropPNGPaths?: {
69
78
  /**
70
79
  * An array that contains the full paths to the graphic files that are used for the floor in
71
80
  * narrow rooms. (The "n" stands for "narrow").
@@ -75,7 +84,7 @@ export type CustomStageTSConfig = Readonly<{
75
84
  *
76
85
  * For an example of this, see the vanilla file "resources/gfx/backdrop/01_basement_nfloor.png".
77
86
  */
78
- nFloors: readonly string[];
87
+ nFloors: string[];
79
88
 
80
89
  /**
81
90
  * An array that contains the full paths to the graphic files that are used for the floor in L
@@ -86,7 +95,7 @@ export type CustomStageTSConfig = Readonly<{
86
95
  *
87
96
  * For an example of this, see the vanilla file "resources/gfx/backdrop/01_lbasementfloor.png".
88
97
  */
89
- lFloors: readonly string[];
98
+ lFloors: string[];
90
99
 
91
100
  /**
92
101
  * An array that contains the full paths to the graphic files that are used for the walls of the
@@ -99,7 +108,7 @@ export type CustomStageTSConfig = Readonly<{
99
108
  * the vanilla file, they concatenate all four variations together into one PNG file. However,
100
109
  * for the custom stages feature, you must separate each wall variation into a separate file.)
101
110
  */
102
- walls: readonly string[];
111
+ walls: string[];
103
112
 
104
113
  /**
105
114
  * An array that contains the full paths to the graphic files for the stage's corners.
@@ -114,8 +123,8 @@ export type CustomStageTSConfig = Readonly<{
114
123
  * you must separate each corner variation into a separate file (and put it in a different file
115
124
  * from the walls).
116
125
  */
117
- corners: readonly string[];
118
- }>;
126
+ corners: string[];
127
+ };
119
128
 
120
129
  /**
121
130
  * Optional. The full path to the spritesheet that contains the graphics of the decorations for
@@ -153,7 +162,7 @@ export type CustomStageTSConfig = Readonly<{
153
162
  * Optional. A collection of paths that contain graphics for the doors of the floor. If not
154
163
  * specified, the doors for Basement will be used.
155
164
  */
156
- doorPNGPaths?: Readonly<{
165
+ doorPNGPaths?: {
157
166
  /**
158
167
  * Optional. The full path to the spritesheet that contains the graphics of the normal doors for
159
168
  * the floor.
@@ -261,7 +270,7 @@ export type CustomStageTSConfig = Readonly<{
261
270
  * located at: `resources/gfx/grid/door_02b_chestroomdoor.png`
262
271
  */
263
272
  chestRoom?: string; // RoomType.CHEST (20)
264
- }>;
273
+ };
265
274
 
266
275
  /**
267
276
  * Optional. An array of shadow objects that describe the graphics for the custom shadows of the
@@ -269,7 +278,7 @@ export type CustomStageTSConfig = Readonly<{
269
278
  * Basement, a shadow of a sideways V is used, among others.) If not specified, no extra shadows
270
279
  * will be drawn.
271
280
  */
272
- shadows?: Readonly<{
281
+ shadows?: {
273
282
  /**
274
283
  * Optional. An array containing the shadows that will be used in rooms of shape
275
284
  * `RoomShape.SHAPE_1x1` (1), `RoomShape.IH` (2), and `RoomShape.IV` (3).
@@ -278,7 +287,7 @@ export type CustomStageTSConfig = Readonly<{
278
287
  *
279
288
  * If not specified, no extra shadows will be drawn in these room shapes.
280
289
  */
281
- "1x1"?: readonly CustomStageShadow[];
290
+ "1x1"?: CustomStageShadow[];
282
291
 
283
292
  /**
284
293
  * Optional. An array containing the shadows that will be used in rooms of shape
@@ -288,7 +297,7 @@ export type CustomStageTSConfig = Readonly<{
288
297
  *
289
298
  * If not specified, no extra shadows will be drawn in these room shapes.
290
299
  */
291
- "1x2"?: readonly CustomStageShadow[];
300
+ "1x2"?: CustomStageShadow[];
292
301
 
293
302
  /**
294
303
  * Optional. An array containing the shadows that will be used in rooms of shape
@@ -298,7 +307,7 @@ export type CustomStageTSConfig = Readonly<{
298
307
  *
299
308
  * If not specified, no extra shadows will be drawn in these room shapes.
300
309
  */
301
- "2x1"?: readonly CustomStageShadow[];
310
+ "2x1"?: CustomStageShadow[];
302
311
 
303
312
  /**
304
313
  * Optional. An array containing the shadows that will be used in rooms of shape
@@ -309,14 +318,22 @@ export type CustomStageTSConfig = Readonly<{
309
318
  *
310
319
  * If not specified, no extra shadows will be drawn in these room shapes.
311
320
  */
312
- "2x2"?: readonly CustomStageShadow[];
313
- }>;
321
+ "2x2"?: CustomStageShadow[];
322
+ };
314
323
 
315
- /** Optional. An array containing the bosses that should be used for the stage. */
316
- bossPool?: readonly CustomStageBossPoolEntry[];
324
+ /**
325
+ * Optional. An array containing the bosses that should be used for the stage. This can include
326
+ * both vanilla bosses and modded bosses.
327
+ */
328
+ bossPool?: CustomStageBossPoolEntry[];
317
329
 
318
- /** Optional. A collection of colors used in the boss "versus" screen. */
319
- versusScreen?: Readonly<{
330
+ /**
331
+ * Optional. A collection of colors used for in the boss "versus" screen for all of the bosses.
332
+ *
333
+ * Note that these graphics will only be applied if one or more bosses are specified in the
334
+ * `bossPool` field.
335
+ */
336
+ versusScreen?: {
320
337
  /**
321
338
  * Optional. An object representing the color to use for the background of the boss "versus"
322
339
  * screen. If not specified, the color for Basement 1 will be used.
@@ -324,7 +341,7 @@ export type CustomStageTSConfig = Readonly<{
324
341
  * For a list of the colors that correspond to the vanilla stages, see
325
342
  * `versusScreenBackgroundColors.ts`.
326
343
  */
327
- backgroundColor?: Readonly<{
344
+ backgroundColor?: {
328
345
  /**
329
346
  * @minimum 0
330
347
  * @maximum 1
@@ -348,7 +365,7 @@ export type CustomStageTSConfig = Readonly<{
348
365
  * @maximum 1
349
366
  */
350
367
  a: number;
351
- }>;
368
+ };
352
369
 
353
370
  /**
354
371
  * Optional. An object representing the color to use for the dirt spots in the boss "versus"
@@ -358,7 +375,7 @@ export type CustomStageTSConfig = Readonly<{
358
375
  * For a list of the colors that correspond to the vanilla stages, see
359
376
  * `versusScreenDirtSpotColors.ts`.
360
377
  */
361
- dirtSpotColor?: Readonly<{
378
+ dirtSpotColor?: {
362
379
  /**
363
380
  * @minimum 0
364
381
  * @maximum 1
@@ -382,16 +399,16 @@ export type CustomStageTSConfig = Readonly<{
382
399
  * @maximum 1
383
400
  */
384
401
  a: number;
385
- }>;
386
- }>;
387
- }>;
402
+ };
403
+ };
404
+ }
388
405
 
389
406
  /**
390
407
  * A description of a custom stage shadow. (In this context, "shadows" are the outlines from things
391
408
  * on the roof. For example, in Basement, a shadow of a sideways V is used, among others.)
392
409
  */
393
410
  // ts-prune-ignore-next
394
- export type CustomStageShadow = Readonly<{
411
+ export interface CustomStageShadow {
395
412
  /**
396
413
  * The full path to the shadow overlay PNG file.
397
414
  *
@@ -406,7 +423,7 @@ export type CustomStageShadow = Readonly<{
406
423
  * If not specified, an object of `{ r: 0, g: 0, b: 0, a: 0.25 }` will be used (which corresponds
407
424
  * to 75% faded black).
408
425
  */
409
- color?: Readonly<{
426
+ color?: {
410
427
  /**
411
428
  * @minimum 0
412
429
  * @maximum 1
@@ -430,27 +447,66 @@ export type CustomStageShadow = Readonly<{
430
447
  * @maximum 1
431
448
  */
432
449
  a: number;
433
- }>;
434
- }>;
450
+ };
451
+ }
435
452
 
436
- /** An object that represents a possible boss for a custom stage. */
453
+ /**
454
+ * An object that represents a possible boss for a custom stage. This can be for a vanilla boss or a
455
+ * custom boss.
456
+ */
437
457
  // ts-prune-ignore-next
438
458
  export interface CustomStageBossPoolEntry {
439
459
  /**
440
- * The name of the boss. This must correspond to the entry in "entities2.xml".
441
- *
442
- * Note that since there is no way to determine the corresponding `EntityType` of the boss during
443
- * compile-time, you must specify the `EntityType` at run-time when your mod first loads using the
444
- * `registerCustomBoss` helper function.
460
+ * The name of the boss. This should correspond to the entry for the boss in the "entities2.xml"
461
+ * file.
445
462
  */
446
463
  name: string;
447
464
 
465
+ /**
466
+ * The arbitrary sub-type chosen for this boss, ranging between 1 and 999. You must set the boss
467
+ * rooms for this boss to this sub-type in Basement Renovator by right-clicking on the room on the
468
+ * right-hand-side.
469
+ *
470
+ * It does not matter if the arbitrary sub-type overlaps with any of the vanilla `BossID` values
471
+ * (e.g. vanilla Boss Room sub-types in "00.special_rooms.stb"). It also does not matter if this
472
+ * value overlaps with the values from other mods.
473
+ *
474
+ * If you are creating an entry for a vanilla boss, it is recommended that you match the sub-type
475
+ * with the corresponding vanilla `BossID` value. This will make things a bit easier to understand
476
+ * for people working on your mod, but is not a hard requirement.
477
+ *
478
+ * @minimum 1
479
+ * @maximum 999
480
+ */
481
+ subType: number;
482
+
448
483
  /**
449
484
  * The weight of the boss. This is used when randomly selecting which boss to use for the floor.
450
485
  * For example, use a value of 1 if you want this boss to be equally likely as any other boss, 0.5
451
486
  * if you want it to be half as likely, 2 if you want it to be twice as likely, and so on.
452
487
  */
453
488
  weight: number;
489
+
490
+ /** Optional. A collection of sprites used for the boss on the "versus" screen. */
491
+ versusScreen?: {
492
+ // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
493
+ /**
494
+ * Mandatory. The full path to the spritesheet that contains the graphics of the name of the
495
+ * boss that will be displayed on the top of the boss "versus" screen.
496
+ *
497
+ * If not specified, a sprite showing "???" will be used.
498
+ */
499
+ namePNGPath: string;
500
+
501
+ // eslint-disable-next-line isaacscript/complete-sentences-jsdoc
502
+ /**
503
+ * Mandatory. The full path to the spritesheet that contains the portrait of the boss that will
504
+ * be displayed on the right side of the boss "versus" screen.
505
+ *
506
+ * If not specified, a sprite showing "???" will be used.
507
+ */
508
+ portraitPNGPath: string;
509
+ };
454
510
  }
455
511
 
456
512
  /**
@@ -460,19 +516,29 @@ export interface CustomStageBossPoolEntry {
460
516
  *
461
517
  * The `CustomStage` interface extends this, adding more data.
462
518
  */
463
- export interface CustomStageLua extends CustomStageTSConfig {
464
- readonly roomsMetadata: readonly CustomStageRoomMetadata[];
519
+ interface CustomStageLuaUnsafe extends CustomStageTSConfig {
520
+ /**
521
+ * This contains metadata about each room in a custom stage, which is used at run-time.
522
+ * (Internally, the IsaacScript standard library uses this as a basis for determining which rooms
523
+ * should randomly appear on the floor.)
524
+ */
525
+ roomsMetadata: CustomStageRoomMetadata[];
465
526
  }
466
527
 
528
+ /** @internal */
529
+ export type CustomStageLua = Immutable<CustomStageLuaUnsafe>;
530
+
467
531
  /**
468
532
  * Metadata about a custom stage room. Each custom stage object contains an array with metadata for
469
533
  * each room.
534
+ *
535
+ * @internal
470
536
  */
471
- export type CustomStageRoomMetadata = Readonly<{
537
+ export interface CustomStageRoomMetadata {
472
538
  type: number;
473
539
  variant: number;
474
540
  subType: number;
475
541
  shape: number;
476
542
  doorSlotFlags: number;
477
543
  weight: number;
478
- }>;
544
+ }
@@ -18,7 +18,7 @@ export interface GridEntityCustomData {
18
18
 
19
19
  roomListIndex: int;
20
20
  gridIndex: int;
21
- anm2Path: string;
21
+ gridCollisionClass?: GridCollisionClass;
22
+ anm2Path?: string;
22
23
  defaultAnimation?: string;
23
- gridCollisionClass: GridCollisionClass;
24
24
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The standard library has the feature to deploy a new room on-the-fly with the `deployJSONRoom`
3
3
  * helper function. It requires a `JSONRoomsFile` as an argument, which is simply an XML file
4
- * converted to JSON. (You create XML room files using the Basement Renovator program.)
4
+ * converted to JSON. (You can create XML room files using the Basement Renovator program.)
5
5
  *
6
6
  * You can convert your XML files using the following command:
7
7
  *
@@ -17,11 +17,12 @@ export interface JSONRoomsFile {
17
17
  rooms: JSONRooms;
18
18
  }
19
19
 
20
+ /** Part of `JSONRoomsFile`. */
20
21
  export interface JSONRooms {
21
22
  room: JSONRoom[];
22
23
  }
23
24
 
24
- /** Part of `JSONRooms`. */
25
+ /** Part of `JSONRoomsFile`. */
25
26
  export interface JSONRoom {
26
27
  $: {
27
28
  /** Needs to be converted to an `int`. */
@@ -55,7 +56,7 @@ export interface JSONRoom {
55
56
  spawn: JSONSpawn[];
56
57
  }
57
58
 
58
- /** Part of `JSONRooms`. */
59
+ /** Part of `JSONRoomsFile`. */
59
60
  export interface JSONDoor {
60
61
  $: {
61
62
  /** Equal to "True" or "False". Needs to be converted to an `boolean`. */
@@ -69,7 +70,7 @@ export interface JSONDoor {
69
70
  };
70
71
  }
71
72
 
72
- /** Part of `JSONRooms`. */
73
+ /** Part of `JSONRoomsFile`. */
73
74
  export interface JSONSpawn {
74
75
  $: {
75
76
  /** Needs to be converted to an `int`. */
@@ -82,7 +83,7 @@ export interface JSONSpawn {
82
83
  entity: JSONEntity[];
83
84
  }
84
85
 
85
- /** Part of `JSONRooms`. */
86
+ /** Part of `JSONRoomsFile`. */
86
87
  export interface JSONEntity {
87
88
  $: {
88
89
  /** Needs to be converted to an `int`. */