isaacscript-common 21.9.0 → 23.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 (45) hide show
  1. package/dist/index.rollup.d.ts +61 -45
  2. package/dist/isaacscript-common.lua +202 -177
  3. package/dist/lualib_bundle.lua +59 -100
  4. package/dist/src/functions/characters.d.ts +8 -1
  5. package/dist/src/functions/characters.d.ts.map +1 -1
  6. package/dist/src/functions/characters.lua +9 -0
  7. package/dist/src/functions/color.d.ts +1 -1
  8. package/dist/src/functions/color.d.ts.map +1 -1
  9. package/dist/src/functions/hex.d.ts +2 -2
  10. package/dist/src/functions/hex.d.ts.map +1 -1
  11. package/dist/src/functions/isaacAPIClass.d.ts +1 -1
  12. package/dist/src/functions/isaacAPIClass.d.ts.map +1 -1
  13. package/dist/src/functions/isaacAPIClass.lua +1 -1
  14. package/dist/src/functions/kColor.d.ts +1 -1
  15. package/dist/src/functions/kColor.d.ts.map +1 -1
  16. package/dist/src/functions/log.d.ts +1 -1
  17. package/dist/src/functions/log.d.ts.map +1 -1
  18. package/dist/src/functions/log.lua +5 -0
  19. package/dist/src/functions/players.d.ts +28 -21
  20. package/dist/src/functions/players.d.ts.map +1 -1
  21. package/dist/src/functions/players.lua +60 -51
  22. package/dist/src/functions/positionVelocity.d.ts +1 -1
  23. package/dist/src/functions/positionVelocity.d.ts.map +1 -1
  24. package/dist/src/functions/roomGrid.d.ts +5 -5
  25. package/dist/src/functions/roomGrid.d.ts.map +1 -1
  26. package/dist/src/functions/ui.d.ts +8 -8
  27. package/dist/src/functions/ui.d.ts.map +1 -1
  28. package/dist/src/functions/vector.d.ts +1 -1
  29. package/dist/src/functions/vector.d.ts.map +1 -1
  30. package/dist/src/objects/characterStartingCollectibles.d.ts +46 -0
  31. package/dist/src/objects/characterStartingCollectibles.d.ts.map +1 -0
  32. package/dist/src/objects/characterStartingCollectibles.lua +49 -0
  33. package/package.json +1 -1
  34. package/src/functions/characters.ts +14 -1
  35. package/src/functions/color.ts +1 -1
  36. package/src/functions/hex.ts +2 -2
  37. package/src/functions/isaacAPIClass.ts +1 -1
  38. package/src/functions/kColor.ts +1 -1
  39. package/src/functions/log.ts +7 -1
  40. package/src/functions/players.ts +72 -57
  41. package/src/functions/positionVelocity.ts +1 -1
  42. package/src/functions/roomGrid.ts +14 -5
  43. package/src/functions/ui.ts +8 -8
  44. package/src/functions/vector.ts +1 -1
  45. package/src/objects/characterStartingCollectibles.ts +144 -0
