isaacscript-common 13.1.1 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -9468,6 +9468,28 @@ export declare function preventChildEntities(entity: Entity): void;
9468
9468
  */
9469
9469
  export declare function preventCollectibleRotation(collectible: EntityPickup, collectibleType: CollectibleType): void;
9470
9470
 
9471
+ /**
9472
+ * Helper function to prevent any removed grid entities from respawning if the player re-enters the
9473
+ * room.
9474
+ *
9475
+ * This is accomplished by spawning a new grid entity on every tile that does not already have a
9476
+ * grid entity. This will force the game to spawn the new grid entity instead of the old one. The
9477
+ * natural grid entity to choose for this purpose is a decoration, since it is non-interacting.
9478
+ * Then, the decorations are made invisible and any shovel uses are intercepted to avoid creating a
9479
+ * crawl space (instead of a trapdoor).
9480
+ *
9481
+ * Another option besides decorations would be to use a pressure plates with a state of 1, which is
9482
+ * a state that is normally unused by the game and makes it invisible & persistent. However, pickups
9483
+ * will not be able to spawn on pressure plates, which lead to various bugs (e.g. pickups spawning
9484
+ * on top of pits). Thus, using a decoration is preferable.
9485
+ *
9486
+ * Yet another option to accomplish this would be to replace the room data with that of an empty
9487
+ * room. However, the room data must exactly match the room type, the room shape, and the doors, so
9488
+ * this is not possible to do in a robust way without adding empty rooms to the mod's `content`
9489
+ * folder to draw the data from.
9490
+ */
9491
+ export declare function preventGridEntityRespawn(): void;
9492
+
9471
9493
  /**
9472
9494
  * Helper function to print something to the in-game console. Use this instead of invoking the
9473
9495
  * `Isaac.ConsoleOutput` method directly because it will automatically insert a newline at the end
@@ -1,6 +1,6 @@
1
1
  --[[
2
2
 
3
- isaacscript-common 13.1.1
3
+ isaacscript-common 13.2.0
4
4
 
5
5
  This is the "isaacscript-common" library, which was created with the IsaacScript tool.
6
6
 
@@ -41734,7 +41734,7 @@ local __TS__New = ____lualib.__TS__New
41734
41734
  local Map = ____lualib.Map
41735
41735
  local __TS__Iterator = ____lualib.__TS__Iterator
41736
41736
  local ____exports = {}
41737
- local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
41737
+ local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
41738
41738
  local ____isaac_2Dtypescript_2Ddefinitions = require("lua_modules.isaac-typescript-definitions.dist.src.index")
41739
41739
  local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
41740
41740
  local EntityCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityCollisionClass
@@ -41770,6 +41770,7 @@ local getAllGridIndexes = ____gridEntities.getAllGridIndexes
41770
41770
  local getGridEntities = ____gridEntities.getGridEntities
41771
41771
  local removeGridEntity = ____gridEntities.removeGridEntity
41772
41772
  local setGridEntityInvisible = ____gridEntities.setGridEntityInvisible
41773
+ local spawnGridEntity = ____gridEntities.spawnGridEntity
41773
41774
  local spawnGridEntityWithVariant = ____gridEntities.spawnGridEntityWithVariant
41774
41775
  local ____jsonRoom = require("src.functions.jsonRoom")
41775
41776
  local getRandomJSONEntity = ____jsonRoom.getRandomJSONEntity
@@ -41820,12 +41821,16 @@ function preUseItemWeNeedToGoDeeper(self, _collectibleType, _rng, player, _useFl
41820
41821
  if futurePlayer == nil then
41821
41822
  return
41822
41823
  end
41824
+ local futureRoomListIndex = getRoomListIndex(nil)
41825
+ if futureRoomListIndex ~= roomListIndex then
41826
+ return
41827
+ end
41823
41828
  v.room.manuallyUsingShovel = true
41824
41829
  futurePlayer:UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER)
41825
41830
  v.room.manuallyUsingShovel = false
41826
41831
  local decorationGridIndexes = v.level.roomToDecorationGridIndexesMap:getAndSetDefault(roomListIndex)
41827
41832
  emptyArray(nil, decorationGridIndexes)
41828
- fillRoomWithDecorations(nil)
41833
+ ____exports.preventGridEntityRespawn(nil)
41829
41834
  end
41830
41835
  )
41831
41836
  return true
@@ -41867,24 +41872,25 @@ function respawnPersistentEntities(self)
41867
41872
  )
41868
41873
  end
41869
41874
  end
41870
- function fillRoomWithDecorations(self)
41875
+ function ____exports.preventGridEntityRespawn(self)
41876
+ errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
41871
41877
  local room = game:GetRoom()
41872
41878
  local roomListIndex = getRoomListIndex(nil)
41879
+ v.level.deployedRoomListIndexes:add(roomListIndex)
41873
41880
  local decorationGridIndexes = v.level.roomToDecorationGridIndexesMap:getAndSetDefault(roomListIndex)
41874
41881
  for ____, gridIndex in ipairs(getAllGridIndexes(nil)) do
41875
41882
  do
41876
41883
  local existingGridEntity = room:GetGridEntity(gridIndex)
41877
41884
  if existingGridEntity ~= nil then
41878
- goto __continue31
41885
+ goto __continue32
41879
41886
  end
41880
- local position = room:GetGridPosition(gridIndex)
41881
- local decoration = Isaac.GridSpawn(GridEntityType.DECORATION, 0, position)
41887
+ local decoration = spawnGridEntity(nil, GridEntityType.DECORATION, gridIndex)
41882
41888
  if decoration ~= nil then
41883
41889
  setGridEntityInvisible(nil, decoration)
41884
41890
  end
41885
41891
  decorationGridIndexes[#decorationGridIndexes + 1] = gridIndex
41886
41892
  end
41887
- ::__continue31::
41893
+ ::__continue32::
41888
41894
  end
41889
41895
  end
41890
41896
  function spawnAllEntities(self, jsonRoom, rng, verbose)
@@ -42141,7 +42147,7 @@ function getPitFrame(self, L, R, U, D, UL, UR, DL, DR)
42141
42147
  end
42142
42148
  return F
42143
42149
  end
42144
- local FEATURE_NAME = "deployJSONRoom"
42150
+ FEATURE_NAME = "deployJSONRoom"
42145
42151
  PERSISTENT_ENTITY_TYPES = __TS__New(Set, {EntityType.WALL_HUGGER})
42146
42152
  local gridEntityXMLTypes = getEnumValues(nil, GridEntityXMLType)
42147
42153
  GRID_ENTITY_XML_TYPE_SET = __TS__New(Set, gridEntityXMLTypes)
@@ -42191,7 +42197,7 @@ function ____exports.deployJSONRoom(self, jsonRoom, seedOrRNG, verbose)
42191
42197
  log(nil, "Finished spawning all of the new entities and grid entities.")
42192
42198
  end
42193
42199
  fixPitGraphics(nil)
42194
- fillRoomWithDecorations(nil)
42200
+ ____exports.preventGridEntityRespawn(nil)
42195
42201
  end
42196
42202
  function ____exports.deployRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
42197
42203
  if seedOrRNG == nil then
@@ -63,4 +63,25 @@ export declare function deployJSONRoom(jsonRoom: JSONRoom | Readonly<JSONRoom>,
63
63
  * what the function is doing. Default is false.
64
64
  */
