isaacscript-common 6.17.1 → 6.20.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 (56) hide show
  1. package/dist/features/customStage/exports.d.ts.map +1 -1
  2. package/dist/features/customStage/exports.lua +2 -7
  3. package/dist/features/customTrapdoor/init.d.ts.map +1 -1
  4. package/dist/features/customTrapdoor/init.lua +10 -2
  5. package/dist/features/extraConsoleCommands/commandsSubroutines.d.ts.map +1 -1
  6. package/dist/features/extraConsoleCommands/commandsSubroutines.lua +2 -1
  7. package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
  8. package/dist/features/extraConsoleCommands/listCommands.lua +2 -1
  9. package/dist/features/playerInventory.d.ts.map +1 -1
  10. package/dist/features/playerInventory.lua +2 -4
  11. package/dist/functions/curses.d.ts +3 -0
  12. package/dist/functions/curses.d.ts.map +1 -0
  13. package/dist/functions/curses.lua +11 -0
  14. package/dist/functions/dimensions.d.ts +12 -0
  15. package/dist/functions/dimensions.d.ts.map +1 -0
  16. package/dist/functions/dimensions.lua +35 -0
  17. package/dist/functions/eden.d.ts.map +1 -1
  18. package/dist/functions/eden.lua +2 -4
  19. package/dist/functions/itemPool.d.ts +8 -0
  20. package/dist/functions/itemPool.d.ts.map +1 -1
  21. package/dist/functions/itemPool.lua +53 -36
  22. package/dist/functions/level.d.ts.map +1 -1
  23. package/dist/functions/level.lua +8 -7
  24. package/dist/functions/levelGrid.d.ts +152 -0
  25. package/dist/functions/levelGrid.d.ts.map +1 -0
  26. package/dist/functions/levelGrid.lua +326 -0
  27. package/dist/functions/roomData.d.ts +5 -0
  28. package/dist/functions/roomData.d.ts.map +1 -1
  29. package/dist/functions/roomData.lua +6 -0
  30. package/dist/functions/roomGrid.d.ts +8 -0
  31. package/dist/functions/roomGrid.d.ts.map +1 -1
  32. package/dist/functions/rooms.d.ts +39 -61
  33. package/dist/functions/rooms.d.ts.map +1 -1
  34. package/dist/functions/rooms.lua +126 -200
  35. package/dist/functions/saveFile.d.ts +1 -1
  36. package/dist/functions/saveFile.lua +1 -1
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.lua +24 -0
  40. package/package.json +2 -2
  41. package/src/features/customStage/exports.ts +10 -11
  42. package/src/features/customTrapdoor/init.ts +7 -3
  43. package/src/features/extraConsoleCommands/commandsSubroutines.ts +2 -1
  44. package/src/features/extraConsoleCommands/listCommands.ts +2 -1
  45. package/src/features/playerInventory.ts +2 -3
  46. package/src/functions/curses.ts +9 -0
  47. package/src/functions/dimensions.ts +41 -0
  48. package/src/functions/eden.ts +2 -4
  49. package/src/functions/itemPool.ts +30 -5
  50. package/src/functions/level.ts +7 -10
  51. package/src/functions/levelGrid.ts +424 -0
  52. package/src/functions/roomData.ts +12 -0
  53. package/src/functions/roomGrid.ts +9 -0
  54. package/src/functions/rooms.ts +90 -206
  55. package/src/functions/saveFile.ts +1 -1
  56. package/src/index.ts +3 -0
@@ -10,6 +10,7 @@ import { StageTravelState } from "../../enums/private/StageTravelState";
10
10
  import { movePlayersToCenter } from "../../functions/playerCenter";
11
11
  import { getAllPlayers } from "../../functions/playerIndex";
12
12
  import { getRoomGridIndex, getRoomListIndex } from "../../functions/roomData";
13
+ import { teleport } from "../../functions/rooms";
13
14
  import { setStage } from "../../functions/stage";
14
15
  import { isString } from "../../functions/types";
15
16
  import { setCustomStage } from "../customStage/exports";
