isaacscript-common 13.1.1 → 13.3.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 (59) hide show
  1. package/dist/index.d.ts +47 -3
  2. package/dist/isaacscript-common.lua +11781 -11710
  3. package/dist/src/callbacks/customRevive.d.ts.map +1 -1
  4. package/dist/src/callbacks/customRevive.lua +2 -1
  5. package/dist/src/callbacks/postNewRoomEarly.lua +2 -2
  6. package/dist/src/classes/ModUpgraded.d.ts +5 -2
  7. package/dist/src/classes/ModUpgraded.d.ts.map +1 -1
  8. package/dist/src/classes/ModUpgraded.lua +39 -3
  9. package/dist/src/core/upgradeMod.d.ts +6 -1
  10. package/dist/src/core/upgradeMod.d.ts.map +1 -1
  11. package/dist/src/core/upgradeMod.lua +9 -2
  12. package/dist/src/features/customStage/exports.lua +2 -2
  13. package/dist/src/features/deployJSONRoom.d.ts +21 -0
  14. package/dist/src/features/deployJSONRoom.d.ts.map +1 -1
  15. package/dist/src/features/deployJSONRoom.lua +33 -9
  16. package/dist/src/features/extraConsoleCommands/listCommands.lua +5 -5
  17. package/dist/src/features/pause.lua +2 -2
  18. package/dist/src/features/saveDataManager/load.d.ts.map +1 -1
  19. package/dist/src/features/saveDataManager/load.lua +2 -1
  20. package/dist/src/features/saveDataManager/main.lua +2 -2
  21. package/dist/src/features/taintedLazarusPlayers.lua +2 -2
  22. package/dist/src/functions/benchmark.d.ts +12 -0
  23. package/dist/src/functions/benchmark.d.ts.map +1 -1
  24. package/dist/src/functions/benchmark.lua +19 -0
  25. package/dist/src/functions/debugFunctions.d.ts +1 -0
  26. package/dist/src/functions/debugFunctions.d.ts.map +1 -1
  27. package/dist/src/functions/debugFunctions.lua +15 -23
  28. package/dist/src/functions/globals.lua +1 -1
  29. package/dist/src/functions/hex.lua +2 -2
  30. package/dist/src/functions/jsonHelpers.lua +2 -2
  31. package/dist/src/functions/log.d.ts +0 -68
  32. package/dist/src/functions/log.d.ts.map +1 -1
  33. package/dist/src/functions/log.lua +3 -496
  34. package/dist/src/functions/logMisc.d.ts +69 -0
  35. package/dist/src/functions/logMisc.d.ts.map +1 -0
  36. package/dist/src/functions/logMisc.lua +498 -0
  37. package/dist/src/index.d.ts +1 -0
  38. package/dist/src/index.d.ts.map +1 -1
  39. package/dist/src/index.lua +8 -0
  40. package/package.json +2 -2
  41. package/src/callbacks/customRevive.ts +2 -1
  42. package/src/callbacks/postNewRoomEarly.ts +1 -1
  43. package/src/classes/ModUpgraded.ts +43 -4
  44. package/src/core/upgradeMod.ts +10 -2
  45. package/src/features/customStage/exports.ts +1 -1
  46. package/src/features/deployJSONRoom.ts +28 -16
  47. package/src/features/extraConsoleCommands/listCommands.ts +1 -1
  48. package/src/features/pause.ts +1 -1
  49. package/src/features/saveDataManager/load.ts +2 -1
  50. package/src/features/saveDataManager/main.ts +1 -1
  51. package/src/features/taintedLazarusPlayers.ts +1 -1
  52. package/src/functions/benchmark.ts +23 -0
  53. package/src/functions/debugFunctions.ts +15 -25
  54. package/src/functions/globals.ts +1 -1
  55. package/src/functions/hex.ts +1 -1
  56. package/src/functions/jsonHelpers.ts +1 -1
  57. package/src/functions/log.ts +5 -443
  58. package/src/functions/logMisc.ts +441 -0
  59. package/src/index.ts +1 -0
@@ -36,6 +36,7 @@ import {
36
36
  getGridEntities,
37
37
  removeGridEntity,
38
38
  setGridEntityInvisible,
39
+ spawnGridEntity,
39
40
  spawnGridEntityWithVariant,
40
41
  } from "../functions/gridEntities";
