isaacscript-common 6.8.0 → 6.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/features/customStage/customStageGridEntities.lua +2 -2
  2. package/dist/features/customStage/exports.d.ts.map +1 -1
  3. package/dist/features/customStage/exports.lua +5 -4
  4. package/dist/features/customStage/init.d.ts.map +1 -1
  5. package/dist/features/customStage/init.lua +12 -3
  6. package/dist/features/customStage/streakText.d.ts +4 -2
  7. package/dist/features/customStage/streakText.d.ts.map +1 -1
  8. package/dist/features/customStage/streakText.lua +216 -15
  9. package/dist/features/customStage/v.d.ts +4 -2
  10. package/dist/features/customStage/v.d.ts.map +1 -1
  11. package/dist/features/customStage/v.lua +9 -1
  12. package/dist/features/customStage/versusScreen.d.ts +1 -1
  13. package/dist/features/customStage/versusScreen.d.ts.map +1 -1
  14. package/dist/features/customStage/versusScreen.lua +2 -5
  15. package/dist/features/extraConsoleCommands/init.lua +1 -0
  16. package/dist/features/extraConsoleCommands/listCommands.d.ts +8 -0
  17. package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
  18. package/dist/features/extraConsoleCommands/listCommands.lua +13 -0
  19. package/dist/features/saveDataManager/exports.d.ts.map +1 -1
  20. package/dist/features/saveDataManager/exports.lua +2 -4
  21. package/dist/features/saveDataManager/load.d.ts +1 -1
  22. package/dist/features/saveDataManager/load.d.ts.map +1 -1
  23. package/dist/features/saveDataManager/main.d.ts.map +1 -1
  24. package/dist/features/saveDataManager/main.lua +0 -1
  25. package/dist/features/saveDataManager/maps.d.ts +3 -3
  26. package/dist/features/saveDataManager/maps.d.ts.map +1 -1
  27. package/dist/features/saveDataManager/maps.lua +1 -4
  28. package/dist/features/saveDataManager/merge.d.ts +2 -2
  29. package/dist/features/saveDataManager/merge.d.ts.map +1 -1
  30. package/dist/features/saveDataManager/merge.lua +3 -3
  31. package/dist/features/saveDataManager/save.d.ts +1 -1
  32. package/dist/features/saveDataManager/save.d.ts.map +1 -1
  33. package/dist/features/saveDataManager/save.lua +1 -2
  34. package/dist/features/saveDataManager/{serializationBrand.d.ts → serializationBrands.d.ts} +1 -1
  35. package/dist/features/saveDataManager/serializationBrands.d.ts.map +1 -0
  36. package/dist/features/saveDataManager/{serializationBrand.lua → serializationBrands.lua} +0 -0
  37. package/dist/functions/array.d.ts.map +1 -1
  38. package/dist/functions/color.d.ts +1 -1
  39. package/dist/functions/color.d.ts.map +1 -1
  40. package/dist/functions/deepCopy.d.ts +1 -1
  41. package/dist/functions/deepCopy.lua +55 -36
  42. package/dist/functions/deepCopyTests.lua +20 -17
  43. package/dist/functions/entities.d.ts +1 -1
  44. package/dist/functions/entities.d.ts.map +1 -1
  45. package/dist/functions/input.d.ts.map +1 -1
  46. package/dist/functions/input.lua +8 -10
  47. package/dist/functions/jsonHelpers.d.ts +1 -1
  48. package/dist/functions/jsonHelpers.d.ts.map +1 -1
  49. package/dist/functions/kColor.d.ts +1 -1
  50. package/dist/functions/kColor.d.ts.map +1 -1
  51. package/dist/functions/log.d.ts +1 -1
  52. package/dist/functions/log.d.ts.map +1 -1
  53. package/dist/functions/log.lua +3 -1
  54. package/dist/functions/mergeTests.d.ts +2 -2
  55. package/dist/functions/mergeTests.lua +2 -2
  56. package/dist/functions/playerIndex.d.ts +1 -1
  57. package/dist/functions/playerIndex.lua +1 -1
  58. package/dist/functions/rng.d.ts +1 -1
  59. package/dist/functions/rng.d.ts.map +1 -1
  60. package/dist/functions/run.d.ts +8 -0
  61. package/dist/functions/run.d.ts.map +1 -1
  62. package/dist/functions/run.lua +15 -0
  63. package/dist/functions/table.d.ts +9 -9
  64. package/dist/functions/table.d.ts.map +1 -1
  65. package/dist/functions/table.lua +23 -21
  66. package/dist/functions/types.d.ts +1 -1
  67. package/dist/functions/types.d.ts.map +1 -1
  68. package/dist/functions/vector.d.ts +1 -1
  69. package/dist/functions/vector.d.ts.map +1 -1
  70. package/dist/interfaces/SaveData.d.ts +1 -1
  71. package/dist/interfaces/private/TSTLClassMetatable.d.ts +1 -1
  72. package/dist/interfaces/private/TSTLClassMetatable.d.ts.map +1 -1
  73. package/dist/lualib_bundle.lua +38 -7
  74. package/dist/types/PlayerIndex.d.ts +3 -2
  75. package/dist/types/PlayerIndex.d.ts.map +1 -1
  76. package/dist/types/private/IsaacAPIClass.d.ts +1 -1
  77. package/dist/types/private/IsaacAPIClass.d.ts.map +1 -1
  78. package/dist/types/private/SerializedIsaacAPIClass.d.ts +1 -1
  79. package/dist/types/private/SerializedIsaacAPIClass.d.ts.map +1 -1
  80. package/dist/types/private/TSTLClass.d.ts +1 -1
  81. package/dist/types/private/TSTLClass.d.ts.map +1 -1
  82. package/package.json +2 -2
  83. package/src/features/customStage/customStageGridEntities.ts +4 -4
  84. package/src/features/customStage/exports.ts +5 -3
  85. package/src/features/customStage/init.ts +19 -7
  86. package/src/features/customStage/streakText.ts +284 -19
  87. package/src/features/customStage/v.ts +6 -1
  88. package/src/features/customStage/versusScreen.ts +2 -5
  89. package/src/features/extraConsoleCommands/init.ts +1 -0
  90. package/src/features/extraConsoleCommands/listCommands.ts +14 -0
  91. package/src/features/saveDataManager/exports.ts +3 -8
  92. package/src/features/saveDataManager/load.ts +2 -3
  93. package/src/features/saveDataManager/main.ts +4 -5
  94. package/src/features/saveDataManager/maps.ts +3 -3
  95. package/src/features/saveDataManager/merge.ts +11 -11
  96. package/src/features/saveDataManager/save.ts +6 -6
  97. package/src/features/saveDataManager/{serializationBrand.ts → serializationBrands.ts} +0 -0
  98. package/src/functions/array.ts +2 -4
  99. package/src/functions/color.ts +3 -3
  100. package/src/functions/deepCopy.ts +77 -40
  101. package/src/functions/deepCopyTests.ts +45 -28
  102. package/src/functions/entities.ts +7 -7
  103. package/src/functions/input.ts +7 -8
  104. package/src/functions/isaacAPIClass.ts +3 -3
  105. package/src/functions/jsonHelpers.ts +3 -3
  106. package/src/functions/kColor.ts +3 -3
  107. package/src/functions/log.ts +7 -4
  108. package/src/functions/mergeTests.ts +24 -24
  109. package/src/functions/playerIndex.ts +1 -1
  110. package/src/functions/rng.ts +3 -3
  111. package/src/functions/run.ts +14 -0
  112. package/src/functions/table.ts +25 -23
  113. package/src/functions/tstlClass.ts +1 -1
  114. package/src/functions/types.ts +3 -1
  115. package/src/functions/vector.ts +3 -3
  116. package/src/interfaces/SaveData.ts +1 -1
  117. package/src/interfaces/private/TSTLClassMetatable.ts +1 -1
  118. package/src/types/PlayerIndex.ts +3 -2
  119. package/src/types/private/IsaacAPIClass.ts +1 -1
  120. package/src/types/private/SerializedIsaacAPIClass.ts +1 -1
  121. package/src/types/private/TSTLClass.ts +1 -1
  122. package/dist/features/saveDataManager/serializationBrand.d.ts.map +0 -1
