isaacscript-common 3.1.0 → 3.1.1

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Set = ____lualib.Set
3
+ local __TS__New = ____lualib.__TS__New
4
+ local ____exports = {}
5
+ local hasSubscriptions, postPickupInit, POST_ASCENT_ROOM_TYPES, v
6
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
7
+ local GameStateFlag = ____isaac_2Dtypescript_2Ddefinitions.GameStateFlag
8
+ local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
9
+ local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
10
+ local ____cachedClasses = require("cachedClasses")
11
+ local game = ____cachedClasses.game
12
+ local ____exports = require("features.saveDataManager.exports")
13
+ local saveDataManager = ____exports.saveDataManager
14
+ local ____roomData = require("functions.roomData")
15
+ local getRoomVisitedCount = ____roomData.getRoomVisitedCount
16
+ local ____postPickupInitFirst = require("callbacks.subscriptions.postPickupInitFirst")
17
+ local postPickupInitFirstFire = ____postPickupInitFirst.postPickupInitFirstFire
18
+ local postPickupInitFirstHasSubscriptions = ____postPickupInitFirst.postPickupInitFirstHasSubscriptions
19
+ function hasSubscriptions(self)
20
+ return postPickupInitFirstHasSubscriptions(nil)
21
+ end
22
+ function postPickupInit(self, pickup)
23
+ if not hasSubscriptions(nil) then
24
+ return
25
+ end
26
+ local room = game:GetRoom()
27
+ local roomType = room:GetType()
28
+ local roomFrameCount = room:GetFrameCount()
29
+ local previouslySeen = v.run.postAscentPickupInitSeeds:has(pickup.InitSeed)
30
+ if POST_ASCENT_ROOM_TYPES:has(roomType) then
31
+ v.run.postAscentPickupInitSeeds:add(pickup.InitSeed)
32
+ end
33
+ if roomFrameCount > 0 then
34
+ postPickupInitFirstFire(nil, pickup)
35
+ return
36
+ end
37
+ local roomVisitedCount = getRoomVisitedCount(nil)
38
+ if roomVisitedCount > 0 then
39
+ return
40
+ end
41
+ local onAscent = game:GetStateFlag(GameStateFlag.BACKWARDS_PATH)
42
+ if onAscent and POST_ASCENT_ROOM_TYPES:has(roomType) and previouslySeen then
43
+ return
44
+ end
45
+ postPickupInitFirstFire(nil, pickup)
46
+ end
47
+ POST_ASCENT_ROOM_TYPES = __TS__New(Set, {RoomType.TREASURE, RoomType.BOSS})
48
+ v = {run = {postAscentPickupInitSeeds = __TS__New(Set)}}
49
+ ---
50
+ -- @internal
51
+ function ____exports.postPickupInitFirstCallbackInit(self, mod)
52
+ saveDataManager(nil, "postPickupInitFirst", v, hasSubscriptions)
53
+ mod:AddCallback(ModCallback.POST_PICKUP_INIT, postPickupInit)
54
+ end
55
+ return ____exports
@@ -0,0 +1,3 @@
1
+ /// <reference types="isaac-typescript-definitions" />
2
+ export declare type PostPickupInitFirstRegisterParameters = PickupRegisterParameters<[
3
+ ], void>;
@@ -0,0 +1,29 @@
1
+ local ____exports = {}
2
+ local subscriptions = {}
3
+ ---
4
+ -- @internal
5
+ function ____exports.postPickupInitFirstHasSubscriptions(self)
6
+ return #subscriptions > 0
7
+ end
8
+ ---
9
+ -- @internal
10
+ function ____exports.postPickupInitFirstRegister(self, ...)
11
+ local args = {...}
12
+ subscriptions[#subscriptions + 1] = args
13
+ end
14
+ ---
15
+ -- @internal
16
+ function ____exports.postPickupInitFirstFire(self, pickup)
17
+ for ____, ____value in ipairs(subscriptions) do
18
+ local callback = ____value[1]
19
+ local pickupVariant = ____value[2]
20
+ do
21
+ if pickupVariant ~= nil and pickupVariant ~= pickup.Variant then
22
+ goto __continue5
23
+ end
24
+ callback(nil, pickup)
25
+ end
26
+ ::__continue5::
27
+ end
28
+ end
29
+ return ____exports
@@ -143,7 +143,7 @@ export declare enum ModCallbackCustom {
143
143
  * only fire if the familiar variant matches the `FamiliarVariant` provided.
144
144
  *
145
145
  * ```ts
146
- * function postTearInitLate(familiar: EntityFamiliar): void {}
146
+ * function postFamiliarInitLate(familiar: EntityFamiliar): void {}
147
147
  * ```
148
148
  */
149
149
  POST_FAMILIAR_INIT_LATE = 11,
@@ -490,6 +490,28 @@ export declare enum ModCallbackCustom {
490
490
  * ```
491
491
  */
492
492
  POST_PICKUP_COLLECT = 36,
493
+ /**
494
+ * Fires from the `MC_POST_PICKUP_INIT` callback on the first time that a player has seen the
495
+ * respective pickup on the run.
496
+ *
497
+ * This callback is useful because pickups will despawn upon leaving the room and respawn upon
498
+ * re-entering the room.
499
+ *
500
+ * For most cases, this callback will simply fire when `MC_POST_PICKUP_INIT` fires and the player
501
+ * is not re-entering a previously visited room.
502
+ *
503
+ * The special case is when a player enters a post-Ascent Treasure Room or Boss Room. For these
504
+ * cases, the `InitSeed` of any pickups seen from previous floors is kept track of to prevent the
505
+ * callback from firing when re-entering the room.
506
+ *
507
+ * When registering the callback, takes an optional second argument that will make the callback
508
+ * only fire if the collectible type matches the `PickupVariant` provided.
509
+ *
510
+ * ```ts
511
+ * function postPickupInitFirst(pickup: EntityPickup): void {}
512
+ * ```
513
+ */
514
+ POST_PICKUP_INIT_FIRST = 37,
493
515
  /**
494
516
  * Fires on the first `MC_POST_PICKUP_UPDATE` frame for each pickup.
495
517
  *
@@ -503,7 +525,7 @@ export declare enum ModCallbackCustom {
503
525
  * function postPickupInitLate(pickup: EntityPickup): void {}
504
526
  * ```
505
527
  */
506
- POST_PICKUP_INIT_LATE = 37,
528
+ POST_PICKUP_INIT_LATE = 38,
507
529
  /**
508
530
  * Fires from the `MC_POST_PICKUP_UPDATE` callback when a pickup's state has changed from what it
509
531
  * was on the previous frame.
@@ -519,9 +541,9 @@ export declare enum ModCallbackCustom {
519
541
  * ): void {}
520
542
  * ```
521
543
  */
522
- POST_PICKUP_STATE_CHANGED = 38,
523
- POST_PIT_RENDER = 39,
524
- POST_PIT_UPDATE = 40,
544
+ POST_PICKUP_STATE_CHANGED = 39,
545
+ POST_PIT_RENDER = 40,
546
+ POST_PIT_UPDATE = 41,
525
547
  /**
526
548
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback when a player entity gains or loses any health
527
549
  * (i.e. hearts). For more information, see the `PlayerHealth` enum.
@@ -537,7 +559,7 @@ export declare enum ModCallbackCustom {
537
559
  * ) {}
538
560
  * ```
539
561
  */
540
- POST_PLAYER_CHANGE_HEALTH = 41,
562
+ POST_PLAYER_CHANGE_HEALTH = 42,
541
563
  /**
542
564
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback when a player entity changes its player type
543
565
  * (i.e. character). For example, it will fire after using Clicker, after dying with the Judas'
@@ -555,7 +577,7 @@ export declare enum ModCallbackCustom {
555
577
  * ) {}
556
578
  * ```
557
579
  */
558
- POST_PLAYER_CHANGE_TYPE = 42,
580
+ POST_PLAYER_CHANGE_TYPE = 43,
559
581
  /**
560
582
  * Fires from the `MC_ENTITY_TAKE_DMG` callback when a player takes fatal damage. Return false to
561
583
  * prevent the fatal damage.
@@ -572,7 +594,7 @@ export declare enum ModCallbackCustom {
572
594
  * function postPlayerFatalDamage(player: EntityPlayer) {}
573
595
  * ```
574
596
  */
575
- POST_PLAYER_FATAL_DAMAGE = 43,
597
+ POST_PLAYER_FATAL_DAMAGE = 44,
576
598
  /**
577
599
  * Fires on the first `MC_POST_PLAYER_UPDATE` frame for each player.
578
600
  *
@@ -586,7 +608,7 @@ export declare enum ModCallbackCustom {
586
608
  * function postPlayerInitLate(pickup: EntityPickup): void {}
587
609
  * ```
588
610
  */
589
- POST_PLAYER_INIT_LATE = 44,
611
+ POST_PLAYER_INIT_LATE = 45,
590
612
  /**
591
613
  * Similar to the vanilla callback of the same name, but fires after the `MC_POST_GAME_STARTED`
592
614
  * callback fires (if the player is spawning on the 0th game frame of the run).
@@ -607,8 +629,8 @@ export declare enum ModCallbackCustom {
607
629
  * function postPlayerInitReordered(player: EntityPlayer): void {}
608
630
  * ```
609
631
  */
610
- POST_PLAYER_INIT_REORDERED = 45,
611
- POST_PLAYER_RENDER_REORDERED = 46,
632
+ POST_PLAYER_INIT_REORDERED = 46,
633
+ POST_PLAYER_RENDER_REORDERED = 47,
612
634
  /**
613
635
  * Similar to the vanilla callback of the same name, but fires after the `MC_POST_GAME_STARTED`
614
636
  * callback fires (if the player is being updated on the 0th game frame of the run).
@@ -629,11 +651,11 @@ export declare enum ModCallbackCustom {
629
651
  * function postPlayerUpdateReordered(player: EntityPlayer): void {}
630
652
  * ```
631
653
  */
632
- POST_PLAYER_UPDATE_REORDERED = 47,
633
- POST_POOP_RENDER = 48,
634
- POST_POOP_UPDATE = 49,
635
- POST_PRESSURE_PLATE_RENDER = 50,
636
- POST_PRESSURE_PLATE_UPDATE = 51,
654
+ POST_PLAYER_UPDATE_REORDERED = 48,
655
+ POST_POOP_RENDER = 49,
656
+ POST_POOP_UPDATE = 50,
657
+ POST_PRESSURE_PLATE_RENDER = 51,
658
+ POST_PRESSURE_PLATE_UPDATE = 52,
637
659
  /**
638
660
  * Fires on the first `MC_POST_PROJECTILE_UPDATE` frame for each projectile.
639
661
  *
@@ -647,7 +669,7 @@ export declare enum ModCallbackCustom {
647
669
  * function postProjectileInitLate(projectile: EntityProjectile): void {}
648
670
  * ```
649
671
  */
650
- POST_PROJECTILE_INIT_LATE = 52,
672
+ POST_PROJECTILE_INIT_LATE = 53,
651
673
  /**
652
674
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback when a player first picks up a new item. The
653
675
  * pickup returned in the callback is assumed to be the first pickup that no longer exists.
@@ -661,10 +683,10 @@ export declare enum ModCallbackCustom {
661
683
  * function postPurchase(player: EntityPlayer, pickup: EntityPickup): void {}
662
684
  * ```
663
685
  */
664
- POST_PURCHASE = 53,
665
- POST_ROCK_RENDER = 54,
666
- POST_ROCK_UPDATE = 55,
667
- POST_ROOM_CLEAR_CHANGED = 56,
686
+ POST_PURCHASE = 54,
687
+ POST_ROCK_RENDER = 55,
688
+ POST_ROCK_UPDATE = 56,
689
+ POST_ROOM_CLEAR_CHANGED = 57,
668
690
  /**
669
691
  * Fires from the `MC_ENTITY_TAKE_DMG` callback when a player takes damage from spikes in a
670
692
  * Sacrifice Room.
@@ -673,7 +695,7 @@ export declare enum ModCallbackCustom {
673
695
  * function postSacrifice(player: EntityPlayer, numSacrifices: int): void {}
674
696
  * ```
675
697
  */
676
- POST_SACRIFICE = 57,
698
+ POST_SACRIFICE = 58,
677
699
  /**
678
700
  * Fires from the `MC_POST_RENDER` callback when a slot entity's animation changes.
679
701
  *
@@ -684,7 +706,7 @@ export declare enum ModCallbackCustom {
684
706
  * function postSlotAnimationChanged(slot: Entity): void {}
685
707
  * ```
686
708
  */
687
- POST_SLOT_ANIMATION_CHANGED = 58,
709
+ POST_SLOT_ANIMATION_CHANGED = 59,
688
710
  /**
689
711
  * Fires from the `MC_POST_RENDER` callback when a slot plays the animation that indicates that it
690
712
  * has broken.
@@ -696,7 +718,7 @@ export declare enum ModCallbackCustom {
696
718
  * function postSlotDestroyed(slot: Entity): void {}
697
719
  * ```
698
720
  */
699
- POST_SLOT_DESTROYED = 59,
721
+ POST_SLOT_DESTROYED = 60,
700
722
  /**
701
723
  * Fires when a new slot entity is initialized. Specifically, this is either:
702
724
  *
@@ -712,7 +734,7 @@ export declare enum ModCallbackCustom {
712
734
  * function postSlotInit(slot: Entity): void {}
713
735
  * ```
714
736
  */
715
- POST_SLOT_INIT = 60,
737
+ POST_SLOT_INIT = 61,
716
738
  /**
717
739
  * Fires from the `MC_POST_RENDER` callback on every frame that a slot entity exists.
718
740
  *
@@ -723,7 +745,7 @@ export declare enum ModCallbackCustom {
723
745
  * function postSlotRender(slot: Entity): void {}
724
746
  * ```
725
747
  */
726
- POST_SLOT_RENDER = 61,
748
+ POST_SLOT_RENDER = 62,
727
749
  /**
728
750
  * Fires from the `MC_POST_UPDATE` callback on every frame that a slot entity exists.
729
751
  *
@@ -734,9 +756,9 @@ export declare enum ModCallbackCustom {
734
756
  * function postSlotUpdate(slot: Entity): void {}
735
757
  * ```
736
758
  */
737
- POST_SLOT_UPDATE = 62,
738
- POST_SPIKES_RENDER = 63,
739
- POST_SPIKES_UPDATE = 64,
759
+ POST_SLOT_UPDATE = 63,
760
+ POST_SPIKES_RENDER = 64,
761
+ POST_SPIKES_UPDATE = 65,
740
762
  /**
741
763
  * Fires on the first `MC_POST_TEAR_UPDATE` frame for each tear.
742
764
  *
@@ -750,7 +772,7 @@ export declare enum ModCallbackCustom {
750
772
  * function postTearInitLate(tear: EntityTear): void {}
751
773
  * ```
752
774
  */
753
- POST_TEAR_INIT_LATE = 65,
775
+ POST_TEAR_INIT_LATE = 66,
754
776
  /**
755
777
  * Fires on the second `MC_POST_TEAR_UPDATE` frame for each tear (i.e. frame 1).
756
778
  *
@@ -763,9 +785,9 @@ export declare enum ModCallbackCustom {
763
785
  * function postTearInitVeryLate(tear: EntityTear): void {}
764
786
  * ```
765
787
  */
766
- POST_TEAR_INIT_VERY_LATE = 66,
767
- POST_TNT_RENDER = 67,
768
- POST_TNT_UPDATE = 68,
788
+ POST_TEAR_INIT_VERY_LATE = 67,
789
+ POST_TNT_RENDER = 68,
790
+ POST_TNT_UPDATE = 69,
769
791
  /**
770
792
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback when a player gains or loses a new
771
793
  * transformation.
@@ -783,7 +805,7 @@ export declare enum ModCallbackCustom {
783
805
  * ): void {}
784
806
  * ```
785
807
  */
786
- POST_TRANSFORMATION = 69,
808
+ POST_TRANSFORMATION = 70,
787
809
  /**
788
810
  * Fires from `MC_ENTITY_TAKE_DMG` callback when a Wishbone or a Walnut breaks.
789
811
  *
@@ -797,7 +819,7 @@ export declare enum ModCallbackCustom {
797
819
  * ): void {}
798
820
  * ```
799
821
  */
800
- POST_TRINKET_BREAK = 70,
822
+ POST_TRINKET_BREAK = 71,
801
823
  /**
802
824
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback on the frame before a Berserk! effect ends
803
825
  * when the player is predicted to die (e.g. they currently have no health left or they took
@@ -810,7 +832,7 @@ export declare enum ModCallbackCustom {
810
832
  * function preBerserkDeath(player: EntityPlayer) {}
811
833
  * ```
812
834
  */
813
- PRE_BERSERK_DEATH = 71,
835
+ PRE_BERSERK_DEATH = 72,
814
836
  /**
815
837
  * Fires from the `MC_POST_PLAYER_FATAL_DAMAGE` callback when a player is about to die. If you
816
838
  * want to initiate a custom revival, return an integer that corresponds to the item or type of
@@ -823,7 +845,7 @@ export declare enum ModCallbackCustom {
823
845
  * function preCustomRevive(player: EntityPlayer) {}
824
846
  * ```
825
847
  */
826
- PRE_CUSTOM_REVIVE = 72,
848
+ PRE_CUSTOM_REVIVE = 73,
827
849
  /**
828
850
  * Fires from the `MC_POST_PEFFECT_UPDATE` callback when an item becomes queued (i.e. when the
829
851
  * player begins to hold the item above their head).
@@ -842,7 +864,7 @@ export declare enum ModCallbackCustom {
842
864
  * ): void {}
843
865
  * ```
844
866
  */
845
- PRE_ITEM_PICKUP = 73,
867
+ PRE_ITEM_PICKUP = 74,
846
868
  /**
847
869
  * Fires on the `MC_POST_RENDER` frame before the player is taken to a new floor. Only fires when
848
870
  * a player jumps into a trapdoor or enters a heaven door (beam of light). Does not fire on the
@@ -856,5 +878,5 @@ export declare enum ModCallbackCustom {
856
878
  * function preNewLevel(player: EntityPlayer): void {}
857
879
  * ```
858
880
  */
859
- PRE_NEW_LEVEL = 74
881
+ PRE_NEW_LEVEL = 75
860
882
  }
@@ -80,80 +80,82 @@ ____exports.ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED = 35
80
80
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED] = "POST_PEFFECT_UPDATE_REORDERED"
81
81
  ____exports.ModCallbackCustom.POST_PICKUP_COLLECT = 36
82
82
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PICKUP_COLLECT] = "POST_PICKUP_COLLECT"
83
- ____exports.ModCallbackCustom.POST_PICKUP_INIT_LATE = 37
83
+ ____exports.ModCallbackCustom.POST_PICKUP_INIT_FIRST = 37
84
+ ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PICKUP_INIT_FIRST] = "POST_PICKUP_INIT_FIRST"
85
+ ____exports.ModCallbackCustom.POST_PICKUP_INIT_LATE = 38
84
86
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PICKUP_INIT_LATE] = "POST_PICKUP_INIT_LATE"
85
- ____exports.ModCallbackCustom.POST_PICKUP_STATE_CHANGED = 38
87
+ ____exports.ModCallbackCustom.POST_PICKUP_STATE_CHANGED = 39
86
88
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PICKUP_STATE_CHANGED] = "POST_PICKUP_STATE_CHANGED"
87
- ____exports.ModCallbackCustom.POST_PIT_RENDER = 39
89
+ ____exports.ModCallbackCustom.POST_PIT_RENDER = 40
88
90
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PIT_RENDER] = "POST_PIT_RENDER"
89
- ____exports.ModCallbackCustom.POST_PIT_UPDATE = 40
91
+ ____exports.ModCallbackCustom.POST_PIT_UPDATE = 41
90
92
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PIT_UPDATE] = "POST_PIT_UPDATE"
91
- ____exports.ModCallbackCustom.POST_PLAYER_CHANGE_HEALTH = 41
93
+ ____exports.ModCallbackCustom.POST_PLAYER_CHANGE_HEALTH = 42
92
94
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_CHANGE_HEALTH] = "POST_PLAYER_CHANGE_HEALTH"
93
- ____exports.ModCallbackCustom.POST_PLAYER_CHANGE_TYPE = 42
95
+ ____exports.ModCallbackCustom.POST_PLAYER_CHANGE_TYPE = 43
94
96
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_CHANGE_TYPE] = "POST_PLAYER_CHANGE_TYPE"
95
- ____exports.ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE = 43
97
+ ____exports.ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE = 44
96
98
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE] = "POST_PLAYER_FATAL_DAMAGE"
97
- ____exports.ModCallbackCustom.POST_PLAYER_INIT_LATE = 44
99
+ ____exports.ModCallbackCustom.POST_PLAYER_INIT_LATE = 45
98
100
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_INIT_LATE] = "POST_PLAYER_INIT_LATE"
99
- ____exports.ModCallbackCustom.POST_PLAYER_INIT_REORDERED = 45
101
+ ____exports.ModCallbackCustom.POST_PLAYER_INIT_REORDERED = 46
100
102
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_INIT_REORDERED] = "POST_PLAYER_INIT_REORDERED"
101
- ____exports.ModCallbackCustom.POST_PLAYER_RENDER_REORDERED = 46
103
+ ____exports.ModCallbackCustom.POST_PLAYER_RENDER_REORDERED = 47
102
104
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_RENDER_REORDERED] = "POST_PLAYER_RENDER_REORDERED"
103
- ____exports.ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED = 47
105
+ ____exports.ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED = 48
104
106
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED] = "POST_PLAYER_UPDATE_REORDERED"
105
- ____exports.ModCallbackCustom.POST_POOP_RENDER = 48
107
+ ____exports.ModCallbackCustom.POST_POOP_RENDER = 49
106
108
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_POOP_RENDER] = "POST_POOP_RENDER"
107
- ____exports.ModCallbackCustom.POST_POOP_UPDATE = 49
109
+ ____exports.ModCallbackCustom.POST_POOP_UPDATE = 50
108
110
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_POOP_UPDATE] = "POST_POOP_UPDATE"
109
- ____exports.ModCallbackCustom.POST_PRESSURE_PLATE_RENDER = 50
111
+ ____exports.ModCallbackCustom.POST_PRESSURE_PLATE_RENDER = 51
110
112
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PRESSURE_PLATE_RENDER] = "POST_PRESSURE_PLATE_RENDER"
111
- ____exports.ModCallbackCustom.POST_PRESSURE_PLATE_UPDATE = 51
113
+ ____exports.ModCallbackCustom.POST_PRESSURE_PLATE_UPDATE = 52
112
114
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PRESSURE_PLATE_UPDATE] = "POST_PRESSURE_PLATE_UPDATE"
113
- ____exports.ModCallbackCustom.POST_PROJECTILE_INIT_LATE = 52
115
+ ____exports.ModCallbackCustom.POST_PROJECTILE_INIT_LATE = 53
114
116
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PROJECTILE_INIT_LATE] = "POST_PROJECTILE_INIT_LATE"
115
- ____exports.ModCallbackCustom.POST_PURCHASE = 53
117
+ ____exports.ModCallbackCustom.POST_PURCHASE = 54
116
118
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_PURCHASE] = "POST_PURCHASE"
117
- ____exports.ModCallbackCustom.POST_ROCK_RENDER = 54
119
+ ____exports.ModCallbackCustom.POST_ROCK_RENDER = 55
118
120
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_ROCK_RENDER] = "POST_ROCK_RENDER"
119
- ____exports.ModCallbackCustom.POST_ROCK_UPDATE = 55
121
+ ____exports.ModCallbackCustom.POST_ROCK_UPDATE = 56
120
122
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_ROCK_UPDATE] = "POST_ROCK_UPDATE"
121
- ____exports.ModCallbackCustom.POST_ROOM_CLEAR_CHANGED = 56
123
+ ____exports.ModCallbackCustom.POST_ROOM_CLEAR_CHANGED = 57
122
124
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_ROOM_CLEAR_CHANGED] = "POST_ROOM_CLEAR_CHANGED"
123
- ____exports.ModCallbackCustom.POST_SACRIFICE = 57
125
+ ____exports.ModCallbackCustom.POST_SACRIFICE = 58
124
126
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SACRIFICE] = "POST_SACRIFICE"
125
- ____exports.ModCallbackCustom.POST_SLOT_ANIMATION_CHANGED = 58
127
+ ____exports.ModCallbackCustom.POST_SLOT_ANIMATION_CHANGED = 59
126
128
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SLOT_ANIMATION_CHANGED] = "POST_SLOT_ANIMATION_CHANGED"
127
- ____exports.ModCallbackCustom.POST_SLOT_DESTROYED = 59
129
+ ____exports.ModCallbackCustom.POST_SLOT_DESTROYED = 60
128
130
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SLOT_DESTROYED] = "POST_SLOT_DESTROYED"
129
- ____exports.ModCallbackCustom.POST_SLOT_INIT = 60
131
+ ____exports.ModCallbackCustom.POST_SLOT_INIT = 61
130
132
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SLOT_INIT] = "POST_SLOT_INIT"
131
- ____exports.ModCallbackCustom.POST_SLOT_RENDER = 61
133
+ ____exports.ModCallbackCustom.POST_SLOT_RENDER = 62
132
134
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SLOT_RENDER] = "POST_SLOT_RENDER"
133
- ____exports.ModCallbackCustom.POST_SLOT_UPDATE = 62
135
+ ____exports.ModCallbackCustom.POST_SLOT_UPDATE = 63
134
136
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SLOT_UPDATE] = "POST_SLOT_UPDATE"
135
- ____exports.ModCallbackCustom.POST_SPIKES_RENDER = 63
137
+ ____exports.ModCallbackCustom.POST_SPIKES_RENDER = 64
136
138
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SPIKES_RENDER] = "POST_SPIKES_RENDER"
137
- ____exports.ModCallbackCustom.POST_SPIKES_UPDATE = 64
139
+ ____exports.ModCallbackCustom.POST_SPIKES_UPDATE = 65
138
140
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_SPIKES_UPDATE] = "POST_SPIKES_UPDATE"
139
- ____exports.ModCallbackCustom.POST_TEAR_INIT_LATE = 65
141
+ ____exports.ModCallbackCustom.POST_TEAR_INIT_LATE = 66
140
142
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TEAR_INIT_LATE] = "POST_TEAR_INIT_LATE"
141
- ____exports.ModCallbackCustom.POST_TEAR_INIT_VERY_LATE = 66
143
+ ____exports.ModCallbackCustom.POST_TEAR_INIT_VERY_LATE = 67
142
144
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TEAR_INIT_VERY_LATE] = "POST_TEAR_INIT_VERY_LATE"
143
- ____exports.ModCallbackCustom.POST_TNT_RENDER = 67
145
+ ____exports.ModCallbackCustom.POST_TNT_RENDER = 68
144
146
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TNT_RENDER] = "POST_TNT_RENDER"
145
- ____exports.ModCallbackCustom.POST_TNT_UPDATE = 68
147
+ ____exports.ModCallbackCustom.POST_TNT_UPDATE = 69
146
148
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TNT_UPDATE] = "POST_TNT_UPDATE"
147
- ____exports.ModCallbackCustom.POST_TRANSFORMATION = 69
149
+ ____exports.ModCallbackCustom.POST_TRANSFORMATION = 70
148
150
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TRANSFORMATION] = "POST_TRANSFORMATION"
149
- ____exports.ModCallbackCustom.POST_TRINKET_BREAK = 70
151
+ ____exports.ModCallbackCustom.POST_TRINKET_BREAK = 71
150
152
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.POST_TRINKET_BREAK] = "POST_TRINKET_BREAK"
151
- ____exports.ModCallbackCustom.PRE_BERSERK_DEATH = 71
153
+ ____exports.ModCallbackCustom.PRE_BERSERK_DEATH = 72
152
154
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.PRE_BERSERK_DEATH] = "PRE_BERSERK_DEATH"
153
- ____exports.ModCallbackCustom.PRE_CUSTOM_REVIVE = 72
155
+ ____exports.ModCallbackCustom.PRE_CUSTOM_REVIVE = 73
154
156
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.PRE_CUSTOM_REVIVE] = "PRE_CUSTOM_REVIVE"
155
- ____exports.ModCallbackCustom.PRE_ITEM_PICKUP = 73
157
+ ____exports.ModCallbackCustom.PRE_ITEM_PICKUP = 74
156
158
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.PRE_ITEM_PICKUP] = "PRE_ITEM_PICKUP"
157
- ____exports.ModCallbackCustom.PRE_NEW_LEVEL = 74
159
+ ____exports.ModCallbackCustom.PRE_NEW_LEVEL = 75
158
160
  ____exports.ModCallbackCustom[____exports.ModCallbackCustom.PRE_NEW_LEVEL] = "PRE_NEW_LEVEL"
