isaacscript-common 6.22.3 → 7.0.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 (83) hide show
  1. package/dist/classes/DefaultMap.d.ts +3 -3
  2. package/dist/classes/DefaultMap.d.ts.map +1 -1
  3. package/dist/classes/DefaultMap.lua +37 -0
  4. package/dist/features/customStage/exports.lua +2 -2
  5. package/dist/features/disableInputs.d.ts +1 -1
  6. package/dist/features/disableInputs.d.ts.map +1 -1
  7. package/dist/features/runInNFrames.lua +1 -6
  8. package/dist/features/runNextRoom.lua +1 -6
  9. package/dist/features/saveDataManager/exports.d.ts +13 -8
  10. package/dist/features/saveDataManager/exports.d.ts.map +1 -1
  11. package/dist/features/saveDataManager/exports.lua +12 -7
  12. package/dist/features/saveDataManager/maps.d.ts +2 -2
  13. package/dist/features/saveDataManager/maps.d.ts.map +1 -1
  14. package/dist/features/taintedLazarusPlayers.lua +1 -6
  15. package/dist/functions/deepCopy.lua +1 -1
  16. package/dist/functions/isaacAPIClass.d.ts +1 -1
  17. package/dist/functions/isaacAPIClass.d.ts.map +1 -1
  18. package/dist/functions/level.lua +2 -2
  19. package/dist/functions/levelGrid.d.ts +3 -1
  20. package/dist/functions/levelGrid.d.ts.map +1 -1
  21. package/dist/functions/levelGrid.lua +15 -10
  22. package/dist/functions/minimap.lua +3 -3
  23. package/dist/functions/rooms.d.ts +1 -1
  24. package/dist/functions/rooms.d.ts.map +1 -1
  25. package/dist/functions/rooms.lua +4 -4
  26. package/dist/interfaces/SaveData.d.ts +43 -4
  27. package/dist/interfaces/SaveData.d.ts.map +1 -1
  28. package/dist/interfaces/SaveData.lua +66 -0
  29. package/dist/types/index.d.ts +0 -1
  30. package/dist/types/index.d.ts.map +1 -1
  31. package/package.json +2 -2
  32. package/src/classes/DefaultMap.ts +36 -7
  33. package/src/features/customStage/exports.ts +2 -2
  34. package/src/features/disableInputs.ts +3 -9
  35. package/src/features/runInNFrames.ts +1 -1
  36. package/src/features/runNextRoom.ts +1 -1
  37. package/src/features/saveDataManager/exports.ts +28 -10
  38. package/src/features/saveDataManager/save.ts +2 -1
  39. package/src/features/taintedLazarusPlayers.ts +2 -2
  40. package/src/functions/deepCopy.ts +1 -1
  41. package/src/functions/entities.ts +2 -2
  42. package/src/functions/isaacAPIClass.ts +0 -1
  43. package/src/functions/level.ts +2 -2
  44. package/src/functions/levelGrid.ts +16 -12
  45. package/src/functions/minimap.ts +3 -3
  46. package/src/functions/rooms.ts +4 -4
  47. package/src/interfaces/SaveData.ts +257 -5
  48. package/src/types/index.ts +0 -1
  49. package/src/types/indexTypeDoc.ts +0 -1
  50. package/dist/classes/indexTypeDoc.d.ts +0 -3
  51. package/dist/classes/indexTypeDoc.d.ts.map +0 -1
  52. package/dist/classes/indexTypeDoc.lua +0 -4
  53. package/dist/core/indexTypeDoc.d.ts +0 -5
  54. package/dist/core/indexTypeDoc.d.ts.map +0 -1
  55. package/dist/core/indexTypeDoc.lua +0 -6
  56. package/dist/enums/indexTypeDoc.d.ts +0 -9
  57. package/dist/enums/indexTypeDoc.d.ts.map +0 -1
  58. package/dist/enums/indexTypeDoc.lua +0 -10
  59. package/dist/features/indexTypeDoc.d.ts +0 -30
  60. package/dist/features/indexTypeDoc.d.ts.map +0 -1
  61. package/dist/features/indexTypeDoc.lua +0 -31
  62. package/dist/functions/indexTypeDoc.d.ts +0 -99
  63. package/dist/functions/indexTypeDoc.d.ts.map +0 -1
  64. package/dist/functions/indexTypeDoc.lua +0 -100
  65. package/dist/indexTypeDoc.d.ts +0 -10
  66. package/dist/indexTypeDoc.d.ts.map +0 -1
  67. package/dist/indexTypeDoc.lua +0 -11
  68. package/dist/interfaces/indexTypeDoc.d.ts +0 -11
  69. package/dist/interfaces/indexTypeDoc.d.ts.map +0 -1
  70. package/dist/interfaces/indexTypeDoc.lua +0 -2
  71. package/dist/maps/indexTypeDoc.d.ts +0 -5
  72. package/dist/maps/indexTypeDoc.d.ts.map +0 -1
  73. package/dist/maps/indexTypeDoc.lua +0 -6
  74. package/dist/objects/indexTypeDoc.d.ts +0 -2
  75. package/dist/objects/indexTypeDoc.d.ts.map +0 -1
  76. package/dist/objects/indexTypeDoc.lua +0 -3
  77. package/dist/types/IsaacAPIClass.d.ts +0 -5
  78. package/dist/types/IsaacAPIClass.d.ts.map +0 -1
  79. package/dist/types/IsaacAPIClass.lua +0 -2
  80. package/dist/types/indexTypeDoc.d.ts +0 -12
  81. package/dist/types/indexTypeDoc.d.ts.map +0 -1
  82. package/dist/types/indexTypeDoc.lua +0 -3
  83. package/src/types/IsaacAPIClass.ts +0 -3