@@ -443,9 +443,7 @@ export function isArray(object: unknown): object is unknown[] {
443
443
  return false;
444
444
  }
445
445
 
446
- // Third, handle the case of an "empty" table. We cannot use the "LuaTable.length" method to
447
- // determine this, since that will not actually return the number of keys. (It will only work
448
- // properly for tables that are being used as arrays, which is not necessarily the case here.)
446
+ // Third, handle the case of an "empty" table.
449
447
  const tableLength = Object.keys(object).length;
450
448
  if (tableLength === 0) {
451
449
  return true;
@@ -453,7 +451,7 @@ export function isArray(object: unknown): object is unknown[] {
453
451
 
454
452
  // Third, check for non-contiguous elements. (Lua tables start at an index of 1.)
455
453
  for (let i = 1; i <= tableLength; i++) {
456
- const element = object.get(i) as unknown;
454
+ const element = object.get(i);
457
455
  if (element === undefined) {
458
456
  return false;
459
457
  }
@@ -4,7 +4,7 @@ import { isaacAPIClassEquals, isIsaacAPIClassOfType } from "./isaacAPIClass";
4
4
  import { copyValuesToTable, getNumbersFromTable, tableHasKeys } from "./table";
5
5
  import { isTable } from "./types";
6
6
 
7
- type SerializedColor = LuaTable<string, unknown> & {
7
+ type SerializedColor = LuaMap<string, unknown> & {
8
8
  readonly __serializedColorBrand: symbol;
9
9
  };
10
10
 
@@ -65,7 +65,7 @@ export function copyColor(
65
65
  );
66
66
  }
67
67
 
68
- const colorTable = new LuaTable<string, unknown>();
68
+ const colorTable = new LuaMap<string, unknown>();
69
69
  copyValuesToTable(color, KEYS, colorTable);
70
70
  colorTable.set(SerializationBrand.COLOR, "");
71
71
  return colorTable as SerializedColor;
@@ -79,7 +79,7 @@ export function copyColor(
79
79
  }
80
80
 
81
81
  const [r, g, b, a, ro, go, bo] = getNumbersFromTable(
82
- color as LuaTable<string, unknown>,
82
+ color as LuaMap<string, unknown>,
83
83
  OBJECT_NAME,
84
84
  ...KEYS,
85
85
  );
@@ -3,12 +3,12 @@ import { CopyableIsaacAPIClassType } from "../enums/private/CopyableIsaacAPIClas
3
3
  import { SerializationBrand } from "../enums/private/SerializationBrand";
4
4
  import { SerializationType } from "../enums/SerializationType";
5
5
  import { SAVE_DATA_MANAGER_DEBUG } from "../features/saveDataManager/saveDataManagerConstants";
6
- import { isSerializationBrand } from "../features/saveDataManager/serializationBrand";
6
+ import { isSerializationBrand } from "../features/saveDataManager/serializationBrands";
7
7
  import { TSTLClass } from "../types/private/TSTLClass";
8
8
  import { isArray } from "./array";
9
9
  import { getEnumValues } from "./enums";
10
10
  import { getIsaacAPIClassName } from "./isaacAPIClass";
11
- import { log, logTable } from "./log";
11
+ import { log } from "./log";
12
12
  import {
13
13
  copyIsaacAPIClass,
14
14
  deserializeIsaacAPIClass,
@@ -36,7 +36,7 @@ const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
36
36
  * It supports the following object types:
37
37
  *
38
38
  * - Primitives (i.e. strings, numbers, and booleans)
39
- * - `LuaTable` / basic TSTL objects
39
+ * - Basic TSTL objects / tables
40
40
  * - TSTL `Map`
41
41
  * - TSTL `Set`
42
42
  * - TSTL classes
@@ -101,9 +101,9 @@ export function deepCopy(
101
101
  }
102
102
 
103
103
  case "table": {
104
- const luaTable = value as LuaTable<AnyNotNil, unknown>;
104
+ const luaMap = value as LuaMap<AnyNotNil, unknown>;
105
105
  return deepCopyTable(
106
- luaTable,
106
+ luaMap,
107
107
  serializationType,
108
108
  traversalDescription,
109
109
  insideMap,
@@ -117,40 +117,40 @@ export function deepCopy(
117
117
  }
118
118
 
119
119
  function deepCopyTable(
120
- luaTable: LuaTable<AnyNotNil, unknown>,
120
+ luaMap: LuaMap<AnyNotNil, unknown>,
121
121
  serializationType: SerializationType,
122
122
  traversalDescription: string,
123
123
  insideMap: boolean,
124
124
  ) {
125
125
  // First, handle the cases of TSTL classes or serialized TSTL classes.
126
- if (isDefaultMap(luaTable) || luaTable.has(SerializationBrand.DEFAULT_MAP)) {
126
+ if (isDefaultMap(luaMap) || luaMap.has(SerializationBrand.DEFAULT_MAP)) {
127
127
  return deepCopyDefaultMap(
128
- luaTable,
128
+ luaMap,
129
129
  serializationType,
130
130
  traversalDescription,
131
131
  insideMap,
132
132
  );
133
133
  }
134
134
 
135
- if (isTSTLMap(luaTable) || luaTable.has(SerializationBrand.MAP)) {
135
+ if (isTSTLMap(luaMap) || luaMap.has(SerializationBrand.MAP)) {
136
136
  return deepCopyMap(
137
- luaTable,
137
+ luaMap,
138
138
  serializationType,
139
139
  traversalDescription,
140
140
  insideMap,
141
141
  );
142
142
  }
143
143
 
144
- if (isTSTLSet(luaTable) || luaTable.has(SerializationBrand.SET)) {
144
+ if (isTSTLSet(luaMap) || luaMap.has(SerializationBrand.SET)) {
145
145
  return deepCopySet(
146
- luaTable,
146
+ luaMap,
147
147
  serializationType,
148
148
  traversalDescription,
149
149
  insideMap,
150
150
  );
151
151
  }
152
152
 
153
- const className = getTSTLClassName(luaTable);
153
+ const className = getTSTLClassName(luaMap);
154
154
 
155
155
  if (className === "WeakMap") {
156
156
  error(
@@ -164,9 +164,9 @@ function deepCopyTable(
164
164
  );
165
165
  }
166
166
 
167
- if (isUserDefinedTSTLClass(luaTable)) {
167
+ if (isUserDefinedTSTLClass(luaMap)) {
168
168
  return deepCopyTSTLClass(
169
- luaTable,
169
+ luaMap,
170
170
  serializationType,
171
171
  traversalDescription,
172
172
  insideMap,
@@ -174,20 +174,20 @@ function deepCopyTable(
174
174
  }
175
175
 
176
176
  // This is not a TSTL Map/Set/class. If it has a metatable, abort.
177
- checkMetatable(luaTable, traversalDescription);
177
+ checkMetatable(luaMap, traversalDescription);
178
178
 
179
179
  // Handle the special case of serialized Isaac API classes.
180
180
  if (
181
- isSerializedIsaacAPIClass(luaTable) &&
181
+ isSerializedIsaacAPIClass(luaMap) &&
182
182
  serializationType === SerializationType.DESERIALIZE
183
183
  ) {
184
- return deserializeIsaacAPIClass(luaTable);
184
+ return deserializeIsaacAPIClass(luaMap);
185
185
  }
186
186
 
187
187
  // Handle the special case of an array.
188
- if (isArray(luaTable)) {
188
+ if (isArray(luaMap)) {
189
189
  return deepCopyArray(
190
- luaTable,
190
+ luaMap,
191
191
  serializationType,
192
192
  traversalDescription,
193
193
  insideMap,
@@ -196,7 +196,7 @@ function deepCopyTable(
196
196
 
197
197
  // Base case: copy a normal Lua table
198
198
  return deepCopyNormalLuaTable(
199
- luaTable,
199
+ luaMap,
200
200
  serializationType,
201
201
  traversalDescription,
202
202
  insideMap,
@@ -204,11 +204,16 @@ function deepCopyTable(
204
204
  }
205
205
 
206
206
  function deepCopyDefaultMap(
207
- defaultMap: DefaultMap<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
207
+ defaultMap: DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
208
208
  serializationType: SerializationType,
209
209
  traversalDescription: string,
210
210
  insideMap: boolean,
211
211
  ) {
212
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
213
+ if (SAVE_DATA_MANAGER_DEBUG) {
214
+ log("deepCopy is copying a DefaultMap.");
215
+ }
216
+
212
217
  const constructorArg = isDefaultMap(defaultMap)
213
218
  ? defaultMap.getConstructorArg()
214
219
  : undefined; // The undefined case is handled explicitly in the "getNewDefaultMap" function.
@@ -287,11 +292,11 @@ function deepCopyDefaultMap(
287
292
  * whether we are serializing or not.
288
293
  */
289
294
  function getNewDefaultMap(
290
- defaultMap: DefaultMap<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
295
+ defaultMap: DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
291
296
  serializationType: SerializationType,
292
297
  traversalDescription: string,
293
298
  constructorArg: unknown,
294
- ) {
299
+ ): DefaultMap<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown> {
295
300
  switch (serializationType) {
296
301
  case SerializationType.NONE: {
297
302
  // eslint-disable-next-line isaacscript/no-invalid-default-map
@@ -301,7 +306,7 @@ function getNewDefaultMap(
301
306
  case SerializationType.SERIALIZE: {
302
307
  // Since we are serializing, the new object will be a Lua table. (At this point, we already
303
308
  // handled the special case of a DefaultMap instantiated with a factory function.)
304
- const newDefaultMap = new LuaTable<AnyNotNil, unknown>();
309
+ const newDefaultMap = new LuaMap<AnyNotNil, unknown>();
305
310
  newDefaultMap.set(SerializationBrand.DEFAULT_MAP, "");
306
311
  newDefaultMap.set(SerializationBrand.DEFAULT_MAP_VALUE, constructorArg);
307
312
 
@@ -331,15 +336,20 @@ function getNewDefaultMap(
331
336
  }
332
337
 
333
338
  function deepCopyMap(
334
- map: Map<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>,
339
+ map: Map<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>,
335
340
  serializationType: SerializationType,
336
341
  traversalDescription: string,
337
342
  insideMap: boolean,
338
343
  ) {
339
- let newMap: Map<AnyNotNil, unknown> | LuaTable<AnyNotNil, unknown>;
344
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
345
+ if (SAVE_DATA_MANAGER_DEBUG) {
346
+ log("deepCopy is copying a Map.");
347
+ }
348
+
349
+ let newMap: Map<AnyNotNil, unknown> | LuaMap<AnyNotNil, unknown>;
340
350
  if (serializationType === SerializationType.SERIALIZE) {
341
351
  // Since we are serializing, the new object will be a Lua table.
342
- newMap = new LuaTable<AnyNotNil, unknown>();
352
+ newMap = new LuaMap<AnyNotNil, unknown>();
343
353
  newMap.set(SerializationBrand.MAP, "");
344
354
  } else {
345
355
  newMap = new Map();
@@ -379,16 +389,21 @@ function deepCopyMap(
379
389
  }
380
390
 
381
391
  function deepCopySet(
382
- set: Set<AnyNotNil> | LuaTable<AnyNotNil, unknown>,
392
+ set: Set<AnyNotNil> | LuaMap<AnyNotNil, unknown>,
383
393
  serializationType: SerializationType,
384
394
  traversalDescription: string,
385
395
  insideMap: boolean,
386
396
  ) {
387
- let newSet: Set<AnyNotNil> | LuaTable<AnyNotNil, string>;
397
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
398
+ if (SAVE_DATA_MANAGER_DEBUG) {
399
+ log("deepCopy is copying a Set.");
400
+ }
401
+
402
+ let newSet: Set<AnyNotNil> | LuaMap<AnyNotNil, string>;
388
403
  if (serializationType === SerializationType.SERIALIZE) {
389
404
  // For serialization purposes, we represent a `Set` as a table with keys that match the
390
405
  // keys/values in the Set and values of an empty string.
391
- newSet = new LuaTable<AnyNotNil, string>();
406
+ newSet = new LuaMap<AnyNotNil, string>();
392
407
  newSet.set(SerializationBrand.SET, "");
393
408
  } else {
394
409
  newSet = new Set();
@@ -405,7 +420,7 @@ function deepCopySet(
405
420
  // Differentiating between the two types looks superfluous but is necessary for TSTL to produce
406
421
  // the proper set method call.
407
422
  if (isTSTLSet(newSet)) {
408
- // We should never be serializing an object of type Set.
423
+ // We should never be serializing an object of type `Set`.
409
424
  error(
410
425
  "The deep copy function cannot convert number keys to strings for a Set.",
411
426
  );
@@ -433,10 +448,15 @@ function deepCopyTSTLClass(
433
448
  traversalDescription: string,
434
449
  insideMap: boolean,
435
450
  ) {
436
- let newClass: TSTLClass | LuaTable<AnyNotNil, unknown>;
451
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
452
+ if (SAVE_DATA_MANAGER_DEBUG) {
453
+ log("deepCopy is copying a TSTL class.");
454
+ }
455
+
456
+ let newClass: TSTLClass | LuaMap<AnyNotNil, unknown>;
437
457
  if (serializationType === SerializationType.SERIALIZE) {
438
458
  // Since we are serializing, the new object will be a Lua table.
439
- newClass = new LuaTable<AnyNotNil, unknown>();
459
+ newClass = new LuaMap<AnyNotNil, unknown>();
440
460
  // (We do not brand it with the class type because we will not have the associated class
441
461
  // constructor during deserialization, so knowing what type of class it is is pointless.)
442
462
  } else {
@@ -467,6 +487,11 @@ function deepCopyArray(
467
487
  traversalDescription: string,
468
488
  insideMap: boolean,
469
489
  ) {
490
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
491
+ if (SAVE_DATA_MANAGER_DEBUG) {
492
+ log("deepCopy is copying an array.");
493
+ }
494
+
470
495
  const newArray: unknown[] = [];
471
496
 
472
497
  for (const value of array) {
@@ -483,14 +508,19 @@ function deepCopyArray(
483
508
  }
484
509
 
485
510
  function deepCopyNormalLuaTable(
486
- luaTable: LuaTable<AnyNotNil, unknown>,
511
+ luaMap: LuaMap<AnyNotNil, unknown>,
487
512
  serializationType: SerializationType,
488
513
  traversalDescription: string,
489
514
  insideMap: boolean,
490
515
  ) {
491
- const newTable = new LuaTable<AnyNotNil, unknown>();
516
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
517
+ if (SAVE_DATA_MANAGER_DEBUG) {
518
+ log("deepCopy is copying a normal Lua table.");
519
+ }
520
+
521
+ const newTable = new LuaMap<AnyNotNil, unknown>();
492
522
  const { entries, convertedNumberKeysToStrings } = getCopiedEntries(
493
- luaTable,
523
+ luaMap,
494
524
  serializationType,
495
525
  traversalDescription,
496
526
  insideMap,
@@ -535,7 +565,6 @@ function getCopiedEntries(
535
565
 
536
566
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
537
567
  if (SAVE_DATA_MANAGER_DEBUG) {
538
- logTable(entries);
539
568
  entries.sort(twoDimensionalSort);
540
569
  }
541
570
 
@@ -575,8 +604,11 @@ function getCopiedEntries(
575
604
  * copy function will refuse to copy a table type that has a metatable, outside of specifically
576
605
  * supported TSTL objects.
577
606
  */
578
- function checkMetatable(luaTable: LuaTable, traversalDescription: string) {
579
- const metatable = getmetatable(luaTable);
607
+ function checkMetatable(
608
+ luaMap: LuaMap<AnyNotNil, unknown>,
609
+ traversalDescription: string,
610
+ ) {
611
+ const metatable = getmetatable(luaMap);
580
612
  if (metatable === undefined) {
581
613
  return;
582
614
  }
@@ -597,6 +629,11 @@ function deepCopyUserdata(
597
629
  serializationType: SerializationType,
598
630
  traversalDescription: string,
599
631
  ) {
632
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
633
+ if (SAVE_DATA_MANAGER_DEBUG) {
634
+ log("deepCopy is copying userdata.");
635
+ }
636
+
600
637
  const classType = getIsaacAPIClassName(value);
601
638
  if (classType === undefined) {
602
639
  error(
@@ -40,7 +40,7 @@ function copiedObjectIsTable() {
40
40
  abc: "def",
41
41
  };
42
42
  const newObject = deepCopy(
43
- oldObject as unknown as LuaTable,
43
+ oldObject as unknown as LuaMap,
44
44
  SerializationType.NONE,
45
45
  "copiedObjectIsTable",
46
46
  );
@@ -56,7 +56,7 @@ function copiedObjectHasKeyAndValueString() {
56
56
  abc: valueToLookFor,
57
57
  };
58
58
  const newTable = deepCopy(
59
- oldObject as unknown as LuaTable,
59
+ oldObject as unknown as LuaMap,
60
60
  SerializationType.NONE,
61
61
  "copiedObjectHasKeyAndValueString",
62
62
  );
@@ -79,7 +79,7 @@ function copiedObjectHasKeyAndValueString() {
79
79
  function copiedTableHasKeyAndValueNumber() {
80
80
  const keyToLookFor = 123;
81
81
  const valueToLookFor = 456;
82
- const oldTable = new LuaTable<AnyNotNil, unknown>();
82
+ const oldTable = new LuaMap<AnyNotNil, unknown>();
83
83
  oldTable.set(keyToLookFor, valueToLookFor);
84
84
 
85
85
  const newObject = deepCopy(
@@ -87,7 +87,7 @@ function copiedTableHasKeyAndValueNumber() {
87
87
  SerializationType.NONE,
88
88
  "copiedTableHasKeyAndValueNumber",
89
89
  );
90
- const newTable = newObject as LuaTable<AnyNotNil, unknown>;
90
+ const newTable = newObject as LuaMap<AnyNotNil, unknown>;
91
91
 
92
92
  const value = newTable.get(keyToLookFor) as number | undefined;
93
93
  if (value === undefined) {
@@ -105,7 +105,7 @@ function copiedTableHasKeyAndValueNumber() {
105
105
  function copiedTableDoesNotCoerceTypes() {
106
106
  const keyToLookFor = 123;
107
107
  const valueToLookFor = 456;
108
- const oldTable = new LuaTable<AnyNotNil, unknown>();
108
+ const oldTable = new LuaMap<AnyNotNil, unknown>();
109
109
  oldTable.set(keyToLookFor, valueToLookFor);
110
110
 
111
111
  const newObject = deepCopy(
@@ -113,7 +113,7 @@ function copiedTableDoesNotCoerceTypes() {
113
113
  SerializationType.NONE,
114
114
  "copiedTableDoesNotCoerceTypes",
115
115
  );
116
- const newTable = newObject as LuaTable<AnyNotNil, unknown>;
116
+ const newTable = newObject as LuaMap<AnyNotNil, unknown>;
117
117
 
118
118
  const keyString = tostring(keyToLookFor);
119
119
  const valueString = tostring(valueToLookFor);
@@ -140,7 +140,7 @@ function copiedObjectHasNoReferencesForPrimitivesForward() {
140
140
  def: originalNumberValue,
141
141
  };
142
142
  const newTable = deepCopy(
143
- oldObject as unknown as LuaTable,
143
+ oldObject as unknown as LuaMap,
144
144
  SerializationType.NONE,
145
145
  "copiedObjectHasNoReferencesForPrimitivesForward",
146
146
  );
@@ -165,7 +165,7 @@ function copiedObjectHasNoReferencesForPrimitivesBackward() {
165
165
  def: originalNumberValue,
166
166
  };
167
167
  const newTable = deepCopy(
168
- oldObject as unknown as LuaTable,
168
+ oldObject as unknown as LuaMap,
169
169
  SerializationType.NONE,
170
170
  "copiedObjectHasNoReferencesForPrimitivesBackward",
171
171
  );
@@ -188,7 +188,7 @@ function copiedObjectHasNoReferencesForArray() {
188
188
  abc: [1, 2, 3],
189
189
  };
190
190
  const newTable = deepCopy(
191
- oldObject as unknown as LuaTable,
191
+ oldObject as unknown as LuaMap,
192
192
  SerializationType.NONE,
193
193
  "copiedObjectHasNoReferencesForArray",
194
194
  );
@@ -229,7 +229,7 @@ function copiedObjectHasChildObject() {
229
229
  },
230
230
  };
231
231
  const newTable = deepCopy(
232
- oldObject as unknown as LuaTable,
232
+ oldObject as unknown as LuaMap,
233
233
  SerializationType.NONE,
234
234
  "copiedObjectHasChildObject",
235
235
  );
@@ -268,11 +268,8 @@ function copiedMapIsMap() {
268
268
  const newObject = deepCopy(oldMap, SerializationType.NONE, "copiedMapIsMap");
269
269
  const newMap = newObject as Map<string, string>;
270
270
 
271
- if (!isTable(newMap)) {
272
- error(`The copied Map had a type of: ${typeof newMap}`);
273
- }
274
271
  if (!isTSTLMap(newMap)) {
275
- error("The copied Map was not a Map.");
272
+ error(`The copied Map was not a Map and has a type of: ${typeof newMap}`);
276
273
  }
277
274
  }
278
275
 
@@ -287,8 +284,13 @@ function copiedMapHasValue() {
287
284
  SerializationType.NONE,
288
285
  "copiedMapHasValue",
289
286
  );
287
+
290
288
  const newMap = newTable as typeof oldMap;
291
289
 
290
+ if (!isTSTLMap(newMap)) {
291
+ error(`The copied Map was not a Map and has a type of: ${typeof newMap}`);
292
+ }
293
+
292
294
  const value = newMap.get(keyToLookFor);
293
295
  if (value === undefined) {
294
296
  error(`The copied Map did not have a key of: ${keyToLookFor}`);
@@ -306,11 +308,8 @@ function copiedSetIsSet() {
306
308
  const newTable = deepCopy(oldSet, SerializationType.NONE, "copiedSetIsSet");
307
309
  const newSet = newTable as Set<string>;
308
310
 
309
- if (!isTable(newSet)) {
310
- error(`The copied Set had a type of: ${typeof newSet}`);
311
- }
312
311
  if (!isTSTLSet(newSet)) {
313
- error("The copied Set was not a Map.");
312
+ error(`The copied Set was not a Set and has a type of: ${typeof newSet}`);
314
313
  }
315
314
  }
316
315
 
@@ -326,6 +325,10 @@ function copiedSetHasValue() {
326
325
  );
327
326
  const newSet = newTable as Set<string>;
328
327
 
328
+ if (!isTSTLSet(newSet)) {
329
+ error(`The copied Set was not a Set and has a type of: ${typeof newSet}`);
330
+ }
331
+
329
332
  const hasValue = newSet.has(valueToLookFor);
330
333
  if (!hasValue) {
331
334
  error(`The copied Set did not have a value of: ${valueToLookFor}`);
@@ -338,7 +341,7 @@ function copiedMapHasChildMap() {
338
341
  const oldChildMap = new Map<number, number>();
339
342
  oldChildMap.set(childMapKey, childMapValue);
340
343
 
341
- const keyToLookFor = "abc";
344
+ const keyToLookFor = "childMap";
342
345
  const oldMap = new Map<string, Map<number, number>>();
343
346
  oldMap.set(keyToLookFor, oldChildMap);
344
347
 
@@ -349,16 +352,19 @@ function copiedMapHasChildMap() {
349
352
  );
350
353
  const newMap = newTable as typeof oldMap;
351
354
 
355
+ if (!isTSTLMap(newMap)) {
356
+ error(`The copied Map was not a Map and had a type of: ${typeof newMap}`);
357
+ }
358
+
352
359
  const newChildMap = newMap.get(keyToLookFor);
353
360
  if (newChildMap === undefined) {
354
361
  error(`The copied Map did not have a child map at key: ${keyToLookFor}`);
355
362
  }
356
363
 
357
- if (!isTable(newChildMap)) {
358
- error(`The copied child Map had a type of: ${typeof newChildMap}`);
359
- }
360
364
  if (!isTSTLMap(newChildMap)) {
361
- error("The copied child Map was not a Map.");
365
+ error(
366
+ `The copied child Map was not a Map and had a type of: ${typeof newChildMap}`,
367
+ );
362
368
  }
363
369
 
364
370
  const value = newChildMap.get(childMapKey);
@@ -390,6 +396,12 @@ function copiedDefaultMapHasChildDefaultMap() {
390
396
  );
391
397
  const newParentMap = newTable as typeof oldParentMap;
392
398
 
399
+ if (!isDefaultMap(newParentMap)) {
400
+ error(
401
+ `The copied parent DefaultMap was not a DefaultMap and had a type of: ${typeof newParentMap}`,
402
+ );
403
+ }
404
+
393
405
  const newChildMap = newParentMap.get(parentMapKey);
394
406
  if (newChildMap === undefined) {
395
407
  error(
@@ -397,11 +409,10 @@ function copiedDefaultMapHasChildDefaultMap() {
397
409
  );
398
410
  }
399
411
 
400
- if (!isTable(newChildMap)) {
401
- error(`The copied child DefaultMap had a type of: ${typeof newChildMap}`);
402
- }
403
412
  if (!isDefaultMap(newChildMap)) {
404
- error("The copied child DefaultMap was not a DefaultMap.");
413
+ error(
414
+ `The copied child DefaultMap was not a DefaultMap and had a type of: ${typeof newChildMap}`,
415
+ );
405
416
  }
406
417
 
407
418
  const newChildMapValue1 = newChildMap.get(childMapKey1);
@@ -432,7 +443,13 @@ function copiedDefaultMapHasBrand() {
432
443
  oldDefaultMap,
433
444
  SerializationType.SERIALIZE,
434
445
  "copiedDefaultMapHasBrand",
435
- ) as LuaTable<AnyNotNil, unknown>;
446
+ ) as LuaMap<AnyNotNil, unknown>;
447
+
448
+ if (!isTable(newTable)) {
449
+ error(
450
+ `The copied DefaultMap was not a table and had a type of: ${typeof newTable}`,
451
+ );
452
+ }
436
453
 
437
454
  if (!newTable.has(SerializationBrand.DEFAULT_MAP)) {
438
455
  error(
@@ -137,11 +137,11 @@ export function getEntities(
137
137
  */
138
138
  export function getEntityFields(
139
139
  entity: Entity,
140
- ): LuaTable<string, boolean | number | string> {
141
- const entityFields = new LuaTable<string, boolean | number | string>();
140
+ ): LuaMap<string, boolean | number | string> {
141
+ const entityFields = new LuaMap<string, boolean | number | string>();
142
142
 
143
143
  const metatable = getmetatable(entity) as
144
- | LuaTable<AnyNotNil, unknown>
144
+ | LuaMap<AnyNotNil, unknown>
145
145
  | undefined;
146
146
  if (metatable === undefined) {
147
147
  error("Failed to get the metatable for an entity.");
@@ -158,7 +158,7 @@ export function getEntityFields(
158
158
  }
159
159
 
160
160
  const parentTable = metatable.get("__parent") as
161
- | LuaTable<AnyNotNil, unknown>
161
+ | LuaMap<AnyNotNil, unknown>
162
162
  | undefined;
163
163
  if (parentTable === undefined) {
164
164
  error('Failed to get the "__parent" table for an entity.');
@@ -171,11 +171,11 @@ export function getEntityFields(
171
171
 
172
172
  function setPrimitiveEntityFields(
173
173
  entity: Entity,
174
- metatable: LuaTable<AnyNotNil, unknown>,
175
- entityFields: LuaTable<string, boolean | number | string>,
174
+ metatable: LuaMap<AnyNotNil, unknown>,
175
+ entityFields: LuaMap<string, boolean | number | string>,
176
176
  ) {
177
177
  const propGetTable = metatable.get("__propget") as
178
- | LuaTable<AnyNotNil, unknown>
178
+ | LuaMap<AnyNotNil, unknown>
179
179
  | undefined;
180
180
  if (propGetTable === undefined) {
181
181
  error('Failed to get the "__propget" table for an entity.');
@@ -4,10 +4,9 @@ import {
4
4
  ControllerIndex,
5
5
  Keyboard,
6
6
  } from "isaac-typescript-definitions";
7
- import { MAX_NUM_INPUTS } from "../constants";
7
+ import { getEnumValues } from "./enums";
8
8
  import { copySet } from "./set";
9
9
  import { trimPrefix } from "./string";
10
- import { erange } from "./utils";
11
10
 
12
11
  const MODIFIER_KEYS: readonly Keyboard[] = [
13
12
  Keyboard.LEFT_SHIFT, // 340
@@ -62,9 +61,9 @@ export function getShootActions(): Set<ButtonAction> {
62
61
 
63
62
  /** Iterates over all inputs to determine if a particular button is pressed (i.e. held down). */
64
63
  export function isActionPressedOnAnyInput(buttonAction: ButtonAction): boolean {
65
- const validInputs = erange(MAX_NUM_INPUTS);
66
- return validInputs.some((input) =>
67
- Input.IsActionPressed(buttonAction, input),
64
+ const controllerIndexes = getEnumValues(ControllerIndex);
65
+ return controllerIndexes.some((controllerIndex) =>
66
+ Input.IsActionPressed(buttonAction, controllerIndex),
68
67
  );
69
68
  }
70
69
 
@@ -75,9 +74,9 @@ export function isActionPressedOnAnyInput(buttonAction: ButtonAction): boolean {
75
74
  export function isActionTriggeredOnAnyInput(
76
75
  buttonAction: ButtonAction,
77
76
  ): boolean {
78
- const validInputs = erange(MAX_NUM_INPUTS);
79
- return validInputs.some((input) =>
80
- Input.IsActionTriggered(buttonAction, input),
77
+ const controllerIndexes = getEnumValues(ControllerIndex);
78
+ return controllerIndexes.some((controllerIndex) =>
79
+ Input.IsActionTriggered(buttonAction, controllerIndex),
81
80
  );
82
81
  }
83
82
 
@@ -16,7 +16,7 @@ export function getIsaacAPIClassName(object: unknown): string | undefined {
16
16
  }
17
17
 
18
18
  const metatable = getmetatable(object) as
19
- | LuaTable<AnyNotNil, unknown>
19
+ | LuaMap<AnyNotNil, unknown>
20
20
  | undefined;
21
21
  if (metatable === undefined) {
22
22
  return undefined;
@@ -60,8 +60,8 @@ export function isaacAPIClassEquals(
60
60
  object2: unknown,
61
61
  keys: string[],
62
62
  ): boolean {
63
- const table1 = object1 as LuaTable<AnyNotNil, unknown>;
64
- const table2 = object2 as LuaTable<AnyNotNil, unknown>;
63
+ const table1 = object1 as LuaMap<AnyNotNil, unknown>;
64
+ const table2 = object2 as LuaMap<AnyNotNil, unknown>;
65
65
 
66
66
  return keys.every((key) => table1.get(key) === table2.get(key));
67
67
  }