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.
- package/dist/index.rollup.d.ts +26 -4
- package/dist/isaacscript-common.lua +626 -645
- package/dist/src/classes/ModFeature.d.ts.map +1 -1
- package/dist/src/classes/ModFeature.lua +5 -9
- package/dist/src/classes/ModUpgraded.d.ts.map +1 -1
- package/dist/src/classes/ModUpgraded.lua +8 -14
- package/dist/src/classes/callbacks/PostNewRoomEarly.lua +2 -2
- package/dist/src/classes/features/callbackLogic/CustomGridEntities.d.ts.map +1 -1
- package/dist/src/classes/features/callbackLogic/CustomGridEntities.lua +3 -3
- package/dist/src/classes/features/other/CharacterHealthConversion.lua +1 -1
- package/dist/src/classes/features/other/CustomItemPools.d.ts.map +1 -1
- package/dist/src/classes/features/other/CustomItemPools.lua +12 -6
- package/dist/src/classes/features/other/CustomStages.d.ts.map +1 -1
- package/dist/src/classes/features/other/CustomStages.lua +12 -14
- package/dist/src/classes/features/other/CustomTrapdoors.d.ts.map +1 -1
- package/dist/src/classes/features/other/CustomTrapdoors.lua +6 -8
- package/dist/src/classes/features/other/DeployJSONRoom.d.ts.map +1 -1
- package/dist/src/classes/features/other/DeployJSONRoom.lua +15 -15
- package/dist/src/classes/features/other/ModdedElementSets.d.ts.map +1 -1
- package/dist/src/classes/features/other/ModdedElementSets.lua +21 -12
- package/dist/src/classes/features/other/Pause.d.ts.map +1 -1
- package/dist/src/classes/features/other/Pause.lua +4 -6
- package/dist/src/classes/features/other/SaveDataManager.d.ts.map +1 -1
- package/dist/src/classes/features/other/SaveDataManager.lua +5 -9
- package/dist/src/classes/features/other/customStages/backdrop.lua +9 -10
- package/dist/src/classes/features/other/saveDataManager/restoreDefaults.lua +1 -1
- package/dist/src/functions/array.d.ts +3 -0
- package/dist/src/functions/array.d.ts.map +1 -1
- package/dist/src/functions/array.lua +9 -3
- package/dist/src/functions/bitSet128.d.ts.map +1 -1
- package/dist/src/functions/bitSet128.lua +4 -6
- package/dist/src/functions/bitwise.d.ts.map +1 -1
- package/dist/src/functions/bitwise.lua +7 -3
- package/dist/src/functions/color.d.ts.map +1 -1
- package/dist/src/functions/color.lua +5 -9
- package/dist/src/functions/deepCopy.lua +23 -31
- package/dist/src/functions/entities.d.ts.map +1 -1
- package/dist/src/functions/entities.lua +20 -18
- package/dist/src/functions/entitiesSpecific.d.ts.map +1 -1
- package/dist/src/functions/entitiesSpecific.lua +11 -27
- package/dist/src/functions/enums.d.ts +6 -4
- package/dist/src/functions/enums.d.ts.map +1 -1
- package/dist/src/functions/enums.lua +13 -9
- package/dist/src/functions/gridEntities.d.ts.map +1 -1
- package/dist/src/functions/gridEntities.lua +18 -11
- package/dist/src/functions/gridEntitiesSpecific.d.ts.map +1 -1
- package/dist/src/functions/gridEntitiesSpecific.lua +16 -28
- package/dist/src/functions/input.d.ts +3 -0
- package/dist/src/functions/input.d.ts.map +1 -1
- package/dist/src/functions/input.lua +14 -14
- package/dist/src/functions/jsonRoom.d.ts.map +1 -1
- package/dist/src/functions/jsonRoom.lua +35 -23
- package/dist/src/functions/kColor.d.ts.map +1 -1
- package/dist/src/functions/kColor.lua +6 -12
- package/dist/src/functions/map.d.ts.map +1 -1
- package/dist/src/functions/map.lua +3 -3
- package/dist/src/functions/minimap.d.ts.map +1 -1
- package/dist/src/functions/minimap.lua +17 -9
- package/dist/src/functions/players.d.ts.map +1 -1
- package/dist/src/functions/players.lua +17 -22
- package/dist/src/functions/rng.d.ts.map +1 -1
- package/dist/src/functions/rng.lua +3 -3
- package/dist/src/functions/roomShapeWalls.d.ts.map +1 -1
- package/dist/src/functions/roomShapeWalls.lua +7 -3
- package/dist/src/functions/roomTransition.d.ts.map +1 -1
- package/dist/src/functions/roomTransition.lua +7 -3
- package/dist/src/functions/rooms.d.ts.map +1 -1
- package/dist/src/functions/rooms.lua +8 -5
- package/dist/src/functions/serialization.d.ts.map +1 -1
- package/dist/src/functions/serialization.lua +8 -18
- package/dist/src/functions/table.d.ts.map +1 -1
- package/dist/src/functions/table.lua +6 -12
- package/dist/src/functions/tstlClass.d.ts.map +1 -1
- package/dist/src/functions/tstlClass.lua +3 -3
- package/dist/src/functions/utils.d.ts +9 -0
- package/dist/src/functions/utils.d.ts.map +1 -1
- package/dist/src/functions/utils.lua +14 -6
- package/dist/src/functions/vector.d.ts.map +1 -1
- package/dist/src/functions/vector.lua +4 -6
- package/dist/src/functions/weighted.d.ts.map +1 -1
- package/dist/src/functions/weighted.lua +7 -3
- package/dist/src/sets/bossSets.d.ts.map +1 -1
- package/dist/src/sets/bossSets.lua +3 -3
- package/package.json +2 -2
- package/src/classes/ModFeature.ts +16 -12
- package/src/classes/ModUpgraded.ts +18 -16
- package/src/classes/callbacks/PostNewRoomEarly.ts +2 -2
- package/src/classes/features/callbackLogic/CustomGridEntities.ts +2 -3
- package/src/classes/features/other/CharacterHealthConversion.ts +1 -1
- package/src/classes/features/other/CustomItemPools.ts +9 -8
- package/src/classes/features/other/CustomStages.ts +9 -10
- package/src/classes/features/other/CustomTrapdoors.ts +9 -10
- package/src/classes/features/other/DeployJSONRoom.ts +21 -21
- package/src/classes/features/other/ModdedElementSets.ts +18 -21
- package/src/classes/features/other/Pause.ts +9 -6
- package/src/classes/features/other/SaveDataManager.ts +14 -16
- package/src/classes/features/other/customStages/backdrop.ts +5 -6
- package/src/classes/features/other/saveDataManager/restoreDefaults.ts +1 -1
- package/src/functions/array.ts +8 -6
- package/src/functions/bitSet128.ts +9 -10
- package/src/functions/bitwise.ts +6 -3
- package/src/functions/color.ts +13 -15
- package/src/functions/deepCopy.ts +18 -24
- package/src/functions/deepCopyTests.ts +5 -6
- package/src/functions/entities.ts +22 -20
- package/src/functions/entitiesSpecific.ts +10 -27
- package/src/functions/enums.ts +29 -17
- package/src/functions/gridEntities.ts +14 -16
- package/src/functions/gridEntitiesSpecific.ts +15 -28
- package/src/functions/input.ts +3 -3
- package/src/functions/jsonRoom.ts +39 -27
- package/src/functions/kColor.ts +17 -20
- package/src/functions/map.ts +5 -5
- package/src/functions/minimap.ts +16 -15
- package/src/functions/players.ts +7 -10
- package/src/functions/rng.ts +5 -5
- package/src/functions/roomShapeWalls.ts +3 -4
- package/src/functions/roomTransition.ts +5 -5
- package/src/functions/rooms.ts +5 -6
- package/src/functions/serialization.ts +25 -30
- package/src/functions/table.ts +18 -20
- package/src/functions/tstlClass.ts +5 -5
- package/src/functions/utils.ts +27 -6
- package/src/functions/vector.ts +9 -10
- package/src/functions/weighted.ts +5 -5
- 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
|
|
425
|
+
return undefined;
|
|
425
426
|
}
|
|
426
427
|
|
|
427
428
|
const door = gridEntity.ToDoor();
|
|
428
|
-
|
|
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
|
|
452
|
+
return undefined;
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
const pit = gridEntity.ToPit();
|
|
457
|
-
|
|
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
|
|
482
|
+
return undefined;
|
|
486
483
|
}
|
|
487
484
|
|
|
488
485
|
const poop = gridEntity.ToPoop();
|
|
489
|
-
|
|
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
|
|
512
|
+
return undefined;
|
|
518
513
|
}
|
|
519
514
|
|
|
520
515
|
const pressurePlate = gridEntity.ToPressurePlate();
|
|
521
|
-
|
|
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
|
|
539
|
+
return undefined;
|
|
547
540
|
}
|
|
548
541
|
|
|
549
542
|
const rock = gridEntity.ToRock();
|
|
550
|
-
|
|
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
|
|
566
|
+
return undefined;
|
|
576
567
|
}
|
|
577
568
|
|
|
578
569
|
const spikes = gridEntity.ToSpikes();
|
|
579
|
-
|
|
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
|
|
593
|
+
return undefined;
|
|
605
594
|
}
|
|
606
595
|
|
|
607
596
|
const tnt = gridEntity.ToTNT();
|
|
608
|
-
|
|
609
|
-
error("Failed to spawn TNT.");
|
|
610
|
-
}
|
|
597
|
+
assertDefined(tnt, "Failed to spawn TNT.");
|
|
611
598
|
|
|
612
599
|
return tnt;
|
|
613
600
|
}
|
package/src/functions/input.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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: ${
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
163
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
212
|
-
|
|
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
|
-
|
|
231
|
-
|
|
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) {
|
package/src/functions/kColor.ts
CHANGED
|
@@ -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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
}
|
package/src/functions/map.ts
CHANGED
|
@@ -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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
}
|
package/src/functions/minimap.ts
CHANGED
|
@@ -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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
}
|
package/src/functions/players.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
255
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/functions/rng.ts
CHANGED
|
@@ -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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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.
|
package/src/functions/rooms.ts
CHANGED
|
@@ -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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
}
|