isaacscript-common 31.5.0 → 31.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 (126) hide show
  1. package/dist/index.rollup.d.ts +26 -4
  2. package/dist/isaacscript-common.lua +626 -645
  3. package/dist/src/classes/ModFeature.d.ts.map +1 -1
  4. package/dist/src/classes/ModFeature.lua +5 -9
  5. package/dist/src/classes/ModUpgraded.d.ts.map +1 -1
  6. package/dist/src/classes/ModUpgraded.lua +8 -14
  7. package/dist/src/classes/callbacks/PostNewRoomEarly.lua +2 -2
  8. package/dist/src/classes/features/callbackLogic/CustomGridEntities.d.ts.map +1 -1
  9. package/dist/src/classes/features/callbackLogic/CustomGridEntities.lua +3 -3
  10. package/dist/src/classes/features/other/CharacterHealthConversion.lua +1 -1
  11. package/dist/src/classes/features/other/CustomItemPools.d.ts.map +1 -1
  12. package/dist/src/classes/features/other/CustomItemPools.lua +12 -6
  13. package/dist/src/classes/features/other/CustomStages.d.ts.map +1 -1
  14. package/dist/src/classes/features/other/CustomStages.lua +12 -14
  15. package/dist/src/classes/features/other/CustomTrapdoors.d.ts.map +1 -1
  16. package/dist/src/classes/features/other/CustomTrapdoors.lua +6 -8
  17. package/dist/src/classes/features/other/DeployJSONRoom.d.ts.map +1 -1
  18. package/dist/src/classes/features/other/DeployJSONRoom.lua +15 -15
  19. package/dist/src/classes/features/other/ModdedElementSets.d.ts.map +1 -1
  20. package/dist/src/classes/features/other/ModdedElementSets.lua +21 -12
  21. package/dist/src/classes/features/other/Pause.d.ts.map +1 -1
  22. package/dist/src/classes/features/other/Pause.lua +4 -6
  23. package/dist/src/classes/features/other/SaveDataManager.d.ts.map +1 -1
  24. package/dist/src/classes/features/other/SaveDataManager.lua +5 -9
  25. package/dist/src/classes/features/other/customStages/backdrop.lua +9 -10
  26. package/dist/src/classes/features/other/saveDataManager/restoreDefaults.lua +1 -1
  27. package/dist/src/functions/array.d.ts +3 -0
  28. package/dist/src/functions/array.d.ts.map +1 -1
  29. package/dist/src/functions/array.lua +9 -3
  30. package/dist/src/functions/bitSet128.d.ts.map +1 -1
  31. package/dist/src/functions/bitSet128.lua +4 -6
  32. package/dist/src/functions/bitwise.d.ts.map +1 -1
  33. package/dist/src/functions/bitwise.lua +7 -3
  34. package/dist/src/functions/color.d.ts.map +1 -1
  35. package/dist/src/functions/color.lua +5 -9
  36. package/dist/src/functions/deepCopy.lua +23 -31
  37. package/dist/src/functions/entities.d.ts.map +1 -1
  38. package/dist/src/functions/entities.lua +20 -18
  39. package/dist/src/functions/entitiesSpecific.d.ts.map +1 -1
  40. package/dist/src/functions/entitiesSpecific.lua +11 -27
  41. package/dist/src/functions/enums.d.ts +6 -4
  42. package/dist/src/functions/enums.d.ts.map +1 -1
  43. package/dist/src/functions/enums.lua +13 -9
  44. package/dist/src/functions/gridEntities.d.ts.map +1 -1
  45. package/dist/src/functions/gridEntities.lua +18 -11
  46. package/dist/src/functions/gridEntitiesSpecific.d.ts.map +1 -1
  47. package/dist/src/functions/gridEntitiesSpecific.lua +16 -28
  48. package/dist/src/functions/input.d.ts +3 -0
  49. package/dist/src/functions/input.d.ts.map +1 -1
  50. package/dist/src/functions/input.lua +14 -14
  51. package/dist/src/functions/jsonRoom.d.ts.map +1 -1
  52. package/dist/src/functions/jsonRoom.lua +35 -23
  53. package/dist/src/functions/kColor.d.ts.map +1 -1
  54. package/dist/src/functions/kColor.lua +6 -12
  55. package/dist/src/functions/map.d.ts.map +1 -1
  56. package/dist/src/functions/map.lua +3 -3
  57. package/dist/src/functions/minimap.d.ts.map +1 -1
  58. package/dist/src/functions/minimap.lua +17 -9
  59. package/dist/src/functions/players.d.ts.map +1 -1
  60. package/dist/src/functions/players.lua +17 -22
  61. package/dist/src/functions/rng.d.ts.map +1 -1
  62. package/dist/src/functions/rng.lua +3 -3
  63. package/dist/src/functions/roomShapeWalls.d.ts.map +1 -1
  64. package/dist/src/functions/roomShapeWalls.lua +7 -3
  65. package/dist/src/functions/roomTransition.d.ts.map +1 -1
  66. package/dist/src/functions/roomTransition.lua +7 -3
  67. package/dist/src/functions/rooms.d.ts.map +1 -1
  68. package/dist/src/functions/rooms.lua +8 -5
  69. package/dist/src/functions/serialization.d.ts.map +1 -1
  70. package/dist/src/functions/serialization.lua +8 -18
  71. package/dist/src/functions/table.d.ts.map +1 -1
  72. package/dist/src/functions/table.lua +6 -12
  73. package/dist/src/functions/tstlClass.d.ts.map +1 -1
  74. package/dist/src/functions/tstlClass.lua +3 -3
  75. package/dist/src/functions/utils.d.ts +9 -0
  76. package/dist/src/functions/utils.d.ts.map +1 -1
  77. package/dist/src/functions/utils.lua +14 -6
  78. package/dist/src/functions/vector.d.ts.map +1 -1
  79. package/dist/src/functions/vector.lua +4 -6
  80. package/dist/src/functions/weighted.d.ts.map +1 -1
  81. package/dist/src/functions/weighted.lua +7 -3
  82. package/dist/src/sets/bossSets.d.ts.map +1 -1
  83. package/dist/src/sets/bossSets.lua +3 -3
  84. package/package.json +2 -2
  85. package/src/classes/ModFeature.ts +16 -12
  86. package/src/classes/ModUpgraded.ts +18 -16
  87. package/src/classes/callbacks/PostNewRoomEarly.ts +2 -2
  88. package/src/classes/features/callbackLogic/CustomGridEntities.ts +2 -3
  89. package/src/classes/features/other/CharacterHealthConversion.ts +1 -1
  90. package/src/classes/features/other/CustomItemPools.ts +9 -8
  91. package/src/classes/features/other/CustomStages.ts +9 -10
  92. package/src/classes/features/other/CustomTrapdoors.ts +9 -10
  93. package/src/classes/features/other/DeployJSONRoom.ts +21 -21
  94. package/src/classes/features/other/ModdedElementSets.ts +18 -21
  95. package/src/classes/features/other/Pause.ts +9 -6
  96. package/src/classes/features/other/SaveDataManager.ts +14 -16
  97. package/src/classes/features/other/customStages/backdrop.ts +5 -6
  98. package/src/classes/features/other/saveDataManager/restoreDefaults.ts +1 -1
  99. package/src/functions/array.ts +8 -6
  100. package/src/functions/bitSet128.ts +9 -10
  101. package/src/functions/bitwise.ts +6 -3
  102. package/src/functions/color.ts +13 -15
  103. package/src/functions/deepCopy.ts +18 -24
  104. package/src/functions/deepCopyTests.ts +5 -6
  105. package/src/functions/entities.ts +22 -20
  106. package/src/functions/entitiesSpecific.ts +10 -27
  107. package/src/functions/enums.ts +29 -17
  108. package/src/functions/gridEntities.ts +14 -16
  109. package/src/functions/gridEntitiesSpecific.ts +15 -28
  110. package/src/functions/input.ts +3 -3
  111. package/src/functions/jsonRoom.ts +39 -27
  112. package/src/functions/kColor.ts +17 -20
  113. package/src/functions/map.ts +5 -5
  114. package/src/functions/minimap.ts +16 -15
  115. package/src/functions/players.ts +7 -10
  116. package/src/functions/rng.ts +5 -5
  117. package/src/functions/roomShapeWalls.ts +3 -4
  118. package/src/functions/roomTransition.ts +5 -5
  119. package/src/functions/rooms.ts +5 -6
  120. package/src/functions/serialization.ts +25 -30
  121. package/src/functions/table.ts +18 -20
  122. package/src/functions/tstlClass.ts +5 -5
  123. package/src/functions/utils.ts +27 -6
  124. package/src/functions/vector.ts +9 -10
  125. package/src/functions/weighted.ts +5 -5
  126. package/src/sets/bossSets.ts +5 -5