@@ -1,2 +1,68 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Map = ____lualib.Map
3
+ local __TS__New = ____lualib.__TS__New
4
+ local __TS__Class = ____lualib.__TS__Class
1
5
  local ____exports = {}
6
+ local function test(self, _saveData)
7
+ end
8
+ do
9
+ local saveDataWithPrimitives = {run = {foo = 123, bar = "bar", baz = true, nested = {foo = 123, bar = "bar", baz = true}}}
10
+ test(nil, saveDataWithPrimitives)
11
+ end
12
+ do
13
+ local saveDataWithEntity = {run = {foo = {}}}
14
+ test(nil, saveDataWithEntity)
15
+ end
16
+ do
17
+ local saveDataWithMap = {run = {foo = __TS__New(Map)}}
18
+ test(nil, saveDataWithMap)
19
+ end
20
+ do
21
+ local saveDataWithMap = {run = {foo = __TS__New(Map)}}
22
+ test(nil, saveDataWithMap)
23
+ end
24
+ do
25
+ local saveDataWithMap = {run = {foo = __TS__New(Map)}}
26
+ test(nil, saveDataWithMap)
27
+ end
28
+ do
29
+ local Foo = __TS__Class()
30
+ Foo.name = "Foo"
31
+ function Foo.prototype.____constructor(self)
32
+ self.someField = 123
33
+ end
34
+ local saveDataWithClass = {run = {foo = __TS__New(Foo)}}
35
+ test(nil, saveDataWithClass)
36
+ end
37
+ do
38
+ local Foo = __TS__Class()
39
+ Foo.name = "Foo"
40
+ function Foo.prototype.____constructor(self)
41
+ self.someField = 123
42
+ end
43
+ function Foo.prototype.someMethod(self)
44
+ end
45
+ local saveDataWithClassWithMethod = {run = {foo = __TS__New(Foo)}}
46
+ test(nil, saveDataWithClassWithMethod)
47
+ end
48
+ do
49
+ local Foo = __TS__Class()
50
+ Foo.name = "Foo"
51
+ function Foo.prototype.____constructor(self)
52
+ self.someField = 123
53
+ end
54
+ local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
55
+ test(nil, saveDataWithNestedClass)
56
+ end
57
+ do
58
+ local Foo = __TS__Class()
59
+ Foo.name = "Foo"
60
+ function Foo.prototype.____constructor(self)
61
+ self.someField = 123
62
+ end
63
+ function Foo.prototype.someMethod(self)
64
+ end
65
+ local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
66
+ test(nil, saveDataWithNestedClass)
67
+ end
2
68
  return ____exports