159
161
  return ____exports
@@ -0,0 +1,3 @@
1
+ /// <reference types="isaac-typescript-definitions" />
2
+ /** Helper function to find out how large a bomb explosion is based on the damage inflicted. */
3
+ export declare function getBombRadiusFromDamage(damage: float): float;
@@ -0,0 +1,12 @@
1
+ local ____exports = {}
2
+ --- Helper function to find out how large a bomb explosion is based on the damage inflicted.
3
+ function ____exports.getBombRadiusFromDamage(self, damage)
4
+ if damage > 175 then
5
+ return 105
6
+ end
7
+ if damage <= 140 then
8
+ return 75
9
+ end
10
+ return 90
11
+ end
12
+ return ____exports
@@ -52,13 +52,13 @@ export declare function getCollectibleGfxFilename(collectibleType: CollectibleTy
52
52
  * and the pedestal pushed to an adjacent tile, but this case should be extremely rare.)
53
53
  * - Mega Chests spawn two collectibles on the exact same position. However, both of them will have
54
54
  * different InitSeeds, so this is not a problem for this indexing scheme.
55
- * - The indexing scheme used is different for collectibles that are inside of a Treasure Room, in
56
- * order to handle the case of the player seeing the same collectible again in a post-Ascent
57
- * Treasure Room. A 5-tuple of stage, stage type, grid index, SubType, and InitSeed is used in
58
- * this case. (Using the room list index or the room grid index is not suitable for this purpose,
59
- * since both of these values can change in the post-Ascent Treasure Room.) Even though there can
60
- * be two Treasure Rooms on an XL floor, both Treasure Rooms should not have collectibles with the
61
- * same grid index, Subtype, and InitSeed.
55
+ * - The indexing scheme used is different for collectibles that are inside of a Treasure Room or
56
+ * Boss Room, in order to handle the case of the player seeing the same collectible again in a
57
+ * post-Ascent Treasure Room or Boss Room. A 5-tuple of stage, stage type, grid index, SubType,
58
+ * and InitSeed is used in this case. (Using the room list index or the room grid index is not
59
+ * suitable for this purpose, since both of these values can change in the post-Ascent rooms.)
60
+ * Even though Treasure Rooms and Boss Rooms are grouped together in this scheme, there probably
61
+ * will not be collectibles with the same grid index, SubType, and InitSeed.
62
62
  */
