isaacscript-common 80.1.0 → 80.2.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.
- 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/set.d.ts +37 -1
- package/dist/functions/set.d.ts.map +1 -1
- package/dist/functions/set.lua +56 -11
- 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 +97 -27
- package/dist/isaacscript-common.lua +152 -158
- 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/set.ts +79 -11
- 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/set.ts
CHANGED
|
@@ -13,7 +13,7 @@ export function addSetsToSet<T>(
|
|
|
13
13
|
...setsToAdd: Array<Set<T> | ReadonlySet<T>>
|
|
14
14
|
): void {
|
|
15
15
|
for (const set of setsToAdd) {
|
|
16
|
-
for (const value of set
|
|
16
|
+
for (const value of set) {
|
|
17
17
|
mainSet.add(value);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -29,7 +29,7 @@ export function combineSets<T>(
|
|
|
29
29
|
): Set<T> {
|
|
30
30
|
const newSet = new Set<T>();
|
|
31
31
|
for (const set of sets) {
|
|
32
|
-
for (const value of set
|
|
32
|
+
for (const value of set) {
|
|
33
33
|
newSet.add(value);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -40,7 +40,7 @@ export function combineSets<T>(
|
|
|
40
40
|
/** Helper function to copy a set. (You can also use a Set constructor to accomplish this task.) */
|
|
41
41
|
export function copySet<T>(oldSet: Set<T> | ReadonlySet<T>): Set<T> {
|
|
42
42
|
const newSet = new Set<T>();
|
|
43
|
-
for (const value of oldSet
|
|
43
|
+
for (const value of oldSet) {
|
|
44
44
|
newSet.add(value);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -58,7 +58,7 @@ export function deleteSetsFromSet<T>(
|
|
|
58
58
|
...setsToRemove: Array<Set<T> | ReadonlySet<T>>
|
|
59
59
|
): void {
|
|
60
60
|
for (const set of setsToRemove) {
|
|
61
|
-
for (const value of set
|
|
61
|
+
for (const value of set) {
|
|
62
62
|
mainSet.delete(value);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -117,15 +117,14 @@ export function getSetCombinations<T>(
|
|
|
117
117
|
/**
|
|
118
118
|
* Helper function to get a sorted array based on the contents of a set.
|
|
119
119
|
*
|
|
120
|
-
* Normally, set values are returned in
|
|
120
|
+
* Normally, set values are returned in insertion order, so use this function when the ordering of
|
|
121
121
|
* the contents is important.
|
|
122
122
|
*/
|
|
123
123
|
export function getSortedSetValues<T>(set: Set<T> | ReadonlySet<T>): T[] {
|
|
124
|
-
const values = set
|
|
125
|
-
const array = [...values];
|
|
124
|
+
const values = [...set];
|
|
126
125
|
|
|
127
126
|
// Check for problematic types in order to throw a helpful error message.
|
|
128
|
-
const firstElement =
|
|
127
|
+
const firstElement = values[0];
|
|
129
128
|
if (firstElement !== undefined) {
|
|
130
129
|
const arrayType = type(firstElement);
|
|
131
130
|
if (!isPrimitive(arrayType)) {
|
|
@@ -135,9 +134,78 @@ export function getSortedSetValues<T>(set: Set<T> | ReadonlySet<T>): T[] {
|
|
|
135
134
|
}
|
|
136
135
|
}
|
|
137
136
|
|
|
138
|
-
|
|
137
|
+
values.sort();
|
|
139
138
|
|
|
140
|
-
return
|
|
139
|
+
return values;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Helper function to convert the keys of an object to a read-only set.
|
|
144
|
+
*
|
|
145
|
+
* Note that the set values will be inserted in a random order, due to how `pairs` works under the
|
|
146
|
+
* hood.
|
|
147
|
+
*
|
|
148
|
+
* Also see the `objectKeysToSet` function.
|
|
149
|
+
*/
|
|
150
|
+
export function objectKeysToReadonlySet<K extends string | number | symbol, V>(
|
|
151
|
+
object: Record<K, V>,
|
|
152
|
+
): ReadonlySet<K> {
|
|
153
|
+
return objectKeysToSet(object);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Helper function to convert the keys of an object to a set.
|
|
158
|
+
*
|
|
159
|
+
* Note that the set values will be inserted in a random order, due to how `pairs` works under the
|
|
160
|
+
* hood.
|
|
161
|
+
*
|
|
162
|
+
* Also see the `objectKeysToReadonlySet` function.
|
|
163
|
+
*/
|
|
164
|
+
export function objectKeysToSet<K extends string | number | symbol, V>(
|
|
165
|
+
object: Record<K, V>,
|
|
166
|
+
): Set<K> {
|
|
167
|
+
const set = new Set<K>();
|
|
168
|
+
|
|
169
|
+
for (const key of Object.keys(object)) {
|
|
170
|
+
set.add(key as K);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return set;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Helper function to convert the values of an object to a read-only set.
|
|
178
|
+
*
|
|
179
|
+
* Note that the set values will be inserted in a random order, due to how `pairs` works under the
|
|
180
|
+
* hood.
|
|
181
|
+
*
|
|
182
|
+
* Also see the `objectValuesToSet` function.
|
|
183
|
+
*/
|
|
184
|
+
export function objectValuesToReadonlySet<
|
|
185
|
+
K extends string | number | symbol,
|
|
186
|
+
V,
|
|
187
|
+
>(object: Record<K, V>): ReadonlySet<V> {
|
|
188
|
+
return objectValuesToSet(object);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Helper function to convert the values of an object to a set.
|
|
193
|
+
*
|
|
194
|
+
* Note that the set values will be inserted in a random order, due to how `pairs` works under the
|
|
195
|
+
* hood.
|
|
196
|
+
*
|
|
197
|
+
* Also see the `objectValuesToReadonlySet` function.
|
|
198
|
+
*/
|
|
199
|
+
export function objectValuesToSet<K extends string | number | symbol, V>(
|
|
200
|
+
object: Record<K, V>,
|
|
201
|
+
): Set<V> {
|
|
202
|
+
const set = new Set<V>();
|
|
203
|
+
|
|
204
|
+
for (const key of Object.values(object)) {
|
|
205
|
+
set.add(key as V);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return set;
|
|
141
209
|
}
|
|
142
210
|
|
|
143
211
|
/**
|
|
@@ -168,6 +236,6 @@ export function setHas<T>(
|
|
|
168
236
|
|
|
169
237
|
/** Helper function to sum every value in a set together. */
|
|
170
238
|
export function sumSet(set: Set<number> | ReadonlySet<number>): number {
|
|
171
|
-
const values = [...set
|
|
239
|
+
const values = [...set];
|
|
172
240
|
return sumArray(values);
|
|
173
241
|
}
|
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,
|