@@ -24,6 +24,21 @@ import {
24
24
  import { isNumber } from "./types";
25
25
  import { repeat } from "./utils";
26
26
 
27
+ /**
28
+ * Helper function to add one or more collectibles to a player.
29
+ *
30
+ * This function is variadic, meaning that you can supply as many collectible types as you want to
31
+ * add.
32
+ */
33
+ export function addCollectible(
34
+ player: EntityPlayer,
35
+ ...collectibleTypes: CollectibleType[]
36
+ ): void {
37
+ for (const collectibleType of collectibleTypes) {
38
+ player.AddCollectible(collectibleType);
39
+ }
40
+ }
41
+
27
42
  export function addCollectibleCostume(
28
43
  player: EntityPlayer,
29
44
  collectibleType: CollectibleType,
@@ -438,6 +453,34 @@ export function getTotalPlayerCollectibles(
438
453
  return sumArray(numCollectiblesArray);
439
454
  }
440
455
 
456
+ /**
457
+ * Helper function to check to see if a player has one or more collectibles.
458
+ *
459
+ * This function is variadic, meaning that you can supply as many collectible types as you want to
460
+ * check for. Returns true if the player has any of the supplied collectible types.
461
+ */
462
+ export function hasCollectible(
463
+ player: EntityPlayer,
464
+ ...collectibleTypes: CollectibleType[]
465
+ ): boolean {
466
+ return collectibleTypes.some((collectibleType) =>
467
+ player.HasCollectible(collectibleType),
468
+ );
469
+ }
470
+
471
+ /**
472
+ * Helper function to check to see if a player has one or more transformations.
473
+ *
474
+ * This function is variadic, meaning that you can supply as many transformations as you want to
475
+ * check for. Returns true if the player has any of the supplied transformations.
476
+ */
477
+ export function hasForm(
478
+ player: EntityPlayer,
479
+ ...playerForms: PlayerForm[]
480
+ ): boolean {
481
+ return playerForms.some((playerForm) => player.HasPlayerForm(playerForm));
482
+ }
483
+
441
484
  /** After touching a white fire, a player will turn into The Lost until they clear a room. */
442
485
  export function hasLostCurse(player: EntityPlayer): boolean {
443
486
  const effects = player.GetEffects();
@@ -565,6 +608,17 @@ export function isLost(player: EntityPlayer): boolean {
565
608
  return character === PlayerType.LOST || character === PlayerType.LOST_B;
566
609
  }
567
610
 
611
+ function isTaintedModded(player: EntityPlayer) {
612
+ // This algorithm only works for modded characters because the `Isaac.GetPlayerTypeByName` method
613
+ // is bugged.
614
+ // https://github.com/Meowlala/RepentanceAPIIssueTracker/issues/117
615
+ const character = player.GetPlayerType();
616
+ const name = player.GetName();
617
+ const taintedCharacter = Isaac.GetPlayerTypeByName(name, true);
618
+
619
+ return character === taintedCharacter;
620
+ }
621
+
568
622
  export function isModdedPlayer(player: EntityPlayer): boolean {
569
623
  return !isVanillaPlayer(player);
570
624
  }
@@ -588,17 +642,6 @@ export function isTainted(player: EntityPlayer): boolean {
588
642
  : isTaintedModded(player);
589
643
  }
590
644
 
591
- function isTaintedModded(player: EntityPlayer) {
592
- // This algorithm only works for modded characters because the `Isaac.GetPlayerTypeByName` method
593
- // is bugged.
594
- // https://github.com/Meowlala/RepentanceAPIIssueTracker/issues/117
595
- const character = player.GetPlayerType();
596
- const name = player.GetName();
597
- const taintedCharacter = Isaac.GetPlayerTypeByName(name, true);
598
-
599
- return character === taintedCharacter;
600
- }
601
-
602
645
  /** Helper function for detecting when a player is Tainted Lazarus or Dead Tainted Lazarus. */
603
646
  export function isTaintedLazarus(player: EntityPlayer): boolean {
604
647
  const character = player.GetPlayerType();
@@ -613,49 +656,6 @@ export function isVanillaPlayer(player: EntityPlayer): boolean {
613
656
  return isVanillaCharacter(character);
614
657
  }
615
658
 
616
- /**
617
- * Helper function to add one or more collectibles to a player.
618
- *
619
- * This function is variadic, meaning that you can supply as many collectible types as you want to
620
- * add.
621
- */
622
- export function playerAddCollectible(
623
- player: EntityPlayer,
624
- ...collectibleTypes: CollectibleType[]
625
- ): void {
626
- for (const collectibleType of collectibleTypes) {
627
- player.AddCollectible(collectibleType);
628
- }
629
- }
630
-
631
- /**
632
- * Helper function to check to see if a player has one or more collectibles.
633
- *
634
- * This function is variadic, meaning that you can supply as many collectible types as you want to
635
- * check for. Returns true if the player has any of the supplied collectible types.
636
- */
637
- export function playerHasCollectible(
638
- player: EntityPlayer,
639
- ...collectibleTypes: CollectibleType[]
640
- ): boolean {
641
- return collectibleTypes.some((collectibleType) =>
642
- player.HasCollectible(collectibleType),
643
- );
644
- }
645
-
646
- /**
647
- * Helper function to check to see if a player has one or more transformations.
648
- *
649
- * This function is variadic, meaning that you can supply as many transformations as you want to
650
- * check for. Returns true if the player has any of the supplied transformations.
651
- */
652
- export function playerHasForm(
653
- player: EntityPlayer,
654
- ...playerForms: PlayerForm[]
655
- ): boolean {
656
- return playerForms.some((playerForm) => player.HasPlayerForm(playerForm));
657
- }
658
-
659
659
  /**
660
660
  * Helper function to remove all of the active items from a player. This includes the Schoolbag item
661
661
  * and any pocket actives.
@@ -667,11 +667,11 @@ export function removeAllActiveItems(player: EntityPlayer): void {
667
667
  continue;
668
668
  }
669
669
 
670
- let hasCollectible: boolean;
670
+ let stillHasCollectible: boolean;
671
671
  do {
672
672
  player.RemoveCollectible(collectibleType);
673
- hasCollectible = player.HasCollectible(collectibleType);
674
- } while (hasCollectible);
673
+ stillHasCollectible = player.HasCollectible(collectibleType);
674
+ } while (stillHasCollectible);
675
675
  }
676
676
  }
677
677
 
@@ -696,6 +696,21 @@ export function removeAllPlayerTrinkets(player: EntityPlayer): void {
696
696
  }
697
697
  }
698
698
 
699
+ /**
700
+ * Helper function to remove one or more collectibles to a player.
701
+ *
702
+ * This function is variadic, meaning that you can supply as many collectible types as you want to
703
+ * remove.
704
+ */
705
+ export function removeCollectible(
706
+ player: EntityPlayer,
707
+ ...collectibleTypes: CollectibleType[]
708
+ ): void {
709
+ for (const collectibleType of collectibleTypes) {
710
+ player.RemoveCollectible(collectibleType);
711
+ }
712
+ }
713
+
699
714
  /**
700
715
  * Helper function to remove a collectible costume from a player. Use this helper function to avoid
701
716
  * having to request the collectible from the item config.
@@ -54,7 +54,7 @@ export function findFreePosition(
54
54
  startingPosition: Vector,
55
55
  avoidActiveEntities = false,
56
56
  minimumDistance?: float,
57
- ): Vector {
57
+ ): Readonly<Vector> {
58
58
  const room = game.GetRoom();
59
59
  const heavenDoors = getEffects(
60
60
  EffectVariant.HEAVEN_LIGHT_DOOR,
@@ -22,7 +22,10 @@ import {
22
22
  *
23
23
  * For example, the coordinates of (0, 0) are equal to `Vector(80, 160)`.
24
24
  */
25
- export function gridCoordinatesToWorldPosition(x: int, y: int): Vector {
25
+ export function gridCoordinatesToWorldPosition(
26
+ x: int,
27
+ y: int,
28
+ ): Readonly<Vector> {
26
29
  const gridPosition = Vector(x, y);
27
30
  return gridPositionToWorldPosition(gridPosition);
28
31
  }
@@ -36,7 +39,7 @@ export function gridCoordinatesToWorldPosition(x: int, y: int): Vector {
36
39
  export function gridIndexToGridPosition(
37
40
  gridIndex: int,
38
41
  roomShape: RoomShape,
39
- ): Vector {
42
+ ): Readonly<Vector> {
40
43
  const gridWidth = getRoomShapeWidth(roomShape);
41
44
 
42
45
  const x = (gridIndex % gridWidth) - 1;
@@ -49,7 +52,9 @@ export function gridIndexToGridPosition(
49
52
  *
50
53
  * For example, the coordinates of (0, 0) are equal to `Vector(80, 160)`.
51
54
  */
52
- export function gridPositionToWorldPosition(gridPosition: Vector): Vector {
55
+ export function gridPositionToWorldPosition(
56
+ gridPosition: Vector,
57
+ ): Readonly<Vector> {
53
58
  const x = (gridPosition.X + 2) * 40;
54
59
  const y = (gridPosition.Y + 4) * 40;
55
60
 
@@ -99,7 +104,9 @@ function isValidGridPositionLRoom(gridPosition: Vector, roomShape: RoomShape) {
99
104
  *
100
105
  * In this context, the grid position of the top-left wall is "Vector(-1, -1)".
101
106
  */
102
- export function worldPositionToGridPosition(worldPos: Vector): Vector {
107
+ export function worldPositionToGridPosition(
108
+ worldPos: Vector,
109
+ ): Readonly<Vector> {
103
110
  const x = Math.round(worldPos.X / 40 - 2);
104
111
  const y = Math.round(worldPos.Y / 40 - 4);
105
112
  return Vector(x, y);
@@ -112,7 +119,9 @@ export function worldPositionToGridPosition(worldPos: Vector): Vector {
112
119
  *
113
120
  * This is similar to the `worldPositionToGridPosition` function, but the values are not rounded.
114
121
  */
115
- export function worldPositionToGridPositionFast(worldPos: Vector): Vector {
122
+ export function worldPositionToGridPositionFast(
123
+ worldPos: Vector,
124
+ ): Readonly<Vector> {
116
125
  const x = worldPos.X / 40 - 2;
117
126
  const y = worldPos.Y / 40 - 4;
118
127
  return Vector(x, y);
@@ -13,7 +13,7 @@ import { copyVector } from "./vector";
13
13
  * - If the user does not have a HUD offset configured, this function will return `Vector(0, 0)`.
14
14
  * - If the user has a HUD offset of 1.0 configured, this function will return `Vector(20, 12)`.
15
15
  */
16
- export function getHUDOffsetVector(): Vector {
16
+ export function getHUDOffsetVector(): Readonly<Vector> {
17
17
  // Convert e.g. 0.4 to 4.
18
18
  const hudOffset = math.floor(Options.HUDOffset * 10);
19
19
 
@@ -89,38 +89,38 @@ export function getHeartsUIWidth(): int {
89
89
  return width;
90
90
  }
91
91
 
92
- export function getScreenBottomCenterPos(): Vector {
92
+ export function getScreenBottomCenterPos(): Readonly<Vector> {
93
93
  const bottomRight = getScreenBottomRightPos();
94
94
  return Vector(bottomRight.X / 2, bottomRight.Y);
95
95
  }
96
96
 
97
- export function getScreenBottomLeftPos(): Vector {
97
+ export function getScreenBottomLeftPos(): Readonly<Vector> {
98
98
  const bottomRight = getScreenBottomRightPos();
99
99
  return Vector(0, bottomRight.Y);
100
100
  }
101
101
 
102
- export function getScreenBottomRightPos(): Vector {
102
+ export function getScreenBottomRightPos(): Readonly<Vector> {
103
103
  const screenWidth = Isaac.GetScreenWidth();
104
104
  const screenHeight = Isaac.GetScreenHeight();
105
105
 
106
106
  return Vector(screenWidth, screenHeight);
107
107
  }
108
108
 
109
- export function getScreenCenterPos(): Vector {
109
+ export function getScreenCenterPos(): Readonly<Vector> {
110
110
  const bottomRight = getScreenBottomRightPos();
111
111
  return bottomRight.div(2);
112
112
  }
113
113
 
114
- export function getScreenTopCenterPos(): Vector {
114
+ export function getScreenTopCenterPos(): Readonly<Vector> {
115
115
  const bottomRight = getScreenBottomRightPos();
116
116
  return Vector(bottomRight.X / 2, 0);
117
117
  }
118
118
 
119
- export function getScreenTopLeftPos(): Vector {
119
+ export function getScreenTopLeftPos(): Readonly<Vector> {
120
120
  return copyVector(VectorZero);
121
121
  }
122
122
 
123
- export function getScreenTopRightPos(): Vector {
123
+ export function getScreenTopRightPos(): Readonly<Vector> {
124
124
  const bottomRight = getScreenBottomRightPos();
125
125
  return Vector(bottomRight.X, 0);
126
126
  }
@@ -90,7 +90,7 @@ export function doesVectorHaveLength(
90
90
  */
91
91
  export function getRandomVector(
92
92
  seedOrRNG: Seed | RNG = getRandomSeed(),
93
- ): Vector {
93
+ ): Readonly<Vector> {
94
94
  const rng = isRNG(seedOrRNG) ? seedOrRNG : newRNG(seedOrRNG);
95
95
 
96
96
  const x = getRandomFloat(-1, 1, rng);
@@ -0,0 +1,144 @@
1
+ import { CollectibleType, PlayerType } from "isaac-typescript-definitions";
2
+
3
+ export const CHARACTER_STARTING_COLLECTIBLES = {
4
+ // -1
5
+ [PlayerType.POSSESSOR]: [],
6
+
7
+ // 0
8
+ [PlayerType.ISAAC]: [CollectibleType.D6],
9
+
10
+ // 1
11
+ [PlayerType.MAGDALENE]: [CollectibleType.YUM_HEART],
12
+
13
+ // 2
14
+ [PlayerType.CAIN]: [CollectibleType.LUCKY_FOOT],
15
+
16
+ // 3
17
+ [PlayerType.JUDAS]: [CollectibleType.BOOK_OF_BELIAL],
18
+
19
+ // 4
20
+ [PlayerType.BLUE_BABY]: [CollectibleType.POOP],
21
+
22
+ // 5
23
+ [PlayerType.EVE]: [
24
+ CollectibleType.DEAD_BIRD, // 117
25
+ CollectibleType.WHORE_OF_BABYLON, // 122
26
+ CollectibleType.RAZOR_BLADE, // 126
27
+ ],
28
+
29
+ // 6
30
+ [PlayerType.SAMSON]: [CollectibleType.BLOODY_LUST],
31
+
32
+ // 7
33
+ [PlayerType.AZAZEL]: [],
34
+
35
+ // 8
36
+ [PlayerType.LAZARUS]: [CollectibleType.ANEMIC],
37
+ // (Lazarus Rags is not granted; the extra life is innate.)
38
+
39
+ // 9
40
+ [PlayerType.EDEN]: [],
41
+
42
+ // 10
43
+ [PlayerType.LOST]: [CollectibleType.ETERNAL_D6],
44
+ // (Holy Mantle is not granted; the effect is innate.)
45
+
46
+ // 11
47
+ [PlayerType.LAZARUS_2]: [CollectibleType.ANEMIC],
48
+ // (Even if the run is started as Lazarus 2 using e.g. `restart 11`, Anemic is still granted.)
49
+
50
+ // 12
51
+ [PlayerType.DARK_JUDAS]: [],
52
+
53
+ // 13
54
+ [PlayerType.LILITH]: [
55
+ CollectibleType.BOX_OF_FRIENDS, // 357
56
+ CollectibleType.CAMBION_CONCEPTION, // 412
57
+ ],
58
+
59
+ // 14
60
+ [PlayerType.KEEPER]: [CollectibleType.WOODEN_NICKEL],
61
+
62
+ // 15
63
+ [PlayerType.APOLLYON]: [CollectibleType.VOID],
64
+
65
+ // 16
66
+ [PlayerType.FORGOTTEN]: [],
67
+
68
+ // 17
69
+ [PlayerType.SOUL]: [],
70
+
71
+ // 18
72
+ [PlayerType.BETHANY]: [CollectibleType.BOOK_OF_VIRTUES],
73
+
74
+ // 19
75
+ [PlayerType.JACOB]: [],
76
+
77
+ // 20
78
+ [PlayerType.ESAU]: [],
79
+
80
+ // 21
81
+ [PlayerType.ISAAC_B]: [],
82
+
83
+ // 22
84
+ [PlayerType.MAGDALENE_B]: [CollectibleType.YUM_HEART],
85
+
86
+ // 23
87
+ [PlayerType.CAIN_B]: [CollectibleType.BAG_OF_CRAFTING],
88
+
89
+ // 24
90
+ [PlayerType.JUDAS_B]: [CollectibleType.DARK_ARTS],
91
+
92
+ // 25
93
+ [PlayerType.BLUE_BABY_B]: [CollectibleType.HOLD],
94
+
95
+ // 26
96
+ [PlayerType.EVE_B]: [CollectibleType.SUMPTORIUM],
97
+
98
+ // 27
99
+ [PlayerType.SAMSON_B]: [],
100
+ // (Berserk is not granted; the rage is innate.)
101
+
102
+ // 28
103
+ [PlayerType.AZAZEL_B]: [],
104
+
105
+ // 29
106
+ [PlayerType.LAZARUS_B]: [CollectibleType.FLIP],
107
+
108
+ // 30
109
+ [PlayerType.EDEN_B]: [],
110
+
111
+ // 31
112
+ [PlayerType.LOST_B]: [],
113
+
114
+ // 32
115
+ [PlayerType.LILITH_B]: [],
116
+
117
+ // 33
118
+ [PlayerType.KEEPER_B]: [],
119
+
120
+ // 34
121
+ [PlayerType.APOLLYON_B]: [CollectibleType.ABYSS],
122
+
123
+ // 35
124
+ [PlayerType.FORGOTTEN_B]: [],
125
+
126
+ // 36
127
+ [PlayerType.BETHANY_B]: [CollectibleType.LEMEGETON],
128
+
129
+ // 37
130
+ [PlayerType.JACOB_B]: [CollectibleType.ANIMA_SOLA],
131
+
132
+ // 38
133
+ [PlayerType.LAZARUS_2_B]: [CollectibleType.FLIP],
134
+ // (Even if the run is started as Dead Tainted Lazarus using e.g. `restart 38`, Flip is still
135
+ // granted.)
136
+
137
+ // 39
138
+ [PlayerType.JACOB_2_B]: [CollectibleType.ANIMA_SOLA],
139
+ // (Even if the run is started as Tainted Jacob in "Lost" form using e.g. `restart 39`, Anima Sola
140
+ // is still granted.)
141
+
142
+ // 40
143
+ [PlayerType.SOUL_B]: [],
144
+ } as const satisfies Record<PlayerType, readonly CollectibleType[]>;