@@ -15,6 +15,7 @@ import {
15
15
  spawnGridEntityWithVariant,
16
16
  } from "./gridEntities";
17
17
  import { asNumber } from "./types";
18
+ import { assertDefined } from "./utils";
18
19
 
19
20
  /**
20
21
  * Helper function to get all of the grid entities of type `GridEntityType.CRAWL_SPACE` (18) in the
@@ -421,13 +422,11 @@ export function spawnDoorWithVariant(
421
422
  gridIndexOrPosition,
422
423
  );
423
424
  if (gridEntity === undefined) {
424
- return gridEntity;
425
+ return undefined;
425
426
  }
426
427
 
427
428
  const door = gridEntity.ToDoor();
428
- if (door === undefined) {
429
- error("Failed to spawn a door.");
430
- }
429
+ assertDefined(door, "Failed to spawn a door.");
431
430
 
432
431
  return door;
433
432
  }
@@ -450,13 +449,11 @@ export function spawnPitWithVariant(
450
449
  gridIndexOrPosition,
451
450
  );
452
451
  if (gridEntity === undefined) {
453
- return gridEntity;
452
+ return undefined;
454
453
  }
455
454
 
456
455
  const pit = gridEntity.ToPit();
457
- if (pit === undefined) {
458
- error("Failed to spawn a pit.");
459
- }
456
+ assertDefined(pit, "Failed to spawn a pit.");
460
457
 
461
458
  return pit;
462
459
  }
@@ -482,13 +479,11 @@ export function spawnPoopWithVariant(
482
479
  gridIndexOrPosition,
483
480
  );
484
481
  if (gridEntity === undefined) {
485
- return gridEntity;
482
+ return undefined;
486
483
  }
487
484
 
488
485
  const poop = gridEntity.ToPoop();
489
- if (poop === undefined) {
490
- error("Failed to spawn a poop.");
491
- }
486
+ assertDefined(poop, "Failed to spawn a poop.");
492
487
 
493
488
  return poop;
494
489
  }
@@ -514,13 +509,11 @@ export function spawnPressurePlateWithVariant(
514
509
  gridIndexOrPosition,
515
510
  );
516
511
  if (gridEntity === undefined) {
517
- return gridEntity;
512
+ return undefined;
518
513
  }
519
514
 
520
515
  const pressurePlate = gridEntity.ToPressurePlate();
521
- if (pressurePlate === undefined) {
522
- error("Failed to spawn a pressure plate.");
523
- }
516
+ assertDefined(pressurePlate, "Failed to spawn a pressure plate.");
524
517
 
525
518
  return pressurePlate;
526
519
  }
@@ -543,13 +536,11 @@ export function spawnRockWithVariant(
543
536
  gridIndexOrPosition,
544
537
  );
545
538
  if (gridEntity === undefined) {
546
- return gridEntity;
539
+ return undefined;
547
540
  }
548
541
 
549
542
  const rock = gridEntity.ToRock();
550
- if (rock === undefined) {
551
- error("Failed to spawn a rock.");
552
- }
543
+ assertDefined(rock, "Failed to spawn a rock.");
553
544
 
554
545
  return rock;
555
546
  }
@@ -572,13 +563,11 @@ export function spawnSpikesWithVariant(
572
563
  gridIndexOrPosition,
573
564
  );
574
565
  if (gridEntity === undefined) {
575
- return gridEntity;
566
+ return undefined;
576
567
  }
577
568
 
578
569
  const spikes = gridEntity.ToSpikes();
579
- if (spikes === undefined) {
580
- error("Failed to spawn spikes.");
581
- }
570
+ assertDefined(spikes, "Failed to spawn spikes.");
582
571
 
583
572
  return spikes;
584
573
  }
@@ -601,13 +590,11 @@ export function spawnTNTWithVariant(
601
590
  gridIndexOrPosition,
602
591
  );
603
592
  if (gridEntity === undefined) {
604
- return gridEntity;
593
+ return undefined;
605
594
  }
606
595
 
607
596
  const tnt = gridEntity.ToTNT();
608
- if (tnt === undefined) {
609
- error("Failed to spawn TNT.");
610
- }
597
+ assertDefined(tnt, "Failed to spawn TNT.");
611
598
 
612
599
  return tnt;
613
600
  }
@@ -9,7 +9,7 @@ import { KEYBOARD_TO_STRING } from "../maps/keyboardToString";
9
9
  import { ReadonlySet } from "../types/ReadonlySet";
10
10
  import { trimPrefix } from "./string";
11
11
 
12
- const MODIFIER_KEYS = [
12
+ export const MODIFIER_KEYS = [
13
13
  Keyboard.LEFT_SHIFT, // 340
14
14
  Keyboard.LEFT_CONTROL, // 341
15
15
  Keyboard.LEFT_ALT, // 342
@@ -20,7 +20,7 @@ const MODIFIER_KEYS = [
20
20
  Keyboard.RIGHT_SUPER, // 347
21
21
  ] as const;
22
22
 
23
- const MOVEMENT_ACTIONS = [
23
+ export const MOVEMENT_ACTIONS = [
24
24
  ButtonAction.LEFT, // 0
25
25
  ButtonAction.RIGHT, // 1
26
26
  ButtonAction.UP, // 2
@@ -31,7 +31,7 @@ export const MOVEMENT_ACTIONS_SET = new ReadonlySet<ButtonAction>(
31
31
  MOVEMENT_ACTIONS,
32
32
  );
33
33
 
34
- const SHOOTING_ACTIONS = [
34
+ export const SHOOTING_ACTIONS = [
35
35
  ButtonAction.SHOOT_LEFT, // 4
36
36
  ButtonAction.SHOOT_RIGHT, // 5
37
37
  ButtonAction.SHOOT_UP, // 6
@@ -1,12 +1,14 @@
1
- import type { DoorSlotFlag, RoomShape } from "isaac-typescript-definitions";
2
- import { DoorSlotFlagZero } from "isaac-typescript-definitions";
1
+ import type { DoorSlotFlag } from "isaac-typescript-definitions";
2
+ import { DoorSlotFlagZero, RoomShape } from "isaac-typescript-definitions";
3
3
  import type { JSONEntity, JSONRoom } from "../interfaces/JSONRoomsFile";
4
4
  import { sumArray } from "./array";
5
5
  import { doorSlotToDoorSlotFlag, getRoomShapeDoorSlot } from "./doors";
6
+ import { isEnumValue } from "./enums";
6
7
  import { addFlag } from "./flag";
7
8
  import { log } from "./log";
8
9
  import { getRandomFloat } from "./random";
9
10
  import { getRandomSeed } from "./rng";
11
+ import { assertDefined } from "./utils";
10
12
 
11
13
  /** This represents either a `JSONRoom` or a `JSONEntity`. */
