isaacscript-common 80.2.0 → 80.2.2
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/classes/callbacks/PostItemDischarge.d.ts.map +1 -1
- package/dist/classes/callbacks/PostItemDischarge.lua +1 -3
- package/dist/classes/features/other/CustomPickups.d.ts.map +1 -1
- package/dist/classes/features/other/CustomPickups.lua +1 -3
- package/dist/classes/features/other/CustomStages.d.ts.map +1 -1
- package/dist/classes/features/other/CustomStages.lua +1 -3
- package/dist/classes/features/other/DeployJSONRoom.d.ts.map +1 -1
- package/dist/classes/features/other/DeployJSONRoom.lua +4 -4
- package/dist/classes/features/other/ModdedElementDetection.d.ts +31 -20
- package/dist/classes/features/other/ModdedElementDetection.d.ts.map +1 -1
- package/dist/classes/features/other/ModdedElementDetection.lua +23 -49
- package/dist/classes/features/other/StageHistory.d.ts.map +1 -1
- package/dist/classes/features/other/StageHistory.lua +1 -3
- package/dist/classes/features/other/extraConsoleCommands/commands.d.ts.map +1 -1
- package/dist/classes/features/other/extraConsoleCommands/commands.lua +1 -6
- package/dist/core/constantsFirstLast.d.ts +29 -6
- package/dist/core/constantsFirstLast.d.ts.map +1 -1
- package/dist/core/constantsFirstLast.lua +18 -3
- package/dist/functions/bosses.d.ts.map +1 -1
- package/dist/functions/bosses.lua +1 -3
- package/dist/functions/doors.d.ts.map +1 -1
- package/dist/functions/doors.lua +5 -7
- package/dist/functions/gridEntities.lua +1 -2
- package/dist/functions/gridEntitiesSpecific.d.ts.map +1 -1
- package/dist/functions/gridEntitiesSpecific.lua +5 -7
- package/dist/functions/nextStage.d.ts.map +1 -1
- package/dist/functions/nextStage.lua +4 -6
- package/dist/functions/npcs.d.ts.map +1 -1
- package/dist/functions/npcs.lua +3 -5
- package/dist/functions/pills.d.ts.map +1 -1
- package/dist/functions/pills.lua +8 -16
- package/dist/functions/pocketItems.d.ts.map +1 -1
- package/dist/functions/pocketItems.lua +1 -3
- package/dist/functions/rooms.d.ts.map +1 -1
- package/dist/functions/rooms.lua +13 -15
- package/dist/functions/stage.lua +2 -6
- package/dist/functions/trinkets.lua +2 -2
- package/dist/functions/types.d.ts +29 -0
- package/dist/functions/types.d.ts.map +1 -1
- package/dist/index.rollup.d.ts +56 -26
- package/dist/isaacscript-common.lua +98 -147
- package/package.json +2 -2
- package/src/classes/callbacks/PostItemDischarge.ts +1 -2
- package/src/classes/features/other/CustomPickups.ts +1 -2
- package/src/classes/features/other/CustomStages.ts +1 -4
- package/src/classes/features/other/DeployJSONRoom.ts +5 -9
- package/src/classes/features/other/ModdedElementDetection.ts +61 -77
- package/src/classes/features/other/StageHistory.ts +1 -2
- package/src/classes/features/other/extraConsoleCommands/commands.ts +2 -6
- package/src/core/constantsFirstLast.ts +29 -6
- package/src/functions/bosses.ts +1 -2
- package/src/functions/doors.ts +5 -6
- package/src/functions/gridEntities.ts +2 -2
- package/src/functions/gridEntitiesSpecific.ts +5 -6
- package/src/functions/nextStage.ts +4 -5
- package/src/functions/npcs.ts +3 -4
- package/src/functions/pills.ts +4 -6
- package/src/functions/pocketItems.ts +1 -2
- package/src/functions/rooms.ts +15 -17
- package/src/functions/stage.ts +3 -3
- package/src/functions/trinkets.ts +2 -2
- package/src/functions/types.ts +30 -0
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
calculateStageTypeRepentance,
|
|
14
14
|
onRepentanceStage,
|
|
15
15
|
} from "./stage";
|
|
16
|
-
import { asNumber } from "./types";
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Helper function to get the stage that a trapdoor or heaven door would take the player to, based
|
|
@@ -35,7 +34,7 @@ export function getNextStage(): LevelStage {
|
|
|
35
34
|
|
|
36
35
|
// First, handle the special case of being on the backwards path.
|
|
37
36
|
if (backwardsPath) {
|
|
38
|
-
const nextStage =
|
|
37
|
+
const nextStage = stage - 1;
|
|
39
38
|
return nextStage === 0 ? LevelStage.HOME : nextStage;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -55,7 +54,7 @@ export function getNextStage(): LevelStage {
|
|
|
55
54
|
case GridRoom.SECRET_EXIT: {
|
|
56
55
|
if (repentanceStage) {
|
|
57
56
|
// e.g. From Downpour 2 to Mines 1, etc.
|
|
58
|
-
return
|
|
57
|
+
return stage + 1;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
if (
|
|
@@ -114,7 +113,7 @@ export function getNextStage(): LevelStage {
|
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
// By default, go to the next floor.
|
|
117
|
-
return
|
|
116
|
+
return stage + 1;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
/**
|
|
@@ -146,7 +145,7 @@ export function getNextStageType(upwards = false): StageType {
|
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
// Second, handle the special case of being in a specific off-grid room.
|
|
149
|
-
if (roomGridIndex ===
|
|
148
|
+
if (roomGridIndex === GridRoom.SECRET_EXIT) {
|
|
150
149
|
return calculateStageTypeRepentance(nextStage);
|
|
151
150
|
}
|
|
152
151
|
|
package/src/functions/npcs.ts
CHANGED
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
import { EGGY_STATE_FRAME_OF_FINAL_SPIDER } from "../core/constants";
|
|
20
20
|
import { ReadonlySet } from "../types/ReadonlySet";
|
|
21
21
|
import { getNPCs } from "./entitiesSpecific";
|
|
22
|
-
import { asNumber } from "./types";
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* Used to filter out certain NPCs when determining of an NPC is "alive" and/or should keep the
|
|
@@ -133,7 +132,7 @@ export function isDaddyLongLegsChildStompEntity(npc: EntityNPC): boolean {
|
|
|
133
132
|
export function isDyingDump(npc: EntityNPC): boolean {
|
|
134
133
|
return (
|
|
135
134
|
npc.Type === EntityType.DUMP &&
|
|
136
|
-
npc.Variant ===
|
|
135
|
+
npc.Variant === DumpVariant.DUMP &&
|
|
137
136
|
npc.State === NPCState.SPECIAL
|
|
138
137
|
);
|
|
139
138
|
}
|
|
@@ -146,7 +145,7 @@ export function isDyingDump(npc: EntityNPC): boolean {
|
|
|
146
145
|
export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
|
|
147
146
|
return (
|
|
148
147
|
npc.Type === EntityType.HOPPER &&
|
|
149
|
-
npc.Variant ===
|
|
148
|
+
npc.Variant === HopperVariant.EGGY &&
|
|
150
149
|
npc.State === NPCState.SUICIDE &&
|
|
151
150
|
npc.StateFrame >= EGGY_STATE_FRAME_OF_FINAL_SPIDER
|
|
152
151
|
);
|
|
@@ -161,7 +160,7 @@ export function isDyingEggyWithNoSpidersLeft(npc: EntityNPC): boolean {
|
|
|
161
160
|
export function isRaglingDeathPatch(npc: EntityNPC): boolean {
|
|
162
161
|
return (
|
|
163
162
|
npc.Type === EntityType.RAGLING &&
|
|
164
|
-
npc.Variant ===
|
|
163
|
+
npc.Variant === RaglingVariant.RAG_MANS_RAGLING &&
|
|
165
164
|
// They go to `STATE_SPECIAL` when they are patches on the ground.
|
|
166
165
|
npc.State === NPCState.SPECIAL
|
|
167
166
|
);
|
package/src/functions/pills.ts
CHANGED
|
@@ -64,7 +64,7 @@ export function getFalsePHDPillEffect(pillEffect: PillEffect): PillEffect {
|
|
|
64
64
|
* corresponds to the horse pill color for blue/blue.
|
|
65
65
|
*/
|
|
66
66
|
export function getHorsePillColor(pillColor: PillColor): PillColor {
|
|
67
|
-
return
|
|
67
|
+
return pillColor + HORSE_PILL_ADJUSTMENT;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/** Helper function to get an array with every non-gold horse pill color. */
|
|
@@ -80,11 +80,9 @@ export function getHorsePillColors(): readonly PillColor[] {
|
|
|
80
80
|
* If called with a non-horse pill color, this function will return back the same color.
|
|
81
81
|
*/
|
|
82
82
|
export function getNormalPillColorFromHorse(pillColor: PillColor): PillColor {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return normalPillColor > PillColor.NULL ? normalPillColor : pillColor;
|
|
83
|
+
return isHorsePill(pillColor)
|
|
84
|
+
? asPillColor(pillColor - HORSE_PILL_ADJUSTMENT)
|
|
85
|
+
: pillColor;
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
/** Helper function to get an array with every non-gold and non-horse pill color. */
|
|
@@ -10,7 +10,6 @@ import { POCKET_ITEM_SLOT_VALUES } from "../arrays/cachedEnumValues";
|
|
|
10
10
|
import { PocketItemType } from "../enums/PocketItemType";
|
|
11
11
|
import type { PocketItemDescription } from "../interfaces/PocketItemDescription";
|
|
12
12
|
import { isCharacter } from "./players";
|
|
13
|
-
import { asNumber } from "./types";
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Helper function to get the `PocketItemSlot` that the player's pocket active collectible item is
|
|
@@ -129,7 +128,7 @@ export function getPocketItems(player: EntityPlayer): PocketItemDescription[] {
|
|
|
129
128
|
});
|
|
130
129
|
}
|
|
131
130
|
|
|
132
|
-
if (
|
|
131
|
+
if (slot + 1 === maxPocketItems) {
|
|
133
132
|
break;
|
|
134
133
|
}
|
|
135
134
|
}
|
package/src/functions/rooms.ts
CHANGED
|
@@ -48,7 +48,6 @@ import {
|
|
|
48
48
|
import { is2x1RoomShape, isBigRoomShape, isLRoomShape } from "./roomShape";
|
|
49
49
|
import { reloadRoom } from "./roomTransition";
|
|
50
50
|
import { getGotoCommand } from "./stage";
|
|
51
|
-
import { asNumber } from "./types";
|
|
52
51
|
import { assertDefined, iRange } from "./utils";
|
|
53
52
|
|
|
54
53
|
const SECRET_ROOM_TYPES = new ReadonlySet([
|
|
@@ -599,7 +598,7 @@ export function isAllRoomsClear(
|
|
|
599
598
|
export function isAngelShop(roomData: RoomConfig): boolean {
|
|
600
599
|
return (
|
|
601
600
|
roomData.Type === RoomType.ANGEL &&
|
|
602
|
-
roomData.Subtype ===
|
|
601
|
+
roomData.Subtype === AngelRoomSubType.SHOP
|
|
603
602
|
);
|
|
604
603
|
}
|
|
605
604
|
|
|
@@ -614,7 +613,7 @@ export function isAngelShop(roomData: RoomConfig): boolean {
|
|
|
614
613
|
export function isBeastRoom(roomData: RoomConfig): boolean {
|
|
615
614
|
return (
|
|
616
615
|
roomData.Type === RoomType.DUNGEON &&
|
|
617
|
-
roomData.Subtype ===
|
|
616
|
+
roomData.Subtype === DungeonSubType.BEAST_ROOM
|
|
618
617
|
);
|
|
619
618
|
}
|
|
620
619
|
|
|
@@ -634,7 +633,7 @@ export function isBossRoomOf(roomData: RoomConfig, bossID: BossID): boolean {
|
|
|
634
633
|
return (
|
|
635
634
|
roomData.Type === RoomType.BOSS &&
|
|
636
635
|
roomData.StageID === StageID.SPECIAL_ROOMS &&
|
|
637
|
-
roomData.Subtype ===
|
|
636
|
+
roomData.Subtype === bossID
|
|
638
637
|
);
|
|
639
638
|
}
|
|
640
639
|
|
|
@@ -646,7 +645,7 @@ export function isBossRoomOf(roomData: RoomConfig, bossID: BossID): boolean {
|
|
|
646
645
|
export function isCrawlSpace(roomData: RoomConfig): boolean {
|
|
647
646
|
return (
|
|
648
647
|
roomData.Type === RoomType.DUNGEON &&
|
|
649
|
-
roomData.Subtype ===
|
|
648
|
+
roomData.Subtype === DungeonSubType.NORMAL
|
|
650
649
|
);
|
|
651
650
|
}
|
|
652
651
|
|
|
@@ -668,9 +667,8 @@ export function isCrawlSpaceWithBlackMarketEntrance(
|
|
|
668
667
|
export function isDeathCertificateArea(roomData: RoomConfig): boolean {
|
|
669
668
|
return (
|
|
670
669
|
roomData.StageID === StageID.HOME &&
|
|
671
|
-
(roomData.Subtype ===
|
|
672
|
-
|
|
673
|
-
roomData.Subtype === asNumber(HomeRoomSubType.DEATH_CERTIFICATE_ITEMS))
|
|
670
|
+
(roomData.Subtype === HomeRoomSubType.DEATH_CERTIFICATE_ENTRANCE ||
|
|
671
|
+
roomData.Subtype === HomeRoomSubType.DEATH_CERTIFICATE_ITEMS)
|
|
674
672
|
);
|
|
675
673
|
}
|
|
676
674
|
|
|
@@ -704,7 +702,7 @@ export function isDogmaRoom(roomData: RoomConfig): boolean {
|
|
|
704
702
|
roomData.StageID === StageID.HOME &&
|
|
705
703
|
roomData.Type === RoomType.DEFAULT &&
|
|
706
704
|
roomData.Variant === 1000 &&
|
|
707
|
-
roomData.Subtype ===
|
|
705
|
+
roomData.Subtype === HomeRoomSubType.LIVING_ROOM
|
|
708
706
|
);
|
|
709
707
|
}
|
|
710
708
|
|
|
@@ -729,7 +727,7 @@ export function isDoubleTrouble(roomData: RoomConfig): boolean {
|
|
|
729
727
|
* Helper function to determine if the index of the provided room is equal to `GridRoom.GENESIS`.
|
|
730
728
|
*/
|
|
731
729
|
export function isGenesisRoom(roomGridIndex: int): boolean {
|
|
732
|
-
return roomGridIndex ===
|
|
730
|
+
return roomGridIndex === GridRoom.GENESIS;
|
|
733
731
|
}
|
|
734
732
|
|
|
735
733
|
/**
|
|
@@ -741,8 +739,8 @@ export function isGenesisRoom(roomGridIndex: int): boolean {
|
|
|
741
739
|
export function isHomeCloset(roomData: RoomConfig): boolean {
|
|
742
740
|
return (
|
|
743
741
|
roomData.StageID === StageID.HOME &&
|
|
744
|
-
(roomData.Subtype ===
|
|
745
|
-
roomData.Subtype ===
|
|
742
|
+
(roomData.Subtype === HomeRoomSubType.CLOSET_LEFT ||
|
|
743
|
+
roomData.Subtype === HomeRoomSubType.CLOSET_RIGHT)
|
|
746
744
|
);
|
|
747
745
|
}
|
|
748
746
|
|
|
@@ -755,7 +753,7 @@ export function isLRoom(roomData: RoomConfig): boolean {
|
|
|
755
753
|
* Helper function to determine if the index of the provided room is equal to `GridRoom.MEGA_SATAN`.
|
|
756
754
|
*/
|
|
757
755
|
export function isMegaSatanRoom(roomGridIndex: int): boolean {
|
|
758
|
-
return roomGridIndex ===
|
|
756
|
+
return roomGridIndex === GridRoom.MEGA_SATAN;
|
|
759
757
|
}
|
|
760
758
|
|
|
761
759
|
/**
|
|
@@ -782,7 +780,7 @@ export function isMinibossRoomOf(
|
|
|
782
780
|
return (
|
|
783
781
|
roomData.Type === RoomType.MINI_BOSS &&
|
|
784
782
|
roomData.StageID === StageID.SPECIAL_ROOMS &&
|
|
785
|
-
roomData.Subtype ===
|
|
783
|
+
roomData.Subtype === minibossID
|
|
786
784
|
);
|
|
787
785
|
}
|
|
788
786
|
|
|
@@ -795,7 +793,7 @@ export function isMirrorRoom(roomData: RoomConfig): boolean {
|
|
|
795
793
|
roomData.Type === RoomType.DEFAULT &&
|
|
796
794
|
(roomData.StageID === StageID.DOWNPOUR ||
|
|
797
795
|
roomData.StageID === StageID.DROSS) &&
|
|
798
|
-
roomData.Subtype ===
|
|
796
|
+
roomData.Subtype === DownpourRoomSubType.MIRROR
|
|
799
797
|
);
|
|
800
798
|
}
|
|
801
799
|
|
|
@@ -828,7 +826,7 @@ export function isRoomType(
|
|
|
828
826
|
* floor.
|
|
829
827
|
*/
|
|
830
828
|
export function isSecretExit(roomGridIndex: int): boolean {
|
|
831
|
-
return roomGridIndex ===
|
|
829
|
+
return roomGridIndex === GridRoom.SECRET_EXIT;
|
|
832
830
|
}
|
|
833
831
|
|
|
834
832
|
/**
|
|
@@ -848,7 +846,7 @@ export function isSecretRoomType(roomType: RoomType): boolean {
|
|
|
848
846
|
* the only way to detect them is by using the grid index.
|
|
849
847
|
*/
|
|
850
848
|
export function isSecretShop(roomGridIndex: int): boolean {
|
|
851
|
-
return roomGridIndex ===
|
|
849
|
+
return roomGridIndex === GridRoom.SECRET_SHOP;
|
|
852
850
|
}
|
|
853
851
|
|
|
854
852
|
/**
|
package/src/functions/stage.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ROOM_TYPE_SPECIAL_GOTO_PREFIXES } from "../objects/roomTypeSpecialGotoP
|
|
|
11
11
|
import { STAGE_TO_STAGE_ID } from "../objects/stageToStageID";
|
|
12
12
|
import { STAGE_TYPE_SUFFIXES } from "../objects/stageTypeSuffixes";
|
|
13
13
|
import { log } from "./log";
|
|
14
|
-
import { asLevelStage
|
|
14
|
+
import { asLevelStage } from "./types";
|
|
15
15
|
import { inRange } from "./utils";
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -62,7 +62,7 @@ export function calculateStageTypeRepentance(stage: LevelStage): StageType {
|
|
|
62
62
|
// This algorithm is from Kilburn. We add one because the alt path is offset by 1 relative to the
|
|
63
63
|
// normal path.
|
|
64
64
|
const seeds = game.GetSeeds();
|
|
65
|
-
const adjustedStage = asLevelStage(
|
|
65
|
+
const adjustedStage = asLevelStage(stage + 1);
|
|
66
66
|
const stageSeed = seeds.GetStageSeed(adjustedStage);
|
|
67
67
|
|
|
68
68
|
// Kilburn does not know why he divided the stage seed by 2 first.
|
|
@@ -84,7 +84,7 @@ export function getEffectiveStage(): LevelStage {
|
|
|
84
84
|
const stage = level.GetStage();
|
|
85
85
|
|
|
86
86
|
if (onRepentanceStage()) {
|
|
87
|
-
return
|
|
87
|
+
return stage + 1;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return stage;
|
|
@@ -42,7 +42,7 @@ const TRINKET_SPRITE_LAYER = 0;
|
|
|
42
42
|
export function getGoldenTrinketType(trinketType: TrinketType): TrinketType {
|
|
43
43
|
return isGoldenTrinketType(trinketType)
|
|
44
44
|
? trinketType
|
|
45
|
-
:
|
|
45
|
+
: trinketType + GOLDEN_TRINKET_ADJUSTMENT;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
@@ -88,7 +88,7 @@ export function getMysteriousPaperEffectForFrame(
|
|
|
88
88
|
*/
|
|
89
89
|
export function getNormalTrinketType(trinketType: TrinketType): TrinketType {
|
|
90
90
|
return isGoldenTrinketType(trinketType)
|
|
91
|
-
?
|
|
91
|
+
? trinketType - GOLDEN_TRINKET_ADJUSTMENT
|
|
92
92
|
: trinketType;
|
|
93
93
|
}
|
|
94
94
|
|
package/src/functions/types.ts
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consider the following code that uses a number enum:
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* enum MyEnum {
|
|
6
|
+
* Value1,
|
|
7
|
+
* }
|
|
8
|
+
*
|
|
9
|
+
* function asMyEnum(num: number): MyEnum {}
|
|
10
|
+
*
|
|
11
|
+
* declare const something: unknown;
|
|
12
|
+
*
|
|
13
|
+
* const foo = something as MyEnum; // no error
|
|
14
|
+
* const bar: MyEnum = something; // error
|
|
15
|
+
* const baz = asMyEnum(something); // error
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Here, using `as` does not give an error because TypeScript allows you to assert a type to a
|
|
19
|
+
* supertype or a subtype. Thus, using `as` to perform a type assertion is not as safe as using a
|
|
20
|
+
* variable declaration or a helper function. However, if we use a variable declaration, then the
|
|
21
|
+
* `isaacscript/strict-enums` rule is triggered, which requires suppressing the lint rule with a `//
|
|
22
|
+
* eslint-disable-next-line`. Thus, the safest and more concise way to do a type assertion is to use
|
|
23
|
+
* a helper function.
|
|
24
|
+
*
|
|
25
|
+
* This file contains helper functions for various number enums that might require type assertions.
|
|
26
|
+
* It also contains helper functions for run-time type checks.
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
|
|
1
31
|
import type {
|
|
2
32
|
CardType,
|
|
3
33
|
CollectibleType,
|