isaacscript-common 6.7.1 → 6.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) 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/commandsSubroutines.lua +4 -4
  16. package/dist/features/extraConsoleCommands/init.lua +1 -0
  17. package/dist/features/extraConsoleCommands/listCommands.d.ts +8 -0
  18. package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
  19. package/dist/features/extraConsoleCommands/listCommands.lua +13 -0
  20. package/dist/features/saveDataManager/exports.d.ts.map +1 -1
  21. package/dist/features/saveDataManager/exports.lua +2 -4
  22. package/dist/features/saveDataManager/load.d.ts +1 -1
  23. package/dist/features/saveDataManager/load.d.ts.map +1 -1
  24. package/dist/features/saveDataManager/main.d.ts.map +1 -1
  25. package/dist/features/saveDataManager/main.lua +0 -1
  26. package/dist/features/saveDataManager/maps.d.ts +3 -3
  27. package/dist/features/saveDataManager/maps.d.ts.map +1 -1
  28. package/dist/features/saveDataManager/maps.lua +1 -4
  29. package/dist/features/saveDataManager/merge.d.ts +2 -2
  30. package/dist/features/saveDataManager/merge.d.ts.map +1 -1
  31. package/dist/features/saveDataManager/merge.lua +3 -3
  32. package/dist/features/saveDataManager/save.d.ts +1 -1
  33. package/dist/features/saveDataManager/save.d.ts.map +1 -1
  34. package/dist/features/saveDataManager/save.lua +1 -2
  35. package/dist/features/saveDataManager/{serializationBrand.d.ts → serializationBrands.d.ts} +1 -1
  36. package/dist/features/saveDataManager/serializationBrands.d.ts.map +1 -0
  37. package/dist/features/saveDataManager/{serializationBrand.lua → serializationBrands.lua} +0 -0
  38. package/dist/functions/array.d.ts.map +1 -1
  39. package/dist/functions/color.d.ts +1 -1
  40. package/dist/functions/color.d.ts.map +1 -1
  41. package/dist/functions/deepCopy.d.ts +1 -1
  42. package/dist/functions/deepCopy.lua +27 -27
  43. package/dist/functions/deepCopyTests.lua +3 -3
  44. package/dist/functions/entities.d.ts +1 -1
  45. package/dist/functions/entities.d.ts.map +1 -1
  46. package/dist/functions/input.d.ts.map +1 -1
  47. package/dist/functions/input.lua +8 -10
  48. package/dist/functions/jsonHelpers.d.ts +1 -1
  49. package/dist/functions/jsonHelpers.d.ts.map +1 -1
  50. package/dist/functions/kColor.d.ts +1 -1
  51. package/dist/functions/kColor.d.ts.map +1 -1
  52. package/dist/functions/log.d.ts +15 -7
  53. package/dist/functions/log.d.ts.map +1 -1
  54. package/dist/functions/log.lua +196 -156
  55. package/dist/functions/mergeTests.d.ts +2 -2
  56. package/dist/functions/mergeTests.lua +2 -2
  57. package/dist/functions/pickupsSpecific.d.ts +2 -2
  58. package/dist/functions/pickupsSpecific.d.ts.map +1 -1
  59. package/dist/functions/playerIndex.d.ts +1 -1
  60. package/dist/functions/playerIndex.lua +1 -1
  61. package/dist/functions/rng.d.ts +1 -1
  62. package/dist/functions/rng.d.ts.map +1 -1
  63. package/dist/functions/run.d.ts +8 -0
  64. package/dist/functions/run.d.ts.map +1 -1
  65. package/dist/functions/run.lua +15 -0
  66. package/dist/functions/table.d.ts +9 -9
  67. package/dist/functions/table.d.ts.map +1 -1
  68. package/dist/functions/table.lua +23 -21
  69. package/dist/functions/types.d.ts +1 -1
  70. package/dist/functions/types.d.ts.map +1 -1
  71. package/dist/functions/vector.d.ts +1 -1
  72. package/dist/functions/vector.d.ts.map +1 -1
  73. package/dist/interfaces/SaveData.d.ts +1 -1
  74. package/dist/interfaces/private/TSTLClassMetatable.d.ts +1 -1
  75. package/dist/interfaces/private/TSTLClassMetatable.d.ts.map +1 -1
  76. package/dist/lualib_bundle.lua +38 -7
  77. package/dist/types/PlayerIndex.d.ts +3 -2
  78. package/dist/types/PlayerIndex.d.ts.map +1 -1
  79. package/dist/types/private/IsaacAPIClass.d.ts +1 -1
  80. package/dist/types/private/IsaacAPIClass.d.ts.map +1 -1
  81. package/dist/types/private/SerializedIsaacAPIClass.d.ts +1 -1
  82. package/dist/types/private/SerializedIsaacAPIClass.d.ts.map +1 -1
  83. package/dist/types/private/TSTLClass.d.ts +1 -1
  84. package/dist/types/private/TSTLClass.d.ts.map +1 -1
  85. package/package.json +2 -2
  86. package/src/features/customStage/customStageGridEntities.ts +4 -4
  87. package/src/features/customStage/exports.ts +5 -3
  88. package/src/features/customStage/init.ts +19 -7
  89. package/src/features/customStage/streakText.ts +284 -19
  90. package/src/features/customStage/v.ts +6 -1
  91. package/src/features/customStage/versusScreen.ts +2 -5
  92. package/src/features/extraConsoleCommands/commandsSubroutines.ts +3 -3
  93. package/src/features/extraConsoleCommands/init.ts +1 -0
  94. package/src/features/extraConsoleCommands/listCommands.ts +14 -0
  95. package/src/features/saveDataManager/exports.ts +3 -8
  96. package/src/features/saveDataManager/load.ts +2 -3
  97. package/src/features/saveDataManager/main.ts +4 -5
  98. package/src/features/saveDataManager/maps.ts +3 -3
  99. package/src/features/saveDataManager/merge.ts +11 -11
  100. package/src/features/saveDataManager/save.ts +6 -6
  101. package/src/features/saveDataManager/{serializationBrand.ts → serializationBrands.ts} +0 -0
  102. package/src/functions/array.ts +2 -4
  103. package/src/functions/color.ts +3 -3
  104. package/src/functions/deepCopy.ts +39 -36
  105. package/src/functions/deepCopyTests.ts +11 -11
  106. package/src/functions/entities.ts +7 -7
  107. package/src/functions/input.ts +7 -8
  108. package/src/functions/isaacAPIClass.ts +3 -3
  109. package/src/functions/jsonHelpers.ts +3 -3
  110. package/src/functions/kColor.ts +3 -3
  111. package/src/functions/log.ts +230 -183
  112. package/src/functions/mergeTests.ts +24 -24
  113. package/src/functions/pickupsSpecific.ts +3 -3
  114. package/src/functions/playerIndex.ts +1 -1
  115. package/src/functions/rng.ts +3 -3
  116. package/src/functions/run.ts +14 -0
  117. package/src/functions/table.ts +25 -23
  118. package/src/functions/tstlClass.ts +1 -1
  119. package/src/functions/types.ts +3 -1
  120. package/src/functions/vector.ts +3 -3
  121. package/src/interfaces/SaveData.ts +1 -1
  122. package/src/interfaces/private/TSTLClassMetatable.ts +1 -1
  123. package/src/types/PlayerIndex.ts +3 -2
  124. package/src/types/private/IsaacAPIClass.ts +1 -1
  125. package/src/types/private/SerializedIsaacAPIClass.ts +1 -1
  126. package/src/types/private/TSTLClass.ts +1 -1
  127. package/dist/features/saveDataManager/serializationBrand.d.ts.map +0 -1