@@ -65,8 +66,10 @@ function checkAllPlayersJumpComplete() {
65
66
  v.run.stateRenderFrame = renderFrameCount;
66
67
 
67
68
  // In order to display the pixelation effect that should happen when we go to a new floor, we need
68
- // to start a room transition. We arbitrarily pick the current room for this purpose.
69
- game.StartRoomTransition(
69
+ // to start a room transition. We arbitrarily pick the current room for this purpose. (We do not
70
+ // have to worry about Curse of the Maze here, because even if we are taken to a different room,
71
+ // it will not matter, since we will be traveling to a new floor after the screen fades to black.)
72
+ teleport(
70
73
  roomGridIndex,
71
74
  Direction.NO_DIRECTION,
72
75
  RoomTransitionAnim.PIXELATION,
@@ -99,10 +102,11 @@ function checkPixelationToBlackComplete() {
99
102
 
100
103
  // Start another pixelation effect. This time, we will keep the screen black with the sprite, and
101
104
  // then remove the black sprite once the pixelation effect is halfway complete.
102
- game.StartRoomTransition(
105
+ teleport(
103
106
  roomGridIndex,
104
107
  Direction.NO_DIRECTION,
105
108
  RoomTransitionAnim.PIXELATION,
109
+ true,
106
110
  );
107
111
  }
108
112
 
@@ -9,10 +9,11 @@ import { game } from "../../cachedClasses";
9
9
  import { HealthType } from "../../enums/HealthType";
10
10
  import { directionToVector } from "../../functions/direction";
11
11
  import { spawnGridEntityWithVariant } from "../../functions/gridEntities";
12
+ import { getRoomGridIndexesForType } from "../../functions/levelGrid";
12
13
  import { logAllEntities, logAllGridEntities } from "../../functions/log";
13
14
  import { addPlayerHealthType } from "../../functions/playerHealth";
14
15
  import { getRoomData, getRoomDescriptor } from "../../functions/roomData";
15
- import { changeRoom, getRoomGridIndexesForType } from "../../functions/rooms";
16
+ import { changeRoom } from "../../functions/rooms";
16
17
  import { printConsole } from "../../functions/utils";
17
18
  import {
18
19
  DEFAULT_ROOM_TYPE_NAME,
@@ -63,6 +63,7 @@ import { getNPCs } from "../../functions/entitiesSpecific";
63
63
  import { getEnumValues } from "../../functions/enums";
64
64
  import { addFlag } from "../../functions/flag";
65
65
  import { spawnGridEntity } from "../../functions/gridEntities";
66
+ import { getRoomGridIndexesForType } from "../../functions/levelGrid";
66
67
  import {
67
68
  logPlayerEffects,
68
69
  logRoom,
@@ -85,7 +86,7 @@ import {
85
86
  useActiveItemTemp,
86
87
  } from "../../functions/players";
87
88
  import { gridCoordinatesToWorldPosition } from "../../functions/roomGrid";
88
- import { changeRoom, getRoomGridIndexesForType } from "../../functions/rooms";
89
+ import { changeRoom } from "../../functions/rooms";
89
90
  import { onSetSeed, restart, setUnseeded } from "../../functions/run";
90
91
  import { getGoldenTrinketType } from "../../functions/trinkets";
91
92
  import { irange, printConsole, printEnabled } from "../../functions/utils";
@@ -5,7 +5,7 @@ import { ModCallbackCustom } from "../enums/ModCallbackCustom";
5
5
  import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
6
6
  import { arrayRemoveInPlace, copyArray } from "../functions/array";
7
7
  import { isActiveCollectible } from "../functions/collectibles";
8
- import { getCollectibleSet } from "../functions/collectibleSet";
8
+ import { getCollectibleArray } from "../functions/collectibleSet";
9
9
  import {
10
10
  defaultMapGetPlayer,
11
11
  mapSetPlayer,
@@ -30,8 +30,7 @@ const v = {
30
30
  function newPlayerInventory(player: EntityPlayer) {
31
31
  const inventory: CollectibleType[] = [];
32
32
 
33
- const collectibleSet = getCollectibleSet();
34
- for (const collectibleType of collectibleSet.values()) {
33
+ for (const collectibleType of getCollectibleArray()) {
35
34
  const numCollectibles = player.GetCollectibleNum(collectibleType, true);
36
35
  repeat(numCollectibles, () => {
37
36
  inventory.push(collectibleType);
@@ -0,0 +1,9 @@
1
+ import { LevelCurse } from "isaac-typescript-definitions";
2
+ import { game } from "../cachedClasses";
3
+ import { hasFlag } from "./flag";
4
+
5
+ export function hasCurse(curse: LevelCurse): boolean {
6
+ const level = game.GetLevel();
7
+ const curses = level.GetCurses();
8
+ return hasFlag(curses, curse);
9
+ }
@@ -0,0 +1,41 @@
1
+ import { Dimension } from "isaac-typescript-definitions";
2
+ import { game } from "../cachedClasses";
3
+ import { NUM_DIMENSIONS } from "../constants";
4
+ import { getRoomGridIndex } from "./roomData";
5
+ import { erange } from "./utils";
6
+
7
+ /**
8
+ * Helper function to get an array with every valid `Dimension` (not including `Dimension.CURRENT`).
9
+ */
10
+ export function getAllDimensions(): Dimension[] {
11
+ return erange(NUM_DIMENSIONS) as Dimension[];
12
+ }
13
+
14
+ /**
15
+ * Helper function to get the current dimension. Most of the time, this will be `Dimension.MAIN`,
16
+ * but it can change if e.g. the player is in the mirror world of Downpour/Dross.
17
+ */
18
+ export function getDimension(): Dimension {
19
+ const level = game.GetLevel();
20
+ const roomGridIndex = getRoomGridIndex();
21
+ const roomDescription = level.GetRoomByIdx(roomGridIndex, Dimension.CURRENT);
22
+ const currentRoomHash = GetPtrHash(roomDescription);
23
+
24
+ for (const dimension of getAllDimensions()) {
25
+ const dimensionRoomDescription = level.GetRoomByIdx(
26
+ roomGridIndex,
27
+ dimension,
28
+ );
29
+ const dimensionRoomHash = GetPtrHash(dimensionRoomDescription);
30
+
31
+ if (dimensionRoomHash === currentRoomHash) {
32
+ return dimension;
33
+ }
34
+ }
35
+
36
+ error("Failed to get the current dimension.");
37
+ }
38
+
39
+ export function inDimension(dimension: Dimension): boolean {
40
+ return dimension === getDimension();
41
+ }
@@ -1,6 +1,6 @@
1
1
  import { CollectibleType, ItemConfigTag } from "isaac-typescript-definitions";
2
2
  import { isHiddenCollectible, isPassiveCollectible } from "./collectibles";
3
- import { getCollectibleSet } from "./collectibleSet";
3
+ import { getCollectibleArray } from "./collectibleSet";
4
4
  import { collectibleHasTag } from "./collectibleTag";
5
5
  import { getRandomSeed } from "./rng";
6
6
  import { copySet, getRandomSetElement } from "./set";
@@ -8,9 +8,7 @@ import { copySet, getRandomSetElement } from "./set";
8
8
  const EDEN_PASSIVE_COLLECTIBLES_SET = new Set<CollectibleType>();
9
9
 
10
10
  function initCollectibleSet() {
11
- const collectibleSet = getCollectibleSet();
12
-
13
- for (const collectibleType of collectibleSet.values()) {
11
+ for (const collectibleType of getCollectibleArray()) {
14
12
  if (
15
13
  isPassiveCollectible(collectibleType) &&
16
14
  !isHiddenCollectible(collectibleType) &&
@@ -7,7 +7,7 @@ import {
7
7
  } from "isaac-typescript-definitions";
8
8
  import { game } from "../cachedClasses";
9
9
  import { PlayerIndex } from "../types/PlayerIndex";
10
- import { getCollectibleSet } from "./collectibleSet";
10
+ import { getCollectibleArray } from "./collectibleSet";
11
11
  import { collectibleHasTag } from "./collectibleTag";
12
12
  import { mapGetPlayer, mapSetPlayer } from "./playerDataStructures";
13
13
  import { getPlayers } from "./playerIndex";
@@ -24,17 +24,41 @@ const TRINKETS_THAT_AFFECT_ITEM_POOLS: readonly TrinketType[] = [
24
24
  TrinketType.NO,
25
25
  ];
26
26
 
27
+ const COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS = CollectibleType.KEY_PIECE_1;
28
+
29
+ /**
30
+ * Helper function to get the remaining collectibles in a given item pool. This function is
31
+ * expensive, so only use it in situations where the lag is acceptable.
32
+ */
33
+ export function getCollectiblesInItemPool(
34
+ itemPoolType: ItemPoolType,
35
+ ): CollectibleType[] {
36
+ const collectibleArray = getCollectibleArray();
37
+ return collectibleArray.filter((collectibleType) =>
38
+ isCollectibleInItemPool(collectibleType, itemPoolType),
39
+ );
40
+ }
41
+
27
42
  /**
28
43
  * Helper function to see if the given collectible is still present in the given item pool.
29
44
  *
30
45
  * If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
31
46
  * then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
32
47
  * collectibles from item pools).
48
+ *
49
+ * Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
50
+ * every collectible except for the one provided.
33
51
  */
34
52
  export function isCollectibleInItemPool(
35
53
  collectibleType: CollectibleType,
36
54
  itemPoolType: ItemPoolType,
37
55
  ): boolean {
56
+ // We use a specific collectible which is known to not be in any pools as a default value. Thus,
57
+ // we must explicitly handle this case.
58
+ if (collectibleType === COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS) {
59
+ return false;
60
+ }
61
+
38
62
  // On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
39
63
  // temporarily change the character to Isaac.
40
64
  const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
@@ -55,8 +79,8 @@ export function isCollectibleInItemPool(
55
79
 
56
80
  // Blacklist every collectible in the game except for the provided collectible.
57
81
  const itemPool = game.GetItemPool();
58
- const collectibleSet = getCollectibleSet();
59
- for (const collectibleTypeInSet of collectibleSet.values()) {
82
+ itemPool.ResetRoomBlacklist();
83
+ for (const collectibleTypeInSet of getCollectibleArray()) {
60
84
  if (collectibleTypeInSet !== collectibleType) {
61
85
  itemPool.AddRoomBlacklist(collectibleTypeInSet);
62
86
  }
@@ -64,12 +88,13 @@ export function isCollectibleInItemPool(
64
88
 
65
89
  // Get a collectible from the pool and see if it is the intended collectible. (We can use any
66
90
  // arbitrary value as the seed since it should not influence the result.)
91
+ const seed = 1 as Seed;
67
92
  const retrievedCollectibleType = itemPool.GetCollectible(
68
93
  itemPoolType,
69
94
  false,
70
- 1 as Seed,
95
+ seed,
96
+ COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS,
71
97
  );
72
-
73
98
  const collectibleUnlocked = retrievedCollectibleType === collectibleType;
74
99
 
75
100
  // Reset the blacklist
@@ -1,21 +1,18 @@
1
1
  import { DoorSlot } from "isaac-typescript-definitions";
2
2
  import { game } from "../cachedClasses";
3
3
  import { getEnumValues } from "./enums";
4
- import {
5
- getNumRooms,
6
- getRooms,
7
- isDoorSlotValidAtGridIndexForRedRoom,
8
- } from "./rooms";
4
+ import { isDoorSlotValidAtGridIndexForRedRoom } from "./levelGrid";
5
+ import { getNumRooms, getRoomsInGrid } from "./rooms";
9
6
 
10
7
  export function fillLevelWithRedRooms(): void {
11
8
  const level = game.GetLevel();
12
9
 
13
- let numRooms: int;
10
+ let numRoomsInGrid: int;
14
11
  do {
15
- const rooms = getRooms();
16
- numRooms = rooms.length;
12
+ const roomsInGrid = getRoomsInGrid();
13
+ numRoomsInGrid = roomsInGrid.length;
17
14
 
18
- for (const roomDescriptor of rooms) {
15
+ for (const roomDescriptor of roomsInGrid) {
19
16
  for (const doorSlot of getEnumValues(DoorSlot)) {
20
17
  if (
21
18
  isDoorSlotValidAtGridIndexForRedRoom(
@@ -27,5 +24,5 @@ export function fillLevelWithRedRooms(): void {
27
24
  }
28
25
  }
29
26
  }
30
- } while (numRooms !== getNumRooms());
27
+ } while (numRoomsInGrid !== getNumRooms());
31
28
  }