isaacscript-common 6.20.1 → 6.20.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/features/customStage/exports.d.ts +6 -1
- package/dist/features/customStage/exports.d.ts.map +1 -1
- package/dist/features/customStage/exports.lua +12 -4
- package/dist/features/customTrapdoor/blackSprite.d.ts.map +1 -1
- package/dist/features/customTrapdoor/blackSprite.lua +1 -0
- package/dist/functions/levelGrid.lua +1 -1
- package/dist/functions/roomData.d.ts +1 -1
- package/dist/functions/roomData.d.ts.map +1 -1
- package/dist/functions/rooms.d.ts +36 -18
- package/dist/functions/rooms.d.ts.map +1 -1
- package/dist/functions/rooms.lua +92 -48
- package/package.json +2 -2
- package/src/features/customStage/exports.ts +16 -4
- package/src/features/customTrapdoor/blackSprite.ts +1 -0
- package/src/functions/levelGrid.ts +1 -1
- package/src/functions/roomData.ts +1 -1
- package/src/functions/rooms.ts +102 -47
|
@@ -4,8 +4,13 @@ import { EntityType } from "isaac-typescript-definitions";
|
|
|
4
4
|
*
|
|
5
5
|
* Custom stages/levels must first be defined in the "tsconfig.json" file. See the documentation for
|
|
6
6
|
* more details: https://isaacscript.github.io/main/custom-stages/
|
|
7
|
+
*
|
|
8
|
+
* @param name The name of the custom stage, corresponding to what is in the "tsconfig.json" file.
|
|
9
|
+
* @param _firstFloor Whether to go to the first floor or the second floor. For example, if you have
|
|
10
|
+
* a custom stage emulating Caves, then the first floor would be Caves 1, and the
|
|
11
|
+
* second floor would be Caves 2.
|
|
7
12
|
*/
|
|
8
|
-
export declare function setCustomStage(name: string, verbose?: boolean): void;
|
|
13
|
+
export declare function setCustomStage(name: string, _firstFloor?: boolean, verbose?: boolean): void;
|
|
9
14
|
export declare function setCustomStageDebug(): void;
|
|
10
15
|
/**
|
|
11
16
|
* By default, unknown bosses will be drawn on the boss "versus" screen as "???". If your custom
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/customStage/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAKX,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/customStage/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAKX,MAAM,8BAA8B,CAAC;AAsBtC;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,WAAW,UAAO,EAClB,OAAO,UAAQ,GACd,IAAI,CAyGN;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAQ1C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,IAAI,CAGN"}
|
|
@@ -19,7 +19,7 @@ local ____rng = require("functions.rng")
|
|
|
19
19
|
local newRNG = ____rng.newRNG
|
|
20
20
|
local ____rooms = require("functions.rooms")
|
|
21
21
|
local getRoomDataForTypeVariant = ____rooms.getRoomDataForTypeVariant
|
|
22
|
-
local
|
|
22
|
+
local getRoomsInGrid = ____rooms.getRoomsInGrid
|
|
23
23
|
local ____stage = require("functions.stage")
|
|
24
24
|
local setStage = ____stage.setStage
|
|
25
25
|
local ____customStageUtils = require("features.customStage.customStageUtils")
|
|
@@ -37,13 +37,21 @@ local DEFAULT_BASE_STAGE_TYPE = StageType.ORIGINAL
|
|
|
37
37
|
--
|
|
38
38
|
-- Custom stages/levels must first be defined in the "tsconfig.json" file. See the documentation for
|
|
39
39
|
-- more details: https://isaacscript.github.io/main/custom-stages/
|
|
40
|
-
|
|
40
|
+
--
|
|
41
|
+
-- @param name The name of the custom stage, corresponding to what is in the "tsconfig.json" file.
|
|
42
|
+
-- @param _firstFloor Whether to go to the first floor or the second floor. For example, if you have
|
|
43
|
+
-- a custom stage emulating Caves, then the first floor would be Caves 1, and the
|
|
44
|
+
-- second floor would be Caves 2.
|
|
45
|
+
function ____exports.setCustomStage(self, name, _firstFloor, verbose)
|
|
46
|
+
if _firstFloor == nil then
|
|
47
|
+
_firstFloor = true
|
|
48
|
+
end
|
|
41
49
|
if verbose == nil then
|
|
42
50
|
verbose = false
|
|
43
51
|
end
|
|
44
52
|
local customStage = customStagesMap:get(name)
|
|
45
53
|
if customStage == nil then
|
|
46
|
-
error(("Failed to set the custom stage of \"" .. name) .. "\" because it was not found in the custom stages map. (Try restarting IsaacScript / recompiling the mod, and try again. If that does not work, you probably forgot to define it in your \"tsconfig.json\" file.) See the website for more details on how to set up custom stages.")
|
|
54
|
+
error(("Failed to set the custom stage of \"" .. name) .. "\" because it was not found in the custom stages map. (Try restarting IsaacScript / recompiling the mod / restarting the game, and try again. If that does not work, you probably forgot to define it in your \"tsconfig.json\" file.) See the website for more details on how to set up custom stages.")
|
|
47
55
|
end
|
|
48
56
|
local level = game:GetLevel()
|
|
49
57
|
local startingRoomGridIndex = level:GetStartingRoomIndex()
|
|
@@ -54,7 +62,7 @@ function ____exports.setCustomStage(self, name, verbose)
|
|
|
54
62
|
local baseStage = customStage.baseStage == nil and DEFAULT_BASE_STAGE or customStage.baseStage
|
|
55
63
|
local baseStageType = customStage.baseStageType == nil and DEFAULT_BASE_STAGE_TYPE or customStage.baseStageType
|
|
56
64
|
setStage(nil, baseStage, baseStageType)
|
|
57
|
-
for ____, room in ipairs(
|
|
65
|
+
for ____, room in ipairs(getRoomsInGrid(nil)) do
|
|
58
66
|
do
|
|
59
67
|
if room.SafeGridIndex == startingRoomGridIndex then
|
|
60
68
|
goto __continue4
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blackSprite.d.ts","sourceRoot":"","sources":["../../../src/features/customTrapdoor/blackSprite.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"blackSprite.d.ts","sourceRoot":"","sources":["../../../src/features/customTrapdoor/blackSprite.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,IAAI,IAAI,CAYtC"}
|
|
@@ -13,6 +13,7 @@ function ____exports.drawBlackSprite(self)
|
|
|
13
13
|
if not blackSprite:IsLoaded() then
|
|
14
14
|
blackSprite:Load("gfx/ui/boss/versusscreen.anm2", true)
|
|
15
15
|
blackSprite:SetFrame("Scene", 0)
|
|
16
|
+
blackSprite.Scale = Vector(100, 100)
|
|
16
17
|
end
|
|
17
18
|
blackSprite:RenderLayer(0, VectorZero)
|
|
18
19
|
end
|
|
@@ -229,7 +229,7 @@ end
|
|
|
229
229
|
-- indexes for N room types.
|
|
230
230
|
function ____exports.getRoomGridIndexesForType(self, ...)
|
|
231
231
|
local roomTypesSet = __TS__New(Set, {...})
|
|
232
|
-
local rooms =
|
|
232
|
+
local rooms = getRoomsInGrid(nil)
|
|
233
233
|
local matchingRooms = __TS__ArrayFilter(
|
|
234
234
|
rooms,
|
|
235
235
|
function(____, roomDescriptor) return roomDescriptor.Data ~= nil and roomTypesSet:has(roomDescriptor.Data.Type) end
|
|
@@ -20,7 +20,7 @@ export declare function getRoomDescriptor(roomGridIndex?: int): RoomDescriptor;
|
|
|
20
20
|
* Alias for the `Level.GetCurrentRoomDesc` method. Use this to make it more clear what type of
|
|
21
21
|
* `RoomDescriptor` object that you are retrieving.
|
|
22
22
|
*/
|
|
23
|
-
export declare function getRoomDescriptorReadOnly():
|
|
23
|
+
export declare function getRoomDescriptorReadOnly(): Readonly<RoomDescriptor>;
|
|
24
24
|
/**
|
|
25
25
|
* Helper function to get the grid index of the current room.
|
|
26
26
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roomData.d.ts","sourceRoot":"","sources":["../../src/functions/roomData.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAER,SAAS,EACT,QAAQ,EACR,OAAO,EACR,MAAM,8BAA8B,CAAC;AAMtC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAiBtE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,UAAU,GAAG,SAAS,CAGvE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,cAAc,CAQrE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,
|
|
1
|
+
{"version":3,"file":"roomData.d.ts","sourceRoot":"","sources":["../../src/functions/roomData.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAER,SAAS,EACT,QAAQ,EACR,OAAO,EACR,MAAM,8BAA8B,CAAC;AAMtC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAiBtE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,UAAU,GAAG,SAAS,CAGvE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,cAAc,CAQrE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,QAAQ,CAAC,cAAc,CAAC,CAGpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,IAAI,GAAG,CAatC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAGzD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,MAAM,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,SAAS,GAAG,SAAS,CAGvE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,OAAO,CAG3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,QAAQ,CAGzD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAGvD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,CAAC,EAAE,GAAG,GAAG,GAAG,CAG5D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,aAAa,EAAE,GAAG,EAClB,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC7B,IAAI,CAGN"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BossID, Dimension, Direction, ItemPoolType, MinibossID, RoomTransitionAnim, RoomType } from "isaac-typescript-definitions";
|
|
1
|
+
import { BackdropType, BossID, Dimension, Direction, ItemPoolType, MinibossID, RoomTransitionAnim, RoomType } from "isaac-typescript-definitions";
|
|
2
2
|
/**
|
|
3
3
|
* Helper function for quickly switching to a new room without playing a particular animation. Use
|
|
4
4
|
* this helper function over invoking the `Game.ChangeRoom` method directly to ensure that you do
|
|
@@ -10,6 +10,18 @@ export declare function changeRoom(roomGridIndex: int): void;
|
|
|
10
10
|
* include off-grid rooms, like the Devil Room.
|
|
11
11
|
*/
|
|
12
12
|
export declare function getNumRooms(): int;
|
|
13
|
+
/**
|
|
14
|
+
* Helper function to get a read-only copy of the room descriptor for every room on the level. This
|
|
15
|
+
* includes off-grid rooms, such as the Devil Room, and extra-dimensional rooms, if they are
|
|
16
|
+
* generated and exist.
|
|
17
|
+
*
|
|
18
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
19
|
+
*
|
|
20
|
+
* Under the hood, this is performed by iterating over the `RoomList` from the `Level.GetRooms`
|
|
21
|
+
* method. This is the best way to see if off-grid rooms have been initialized, since it is possible
|
|
22
|
+
* for mods to insert room data at non-official negative room grid indexes.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getReadOnlyRooms(): Array<Readonly<RoomDescriptor>>;
|
|
13
25
|
/**
|
|
14
26
|
* Helper function to get the room data for a specific room type and variant combination. This is
|
|
15
27
|
* accomplished by using the "goto" console command to load the specified room into the
|
|
@@ -45,39 +57,43 @@ export declare function getRoomItemPoolType(): ItemPoolType;
|
|
|
45
57
|
export declare function getRoomTypeName(roomType: RoomType): string;
|
|
46
58
|
/**
|
|
47
59
|
* Helper function to get the room descriptor for every room on the level. This includes off-grid
|
|
48
|
-
* rooms, such as the Devil Room.
|
|
49
|
-
*
|
|
60
|
+
* rooms, such as the Devil Room.
|
|
61
|
+
*
|
|
62
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
50
63
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
64
|
+
* - If you want just the rooms inside of the grid, use the `getRoomsInGrid` helper function.
|
|
65
|
+
* - If you want just the rooms outside of the grid, use the `getRoomsOutsideGrid` helper function.
|
|
53
66
|
*
|
|
54
67
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
55
|
-
* extra-dimensional rooms are automatically generated
|
|
56
|
-
*
|
|
68
|
+
* extra-dimensional rooms are automatically generated. Default is
|
|
69
|
+
* false.
|
|
57
70
|
*/
|
|
58
71
|
export declare function getRooms(includeExtraDimensionalRooms?: boolean): RoomDescriptor[];
|
|
59
72
|
/**
|
|
60
|
-
* Helper function to get the room descriptor for every room on the level
|
|
61
|
-
*
|
|
73
|
+
* Helper function to get the room descriptor for every room on the level that is on the grid. (For
|
|
74
|
+
* example, Devil Rooms are excluded.)
|
|
62
75
|
*
|
|
63
|
-
*
|
|
64
|
-
* data are assumed to be non-existent and are not added to the list.
|
|
76
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
65
77
|
*
|
|
66
78
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
67
|
-
* extra-dimensional rooms are automatically be generated
|
|
68
|
-
*
|
|
79
|
+
* extra-dimensional rooms are automatically be generated. Default
|
|
80
|
+
* is false.
|
|
69
81
|
*/
|
|
70
82
|
export declare function getRoomsInGrid(includeExtraDimensionalRooms?: boolean): RoomDescriptor[];
|
|
71
83
|
/**
|
|
72
84
|
* Helper function to get the room descriptor for every room on the level in a specific dimension.
|
|
73
85
|
* This will not include any off-grid rooms, such as the Devil Room.
|
|
74
86
|
*
|
|
75
|
-
*
|
|
76
|
-
* data are assumed to be non-existent and are not added to the list.
|
|
77
|
-
*
|
|
78
|
-
* @returns A map of room ListIndex to RoomDescriptor.
|
|
87
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
79
88
|
*/
|
|
80
89
|
export declare function getRoomsOfDimension(dimension: Dimension): RoomDescriptor[];
|
|
90
|
+
/**
|
|
91
|
+
* Helper function to get the room descriptor for every room on the level that is outside of the
|
|
92
|
+
* grid (like a Devil Room).
|
|
93
|
+
*
|
|
94
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
95
|
+
*/
|
|
96
|
+
export declare function getRoomsOutsideGrid(): RoomDescriptor[];
|
|
81
97
|
/**
|
|
82
98
|
* Helper function to determine if the current room shape is equal to `RoomShape.1x2` or
|
|
83
99
|
* `RoomShape.2x1`.
|
|
@@ -139,7 +155,7 @@ export declare function inStartingRoom(): boolean;
|
|
|
139
155
|
/**
|
|
140
156
|
* Helper function to loop through every room on the floor and see if it has been cleared.
|
|
141
157
|
*
|
|
142
|
-
* This function will only check rooms
|
|
158
|
+
* This function will only check rooms inside the gird and inside the current dimension.
|
|
143
159
|
*
|
|
144
160
|
* @param onlyCheckRoomTypes Optional. A whitelist of room types. If specified, room types not in
|
|
145
161
|
* the array will be ignored. If not specified, then all rooms will be
|
|
@@ -153,6 +169,8 @@ export declare function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolea
|
|
|
153
169
|
* positions/velocities before updating the room, and then restore those positions/velocities.
|
|
154
170
|
*/
|
|
155
171
|
export declare function roomUpdateSafe(): void;
|
|
172
|
+
/** Helper function to set the backdrop of the current room. */
|
|
173
|
+
export declare function setBackdrop(backdropType: BackdropType): void;
|
|
156
174
|
/**
|
|
157
175
|
* Helper function to convert an uncleared room to a cleared room in the `POST_NEW_ROOM` callback.
|
|
158
176
|
* This is useful because if enemies are removed in this callback, a room drop will be awarded and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rooms.d.ts","sourceRoot":"","sources":["../../src/functions/rooms.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,SAAS,EACT,SAAS,EAKT,YAAY,EAEZ,UAAU,EAGV,kBAAkB,EAClB,QAAQ,EAGT,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"rooms.d.ts","sourceRoot":"","sources":["../../src/functions/rooms.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EACZ,MAAM,EACN,SAAS,EACT,SAAS,EAKT,YAAY,EAEZ,UAAU,EAGV,kBAAkB,EAClB,QAAQ,EAGT,MAAM,8BAA8B,CAAC;AAiCtC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI,CAenD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAGjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAiBlE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,GAAG,EAChB,oBAAoB,UAAO,GAC1B,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,CAgBlC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,YAAY,CAOlD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,4BAA4B,UAAQ,GACnC,cAAc,EAAE,CAOlB;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,4BAA4B,UAAQ,GACnC,cAAc,EAAE,CAqBlB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,EAAE,CAe1E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAWtD;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAKnC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAOrC;AAED,wBAAgB,WAAW,IAAI,OAAO,CASrC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAWpD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAOtC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAWhD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAGnD;AAED,wBAAgB,eAAe,IAAI,OAAO,CAMzC;AAED,wBAAgB,aAAa,IAAI,OAAO,CAKvC;AAED,+FAA+F;AAC/F,wBAAgB,OAAO,IAAI,OAAO,CAUjC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAKzC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CASrC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAWhE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAKtC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAMxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAcxE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAWrC;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,IAAI,CA8BrC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CACtB,aAAa,EAAE,GAAG,EAClB,SAAS,YAAyB,EAClC,kBAAkB,qBAA8B,EAChD,KAAK,UAAQ,GACZ,IAAI,CA0BN"}
|
package/dist/functions/rooms.lua
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
local ____lualib = require("lualib_bundle")
|
|
2
|
+
local __TS__SparseArrayNew = ____lualib.__TS__SparseArrayNew
|
|
3
|
+
local __TS__SparseArrayPush = ____lualib.__TS__SparseArrayPush
|
|
4
|
+
local __TS__SparseArraySpread = ____lualib.__TS__SparseArraySpread
|
|
2
5
|
local Map = ____lualib.Map
|
|
3
6
|
local __TS__New = ____lualib.__TS__New
|
|
4
7
|
local __TS__Spread = ____lualib.__TS__Spread
|
|
5
8
|
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
|
9
|
+
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
|
|
6
10
|
local __TS__StringIncludes = ____lualib.__TS__StringIncludes
|
|
7
11
|
local Set = ____lualib.Set
|
|
8
12
|
local __TS__ArrayEvery = ____lualib.__TS__ArrayEvery
|
|
@@ -27,6 +31,7 @@ local game = ____cachedClasses.game
|
|
|
27
31
|
local sfxManager = ____cachedClasses.sfxManager
|
|
28
32
|
local ____constants = require("constants")
|
|
29
33
|
local MAX_LEVEL_GRID_INDEX = ____constants.MAX_LEVEL_GRID_INDEX
|
|
34
|
+
local NUM_DIMENSIONS = ____constants.NUM_DIMENSIONS
|
|
30
35
|
local ____roomTypeNames = require("objects.roomTypeNames")
|
|
31
36
|
local ROOM_TYPE_NAMES = ____roomTypeNames.ROOM_TYPE_NAMES
|
|
32
37
|
local ____mineShaftRoomSubTypesSet = require("sets.mineShaftRoomSubTypesSet")
|
|
@@ -51,6 +56,7 @@ local setEntityPositions = ____positionVelocity.setEntityPositions
|
|
|
51
56
|
local setEntityVelocities = ____positionVelocity.setEntityVelocities
|
|
52
57
|
local ____roomData = require("functions.roomData")
|
|
53
58
|
local getRoomData = ____roomData.getRoomData
|
|
59
|
+
local getRoomDescriptor = ____roomData.getRoomDescriptor
|
|
54
60
|
local getRoomDescriptorReadOnly = ____roomData.getRoomDescriptorReadOnly
|
|
55
61
|
local getRoomGridIndex = ____roomData.getRoomGridIndex
|
|
56
62
|
local getRoomName = ____roomData.getRoomName
|
|
@@ -59,61 +65,73 @@ local getRoomSubType = ____roomData.getRoomSubType
|
|
|
59
65
|
local ____stage = require("functions.stage")
|
|
60
66
|
local getGotoCommand = ____stage.getGotoCommand
|
|
61
67
|
local ____utils = require("functions.utils")
|
|
68
|
+
local erange = ____utils.erange
|
|
62
69
|
local irange = ____utils.irange
|
|
63
|
-
--- Helper function to get the room descriptor for every room on the level. This
|
|
64
|
-
-- rooms, such as the Devil Room
|
|
65
|
-
--
|
|
70
|
+
--- Helper function to get a read-only copy of the room descriptor for every room on the level. This
|
|
71
|
+
-- includes off-grid rooms, such as the Devil Room, and extra-dimensional rooms, if they are
|
|
72
|
+
-- generated and exist.
|
|
66
73
|
--
|
|
67
|
-
--
|
|
68
|
-
-- data are assumed to be non-existent and are not added to the list.
|
|
74
|
+
-- Room descriptors without any data are assumed to be non-existent and are not included.
|
|
69
75
|
--
|
|
70
|
-
--
|
|
71
|
-
--
|
|
72
|
-
--
|
|
73
|
-
function ____exports.
|
|
74
|
-
if includeExtraDimensionalRooms == nil then
|
|
75
|
-
includeExtraDimensionalRooms = false
|
|
76
|
-
end
|
|
76
|
+
-- Under the hood, this is performed by iterating over the `RoomList` from the `Level.GetRooms`
|
|
77
|
+
-- method. This is the best way to see if off-grid rooms have been initialized, since it is possible
|
|
78
|
+
-- for mods to insert room data at non-official negative room grid indexes.
|
|
79
|
+
function ____exports.getReadOnlyRooms(self)
|
|
77
80
|
local level = game:GetLevel()
|
|
78
81
|
local roomList = level:GetRooms()
|
|
79
|
-
|
|
80
|
-
local roomsMap = __TS__New(Map)
|
|
82
|
+
local readOnlyRoomDescriptors = {}
|
|
81
83
|
do
|
|
82
84
|
local i = 0
|
|
83
85
|
while i < roomList.Size do
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
goto __continue10
|
|
88
|
-
end
|
|
89
|
-
if not includeExtraDimensionalRooms and roomsMap:has(roomDescriptor.SafeGridIndex) then
|
|
90
|
-
goto __continue10
|
|
91
|
-
end
|
|
92
|
-
roomsMap:set(roomDescriptor.SafeGridIndex, roomDescriptor)
|
|
86
|
+
local readOnlyRoomDescriptor = roomList:Get(i)
|
|
87
|
+
if readOnlyRoomDescriptor ~= nil and readOnlyRoomDescriptor.Data ~= nil then
|
|
88
|
+
readOnlyRoomDescriptors[#readOnlyRoomDescriptors + 1] = readOnlyRoomDescriptor
|
|
93
89
|
end
|
|
94
|
-
::__continue10::
|
|
95
90
|
i = i + 1
|
|
96
91
|
end
|
|
97
92
|
end
|
|
98
|
-
return
|
|
93
|
+
return readOnlyRoomDescriptors
|
|
99
94
|
end
|
|
100
|
-
--- Helper function to get the room descriptor for every room on the level
|
|
101
|
-
--
|
|
95
|
+
--- Helper function to get the room descriptor for every room on the level that is on the grid. (For
|
|
96
|
+
-- example, Devil Rooms are excluded.)
|
|
102
97
|
--
|
|
103
|
-
--
|
|
104
|
-
-- data are assumed to be non-existent and are not added to the list.
|
|
98
|
+
-- Room descriptors without any data are assumed to be non-existent and are not included.
|
|
105
99
|
--
|
|
106
100
|
-- @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
107
|
-
-- extra-dimensional rooms are automatically be generated
|
|
108
|
-
--
|
|
101
|
+
-- extra-dimensional rooms are automatically be generated. Default
|
|
102
|
+
-- is false.
|
|
109
103
|
function ____exports.getRoomsInGrid(self, includeExtraDimensionalRooms)
|
|
110
104
|
if includeExtraDimensionalRooms == nil then
|
|
111
105
|
includeExtraDimensionalRooms = false
|
|
112
106
|
end
|
|
113
|
-
local
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
107
|
+
local level = game:GetLevel()
|
|
108
|
+
local dimensions = includeExtraDimensionalRooms and erange(nil, NUM_DIMENSIONS) or ({Dimension.CURRENT})
|
|
109
|
+
--- We use a map instead of an array because room shapes occupy more than one room grid index.
|
|
110
|
+
local roomDescriptorMap = __TS__New(Map)
|
|
111
|
+
for ____, dimension in ipairs(dimensions) do
|
|
112
|
+
for ____, roomGridIndex in ipairs(irange(nil, MAX_LEVEL_GRID_INDEX)) do
|
|
113
|
+
local roomDescriptor = level:GetRoomByIdx(roomGridIndex, dimension)
|
|
114
|
+
if roomDescriptor.Data ~= nil then
|
|
115
|
+
local ptrHash = GetPtrHash(roomDescriptor)
|
|
116
|
+
roomDescriptorMap:set(ptrHash, roomDescriptor)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
return {__TS__Spread(roomDescriptorMap:values())}
|
|
121
|
+
end
|
|
122
|
+
--- Helper function to get the room descriptor for every room on the level that is outside of the
|
|
123
|
+
-- grid (like a Devil Room).
|
|
124
|
+
--
|
|
125
|
+
-- Room descriptors without any data are assumed to be non-existent and are not included.
|
|
126
|
+
function ____exports.getRoomsOutsideGrid(self)
|
|
127
|
+
local readOnlyRooms = ____exports.getReadOnlyRooms(nil)
|
|
128
|
+
local readOnlyRoomsOffGrid = __TS__ArrayFilter(
|
|
129
|
+
readOnlyRooms,
|
|
130
|
+
function(____, readOnlyRoomDescriptor) return readOnlyRoomDescriptor.SafeGridIndex < 0 end
|
|
131
|
+
)
|
|
132
|
+
return __TS__ArrayMap(
|
|
133
|
+
readOnlyRoomsOffGrid,
|
|
134
|
+
function(____, readOnlyRoomDescriptor) return getRoomDescriptor(nil, readOnlyRoomDescriptor.SafeGridIndex) end
|
|
117
135
|
)
|
|
118
136
|
end
|
|
119
137
|
--- Helper function to change the current room. It can be used for both teleportation and "normal"
|
|
@@ -226,13 +244,34 @@ end
|
|
|
226
244
|
function ____exports.getRoomTypeName(self, roomType)
|
|
227
245
|
return ROOM_TYPE_NAMES[roomType]
|
|
228
246
|
end
|
|
247
|
+
--- Helper function to get the room descriptor for every room on the level. This includes off-grid
|
|
248
|
+
-- rooms, such as the Devil Room.
|
|
249
|
+
--
|
|
250
|
+
-- Room descriptors without any data are assumed to be non-existent and are not included.
|
|
251
|
+
--
|
|
252
|
+
-- - If you want just the rooms inside of the grid, use the `getRoomsInGrid` helper function.
|
|
253
|
+
-- - If you want just the rooms outside of the grid, use the `getRoomsOutsideGrid` helper function.
|
|
254
|
+
--
|
|
255
|
+
-- @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
256
|
+
-- extra-dimensional rooms are automatically generated. Default is
|
|
257
|
+
-- false.
|
|
258
|
+
function ____exports.getRooms(self, includeExtraDimensionalRooms)
|
|
259
|
+
if includeExtraDimensionalRooms == nil then
|
|
260
|
+
includeExtraDimensionalRooms = false
|
|
261
|
+
end
|
|
262
|
+
local roomsInGrid = ____exports.getRoomsInGrid(nil, includeExtraDimensionalRooms)
|
|
263
|
+
local roomsOutsideGrid = ____exports.getRoomsOutsideGrid(nil)
|
|
264
|
+
local ____array_0 = __TS__SparseArrayNew(table.unpack(roomsInGrid))
|
|
265
|
+
__TS__SparseArrayPush(
|
|
266
|
+
____array_0,
|
|
267
|
+
table.unpack(roomsOutsideGrid)
|
|
268
|
+
)
|
|
269
|
+
return {__TS__SparseArraySpread(____array_0)}
|
|
270
|
+
end
|
|
229
271
|
--- Helper function to get the room descriptor for every room on the level in a specific dimension.
|
|
230
272
|
-- This will not include any off-grid rooms, such as the Devil Room.
|
|
231
273
|
--
|
|
232
|
-
--
|
|
233
|
-
-- data are assumed to be non-existent and are not added to the list.
|
|
234
|
-
--
|
|
235
|
-
-- @returns A map of room ListIndex to RoomDescriptor.
|
|
274
|
+
-- Room descriptors without any data are assumed to be non-existent and are not included.
|
|
236
275
|
function ____exports.getRoomsOfDimension(self, dimension)
|
|
237
276
|
local level = game:GetLevel()
|
|
238
277
|
--- We use a map instead of an array because room shapes occupy more than one room grid index.
|
|
@@ -240,7 +279,8 @@ function ____exports.getRoomsOfDimension(self, dimension)
|
|
|
240
279
|
for ____, roomGridIndex in ipairs(irange(nil, MAX_LEVEL_GRID_INDEX)) do
|
|
241
280
|
local roomDescriptor = level:GetRoomByIdx(roomGridIndex, dimension)
|
|
242
281
|
if roomDescriptor.Data ~= nil then
|
|
243
|
-
|
|
282
|
+
local ptrHash = GetPtrHash(roomDescriptor)
|
|
283
|
+
roomsMap:set(ptrHash, roomDescriptor)
|
|
244
284
|
end
|
|
245
285
|
end
|
|
246
286
|
return {__TS__Spread(roomsMap:values())}
|
|
@@ -352,20 +392,20 @@ function ____exports.inStartingRoom(self)
|
|
|
352
392
|
end
|
|
353
393
|
--- Helper function to loop through every room on the floor and see if it has been cleared.
|
|
354
394
|
--
|
|
355
|
-
-- This function will only check rooms
|
|
395
|
+
-- This function will only check rooms inside the gird and inside the current dimension.
|
|
356
396
|
--
|
|
357
397
|
-- @param onlyCheckRoomTypes Optional. A whitelist of room types. If specified, room types not in
|
|
358
398
|
-- the array will be ignored. If not specified, then all rooms will be
|
|
359
399
|
-- checked. Undefined by default.
|
|
360
400
|
function ____exports.isAllRoomsClear(self, onlyCheckRoomTypes)
|
|
361
|
-
local
|
|
401
|
+
local ____temp_1
|
|
362
402
|
if onlyCheckRoomTypes == nil then
|
|
363
|
-
|
|
403
|
+
____temp_1 = nil
|
|
364
404
|
else
|
|
365
|
-
|
|
405
|
+
____temp_1 = __TS__New(Set, onlyCheckRoomTypes)
|
|
366
406
|
end
|
|
367
|
-
local roomTypeWhitelist =
|
|
368
|
-
local rooms = ____exports.
|
|
407
|
+
local roomTypeWhitelist = ____temp_1
|
|
408
|
+
local rooms = ____exports.getRoomsInGrid(nil)
|
|
369
409
|
local matchingRooms = roomTypeWhitelist == nil and rooms or __TS__ArrayFilter(
|
|
370
410
|
rooms,
|
|
371
411
|
function(____, roomDescriptor) return roomDescriptor.Data ~= nil and roomTypeWhitelist:has(roomDescriptor.Data.Type) end
|
|
@@ -388,6 +428,10 @@ function ____exports.roomUpdateSafe(self)
|
|
|
388
428
|
setEntityPositions(nil, entityPositions, entities)
|
|
389
429
|
setEntityVelocities(nil, entityVelocities, entities)
|
|
390
430
|
end
|
|
431
|
+
--- Helper function to set the backdrop of the current room.
|
|
432
|
+
function ____exports.setBackdrop(self, backdropType)
|
|
433
|
+
game:ShowHallucination(0, backdropType)
|
|
434
|
+
end
|
|
391
435
|
--- Helper function to convert an uncleared room to a cleared room in the `POST_NEW_ROOM` callback.
|
|
392
436
|
-- This is useful because if enemies are removed in this callback, a room drop will be awarded and
|
|
393
437
|
-- the doors will start closed and then open.
|
|
@@ -401,12 +445,12 @@ function ____exports.setRoomCleared(self)
|
|
|
401
445
|
for ____, door in ipairs(getDoors(nil)) do
|
|
402
446
|
do
|
|
403
447
|
if isHiddenSecretRoomDoor(nil, door) then
|
|
404
|
-
goto
|
|
448
|
+
goto __continue48
|
|
405
449
|
end
|
|
406
450
|
openDoorFast(nil, door)
|
|
407
451
|
door.ExtraVisible = false
|
|
408
452
|
end
|
|
409
|
-
::
|
|
453
|
+
::__continue48::
|
|
410
454
|
end
|
|
411
455
|
sfxManager:Stop(SoundEffect.DOOR_HEAVY_OPEN)
|
|
412
456
|
game:ShakeScreen(0)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isaacscript-common",
|
|
3
|
-
"version": "6.20.
|
|
3
|
+
"version": "6.20.2",
|
|
4
4
|
"description": "Helper functions and features for IsaacScript mods.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"isaac",
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"main": "dist/index",
|
|
23
23
|
"types": "dist/index.d.ts",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"isaac-typescript-definitions": "^3.1.
|
|
25
|
+
"isaac-typescript-definitions": "^3.1.3"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -10,7 +10,10 @@ import { reorderedCallbacksSetStage } from "../../callbacks/reorderedCallbacks";
|
|
|
10
10
|
import { getEntityIDFromConstituents } from "../../functions/entities";
|
|
11
11
|
import { log, logError } from "../../functions/log";
|
|
12
12
|
import { newRNG } from "../../functions/rng";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getRoomDataForTypeVariant,
|
|
15
|
+
getRoomsInGrid,
|
|
16
|
+
} from "../../functions/rooms";
|
|
14
17
|
import { setStage } from "../../functions/stage";
|
|
15
18
|
import { getRandomCustomStageRoom } from "./customStageUtils";
|
|
16
19
|
import { topStreakTextStart } from "./streakText";
|
|
@@ -28,12 +31,21 @@ const DEFAULT_BASE_STAGE_TYPE = StageType.ORIGINAL;
|
|
|
28
31
|
*
|
|
29
32
|
* Custom stages/levels must first be defined in the "tsconfig.json" file. See the documentation for
|
|
30
33
|
* more details: https://isaacscript.github.io/main/custom-stages/
|
|
34
|
+
*
|
|
35
|
+
* @param name The name of the custom stage, corresponding to what is in the "tsconfig.json" file.
|
|
36
|
+
* @param _firstFloor Whether to go to the first floor or the second floor. For example, if you have
|
|
37
|
+
* a custom stage emulating Caves, then the first floor would be Caves 1, and the
|
|
38
|
+
* second floor would be Caves 2.
|
|
31
39
|
*/
|
|
32
|
-
export function setCustomStage(
|
|
40
|
+
export function setCustomStage(
|
|
41
|
+
name: string,
|
|
42
|
+
_firstFloor = true,
|
|
43
|
+
verbose = false,
|
|
44
|
+
): void {
|
|
33
45
|
const customStage = customStagesMap.get(name);
|
|
34
46
|
if (customStage === undefined) {
|
|
35
47
|
error(
|
|
36
|
-
`Failed to set the custom stage of "${name}" because it was not found in the custom stages map. (Try restarting IsaacScript / recompiling the mod, and try again. If that does not work, you probably forgot to define it in your "tsconfig.json" file.) See the website for more details on how to set up custom stages.`,
|
|
48
|
+
`Failed to set the custom stage of "${name}" because it was not found in the custom stages map. (Try restarting IsaacScript / recompiling the mod / restarting the game, and try again. If that does not work, you probably forgot to define it in your "tsconfig.json" file.) See the website for more details on how to set up custom stages.`,
|
|
37
49
|
);
|
|
38
50
|
}
|
|
39
51
|
|
|
@@ -56,7 +68,7 @@ export function setCustomStage(name: string, verbose = false): void {
|
|
|
56
68
|
setStage(baseStage, baseStageType);
|
|
57
69
|
|
|
58
70
|
// Now, we need to pick a custom room for each vanilla room.
|
|
59
|
-
for (const room of
|
|
71
|
+
for (const room of getRoomsInGrid()) {
|
|
60
72
|
// The starting floor of each room should stay empty.
|
|
61
73
|
if (room.SafeGridIndex === startingRoomGridIndex) {
|
|
62
74
|
continue;
|
|
@@ -16,6 +16,7 @@ export function drawBlackSprite(): void {
|
|
|
16
16
|
if (!blackSprite.IsLoaded()) {
|
|
17
17
|
blackSprite.Load("gfx/ui/boss/versusscreen.anm2", true);
|
|
18
18
|
blackSprite.SetFrame("Scene", 0);
|
|
19
|
+
blackSprite.Scale = Vector(100, 100);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
blackSprite.RenderLayer(0, VectorZero);
|
|
@@ -207,7 +207,7 @@ export function getNewRoomCandidatesForLevel(): Array<
|
|
|
207
207
|
export function getRoomGridIndexesForType(...roomTypes: RoomType[]): int[] {
|
|
208
208
|
const roomTypesSet = new Set<RoomType>([...roomTypes]);
|
|
209
209
|
|
|
210
|
-
const rooms =
|
|
210
|
+
const rooms = getRoomsInGrid();
|
|
211
211
|
const matchingRooms = rooms.filter(
|
|
212
212
|
(roomDescriptor) =>
|
|
213
213
|
roomDescriptor.Data !== undefined &&
|
|
@@ -62,7 +62,7 @@ export function getRoomDescriptor(roomGridIndex?: int): RoomDescriptor {
|
|
|
62
62
|
* Alias for the `Level.GetCurrentRoomDesc` method. Use this to make it more clear what type of
|
|
63
63
|
* `RoomDescriptor` object that you are retrieving.
|
|
64
64
|
*/
|
|
65
|
-
export function getRoomDescriptorReadOnly():
|
|
65
|
+
export function getRoomDescriptorReadOnly(): Readonly<RoomDescriptor> {
|
|
66
66
|
const level = game.GetLevel();
|
|
67
67
|
return level.GetCurrentRoomDesc();
|
|
68
68
|
}
|
package/src/functions/rooms.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AngelRoomSubType,
|
|
3
|
+
BackdropType,
|
|
3
4
|
BossID,
|
|
4
5
|
Dimension,
|
|
5
6
|
Direction,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
StageID,
|
|
19
20
|
} from "isaac-typescript-definitions";
|
|
20
21
|
import { game, sfxManager } from "../cachedClasses";
|
|
21
|
-
import { MAX_LEVEL_GRID_INDEX } from "../constants";
|
|
22
|
+
import { MAX_LEVEL_GRID_INDEX, NUM_DIMENSIONS } from "../constants";
|
|
22
23
|
import { ROOM_TYPE_NAMES } from "../objects/roomTypeNames";
|
|
23
24
|
import { MINE_SHAFT_ROOM_SUB_TYPE_SET } from "../sets/mineShaftRoomSubTypesSet";
|
|
24
25
|
import { hasCurse } from "./curses";
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
} from "./positionVelocity";
|
|
40
41
|
import {
|
|
41
42
|
getRoomData,
|
|
43
|
+
getRoomDescriptor,
|
|
42
44
|
getRoomDescriptorReadOnly,
|
|
43
45
|
getRoomGridIndex,
|
|
44
46
|
getRoomName,
|
|
@@ -46,7 +48,7 @@ import {
|
|
|
46
48
|
getRoomSubType,
|
|
47
49
|
} from "./roomData";
|
|
48
50
|
import { getGotoCommand } from "./stage";
|
|
49
|
-
import { irange } from "./utils";
|
|
51
|
+
import { erange, irange } from "./utils";
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* Helper function for quickly switching to a new room without playing a particular animation. Use
|
|
@@ -79,6 +81,36 @@ export function getNumRooms(): int {
|
|
|
79
81
|
return rooms.length;
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Helper function to get a read-only copy of the room descriptor for every room on the level. This
|
|
86
|
+
* includes off-grid rooms, such as the Devil Room, and extra-dimensional rooms, if they are
|
|
87
|
+
* generated and exist.
|
|
88
|
+
*
|
|
89
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
90
|
+
*
|
|
91
|
+
* Under the hood, this is performed by iterating over the `RoomList` from the `Level.GetRooms`
|
|
92
|
+
* method. This is the best way to see if off-grid rooms have been initialized, since it is possible
|
|
93
|
+
* for mods to insert room data at non-official negative room grid indexes.
|
|
94
|
+
*/
|
|
95
|
+
export function getReadOnlyRooms(): Array<Readonly<RoomDescriptor>> {
|
|
96
|
+
const level = game.GetLevel();
|
|
97
|
+
const roomList = level.GetRooms();
|
|
98
|
+
|
|
99
|
+
const readOnlyRoomDescriptors: Array<Readonly<RoomDescriptor>> = [];
|
|
100
|
+
|
|
101
|
+
for (let i = 0; i < roomList.Size; i++) {
|
|
102
|
+
const readOnlyRoomDescriptor = roomList.Get(i);
|
|
103
|
+
if (
|
|
104
|
+
readOnlyRoomDescriptor !== undefined &&
|
|
105
|
+
readOnlyRoomDescriptor.Data !== undefined
|
|
106
|
+
) {
|
|
107
|
+
readOnlyRoomDescriptors.push(readOnlyRoomDescriptor);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return readOnlyRoomDescriptors;
|
|
112
|
+
}
|
|
113
|
+
|
|
82
114
|
/**
|
|
83
115
|
* Helper function to get the room data for a specific room type and variant combination. This is
|
|
84
116
|
* accomplished by using the "goto" console command to load the specified room into the
|
|
@@ -146,87 +178,105 @@ export function getRoomTypeName(roomType: RoomType): string {
|
|
|
146
178
|
|
|
147
179
|
/**
|
|
148
180
|
* Helper function to get the room descriptor for every room on the level. This includes off-grid
|
|
149
|
-
* rooms, such as the Devil Room.
|
|
150
|
-
*
|
|
181
|
+
* rooms, such as the Devil Room.
|
|
182
|
+
*
|
|
183
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
151
184
|
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
185
|
+
* - If you want just the rooms inside of the grid, use the `getRoomsInGrid` helper function.
|
|
186
|
+
* - If you want just the rooms outside of the grid, use the `getRoomsOutsideGrid` helper function.
|
|
154
187
|
*
|
|
155
188
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
156
|
-
* extra-dimensional rooms are automatically generated
|
|
157
|
-
*
|
|
189
|
+
* extra-dimensional rooms are automatically generated. Default is
|
|
190
|
+
* false.
|
|
158
191
|
*/
|
|
159
192
|
export function getRooms(
|
|
160
193
|
includeExtraDimensionalRooms = false,
|
|
161
194
|
): RoomDescriptor[] {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
for (let i = 0; i < roomList.Size; i++) {
|
|
169
|
-
const roomDescriptor = roomList.Get(i);
|
|
170
|
-
if (roomDescriptor === undefined || roomDescriptor.Data === undefined) {
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
!includeExtraDimensionalRooms &&
|
|
176
|
-
roomsMap.has(roomDescriptor.SafeGridIndex)
|
|
177
|
-
) {
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
roomsMap.set(roomDescriptor.SafeGridIndex, roomDescriptor);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return [...roomsMap.values()];
|
|
195
|
+
// The obvious way to get all of the rooms would be to iterate over the `RoomList` from the
|
|
196
|
+
// `Level.GetRooms` method. However, this results in read-only data, and we want to return a
|
|
197
|
+
// writable object. Instead, we let the heavy lifting be handled by other functions.
|
|
198
|
+
const roomsInGrid = getRoomsInGrid(includeExtraDimensionalRooms);
|
|
199
|
+
const roomsOutsideGrid = getRoomsOutsideGrid();
|
|
200
|
+
return [...roomsInGrid, ...roomsOutsideGrid];
|
|
185
201
|
}
|
|
186
202
|
|
|
187
203
|
/**
|
|
188
|
-
* Helper function to get the room descriptor for every room on the level
|
|
189
|
-
*
|
|
204
|
+
* Helper function to get the room descriptor for every room on the level that is on the grid. (For
|
|
205
|
+
* example, Devil Rooms are excluded.)
|
|
190
206
|
*
|
|
191
|
-
*
|
|
192
|
-
* data are assumed to be non-existent and are not added to the list.
|
|
207
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
193
208
|
*
|
|
194
209
|
* @param includeExtraDimensionalRooms Optional. On some floors (e.g. Downpour 2, Mines 2),
|
|
195
|
-
* extra-dimensional rooms are automatically be generated
|
|
196
|
-
*
|
|
210
|
+
* extra-dimensional rooms are automatically be generated. Default
|
|
211
|
+
* is false.
|
|
197
212
|
*/
|
|
198
213
|
export function getRoomsInGrid(
|
|
199
214
|
includeExtraDimensionalRooms = false,
|
|
200
215
|
): RoomDescriptor[] {
|
|
201
|
-
const
|
|
202
|
-
|
|
216
|
+
const level = game.GetLevel();
|
|
217
|
+
|
|
218
|
+
const dimensions = includeExtraDimensionalRooms
|
|
219
|
+
? (erange(NUM_DIMENSIONS) as Dimension[])
|
|
220
|
+
: [Dimension.CURRENT];
|
|
221
|
+
|
|
222
|
+
/** We use a map instead of an array because room shapes occupy more than one room grid index. */
|
|
223
|
+
const roomDescriptorMap = new Map<PtrHash, RoomDescriptor>();
|
|
224
|
+
|
|
225
|
+
for (const dimension of dimensions) {
|
|
226
|
+
for (const roomGridIndex of irange(MAX_LEVEL_GRID_INDEX)) {
|
|
227
|
+
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
228
|
+
if (roomDescriptor.Data !== undefined) {
|
|
229
|
+
const ptrHash = GetPtrHash(roomDescriptor);
|
|
230
|
+
roomDescriptorMap.set(ptrHash, roomDescriptor);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return [...roomDescriptorMap.values()];
|
|
203
236
|
}
|
|
204
237
|
|
|
205
238
|
/**
|
|
206
239
|
* Helper function to get the room descriptor for every room on the level in a specific dimension.
|
|
207
240
|
* This will not include any off-grid rooms, such as the Devil Room.
|
|
208
241
|
*
|
|
209
|
-
*
|
|
210
|
-
* data are assumed to be non-existent and are not added to the list.
|
|
211
|
-
*
|
|
212
|
-
* @returns A map of room ListIndex to RoomDescriptor.
|
|
242
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
213
243
|
*/
|
|
214
244
|
export function getRoomsOfDimension(dimension: Dimension): RoomDescriptor[] {
|
|
215
245
|
const level = game.GetLevel();
|
|
216
246
|
|
|
217
247
|
/** We use a map instead of an array because room shapes occupy more than one room grid index. */
|
|
218
|
-
const roomsMap = new Map<
|
|
248
|
+
const roomsMap = new Map<PtrHash, RoomDescriptor>();
|
|
219
249
|
|
|
220
250
|
for (const roomGridIndex of irange(MAX_LEVEL_GRID_INDEX)) {
|
|
221
251
|
const roomDescriptor = level.GetRoomByIdx(roomGridIndex, dimension);
|
|
222
252
|
if (roomDescriptor.Data !== undefined) {
|
|
223
|
-
|
|
253
|
+
const ptrHash = GetPtrHash(roomDescriptor);
|
|
254
|
+
roomsMap.set(ptrHash, roomDescriptor);
|
|
224
255
|
}
|
|
225
256
|
}
|
|
226
257
|
|
|
227
258
|
return [...roomsMap.values()];
|
|
228
259
|
}
|
|
229
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Helper function to get the room descriptor for every room on the level that is outside of the
|
|
263
|
+
* grid (like a Devil Room).
|
|
264
|
+
*
|
|
265
|
+
* Room descriptors without any data are assumed to be non-existent and are not included.
|
|
266
|
+
*/
|
|
267
|
+
export function getRoomsOutsideGrid(): RoomDescriptor[] {
|
|
268
|
+
// We filter an array of all rooms instead of iterating over the `GridRoom` enum because it is
|
|
269
|
+
// possible for mods to insert data at arbitrary negative room grid indexes.
|
|
270
|
+
const readOnlyRooms = getReadOnlyRooms();
|
|
271
|
+
const readOnlyRoomsOffGrid = readOnlyRooms.filter(
|
|
272
|
+
(readOnlyRoomDescriptor) => readOnlyRoomDescriptor.SafeGridIndex < 0,
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
return readOnlyRoomsOffGrid.map((readOnlyRoomDescriptor) =>
|
|
276
|
+
getRoomDescriptor(readOnlyRoomDescriptor.SafeGridIndex),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
230
280
|
/**
|
|
231
281
|
* Helper function to determine if the current room shape is equal to `RoomShape.1x2` or
|
|
232
282
|
* `RoomShape.2x1`.
|
|
@@ -413,7 +463,7 @@ export function inStartingRoom(): boolean {
|
|
|
413
463
|
/**
|
|
414
464
|
* Helper function to loop through every room on the floor and see if it has been cleared.
|
|
415
465
|
*
|
|
416
|
-
* This function will only check rooms
|
|
466
|
+
* This function will only check rooms inside the gird and inside the current dimension.
|
|
417
467
|
*
|
|
418
468
|
* @param onlyCheckRoomTypes Optional. A whitelist of room types. If specified, room types not in
|
|
419
469
|
* the array will be ignored. If not specified, then all rooms will be
|
|
@@ -422,7 +472,7 @@ export function inStartingRoom(): boolean {
|
|
|
422
472
|
export function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolean {
|
|
423
473
|
const roomTypeWhitelist =
|
|
424
474
|
onlyCheckRoomTypes === undefined ? null : new Set(onlyCheckRoomTypes);
|
|
425
|
-
const rooms =
|
|
475
|
+
const rooms = getRoomsInGrid();
|
|
426
476
|
const matchingRooms =
|
|
427
477
|
roomTypeWhitelist === null
|
|
428
478
|
? rooms
|
|
@@ -454,6 +504,11 @@ export function roomUpdateSafe(): void {
|
|
|
454
504
|
setEntityVelocities(entityVelocities, entities);
|
|
455
505
|
}
|
|
456
506
|
|
|
507
|
+
/** Helper function to set the backdrop of the current room. */
|
|
508
|
+
export function setBackdrop(backdropType: BackdropType): void {
|
|
509
|
+
game.ShowHallucination(0, backdropType);
|
|
510
|
+
}
|
|
511
|
+
|
|
457
512
|
/**
|
|
458
513
|
* Helper function to convert an uncleared room to a cleared room in the `POST_NEW_ROOM` callback.
|
|
459
514
|
* This is useful because if enemies are removed in this callback, a room drop will be awarded and
|