63
63
  export declare function getCollectibleIndex(collectible: EntityPickup): CollectibleIndex;
64
64
  /**
@@ -176,13 +176,13 @@ end
176
176
  -- and the pedestal pushed to an adjacent tile, but this case should be extremely rare.)
177
177
  -- - Mega Chests spawn two collectibles on the exact same position. However, both of them will have
178
178
  -- different InitSeeds, so this is not a problem for this indexing scheme.
179
- -- - The indexing scheme used is different for collectibles that are inside of a Treasure Room, in
180
- -- order to handle the case of the player seeing the same collectible again in a post-Ascent
181
- -- Treasure Room. A 5-tuple of stage, stage type, grid index, SubType, and InitSeed is used in
182
- -- this case. (Using the room list index or the room grid index is not suitable for this purpose,
183
- -- since both of these values can change in the post-Ascent Treasure Room.) Even though there can
184
- -- be two Treasure Rooms on an XL floor, both Treasure Rooms should not have collectibles with the
185
- -- same grid index, Subtype, and InitSeed.
179
+ -- - The indexing scheme used is different for collectibles that are inside of a Treasure Room or
180
+ -- Boss Room, in order to handle the case of the player seeing the same collectible again in a
181
+ -- post-Ascent Treasure Room or Boss Room. A 5-tuple of stage, stage type, grid index, SubType,
182
+ -- and InitSeed is used in this case. (Using the room list index or the room grid index is not
183
+ -- suitable for this purpose, since both of these values can change in the post-Ascent rooms.)
184
+ -- Even though Treasure Rooms and Boss Rooms are grouped together in this scheme, there probably
185
+ -- will not be collectibles with the same grid index, SubType, and InitSeed.
186
186
  function ____exports.getCollectibleIndex(self, collectible)
187
187
  if not isCollectible(nil, collectible) then
188
188
  local entityID = getEntityID(nil, collectible)
@@ -195,7 +195,7 @@ function ____exports.getCollectibleIndex(self, collectible)
195
195
  local roomType = room:GetType()
196
196
  local gridIndex = room:GetGridIndex(collectible.Position)
197
197
  local roomListIndex = getRoomListIndex(nil)
198
- if roomType == RoomType.TREASURE then
198
+ if roomType == RoomType.TREASURE or roomType == RoomType.BOSS then
199
199
  return (((((((tostring(stage) .. ",") .. tostring(stageType)) .. ",") .. tostring(gridIndex)) .. ",") .. tostring(collectible.SubType)) .. ",") .. tostring(collectible.InitSeed)
200
200
  end
201
201
  return (((((tostring(roomListIndex) .. ",") .. tostring(gridIndex)) .. ",") .. tostring(collectible.SubType)) .. ",") .. tostring(collectible.InitSeed)
@@ -1,4 +1,11 @@
1
1
  import { Direction } from "isaac-typescript-definitions";
2
+ /**
3
+ * Helper function to convert the degrees of an angle to the `Direction` enum.
4
+ *
5
+ * Note that this function considers 0 degrees to be pointing to the right, which is unusual because
6
+ * 0 normally corresponds to up. (This corresponds to how the `Vector.GetAngleDegrees` method
7
+ * works.)
8
+ */
2
9
  export declare function angleToDirection(angleDegrees: int): Direction;