@@ -2,7 +2,6 @@ export * from "./AnyEntity";
2
2
  export * from "./AnyGridEntity";
3
3
  export * from "./CollectibleIndex";
4
4
  export * from "./Immutable";
5
- export * from "./IsaacAPIClass";
6
5
  export * from "./PickingUpItem";
7
6
  export * from "./PickupIndex";
8
7
  export * from "./PlayerIndex";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "6.22.3",
3
+ "version": "7.0.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -22,6 +22,6 @@
22
22
  "main": "dist/index",
23
23
  "types": "dist/index.d.ts",
24
24
  "dependencies": {
25
- "isaac-typescript-definitions": "^3.1.4"
25
+ "isaac-typescript-definitions": "^3.2.1"
26
26
  }
27
27
  }
@@ -5,9 +5,7 @@ import { isFunction, isPrimitive } from "../functions/types";
5
5
  * A function that creates the default value for your `DefaultMap`. For example, if it was a
6
6
  * `DefaultMap` containing maps, the factory function would be: `() => new Map()`
7
7
  */
8
- export type FactoryFunction<V, Args extends unknown[]> = (
9
- ...extraArgs: Args
10
- ) => V;
8
+ export type FactoryFunction<V, Args extends unknown[]> = (...args: Args) => V;
11
9
 
12
10
  /**
13
11
  * `DefaultMap` is a data structure that makes working with default values easier.
@@ -127,13 +125,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
127
125
  * If the key exists, this will return the same thing as the normal `Map.get` method. Otherwise,
128
126
  * it will set a default value for the provided key, and then return the default value.
129
127
  */