@@ -19,7 +19,7 @@ import { getCollectibleName } from "./collectibles";
19
19
  import { getEntities, getEntityID } from "./entities";
20
20
  import { getEnumEntries } from "./enums";
21
21
  import { hasFlag } from "./flag";
22
- import { getGridEntities } from "./gridEntities";
22
+ import { getGridEntities, getGridEntityID } from "./gridEntities";
23
23
  import { getIsaacAPIClassName } from "./isaacAPIClass";
24
24
  import { getPlayerHealth } from "./playerHealth";
25
25
  import { getEffectsList, getPlayerName } from "./players";
@@ -83,6 +83,106 @@ export function log(this: void, msg: string): void {
83
83
  Isaac.DebugString(debugMsg);
84
84
  }
85
85
 
86
+ /** Helper function for printing out every entity (or filtered entity) in the current room. */
87
+ export function logAllEntities(
88
+ this: void,
89
+ includeBackgroundEffects: boolean,
90
+ entityTypeFilter?: EntityType,
91
+ ): void {
92
+ let msg = "Entities in the room";
93
+ if (entityTypeFilter !== undefined) {
94
+ msg += ` (filtered to entity type ${entityTypeFilter})`;
95
+ } else if (!includeBackgroundEffects) {
96
+ msg += " (not including background effects)";
97
+ }
98
+ msg += ":\n";
99
+
100
+ const entities = getEntities();
101
+ let numMatchedEntities = 0;
102
+ entities.forEach((entity, i) => {
103
+ // If a filter was specified, exclude all entities outside of the filter.
104
+ if (entityTypeFilter !== undefined && entity.Type !== entityTypeFilter) {
105
+ return;
106
+ }
107
+
108
+ const effect = entity.ToEffect();
109
+ if (
110
+ !includeBackgroundEffects &&
111
+ effect !== undefined &&
112
+ IGNORE_EFFECT_VARIANTS.has(effect.Variant)
113
+ ) {
114
+ return;
115
+ }
116
+
117
+ msg += getEntityLogLine(entity, i + 1);
118
+ numMatchedEntities++;
119
+ });
120
+
121
+ if (numMatchedEntities === 0) {
122
+ msg += "(no entities matched)\n";
123
+ } else {
124
+ msg += `(${numMatchedEntities} total ${
125
+ numMatchedEntities === 1 ? "entity" : "entities"
126
+ })\n`;
127
+ }
128
+
129
+ log(msg);
130
+ }
131
+
132
+ /**
133
+ * Helper function for printing out every grid entity (or filtered grid entity) in the current room.
134
+ */
135
+ export function logAllGridEntities(
136
+ this: void,
137
+ includeWalls: boolean,
138
+ gridEntityTypeFilter?: GridEntityType,
139
+ ): void {
140
+ let msg = "Grid entities in the room";
141
+ if (gridEntityTypeFilter !== undefined) {
142
+ msg += ` (filtered to grid entity type ${gridEntityTypeFilter})`;
143
+ } else if (!includeWalls) {
144
+ msg += " (not including walls)";
145
+ }
146
+ msg += ":\n";
147
+
148
+ const gridEntities = getGridEntities();
149
+ let numMatchedEntities = 0;
150
+ gridEntities.forEach((gridEntity) => {
151
+ const gridEntityIndex = gridEntity.GetGridIndex();
152
+ const gridEntityType = gridEntity.GetType();
153
+
154
+ // If a filter was specified, exclude all entities outside of the filter.
155
+ if (
156
+ gridEntityTypeFilter !== undefined &&
157
+ gridEntityType !== gridEntityTypeFilter
158
+ ) {
159
+ return;
160
+ }
161
+
162
+ if (
163
+ !includeWalls &&
164
+ gridEntityType === GridEntityType.WALL &&
165
+ gridEntityTypeFilter !== GridEntityType.WALL
166
+ ) {
167
+ return;
168
+ }
169
+
170
+ msg += getGridEntityLogLine(gridEntity, gridEntityIndex);
171
+
172
+ numMatchedEntities++;
173
+ });
174
+
175
+ if (numMatchedEntities === 0) {
176
+ msg += "(no grid entities matched)\n";
177
+ } else {
178
+ msg += `(${numMatchedEntities} total grid ${
179
+ numMatchedEntities === 1 ? "entity" : "entities"
180
+ })\n`;
181
+ }
182
+
183
+ log(msg);
184
+ }
185
+
86
186
  export function logArray<T>(this: void, array: T[] | readonly T[]): void {
87
187
  const arrayString = arrayToString(array);
88
188
  log(`Array: ${arrayString}`);
@@ -130,116 +230,90 @@ export function logEffects(this: void, player: EntityPlayer): void {
130
230
  });