65
65
  export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
66
+ /**
67
+ * Helper function to prevent any removed grid entities from respawning if the player re-enters the
68
+ * room.
69
+ *
70
+ * This is accomplished by spawning a new grid entity on every tile that does not already have a
71
+ * grid entity. This will force the game to spawn the new grid entity instead of the old one. The
72
+ * natural grid entity to choose for this purpose is a decoration, since it is non-interacting.
73
+ * Then, the decorations are made invisible and any shovel uses are intercepted to avoid creating a
74
+ * crawl space (instead of a trapdoor).
75
+ *
76
+ * Another option besides decorations would be to use a pressure plates with a state of 1, which is
77
+ * a state that is normally unused by the game and makes it invisible & persistent. However, pickups
78
+ * will not be able to spawn on pressure plates, which lead to various bugs (e.g. pickups spawning
79
+ * on top of pits). Thus, using a decoration is preferable.
80
+ *
81
+ * Yet another option to accomplish this would be to replace the room data with that of an empty
82
+ * room. However, the room data must exactly match the room type, the room shape, and the doors, so
83
+ * this is not possible to do in a robust way without adding empty rooms to the mod's `content`
84
+ * folder to draw the data from.
85
+ */
86
+ export declare function preventGridEntityRespawn(): void;
66
87
  //# sourceMappingURL=deployJSONRoom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deployJSONRoom.d.ts","sourceRoot":"","sources":["../../../src/features/deployJSONRoom.ts"],"names":[],"mappings":";;AAgDA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAwKvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,EACvC,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CA4BN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAaN"}
1
+ {"version":3,"file":"deployJSONRoom.d.ts","sourceRoot":"","sources":["../../../src/features/deployJSONRoom.ts"],"names":[],"mappings":";;AAiDA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AA6KvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,EACvC,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CA4BN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAaN;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA0B/C"}
@@ -4,7 +4,7 @@ local __TS__New = ____lualib.__TS__New
4
4
  local Map = ____lualib.Map
5
5
  local __TS__Iterator = ____lualib.__TS__Iterator
6
6
  local ____exports = {}
7
- local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
7
+ local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
8
8
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
9
9
  local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
10
10
  local EntityCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityCollisionClass
@@ -40,6 +40,7 @@ local getAllGridIndexes = ____gridEntities.getAllGridIndexes
40
40
  local getGridEntities = ____gridEntities.getGridEntities
41
41
  local removeGridEntity = ____gridEntities.removeGridEntity
42
42
  local setGridEntityInvisible = ____gridEntities.setGridEntityInvisible
43
+ local spawnGridEntity = ____gridEntities.spawnGridEntity
43
44
  local spawnGridEntityWithVariant = ____gridEntities.spawnGridEntityWithVariant