41
42
  import { getRandomJSONEntity, getRandomJSONRoom } from "../functions/jsonRoom";
@@ -145,6 +146,11 @@ function preUseItemWeNeedToGoDeeper(
145
146
  return;
146
147
  }
147
148
 
149
+ const futureRoomListIndex = getRoomListIndex();
150
+ if (futureRoomListIndex !== roomListIndex) {
151
+ return;
152
+ }
153
+
148
154
  v.room.manuallyUsingShovel = true;
149
155
  futurePlayer.UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER);
150
156
  v.room.manuallyUsingShovel = false;
@@ -152,7 +158,7 @@ function preUseItemWeNeedToGoDeeper(
152
158
  const decorationGridIndexes =
153
159
  v.level.roomToDecorationGridIndexesMap.getAndSetDefault(roomListIndex);
154
160
  emptyArray(decorationGridIndexes);
155
- fillRoomWithDecorations();
161
+ preventGridEntityRespawn();
156
162
  });
157
163
 
158
164
  // Cancel the original effect.
@@ -273,7 +279,7 @@ export function deployJSONRoom(
273
279
  }
274
280
 
275
281
  fixPitGraphics();
276
- fillRoomWithDecorations();
282
+ preventGridEntityRespawn();
277
283
  }
278
284
 
279
285
  /**
@@ -328,27 +334,35 @@ export function deployRandomJSONRoom(
328
334
  }
329
335
 
330
336
  /**
331
- * We removed most normal entities, which should prevent them from respawning when the player
332
- * re-enters the room. However, this is not the case for grid entities; even if they are removed,
333
- * they will come back when the player re-enters the room.
337
+ * Helper function to prevent any removed grid entities from respawning if the player re-enters the
338
+ * room.
334
339
  *
335
- * In order to prevent this from happening, we can spawn a grid entity on every tile that does not
336
- * already have a grid entity. The natural grid entity to choose for this purpose is a decoration,
337
- * since it is non-interacting.
340
+ * This is accomplished by spawning a new grid entity on every tile that does not already have a
341
+ * grid entity. This will force the game to spawn the new grid entity instead of the old one. The
342
+ * natural grid entity to choose for this purpose is a decoration, since it is non-interacting.
343
+ * Then, the decorations are made invisible and any shovel uses are intercepted to avoid creating a
344
+ * crawl space (instead of a trapdoor).
338
345
  *
339
346
  * Another option besides decorations would be to use a pressure plates with a state of 1, which is
340
347
  * a state that is normally unused by the game and makes it invisible & persistent. However, pickups
341
348
  * will not be able to spawn on pressure plates, which lead to various bugs (e.g. pickups spawning
342
- * on top of pits). Thus, we use a decoration and remove its sprite to make it invisible.
349
+ * on top of pits). Thus, using a decoration is preferable.
343
350
  *
344
- * Yet another option is to replace the room data with that of an empty room. However, the room data
345
- * must exactly match the room type, the room shape, and the doors, so this is not possible to do in
346
- * a robust way without adding empty rooms to the mod's `content` folder to draw the data from.
351
+ * Yet another option to accomplish this would be to replace the room data with that of an empty
352
+ * room. However, the room data must exactly match the room type, the room shape, and the doors, so
353
+ * this is not possible to do in a robust way without adding empty rooms to the mod's `content`
354
+ * folder to draw the data from.
347
355
  */