131
231
  }
132
232
 
133
- /** Helper function for printing out every entity (or filtered entity) in the current room. */
134
- export function logEntities(
135
- this: void,
136
- includeBackgroundEffects: boolean,
137
- entityTypeFilter?: EntityType,
138
- ): void {
139
- let msg = "Entities in the room";
140
- if (entityTypeFilter !== undefined) {
141
- msg += ` (filtered to entity type ${entityTypeFilter})`;
142
- } else if (!includeBackgroundEffects) {
143
- msg += " (not including background effects)";
233
+ /** Helper function for logging an array of specific entities. */
234
+ export function logEntities(this: void, entities: Entity[]): void {
235
+ for (const entity of entities) {
236
+ logEntity(entity);
144
237
  }
145
- msg += ":\n";
146
-
147
- const entities = getEntities();
148
- let numMatchedEntities = 0;
149
- entities.forEach((entity, i) => {
150
- // If a filter was specified, exclude all entities outside of the filter.
151
- if (entityTypeFilter !== undefined && entity.Type !== entityTypeFilter) {
152
- return;
153
- }
154
-
155
- const effect = entity.ToEffect();
156
- if (
157
- !includeBackgroundEffects &&
158
- effect !== undefined &&
159
- IGNORE_EFFECT_VARIANTS.has(effect.Variant)
160
- ) {
161
- return;
162
- }
238
+ }
163
239
 
164
- const entityID = getEntityID(entity);
165
- msg += `${i + 1}) ${entityID}`;
240
+ /** Helper function to log information about a specific entity. */
241
+ export function logEntity(this: void, entity: Entity): void {
242
+ const msg = getEntityLogLine(entity);
243
+ log(msg);
244
+ }
166
245
 
167
- const bomb = entity.ToBomb();
168
- if (bomb !== undefined) {
169
- msg += " (bomb)";
170
- }
246
+ function getEntityLogLine(entity: Entity, num?: int): string {
247
+ let msg = num === undefined ? "" : `${num}) `;
171
248
 
172
- if (effect !== undefined) {
173
- msg += ` (effect) (State: ${effect.State})`;
174
- }
249
+ msg += getEntityID(entity);
175
250
 
176
- const familiar = entity.ToFamiliar();
177
- if (familiar !== undefined) {
178
- msg += ` (familiar) (State: ${familiar.State})`;
179
- }
251
+ const bomb = entity.ToBomb();
252
+ if (bomb !== undefined) {
253
+ msg += " (bomb)";
254
+ }
180
255
 
181
- const knife = entity.ToKnife();
182
- if (knife !== undefined) {
183
- msg += " (knife)";
184
- }
256
+ const effect = entity.ToEffect();
257
+ if (effect !== undefined) {
258
+ msg += ` (effect) (State: ${effect.State})`;
259
+ }
185
260
 
186
- const laser = entity.ToLaser();
187
- if (laser !== undefined) {
188
- msg += " (laser)";
189
- }
261
+ const familiar = entity.ToFamiliar();
262
+ if (familiar !== undefined) {
263
+ msg += ` (familiar) (State: ${familiar.State})`;
264
+ }
190
265
 
191
- const npc = entity.ToNPC();
192
- if (npc !== undefined) {
193
- msg += ` (NPC) (State: ${npc.State})`;
194
- }
266
+ const knife = entity.ToKnife();
267
+ if (knife !== undefined) {
268
+ msg += " (knife)";
269
+ }
195
270
 
196
- const pickup = entity.ToPickup();
197
- if (pickup !== undefined) {
198
- msg += ` (pickup) (State: ${pickup.State})`;
199
- }
271
+ const laser = entity.ToLaser();
272
+ if (laser !== undefined) {
273
+ msg += " (laser)";
274
+ }
200
275
 
201
- const player = entity.ToPlayer();
202
- if (player !== undefined) {
203
- msg += " (player)";
204
- }
276
+ const npc = entity.ToNPC();
277
+ if (npc !== undefined) {
278
+ msg += ` (NPC) (State: ${npc.State})`;
279
+ }
205
280
 
206
- const projectile = entity.ToProjectile();
207
- if (projectile !== undefined) {
208
- msg += " (projectile)";
209
- }
281
+ const pickup = entity.ToPickup();
282
+ if (pickup !== undefined) {
283
+ msg += ` (pickup) (State: ${pickup.State})`;
284
+ }
210
285
 
211
- const tear = entity.ToTear();
212
- if (tear !== undefined) {
213
- msg += " (tear)";
214
- }
286
+ const player = entity.ToPlayer();
287
+ if (player !== undefined) {
288
+ msg += " (player)";
289
+ }
215
290
 
216
- msg += "\n";
217
- msg += ` - Index: ${entity.Index}\n`;
218
- msg += ` - InitSeed: ${entity.InitSeed}\n`;
219
- msg += ` - DropSeed: ${entity.DropSeed}\n`;
220
- msg += ` - Position: (${entity.Position.X}, ${entity.Position.Y})\n`;
221
- msg += ` - Velocity: (${entity.Velocity.X}, ${entity.Velocity.Y})\n`;
222
- msg += ` - HP: ${entity.HitPoints} / ${entity.MaxHitPoints}\n`;
223
- msg += ` - Parent: ${entity.Parent}\n`;
224
- msg += ` - Child: ${entity.Child}\n`;
225
- msg += ` - SpawnerEntity: ${entity.SpawnerEntity}\n`;
226
- msg += ` - SpawnerType / SpawnerVariant: ${entity.SpawnerType}.${entity.SpawnerVariant}\n`;
227
- if (npc !== undefined) {
228
- msg += ` - CanShutDoors: ${npc.CanShutDoors}\n`;
229
- }
291
+ const projectile = entity.ToProjectile();
292
+ if (projectile !== undefined) {
293
+ msg += " (projectile)";
294
+ }
230
295
 
231
- numMatchedEntities++;
232
- });
296
+ const tear = entity.ToTear();
297
+ if (tear !== undefined) {
298
+ msg += " (tear)";
299
+ }
233
300
 
234
- if (numMatchedEntities === 0) {
235
- msg += "(no entities matched)\n";
236
- } else {
237
- msg += `(${numMatchedEntities} total ${
238
- numMatchedEntities === 1 ? "entity" : "entities"
239
- })\n`;
301
+ msg += "\n";
302
+ msg += ` - Index: ${entity.Index}\n`;
303
+ msg += ` - InitSeed: ${entity.InitSeed}\n`;
304
+ msg += ` - DropSeed: ${entity.DropSeed}\n`;
305
+ msg += ` - Position: (${entity.Position.X}, ${entity.Position.Y})\n`;
306
+ msg += ` - Velocity: (${entity.Velocity.X}, ${entity.Velocity.Y})\n`;
307
+ msg += ` - HP: ${entity.HitPoints} / ${entity.MaxHitPoints}\n`;
308
+ msg += ` - Parent: ${entity.Parent}\n`;
309
+ msg += ` - Child: ${entity.Child}\n`;
310
+ msg += ` - SpawnerEntity: ${entity.SpawnerEntity}\n`;
311
+ msg += ` - SpawnerType / SpawnerVariant: ${entity.SpawnerType}.${entity.SpawnerVariant}\n`;
312
+ if (npc !== undefined) {
313
+ msg += ` - CanShutDoors: ${npc.CanShutDoors}\n`;
240
314
  }
241
315
 
242
- log(msg);
316
+ return msg;
243
317
  }
244
318
 
245
319
  /** Helper function for printing out every entity flag that is turned on. Useful when debugging. */
@@ -316,106 +390,74 @@ export function logGameStateFlags(this: void): void {
316
390
  }
317
391
  }
318
392
 
319
- /**
320
- * Helper function for printing out every grid entity (or filtered grid entity) in the current room.
321
- */
322
- export function logGridEntities(
323
- this: void,
324
- includeWalls: boolean,
325
- gridEntityTypeFilter?: GridEntityType,
326
- ): void {
327
- let msg = "Grid entities in the room";
328
- if (gridEntityTypeFilter !== undefined) {
329
- msg += ` (filtered to grid entity type ${gridEntityTypeFilter})`;
330
- } else if (!includeWalls) {
331
- msg += " (not including walls)";
393
+ /** Helper function for logging an array of specific grid entities. */
394
+ export function logGridEntities(this: void, gridEntities: GridEntity[]): void {
395
+ for (const gridEntity of gridEntities) {
396
+ logGridEntity(gridEntity);
332
397
  }
333
- msg += ":\n";
334
-
335
- const gridEntities = getGridEntities();
336
- let numMatchedEntities = 0;
337
- gridEntities.forEach((gridEntity) => {
338
- const gridEntityIndex = gridEntity.GetGridIndex();
339
- const gridEntityType = gridEntity.GetType();
340
- const gridEntityVariant = gridEntity.GetVariant();
341
- const gridEntityDesc = gridEntity.GetSaveState();
342
-
343
- // If a filter was specified, exclude all entities outside of the filter.
344
- if (
345
- gridEntityTypeFilter !== undefined &&
346
- gridEntityType !== gridEntityTypeFilter
347
- ) {
348
- return;
349
- }
398
+ }
350
399
 
351
- if (
352
- !includeWalls &&
353
- gridEntityType === GridEntityType.WALL &&
354
- gridEntityTypeFilter !== GridEntityType.WALL
355
- ) {
356
- return;
357
- }
400
+ /** Helper function for log information about a specific grid entity. */
401
+ export function logGridEntity(this: void, gridEntity: GridEntity): void {
402
+ const msg = getGridEntityLogLine(gridEntity);
403
+ log(msg);
404
+ }
358
405
 
359
- msg += `${gridEntityIndex}) ${gridEntityType}.${gridEntityVariant}.${gridEntity.State}`;
406
+ function getGridEntityLogLine(gridEntity: GridEntity, num?: int): string {
407
+ const gridEntityDesc = gridEntity.GetSaveState();
360
408
 
361
- const door = gridEntity.ToDoor();
362
- if (door !== undefined) {
363
- msg += " (door)";
364
- }
409
+ let msg = num === undefined ? "" : `${num}) `;
365
410
 
366
- const pit = gridEntity.ToPit();
367
- if (pit !== undefined) {
368
- msg += " (pit)";
369
- }
411
+ msg += getGridEntityID(gridEntity);
370
412
 
371
- const poop = gridEntity.ToPoop();
372
- if (poop !== undefined) {
373
- msg += " (poop)";
374
- }
413
+ const door = gridEntity.ToDoor();
414
+ if (door !== undefined) {
415
+ msg += " (door)";
416
+ }
375
417
 
376
- const pressurePlate = gridEntity.ToPressurePlate();
377
- if (pressurePlate !== undefined) {
378
- msg += " (pressurePlate)";
379
- }
418
+ const pit = gridEntity.ToPit();
419
+ if (pit !== undefined) {
420
+ msg += " (pit)";
421
+ }
380
422
 
381
- const rock = gridEntity.ToRock();
382
- if (rock !== undefined) {
383
- msg += " (rock)";
384
- }
423
+ const poop = gridEntity.ToPoop();
424
+ if (poop !== undefined) {
425
+ msg += " (poop)";
426
+ }
385
427
 
386
- const spikes = gridEntity.ToSpikes();
387
- if (spikes !== undefined) {
388
- msg += " (spikes)";
389
- }
428
+ const pressurePlate = gridEntity.ToPressurePlate();
429
+ if (pressurePlate !== undefined) {
430
+ msg += " (pressurePlate)";
431
+ }
390
432
 
391
- const tnt = gridEntity.ToTNT();
392
- if (tnt !== undefined) {
393
- msg += " (TNT)";
394
- }
433
+ const rock = gridEntity.ToRock();
434
+ if (rock !== undefined) {
435
+ msg += " (rock)";
436
+ }
395
437
 
396
- msg += ` - VarData: ${gridEntity.VarData}\n`;
397
- msg += ` - Position: (${gridEntity.Position.X}, ${gridEntity.Position.Y})\n`;
398
- msg += ` - SpawnSeed: ${gridEntityDesc.SpawnSeed}\n`;
399
- msg += ` - VariableSeed: ${gridEntityDesc.VariableSeed})\n`;
400
- if (door !== undefined) {
401
- msg += ` - Slot: ${door.Slot}\n`;
402
- msg += ` - Direction: ${door.Direction}\n`;
403
- msg += ` - TargetRoomIndex: ${door.TargetRoomIndex}\n`;
404
- msg += ` - TargetRoomType: ${door.TargetRoomType}\n`;
405
- }
438
+ const spikes = gridEntity.ToSpikes();
439
+ if (spikes !== undefined) {
440
+ msg += " (spikes)";
441
+ }
406
442
 
407
- numMatchedEntities++;
408
- });
443
+ const tnt = gridEntity.ToTNT();
444
+ if (tnt !== undefined) {
445
+ msg += " (TNT)";
446
+ }
409
447
 
410
- if (numMatchedEntities === 0) {
411
- msg += "(no grid entities matched)\n";
412
- } else {
413
- msg += `(${numMatchedEntities} total grid ${
414
- numMatchedEntities === 1 ? "entity" : "entities"
415
- })\n`;
448
+ msg += ` - State: ${gridEntity.State}\n`;
449
+ msg += ` - VarData: ${gridEntity.VarData}\n`;
450
+ msg += ` - Position: (${gridEntity.Position.X}, ${gridEntity.Position.Y})\n`;
451
+ msg += ` - SpawnSeed: ${gridEntityDesc.SpawnSeed}\n`;
452
+ msg += ` - VariableSeed: ${gridEntityDesc.VariableSeed})\n`;
453
+ if (door !== undefined) {
454
+ msg += ` - Slot: ${door.Slot}\n`;
455
+ msg += ` - Direction: ${door.Direction}\n`;
456
+ msg += ` - TargetRoomIndex: ${door.TargetRoomIndex}\n`;
457
+ msg += ` - TargetRoomType: ${door.TargetRoomType}\n`;
416
458
  }
417
459
 
418
- log(msg);
460
+ return msg;
419
461
  }
420
462
 
421
463
  export function logKColor(this: void, kColor: KColor): void {
@@ -616,7 +658,8 @@ export function logTable(
616
658
  // Put it in an IIFE so that the it will show as "func" instead of "logTable" and align with the
617
659
  // other text.
618
660
  (() => {
619
- log(`${indentation}The size of the table was: ${luaTable.length()}`);
661
+ const { length } = Object.keys(luaTable);
662
+ log(`${indentation}The size of the table was: ${length}`);
620
663
  })();
621
664
  }
622
665
 
@@ -626,8 +669,8 @@ export function logTable(
626
669
  */
627
670
  export function logTableDifferences<K, V>(
628
671
  this: void,
629
- table1: LuaTable<K, V>,
630
- table2: LuaTable<K, V>,
672
+ table1: LuaMap<K, V>,
673
+ table2: LuaMap<K, V>,
631
674
  ): void {
632
675
  log("Comparing two Lua tables:");
633
676
 
@@ -683,7 +726,7 @@ export function logUserdata(this: void, userdata: unknown): void {
683
726
  }
684
727
 
685
728
  const metatable = getmetatable(userdata) as
686
- | LuaTable<AnyNotNil, unknown>
729
+ | LuaMap<AnyNotNil, unknown>
687
730
  | undefined;
688
731
  if (metatable === undefined) {
689
732
  log("Userdata: [no metatable]");
@@ -714,17 +757,21 @@ export function setLogFunctionsGlobal(): void {
714
757
  const globals = _G as Record<string, unknown>;
715
758
 
716
759
  globals["log"] = log;
760
+ globals["logAllEntities"] = logAllEntities;
761
+ globals["logAllGridEntities"] = logAllGridEntities;
717
762
  globals["logArray"] = logArray;
718
763
  globals["logColor"] = logColor;
719
764
  globals["logDamageFlags"] = logDamageFlags;
720
765
  globals["logEffects"] = logEffects;
721
766
  globals["logEntities"] = logEntities;
767
+ globals["logEntity"] = logEntity;
722
768
  globals["logEntityID"] = logEntityID;
723
769
  globals["logEntityFlags"] = logEntityFlags;
724
770
  globals["logError"] = logError;
725
771
  globals["logFlags"] = logFlags;
726
772
  globals["logGameStateFlags"] = logGameStateFlags;
727
773
  globals["logGridEntities"] = logGridEntities;
774
+ globals["logGridEntity"] = logGridEntity;
728
775
  globals["logKColor"] = logKColor;
729
776
  globals["logLevelStateFlags"] = logLevelStateFlags;
730
777
  globals["logMap"] = logMap;
@@ -8,8 +8,8 @@ import { isSerializedIsaacAPIClass } from "./serialization";
8
8
  import { copyVector, isVector } from "./vector";
9
9
 
10
10
  /**
11
- * Run the suite of tests that prove that the "merge" helper function works properly. (This function
12
- * is not exported but is used internally in the save data manager.)
11
+ * Run the suite of tests that prove that the "merge" function works properly. (This function is not
12
+ * exported but is used internally in the save data manager.)
13
13
  *
14
14
  * This function is only useful if you are troubleshooting the save data manager.
15
15
  */
@@ -37,10 +37,10 @@ function oldTableHasUpdatedValue() {
37
37
  const newValue = "baz";
38
38
  const oldTable = {
39
39
  foo: oldValue,
40
- } as unknown as LuaTable<AnyNotNil, unknown>;
40
+ } as unknown as LuaMap<AnyNotNil, unknown>;
41
41
  const newTable = {
42
42
  foo: newValue,
43
- } as unknown as LuaTable<AnyNotNil, unknown>;
43
+ } as unknown as LuaMap<AnyNotNil, unknown>;
44
44
 
45
45
  merge(oldTable, newTable, "oldTableHasUpdatedValue");
46
46
 
@@ -56,10 +56,10 @@ function newTableHasSameValue() {
56
56
  const newValue = "baz";
57
57
  const oldTable = {
58
58
  foo: oldValue,
59
- } as unknown as LuaTable<AnyNotNil, unknown>;
59
+ } as unknown as LuaMap<AnyNotNil, unknown>;
60
60
  const newTable = {
61
61
  foo: newValue,
62
- } as unknown as LuaTable<AnyNotNil, unknown>;
62
+ } as unknown as LuaMap<AnyNotNil, unknown>;
63
63
 
64
64
  merge(oldTable, newTable, "newTableHasSameValue");
65
65
 
@@ -74,10 +74,10 @@ function oldTableHasUpdatedValueFromNull() {
74
74
  const newValue = "baz";
75
75
  const oldTable = {
76
76
  foo: null as string | null,
77
- } as unknown as LuaTable<AnyNotNil, unknown>;
77
+ } as unknown as LuaMap<AnyNotNil, unknown>;
78
78
  const newTable = {
79
79
  foo: newValue,
80
- } as unknown as LuaTable<AnyNotNil, unknown>;
80
+ } as unknown as LuaMap<AnyNotNil, unknown>;
81
81
 
82
82
  merge(oldTable, newTable, "oldTableHasUpdatedValueFromNull");
83
83
 
@@ -109,13 +109,13 @@ function oldTableHasFilledChildTable() {
109
109
  const newValue = "baz";
110
110
  const oldTable = {
111
111
  foo: null as Foo | null,
112
- } as unknown as LuaTable<AnyNotNil, unknown>;
112
+ } as unknown as LuaMap<AnyNotNil, unknown>;
113
113
  const foo: Foo = {
114
114
  bar: newValue,
115
115
  };
116
116
  const newTable = {
117
117
  foo,
118
- } as unknown as LuaTable<AnyNotNil, unknown>;
118
+ } as unknown as LuaMap<AnyNotNil, unknown>;
119
119
 
120
120
  merge(oldTable, newTable, "oldTableHasFilledChildTable");
121
121
 
@@ -148,8 +148,8 @@ function oldTableHasFilledMap() {
148
148
  const serializedSaveData = deepCopy(saveData, SerializationType.SERIALIZE);
149
149
 
150
150
  merge(
151
- v as unknown as LuaTable,
152
- serializedSaveData as LuaTable,
151
+ v as unknown as LuaMap,
152
+ serializedSaveData as LuaMap,
153
153
  "oldTableHasFilledMap",
154
154
  );
155
155
 
@@ -216,8 +216,8 @@ function oldTableHasFilledDefaultMap() {
216
216
  const serializedSaveData = deepCopy(saveData, SerializationType.SERIALIZE);
217
217
 
218
218
  merge(
219
- v as unknown as LuaTable,
220
- serializedSaveData as LuaTable,
219
+ v as unknown as LuaMap,
220
+ serializedSaveData as LuaMap,
221
221
  "oldTableHasFilledDefaultMap",
222
222
  );
223
223
 
@@ -278,13 +278,13 @@ function oldTableHasVector() {
278
278
  const newValue = Vector(x, y);
279
279
  const oldTable = {
280
280
  foo: null as Foo | null,
281
- } as unknown as LuaTable<AnyNotNil, unknown>;
281
+ } as unknown as LuaMap<AnyNotNil, unknown>;
282
282
  const foo: Foo = {
283
283
  bar: newValue,
284
284
  };
285
285
  const newTable = {
286
286
  foo,
287
- } as unknown as LuaTable<AnyNotNil, unknown>;
287
+ } as unknown as LuaMap<AnyNotNil, unknown>;
288
288
 
289
289
  merge(oldTable, newTable, "oldTableHasVector");
290
290
 
@@ -319,18 +319,18 @@ function oldTableHasVectorSerialized() {
319
319
  const newValue = Vector(x, y);
320
320
  const oldTable = {
321
321
  foo: null as Foo | null,
322
- } as unknown as LuaTable<AnyNotNil, unknown>;
322
+ } as unknown as LuaMap<AnyNotNil, unknown>;
323
323
  const foo: Foo = {
324
324
  bar: newValue,
325
325
  };
326
326
  const newTable = {
327
327
  foo,
328
- } as unknown as LuaTable<AnyNotNil, unknown>;
328
+ } as unknown as LuaMap<AnyNotNil, unknown>;
329
329
  const newTableSerialized = deepCopy(
330
330
  newTable,
331
331
  SerializationType.SERIALIZE,
332
332
  "oldTableHasVectorSerialized",
333
- ) as LuaTable<AnyNotNil, unknown>;
333
+ ) as LuaMap<AnyNotNil, unknown>;
334
334
 
335
335
  merge(oldTable, newTableSerialized, "oldTableHasVectorSerialized");
336
336
 
@@ -366,13 +366,13 @@ function oldTableHasRNG() {
366
366
  const newValue = newRNG(seed);
367
367
  const oldTable = {
368
368
  foo: null as Foo | null,
369
- } as unknown as LuaTable<AnyNotNil, unknown>;
369
+ } as unknown as LuaMap<AnyNotNil, unknown>;
370
370
  const foo: Foo = {
371
371
  bar: newValue,
372
372
  };
373
373
  const newTable = {
374
374
  foo,
375
- } as unknown as LuaTable<AnyNotNil, unknown>;
375
+ } as unknown as LuaMap<AnyNotNil, unknown>;
376
376
 
377
377
  merge(oldTable, newTable, "oldTableHasRNG");
378
378
 
@@ -403,18 +403,18 @@ function oldTableHasRNGSerialized() {
403
403
  const newValue = newRNG(seed);
404
404
  const oldTable = {
405
405
  foo: null as Foo | null,
406
- } as unknown as LuaTable<AnyNotNil, unknown>;
406
+ } as unknown as LuaMap<AnyNotNil, unknown>;
407
407
  const foo: Foo = {
408
408
  bar: newValue,
409
409
  };
410
410
  const newTable = {
411
411
  foo,
412
- } as unknown as LuaTable<AnyNotNil, unknown>;
412
+ } as unknown as LuaMap<AnyNotNil, unknown>;
413
413
  const newTableSerialized = deepCopy(
414
414
  newTable,
415
415
  SerializationType.SERIALIZE,
416
416
  "oldTableHasRNGSerialized",
417
- ) as LuaTable<AnyNotNil, unknown>;
417
+ ) as LuaMap<AnyNotNil, unknown>;
418
418
 
419
419
  merge(oldTable, newTableSerialized, "oldTableHasRNGSerialized");
420
420