130
- getAndSetDefault(key: Key, ...extraArgs: Args): Value {
128
+ getAndSetDefault(key: Key, ...args: Args): Value {
131
129
  const value = super.get(key);
132
130
  if (value !== undefined) {
133
131
  return value;
134
132
  }
135
133
 
136
- const defaultValue = this.getDefaultValue(...extraArgs);
134
+ const defaultValue = this.getDefaultValue(...args);
137
135
  this.set(key, defaultValue);
138
136
  return defaultValue;
139
137
  }
@@ -142,13 +140,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
142
140
  * Returns the default value to be used for a new key. (If a factory function was provided during
143
141
  * instantiation, this will execute the factory function.)
144
142
  */
145
- getDefaultValue(...extraArgs: Args): Value {
143
+ getDefaultValue(...args: Args): Value {
146
144
  if (this.defaultValue !== undefined) {
147
145
  return this.defaultValue;
148
146
  }
149
147
 
150
148
  if (this.defaultValueFactory !== undefined) {
151
- return this.defaultValueFactory(...extraArgs);
149
+ return this.defaultValueFactory(...args);
152
150
  }
153
151
 
154
152
  error("A DefaultMap was incorrectly instantiated.");
@@ -170,3 +168,34 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
170
168
  error("A DefaultMap was incorrectly instantiated.");
171
169
  }
172
170
  }
171
+
172
+ /* eslint-disable @typescript-eslint/no-unused-vars */
173
+ function test() {
174
+ // Boolean
175
+ const myDefaultMapBoolean = new DefaultMap<string, boolean>(false);
176
+ const myDefaultMapBooleanFactory = new DefaultMap<string, boolean>(
177
+ () => false,
178
+ );
179
+ const myDefaultMapBooleanWithoutParams = new DefaultMap(false);
180
+
181
+ // Number
182
+ const myDefaultMapNumber = new DefaultMap<string, number>(123);
183
+ const myDefaultMapNumberFactory = new DefaultMap<string, number>(() => 123);
184
+ const myDefaultMapNumberWithoutParams = new DefaultMap(123);
185
+
186
+ // String
187
+ const myDefaultMapString = new DefaultMap<string, string>("foo");
188
+ const myDefaultMapStringFactory = new DefaultMap<string, string>(() => "foo");
189
+ const myDefaultMapStringWithoutParams = new DefaultMap("foo");
190
+
191
+ // Array
192
+ const myDefaultMapArray = new DefaultMap<string, string[]>(() => []);
193
+ const myDefaultMapArrayWithoutParams = new DefaultMap(() => []);
194
+
195
+ // Map
196
+ const myDefaultMapMap = new DefaultMap<string, Map<string, string>>(
197
+ () => new Map(),
198
+ );
199
+ const myDefaultMapMapWithoutParams = new DefaultMap(() => new Map());
200
+ }
201
+ /* eslint-enable @typescript-eslint/no-unused-vars */
@@ -21,7 +21,7 @@ import { logError } from "../../functions/log";
21
21
  import { newRNG } from "../../functions/rng";
22
22
  import {
23
23
  getRoomDataForTypeVariant,
24
- getRoomsInGrid,
24
+ getRoomsInsideGrid,
25
25
  } from "../../functions/rooms";
26
26
  import { setStage } from "../../functions/stage";
27
27
  import { CustomStage } from "../../interfaces/private/CustomStage";
@@ -121,7 +121,7 @@ function setStageRoomsData(
121
121
  const level = game.GetLevel();
122
122
  const startingRoomGridIndex = level.GetStartingRoomIndex();
123
123
 
124
- for (const room of getRoomsInGrid()) {
124
+ for (const room of getRoomsInsideGrid()) {
125
125
  // The starting floor of each room should stay empty.
126
126
  if (room.SafeGridIndex === startingRoomGridIndex) {
127
127
  continue;
@@ -12,16 +12,10 @@ const FEATURE_NAME = "disableInputs";
12
12
  const v = {
13
13
  run: {
14
14
  /** Indexed by the requesting feature key. */
15
- disableInputsWithWhitelistMap: new Map<
16
- string,
17
- Set<ButtonAction> | ReadonlySet<ButtonAction>
18
- >(),
15
+ disableInputsWithWhitelistMap: new Map<string, ReadonlySet<ButtonAction>>(),
19
16
 
20
17
  /** Indexed by the requesting feature key. */
21
- enableInputsWithBlacklistMap: new Map<
22
- string,
23
- Set<ButtonAction> | ReadonlySet<ButtonAction>
24
- >(),
18
+ enableInputsWithBlacklistMap: new Map<string, ReadonlySet<ButtonAction>>(),
25
19
  },
26
20
  };
27
21
 
@@ -154,7 +148,7 @@ export function enableAllInputsExceptFor(
154
148
  */
155
149
  export function disableAllInputsExceptFor(
156
150
  key: string,
157
- whitelist: Set<ButtonAction>,
151
+ whitelist: Set<ButtonAction> | ReadonlySet<ButtonAction>,
158
152
  ): void {
159
153
  errorIfFeaturesNotInitialized(FEATURE_NAME);
160
154
 
@@ -31,7 +31,7 @@ const v = {
31
31
  };
32
32
 
33
33
  export function runInNFramesInit(mod: Mod): void {
34
- saveDataManager(FEATURE_NAME, v, () => false); // Functions are not serializable.
34
+ saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
35
35
 
36
36
  mod.AddCallback(ModCallback.POST_UPDATE, postUpdate); // 1
37
37
  mod.AddCallback(ModCallback.POST_RENDER, postRender); // 2
@@ -13,7 +13,7 @@ const v = {
13
13
  };
14
14
 
15
15
  export function runNextRoomInit(mod: ModUpgraded): void {
16
- saveDataManager(FEATURE_NAME, v, () => false); // Functions are not serializable.
16
+ saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
17
17
 
18
18
  mod.AddCallbackCustom(
19
19
  ModCallbackCustom.POST_NEW_ROOM_REORDERED,
@@ -96,18 +96,30 @@ import { SAVE_DATA_MANAGER_FEATURE_NAME } from "./saveDataManagerConstants";
96
96
  * manager. The save data manager will throw an error if the key is already registered.
97
97
  * @param v An object that corresponds to the `SaveData` interface. The object is conventionally
98
98
  * called "v" for brevity. ("v" is short for "local variables").
99
- * @param conditionalFunc An optional function to run upon saving this key to disk. For example,
100
- * this allows features to only save data to disk if the feature is enabled.
101
- * Specify a value of `() => false` to completely disable saving this feature
102
- * to disk. Disabling saving to disk is useful if you are using data that is
103
- * not serializable. Alternatively, it could be useful if you want to use the
104
- * save data manager to automatically reset variables on run/level/room, but
105
- * not clutter the the "save#.dat" file with unnecessary keys.
99
+ * @param conditionalFunc Optional. A function to run to check if this save data should be written
100
+ * to disk. Default is `() => true`, meaning that this save data will always
101
+ * be written to disk. Use a conditional function for the situations when the
102
+ * local variables are for a feature that the end-user can disable. (If the
103
+ * feature is disabled, then there would be no point in writing any of the
104
+ * variables to the "save#.dat" file.) You can also specify `false` to this
105
+ * argument in order to completely disable saving data. (Specifying `false`
106
+ * will allow you to use non-serializable objects in your save data, such as
107
+ * `EntityPtr`.
106
108
  */
109
+ export function saveDataManager<Persistent, Run, Level>(
110
+ key: string, // This is the overload for the standard case with serializable data.
111
+ v: SaveData<Persistent, Run, Level>,
112
+ conditionalFunc?: () => boolean,
113
+ ): void;
107
114
  export function saveDataManager(
108
- key: string,
115
+ key: string, // This is the overload for the case when saving data is disabled.
109
116
  v: SaveData,
110
- conditionalFunc?: () => boolean,
117
+ conditionalFunc: false,
118
+ ): void;
119
+ export function saveDataManager<Persistent, Run, Level>(
120
+ key: string,
121
+ v: SaveData<Persistent, Run, Level>,
122
+ conditionalFunc?: (() => boolean) | false,
111
123
  ): void {
112
124
  errorIfFeaturesNotInitialized(SAVE_DATA_MANAGER_FEATURE_NAME);
113
125
 
@@ -126,6 +138,12 @@ export function saveDataManager(
126
138
  // Add the new save data to the map.
127
139
  saveDataMap.set(key, v);
128
140
 
141
+ // Convert the boolean to a function, if necessary. (Having the argument be a boolean is necessary
142
+ // in order for the overloads to work properly.)
143
+ if (conditionalFunc === false) {
144
+ conditionalFunc = () => false;
145
+ }
146
+
129
147
  // If the only key in the save data is "room", then we don't have to worry about saving this data
130
148
  // to disk (because the room would be reloaded upon resuming a continued run).
131
149
  const saveDataKeys = Object.keys(v);
@@ -135,7 +153,7 @@ export function saveDataManager(
135
153
 
136
154
  // Make a copy of the initial save data so that we can use it to restore the default values later
137
155
  // on.
138
- const saveDataCopy = deepCopy(v, SerializationType.NONE, key) as SaveData;
156
+ const saveDataCopy = deepCopy(v, SerializationType.NONE, key) as typeof v;
139
157
  saveDataDefaultsMap.set(key, saveDataCopy);
140
158
 
141
159
  // Store the conditional function for later, if present.
@@ -44,7 +44,8 @@ function getAllSaveDataToWriteToDisk(
44
44
  }
45
45
  }
46
46
 
47
- // Strip out the room part of the save data.
47
+ // Strip out the room part of the save data (and any other arbitrary fields that they might
48
+ // have added).
48
49
  const saveDataWithoutRoom: SaveData = {
49
50
  persistent: saveData.persistent,
50
51
  run: saveData.run,
@@ -31,10 +31,10 @@ const v = {
31
31
  };
32
32
 
33
33
  export function taintedLazarusPlayersInit(mod: ModUpgraded): void {
34
- // `EntityPtr` is not serializable, so we cannot save data. However, this is inconsequential,
34
+ // `EntityPtr` is not serializable, so we cannot save the data. However, this is inconsequential,
35
35
  // since the `POST_PLAYER_INIT` callback will fire when a run is continued, which will repopulate
36
36
  // the `subPlayerMap`.
37
- saveDataManager(FEATURE_NAME, v, () => false);
37
+ saveDataManager(FEATURE_NAME, v, false);
38
38
 
39
39
  mod.AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit);
40
40
  }
@@ -233,7 +233,7 @@ function deepCopyDefaultMap(
233
233
  // throw a run-time error to immediately alert the end-user that their data structure is
234
234
  // invalid.
235
235
  error(
236
- 'Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of another map. You cannot use a nested DefaultMap in this way because factory functions are not serializable. (In other words, there is no way to copy the function that you are using for the DefaultMap into the "save#.dat" file.) Instead, refactor your data structure so that the DefaultMap is not nested.',
236
+ "Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#failed-to-deep-copy-a-defaultmap",
237
237
  );
238
238
  } else {
239
239
  // In most cases, the DefaultMap will be attached to a normal table element. In this case, if
@@ -187,9 +187,9 @@ function setPrimitiveEntityFields(
187
187
  const indexKey = key as keyof typeof entity;
188
188
  const value = entity[indexKey];
189
189
  if (isPrimitive(value)) {
190
- entityFields.set(indexKey, value);
190
+ entityFields.set(indexKey as string, value);
191
191
  } else if (isVector(value)) {
192
- entityFields.set(indexKey, vectorToString(value));
192
+ entityFields.set(indexKey as string, vectorToString(value));
193
193
  }
194
194
  }
195
195
  }
@@ -1,4 +1,3 @@
1
- import { IsaacAPIClass } from "../types/IsaacAPIClass";
2
1
  import { trimPrefix } from "./string";
3
2
  import { isString, isUserdata } from "./types";
4
3
 
@@ -2,14 +2,14 @@ import { DoorSlot } from "isaac-typescript-definitions";
2
2
  import { game } from "../core/cachedClasses";
3
3
  import { getEnumValues } from "./enums";
4
4
  import { isDoorSlotValidAtGridIndexForRedRoom } from "./levelGrid";
5
- import { getNumRooms, getRoomsInGrid } from "./rooms";
5
+ import { getNumRooms, getRoomsInsideGrid } from "./rooms";
6
6
 
7
7
  export function fillLevelWithRedRooms(): void {
8
8
  const level = game.GetLevel();
9
9
 
10
10
  let numRoomsInGrid: int;
11
11
  do {
12
- const roomsInGrid = getRoomsInGrid();
12
+ const roomsInGrid = getRoomsInsideGrid();
13
13
  numRoomsInGrid = roomsInGrid.length;
14
14
 
15
15
  for (const roomDescriptor of roomsInGrid) {
@@ -35,7 +35,7 @@ import {
35
35
  getRoomGridIndex,
36
36
  getRoomShape,
37
37
  } from "./roomData";
38
- import { getRooms, getRoomsInGrid } from "./rooms";
38
+ import { getRooms, getRoomsInsideGrid } from "./rooms";
39
39
  import { getGridIndexDelta } from "./roomShape";
40
40
 
41
41
  const LEFT = -1;
@@ -63,7 +63,7 @@ export function getAdjacentRoomGridIndexes(roomGridIndex?: int): int[] {
63
63
  const roomGridIndexToUse =
64
64
  roomGridIndex === undefined ? getRoomGridIndex() : roomGridIndex;
65
65
 
66
- if (!isRoomGridIndexInBounds(roomGridIndexToUse)) {
66
+ if (!isRoomInsideGrid(roomGridIndexToUse)) {
67
67
  return [];
68
68
  }
69
69
 
@@ -72,7 +72,7 @@ export function getAdjacentRoomGridIndexes(roomGridIndex?: int): int[] {
72
72
  );
73
73
 
74
74
  return adjacentRoomGridIndexes.filter((adjacentRoomGridIndex) =>
75
- isRoomGridIndexInBounds(adjacentRoomGridIndex),
75
+ isRoomInsideGrid(adjacentRoomGridIndex),
76
76
  );
77
77
  }
78
78
 
@@ -117,7 +117,7 @@ export function getNewRoomCandidatesBesideRoom(
117
117
  ): Array<[doorSlot: DoorSlot, roomGridIndex: int]> {
118
118
  const roomDescriptor = getRoomDescriptor(roomGridIndex);
119
119
 
120
- if (!isRoomGridIndexInBounds(roomDescriptor.SafeGridIndex)) {
120
+ if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
121
121
  return [];
122
122
  }
123
123
 
@@ -172,7 +172,7 @@ export function getNewRoomCandidatesBesideRoom(
172
172
  export function getNewRoomCandidatesForLevel(): Array<
173
173
  [adjacentRoomGridIndex: int, doorSlot: DoorSlot, newRoomGridIndex: int]
174
174
  > {
175
- const rooms = getRoomsInGrid();
175
+ const rooms = getRoomsInsideGrid();
176
176
  const normalRooms = rooms.filter(
177
177
  (room) =>
178
178
  room.Data !== undefined &&
@@ -207,7 +207,7 @@ export function getNewRoomCandidatesForLevel(): Array<
207
207
  export function getRoomGridIndexesForType(...roomTypes: RoomType[]): int[] {
208
208
  const roomTypesSet = new Set<RoomType>([...roomTypes]);
209
209
 
210
- const rooms = getRoomsInGrid();
210
+ const rooms = getRoomsInsideGrid();
211
211
  const matchingRooms = rooms.filter(
212
212
  (roomDescriptor) =>
213
213
  roomDescriptor.Data !== undefined &&
@@ -230,7 +230,7 @@ export function getRoomGridIndexesForType(...roomTypes: RoomType[]): int[] {
230
230
  export function getRoomNeighbors(roomGridIndex?: int): Map<DoorSlot, int> {
231
231
  const roomDescriptor = getRoomDescriptor(roomGridIndex);
232
232
 
233
- if (!isRoomGridIndexInBounds(roomDescriptor.SafeGridIndex)) {
233
+ if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
234
234
  return new Map();
235
235
  }
236
236
 
@@ -293,7 +293,7 @@ export function getRoomShapeNeighborGridIndexes(
293
293
  const neighborGridIndexes = new Map<DoorSlot, int>();
294
294
  for (const [doorSlot, delta] of roomShapeNeighborGridIndexDeltas.entries()) {
295
295
  const roomGridIndex = safeRoomGridIndex + delta;
296
- if (isRoomGridIndexInBounds(roomGridIndex)) {
296
+ if (isRoomInsideGrid(roomGridIndex)) {
297
297
  neighborGridIndexes.set(doorSlot, roomGridIndex);
298
298
  }
299
299
  }
@@ -356,9 +356,7 @@ export function isDoorSlotValidAtGridIndexForRedRoom(
356
356
  }
357
357
 
358
358
  const redRoomGridIndex = roomGridIndex + delta;
359
- return (
360
- !roomExists(redRoomGridIndex) && isRoomGridIndexInBounds(redRoomGridIndex)
361
- );
359
+ return !roomExists(redRoomGridIndex) && isRoomInsideGrid(redRoomGridIndex);
362
360
  }
363
361
 
364
362
  /**
@@ -376,8 +374,14 @@ export function isRedKeyRoom(roomGridIndex?: int): boolean {
376
374
  * Helper function to determine if a given room grid index is inside of the normal 13x13 level grid.
377
375
  *
378
376
  * For example, Devil Rooms and the Mega Satan room are not considered to be inside the grid.
377
+ *
378
+ * @param roomGridIndex Optional. Default is the current room index.
379
379
  */
380
- export function isRoomGridIndexInBounds(roomGridIndex: int): boolean {
380
+ export function isRoomInsideGrid(roomGridIndex?: int): boolean {
381
+ if (roomGridIndex === undefined) {
382
+ roomGridIndex = getRoomGridIndex();
383
+ }
384
+
381
385
  return roomGridIndex >= 0 && roomGridIndex <= MAX_LEVEL_GRID_INDEX;
382
386
  }
383
387
 
@@ -1,7 +1,7 @@
1
1
  import { DisplayFlag, DisplayFlagZero } from "isaac-typescript-definitions";
2
2
  import { game } from "../core/cachedClasses";
3
3
  import { getRoomDescriptor } from "./roomData";
4
- import { getRoomsInGrid } from "./rooms";
4
+ import { getRoomsInsideGrid } from "./rooms";
5
5
 
6
6
  /**
7
7
  * Helper function to set the value of `DisplayFlag` for every room on the floor to 0.
@@ -12,7 +12,7 @@ import { getRoomsInGrid } from "./rooms";
12
12
  export function clearFloorDisplayFlags(): void {
13
13
  const level = game.GetLevel();
14
14
 
15
- for (const room of getRoomsInGrid()) {
15
+ for (const room of getRoomsInsideGrid()) {
16
16
  room.DisplayFlags = DisplayFlagZero;
17
17
  }
18
18
 
@@ -27,7 +27,7 @@ export function clearFloorDisplayFlags(): void {
27
27
  export function getFloorDisplayFlags(): Map<int, BitFlags<DisplayFlag>> {
28
28
  const displayFlagsMap = new Map<int, BitFlags<DisplayFlag>>();
29
29
 
30
- const roomsInGrid = getRoomsInGrid();
30
+ const roomsInGrid = getRoomsInsideGrid();
31
31
  for (const roomDescriptor of roomsInGrid) {
32
32
  displayFlagsMap.set(
33
33
  roomDescriptor.SafeGridIndex,
@@ -74,7 +74,7 @@ export function changeRoom(roomGridIndex: int): void {
74
74
  * include off-grid rooms, like the Devil Room.
75
75
  */
76
76
  export function getNumRooms(): int {
77
- const rooms = getRoomsInGrid();
77
+ const rooms = getRoomsInsideGrid();
78
78
  return rooms.length;
79
79
  }
80
80
 
@@ -186,7 +186,7 @@ export function getRooms(
186
186
  // The obvious way to get all of the rooms would be to iterate over the `RoomList` from the
187
187
  // `Level.GetRooms` method. However, this results in read-only data, and we want to return a
188
188
  // writable object. Instead, we let the heavy lifting be handled by other functions.
189
- const roomsInGrid = getRoomsInGrid(includeExtraDimensionalRooms);
189
+ const roomsInGrid = getRoomsInsideGrid(includeExtraDimensionalRooms);
190
190
  const roomsOutsideGrid = getRoomsOutsideGrid();
191
191
  return [...roomsInGrid, ...roomsOutsideGrid];
192
192
  }
@@ -201,7 +201,7 @@ export function getRooms(
201
201
  * extra-dimensional rooms are automatically be generated. Default
202
202
  * is false.
203
203
  */
204
- export function getRoomsInGrid(
204
+ export function getRoomsInsideGrid(
205
205
  includeExtraDimensionalRooms = false,
206
206
  ): RoomDescriptor[] {
207
207
  const level = game.GetLevel();
@@ -463,7 +463,7 @@ export function inStartingRoom(): boolean {
463
463
  export function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolean {
464
464
  const roomTypeWhitelist =
465
465
  onlyCheckRoomTypes === undefined ? null : new Set(onlyCheckRoomTypes);
466
- const rooms = getRoomsInGrid();
466
+ const rooms = getRoomsInsideGrid();
467
467
  const matchingRooms =
468
468
  roomTypeWhitelist === null
469
469
  ? rooms