348
- function fillRoomWithDecorations() {
356
+ export function preventGridEntityRespawn(): void {
357
+ errorIfFeaturesNotInitialized(FEATURE_NAME);
358
+
349
359
  const room = game.GetRoom();
350
360
  const roomListIndex = getRoomListIndex();
351
361
 
362
+ // Ensure that this room is in the deployed room set, or else the shovel interception code will
363
+ // not work properly.
364
+ v.level.deployedRoomListIndexes.add(roomListIndex);
365
+
352
366
  const decorationGridIndexes =
353
367
  v.level.roomToDecorationGridIndexesMap.getAndSetDefault(roomListIndex);
354
368
 
@@ -358,9 +372,7 @@ function fillRoomWithDecorations() {
358
372
  continue;
359
373
  }
360
374
 
361
- const position = room.GetGridPosition(gridIndex);
362
- const decoration = Isaac.GridSpawn(GridEntityType.DECORATION, 0, position);
363
-
375
+ const decoration = spawnGridEntity(GridEntityType.DECORATION, gridIndex);
364
376
  if (decoration !== undefined) {
365
377
  setGridEntityInvisible(decoration);
366
378
  }
@@ -83,7 +83,7 @@ import {
83
83
  logRoom,
84
84
  logSeedEffects,
85
85
  logSounds,
86
- } from "../../functions/log";
86
+ } from "../../functions/logMisc";
87
87
  import { getMapPartialMatch } from "../../functions/map";
88
88
  import { runMergeTests } from "../../functions/mergeTests";
89
89
  import {
@@ -12,7 +12,7 @@ import {
12
12
  removeAllTears,
13
13
  } from "../functions/entitiesSpecific";
14
14
  import { isTear } from "../functions/isaacAPIClass";
15
- import { logError } from "../functions/log";
15
+ import { logError } from "../functions/logMisc";
16
16
  import { getAllPlayers } from "../functions/playerIndex";
17
17
  import { useActiveItemTemp } from "../functions/players";
18
18
  import { disableAllInputsExceptFor, enableAllInputs } from "./disableInputs";
@@ -1,5 +1,6 @@
1
1
  import { jsonDecode } from "../../functions/jsonHelpers";
2
- import { log, logError } from "../../functions/log";
2
+ import { log } from "../../functions/log";
3
+ import { logError } from "../../functions/logMisc";
3
4
  import { iterateTableInOrder } from "../../functions/table";
4
5
  import { isString, isTable } from "../../functions/types";
5
6
  import { SaveData } from "../../interfaces/SaveData";
@@ -5,7 +5,7 @@ import { ModCallbackCustom } from "../../enums/ModCallbackCustom";
5
5
  import { SaveDataKey } from "../../enums/SaveDataKey";
6
6
  import { SerializationType } from "../../enums/SerializationType";
7
7
  import { deepCopy } from "../../functions/deepCopy";
8
- import { logError } from "../../functions/log";
8
+ import { logError } from "../../functions/logMisc";
9
9
  import { onFirstFloor } from "../../functions/stage";
10
10
  import { clearTable, iterateTableInOrder } from "../../functions/table";
11
11
  import { SaveData } from "../../interfaces/SaveData";
@@ -4,7 +4,7 @@
4
4
  import { ModCallback, PlayerType } from "isaac-typescript-definitions";
5
5
  import { ModUpgraded } from "../classes/ModUpgraded";
6
6
  import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
7
- import { logError } from "../functions/log";
7
+ import { logError } from "../functions/logMisc";
8
8
  import { saveDataManager } from "./saveDataManager/exports";
9
9
 
10
10
  const FEATURE_NAME = "taintedLazarusPlayers";
@@ -1,3 +1,4 @@
1
+ import { SECOND_IN_MILLISECONDS } from "../core/constants";
1
2
  import { log } from "./log";
2
3
 
3
4
  /**
@@ -39,3 +40,25 @@ export function benchmark(
39
40
 
40
41
  return averages;
41
42
  }
43
+
44
+ /**
45
+ * Helper function to get the current time in seconds for benchmarking / profiling purposes.
46
+ *
47
+ * - If the "--luadebug" flag is enabled, then this function will use the `socket.gettime` method,
48
+ * which returns the epoch timestamp in seconds (e.g. "1640320492.5779"). This is preferable over
49
+ * the `Isaac.GetTime` method, since it has one extra decimal point of precision.
50
+ * - If the "--luadebug" flag is disabled, then this function will use the `Isaac.GetTime` method,
51
+ * which returns the number of seconds since the computer's operating system was started (e.g.
52
+ * "739454.963"). (The milliseconds return value of `Isaac.GetTime` is converted to seconds to
53
+ * align with the return value of `socket.gettime`.)
54
+ */
55
+ export function getTime(): float {
56
+ const [ok, requiredSocket] = pcall(require, "socket");
57
+ if (ok) {
58
+ const socket = requiredSocket as Socket;
59
+ return socket.gettime();
60
+ }
61
+
62
+ // The "--luadebug" launch option is not enabled.
63
+ return Isaac.GetTime() / SECOND_IN_MILLISECONDS;
64
+ }
@@ -6,6 +6,7 @@ import { saveDataManagerSetGlobal } from "../features/saveDataManager/exports";
6
6
  import * as logExports from "./log";
7
7
  import { log } from "./log";
8
8
  import * as logEntitiesExports from "./logEntities";
9
+ import * as logMiscExports from "./logMisc";
9
10
 
10
11
  /**
11
12
  * Helper function to enable some IsaacScript features that are useful when developing a mod. They
@@ -27,6 +28,7 @@ import * as logEntitiesExports from "./logEntities";
27
28
  export function enableDevFeatures(mod: ModUpgraded): void {
28
29
  saveDataManagerSetGlobal();
29
30
  setLogFunctionsGlobal();
31
+ setTracebackFunctionsGlobal();
30
32
  enableExtraConsoleCommands(mod);
31
33
  enableFastReset();
32
34
  removeFadeIn();
@@ -45,8 +47,8 @@ export function getTraceback(): string {
45
47
  return debug.traceback();
46
48
  }
47
49
 
48
- if (sandboxGetTraceback !== undefined) {
49
- return sandboxGetTraceback();
50
+ if (SandboxGetTraceback !== undefined) {
51
+ return SandboxGetTraceback();
50
52
  }
51
53
 
52
54
  return 'stack traceback:\n(the "--luadebug" flag is not enabled)';
@@ -81,13 +83,19 @@ export function isLuaDebugEnabled(): boolean {
81
83
  export function setLogFunctionsGlobal(): void {
82
84
  const globals = _G as Record<string, unknown>;
83
85
 
84
- for (const [logFuncName, logFunc] of Object.entries(logExports)) {
85
- globals[logFuncName] = logFunc;
86
+ for (const exports of [logExports, logMiscExports, logEntitiesExports]) {
87
+ // eslint-disable-next-line isaacscript/no-object-any
88
+ for (const [logFuncName, logFunc] of Object.entries(exports)) {
89
+ globals[logFuncName] = logFunc;
90
+ }
86
91
  }
92
+ }
87
93
 
88
- for (const [logFuncName, logFunc] of Object.entries(logEntitiesExports)) {
89
- globals[logFuncName] = logFunc;
90
- }
94
+ export function setTracebackFunctionsGlobal(): void {
95
+ const globals = _G as Record<string, unknown>;
96
+
97
+ globals["getTraceback"] = getTraceback;
98
+ globals["traceback"] = traceback;
91
99
  }
92
100
 
93
101
  /**
@@ -101,21 +109,3 @@ export function traceback(): void {
101
109
  const tracebackOutput = getTraceback();
102
110
  log(tracebackOutput);
103
111
  }
104
-
105
- // If the debug functions will provide useful output, make them global by default.
106
- if (isLuaDebugEnabled() || sandboxGetTraceback !== undefined) {
107
- setDebugFunctionsGlobal();
108
- }
109
-
110
- function setDebugFunctionsGlobal() {
111
- // "debug" is not always defined like the Lua definitions imply.
112
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
113
- if (_G.debug === undefined && sandboxGetTraceback === undefined) {
114
- return;
115
- }
116
-
117
- const globals = _G as Record<string, unknown>;
118
-
119
- globals["getTraceback"] = getTraceback;
120
- globals["traceback"] = traceback;
121
- }
@@ -205,7 +205,7 @@ export function getDefaultGlobals(): ReadonlySet<string> {
205
205
  }
206
206
 
207
207
  function isRacingPlusSandboxEnabled() {
208
- return getParentFunctionDescription !== undefined;
208
+ return SandboxGetParentFunctionDescription !== undefined;
209
209
  }
210
210
 
211
211
  /**
@@ -1,4 +1,4 @@
1
- import { logError } from "./log";
1
+ import { logError } from "./logMisc";
2
2
 
3
3
  const HEX_STRING_LENGTH = 6;
4
4
 
@@ -1,5 +1,5 @@
1
1
  import * as jsonLua from "../lib/jsonLua";
2
- import { logError } from "./log";
2
+ import { logError } from "./logMisc";
3
3
 
4
4
  function tryDecode(this: void, jsonString: string) {
5
5
  return jsonLua.decode(jsonString) as LuaMap<AnyNotNil, unknown>;