12
14
  interface JSONObject {
@@ -24,9 +26,14 @@ export function getJSONRoomDoorSlotFlags(
24
26
  ): BitFlags<DoorSlotFlag> {
25
27
  const roomShapeString = jsonRoom.$.shape;
26
28
  const roomShapeNumber = tonumber(roomShapeString);
27
- if (roomShapeNumber === undefined) {
29
+ assertDefined(
30
+ roomShapeNumber,
31
+ `Failed to parse the "shape" field of a JSON room: ${roomShapeString}`,
32
+ );
33
+
34
+ if (!isEnumValue(roomShapeNumber, RoomShape)) {
28
35
  error(
29
- `Failed to parse the "shape" field of a JSON room: ${roomShapeString}`,
36
+ `Failed to parse the "shape" field of a JSON room since it was an invalid number: ${roomShapeNumber}`,
30
37
  );
31
38
  }
32
39
  const roomShape = roomShapeNumber as RoomShape;
@@ -47,22 +54,23 @@ export function getJSONRoomDoorSlotFlags(
47
54
 
48
55
  const xString = door.$.x;
49
56
  const x = tonumber(xString);
50
- if (x === undefined) {
51
- error(`Failed to parse the "x" field of a JSON room door: ${xString}`);
52
- }
57
+ assertDefined(
58
+ x,
59
+ `Failed to parse the "x" field of a JSON room door: ${xString}`,
60
+ );
53
61
 
54
62
  const yString = door.$.y;
55
63
  const y = tonumber(yString);
56
- if (y === undefined) {
57
- error(`Failed to parse the "y" field of a JSON room door: ${yString}`);
58
- }
64
+ assertDefined(
65
+ y,
66
+ `Failed to parse the "y" field of a JSON room door: ${yString}`,
67
+ );
59
68
 
60
69
  const doorSlot = getRoomShapeDoorSlot(roomShape, x, y);
61
- if (doorSlot === undefined) {
62
- error(
63
- `Failed to retrieve the door slot for a JSON room door at coordinates: [${x}, ${y}]`,
64
- );
65
- }
70
+ assertDefined(
71
+ doorSlot,
72
+ `Failed to retrieve the door slot for a JSON room door at coordinates: [${x}, ${y}]`,
73
+ );
66
74
 
67
75
  const doorSlotFlag = doorSlotToDoorSlotFlag(doorSlot);
68
76
  doorSlotFlags = addFlag(doorSlotFlags, doorSlotFlag);
@@ -159,9 +167,10 @@ export function getRandomJSONEntity(
159
167
  jsonEntities,
160
168
  chosenWeight,
161
169
  );
162
- if (randomJSONEntity === undefined) {
163
- error(`Failed to get a JSON entity with chosen weight: ${chosenWeight}`);
164
- }
170
+ assertDefined(
171
+ randomJSONEntity,
172
+ `Failed to get a JSON entity with chosen weight: ${chosenWeight}`,
173
+ );
165
174
 
166
175
  return randomJSONEntity;
167
176
  }
@@ -197,9 +206,10 @@ export function getRandomJSONRoom(
197
206
  }
198
207
 
199
208
  const randomJSONRoom = getJSONObjectWithChosenWeight(jsonRooms, chosenWeight);
200
- if (randomJSONRoom === undefined) {
201
- error(`Failed to get a JSON room with chosen weight: ${chosenWeight}`);
202
- }
209
+ assertDefined(
210
+ randomJSONRoom,
211
+ `Failed to get a JSON room with chosen weight: ${chosenWeight}`,
212
+ );
203
213
 
204
214
  return randomJSONRoom;
205
215
  }
@@ -208,9 +218,10 @@ function getTotalWeightOfJSONObject(jsonOjectArray: JSONObject[]): float {
208
218
  const weights = jsonOjectArray.map((jsonObject) => {
209
219
  const weightString = jsonObject.$.weight;
210
220
  const weight = tonumber(weightString);
211
- if (weight === undefined) {
212
- error(`Failed to parse the weight of a JSON object: ${weightString}.`);
213
- }
221
+ assertDefined(
222
+ weight,
223
+ `Failed to parse the weight of a JSON object: ${weightString}.`,
224
+ );
214
225
 
215
226
  return weight;
216
227
  });
@@ -227,9 +238,10 @@ function getJSONObjectWithChosenWeight<T extends JSONObject>(
227
238
  for (const jsonObject of jsonOjectArray) {
228
239
  const weightString = jsonObject.$.weight;
229
240
  const weight = tonumber(weightString);
230
- if (weight === undefined) {
231
- error(`Failed to parse the weight of a JSON object: ${weightString}`);
232
- }
241
+ assertDefined(
242
+ weight,
243
+ `Failed to parse the weight of a JSON object: ${weightString}`,
244
+ );
233
245
 
234
246
  weightAccumulator += weight;
235
247
  if (weightAccumulator >= chosenWeight) {
@@ -9,6 +9,7 @@ import {
9
9
  tableHasKeys,
10
10
  } from "./table";
11
11
  import { isTable } from "./types";
12
+ import { assertDefined } from "./utils";
12
13
 
13
14
  export type SerializedKColor = LuaMap<string, unknown> & {
14
15
  readonly __serializedKColorBrand: symbol;
@@ -42,26 +43,22 @@ export function deserializeKColor(kColor: SerializedKColor): KColor {
42
43
 
43
44
  const [r, g, b, a] = getNumbersFromTable(kColor, OBJECT_NAME, ...KEYS);
44
45
 
45
- if (r === undefined) {
46
- error(
47
- `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Red`,
48
- );
49
- }
50
- if (g === undefined) {
51
- error(
52
- `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Green`,
53
- );
54
- }
55
- if (b === undefined) {
56
- error(
57
- `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Blue`,
58
- );
59
- }
60
- if (a === undefined) {
61
- error(
62
- `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Alpha`,
63
- );
64
- }
46
+ assertDefined(
47
+ r,
48
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Red`,
49
+ );
50
+ assertDefined(
51
+ g,
52
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Green`,
53
+ );
54
+ assertDefined(
55
+ b,
56
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Blue`,
57
+ );
58
+ assertDefined(
59
+ a,
60
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: Alpha`,
61
+ );
65
62
 
66
63
  return KColor(r, g, b, a);
67
64
  }
@@ -1,6 +1,7 @@
1
1
  import type { DefaultMap } from "../classes/DefaultMap";
2
2
  import { sumArray } from "./array";
3
3
  import { getPartialMatch } from "./string";
4
+ import { assertDefined } from "./utils";
4
5
 
5
6
  /** Helper function to copy a map. (You can also use a Map constructor to accomplish this task.) */
6
7
  export function copyMap<K, V>(
@@ -73,11 +74,10 @@ export function getMapPartialMatch<T>(
73
74
  }
74
75
 
75
76
  const value = map.get(matchingKey);
76
- if (value === undefined) {
77
- error(
78
- `Failed to get the map value corresponding to the partial match of: ${matchingKey}`,
79
- );
80
- }
77
+ assertDefined(
78
+ value,
79
+ `Failed to get the map value corresponding to the partial match of: ${matchingKey}`,
80
+ );
81
81
 
82
82
  return [matchingKey, value];
83
83
  }
@@ -4,6 +4,7 @@ import { game } from "../core/cachedClasses";
4
4
  import { addFlag } from "./flag";
5
5
  import { getRoomDescriptor, getRoomGridIndex } from "./roomData";
6
6
  import { getRoomsInsideGrid } from "./rooms";
7
+ import { assertDefined } from "./utils";
7
8
 
8
9
  /**
9
10
  * Helper function to add a `DisplayFlag` to a particular room's minimap display flags (e.g. whether
@@ -101,11 +102,11 @@ export function getRoomDisplayFlags(
101
102
  }
102
103
 
103
104
  const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
104
- if (minimapAPIRoomDescriptor === undefined) {
105
- error(
106
- `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
107
- );
108
- }
105
+ assertDefined(
106
+ minimapAPIRoomDescriptor,
107
+ `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
108
+ );
109
+
109
110
  return minimapAPIRoomDescriptor.GetDisplayFlags();
110
111
  }
111
112
 
@@ -126,11 +127,11 @@ export function hideRoomOnMinimap(roomGridIndex: int): void {
126
127
  // `Hidden` property.
127
128
  if (MinimapAPI !== undefined) {
128
129
  const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
129
- if (minimapAPIRoomDescriptor === undefined) {
130
- error(
131
- `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
132
- );
133
- }
130
+ assertDefined(
131
+ minimapAPIRoomDescriptor,
132
+ `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
133
+ );
134
+
134
135
  minimapAPIRoomDescriptor.Hidden = true;
135
136
  }
136
137
  }
@@ -225,11 +226,11 @@ export function setRoomDisplayFlags(
225
226
  }
226
227
  } else {
227
228
  const minimapAPIRoomDescriptor = MinimapAPI.GetRoomByIdx(roomGridIndex);
228
- if (minimapAPIRoomDescriptor === undefined) {
229
- error(
230
- `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
231
- );
232
- }
229
+ assertDefined(
230
+ minimapAPIRoomDescriptor,
231
+ `Failed to get the MinimapAPI room descriptor for the room at grid index: ${roomGridIndex}`,
232
+ );
233
+
233
234
  minimapAPIRoomDescriptor.SetDisplayFlags(displayFlags);
234
235
  }
235
236
  }
@@ -23,7 +23,7 @@ import {
23
23
  getPlayers,
24
24
  } from "./playerIndex";
25
25
  import { isNumber } from "./types";
26
- import { repeat } from "./utils";
26
+ import { assertDefined, repeat } from "./utils";
27
27
 
28
28
  /**
29
29
  * Helper function to add one or more collectibles to a player.
@@ -217,9 +217,7 @@ export function getClosestPlayer(position: Vector): EntityPlayer {
217
217
  }
218
218
  }
219
219
 
220
- if (closestPlayer === undefined) {
221
- error("Failed to find the closest player.");
222
- }
220
+ assertDefined(closestPlayer, "Failed to find the closest player.");
223
221
 
224
222
  return closestPlayer;
225
223
  }
@@ -251,9 +249,10 @@ export function getFinalPlayer(): EntityPlayer {
251
249
  const players = getPlayers();
252
250
 
253
251
  const lastPlayer = getLastElement(players);
254
- if (lastPlayer === undefined) {
255
- error("Failed to get the final player since there were 0 players.");
256
- }
252
+ assertDefined(
253
+ lastPlayer,
254
+ "Failed to get the final player since there were 0 players.",
255
+ );
257
256
 
258
257
  return lastPlayer;
259
258
  }
@@ -273,9 +272,7 @@ export function getNewestPlayer(): EntityPlayer {
273
272
  }
274
273
  }
275
274
 
276
- if (newestPlayer === undefined) {
277
- error("Failed to find the newest player.");
278
- }
275
+ assertDefined(newestPlayer, "Failed to find the newest player.");
279
276
 
280
277
  return newestPlayer;
281
278
  }
@@ -4,6 +4,7 @@ import { SerializationBrand } from "../enums/private/SerializationBrand";
4
4
  import { isaacAPIClassEquals, isIsaacAPIClassOfType } from "./isaacAPIClass";
5
5
  import { getNumbersFromTable, tableHasKeys } from "./table";
6
6
  import { isTable } from "./types";
7
+ import { assertDefined } from "./utils";
7
8
 
8
9
  export type SerializedRNG = LuaMap<string, unknown> & {
9
10
  readonly __serializedRNGBrand: symbol;
@@ -45,11 +46,10 @@ export function deserializeRNG(rng: SerializedRNG): RNG {
45
46
 
46
47
  const [seed] = getNumbersFromTable(rng, OBJECT_NAME, ...KEYS);
47
48
 
48
- if (seed === undefined) {
49
- error(
50
- `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: seed`,
51
- );
52
- }
49
+ assertDefined(
50
+ seed,
51
+ `Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: seed`,
52
+ );
53
53
 
54
54
  return newRNG(seed as Seed);
55
55
  }
@@ -7,6 +7,7 @@ import { ReadonlySet } from "../types/ReadonlySet";
7
7
  import { getGridIndexesBetween } from "./gridIndex";
8
8
  import { getRoomShapeCorners, isLRoomShape } from "./roomShape";
9
9
  import { inBossRoomOf, inHomeCloset } from "./rooms";
10
+ import { assertDefined } from "./utils";
10
11
 
11
12
  const ROOM_SHAPE_TO_WALL_GRID_INDEX_SET: ReadonlyMap<
12
13
  RoomShape,
@@ -329,10 +330,8 @@ export function isVanillaWallGridIndex(gridIndex: int): boolean {
329
330
  wallGridIndexSet = MOTHER_ROOM_CORNERS_SET;
330
331
  } else {
331
332
  wallGridIndexSet = ROOM_SHAPE_TO_WALL_GRID_INDEX_SET.get(roomShape);
332
- }
333
-
334
- if (wallGridIndexSet === undefined) {
335
- error(
333
+ assertDefined(
334
+ wallGridIndexSet,
336
335
  `Failed to find the wall grid index set for: RoomShape.${RoomShape[roomShape]} (${roomShape})`,
337
336
  );
338
337
  }
@@ -5,6 +5,7 @@ import {
5
5
  } from "isaac-typescript-definitions";
6
6
  import { game } from "../core/cachedClasses";
7
7
  import { getRoomData, getRoomGridIndex } from "./roomData";
8
+ import { assertDefined } from "./utils";
8
9
 
9
10
  /**
10
11
  * Helper function to reload the current room using `Game.StartRoomTransition`.
@@ -40,11 +41,10 @@ export function teleport(
40
41
  const level = game.GetLevel();
41
42
 
42
43
  const roomData = getRoomData(roomGridIndex);
43
- if (roomData === undefined) {
44
- error(
45
- `Failed to change the room to grid index ${roomGridIndex} because that room does not exist.`,
46
- );
47
- }
44
+ assertDefined(
45
+ roomData,
46
+ `Failed to change the room to grid index ${roomGridIndex} because that room does not exist.`,
47
+ );
48
48
 
49
49
  // This must be set before every `Game.StartRoomTransition` method invocation or else the function
50
50
  // can send you to the wrong room.
@@ -48,7 +48,7 @@ import { isLRoomShape } from "./roomShape";
48
48
  import { reloadRoom } from "./roomTransition";
49
49
  import { getGotoCommand } from "./stage";
50
50
  import { asNumber } from "./types";
51
- import { iRange } from "./utils";
51
+ import { assertDefined, iRange } from "./utils";
52
52
 
53
53
  const SECRET_ROOM_TYPES = new ReadonlySet([
54
54
  RoomType.SECRET,
@@ -65,11 +65,10 @@ export function changeRoom(roomGridIndex: int): void {
65
65
  const level = game.GetLevel();
66
66
 
67
67
  const roomData = getRoomData(roomGridIndex);
68
- if (roomData === undefined) {
69
- error(
70
- `Failed to change the room to grid index ${roomGridIndex} because that room does not exist.`,
71
- );
72
- }
68
+ assertDefined(
69
+ roomData,
70
+ `Failed to change the room to grid index ${roomGridIndex} because that room does not exist.`,
71
+ );
73
72
 
74
73
  // LeaveDoor must be set before every `Game.ChangeRoom` invocation or else the function can send
75
74
  // you to the wrong room.
@@ -10,6 +10,7 @@ import type {
10
10
  import { ISAAC_API_CLASS_TYPE_TO_FUNCTIONS } from "../objects/isaacAPIClassTypeToFunctions";
11
11
  import { getIsaacAPIClassName } from "./isaacAPIClass";
12
12
  import { isTable, isUserdata } from "./types";
13
+ import { assertDefined } from "./utils";
13
14
 
14
15
  /**
15
16
  * Helper function to generically copy an Isaac API class without knowing what specific type of
@@ -27,11 +28,10 @@ export function copyIsaacAPIClass<T extends CopyableIsaacAPIClass>(
27
28
  }
28
29
 
29
30
  const isaacAPIClassType = getIsaacAPIClassName(isaacAPIClass);
30
- if (isaacAPIClassType === undefined) {
31
- error(
32
- "Failed to copy an Isaac API class since it does not have a class type.",
33
- );
34
- }
31
+ assertDefined(
32
+ isaacAPIClassType,
33
+ "Failed to copy an Isaac API class since it does not have a class type.",
34
+ );
35
35
 
36
36
  const copyableIsaacAPIClassType =
37
37
  isaacAPIClassType as CopyableIsaacAPIClassType;
@@ -48,11 +48,10 @@ export function copyIsaacAPIClass<T extends CopyableIsaacAPIClass>(
48
48
  ThisSerializedIsaacAPIClassType
49
49
  >
50
50
  | undefined;
51
- if (functions === undefined) {
52
- error(
53
- `Failed to copy an Isaac API class since the associated functions were not found for Isaac API class type: ${copyableIsaacAPIClassType}`,
54
- );
55
- }
51
+ assertDefined(
52
+ functions,
53
+ `Failed to copy an Isaac API class since the associated functions were not found for Isaac API class type: ${copyableIsaacAPIClassType}`,
54
+ );
56
55
 
57
56
  return functions.copy(isaacAPIClass);
58
57
  }
@@ -78,11 +77,10 @@ export function deserializeIsaacAPIClass<
78
77
  const copyableIsaacAPIClassType = getSerializedTableType(
79
78
  serializedIsaacAPIClass,
80
79
  );
81
- if (copyableIsaacAPIClassType === undefined) {
82
- error(
83
- "Failed to deserialize an Isaac API class since a valid class type brand was not found.",
84
- );
85
- }
80
+ assertDefined(
81
+ copyableIsaacAPIClassType,
82
+ "Failed to deserialize an Isaac API class since a valid class type brand was not found.",
83
+ );
86
84
 
87
85
  type ThisIsaacAPIClassType = IsaacAPIClassTypeToType[SerializedT["__kind"]];
88
86
  type ThisSerializedIsaacAPIClassType = SerializedT;
@@ -95,11 +93,10 @@ export function deserializeIsaacAPIClass<
95
93
  ThisSerializedIsaacAPIClassType
96
94
  >
97
95
  | undefined;
98
- if (functions === undefined) {
99
- error(
100
- `Failed to deserialize an Isaac API class since the associated functions were not found for class type: ${copyableIsaacAPIClassType}`,
101
- );
102
- }
96
+ assertDefined(
97
+ functions,
98
+ `Failed to deserialize an Isaac API class since the associated functions were not found for class type: ${copyableIsaacAPIClassType}`,
99
+ );
103
100
 
104
101
  return functions.deserialize(serializedIsaacAPIClass);
105
102
  }
@@ -170,11 +167,10 @@ export function serializeIsaacAPIClass<T extends CopyableIsaacAPIClass>(
170
167
  }
171
168
 
172
169
  const isaacAPIClassType = getIsaacAPIClassName(isaacAPIClass);
173
- if (isaacAPIClassType === undefined) {
174
- error(
175
- "Failed to serialize an Isaac API class since it does not have a class type.",
176
- );
177
- }
170
+ assertDefined(
171
+ isaacAPIClassType,
172
+ "Failed to serialize an Isaac API class since it does not have a class name.",
173
+ );
178
174
 
179
175
  const copyableIsaacAPIClassType =
180
176
  isaacAPIClassType as CopyableIsaacAPIClassType;
@@ -191,11 +187,10 @@ export function serializeIsaacAPIClass<T extends CopyableIsaacAPIClass>(
191
187
  ThisSerializedIsaacAPIClassType
192
188
  >
193
189
  | undefined;
194
- if (functions === undefined) {
195
- error(
196
- `Failed to serialize an Isaac API class since the associated functions were not found for class type: ${copyableIsaacAPIClassType}`,
197
- );
198
- }
190
+ assertDefined(
191
+ functions,
192
+ `Failed to serialize an Isaac API class since the associated functions were not found for class type: ${copyableIsaacAPIClassType}`,
193
+ );
199
194
 
200
195
  return functions.serialize(isaacAPIClass);
201
196
  }