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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bossSets.d.ts","sourceRoot":"","sources":["../../../src/sets/bossSets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bossSets.d.ts","sourceRoot":"","sources":["../../../src/sets/bossSets.ts"],"names":[],"mappings":"AAobA,eAAO,MAAM,mCAAmC,+DAe9C,CAAC;AAEH,eAAO,MAAM,8BAA8B,0CAezC,CAAC;AAEH,eAAO,MAAM,cAAc,qBAQzB,CAAC;AAEH,eAAO,MAAM,qCAAqC,qBACX,CAAC"}
|
|
@@ -41,6 +41,8 @@ local ____entities = require("src.functions.entities")
|
|
|
41
41
|
local parseEntityTypeVariantString = ____entities.parseEntityTypeVariantString
|
|
42
42
|
local ____set = require("src.functions.set")
|
|
43
43
|
local copySet = ____set.copySet
|
|
44
|
+
local ____utils = require("src.functions.utils")
|
|
45
|
+
local assertDefined = ____utils.assertDefined
|
|
44
46
|
local ____ReadonlyMap = require("src.types.ReadonlyMap")
|
|
45
47
|
local ReadonlyMap = ____ReadonlyMap.ReadonlyMap
|
|
46
48
|
local ____ReadonlySet = require("src.types.ReadonlySet")
|
|
@@ -52,9 +54,7 @@ function getAllBossesExcludingStoryBossesSet(self)
|
|
|
52
54
|
local allBosses = {__TS__Spread(____exports.ALL_BOSSES_SET:values())}
|
|
53
55
|
for ____, entityTypeVariantString in ipairs(allBosses) do
|
|
54
56
|
local tuple = parseEntityTypeVariantString(nil, entityTypeVariantString)
|
|
55
|
-
|
|
56
|
-
error("Failed to parse a boss tuple when constructing the story boss set.")
|
|
57
|
-
end
|
|
57
|
+
assertDefined(nil, tuple, "Failed to parse a boss tuple when constructing the story boss set.")
|
|
58
58
|
local entityType, _variant = table.unpack(tuple)
|
|
59
59
|
if STORY_BOSSES_SET:has(entityType) then
|
|
60
60
|
allBossesExcludingStoryBossesSet:delete(entityTypeVariantString)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isaacscript-common",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.6.0",
|
|
4
4
|
"description": "Helper functions and features for IsaacScript mods.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"isaac",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"main": "dist/src/index",
|
|
26
26
|
"types": "dist/index.rollup.d.ts",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"isaac-typescript-definitions": "^13.0.
|
|
28
|
+
"isaac-typescript-definitions": "^13.0.27"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getTSTLClassName,
|
|
8
8
|
} from "../functions/tstlClass";
|
|
9
9
|
import { isFunction, isNumber, isTable } from "../functions/types";
|
|
10
|
+
import { assertDefined } from "../functions/utils";
|
|
10
11
|
import type { TSTLClassMetatable } from "../interfaces/TSTLClassMetatable";
|
|
11
12
|
import type { AnyFunction } from "../types/AnyFunction";
|
|
12
13
|
import type { ModUpgraded } from "./ModUpgraded";
|
|
@@ -124,14 +125,16 @@ export class ModFeature {
|
|
|
124
125
|
this.initialized = init;
|
|
125
126
|
|
|
126
127
|
const constructor = getTSTLClassConstructor(this);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
assertDefined(
|
|
129
|
+
constructor,
|
|
130
|
+
"Failed to get the TSTL class constructor for a mod feature.",
|
|
131
|
+
);
|
|
130
132
|
|
|
131
133
|
const tstlClassName = getTSTLClassName(this);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
assertDefined(
|
|
135
|
+
tstlClassName,
|
|
136
|
+
"Failed to get the TSTL class name for a mod feature.",
|
|
137
|
+
);
|
|
135
138
|
|
|
136
139
|
initDecoratedCallbacks(this, constructor, tstlClassName, true, init);
|
|
137
140
|
initDecoratedCallbacks(this, constructor, tstlClassName, false, init);
|
|
@@ -360,12 +363,13 @@ function initSaveDataManager(
|
|
|
360
363
|
const saveDataManagerMethodName = init
|
|
361
364
|
? "saveDataManager"
|
|
362
365
|
: "saveDataManagerRemove";
|
|
363
|
-
const saveDataManagerMethod = mod[saveDataManagerMethodName]
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
366
|
+
const saveDataManagerMethod = mod[saveDataManagerMethodName] as
|
|
367
|
+
| AnyFunction
|
|
368
|
+
| undefined;
|
|
369
|
+
assertDefined(
|
|
370
|
+
saveDataManagerMethod,
|
|
371
|
+
'Failed to initialize a mod feature class due to having a "v" object and not having the save data manager initialized. You must pass "ISCFeature.SAVE_DATA_MANAGER" to the "upgradeMod" function.',
|
|
372
|
+
);
|
|
369
373
|
|
|
370
374
|
if (typeof saveDataManagerMethod !== "function") {
|
|
371
375
|
error(
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getTSTLClassConstructor,
|
|
12
12
|
getTSTLClassName,
|
|
13
13
|
} from "../functions/tstlClass";
|
|
14
|
+
import { assertDefined } from "../functions/utils";
|
|
14
15
|
import type { AddCallbackParametersCustom } from "../interfaces/private/AddCallbackParametersCustom";
|
|
15
16
|
import type { ModUpgradedInterface } from "../interfaces/private/ModUpgradedInterface";
|
|
16
17
|
import type { AnyFunction } from "../types/AnyFunction";
|
|
@@ -234,11 +235,10 @@ export class ModUpgraded implements Mod {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
const modCallbackCustom = tonumber(modCallbackCustomString);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
238
|
+
assertDefined(
|
|
239
|
+
modCallbackCustom,
|
|
240
|
+
"Failed to convert an index on the callbacks object to a number.",
|
|
241
|
+
);
|
|
242
242
|
|
|
243
243
|
log(
|
|
244
244
|
`- ModCallbackCustom.${ModCallbackCustom[modCallbackCustom]} (${modCallbackCustom})`,
|
|
@@ -254,9 +254,10 @@ export class ModUpgraded implements Mod {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
const iscFeature = tonumber(iscFeatureString);
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
assertDefined(
|
|
258
|
+
iscFeature,
|
|
259
|
+
"Failed to convert an index on the features object to a number.",
|
|
260
|
+
);
|
|
260
261
|
|
|
261
262
|
log(`- ISCFeature.${ISCFeature[iscFeature]} (${iscFeature})`);
|
|
262
263
|
}
|
|
@@ -324,9 +325,8 @@ export class ModUpgraded implements Mod {
|
|
|
324
325
|
|
|
325
326
|
if (feature.v !== undefined) {
|
|
326
327
|
const className = getTSTLClassName(feature);
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
328
|
+
assertDefined(className, "Failed to get the name of a feature.");
|
|
329
|
+
|
|
330
330
|
const saveDataManagerClass = this.features[ISCFeature.SAVE_DATA_MANAGER];
|
|
331
331
|
saveDataManagerClass.saveDataManager(
|
|
332
332
|
className,
|
|
@@ -387,9 +387,8 @@ export class ModUpgraded implements Mod {
|
|
|
387
387
|
|
|
388
388
|
if (feature.v !== undefined) {
|
|
389
389
|
const className = getTSTLClassName(feature);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
390
|
+
assertDefined(className, "Failed to get the name of a feature.");
|
|
391
|
+
|
|
393
392
|
const saveDataManagerClass = this.features[ISCFeature.SAVE_DATA_MANAGER];
|
|
394
393
|
saveDataManagerClass.saveDataManagerRemove(className);
|
|
395
394
|
}
|
|
@@ -430,6 +429,9 @@ function getExportedMethodsFromFeature(featureClass: unknown): FunctionTuple[] {
|
|
|
430
429
|
|
|
431
430
|
return exportedMethodNames.map((name) => {
|
|
432
431
|
const featureClassRecord = featureClass as Record<string, AnyFunction>;
|
|
432
|
+
|
|
433
|
+
// We cannot split out the method to a separate variable or else the "self" parameter will not
|
|
434
|
+
// be properly passed to the method.
|
|
433
435
|
if (featureClassRecord[name] === undefined) {
|
|
434
436
|
error(`Failed to find a decorated exported method: ${name}`);
|
|
435
437
|
}
|
|
@@ -437,8 +439,8 @@ function getExportedMethodsFromFeature(featureClass: unknown): FunctionTuple[] {
|
|
|
437
439
|
// In order for "this" to work properly in the method, we have to wrap the method invocation in
|
|
438
440
|
// an arrow function.
|
|
439
441
|
const wrappedMethod = (...args: unknown[]) =>
|
|
440
|
-
// We
|
|
441
|
-
//
|
|
442
|
+
// We use a non-null assertion since we have already validated that the function exists. (See
|
|
443
|
+
// the above comment.)
|
|
442
444
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
443
445
|
featureClassRecord[name]!(...args);
|
|
444
446
|
|
|
@@ -68,7 +68,7 @@ export class PostNewRoomEarly extends CustomCallback<ModCallbackCustom.POST_NEW_
|
|
|
68
68
|
topLeftWall = spawnGridEntity(GridEntityType.WALL, topLeftWallGridIndex);
|
|
69
69
|
if (topLeftWall === undefined) {
|
|
70
70
|
logError(
|
|
71
|
-
"Failed to spawn a new wall
|
|
71
|
+
"Failed to spawn a new wall for the POST_NEW_ROOM_EARLY callback (on the first try).",
|
|
72
72
|
);
|
|
73
73
|
return false;
|
|
74
74
|
}
|
|
@@ -83,7 +83,7 @@ export class PostNewRoomEarly extends CustomCallback<ModCallbackCustom.POST_NEW_
|
|
|
83
83
|
);
|
|
84
84
|
if (topLeftWall2 === undefined) {
|
|
85
85
|
logError(
|
|
86
|
-
"Failed to spawn a new wall
|
|
86
|
+
"Failed to spawn a new wall for the POST_NEW_ROOM_EARLY callback (on the second try).",
|
|
87
87
|
);
|
|
88
88
|
return false;
|
|
89
89
|
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import { getPlayerFromPtr } from "../../../functions/players";
|
|
17
17
|
import { getRoomListIndex } from "../../../functions/roomData";
|
|
18
18
|
import { isNumber } from "../../../functions/types";
|
|
19
|
+
import { assertDefined } from "../../../functions/utils";
|
|
19
20
|
import { isVector } from "../../../functions/vector";
|
|
20
21
|
import type { GridEntityCustomData } from "../../../interfaces/GridEntityCustomData";
|
|
21
22
|
import { DefaultMap } from "../../DefaultMap";
|
|
@@ -245,9 +246,7 @@ export class CustomGridEntities extends Feature {
|
|
|
245
246
|
baseGridEntityVariant,
|
|
246
247
|
gridIndexOrPosition,
|
|
247
248
|
);
|
|
248
|
-
|
|
249
|
-
error("Failed to spawn a custom grid entity.");
|
|
250
|
-
}
|
|
249
|
+
assertDefined(customGridEntity, "Failed to spawn a custom grid entity.");
|
|
251
250
|
|
|
252
251
|
if (gridCollisionClass !== undefined) {
|
|
253
252
|
customGridEntity.CollisionClass = gridCollisionClass;
|
|
@@ -70,7 +70,7 @@ export class CharacterHealthConversion extends Feature {
|
|
|
70
70
|
const conversionHeartSubType =
|
|
71
71
|
this.characterHealthReplacementMap.get(character);
|
|
72
72
|
if (conversionHeartSubType === undefined) {
|
|
73
|
-
return;
|
|
73
|
+
return undefined;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
convertRedHeartContainers(player, conversionHeartSubType);
|
|
@@ -5,6 +5,7 @@ import { ModCallbackCustom } from "../../../enums/ModCallbackCustom";
|
|
|
5
5
|
import { arrayRemoveIndexInPlace } from "../../../functions/array";
|
|
6
6
|
import { copyMap } from "../../../functions/map";
|
|
7
7
|
import { getRandomSeed } from "../../../functions/rng";
|
|
8
|
+
import { assertDefined } from "../../../functions/utils";
|
|
8
9
|
import { getRandomIndexFromWeightedArray } from "../../../functions/weighted";
|
|
9
10
|
import type { WeightedArray } from "../../../types/WeightedArray";
|
|
10
11
|
import { Feature } from "../../private/Feature";
|
|
@@ -116,9 +117,10 @@ export class CustomItemPools extends Feature {
|
|
|
116
117
|
defaultItem = CollectibleType.NULL,
|
|
117
118
|
): CollectibleType {
|
|
118
119
|
const customItemPool = v.run.customItemPools.get(itemPoolTypeCustom);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
assertDefined(
|
|
121
|
+
customItemPool,
|
|
122
|
+
`Failed to find the custom item pool of: ${itemPoolTypeCustom}`,
|
|
123
|
+
);
|
|
122
124
|
|
|
123
125
|
if (customItemPool.length === 0) {
|
|
124
126
|
return defaultItem;
|
|
@@ -129,11 +131,10 @@ export class CustomItemPools extends Feature {
|
|
|
129
131
|
seedOrRNG,
|
|
130
132
|
);
|
|
131
133
|
const tuple = customItemPool[randomIndex];
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
134
|
+
assertDefined(
|
|
135
|
+
tuple,
|
|
136
|
+
`Failed to get an element from a custom item pool using a random index of: ${randomIndex}`,
|
|
137
|
+
);
|
|
137
138
|
|
|
138
139
|
if (decrease) {
|
|
139
140
|
arrayRemoveIndexInPlace(customItemPool, randomIndex);
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
import { getMusicForStage } from "../../../functions/sound";
|
|
32
32
|
import { setStage } from "../../../functions/stage";
|
|
33
33
|
import { asNumber } from "../../../functions/types";
|
|
34
|
+
import { assertDefined } from "../../../functions/utils";
|
|
34
35
|
import type {
|
|
35
36
|
CustomStageLua,
|
|
36
37
|
CustomStageRoomMetadata,
|
|
@@ -201,11 +202,10 @@ export class CustomStages extends Feature {
|
|
|
201
202
|
destinationStage: LevelStage,
|
|
202
203
|
_destinationStageType: StageType,
|
|
203
204
|
) => {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
205
|
+
assertDefined(
|
|
206
|
+
destinationName,
|
|
207
|
+
"Failed to go to a custom stage since the custom trapdoors feature did not pass a destination name to the logic function.",
|
|
208
|
+
);
|
|
209
209
|
|
|
210
210
|
const firstFloor = destinationStage === LevelStage.BASEMENT_1;
|
|
211
211
|
this.setCustomStage(destinationName, firstFloor);
|
|
@@ -498,11 +498,10 @@ export class CustomStages extends Feature {
|
|
|
498
498
|
verbose = false,
|
|
499
499
|
): void {
|
|
500
500
|
const customStage = this.customStagesMap.get(name);
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
501
|
+
assertDefined(
|
|
502
|
+
customStage,
|
|
503
|
+
`Failed to set the custom stage of "${name}" because it was not found in the custom stages map. (Try restarting IsaacScript / recompiling the mod / restarting the game, and try again. If that does not work, you probably forgot to define it in your "tsconfig.json" file.) See the website for more details on how to set up custom stages.`,
|
|
504
|
+
);
|
|
506
505
|
|
|
507
506
|
const level = game.GetLevel();
|
|
508
507
|
const stage = level.GetStage();
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
import { teleport } from "../../../functions/roomTransition";
|
|
38
38
|
import { setStage } from "../../../functions/stage";
|
|
39
39
|
import { getTSTLClassName } from "../../../functions/tstlClass";
|
|
40
|
+
import { assertDefined } from "../../../functions/utils";
|
|
40
41
|
import { isVector } from "../../../functions/vector";
|
|
41
42
|
import type { CustomTrapdoorDescription } from "../../../interfaces/private/CustomTrapdoorDescription";
|
|
42
43
|
import { ReadonlySet } from "../../../types/ReadonlySet";
|
|
@@ -365,11 +366,10 @@ export class CustomTrapdoors extends Feature {
|
|
|
365
366
|
this.logStateChanged();
|
|
366
367
|
|
|
367
368
|
const tstlClassName = getTSTLClassName(this);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
369
|
+
assertDefined(
|
|
370
|
+
tstlClassName,
|
|
371
|
+
"Failed to find get the class name for the custom trapdoor feature.",
|
|
372
|
+
);
|
|
373
373
|
|
|
374
374
|
this.disableInputs.enableAllInputs(tstlClassName);
|
|
375
375
|
}
|
|
@@ -506,11 +506,10 @@ export class CustomTrapdoors extends Feature {
|
|
|
506
506
|
this.logStateChanged();
|
|
507
507
|
|
|
508
508
|
const tstlClassName = getTSTLClassName(this);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
509
|
+
assertDefined(
|
|
510
|
+
tstlClassName,
|
|
511
|
+
"Failed to find get the class name for the custom trapdoor feature.",
|
|
512
|
+
);
|
|
514
513
|
|
|
515
514
|
// We don't want to allow pausing, since that will allow render frames to pass without advancing
|
|
516
515
|
// the stage traveling logic. (We track how many render frames have passed to know when to move
|
|
@@ -28,6 +28,7 @@ import { getRandomSeed, isRNG, newRNG } from "../../../functions/rng";
|
|
|
28
28
|
import { gridCoordinatesToWorldPosition } from "../../../functions/roomGrid";
|
|
29
29
|
import { setRoomCleared, setRoomUncleared } from "../../../functions/rooms";
|
|
30
30
|
import { asCollectibleType, asNumber } from "../../../functions/types";
|
|
31
|
+
import { assertDefined } from "../../../functions/utils";
|
|
31
32
|
import type { JSONRoom } from "../../../interfaces/JSONRoomsFile";
|
|
32
33
|
import { ReadonlySet } from "../../../types/ReadonlySet";
|
|
33
34
|
import { Feature } from "../../private/Feature";
|
|
@@ -68,41 +69,40 @@ export class DeployJSONRoom extends Feature {
|
|
|
68
69
|
for (const jsonSpawn of jsonRoom.spawn) {
|
|
69
70
|
const xString = jsonSpawn.$.x;
|
|
70
71
|
const x = tonumber(xString);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
72
|
+
assertDefined(
|
|
73
|
+
x,
|
|
74
|
+
`Failed to convert the following x coordinate to a number (for a spawn): ${xString}`,
|
|
75
|
+
);
|
|
76
76
|
|
|
77
77
|
const yString = jsonSpawn.$.y;
|
|
78
78
|
const y = tonumber(yString);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
79
|
+
assertDefined(
|
|
80
|
+
y,
|
|
81
|
+
`Failed to convert the following y coordinate to a number (for a spawn): ${yString}`,
|
|
82
|
+
);
|
|
84
83
|
|
|
85
84
|
const jsonEntity = getRandomJSONEntity(jsonSpawn.entity);
|
|
86
85
|
|
|
87
86
|
const entityTypeString = jsonEntity.$.type;
|
|
88
87
|
const entityTypeNumber = tonumber(entityTypeString);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
88
|
+
assertDefined(
|
|
89
|
+
entityTypeNumber,
|
|
90
|
+
`Failed to convert the entity type to a number: ${entityTypeString}`,
|
|
91
|
+
);
|
|
94
92
|
|
|
95
93
|
const variantString = jsonEntity.$.variant;
|
|
96
94
|
const variant = tonumber(variantString);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
assertDefined(
|
|
96
|
+
variant,
|
|
97
|
+
`Failed to convert the entity variant to a number: ${variant}`,
|
|
98
|
+
);
|
|
100
99
|
|
|
101
100
|
const subTypeString = jsonEntity.$.subtype;
|
|
102
101
|
const subType = tonumber(subTypeString);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
assertDefined(
|
|
103
|
+
subType,
|
|
104
|
+
`Failed to convert the entity sub-type to a number: ${subType}`,
|
|
105
|
+
);
|
|
106
106
|
|
|
107
107
|
const isGridEntity = GRID_ENTITY_XML_TYPE_SET.has(
|
|
108
108
|
entityTypeNumber as GridEntityXMLType,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
getVanillaTrinketTypeRange,
|
|
41
41
|
trinketHasCacheFlag,
|
|
42
42
|
} from "../../../functions/trinkets";
|
|
43
|
-
import { repeat } from "../../../functions/utils";
|
|
43
|
+
import { assertDefined, repeat } from "../../../functions/utils";
|
|
44
44
|
import { ITEM_CONFIG_CARD_TYPES_FOR_CARDS_SET } from "../../../sets/itemConfigCardTypesForCardsSet";
|
|
45
45
|
import { ReadonlyMap } from "../../../types/ReadonlyMap";
|
|
46
46
|
import { ReadonlySet } from "../../../types/ReadonlySet";
|
|
@@ -440,11 +440,11 @@ export class ModdedElementSets extends Feature {
|
|
|
440
440
|
if (itemConfigCardType !== undefined) {
|
|
441
441
|
const cardTypeSet =
|
|
442
442
|
this.itemConfigCardTypeToCardTypeMap.get(itemConfigCardType);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
443
|
+
assertDefined(
|
|
444
|
+
cardTypeSet,
|
|
445
|
+
`Failed to get the card set for item config card type: ${itemConfigCardType}`,
|
|
446
|
+
);
|
|
447
|
+
|
|
448
448
|
cardTypeSet.add(cardType);
|
|
449
449
|
|
|
450
450
|
if (ITEM_CONFIG_CARD_TYPES_FOR_CARDS_SET.has(itemConfigCardType)) {
|
|
@@ -515,11 +515,10 @@ export class ModdedElementSets extends Feature {
|
|
|
515
515
|
for (const itemConfigCardType of itemConfigCardTypes) {
|
|
516
516
|
const cardTypeSet =
|
|
517
517
|
this.itemConfigCardTypeToCardTypeMap.get(itemConfigCardType);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
}
|
|
518
|
+
assertDefined(
|
|
519
|
+
cardTypeSet,
|
|
520
|
+
`Failed to get the card type set for item config type: ${itemConfigCardType}`,
|
|
521
|
+
);
|
|
523
522
|
|
|
524
523
|
for (const cardType of cardTypeSet) {
|
|
525
524
|
matchingCardTypes.add(cardType);
|
|
@@ -588,11 +587,10 @@ export class ModdedElementSets extends Feature {
|
|
|
588
587
|
playerForm: PlayerForm,
|
|
589
588
|
): ReadonlySet<CollectibleType> {
|
|
590
589
|
const itemConfigTag = TRANSFORMATION_TO_TAG_MAP.get(playerForm);
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
590
|
+
assertDefined(
|
|
591
|
+
itemConfigTag,
|
|
592
|
+
`Failed to get the collectible types for the transformation of ${playerForm} because that transformation is not based on collectibles.`,
|
|
593
|
+
);
|
|
596
594
|
|
|
597
595
|
return this.getCollectiblesWithTag(itemConfigTag);
|
|
598
596
|
}
|
|
@@ -648,11 +646,10 @@ export class ModdedElementSets extends Feature {
|
|
|
648
646
|
this.lazyInitTagToCollectibleTypesMap();
|
|
649
647
|
|
|
650
648
|
const collectibleTypes = this.tagToCollectibleTypesMap.get(itemConfigTag);
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
}
|
|
649
|
+
assertDefined(
|
|
650
|
+
collectibleTypes,
|
|
651
|
+
`The item config tag of ${itemConfigTag} is not a valid value of the "ItemConfigTag" enum.`,
|
|
652
|
+
);
|
|
656
653
|
|
|
657
654
|
return collectibleTypes;
|
|
658
655
|
}
|
|
@@ -17,6 +17,7 @@ import { logError } from "../../../functions/logMisc";
|
|
|
17
17
|
import { getAllPlayers } from "../../../functions/playerIndex";
|
|
18
18
|
import { useActiveItemTemp } from "../../../functions/players";
|
|
19
19
|
import { getTSTLClassName } from "../../../functions/tstlClass";
|
|
20
|
+
import { assertDefined } from "../../../functions/utils";
|
|
20
21
|
import { ReadonlySet } from "../../../types/ReadonlySet";
|
|
21
22
|
import { Feature } from "../../private/Feature";
|
|
22
23
|
import type { DisableInputs } from "./DisableInputs";
|
|
@@ -170,9 +171,10 @@ export class Pause extends Feature {
|
|
|
170
171
|
useActiveItemTemp(firstPlayer, CollectibleType.PAUSE);
|
|
171
172
|
|
|
172
173
|
const tstlClassName = getTSTLClassName(this);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
assertDefined(
|
|
175
|
+
tstlClassName,
|
|
176
|
+
"Failed to get the class name for the pause feature.",
|
|
177
|
+
);
|
|
176
178
|
|
|
177
179
|
const whitelist = new ReadonlySet([
|
|
178
180
|
ButtonAction.MENU_CONFIRM,
|
|
@@ -210,9 +212,10 @@ export class Pause extends Feature {
|
|
|
210
212
|
v.run.shouldUnpause = true;
|
|
211
213
|
|
|
212
214
|
const tstlClassName = getTSTLClassName(this);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
assertDefined(
|
|
216
|
+
tstlClassName,
|
|
217
|
+
"Failed to find get the class name for the pause feature.",
|
|
218
|
+
);
|
|
216
219
|
|
|
217
220
|
this.disableInputs.enableAllInputs(tstlClassName);
|
|
218
221
|
for (const player of getAllPlayers()) {
|
|
@@ -10,6 +10,7 @@ import { log } from "../../../functions/log";
|
|
|
10
10
|
import { onFirstFloor } from "../../../functions/stage";
|
|
11
11
|
import { getTSTLClassName, isTSTLClass } from "../../../functions/tstlClass";
|
|
12
12
|
import { isString, isTable } from "../../../functions/types";
|
|
13
|
+
import { assertDefined } from "../../../functions/utils";
|
|
13
14
|
import type { SaveData } from "../../../interfaces/SaveData";
|
|
14
15
|
import type { AnyClass } from "../../../types/AnyClass";
|
|
15
16
|
import { ReadonlySet } from "../../../types/ReadonlySet";
|
|
@@ -332,11 +333,10 @@ export class SaveDataManager extends Feature {
|
|
|
332
333
|
): void {
|
|
333
334
|
if (isTSTLClass(key)) {
|
|
334
335
|
const className = getTSTLClassName(key);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
336
|
+
assertDefined(
|
|
337
|
+
className,
|
|
338
|
+
'Failed to get the class name for the submitted class (as part of the "key" parameter) when registering new data with the save data manager.',
|
|
339
|
+
);
|
|
340
340
|
|
|
341
341
|
key = className;
|
|
342
342
|
}
|
|
@@ -459,12 +459,11 @@ export class SaveDataManager extends Feature {
|
|
|
459
459
|
public saveDataManagerRegisterClass(...tstlClasses: AnyClass[]): void {
|
|
460
460
|
for (const tstlClass of tstlClasses) {
|
|
461
461
|
const { name } = tstlClass;
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
462
|
+
assertDefined(
|
|
463
|
+
// Since we are accepting untrusted user input, this might nto be a real TSTL class.
|
|
464
|
+
name as string | undefined,
|
|
465
|
+
"Failed to register a class with the save data manager due to not being able to derive the name of the class.",
|
|
466
|
+
);
|
|
468
467
|
|
|
469
468
|
this.classConstructors.set(name, tstlClass);
|
|
470
469
|
}
|
|
@@ -528,11 +527,10 @@ export class SaveDataManager extends Feature {
|
|
|
528
527
|
}
|
|
529
528
|
|
|
530
529
|
const saveData = this.saveDataMap.get(key);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
530
|
+
assertDefined(
|
|
531
|
+
saveData,
|
|
532
|
+
`The save data manager is not managing save data for a key of: ${key}`,
|
|
533
|
+
);
|
|
536
534
|
|
|
537
535
|
restoreDefaultForFeatureKey(
|
|
538
536
|
this.saveDataDefaultsMap,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
removeCharactersBefore,
|
|
20
20
|
trimPrefix,
|
|
21
21
|
} from "../../../../functions/string";
|
|
22
|
-
import { eRange, iRange } from "../../../../functions/utils";
|
|
22
|
+
import { assertDefined, eRange, iRange } from "../../../../functions/utils";
|
|
23
23
|
import type { CustomStage } from "../../../../interfaces/private/CustomStage";
|
|
24
24
|
import { ReadonlySet } from "../../../../types/ReadonlySet";
|
|
25
25
|
import { ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH } from "./constants";
|
|
@@ -149,11 +149,10 @@ function spawnWallEntity(
|
|
|
149
149
|
? ROOM_SHAPE_WALL_EXTRA_ANM2_LAYERS
|
|
150
150
|
: ROOM_SHAPE_WALL_ANM2_LAYERS;
|
|
151
151
|
const numWallLayers = wallLayersArray[roomShape];
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
152
|
+
assertDefined(
|
|
153
|
+
numWallLayers,
|
|
154
|
+
`Failed to get the layers when creating the backdrop for custom stage: ${customStage.name}`,
|
|
155
|
+
);
|
|
157
156
|
|
|
158
157
|
if (isLRoomShape(roomShape)) {
|
|
159
158
|
const cornerPNGPath = getBackdropPNGPath(
|
|
@@ -80,7 +80,7 @@ export function restoreDefaultForFeatureKey(
|
|
|
80
80
|
const childTableDefaults = saveDataDefaults[saveDataKey];
|
|
81
81
|
if (childTableDefaults === undefined) {
|
|
82
82
|
logError(
|
|
83
|
-
`Failed to find the default copy of the child table "${saveDataKey}" for subscriber "${subscriberName}". This error usually means that your save data is out of date. You can try purging all of your save data by deleting the following directory: C:\\Program Files (x86)\\Steam\\steamapps\\common\\The Binding of Isaac Rebirth\\data`,
|
|
83
|
+
`Failed to find the default copy of the child table "${saveDataKey}" for subscriber "${subscriberName}". This error usually means that your mod-specific save data is out of date. You can try purging all of your mod-specific save data by deleting the following directory: C:\\Program Files (x86)\\Steam\\steamapps\\common\\The Binding of Isaac Rebirth\\data`,
|
|
84
84
|
);
|
|
85
85
|
return;
|
|
86
86
|
}
|