3
10
  export declare function directionToDegrees(direction: Direction): int;
4
11
  export declare function directionToVector(direction: Direction): Vector;
@@ -7,6 +7,11 @@ local ____directionToDegrees = require("objects.directionToDegrees")
7
7
  local DIRECTION_TO_DEGREES = ____directionToDegrees.DIRECTION_TO_DEGREES
8
8
  local ____directionToVector = require("objects.directionToVector")
9
9
  local DIRECTION_TO_VECTOR = ____directionToVector.DIRECTION_TO_VECTOR
10
+ --- Helper function to convert the degrees of an angle to the `Direction` enum.
11
+ --
12
+ -- Note that this function considers 0 degrees to be pointing to the right, which is unusual because
13
+ -- 0 normally corresponds to up. (This corresponds to how the `Vector.GetAngleDegrees` method
14
+ -- works.)
10
15
  function ____exports.angleToDirection(self, angleDegrees)
11
16
  local positiveDegrees = angleDegrees
12
17
  while positiveDegrees < 0 do
@@ -14,18 +19,18 @@ function ____exports.angleToDirection(self, angleDegrees)
14
19
  end
15
20
  local normalizedDegrees = positiveDegrees % 360
16
21
  if normalizedDegrees < 45 then
17
- return Direction.UP
22
+ return Direction.RIGHT
18
23
  end