44
45
  local ____jsonRoom = require("src.functions.jsonRoom")
45
46
  local getRandomJSONEntity = ____jsonRoom.getRandomJSONEntity
@@ -90,12 +91,16 @@ function preUseItemWeNeedToGoDeeper(self, _collectibleType, _rng, player, _useFl
90
91
  if futurePlayer == nil then
91
92
  return
92
93
  end
94
+ local futureRoomListIndex = getRoomListIndex(nil)
95
+ if futureRoomListIndex ~= roomListIndex then
96
+ return
97
+ end
93
98
  v.room.manuallyUsingShovel = true
94
99
  futurePlayer:UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER)
95
100
  v.room.manuallyUsingShovel = false
96
101
  local decorationGridIndexes = v.level.roomToDecorationGridIndexesMap:getAndSetDefault(roomListIndex)
97
102
  emptyArray(nil, decorationGridIndexes)
98
- fillRoomWithDecorations(nil)
103
+ ____exports.preventGridEntityRespawn(nil)
99
104
  end
100
105
  )
101
106
  return true
@@ -137,24 +142,43 @@ function respawnPersistentEntities(self)
137
142
  )
138
143
  end
139
144
  end
140
- function fillRoomWithDecorations(self)
145
+ --- Helper function to prevent any removed grid entities from respawning if the player re-enters the
146
+ -- room.
147
+ --
148
+ -- This is accomplished by spawning a new grid entity on every tile that does not already have a
149
+ -- grid entity. This will force the game to spawn the new grid entity instead of the old one. The
150
+ -- natural grid entity to choose for this purpose is a decoration, since it is non-interacting.
151
+ -- Then, the decorations are made invisible and any shovel uses are intercepted to avoid creating a
152
+ -- crawl space (instead of a trapdoor).
153
+ --
154
+ -- Another option besides decorations would be to use a pressure plates with a state of 1, which is
155
+ -- a state that is normally unused by the game and makes it invisible & persistent. However, pickups
156
+ -- will not be able to spawn on pressure plates, which lead to various bugs (e.g. pickups spawning
157
+ -- on top of pits). Thus, using a decoration is preferable.
158
+ --
159
+ -- Yet another option to accomplish this would be to replace the room data with that of an empty
160
+ -- room. However, the room data must exactly match the room type, the room shape, and the doors, so
161
+ -- this is not possible to do in a robust way without adding empty rooms to the mod's `content`
162
+ -- folder to draw the data from.
163
+ function ____exports.preventGridEntityRespawn(self)
164
+ errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
141
165
  local room = game:GetRoom()
142
166
  local roomListIndex = getRoomListIndex(nil)
167
+ v.level.deployedRoomListIndexes:add(roomListIndex)
143
168
  local decorationGridIndexes = v.level.roomToDecorationGridIndexesMap:getAndSetDefault(roomListIndex)
144
169
  for ____, gridIndex in ipairs(getAllGridIndexes(nil)) do
145
170
  do
146
171
  local existingGridEntity = room:GetGridEntity(gridIndex)
147
172
  if existingGridEntity ~= nil then
148
- goto __continue31
173
+ goto __continue32
149
174
  end
150
- local position = room:GetGridPosition(gridIndex)
151
- local decoration = Isaac.GridSpawn(GridEntityType.DECORATION, 0, position)
175
+ local decoration = spawnGridEntity(nil, GridEntityType.DECORATION, gridIndex)
152
176
  if decoration ~= nil then
153
177
  setGridEntityInvisible(nil, decoration)
154
178
  end
155
179
  decorationGridIndexes[#decorationGridIndexes + 1] = gridIndex
156
180
  end
157
- ::__continue31::
181
+ ::__continue32::
158
182
  end
159
183
  end
160
184
  function spawnAllEntities(self, jsonRoom, rng, verbose)
@@ -411,7 +435,7 @@ function getPitFrame(self, L, R, U, D, UL, UR, DL, DR)
411
435
  end
412
436
  return F
413
437
  end
414
- local FEATURE_NAME = "deployJSONRoom"
438
+ FEATURE_NAME = "deployJSONRoom"
415
439
  PERSISTENT_ENTITY_TYPES = __TS__New(Set, {EntityType.WALL_HUGGER})
416
440
  local gridEntityXMLTypes = getEnumValues(nil, GridEntityXMLType)
417
441
  GRID_ENTITY_XML_TYPE_SET = __TS__New(Set, gridEntityXMLTypes)
@@ -489,7 +513,7 @@ function ____exports.deployJSONRoom(self, jsonRoom, seedOrRNG, verbose)
489
513
  log(nil, "Finished spawning all of the new entities and grid entities.")
490
514
  end
491
515
  fixPitGraphics(nil)
492
- fillRoomWithDecorations(nil)
516
+ ____exports.preventGridEntityRespawn(nil)
493
517
  end
494
518
  --- Helper function to deconstruct a vanilla room and set up a custom room in its place.
495
519
  -- Specifically, this will clear the current room of all entities and grid entities, and then spawn
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "13.1.1",
3
+ "version": "13.2.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -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
  }