19
24
  if normalizedDegrees < 135 then
20
- return Direction.RIGHT
25
+ return Direction.DOWN
21
26
  end
22
27
  if normalizedDegrees < 225 then
23
- return Direction.DOWN
28
+ return Direction.LEFT
24
29
  end
25
30
  if normalizedDegrees < 315 then
26
- return Direction.RIGHT
31
+ return Direction.UP
27
32
  end
28
- return Direction.UP
33
+ return Direction.RIGHT
29
34
  end
30
35
  function ____exports.directionToDegrees(self, direction)
31
36
  return DIRECTION_TO_DEGREES[direction]
@@ -100,6 +100,8 @@ export declare function getPlayerCollectibleCount(player: EntityPlayer, ...colle
100
100
  * the player has.
101
101
  */
102
102
  export declare function getPlayerCollectibleMap(player: EntityPlayer): Map<CollectibleType, int>;
103
+ /** Helper function to get the player from a tear, laser, bomb, etc. */
104
+ export declare function getPlayerFromTear(entity: Entity): EntityPlayer | undefined;
103
105
  /**
104
106
  * Returns the number of red hearts that the player has, excluding any rotten hearts. For example,
105
107
  * if the player has one full black heart, one full soul heart, and one half black heart, this
@@ -207,6 +209,11 @@ export declare function isBethany(player: EntityPlayer): boolean;
207
209
  * for. Returns true if the player is any of the supplied characters.
208
210
  */
209
211
  export declare function isCharacter(player: EntityPlayer, ...characters: PlayerType[]): boolean;
212
+ /**
213
+ * Helper function to see if a damage source is from a player. Use this instead of comparing to the
214
+ * entity directly because it takes familiars into account.
215
+ */
216
+ export declare function isDamageFromPlayer(damageSource: Entity): boolean;
210
217
  /**
211
218
  * Helper function for detecting when a player is Eden or Tainted Eden. Useful for situations where
212
219
  * you want to know if the starting stats were randomized, for example.
@@ -15,6 +15,7 @@ local ActiveSlot = ____isaac_2Dtypescript_2Ddefinitions.ActiveSlot
15
15
  local CacheFlag = ____isaac_2Dtypescript_2Ddefinitions.CacheFlag
16
16
  local Challenge = ____isaac_2Dtypescript_2Ddefinitions.Challenge
17
17
  local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
18
+ local FamiliarVariant = ____isaac_2Dtypescript_2Ddefinitions.FamiliarVariant
18
19
  local NullItemID = ____isaac_2Dtypescript_2Ddefinitions.NullItemID
19
20
  local PlayerForm = ____isaac_2Dtypescript_2Ddefinitions.PlayerForm
20
21
  local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
@@ -377,6 +378,30 @@ function ____exports.getPlayerCollectibleMap(self, player)
377
378
  end
378
379
  return collectibleMap
379
380
  end
381
+ --- Helper function to get the player from a tear, laser, bomb, etc.
382
+ function ____exports.getPlayerFromTear(self, entity)
383
+ if entity.Parent ~= nil then
384
+ local player = entity.Parent:ToPlayer()
385
+ if player ~= nil then
386
+ return player
387
+ end
388
+ local familiar = entity.Parent:ToFamiliar()
389
+ if familiar ~= nil and familiar.Variant == FamiliarVariant.INCUBUS then
390
+ return familiar.Player
391
+ end
392
+ end
393
+ if entity.SpawnerEntity ~= nil then
394
+ local player = entity.SpawnerEntity:ToPlayer()
395
+ if player ~= nil then
396
+ return player
397
+ end
398
+ local familiar = entity.SpawnerEntity:ToFamiliar()
399
+ if familiar ~= nil and familiar.Variant == FamiliarVariant.INCUBUS then
400
+ return familiar.Player
401
+ end
402
+ end
403
+ return nil
404
+ end
380
405
  --- Returns the number of red hearts that the player has, excluding any rotten hearts. For example,
381
406
  -- if the player has one full black heart, one full soul heart, and one half black heart, this
382
407
  -- function returns 3.
@@ -567,6 +592,16 @@ function ____exports.isBethany(self, player)
567
592
  local character = player:GetPlayerType()
568
593
  return character == PlayerType.BETHANY or character == PlayerType.BETHANY_B
569
594
  end
595
+ --- Helper function to see if a damage source is from a player. Use this instead of comparing to the
596
+ -- entity directly because it takes familiars into account.
597
+ function ____exports.isDamageFromPlayer(self, damageSource)
598
+ local player = damageSource:ToPlayer()
599
+ if player ~= nil then
600
+ return true
601
+ end
602
+ local indirectPlayer = ____exports.getPlayerFromTear(nil, damageSource)
603
+ return indirectPlayer ~= nil
604
+ end
570
605
  --- Helper function for detecting when a player is Eden or Tainted Eden. Useful for situations where
571
606
  -- you want to know if the starting stats were randomized, for example.
572
607
  function ____exports.isEden(self, player)
@@ -684,9 +719,9 @@ function ____exports.setActiveItem(self, player, collectibleType, activeSlot, ch
684
719
  itemPool:RemoveCollectible(collectibleType)
685
720
  end
686
721
  repeat
687
- local ____switch113 = activeSlot
688
- local ____cond113 = ____switch113 == ActiveSlot.PRIMARY
689
- if ____cond113 then
722
+ local ____switch122 = activeSlot
723
+ local ____cond122 = ____switch122 == ActiveSlot.PRIMARY
724
+ if ____cond122 then
690
725
  do
691
726
  if primaryCollectibleType ~= CollectibleType.NULL then
692
727
  player:RemoveCollectible(primaryCollectibleType)
@@ -695,8 +730,8 @@ function ____exports.setActiveItem(self, player, collectibleType, activeSlot, ch
695
730
  break
696
731
  end
697
732
  end
698
- ____cond113 = ____cond113 or ____switch113 == ActiveSlot.SECONDARY
699
- if ____cond113 then
733
+ ____cond122 = ____cond122 or ____switch122 == ActiveSlot.SECONDARY
734
+ if ____cond122 then
700
735
  do
701
736
  if primaryCollectibleType ~= CollectibleType.NULL then
702
737
  player:RemoveCollectible(primaryCollectibleType)
@@ -711,16 +746,16 @@ function ____exports.setActiveItem(self, player, collectibleType, activeSlot, ch
711
746
  break
712
747
  end
713
748
  end
714
- ____cond113 = ____cond113 or ____switch113 == ActiveSlot.POCKET
715
- if ____cond113 then
749
+ ____cond122 = ____cond122 or ____switch122 == ActiveSlot.POCKET
750
+ if ____cond122 then
716
751
  do
717
752
  player:SetPocketActiveItem(collectibleType, activeSlot, keepInPools)
718
753
  player:SetActiveCharge(charge, activeSlot)
719
754
  break
720
755
  end
721
756
  end
722
- ____cond113 = ____cond113 or ____switch113 == ActiveSlot.POCKET_SINGLE_USE
723
- if ____cond113 then
757
+ ____cond122 = ____cond122 or ____switch122 == ActiveSlot.POCKET_SINGLE_USE
758
+ if ____cond122 then
724
759
  do
725
760
  player:SetPocketActiveItem(collectibleType, activeSlot, keepInPools)
726
761
  break
@@ -12,6 +12,8 @@ export declare function addPlayerHealthType(player: EntityPlayer, healthType: He
12
12
  */
13
13
  export declare function getPlayerHealth(player: EntityPlayer): PlayerHealth;
14
14
  export declare function getPlayerHealthType(player: EntityPlayer, healthType: HealthType): int;
15
+ export declare function playerConvertBlackHeartsToSoulHearts(player: EntityPlayer): void;
16
+ export declare function playerConvertSoulHeartsToBlackHearts(player: EntityPlayer): void;
15
17
  export declare function removeAllPlayerHealth(player: EntityPlayer): void;
16
18
  /**
17
19
  * Helper function to set a player's health to a specific state. You can use this in combination
@@ -1,4 +1,5 @@
1
1
  local ____lualib = require("lualib_bundle")
2
+ local __TS__ArrayMap = ____lualib.__TS__ArrayMap
2
3
  local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
3
4
  local ____exports = {}
4
5
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
@@ -16,6 +17,79 @@ local isCharacter = ____player.isCharacter
16
17
  local ____utils = require("functions.utils")
17
18
  local ensureAllCases = ____utils.ensureAllCases
18
19
  local ____repeat = ____utils["repeat"]
20
+ function ____exports.removeAllPlayerHealth(self, player)
21
+ local goldenHearts = player:GetGoldenHearts()
22
+ local eternalHearts = player:GetEternalHearts()
23
+ local boneHearts = player:GetBoneHearts()
24
+ local brokenHearts = player:GetBrokenHearts()
25
+ player:AddGoldenHearts(goldenHearts * -1)
26
+ player:AddEternalHearts(eternalHearts * -1)
27
+ player:AddBoneHearts(boneHearts * -1)
28
+ player:AddBrokenHearts(brokenHearts * -1)
29
+ player:AddMaxHearts(MAX_PLAYER_HEART_CONTAINERS * -2, true)
30
+ player:AddSoulHearts(MAX_PLAYER_HEART_CONTAINERS * -2)
31
+ if isCharacter(nil, player, PlayerType.THE_SOUL) then
32
+ local forgotten = player:GetSubPlayer()
33
+ if forgotten ~= nil then
34
+ local forgottenBoneHearts = forgotten:GetBoneHearts()
35
+ forgotten:AddBoneHearts(forgottenBoneHearts * -1)
36
+ end
37
+ end
38
+ end
39
+ --- Helper function to set a player's health to a specific state. You can use this in combination
40
+ -- with the `getPlayerHealth` function to restore the player's health back to a certain
41
+ -- configuration at a later time.
42
+ --
43
+ -- Based on the `REVEL.LoadHealth` function in the Revelations mod.
44
+ function ____exports.setPlayerHealth(self, player, playerHealth)
45
+ local character = player:GetPlayerType()
46
+ local subPlayer = player:GetSubPlayer()
47
+ ____exports.removeAllPlayerHealth(nil, player)
48
+ if character == PlayerType.THE_SOUL and subPlayer ~= nil then
49
+ subPlayer:AddMaxHearts(playerHealth.maxHearts, false)
50
+ else
51
+ player:AddMaxHearts(playerHealth.maxHearts, false)
52
+ end
53
+ player:AddEternalHearts(playerHealth.eternalHearts)
54
+ local soulHeartsRemaining = playerHealth.soulHearts
55
+ __TS__ArrayForEach(
56
+ playerHealth.soulHeartTypes,
57
+ function(____, heartType, i)
58
+ local isHalf = playerHealth.soulHearts + playerHealth.boneHearts * 2 < (i + 1) * 2
59
+ local addAmount = 2
60
+ if isHalf or heartType == HeartSubType.BONE or soulHeartsRemaining < 2 then
61
+ addAmount = 1
62
+ end
63
+ if heartType == HeartSubType.SOUL then
64
+ player:AddSoulHearts(addAmount)
65
+ soulHeartsRemaining = soulHeartsRemaining - addAmount
66
+ elseif heartType == HeartSubType.BLACK then
67
+ player:AddBlackHearts(addAmount)
68
+ soulHeartsRemaining = soulHeartsRemaining - addAmount
69
+ elseif heartType == HeartSubType.BONE then
70
+ player:AddBoneHearts(addAmount)
71
+ end
72
+ end
73
+ )
74
+ player:AddRottenHearts(playerHealth.rottenHearts)
75
+ ____repeat(
76
+ nil,
77
+ playerHealth.hearts,
78
+ function()
79
+ player:AddHearts(1)
80
+ if character == PlayerType.MAGDALENE_B then
81
+ player:AddHearts(-1)
82
+ end
83
+ end
84
+ )
85
+ player:AddGoldenHearts(playerHealth.goldenHearts)
86
+ player:AddBrokenHearts(playerHealth.brokenHearts)
87
+ if character == PlayerType.BETHANY then
88
+ player:SetSoulCharge(playerHealth.soulCharges)
89
+ elseif character == PlayerType.BETHANY_B then
90
+ player:SetBloodCharge(playerHealth.bloodCharges)
91
+ end
92
+ end
19
93
  function ____exports.addPlayerHealthType(self, player, healthType, numHearts)
20
94
  repeat
21
95
  local ____switch3 = healthType
@@ -220,77 +294,22 @@ function ____exports.getPlayerHealthType(self, player, healthType)
220
294
  end
221
295
  until true
222
296
  end
223
- function ____exports.removeAllPlayerHealth(self, player)
224
- local goldenHearts = player:GetGoldenHearts()
225
- local eternalHearts = player:GetEternalHearts()
226
- local boneHearts = player:GetBoneHearts()
227
- local brokenHearts = player:GetBrokenHearts()
228
- player:AddGoldenHearts(goldenHearts * -1)
229
- player:AddEternalHearts(eternalHearts * -1)
230
- player:AddBoneHearts(boneHearts * -1)
231
- player:AddBrokenHearts(brokenHearts * -1)
232
- player:AddMaxHearts(MAX_PLAYER_HEART_CONTAINERS * -2, true)
233
- player:AddSoulHearts(MAX_PLAYER_HEART_CONTAINERS * -2)
234
- if isCharacter(nil, player, PlayerType.THE_SOUL) then
235
- local forgotten = player:GetSubPlayer()
236
- if forgotten ~= nil then
237
- local forgottenBoneHearts = forgotten:GetBoneHearts()
238
- forgotten:AddBoneHearts(forgottenBoneHearts * -1)
239
- end
240
- end
241
- end
242
- --- Helper function to set a player's health to a specific state. You can use this in combination
243
- -- with the `getPlayerHealth` function to restore the player's health back to a certain
244
- -- configuration at a later time.
245
- --
246
- -- Based on the `REVEL.LoadHealth` function in the Revelations mod.
247
- function ____exports.setPlayerHealth(self, player, playerHealth)
248
- local character = player:GetPlayerType()
249
- local subPlayer = player:GetSubPlayer()
297
+ function ____exports.playerConvertBlackHeartsToSoulHearts(self, player)
298
+ local playerHealth = ____exports.getPlayerHealth(nil, player)
250
299
  ____exports.removeAllPlayerHealth(nil, player)
251
- if character == PlayerType.THE_SOUL and subPlayer ~= nil then
252
- subPlayer:AddMaxHearts(playerHealth.maxHearts, false)
253
- else
254
- player:AddMaxHearts(playerHealth.maxHearts, false)
255
- end
256
- player:AddEternalHearts(playerHealth.eternalHearts)
257
- local soulHeartsRemaining = playerHealth.soulHearts
258
- __TS__ArrayForEach(
300
+ playerHealth.soulHeartTypes = __TS__ArrayMap(
259
301
  playerHealth.soulHeartTypes,
260
- function(____, heartType, i)
261
- local isHalf = playerHealth.soulHearts + playerHealth.boneHearts * 2 < (i + 1) * 2
262
- local addAmount = 2
263
- if isHalf or heartType == HeartSubType.BONE or soulHeartsRemaining < 2 then
264
- addAmount = 1
265
- end
266
- if heartType == HeartSubType.SOUL then
267
- player:AddSoulHearts(addAmount)
268
- soulHeartsRemaining = soulHeartsRemaining - addAmount
269
- elseif heartType == HeartSubType.BLACK then
270
- player:AddBlackHearts(addAmount)
271
- soulHeartsRemaining = soulHeartsRemaining - addAmount
272
- elseif heartType == HeartSubType.BONE then
273
- player:AddBoneHearts(addAmount)
274
- end
275
- end
302
+ function(____, soulHeartType) return soulHeartType == HeartSubType.BLACK and HeartSubType.SOUL or soulHeartType end
276
303
  )
277
- player:AddRottenHearts(playerHealth.rottenHearts)
278
- ____repeat(
279
- nil,
280
- playerHealth.hearts,
281
- function()
282
- player:AddHearts(1)
283
- if character == PlayerType.MAGDALENE_B then
284
- player:AddHearts(-1)
285
- end
286
- end
304
+ ____exports.setPlayerHealth(nil, player, playerHealth)
305
+ end
306
+ function ____exports.playerConvertSoulHeartsToBlackHearts(self, player)
307
+ local playerHealth = ____exports.getPlayerHealth(nil, player)
308
+ ____exports.removeAllPlayerHealth(nil, player)
309
+ playerHealth.soulHeartTypes = __TS__ArrayMap(
310
+ playerHealth.soulHeartTypes,
311
+ function(____, soulHeartType) return soulHeartType == HeartSubType.SOUL and HeartSubType.BLACK or soulHeartType end
287
312
  )
288
- player:AddGoldenHearts(playerHealth.goldenHearts)
289
- player:AddBrokenHearts(playerHealth.brokenHearts)
290
- if character == PlayerType.BETHANY then
291
- player:SetSoulCharge(playerHealth.soulCharges)
292
- elseif character == PlayerType.BETHANY_B then
293
- player:SetBloodCharge(playerHealth.bloodCharges)
294
- end
313
+ ____exports.setPlayerHealth(nil, player, playerHealth)
295
314
  end
296
315
  return ____exports
package/index.d.ts CHANGED
@@ -30,6 +30,7 @@ export { getTaintedLazarusSubPlayer } from "./features/taintedLazarusPlayers";
30
30
  export * from "./functions/array";
31
31
  export * from "./functions/benchmark";
32
32
  export * from "./functions/bitwise";
33
+ export * from "./functions/bombs";
33
34
  export * from "./functions/boss";
34
35
  export * from "./functions/cacheFlag";
35
36
  export * from "./functions/cards";
package/index.lua CHANGED
@@ -242,6 +242,14 @@ do
242
242
  end
243
243
  end
244
244
  end
245
+ do
246
+ local ____export = require("functions.bombs")
247
+ for ____exportKey, ____exportValue in pairs(____export) do
248
+ if ____exportKey ~= "default" then
249
+ ____exports[____exportKey] = ____exportValue
250
+ end
251
+ end
252
+ end
245
253
  do
246
254
  local ____export = require("functions.boss")
247
255
  for ____exportKey, ____exportValue in pairs(____export) do
@@ -51,6 +51,8 @@ local ____postNPCStateChanged = require("callbacks.postNPCStateChanged")
51
51
  local postNPCStateChangedCallbackInit = ____postNPCStateChanged.postNPCStateChangedCallbackInit
52
52
  local ____postPickupCollect = require("callbacks.postPickupCollect")
53
53
  local postPickupCollectCallbackInit = ____postPickupCollect.postPickupCollectCallbackInit
54
+ local ____postPickupInitFirst = require("callbacks.postPickupInitFirst")
55
+ local postPickupInitFirstCallbackInit = ____postPickupInitFirst.postPickupInitFirstCallbackInit
54
56
  local ____postPickupInitLate = require("callbacks.postPickupInitLate")
55
57
  local postPickupInitLateCallbackInit = ____postPickupInitLate.postPickupInitLateCallbackInit
56
58
  local ____postPickupStateChanged = require("callbacks.postPickupStateChanged")
@@ -144,6 +146,7 @@ function ____exports.initCustomCallbacks(self, mod)
144
146
  postNPCInitLateCallbackInit(nil, mod)
145
147
  postNPCStateChangedCallbackInit(nil, mod)
146
148
  postPickupCollectCallbackInit(nil, mod)
149
+ postPickupInitFirstCallbackInit(nil, mod)
147
150
  postPickupInitLateCallbackInit(nil, mod)
148
151
  postPickupStateChangedCallbackInit(nil, mod)
149
152
  postPitRenderInit(nil, mod)
@@ -35,6 +35,7 @@ import { PostNPCInitLateRegisterParameters } from "../callbacks/subscriptions/po
35
35
  import { PostNPCStateChangedRegisterParameters } from "../callbacks/subscriptions/postNPCStateChanged";
36
36
  import { PostPEffectUpdateReorderedRegisterParameters } from "../callbacks/subscriptions/postPEffectUpdateReordered";
37
37
  import { PostPickupCollectRegisterParameters } from "../callbacks/subscriptions/postPickupCollect";
38
+ import { PostPickupInitFirstRegisterParameters } from "../callbacks/subscriptions/postPickupInitFirst";
38
39
  import { PostPickupInitLateRegisterParameters } from "../callbacks/subscriptions/postPickupInitLate";
39
40
  import { PostPickupStateChangedRegisterParameters } from "../callbacks/subscriptions/postPickupStateChanged";
40
41
  import { PostPitRenderRegisterParameters } from "../callbacks/subscriptions/postPitRender";
@@ -112,6 +113,7 @@ export interface AddCallbackParameterCustom {
112
113
  [ModCallbackCustom.POST_NPC_STATE_CHANGED]: PostNPCStateChangedRegisterParameters;
113
114
  [ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED]: PostPEffectUpdateReorderedRegisterParameters;
114
115
  [ModCallbackCustom.POST_PICKUP_COLLECT]: PostPickupCollectRegisterParameters;
116
+ [ModCallbackCustom.POST_PICKUP_INIT_FIRST]: PostPickupInitFirstRegisterParameters;
115
117
  [ModCallbackCustom.POST_PICKUP_INIT_LATE]: PostPickupInitLateRegisterParameters;
116
118
  [ModCallbackCustom.POST_PICKUP_STATE_CHANGED]: PostPickupStateChangedRegisterParameters;
117
119
  [ModCallbackCustom.POST_PIT_RENDER]: PostPitRenderRegisterParameters;
@@ -73,6 +73,8 @@ local ____postPEffectUpdateReordered = require("callbacks.subscriptions.postPEff
73
73
  local postPEffectUpdateReorderedRegister = ____postPEffectUpdateReordered.postPEffectUpdateReorderedRegister
74
74
  local ____postPickupCollect = require("callbacks.subscriptions.postPickupCollect")
75
75
  local postPickupCollectRegister = ____postPickupCollect.postPickupCollectRegister
76
+ local ____postPickupInitFirst = require("callbacks.subscriptions.postPickupInitFirst")
77
+ local postPickupInitFirstRegister = ____postPickupInitFirst.postPickupInitFirstRegister
76
78
  local ____postPickupInitLate = require("callbacks.subscriptions.postPickupInitLate")
77
79
  local postPickupInitLateRegister = ____postPickupInitLate.postPickupInitLateRegister
78
80
  local ____postPickupStateChanged = require("callbacks.subscriptions.postPickupStateChanged")
@@ -189,6 +191,7 @@ ____exports.CALLBACK_REGISTER_FUNCTIONS = {
189
191
  [ModCallbackCustom.POST_NPC_STATE_CHANGED] = postNPCStateChangedRegister,
190
192
  [ModCallbackCustom.POST_PEFFECT_UPDATE_REORDERED] = postPEffectUpdateReorderedRegister,
191
193
  [ModCallbackCustom.POST_PICKUP_COLLECT] = postPickupCollectRegister,
194
+ [ModCallbackCustom.POST_PICKUP_INIT_FIRST] = postPickupInitFirstRegister,
192
195
  [ModCallbackCustom.POST_PICKUP_INIT_LATE] = postPickupInitLateRegister,
193
196
  [ModCallbackCustom.POST_PICKUP_STATE_CHANGED] = postPickupStateChangedRegister,
194
197
  [ModCallbackCustom.POST_PIT_RENDER] = postPitRenderRegister,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",